← back to Desktop Dotbar
test/ticket-states.test.js
53 lines
'use strict';
// ticket-states: the bar must ALWAYS carry all five ticket states plus the dw / non-dw pair
// (Steve 2026-09-25 x2), and an unreachable board must read as NOT-MEASURED — never as hidden,
// never as a fake 0. Zero deps.
const test = require('node:test');
const assert = require('node:assert');
const { ticketStates, TICKET_STATES } = require('../ticket-states');
const KEYS = ['blocked', 'open', 'idle', 'doing', 'parked', 'dw', 'nondw'];
test('healthy board: every state + the dw/non-dw pair, with measured counts, zeros kept', () => {
const s = ticketStates({ updated: Date.now(), ok: true, blocked: 78, open: 33, idle: 0, doing: 20, parked: 5, dw: 115, nondw: 21 });
assert.deepEqual(s.map(x => x.key), KEYS);
assert.deepEqual(s.map(x => x.n), [78, 33, 0, 20, 5, 115, 21]);
assert.equal(s.find(x => x.key === 'dw').section, 'dw');
assert.equal(s.find(x => x.key === 'nondw').section, 'nondw', 'non-dw drills into the board Non-DW section');
const idle = s.find(x => x.key === 'idle');
assert.equal(idle.zero, true, 'a zero state is KEPT (dimmed), not dropped');
assert.equal(s.find(x => x.key === 'idle').section, 'stopped', 'idle opens the board stopped section');
});
// NEGATIVE (fault-injection): the exact 2026-09-25 failure — ticket-board down after a reboot.
test('NEGATIVE: never-fetched board -> every chip NOT-measured (null, not 0), dw/non-dw included', () => {
const s = ticketStates({ updated: 0, ok: false, blocked: 0, open: 0, idle: 0, doing: 0, parked: 0, dw: 0, nondw: 0 });
assert.equal(s.length, KEYS.length, 'row must not disappear when the board is down');
for (const x of s) {
assert.strictEqual(x.n, null, `${x.key} must be null (unmeasured), got ${x.n}`);
assert.equal(x.measured, false);
}
});
test('NEGATIVE: board went down after a good fetch -> stale counts are NOT presented as measured', () => {
const s = ticketStates({ updated: Date.now() - 60000, ok: false, blocked: 78, open: 33, idle: 4, doing: 20, parked: 5, dw: 115, nondw: 21 });
assert.ok(s.every(x => x.n === null), 'ok:false must blank the counts to "–"');
});
// The dw/non-dw pair is a SECOND cut of the same population, so it must reconcile with the first.
// If it ever does not, one of the two is counting a different set and the row is lying.
test('dw + non-dw reconciles with the five state counts', () => {
const snap = { updated: Date.now(), ok: true, blocked: 78, open: 33, idle: 4, doing: 20, parked: 5, dw: 115, nondw: 25 };
const s = ticketStates(snap);
const byState = ['blocked', 'open', 'idle', 'doing', 'parked'].reduce((a, k) => a + snap[k], 0);
const bySeg = s.filter(x => x.key === 'dw' || x.key === 'nondw').reduce((a, x) => a + x.n, 0);
assert.equal(bySeg, byState, 'dw + non-dw must partition exactly the population the states count');
});
test('missing/garbage snapshot never throws and still yields every chip', () => {
for (const snap of [undefined, null, {}, { updated: 1, ok: true, blocked: 'x' }]) {
const s = ticketStates(snap);
assert.equal(s.length, TICKET_STATES.length);
}
});