fix(gameplay): restore reveal before scoreboard
This commit is contained in:
@@ -104,9 +104,15 @@ describe('SPA Angular API contract smoke (host/player foundation)', () => {
|
||||
if (url === '/lobby/sessions/ABCD12/questions/77/scores/calculate') {
|
||||
expect(body).toEqual({});
|
||||
return {
|
||||
session: { code: 'ABCD12', status: 'scoreboard', current_round: 1 },
|
||||
session: { code: 'ABCD12', status: 'reveal', current_round: 1 },
|
||||
round_question: { id: 77, round_number: 1 },
|
||||
events_created: 2,
|
||||
reveal: {
|
||||
round_question_id: 77,
|
||||
correct_answer: 'A',
|
||||
lies: [],
|
||||
guesses: []
|
||||
},
|
||||
leaderboard: [
|
||||
{ id: 9, nickname: 'Maja', score: 200 },
|
||||
{ id: 10, nickname: 'Bo', score: 150 }
|
||||
|
||||
@@ -701,7 +701,7 @@ class ScoreCalculationTests(TestCase):
|
||||
self.player_two = Player.objects.create(session=self.session, nickname="Mads")
|
||||
self.player_three = Player.objects.create(session=self.session, nickname="Nora")
|
||||
|
||||
def test_host_can_calculate_scores_and_transition_to_scoreboard(self):
|
||||
def test_host_can_calculate_scores_and_transition_to_reveal(self):
|
||||
Guess.objects.create(round_question=self.round_question, player=self.player_one, selected_text="Tennis", is_correct=True)
|
||||
Guess.objects.create(
|
||||
round_question=self.round_question,
|
||||
@@ -728,7 +728,7 @@ class ScoreCalculationTests(TestCase):
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
payload = response.json()
|
||||
self.assertEqual(payload["session"]["status"], GameSession.Status.SCOREBOARD)
|
||||
self.assertEqual(payload["session"]["status"], GameSession.Status.REVEAL)
|
||||
self.assertEqual(payload["events_created"], 2)
|
||||
|
||||
self.player_one.refresh_from_db()
|
||||
@@ -737,7 +737,7 @@ class ScoreCalculationTests(TestCase):
|
||||
|
||||
self.assertEqual(self.player_one.score, 5)
|
||||
self.assertEqual(self.player_three.score, 4)
|
||||
self.assertEqual(self.session.status, GameSession.Status.SCOREBOARD)
|
||||
self.assertEqual(self.session.status, GameSession.Status.REVEAL)
|
||||
|
||||
def test_calculate_scores_requires_host(self):
|
||||
self.client.login(username="other_score", password="secret123")
|
||||
@@ -813,6 +813,16 @@ class RevealRoundFlowTests(TestCase):
|
||||
self.assertEqual(response.status_code, 403)
|
||||
self.assertEqual(response.json()["error"], "Only host can view scoreboard")
|
||||
|
||||
def test_reveal_scoreboard_rejects_scoreboard_phase(self):
|
||||
self.session.status = GameSession.Status.SCOREBOARD
|
||||
self.session.save(update_fields=["status"])
|
||||
self.client.login(username="host_reveal", password="secret123")
|
||||
|
||||
response = self.client.get(reverse("lobby:reveal_scoreboard", kwargs={"code": self.session.code}))
|
||||
|
||||
self.assertEqual(response.status_code, 400)
|
||||
self.assertEqual(response.json()["error"], "Scoreboard is only available in reveal phase")
|
||||
|
||||
def test_host_can_finish_game_from_scoreboard(self):
|
||||
self.client.login(username="host_reveal", password="secret123")
|
||||
self.client.get(reverse("lobby:reveal_scoreboard", kwargs={"code": self.session.code}))
|
||||
@@ -881,7 +891,7 @@ 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_from_scoreboard_phase(self):
|
||||
def test_reveal_scoreboard_rejects_repeated_reads_after_promotion(self):
|
||||
self.client.login(username="host_reveal", password="secret123")
|
||||
|
||||
first_response = self.client.get(
|
||||
@@ -898,8 +908,8 @@ class RevealRoundFlowTests(TestCase):
|
||||
)
|
||||
|
||||
self.assertEqual(first_response.status_code, 200)
|
||||
self.assertEqual(second_response.status_code, 200)
|
||||
self.assertEqual(second_response.json()["session"]["status"], GameSession.Status.SCOREBOARD)
|
||||
self.assertEqual(second_response.status_code, 400)
|
||||
self.assertEqual(second_response.json()["error"], "Scoreboard is only available in reveal phase")
|
||||
|
||||
def test_start_next_round_rejects_wrong_phase(self):
|
||||
self.client.login(username="host_reveal", password="secret123")
|
||||
|
||||
@@ -714,12 +714,11 @@ def reveal_scoreboard(request: HttpRequest, code: str) -> JsonResponse:
|
||||
|
||||
with transaction.atomic():
|
||||
locked_session = GameSession.objects.select_for_update().get(pk=session.pk)
|
||||
if locked_session.status not in {GameSession.Status.REVEAL, GameSession.Status.SCOREBOARD}:
|
||||
return JsonResponse({"error": "Scoreboard is only available in reveal or scoreboard phase"}, status=400)
|
||||
if locked_session.status != GameSession.Status.REVEAL:
|
||||
return JsonResponse({"error": "Scoreboard is only available in reveal phase"}, status=400)
|
||||
|
||||
if locked_session.status == GameSession.Status.REVEAL:
|
||||
locked_session.status = GameSession.Status.SCOREBOARD
|
||||
locked_session.save(update_fields=["status"])
|
||||
locked_session.status = GameSession.Status.SCOREBOARD
|
||||
locked_session.save(update_fields=["status"])
|
||||
|
||||
leaderboard = list(
|
||||
Player.objects.filter(session=session)
|
||||
@@ -897,7 +896,7 @@ def calculate_scores(request: HttpRequest, code: str, round_question_id: int) ->
|
||||
|
||||
ScoreEvent.objects.bulk_create(score_events)
|
||||
|
||||
locked_session.status = GameSession.Status.SCOREBOARD
|
||||
locked_session.status = GameSession.Status.REVEAL
|
||||
locked_session.save(update_fields=["status"])
|
||||
|
||||
leaderboard = list(
|
||||
@@ -910,7 +909,7 @@ def calculate_scores(request: HttpRequest, code: str, round_question_id: int) ->
|
||||
{
|
||||
"session": {
|
||||
"code": session.code,
|
||||
"status": GameSession.Status.SCOREBOARD,
|
||||
"status": GameSession.Status.REVEAL,
|
||||
"current_round": session.current_round,
|
||||
},
|
||||
"round_question": {
|
||||
|
||||
Reference in New Issue
Block a user