diff --git a/frontend/src/spa/vertical-slice.ts b/frontend/src/spa/vertical-slice.ts index 86d4301..f951e06 100644 --- a/frontend/src/spa/vertical-slice.ts +++ b/frontend/src/spa/vertical-slice.ts @@ -1,18 +1,15 @@ import type { ApiClient } from '../api/client'; import type { SessionDetailResponse } from '../api/types'; +import { + createSessionContextStore, + type SessionContext, + type SessionContextInput, + type SessionContextStore as PersistedSessionContextStore +} from './session-context-store'; export type AsyncState = 'idle' | 'loading' | 'success' | 'error'; -export interface SessionContext { - sessionCode: string; - playerToken: string; - nickname: string; -} - -export interface SessionContextStore { - get(): SessionContext | null; - set(context: SessionContext): void; -} +export type SessionContextStore = Pick; export interface VerticalSliceState { sessionCode: string; @@ -30,14 +27,9 @@ export interface VerticalSliceController { startRound(sessionCode: string, categorySlug: string): Promise; } -const NOOP_SESSION_CONTEXT_STORE: SessionContextStore = { - get: () => null, - set: () => undefined -}; - export function createVerticalSliceController( api: ApiClient, - sessionContextStore: SessionContextStore = NOOP_SESSION_CONTEXT_STORE + sessionContextStore: SessionContextStore = createSessionContextStore() ): VerticalSliceController { const persistedContext = sessionContextStore.get(); @@ -96,11 +88,12 @@ export function createVerticalSliceController( state.joinState = 'success'; state.sessionCode = normalizeCode(join.data.session.code || requestCode); - sessionContextStore.set({ + const nextContext: SessionContextInput = { sessionCode: state.sessionCode, - playerToken: join.data.player.session_token, - nickname: join.data.player.nickname - }); + playerId: join.data.player.id, + token: join.data.player.session_token + }; + sessionContextStore.set(nextContext); return hydrateLobby(state.sessionCode); } @@ -131,3 +124,5 @@ export function createVerticalSliceController( startRound }; } + +export type { SessionContext }; diff --git a/frontend/tests/vertical-slice.test.ts b/frontend/tests/vertical-slice.test.ts index fd588b4..a8a256d 100644 --- a/frontend/tests/vertical-slice.test.ts +++ b/frontend/tests/vertical-slice.test.ts @@ -68,11 +68,43 @@ function makeSessionContextStore(initial: SessionContext | null = null): Session get: vi.fn(() => value), set: vi.fn((next: SessionContext) => { value = next; + return next; }) }; } describe('vertical slice controller: lobby -> join -> start round', () => { + it('uses createSessionContextStore by default (no manual injection)', async () => { + vi.resetModules(); + const defaultStore = { + get: vi.fn(() => null), + set: vi.fn((next: SessionContext) => next), + clear: vi.fn() + }; + + vi.doMock('../src/spa/session-context-store', async () => { + const actual = await vi.importActual('../src/spa/session-context-store'); + return { + ...actual, + createSessionContextStore: vi.fn(() => defaultStore) + }; + }); + + const { createVerticalSliceController: createControllerWithMock } = await import('../src/spa/vertical-slice'); + const api = makeApiMock(); + const controller = createControllerWithMock(api); + + await controller.joinLobby('ABCD12', 'Maja'); + + expect(defaultStore.set).toHaveBeenCalledWith({ + sessionCode: 'ABCD12', + playerId: 9, + token: 'token-1' + }); + + vi.doUnmock('../src/spa/session-context-store'); + vi.resetModules(); + }); it('tracks loading and success state for join + start flow', async () => { const api = makeApiMock(); const controller = createVerticalSliceController(api); @@ -102,8 +134,8 @@ describe('vertical slice controller: lobby -> join -> start round', () => { expect(sessionContextStore.set).toHaveBeenCalledWith({ sessionCode: 'ABCD12', - playerToken: 'token-1', - nickname: 'Maja' + playerId: 9, + token: 'token-1' }); expect(controller.getState().sessionCode).toBe('ABCD12'); }); @@ -112,8 +144,8 @@ describe('vertical slice controller: lobby -> join -> start round', () => { const api = makeApiMock(); const sessionContextStore = makeSessionContextStore({ sessionCode: 'wxyz99', - playerToken: 'token-old', - nickname: 'Maja' + playerId: 5, + token: 'token-old' }); const controller = createVerticalSliceController(api, sessionContextStore);