Files
AtreidesAssetsFree/tests/db/change-log.test.mjs
T

78 lines
3.4 KiB
JavaScript
Raw Normal View History

2026-10-29 11:57:29 +01:00
// Generated, do not edit. sha256:7e68bde59de6fb368899c1d7c4f191cb1a698e2a3f71f077372987a488b10794
import { describe, it, before, after } from 'node:test';
import assert from 'node:assert/strict';
import { openBaselineDb } from '../helpers/baseline-db.mjs';
import { CONFIG, ENUMS } from '../../shared/config.js';
let db;
const NU = '2026-09-07T12:00:00Z';
const schrijf = (over = {}) => {
const r = { tableName: 'Account', rowId: 1, operation: 'update', origin: 'manual',
originId: null, changes: '{"name":["a","b"]}', occurredAt: NU, ...over };
db.prepare(`INSERT INTO ChangeLog (tableName, rowId, operation, origin, originId, changes, occurredAt)
VALUES (?, ?, ?, ?, ?, ?, ?)`)
.run(r.tableName, r.rowId, r.operation, r.origin, r.originId, r.changes, r.occurredAt);
};
before(() => { db = openBaselineDb(); });
after(() => db.close());
describe('ChangeLog: wat de tabel accepteert', () => {
it('neemt een gewone wijziging aan', () => {
schrijf({ rowId: 101 });
const r = db.prepare(`SELECT * FROM ChangeLog WHERE rowId = 101`).get();
assert.equal(r.operation, 'update');
assert.equal(r.originId, null, 'een handmatige wijziging heeft geen rij die hem aanwijst');
});
it('neemt een verwijdering aan, met de hele rij in changes', () => {
schrijf({ rowId: 102, operation: 'delete', changes: '{"id":102,"name":"Kluis","kind":"vault"}' });
const r = db.prepare(`SELECT operation, changes FROM ChangeLog WHERE rowId = 102`).get();
assert.equal(r.operation, 'delete');
assert.deepEqual(JSON.parse(r.changes).name, 'Kluis');
});
it('neemt elke herkomst uit de enum aan', () => {
for (const [i, origin] of ENUMS.CHANGE_ORIGIN.entries()) {
schrijf({ rowId: 200 + i, origin });
}
const n = db.prepare(`SELECT COUNT(*) AS n FROM ChangeLog WHERE rowId >= 200 AND rowId < 300`).get().n;
assert.equal(n, ENUMS.CHANGE_ORIGIN.length);
});
it('weigert een insert-regel, want die bestaat niet', () => {
assert.throws(() => schrijf({ rowId: 301, operation: 'insert' }), /CHECK/i,
'een nieuw record heeft zijn eigen createdAt; dat levert geen logboekregel op');
});
it('weigert een onbekende herkomst', () => {
assert.throws(() => schrijf({ rowId: 302, origin: 'zomaar' }), /CHECK/i);
});
it('weigert een regel zonder tabel, rij, herkomst of moment', () => {
assert.throws(() => schrijf({ rowId: 303, tableName: null }), /NOT NULL/i);
assert.throws(() => schrijf({ rowId: null }), /NOT NULL/i);
assert.throws(() => schrijf({ rowId: 304, origin: null }), /NOT NULL/i);
assert.throws(() => schrijf({ rowId: 305, occurredAt: null }), /NOT NULL/i);
assert.throws(() => schrijf({ rowId: 306, changes: null }), /NOT NULL/i);
});
});
describe('ChangeLog: hoe hij in de registers staat', () => {
it('staat als append-only logboek buiten de verwijderbare tabellen', () => {
assert.ok(CONFIG.DB_TABLES.includes('ChangeLog'));
assert.ok(!CONFIG.DB_DELETABLE_TABLES.includes('ChangeLog'));
});
it('doet zelf niet mee in het logboek', () => {
assert.equal(CONFIG.DB_HISTORY.UNTRACKED.ChangeLog, 'logboek');
assert.ok(!CONFIG.DB_HISTORY.TRACKED.includes('ChangeLog'), 'een logboek van een logboek zegt niets');
});
it('deelt `changes` niet met de AI', async () => {
const { FIELD_POLICY } = await import('../../server/ai/policy.js');
assert.equal(FIELD_POLICY.changes, 'drop');
assert.equal(FIELD_POLICY.rowId, 'handle', 'een verwijzing, geen getal');
});
});