feat(appdata): 增加归档导出校验脚本

This commit is contained in:
2026-07-08 16:42:40 +08:00
parent 36202028d2
commit 869b1c1060
7 changed files with 389 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import {
buildAppDataArchive,
verifyAppDataArchive,
} from './lib/appdata-archive.mjs';
test('builds and verifies an AppData archive with deterministic checksums', () => {
const archive = buildAppDataArchive(
[
{
key: 'dev-tasks',
value: [{ id: 'dt-1', title: '开发任务' }],
updatedAt: new Date('2026-07-08T08:00:00.000Z'),
},
{
key: 'products-overview',
value: [{ id: 'p1', name: 'FTB' }],
updatedAt: new Date('2026-07-08T08:01:00.000Z'),
},
],
{
appVersion: 'test-version',
appBuildTime: '2026-07-08T08:02:00.000Z',
exportedAt: '2026-07-08T08:03:00.000Z',
sourceCommit: 'test-commit',
},
);
assert.deepEqual(archive.keys, ['dev-tasks', 'products-overview']);
assert.equal(archive.metadata.rowCount, 2);
assert.equal(archive.metadata.keyCount, 2);
assert.match(archive.metadata.payloadChecksum, /^[a-f0-9]{64}$/);
const verification = verifyAppDataArchive(archive);
assert.equal(verification.ok, true);
assert.deepEqual(verification.errors, []);
});
test('verification fails when archived row content is tampered', () => {
const archive = buildAppDataArchive(
[
{
key: 'dev-tasks',
value: [{ id: 'dt-1', title: '开发任务' }],
updatedAt: new Date('2026-07-08T08:00:00.000Z'),
},
],
{
appVersion: 'test-version',
appBuildTime: '2026-07-08T08:02:00.000Z',
exportedAt: '2026-07-08T08:03:00.000Z',
sourceCommit: 'test-commit',
},
);
archive.rows[0].value[0].title = '被篡改';
const verification = verifyAppDataArchive(archive);
assert.equal(verification.ok, false);
assert.match(verification.errors.join('\n'), /checksum/i);
});