From a102a72a7744e31624caee7ed28b5ecb54167312 Mon Sep 17 00:00:00 2001 From: dev-bot Date: Tue, 17 Mar 2026 13:21:52 +0000 Subject: [PATCH] fix(gameplay): refresh reused bootstrap lie timer --- fupogfakta/services.py | 10 +++++++++- fupogfakta/tests.py | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/fupogfakta/services.py b/fupogfakta/services.py index a84a6a8..999a89d 100644 --- a/fupogfakta/services.py +++ b/fupogfakta/services.py @@ -2,6 +2,7 @@ import random from dataclasses import dataclass from django.db import transaction +from django.utils import timezone from .models import GameSession, Guess, LieAnswer, Player, Question, RoundConfig, RoundQuestion, ScoreEvent @@ -40,9 +41,16 @@ def get_current_round_question(session: GameSession) -> RoundQuestion | None: def reset_round_question_bootstrap_state(round_question: RoundQuestion) -> RoundQuestion: Guess.objects.filter(round_question=round_question).delete() LieAnswer.objects.filter(round_question=round_question).delete() + + update_fields: list[str] = [] if round_question.mixed_answers: round_question.mixed_answers = [] - round_question.save(update_fields=["mixed_answers"]) + update_fields.append("mixed_answers") + + round_question.shown_at = timezone.now() + update_fields.append("shown_at") + + round_question.save(update_fields=update_fields) return round_question diff --git a/fupogfakta/tests.py b/fupogfakta/tests.py index 306e5eb..85bd65d 100644 --- a/fupogfakta/tests.py +++ b/fupogfakta/tests.py @@ -1,7 +1,9 @@ +from datetime import timedelta from unittest.mock import patch from django.contrib.auth import get_user_model from django.test import TestCase +from django.utils import timezone from fupogfakta.models import Category, GameSession, Guess, LieAnswer, Player, Question, RoundConfig, RoundQuestion, ScoreEvent from fupogfakta.payloads import build_lie_started_payload, build_reveal_payload @@ -100,6 +102,39 @@ class FupOgFaktaExtractionSliceTests(TestCase): with self.assertRaisesMessage(ValueError, "next_round_invalid_phase"): start_next_round(self.session) + def test_start_next_round_refreshes_shown_at_for_reused_bootstrap_question(self): + self.session.status = GameSession.Status.SCOREBOARD + self.session.save(update_fields=["status"]) + stale_shown_at = timezone.now() - timedelta(minutes=10) + stale_round_question = RoundQuestion.objects.create( + session=self.session, + round_number=2, + question=self.question_two, + correct_answer=self.question_two.correct_answer, + shown_at=stale_shown_at, + mixed_answers=["Stale truth", "Stale lie"], + ) + LieAnswer.objects.create(round_question=stale_round_question, player=self.alice, text="Stale lie") + Guess.objects.create( + round_question=stale_round_question, + player=self.bob, + selected_text="Stale truth", + is_correct=True, + ) + + before_transition = timezone.now() + result = start_next_round(self.session) + after_transition = timezone.now() + + stale_round_question.refresh_from_db() + self.assertEqual(result.round_question.id, stale_round_question.id) + self.assertGreaterEqual(stale_round_question.shown_at, before_transition) + self.assertLessEqual(stale_round_question.shown_at, after_transition) + self.assertNotEqual(stale_round_question.shown_at, stale_shown_at) + self.assertEqual(stale_round_question.mixed_answers, []) + self.assertEqual(stale_round_question.lies.count(), 0) + self.assertEqual(stale_round_question.guesses.count(), 0) + def test_finish_game_moves_scoreboard_transition_into_service(self): self.session.status = GameSession.Status.SCOREBOARD self.session.save(update_fields=["status"])