'use strict'; const test = require('node:test'); const assert = require('node:assert/strict'); const DashboardApi = require('../../src/specificClass.js'); const handlers = require('../../src/commands/handlers.js'); function makeCtx(sends, nodeId = 'dApi-1') { return { node: { id: nodeId }, RED: { nodes: { getNode: () => null } }, send: (m) => sends.push(m), logger: null, }; } function makeChildPayload(id, softwareType = 'measurement') { return { config: { general: { id, name: id }, functionality: { softwareType, positionVsParent: 'downstream' }, }, }; } test('recordChild caches child source by id; subsequent ones replace by id', () => { const api = new DashboardApi({}); api.recordChild(makeChildPayload('a')); api.recordChild(makeChildPayload('b')); api.recordChild(makeChildPayload('a')); // replace assert.equal(api.cachedChildSources().length, 2); }); test('regenerate-dashboard with no cached children is a no-op (no msgs emitted)', async () => { const api = new DashboardApi({}); const sends = []; await handlers.regenerateDashboard(api, { topic: 'regenerate-dashboard', payload: {} }, makeCtx(sends)); assert.equal(sends.length, 0); }); test('regenerate-dashboard re-emits for each cached child, bypassing diff', async () => { const api = new DashboardApi({}); // Pre-populate cache as if two children had registered. api.recordChild(makeChildPayload('m-1')); api.recordChild(makeChildPayload('m-2')); // Set a diff that says nothing changed — registerChild would skip, but // regenerateDashboard should ignore the predicate. api.lastFlowsStartedDiff = { added: [], changed: [], removed: [], rewired: [] }; const sends = []; await handlers.regenerateDashboard(api, { topic: 'regenerate-dashboard', payload: {} }, makeCtx(sends)); // Each child yields at least one dashboard message (the root for the child's view). assert.ok(sends.length >= 2, `expected ≥2 emitted msgs, got ${sends.length}`); // Every emitted msg carries trigger: 'manual' in meta. for (const m of sends) assert.equal(m.meta?.trigger, 'manual'); }); test('child.register stamps trigger: child.register in emitted msg meta', async () => { const api = new DashboardApi({}); api.lastFlowsStartedDiff = null; // cold-start → always regen const sends = []; await handlers.registerChild(api, { topic: 'child.register', payload: makeChildPayload('m-3') }, makeCtx(sends)); assert.ok(sends.length >= 1); for (const m of sends) assert.equal(m.meta?.trigger, 'child.register'); }); test('command registry exposes regenerate-dashboard with regen alias', () => { const registry = require('../../src/commands/index.js'); const entry = registry.find((e) => e.topic === 'regenerate-dashboard'); assert.ok(entry, 'topic registered'); assert.deepEqual(entry.aliases, ['regen']); assert.equal(typeof entry.handler, 'function'); });