Files
weirsoe-party-protocol/frontend/tests/lobby-i18n.contract.test.ts
Asger Geel Weirsoee 3398aead7f
All checks were successful
CI / test-and-quality (push) Successful in 3m57s
CI / test-and-quality (pull_request) Successful in 4m1s
frontend: consume shared backend->frontend error map at runtime
2026-03-01 22:49:49 +00:00

69 lines
2.8 KiB
TypeScript

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 at runtime even when fallback key differs', () => {
expect(
lobbyMessageFromApiPayload(
{ error_code: 'session_not_joinable', locale: 'da' },
'start_round_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.');
});
});