import { readFile } from 'node:fs/promises'; import { describe, expect, it } from 'vitest'; import { normalizeArchivedGeneral, type ArchivedJsonValue } from '@sammo-ts/common'; const fixture = async (name: string): Promise => JSON.parse(await readFile(new URL(`./fixtures/${name}`, import.meta.url), 'utf8')) as ArchivedJsonValue; describe('normalizeArchivedGeneral', () => { it('normalizes the sanitized CHE legacy-flat keyset without leaking connection metadata', async () => { const { sourceFormat, snapshot } = normalizeArchivedGeneral( await fixture('che-old-general-legacy-flat-v0.json'), 'fallback' ); expect(sourceFormat).toBe('legacy-flat-v0'); expect(snapshot).toMatchObject({ schemaVersion: 1, identity: { name: '구형테스트장수', nationId: 3 }, stats: { leadership: 81, strength: 73, intelligence: 66 }, mastery: { infantry: 101, archery: 202, cavalry: 303, special: 404, siege: 505 }, battle: { battles: 20, wins: 12, losses: 8, winRate: 60, killRate: 125, tactics: { total: { wins: 3, draws: 1, losses: 2 } }, }, history: ['●첫 기록', '●둘째 기록'], availability: { mastery: true, battleAggregates: true, tactics: true }, }); expect(JSON.stringify(snapshot)).not.toMatch(/"(?:ip|lastconnect|refresh)"/iu); }); it('normalizes the sanitized HWE ref-flat keyset and marks absent battle records unavailable', async () => { const { sourceFormat, snapshot } = normalizeArchivedGeneral( await fixture('hwe-old-general-ref-flat-v1.json'), 'fallback' ); expect(sourceFormat).toBe('ref-flat-v1'); expect(snapshot).toMatchObject({ identity: { name: '신형테스트장수', officerLevel: 7 }, stats: { leadership: 91, strength: 82, intelligence: 74, leadershipExperience: 11, }, traits: { personality: 'che_의리', specialDomestic: 'che_상재', specialWar: 'che_신산' }, mastery: { infantry: 111, archery: 222, cavalry: 333, special: 444, siege: 555 }, battle: { battles: null, wins: null, losses: null, winRate: null, killRate: null }, availability: { mastery: true, battleAggregates: false, tactics: false }, }); expect(snapshot.availability.battleDetailLogs).toBe(false); expect(snapshot.availability.battleResultLogs).toBe(false); }); it('keeps an already-normalized version 1 snapshot stable', async () => { const first = normalizeArchivedGeneral(await fixture('che-old-general-legacy-flat-v0.json'), 'fallback'); const second = normalizeArchivedGeneral( first.snapshot as unknown as ArchivedJsonValue, first.snapshot.identity.name ); expect(second.sourceFormat).toBe('core-snapshot-v1'); expect(second.snapshot).toEqual(first.snapshot); }); });