63 lines
1.8 KiB
JavaScript
63 lines
1.8 KiB
JavaScript
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);
|
|
});
|