From c9e64bc8a876cb4c01c2e62f4a21158236ae5761 Mon Sep 17 00:00:00 2001 From: dev-bot Date: Tue, 17 Mar 2026 20:48:39 +0000 Subject: [PATCH] test(gameplay): lock lobby delegation for host transitions (#310) --- fupogfakta/tests.py | 69 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/fupogfakta/tests.py b/fupogfakta/tests.py index f737672..39da7e6 100644 --- a/fupogfakta/tests.py +++ b/fupogfakta/tests.py @@ -3,6 +3,7 @@ from unittest.mock import patch from django.contrib.auth import get_user_model from django.test import TestCase +from django.urls import reverse from django.utils import timezone from fupogfakta.models import Category, GameSession, Guess, LieAnswer, Player, Question, RoundConfig, RoundQuestion, ScoreEvent @@ -193,6 +194,74 @@ class FupOgFaktaExtractionSliceTests(TestCase): self.assertEqual(result.session.status, GameSession.Status.FINISHED) self.assertEqual(self.session.status, GameSession.Status.FINISHED) + @patch("lobby.views.sync_broadcast_phase_event") + @patch("lobby.views._start_next_round") + def test_start_next_round_view_delegates_to_fupogfakta_service(self, mock_start_next_round, mock_broadcast): + self.client.login(username="host", password="secret123") + self.session.status = GameSession.Status.SCOREBOARD + self.session.save(update_fields=["status"]) + response_payload = { + "session": { + "code": self.session.code, + "status": GameSession.Status.LIE, + "current_round": 2, + } + } + mock_start_next_round.return_value = type( + "Transition", + (), + { + "session": self.session, + "should_broadcast": True, + "response_payload": response_payload, + "phase_event_name": "phase.lie_started", + "phase_event_payload": {"round_number": 2}, + }, + )() + + response = self.client.post(reverse("lobby:start_next_round", kwargs={"code": self.session.code})) + + self.assertEqual(response.status_code, 200) + self.assertEqual(response.json(), response_payload) + mock_start_next_round.assert_called_once_with(self.session) + mock_broadcast.assert_called_once_with(self.session.code, "phase.lie_started", {"round_number": 2}) + + @patch("lobby.views.sync_broadcast_phase_event") + @patch("lobby.views._finish_game") + def test_finish_game_view_delegates_to_fupogfakta_service(self, mock_finish_game, mock_broadcast): + self.client.login(username="host", password="secret123") + self.session.status = GameSession.Status.SCOREBOARD + self.session.save(update_fields=["status"]) + response_payload = { + "session": { + "code": self.session.code, + "status": GameSession.Status.FINISHED, + "current_round": 1, + }, + "winner": None, + "leaderboard": [], + } + finished_session = GameSession.objects.get(pk=self.session.pk) + finished_session.status = GameSession.Status.FINISHED + mock_finish_game.return_value = type( + "Transition", + (), + { + "session": finished_session, + "should_broadcast": True, + "response_payload": response_payload, + "phase_event_name": "phase.game_over", + "phase_event_payload": {"leaderboard": []}, + }, + )() + + response = self.client.post(reverse("lobby:finish_game", kwargs={"code": self.session.code})) + + self.assertEqual(response.status_code, 200) + self.assertEqual(response.json(), response_payload) + mock_finish_game.assert_called_once_with(self.session) + mock_broadcast.assert_called_once_with(self.session.code, "phase.game_over", {"leaderboard": []}) + def test_promote_reveal_to_scoreboard_moves_transition_into_service(self): round_question = RoundQuestion.objects.create( session=self.session,