From 749997a8fb94ac1c0b41c1baa9bd0bd43fe484df Mon Sep 17 00:00:00 2001 From: Asger Geel Weirsoee Date: Sun, 1 Mar 2026 13:32:17 +0000 Subject: [PATCH] fix(spa): guard empty session code before hydrate/start --- frontend/src/spa/vertical-slice.ts | 12 ++++++++++++ frontend/tests/vertical-slice.test.ts | 24 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/frontend/src/spa/vertical-slice.ts b/frontend/src/spa/vertical-slice.ts index f951e06..9e901f3 100644 --- a/frontend/src/spa/vertical-slice.ts +++ b/frontend/src/spa/vertical-slice.ts @@ -52,6 +52,12 @@ export function createVerticalSliceController( const fallbackCode = normalizeCode(state.sessionCode || persistedContext?.sessionCode || ''); state.sessionCode = normalizedRequestedCode || fallbackCode; + if (!state.sessionCode) { + state.loadingSession = false; + state.errorMessage = 'Session-kode mangler.'; + return { ...state }; + } + const result = await api.getSession(state.sessionCode); state.loadingSession = false; @@ -106,6 +112,12 @@ export function createVerticalSliceController( const fallbackCode = normalizeCode(state.sessionCode || persistedContext?.sessionCode || ''); const codeToUse = normalizedRequestedCode || fallbackCode; + if (!codeToUse) { + state.startRoundState = 'error'; + state.errorMessage = 'Session-kode mangler.'; + return { ...state }; + } + const start = await api.startRound(codeToUse, { category_slug: categorySlug }); if (!start.ok) { state.startRoundState = 'error'; diff --git a/frontend/tests/vertical-slice.test.ts b/frontend/tests/vertical-slice.test.ts index a8a256d..7c4c521 100644 --- a/frontend/tests/vertical-slice.test.ts +++ b/frontend/tests/vertical-slice.test.ts @@ -189,6 +189,30 @@ describe('vertical slice controller: lobby -> join -> start round', () => { expect(state.errorMessage).toContain('Kunne ikke starte runden'); }); + it('shows local validation error and avoids API call when hydrating without any session code', async () => { + const api = makeApiMock(); + const controller = createVerticalSliceController(api, makeSessionContextStore(null)); + + await controller.hydrateLobby(' '); + + const state = controller.getState(); + expect(state.errorMessage).toBe('Session-kode mangler.'); + expect(state.loadingSession).toBe(false); + expect(api.getSession).not.toHaveBeenCalled(); + }); + + it('shows local validation error and avoids API call when starting round without any session code', async () => { + const api = makeApiMock(); + const controller = createVerticalSliceController(api, makeSessionContextStore(null)); + + await controller.startRound(' ', 'history'); + + const state = controller.getState(); + expect(state.startRoundState).toBe('error'); + expect(state.errorMessage).toBe('Session-kode mangler.'); + expect(api.startRound).not.toHaveBeenCalled(); + }); + it('uses joined session code when starting round without a reload', async () => { const api = makeApiMock(); const controller = createVerticalSliceController(api);