import { afterAll, beforeEach, describe, expect, it } from 'vitest'; import { fileURLToPath } from 'node:url'; import { allTerritoryKeys, expandCountriesToKeys, hasRegionData, loadRegions, referenceForKeys, regionName, resetRegions, validKeys, } from './regions'; import type { GameState } from '../shared/types'; // The repo root: this file lives in server/, so '..' is the directory holding // public/region-keys.json and public/regions.geo.json. cwd-independent (mirrors // how server/index.ts locates its root via import.meta.url). const root = fileURLToPath(new URL('..', import.meta.url)); describe('regions (region-key loader, v0.19 #16 P1)', () => { beforeEach(() => { expect(loadRegions(root)).toBe(true); }); it('loads the full manifest: 1,796 unique valid region keys', () => { expect(hasRegionData()).toBe(true); expect(validKeys().size).toBe(1796); }); it('expands an ISO_A3 country to the region keys of all its sub-regions', () => { const fra = expandCountriesToKeys(['FRA']); // FRA has 42 sub-regions in the committed dataset. expect(fra).toHaveLength(42); // every expanded key is a real region key for (const k of fra) expect(validKeys().has(k)).toBe(true); // and the reference table labels each one with its parent country const ref = referenceForKeys(fra); expect(Object.keys(ref)).toHaveLength(42); for (const [k, label] of Object.entries(ref)) { expect(label.endsWith('(FRA)')).toBe(true); expect(regionName(k)).toBeTruthy(); } // sample known FRA keys, and their exact reference strings expect(fra).toContain('ain-lqtt'); expect(ref['ain-lqtt']).toBe('Ain (FRA)'); expect(ref['aisne-gstu']).toBe('Aisne (FRA)'); }); it('referenceForKeys labels only known keys and omits unknown ones', () => { const ref = referenceForKeys(['ain-lqtt', 'not-a-real-key-xyz']); expect(ref['ain-lqtt']).toBe('Ain (FRA)'); expect(ref['not-a-real-key-xyz']).toBeUndefined(); }); it('allTerritoryKeys unions every nation\'s territory keys (no overlap)', () => { const state: GameState = { id: 'g', presetId: 'p', presetTitle: 'P', playerNationId: 'uk', turn: 1, date: '1939-09-01', nations: { uk: { id: 'uk', name: 'UK', type: 'major', stats: { military: 80, economy: 70, stability: 60, population: 50 }, territory: expandCountriesToKeys(['GBR']), relations: {}, }, fr: { id: 'fr', name: 'FR', type: 'major', stats: { military: 80, economy: 70, stability: 60, population: 50 }, territory: expandCountriesToKeys(['FRA']), relations: {}, }, }, events: [], pending: [], version: 1, }; // 16 GBR sub-regions + 42 FRA sub-regions, no overlap between the two. expect(allTerritoryKeys(state).size).toBe(58); }); describe('graceful degradation with no region data', () => { beforeEach(() => resetRegions()); it('expands to the raw input, omits references, and reports no data', () => { expect(hasRegionData()).toBe(false); // no manifest -> the country list passes through unchanged (old model) expect(expandCountriesToKeys(['FRA', 'GBR'])).toEqual(['FRA', 'GBR']); expect(referenceForKeys(['FRA'])).toEqual({}); expect(validKeys().size).toBe(0); expect(regionName('FRA')).toBeUndefined(); }); }); afterAll(() => resetRegions()); });