fix(gameplay): restore scoreboard phase error contract
This commit is contained in:
@@ -782,7 +782,8 @@ class RevealRoundFlowTests(TestCase):
|
||||
self.player_one = Player.objects.create(session=self.session, nickname="Luna", score=9)
|
||||
self.player_two = Player.objects.create(session=self.session, nickname="Mads", score=3)
|
||||
|
||||
def test_host_can_get_reveal_scoreboard(self):
|
||||
@patch("lobby.views.sync_broadcast_phase_event")
|
||||
def test_host_can_get_reveal_scoreboard(self, mock_sync_broadcast_phase_event):
|
||||
self.client.login(username="host_reveal", password="secret123")
|
||||
|
||||
response = self.client.get(
|
||||
@@ -796,6 +797,17 @@ class RevealRoundFlowTests(TestCase):
|
||||
payload = response.json()
|
||||
self.assertEqual(payload["session"]["status"], GameSession.Status.SCOREBOARD)
|
||||
self.assertEqual([item["nickname"] for item in payload["leaderboard"]], ["Luna", "Mads"])
|
||||
mock_sync_broadcast_phase_event.assert_called_once_with(
|
||||
self.session.code,
|
||||
"phase.scoreboard",
|
||||
{
|
||||
"leaderboard": [
|
||||
{"id": self.player_one.id, "nickname": "Luna", "score": 9},
|
||||
{"id": self.player_two.id, "nickname": "Mads", "score": 3},
|
||||
],
|
||||
"current_round": 1,
|
||||
},
|
||||
)
|
||||
|
||||
self.session.refresh_from_db()
|
||||
self.assertEqual(self.session.status, GameSession.Status.SCOREBOARD)
|
||||
@@ -807,11 +819,16 @@ class RevealRoundFlowTests(TestCase):
|
||||
reverse(
|
||||
"lobby:reveal_scoreboard",
|
||||
kwargs={"code": self.session.code},
|
||||
)
|
||||
),
|
||||
HTTP_ACCEPT_LANGUAGE="fr",
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 403)
|
||||
self.assertEqual(response.json()["error"], "Only host can view scoreboard")
|
||||
self.assertEqual(response.json(), {
|
||||
"error": "Only host can view scoreboard",
|
||||
"error_code": "host_only_view_scoreboard",
|
||||
"locale": "en",
|
||||
})
|
||||
|
||||
def test_reveal_scoreboard_is_idempotent_in_scoreboard_phase(self):
|
||||
self.session.status = GameSession.Status.SCOREBOARD
|
||||
@@ -825,7 +842,8 @@ class RevealRoundFlowTests(TestCase):
|
||||
self.assertEqual(payload["session"]["status"], GameSession.Status.SCOREBOARD)
|
||||
self.assertEqual([item["nickname"] for item in payload["leaderboard"]], ["Luna", "Mads"])
|
||||
|
||||
def test_host_can_finish_game_from_scoreboard(self):
|
||||
@patch("lobby.views.sync_broadcast_phase_event")
|
||||
def test_host_can_finish_game_from_scoreboard(self, _mock_sync_broadcast_phase_event):
|
||||
self.client.login(username="host_reveal", password="secret123")
|
||||
self.client.get(reverse("lobby:reveal_scoreboard", kwargs={"code": self.session.code}))
|
||||
|
||||
@@ -852,11 +870,16 @@ class RevealRoundFlowTests(TestCase):
|
||||
reverse(
|
||||
"lobby:finish_game",
|
||||
kwargs={"code": self.session.code},
|
||||
)
|
||||
),
|
||||
HTTP_ACCEPT_LANGUAGE="da",
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 403)
|
||||
self.assertEqual(response.json()["error"], "Only host can finish game")
|
||||
self.assertEqual(response.json(), {
|
||||
"error": "Kun værten kan afslutte spillet",
|
||||
"error_code": "host_only_finish_game",
|
||||
"locale": "da",
|
||||
})
|
||||
|
||||
def test_finish_game_rejects_wrong_phase(self):
|
||||
self.client.login(username="host_reveal", password="secret123")
|
||||
@@ -867,13 +890,19 @@ class RevealRoundFlowTests(TestCase):
|
||||
reverse(
|
||||
"lobby:finish_game",
|
||||
kwargs={"code": self.session.code},
|
||||
)
|
||||
),
|
||||
HTTP_ACCEPT_LANGUAGE="fr",
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 400)
|
||||
self.assertEqual(response.json()["error"], "Game can only be finished from scoreboard phase")
|
||||
self.assertEqual(response.json(), {
|
||||
"error": "Game can only be finished from scoreboard phase",
|
||||
"error_code": "finish_game_invalid_phase",
|
||||
"locale": "en",
|
||||
})
|
||||
|
||||
def test_host_can_start_next_round_from_scoreboard(self):
|
||||
@patch("lobby.views.sync_broadcast_phase_event")
|
||||
def test_host_can_start_next_round_from_scoreboard(self, _mock_sync_broadcast_phase_event):
|
||||
self.client.login(username="host_reveal", password="secret123")
|
||||
self.client.get(reverse("lobby:reveal_scoreboard", kwargs={"code": self.session.code}))
|
||||
|
||||
@@ -893,7 +922,28 @@ class RevealRoundFlowTests(TestCase):
|
||||
self.assertEqual(self.session.status, GameSession.Status.LOBBY)
|
||||
self.assertEqual(self.session.current_round, 2)
|
||||
|
||||
def test_reveal_scoreboard_allows_repeated_reads_after_promotion(self):
|
||||
def test_start_next_round_requires_host(self):
|
||||
self.session.status = GameSession.Status.SCOREBOARD
|
||||
self.session.save(update_fields=["status"])
|
||||
self.client.login(username="other_reveal", password="secret123")
|
||||
|
||||
response = self.client.post(
|
||||
reverse(
|
||||
"lobby:start_next_round",
|
||||
kwargs={"code": self.session.code},
|
||||
),
|
||||
HTTP_ACCEPT_LANGUAGE="fr",
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 403)
|
||||
self.assertEqual(response.json(), {
|
||||
"error": "Only host can start next round",
|
||||
"error_code": "host_only_start_next_round",
|
||||
"locale": "en",
|
||||
})
|
||||
|
||||
@patch("lobby.views.sync_broadcast_phase_event")
|
||||
def test_reveal_scoreboard_allows_repeated_reads_after_promotion(self, mock_sync_broadcast_phase_event):
|
||||
self.client.login(username="host_reveal", password="secret123")
|
||||
|
||||
first_response = self.client.get(
|
||||
@@ -914,6 +964,7 @@ class RevealRoundFlowTests(TestCase):
|
||||
self.assertEqual(first_response.json()["session"]["status"], GameSession.Status.SCOREBOARD)
|
||||
self.assertEqual(second_response.json()["session"]["status"], GameSession.Status.SCOREBOARD)
|
||||
self.assertEqual([item["nickname"] for item in second_response.json()["leaderboard"]], ["Luna", "Mads"])
|
||||
self.assertEqual(mock_sync_broadcast_phase_event.call_count, 1)
|
||||
|
||||
def test_start_next_round_rejects_wrong_phase(self):
|
||||
self.client.login(username="host_reveal", password="secret123")
|
||||
@@ -924,11 +975,16 @@ class RevealRoundFlowTests(TestCase):
|
||||
reverse(
|
||||
"lobby:start_next_round",
|
||||
kwargs={"code": self.session.code},
|
||||
)
|
||||
),
|
||||
HTTP_ACCEPT_LANGUAGE="da",
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 400)
|
||||
self.assertEqual(response.json()["error"], "Next round can only start from scoreboard phase")
|
||||
self.assertEqual(response.json(), {
|
||||
"error": "Næste runde kan kun starte fra scoreboard-fasen",
|
||||
"error_code": "next_round_invalid_phase",
|
||||
"locale": "da",
|
||||
})
|
||||
|
||||
class UiScreenTests(TestCase):
|
||||
def setUp(self):
|
||||
|
||||
Reference in New Issue
Block a user