feat: complete realtime challenge matchmaking
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
import pytest
|
||||
from django.test import Client
|
||||
|
||||
from accounts.models import User
|
||||
from contest.models import Contest, ContestQuestion, Question, QuestionVersion
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def realtime_api_setup(db):
|
||||
question = Question.objects.create(
|
||||
slug="realtime-api-question",
|
||||
track=Question.Track.STANDARD,
|
||||
)
|
||||
version = QuestionVersion.objects.create(
|
||||
question=question,
|
||||
version=1,
|
||||
prompt="18 + 24",
|
||||
answer="42",
|
||||
explanation="18 + 24 = 42",
|
||||
)
|
||||
contest = Contest.objects.create(
|
||||
slug="realtime-api",
|
||||
title="API 联机赛",
|
||||
kind=Contest.Kind.REALTIME,
|
||||
track=Question.Track.STANDARD,
|
||||
status=Contest.Status.PUBLISHED,
|
||||
duration_seconds=60,
|
||||
)
|
||||
ContestQuestion.objects.create(
|
||||
contest=contest,
|
||||
question_version=version,
|
||||
order=1,
|
||||
points=100,
|
||||
)
|
||||
first = User.objects.create_user(
|
||||
username="api_player_one",
|
||||
password="StrongPass_2026",
|
||||
nickname="API 玩家一",
|
||||
)
|
||||
second = User.objects.create_user(
|
||||
username="api_player_two",
|
||||
password="StrongPass_2026",
|
||||
nickname="API 玩家二",
|
||||
)
|
||||
first_client = Client()
|
||||
second_client = Client()
|
||||
first_client.force_login(first)
|
||||
second_client.force_login(second)
|
||||
return contest, first_client, second_client
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_challenge_api_创建加入状态提交形成完整闭环(realtime_api_setup):
|
||||
contest, first_client, second_client = realtime_api_setup
|
||||
created = first_client.post(
|
||||
f"/api/v1/contests/{contest.slug}/challenges/",
|
||||
{},
|
||||
content_type="application/json",
|
||||
)
|
||||
code = created.json()["challenge_code"]
|
||||
|
||||
joined = second_client.post(
|
||||
"/api/v1/contests/challenges/join/",
|
||||
{"challenge_code": code.lower()},
|
||||
content_type="application/json",
|
||||
)
|
||||
match_id = joined.json()["match_id"]
|
||||
first_state = first_client.get(f"/api/v1/contests/matches/{match_id}/")
|
||||
|
||||
assert created.status_code == 201
|
||||
assert joined.status_code == 200
|
||||
assert joined.json()["status"] == "active"
|
||||
assert first_state.json()["opponent"]["nickname"] == "API 玩家二"
|
||||
|
||||
first_attempt = first_state.json()["attempt"]["attempt_id"]
|
||||
second_attempt = joined.json()["attempt"]["attempt_id"]
|
||||
first_submit = first_client.post(
|
||||
f"/api/v1/contests/attempts/{first_attempt}/submit/",
|
||||
{"answers": [{"order": 1, "answer": "42"}]},
|
||||
content_type="application/json",
|
||||
HTTP_IDEMPOTENCY_KEY="api-submit-one",
|
||||
)
|
||||
second_submit = second_client.post(
|
||||
f"/api/v1/contests/attempts/{second_attempt}/submit/",
|
||||
{"answers": [{"order": 1, "answer": "0"}]},
|
||||
content_type="application/json",
|
||||
HTTP_IDEMPOTENCY_KEY="api-submit-two",
|
||||
)
|
||||
|
||||
assert first_submit.json()["status"] == "active"
|
||||
assert "correct_answer" not in first_submit.json()["attempt"]["questions"][0]
|
||||
assert second_submit.json()["status"] == "completed"
|
||||
assert second_submit.json()["result"]["winner"] == "opponent"
|
||||
final_state = first_client.get(f"/api/v1/contests/matches/{match_id}/").json()
|
||||
assert final_state["result"]["winner"] == "self"
|
||||
assert final_state["attempt"]["questions"][0]["correct_answer"] == "42"
|
||||
Reference in New Issue
Block a user