feat(f3): add guess submission endpoint with deadline checks

This commit is contained in:
2026-02-27 16:31:31 +01:00
parent 3ee478f094
commit d66c21ecb3
4 changed files with 211 additions and 1 deletions

View File

@@ -8,6 +8,7 @@ from django.utils import timezone
from fupogfakta.models import (
Category,
GameSession,
Guess,
LieAnswer,
Player,
Question,
@@ -337,3 +338,108 @@ class MixAnswersTests(TestCase):
self.assertEqual(response.status_code, 200)
answer_texts = [entry["text"] for entry in response.json()["answers"]]
self.assertEqual(set(answer_texts), {"København", "Aarhus"})
class GuessSubmissionTests(TestCase):
def setUp(self):
self.host = User.objects.create_user(username="host_guess", password="secret123")
self.session = GameSession.objects.create(host=self.host, code="GU3551", status=GameSession.Status.GUESS)
self.category = Category.objects.create(name="Videnskab", slug="videnskab", is_active=True)
self.question = Question.objects.create(
category=self.category,
prompt="Hvilken planet kaldes den røde planet?",
correct_answer="Mars",
is_active=True,
)
self.round_config = RoundConfig.objects.create(
session=self.session,
number=1,
category=self.category,
lie_seconds=45,
guess_seconds=30,
)
self.round_question = RoundQuestion.objects.create(
session=self.session,
round_number=1,
question=self.question,
correct_answer="Mars",
)
self.player = Player.objects.create(session=self.session, nickname="Luna")
self.liar = Player.objects.create(session=self.session, nickname="Mads")
LieAnswer.objects.create(round_question=self.round_question, player=self.liar, text="Jupiter")
def test_player_can_submit_guess_in_guess_phase(self):
response = self.client.post(
reverse(
"lobby:submit_guess",
kwargs={"code": self.session.code, "round_question_id": self.round_question.id},
),
data={"player_id": self.player.id, "selected_text": "Mars"},
content_type="application/json",
)
self.assertEqual(response.status_code, 201)
payload = response.json()
self.assertTrue(payload["guess"]["is_correct"])
self.assertIsNone(payload["guess"]["fooled_player_id"])
self.assertIn("guess_deadline_at", payload["window"])
def test_submit_guess_rejects_when_not_in_guess_phase(self):
self.session.status = GameSession.Status.LIE
self.session.save(update_fields=["status"])
response = self.client.post(
reverse(
"lobby:submit_guess",
kwargs={"code": self.session.code, "round_question_id": self.round_question.id},
),
data={"player_id": self.player.id, "selected_text": "Mars"},
content_type="application/json",
)
self.assertEqual(response.status_code, 400)
self.assertEqual(response.json()["error"], "Guess submission is only allowed in guess phase")
def test_submit_guess_rejects_unknown_answer(self):
response = self.client.post(
reverse(
"lobby:submit_guess",
kwargs={"code": self.session.code, "round_question_id": self.round_question.id},
),
data={"player_id": self.player.id, "selected_text": "Venus"},
content_type="application/json",
)
self.assertEqual(response.status_code, 400)
self.assertEqual(response.json()["error"], "Selected answer is not part of this round")
def test_submit_guess_rejects_duplicate_submission(self):
Guess.objects.create(round_question=self.round_question, player=self.player, selected_text="Mars", is_correct=True)
response = self.client.post(
reverse(
"lobby:submit_guess",
kwargs={"code": self.session.code, "round_question_id": self.round_question.id},
),
data={"player_id": self.player.id, "selected_text": "Jupiter"},
content_type="application/json",
)
self.assertEqual(response.status_code, 409)
self.assertEqual(response.json()["error"], "Guess already submitted for this player")
def test_submit_guess_rejects_after_deadline(self):
self.round_question.shown_at = timezone.now() - timedelta(seconds=76)
self.round_question.save(update_fields=["shown_at"])
response = self.client.post(
reverse(
"lobby:submit_guess",
kwargs={"code": self.session.code, "round_question_id": self.round_question.id},
),
data={"player_id": self.player.id, "selected_text": "Mars"},
content_type="application/json",
)
self.assertEqual(response.status_code, 400)
self.assertEqual(response.json()["error"], "Guess submission window has closed")