173 lines
6.3 KiB
JavaScript
173 lines
6.3 KiB
JavaScript
// Generated, do not edit. sha256:a27e8c58c9aae75ab07e5381309139cb5309819db52788dbf42ff055ad51599e
|
|
import { describe, it, beforeEach, mock } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
|
|
import { createDbHarness } from '../helpers/db-node.mjs';
|
|
|
|
const harness = createDbHarness();
|
|
mock.module('../../server/db.js', { namedExports: harness.exports });
|
|
|
|
const { flushChanges, changesSince, pruneChanges } = await import('../../server/data/bus.js');
|
|
const { emitChange } = await import('../../server/data/_events.js');
|
|
const { CONFIG } = await import('../../shared/config.js');
|
|
|
|
const rijen = () => harness.exports.all(`SELECT id, name, occurredAt FROM BusSignal ORDER BY id`);
|
|
|
|
const oudeRij = (naam, urenGeleden) => harness.exports.run(
|
|
`INSERT INTO BusSignal (name, occurredAt) VALUES (?,?)`,
|
|
[naam, new Date(Date.now() - urenGeleden * 3600_000).toISOString()]);
|
|
|
|
beforeEach(() => {
|
|
harness.recreate();
|
|
flushChanges();
|
|
});
|
|
|
|
describe('bus: het mandje wegschrijven', () => {
|
|
it('schrijft elke naam uit het mandje naar de tabel', async () => {
|
|
emitChange('providers-changed');
|
|
emitChange('connections-changed');
|
|
const namen = flushChanges();
|
|
assert.deepEqual(namen.sort(), ['connections-changed', 'providers-changed']);
|
|
assert.deepEqual(rijen().map(r => r.name).sort(), ['connections-changed', 'providers-changed']);
|
|
assert.ok(rijen()[0].occurredAt, 'en er staat een moment bij');
|
|
});
|
|
|
|
it('voegt hetzelfde signaal binnen één eenheid werk samen', async () => {
|
|
emitChange('providers-changed');
|
|
emitChange('providers-changed');
|
|
emitChange('providers-changed');
|
|
flushChanges();
|
|
assert.equal(rijen().length, 1);
|
|
});
|
|
|
|
it('maakt het mandje leeg, zodat een tweede flush niets dubbel schrijft', async () => {
|
|
emitChange('providers-changed');
|
|
flushChanges();
|
|
assert.deepEqual(flushChanges(), [], 'niets meer over');
|
|
assert.equal(rijen().length, 1);
|
|
});
|
|
|
|
it('doet niets bij een leeg mandje, en schrijft dus ook geen lege rij', async () => {
|
|
assert.deepEqual(flushChanges(), []);
|
|
assert.equal(rijen().length, 0);
|
|
});
|
|
|
|
it('GOOIT NOOIT WEG: twee opeenvolgende flushes bewaren allebei hun signaal', async () => {
|
|
emitChange('eerst-dit');
|
|
flushChanges();
|
|
emitChange('daarna-dit');
|
|
flushChanges();
|
|
assert.deepEqual(rijen().map(r => r.name), ['eerst-dit', 'daarna-dit'], 'allebei, op volgorde');
|
|
});
|
|
});
|
|
|
|
describe('bus: teruglezen sinds een cursor', () => {
|
|
it('geeft bij een nieuwe client alleen de stand en geen historie', async () => {
|
|
emitChange('oud-nieuws');
|
|
flushChanges();
|
|
const r = changesSince(null);
|
|
assert.deepEqual(r.names, []);
|
|
assert.equal(r.cursor, 1, 'wél de stand, zodat de volgende poll wél iets kan opleveren');
|
|
assert.equal(r.reset, false);
|
|
});
|
|
|
|
it('geeft alleen wat er ná de cursor bij kwam', async () => {
|
|
emitChange('eerste');
|
|
flushChanges();
|
|
const na1 = changesSince(null).cursor;
|
|
emitChange('tweede');
|
|
flushChanges();
|
|
const r = changesSince(na1);
|
|
assert.deepEqual(r.names, ['tweede']);
|
|
assert.equal(r.cursor, 2);
|
|
});
|
|
|
|
it('ontdubbelt de namen, want een prikkel is inhoudsloos', async () => {
|
|
emitChange('providers-changed');
|
|
flushChanges();
|
|
emitChange('providers-changed');
|
|
flushChanges();
|
|
assert.deepEqual(changesSince(0).names, ['providers-changed'], 'twee rijen, één naam');
|
|
});
|
|
|
|
it('geeft niets terug als er niets nieuws is, en houdt de cursor gelijk', async () => {
|
|
emitChange('iets');
|
|
flushChanges();
|
|
const r = changesSince(1);
|
|
assert.deepEqual(r.names, []);
|
|
assert.equal(r.cursor, 1);
|
|
});
|
|
|
|
it('zegt "ververs alles" als de cursor achterloopt op de oudste bewaarde rij', async () => {
|
|
for (const naam of ['een', 'twee', 'drie']) { emitChange(naam); flushChanges(); }
|
|
harness.exports.run(`DELETE FROM BusSignal WHERE id <= 2`);
|
|
const r = changesSince(0);
|
|
assert.equal(r.reset, true);
|
|
assert.deepEqual(r.names, [], 'en géén halve lijst erbij, die zou suggereren dat het daarbij blijft');
|
|
assert.equal(r.cursor, 3);
|
|
});
|
|
|
|
it('meldt geen reset als de cursor precies aansluit op de oudste rij', async () => {
|
|
for (const naam of ['een', 'twee', 'drie']) { emitChange(naam); flushChanges(); }
|
|
harness.exports.run(`DELETE FROM BusSignal WHERE id <= 2`);
|
|
const r = changesSince(2);
|
|
assert.equal(r.reset, false);
|
|
assert.deepEqual(r.names, ['drie']);
|
|
});
|
|
|
|
it('behandelt onzin als een nieuwe client in plaats van om te vallen', async () => {
|
|
emitChange('iets');
|
|
flushChanges();
|
|
for (const raar of ['onzin', -1, 1.5, undefined, {}]) {
|
|
const r = changesSince(raar);
|
|
assert.deepEqual(r.names, [], `${JSON.stringify(raar)} hoort als "ik begin nu" te lezen`);
|
|
assert.equal(r.reset, false);
|
|
}
|
|
});
|
|
|
|
it('geeft op een lege bus een cursor van nul en geen null', async () => {
|
|
const r = changesSince(null);
|
|
assert.deepEqual(r, { cursor: 0, names: [], reset: false });
|
|
});
|
|
});
|
|
|
|
describe('bus: opruimen', () => {
|
|
it('gooit weg wat ouder is dan de bewaartermijn en laat de rest staan', async () => {
|
|
oudeRij('van-gisteren', CONFIG.BUS.RETENTION_HOURS + 1);
|
|
oudeRij('van-net', 1);
|
|
assert.equal(pruneChanges(), 1, 'geeft terug hoeveel er weg zijn');
|
|
assert.deepEqual(rijen().map(r => r.name), ['van-net']);
|
|
});
|
|
|
|
it('laat een rij die binnen de termijn valt staan', async () => {
|
|
oudeRij('net-binnen', CONFIG.BUS.RETENTION_HOURS - 1);
|
|
assert.equal(pruneChanges(), 0);
|
|
assert.equal(rijen().length, 1);
|
|
});
|
|
|
|
it('doet niets op een lege bus', async () => {
|
|
assert.equal(pruneChanges(), 0);
|
|
});
|
|
|
|
it('valt terug op de SSOT-waarde bij onzin', async () => {
|
|
oudeRij('oud', CONFIG.BUS.RETENTION_HOURS + 2);
|
|
assert.equal(pruneChanges('onzin'), 1);
|
|
});
|
|
|
|
it('ruimt op tijdens het wegschrijven, zonder dat de aanroeper er iets voor doet', async () => {
|
|
oudeRij('van-gisteren', CONFIG.BUS.RETENTION_HOURS + 1);
|
|
emitChange('nieuw');
|
|
flushChanges();
|
|
assert.deepEqual(rijen().map(r => r.name), ['nieuw'], 'de oude rij is meegenomen');
|
|
});
|
|
|
|
it('ruimt bij élke schrijfactie op, ook de tweede', async () => {
|
|
emitChange('eerste');
|
|
flushChanges();
|
|
oudeRij('van-gisteren', CONFIG.BUS.RETENTION_HOURS + 1);
|
|
emitChange('tweede');
|
|
flushChanges();
|
|
assert.equal(rijen().some(r => r.name === 'van-gisteren'), false, 'ook nu meegenomen');
|
|
});
|
|
});
|