import { describe, expect, it } from 'vitest'; import lobbyCatalog from '../../shared/i18n/lobby.json'; import { lobbyMessage, lobbyMessageFromApiPayload } from '../src/spa/lobby-i18n'; describe('shared i18n keyspace contract', () => { it('keeps en as default and da/en matrix for frontend error keys', () => { expect(lobbyCatalog.locales.default).toBe('en'); expect(lobbyCatalog.locales.supported).toEqual(expect.arrayContaining(['en', 'da'])); for (const [key, translations] of Object.entries(lobbyCatalog.frontend.errors)) { expect(translations.en, `${key} missing en`).toBeTruthy(); expect(translations.da, `${key} missing da`).toBeTruthy(); } }); it('keeps backend error-code keyspace aligned with shared backend→frontend map and backend translations', () => { for (const [code, backendKey] of Object.entries(lobbyCatalog.backend.error_codes)) { const frontendKey = lobbyCatalog.contract.backend_to_frontend_error_keys[ code as keyof typeof lobbyCatalog.contract.backend_to_frontend_error_keys ]; expect(lobbyCatalog.backend.errors[backendKey as keyof typeof lobbyCatalog.backend.errors]).toBeDefined(); expect(frontendKey, `missing frontend mapping for ${code}`).toBeTruthy(); expect(lobbyCatalog.frontend.errors[frontendKey as keyof typeof lobbyCatalog.frontend.errors]).toBeDefined(); } for (const [key, translations] of Object.entries(lobbyCatalog.backend.errors)) { expect(translations.en, `${key} missing en`).toBeTruthy(); expect(translations.da, `${key} missing da`).toBeTruthy(); } }); }); describe('lobbyMessage locale handling', () => { it('uses english by default and falls back to default for unsupported locale', () => { expect(lobbyMessage('session_code_required')).toBe('Session code is required.'); expect(lobbyMessage('session_code_required', 'fr')).toBe('Session code is required.'); }); it('resolves locale from api payload and maps known backend error codes directly', () => { expect( lobbyMessageFromApiPayload( { error_code: 'session_not_found', locale: 'da' }, 'join_failed', ), ).toBe('Sessionskoden er ugyldig, eller sessionen findes ikke længere.'); }); it('uses shared backend→frontend key-map when backend key differs from frontend copy key', () => { expect( lobbyMessageFromApiPayload( { error_code: 'session_not_joinable', locale: 'da' }, 'join_failed', ), ).toBe('Kunne ikke joine. Tjek kode eller kaldenavn og prøv igen.'); }); it('falls back to caller-provided fallback key for unknown backend error codes', () => { expect( lobbyMessageFromApiPayload( { error_code: 'unknown_backend_key', locale: 'da' }, 'join_failed', ), ).toBe('Kunne ikke joine. Tjek kode eller kaldenavn og prøv igen.'); }); });