feat: gate client actions by canonical phase state

This commit is contained in:
2026-03-16 10:15:35 +00:00
parent 9594a8fcb0
commit 076faf2ff1
5 changed files with 188 additions and 21 deletions
@@ -245,6 +245,30 @@ describe('HostShellComponent gameplay wiring', () => {
expect(component.finishError).toContain('Session code is required');
});
it('blocks illegal host actions outside canonical reveal/scoreboard boundaries', async () => {
const fetchMock: FetchMock = vi.fn();
vi.stubGlobal('fetch', fetchMock);
const component = new HostShellComponent();
component.sessionCode = 'ABCD12';
for (const status of ['lie', 'guess', 'reveal'] as const) {
component.session = sessionDetailPayload(status) as any;
await component.startNextRound();
await component.finishGame();
}
component.session = sessionDetailPayload('reveal') as any;
expect(component.canStartNextRound).toBe(false);
expect(component.canFinishGame).toBe(false);
component.session = sessionDetailPayload('scoreboard') as any;
await component.loadScoreboard();
expect(component.canLoadScoreboard).toBe(false);
expect(fetchMock).not.toHaveBeenCalled();
});
it('syncs host hash-route with latest phase after refresh without page reload', async () => {
const fetchMock: FetchMock = vi.fn().mockResolvedValue(jsonResponse(200, sessionDetailPayload('guess', { roundQuestionId: 77 })));
vi.stubGlobal('fetch', fetchMock);