feat: 레거시 재이관과 계정 복구 기반을 추가
중앙 이전 기록 스키마와 버전 정규화기를 도입하고, 재실행 시 현행 계정 상태를 보존한다. 카카오 인증 뒤 이관 비밀번호를 1회 설정하는 흐름과 비카카오 계정용 안전한 CLI 복구 경로를 추가한다.
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
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<ArchivedJsonValue> =>
|
||||
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: ['<C>●</>첫 기록', '<Y>●</>둘째 기록'],
|
||||
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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user