Files
cinny/src/app/utils/dataExport.test.ts
T

77 lines
3.0 KiB
TypeScript
Raw Normal View History

import { test } from 'node:test';
import assert from 'node:assert/strict';
import { buildExport, mergeData, parseExport, planImport } from './dataExport';
const file = buildExport({
userId: '@a:hs',
accountData: {
'io.lotus.bookmarks': { bookmarks: [{ id: 'b1', note: 'x' }] },
'io.lotus.user_notes': { notes: { '@b:hs': 'met at LAN party' } },
'm.direct': { secret: true },
'io.lotus.settings': { theme: 'dark', fontSize: 16 },
},
decoration: 'halo',
localSettings: { callNoiseSuppression: 'ml' },
now: new Date('2026-10-25T00:00:00Z'),
});
test('[#114] export keeps only our own types', () => {
assert.equal(file.format, 'lotus-chat-data');
assert.equal(file.version, 1);
assert.deepEqual(Object.keys(file.accountData).sort(), [
'io.lotus.bookmarks',
'io.lotus.settings',
'io.lotus.user_notes',
]);
assert.equal(file.profile.decoration, 'halo');
});
test('[#114] parse: round trip, wrong files, newer versions, foreign types', () => {
const r = parseExport(JSON.stringify(file));
assert.ok(r.ok);
assert.equal(parseExport('nope').ok, false);
assert.equal(parseExport('{"format":"other"}').ok, false);
const newer = parseExport(JSON.stringify({ ...file, version: 2 }));
assert.ok(!newer.ok && /newer Lotus Chat/.test(newer.error));
const sneaky = parseExport(
JSON.stringify({ ...file, accountData: { 'm.push_rules': {}, 'io.lotus.bookmarks': {} } }),
);
assert.ok(sneaky.ok);
assert.deepEqual(Object.keys(sneaky.file.accountData), ['io.lotus.bookmarks']);
});
test('[#114] merge: lists by id, maps by key, conflicts kept unless preferred', () => {
const mine = { bookmarks: [{ id: 'b1', note: 'mine' }, { id: 'b2' }] };
const theirs = { bookmarks: [{ id: 'b1', note: 'theirs' }, { id: 'b3' }] };
const keep = mergeData(mine, theirs);
assert.equal(keep.added, 1);
assert.equal(keep.conflicts, 1);
assert.deepEqual(keep.value, {
bookmarks: [{ id: 'b1', note: 'mine' }, { id: 'b2' }, { id: 'b3' }],
});
const take = mergeData(mine, theirs, true);
assert.deepEqual((take.value as typeof mine).bookmarks[0], { id: 'b1', note: 'theirs' });
const notes = mergeData({ a: 1, b: 2 }, { b: 3, c: 4 });
assert.deepEqual(notes, { value: { a: 1, b: 2, c: 4 }, added: 1, conflicts: 1 });
assert.deepEqual(mergeData(undefined, { x: 1 }), { value: { x: 1 }, added: 1, conflicts: 0 });
assert.deepEqual(mergeData(['a'], ['a', 'b']).value, ['a', 'b']);
});
test('[#114] plan summarises per category', () => {
const plan = planImport(file, {
accountData: { 'io.lotus.settings': { theme: 'light' } },
decoration: null,
localSettings: { callNoiseSuppression: 'ml' },
});
const by = Object.fromEntries(plan.map((p) => [p.key, p]));
assert.deepEqual(
[by['io.lotus.settings'].added, by['io.lotus.settings'].conflicts],
[1, 1],
'fontSize new, theme differs',
);
assert.equal(by['io.lotus.bookmarks'].added, 1);
assert.equal(by['profile.decoration'].added, 1);
assert.deepEqual([by['local.settings'].added, by['local.settings'].conflicts], [0, 0]);
});