diff --git a/frontend/angular/src/app/features/host/host-shell.component.spec.ts b/frontend/angular/src/app/features/host/host-shell.component.spec.ts index a3380e7..6151161 100644 --- a/frontend/angular/src/app/features/host/host-shell.component.spec.ts +++ b/frontend/angular/src/app/features/host/host-shell.component.spec.ts @@ -71,4 +71,50 @@ describe('HostShellComponent gameplay wiring', () => { expect(component.scoreboardError).toContain('Scoreboard failed: Scoreboard unavailable'); expect(component.loading).toBe(false); }); + + it('wires showQuestion, mixAnswers and calculateScores with expected request payloads', async () => { + const sessionAfterAction = { + session: { code: 'ABCD12', status: 'guess', current_round: 1 }, + round_question: { id: 77, prompt: 'Q?', answers: [] }, + players: [], + }; + + const fetchMock: FetchMock = vi + .fn() + .mockResolvedValueOnce(jsonResponse(200, { ok: true })) + .mockResolvedValueOnce(jsonResponse(200, sessionAfterAction)) + .mockResolvedValueOnce(jsonResponse(200, { ok: true })) + .mockResolvedValueOnce(jsonResponse(200, sessionAfterAction)) + .mockResolvedValueOnce(jsonResponse(200, { ok: true })) + .mockResolvedValueOnce(jsonResponse(200, sessionAfterAction)); + + vi.stubGlobal('fetch', fetchMock); + + const component = new HostShellComponent(); + component.sessionCode = ' abcd12 '; + component.roundQuestionId = ' 77 '; + + await component.showQuestion(); + await component.mixAnswers(); + await component.calculateScores(); + + expect(fetchMock).toHaveBeenNthCalledWith( + 1, + '/lobby/sessions/ABCD12/questions/show', + expect.objectContaining({ method: 'POST', body: JSON.stringify({}) }) + ); + expect(fetchMock).toHaveBeenNthCalledWith( + 3, + '/lobby/sessions/ABCD12/questions/77/answers/mix', + expect.objectContaining({ method: 'POST', body: JSON.stringify({}) }) + ); + expect(fetchMock).toHaveBeenNthCalledWith( + 5, + '/lobby/sessions/ABCD12/questions/77/scores/calculate', + expect.objectContaining({ method: 'POST', body: JSON.stringify({}) }) + ); + + expect(component.error).toBe(''); + expect(component.loading).toBe(false); + }); }); diff --git a/frontend/angular/src/app/features/player/player-shell.component.spec.ts b/frontend/angular/src/app/features/player/player-shell.component.spec.ts index 30ebc91..6a0862b 100644 --- a/frontend/angular/src/app/features/player/player-shell.component.spec.ts +++ b/frontend/angular/src/app/features/player/player-shell.component.spec.ts @@ -66,6 +66,14 @@ describe('PlayerShellComponent gameplay wiring', () => { await component.submitLie(); + expect(fetchMock).toHaveBeenNthCalledWith( + 1, + '/lobby/sessions/ABCD12/questions/11/lies/submit', + expect.objectContaining({ + method: 'POST', + body: JSON.stringify({ player_id: 9, session_token: 'token-1', text: 'my lie' }), + }) + ); expect(component.submitError?.kind).toBe('lie'); expect(component.submitError?.message).toContain('Lie submit failed: Temporary submit outage'); @@ -75,4 +83,49 @@ describe('PlayerShellComponent gameplay wiring', () => { expect(component.session?.session.status).toBe('guess'); expect(fetchMock).toHaveBeenCalledTimes(3); }); + + it('surfaces guess submit error and retries with selected answer payload', async () => { + const fetchMock: FetchMock = vi + .fn() + .mockResolvedValueOnce(jsonResponse(503, { error: 'Guess queue busy' })) + .mockResolvedValueOnce(jsonResponse(200, { ok: true })) + .mockResolvedValueOnce( + jsonResponse(200, { + session: { code: 'ABCD12', status: 'reveal', current_round: 1 }, + round_question: { id: 11, prompt: 'Q?', answers: [{ text: 'A' }, { text: 'B' }] }, + }) + ); + + vi.stubGlobal('fetch', fetchMock); + + const component = new PlayerShellComponent(); + component.sessionCode = ' abcd12 '; + component.playerId = 9; + component.sessionToken = 'token-1'; + component.selectedGuess = 'B'; + component.session = { + session: { code: 'ABCD12', status: 'guess', current_round: 1 }, + round_question: { id: 11, prompt: 'Q?', answers: [{ text: 'A' }, { text: 'B' }] }, + }; + + await component.submitGuess(); + + expect(fetchMock).toHaveBeenNthCalledWith( + 1, + '/lobby/sessions/ABCD12/questions/11/guesses/submit', + expect.objectContaining({ + method: 'POST', + body: JSON.stringify({ player_id: 9, session_token: 'token-1', selected_text: 'B' }), + }) + ); + expect(component.submitError?.kind).toBe('guess'); + expect(component.submitError?.message).toContain('Guess submit failed: Guess queue busy'); + + await component.submitGuess(); + + expect(component.submitError).toBeNull(); + expect(component.session?.session.status).toBe('reveal'); + expect(component.selectedGuess).toBe(''); + expect(fetchMock).toHaveBeenCalledTimes(3); + }); });