97 lines
3.2 KiB
Python
97 lines
3.2 KiB
Python
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"
|