// Golden-ish tests for services/renderers/{phone,av}StatusRenderer.js // // True byte-for-byte golden strings aren't practical because both // renderers call `simpleTimeAgo` (which uses `Date.now()`). Instead we // assert on structural properties AND on the exact assembly of key // lines — enough to catch a regression like "we lost the Meraki // `[Meraki↗](url)` link" or "the header format changed" but robust to // time-of-day drift. import test from 'node:test'; import assert from 'node:assert/strict'; import { renderPhoneStatusMarkdown, renderDectDiagnosticsMarkdown, } from '../services/renderers/phoneStatusRenderer.js'; import { renderAvStatusMarkdown } from '../services/renderers/avStatusRenderer.js'; import { renderDectStatusMarkdown } from '../services/renderers/dectStatusRenderer.js'; // Timestamp exactly 3 hours in the past — makes `simpleTimeAgo` // deterministic to "3 hours ago" for the duration of this test run. const threeHrAgo = () => new Date(Date.now() - 3 * 60 * 60 * 1000).toISOString(); test('phone renderer: header and empty-store message', () => { const md = renderPhoneStatusMarkdown({}, { storeNum: '782' }); assert.match(md, /^\*\*Phone Status - Store 782\*\*/); assert.match(md, /No phones or DECT basestations found/); }); test('phone renderer: full desk-phone entry preserves Meraki link', () => { const data = { phones: { data: [{ displayName: 'PHONE 782-1', status: 'connected', lastSeen: threeHrAgo(), firmware: '12.0.4', serial: 'ABC12345', meraki: { switchName: 'STORE-782-SW1', status: 'Online', port: '17', vlan: '20', ip: '10.1.1.5', lastSeen: threeHrAgo(), clientUrl: 'https://n123.meraki.com/example/manage/clients/abc/overview', usage: { sent: 1024, recv: 4096 }, }, }], }, telephonyProfile: { timeZone: 'America/New_York' }, locationMainNumber: '+14125550100', }; const md = renderPhoneStatusMarkdown(data, { storeNum: '782', footer: false }); // Header lines the poller cares about assert.match(md, /\*\*Timezone:\*\* America\/New_York/); assert.match(md, /\*\*PhoneNumber:\*\* \+14125550100/); // Bold device name assert.match(md, /\*\*PHONE 782-1\*\*/); // Firmware / serial line assert.match(md, /FW: 12\.0\.4 • Serial: ABC12345/); // Meraki port info + link — the whole reason we ripped out the codeBlock assert.match(md, /\*\*STORE-782-SW1\*\*/); assert.match(md, /\[Meraki↗\]\(https:\/\/n123\.meraki\.com\/example\/manage\/clients\/abc\/overview\)/); // Data usage assert.match(md, /Data \(recent\): 1 KB sent \/ 4 KB recv/); // No footer when opts.footer is false — Jira uses this mode assert.doesNotMatch(md, /Last checked/); }); test('phone renderer: footer appears when opts.footer=true (default) on non-empty data', () => { // The empty-store branch legitimately returns early with no footer // — that matches the chat handler's historical behavior. Feed a // minimal populated fixture to exercise the footer path. const data = { phones: { data: [{ displayName: 'X', status: 'connected', lastSeen: threeHrAgo() }], }, }; const md = renderPhoneStatusMarkdown(data, { storeNum: '782' }); assert.match(md, /Last checked:/); }); test('phone renderer: detailed mode reveals SIP details', () => { const data = { phones: { data: [{ displayName: 'PHONE 782-2', status: 'connected', lastSeen: threeHrAgo(), primarySipUrl: 'sip:782-2@aeo2go.webex.com', sipUrls: ['sip:a@x', 'sip:b@x', 'sip:c@x'], }], }, }; const compact = renderPhoneStatusMarkdown(data, { storeNum: '782', detailed: false, footer: false }); const detailed = renderPhoneStatusMarkdown(data, { storeNum: '782', detailed: true, footer: false }); assert.doesNotMatch(compact, /SIP: sip:782-2/); assert.match(detailed, /SIP: sip:782-2@aeo2go\.webex\.com/); assert.match(detailed, /Alt SIPs: sip:a@x, sip:b@x…/); }); // ───────────────────────────────────────────────────────────── // IGMP snooping / DECT-safe multicast warning line // ───────────────────────────────────────────────────────────── test('phone renderer: multicast warning line includes every deviation kind', () => { const data = { dectBasestations: [ { mac: 'aa:bb:cc:dd:ee:ff', meraki: { status: 'Online' } }, ], dectHandsets: [], multicast: { needsFix: true, defaultSnoopOn: true, defaultFloodOff: true, deviatingOverrides: [{}, {}], }, }; const md = renderPhoneStatusMarkdown(data, { storeNum: '782', footer: false }); assert.match(md, /\*\*Multicast:\*\* ⚠️/); assert.match(md, /IGMP snoop=ON default/); assert.match(md, /flood-unknown=OFF default/); assert.match(md, /2 switch override\(s\) deviate/); assert.match(md, /may disrupt DECT/); }); test('phone renderer: multicast line names only the snoop deviation when that is the only problem', () => { const data = { dectBasestations: [ { mac: 'aa:bb:cc:dd:ee:ff', meraki: { status: 'Online' } }, ], dectHandsets: [], multicast: { needsFix: true, defaultSnoopOn: true, defaultFloodOff: false, deviatingOverrides: [], }, }; const md = renderPhoneStatusMarkdown(data, { storeNum: '782', footer: false }); assert.match(md, /\*\*Multicast:\*\* ⚠️ IGMP snoop=ON default — may disrupt DECT/); assert.doesNotMatch(md, /flood-unknown/); assert.doesNotMatch(md, /switch override/); }); test('phone renderer: multicast line is ABSENT when needsFix is false', () => { const data = { dectBasestations: [ { mac: 'aa:bb:cc:dd:ee:ff', meraki: { status: 'Online' } }, ], dectHandsets: [], multicast: { needsFix: false, defaultSnoopOn: false, defaultFloodOff: false, deviatingOverrides: [], }, }; const md = renderPhoneStatusMarkdown(data, { storeNum: '782', footer: false }); assert.doesNotMatch(md, /\*\*Multicast:\*\*/); }); test('phone renderer: multicast line is ABSENT when there are no DECT basestations', () => { // Even if needsFix is true, the warning lives INSIDE the DECT section // which itself is gated on dectBasestations.length > 0. Stores with // no DECT get no multicast noise — it's simply not their problem. const data = { phones: { data: [{ displayName: 'DESK', status: 'connected', lastSeen: threeHrAgo() }], }, dectBasestations: [], multicast: { needsFix: true, defaultSnoopOn: true, defaultFloodOff: true, deviatingOverrides: [{}], }, }; const md = renderPhoneStatusMarkdown(data, { storeNum: '782', footer: false }); assert.doesNotMatch(md, /\*\*Multicast:\*\*/); }); // ───────────────────────────────────────────────────────────── test('av renderer: header always says (Mode: detailed)', () => { const md = renderAvStatusMarkdown({}, { storeNum: '782', footer: false }); assert.match(md, /^\*\*Device Status - Store 782\*\* \(Mode: detailed\)/); }); test('av renderer: MDM entry with Meraki wired client preserves link', () => { const data = { mdm: { data: [{ friendlyName: 'STORE-782-KIOSK-1', lastSeen: threeHrAgo(), meraki: { deviceName: 'STORE-782-SW2', recentDeviceConnection: 'Wired', status: 'Online', clientStatus: 'Online', port: '4', vlan: '30', ip: '10.1.2.20', mac: 'aa:bb:cc:dd:ee:ff', lastSeen: threeHrAgo(), clientUrl: 'https://n123.meraki.com/example/manage/clients/xyz/overview', }, }], }, }; const md = renderAvStatusMarkdown(data, { storeNum: '782', footer: false }); assert.match(md, /\*\*STORE-782-KIOSK-1\*\*/); assert.match(md, /\*\*STORE-782-SW2 \(Wired - Online\)\*\*/); assert.match(md, /\[Meraki↗\]\(https:\/\/n123\.meraki\.com\/example\/manage\/clients\/xyz\/overview\)/); // Port line with double-arrow indent assert.match(md, / → → Port: \*\*4\*\*/); }); test('av renderer: absent MDM devices prints friendly message', () => { const md = renderAvStatusMarkdown({ mdm: { data: [] } }, { storeNum: '782', footer: false }); assert.match(md, /No MDM devices found for this store/); }); test('av renderer: Atlas AMP with vitals renders temps + fan + amps', () => { const data = { mdm: { data: [] }, atlas: { data: [{ name: 'US000782AMP', status: 'online', last_seen_at: new Date(Date.now() - 5 * 60 * 1000).toISOString(), model: { name: 'Atlas-4M' }, firmware: { version: '1.9.3' }, sn: 'SN-782-AMP', state: { voltageMonitor: '120.4', faultStatus: 0, tempCpu: '40', tempPsu: '35', tempIo: '38', fanSpeed: 45.7, ampStatus_1: 'Active', ampStatus_2: 'Ready', IpAddress: '10.1.9.9', }, }], }, }; const md = renderAvStatusMarkdown(data, { storeNum: '782', footer: false }); assert.match(md, /\*\*Atlas Devices:\*\*/); assert.match(md, /\*\*US000782AMP\*\* \(online\)/); assert.match(md, /Atlas-4M • FW 1\.9\.3 • SN SN-782-AMP • IP 10\.1\.9\.9/); assert.match(md, /CPU: 104°F • PSU: 95°F • Io: 100°F • Voltage: 120\.4V • Fan: 46%/); assert.match(md, /Amps: Amp1: Active, Amp2: Ready/); }); // ───────────────────────────────────────────────────────────── // DECT follow-up "loading" hint (main /phonestatus output) // ───────────────────────────────────────────────────────────── test('phone renderer: dectFollowUpBaseCount > 0 emits a loading hint inside the DECT section', () => { const data = { dectBasestations: [ { mac: 'aa:bb:cc:dd:ee:01', meraki: { status: 'Online' } }, { mac: 'aa:bb:cc:dd:ee:02', meraki: { status: 'Online' } }, ], dectHandsets: [], }; const md = renderPhoneStatusMarkdown(data, { storeNum: '782', footer: false, dectFollowUpBaseCount: 2, }); assert.match(md, /Base-station diagnostics loading for 2 bases/); }); test('phone renderer: dectFollowUpBaseCount === 1 uses singular "base"', () => { const data = { dectBasestations: [{ mac: 'aa:bb:cc:dd:ee:01', meraki: { status: 'Online' } }], dectHandsets: [], }; const md = renderPhoneStatusMarkdown(data, { storeNum: '782', footer: false, dectFollowUpBaseCount: 1, }); assert.match(md, /loading for 1 base —/); }); test('phone renderer: dectFollowUpBaseCount === 0 emits no loading hint (default state)', () => { const data = { dectBasestations: [{ mac: 'aa:bb:cc:dd:ee:01', meraki: { status: 'Online' } }], dectHandsets: [], }; const md = renderPhoneStatusMarkdown(data, { storeNum: '782', footer: false }); assert.doesNotMatch(md, /diagnostics loading/); }); // ───────────────────────────────────────────────────────────── // DECT follow-up message (renderDectDiagnosticsMarkdown) // ───────────────────────────────────────────────────────────── const okResult = (overrides = {}) => ({ base: { mac: '6c:ab:05:f6:28:19', ip: '10.4.11.87', name: 'Basestation A' }, ok: true, data: { time: { operatingTime: '02:15:00 (H:M:S)' }, firmware: { version: '05-01-03-0101-09' }, multiCell: { role: 'primary' }, conflictInfo: 'No Conflict', rebootLog: [], rtp: { current: 0 }, }, verdict: { healthy: true, warnings: [], info: [] }, elapsedMs: 812, ...overrides, }); test('dect diagnostics renderer: empty input returns empty string (caller should not send)', () => { assert.equal(renderDectDiagnosticsMarkdown([], { storeNum: '782' }), ''); assert.equal(renderDectDiagnosticsMarkdown(null, { storeNum: '782' }), ''); }); test('dect diagnostics renderer: healthy base renders check + uptime + firmware', () => { const md = renderDectDiagnosticsMarkdown([okResult()], { storeNum: '782', footer: false }); assert.match(md, /\*\*DECT Base Station Diagnostics — Store 782\*\*/); assert.match(md, /✅ \*\*Basestation A\*\* \(10\.4\.11\.87\)/); assert.match(md, /uptime 02:15:00/); assert.match(md, /fw 05-01-03-0101-09/); assert.match(md, /role: primary/); }); test('dect diagnostics renderer: warnings from verdict are surfaced under the header', () => { const md = renderDectDiagnosticsMarkdown([ okResult({ verdict: { healthy: false, warnings: ['Rx errors: 42 since last boot'], info: [], }, }), ], { storeNum: '782', footer: false }); assert.match(md, /⚠️ \*\*Basestation A\*\*/); assert.match(md, /⚠️ Rx errors: 42 since last boot/); }); test('dect diagnostics renderer: recent Power Loss reboot gets its own bolt line + suppresses duplicate warning', () => { const md = renderDectDiagnosticsMarkdown([ okResult({ data: { time: { operatingTime: '02:15:00' }, firmware: { version: '05-01-03-0101-09' }, multiCell: { role: 'primary' }, conflictInfo: 'No Conflict', rebootLog: [ { sequence: 164, at: '2026-07-02T12:54:12', reasonName: 'Power Loss', reasonCode: 80 }, ], rtp: { current: 0 }, }, verdict: { healthy: false, warnings: ['1 recent power-loss reboot(s); most recent at 2026-07-02T12:54:12'], info: [], }, }), ], { storeNum: '782', footer: false }); // The structured line survives … assert.match(md, /⚡ Recent power loss: 2026-07-02T12:54:12 \(reboot #164\)/); // … but the summary warning about power-loss is filtered out to // avoid duplication under the same header. assert.doesNotMatch(md, /⚠️ 1 recent power-loss/); }); test('dect diagnostics renderer: active RTP session gets a call icon', () => { const md = renderDectDiagnosticsMarkdown([ okResult({ data: { time: { operatingTime: '02:15:00' }, firmware: { version: '05-01-03-0101-09' }, multiCell: { role: 'primary' }, conflictInfo: 'No Conflict', rebootLog: [], rtp: { current: 2 }, }, }), ], { storeNum: '782', footer: false }); assert.match(md, /📞 2 active RTP session/); }); test('dect diagnostics renderer: base with error renders remediation hint', () => { const md = renderDectDiagnosticsMarkdown([ { base: { mac: '6c:ab:05:f6:28:19', ip: '10.4.11.87', name: 'Basestation A' }, ok: false, data: null, verdict: null, elapsedMs: 15003, error: { code: 'RELAY_RPC_TIMEOUT', message: 'timed out after 15000ms', hint: 'Relay accepted the request but the base did not respond in time.', }, }, ], { storeNum: '782', footer: false }); assert.match(md, /⚠️ \*\*Basestation A\*\* \(10\.4\.11\.87\) — collect failed: timed out after 15000ms/); assert.match(md, /Relay accepted the request but the base did not respond in time\./); }); test('dect diagnostics renderer: footer references /dectstatus command by store', () => { const md = renderDectDiagnosticsMarkdown([okResult()], { storeNum: '782' }); assert.match(md, /Use `\/dectstatus 782`/); }); // ───────────────────────────────────────────────────────────── // Full /dectstatus dump (renderDectStatusMarkdown) // ───────────────────────────────────────────────────────────── const fullOkResult = () => ({ base: { mac: '6c:ab:05:f6:28:19', ip: '10.4.11.87', name: 'Basestation A' }, ok: true, data: { device: { model: 'DBS-210-3PC', macAddress: '6c:ab:05:f6:28:19', ipAddress: '10.4.11.87', rfpiAddress: '13508C9C; RPN:00', }, firmware: { version: 'IPDECT-V2/05-01-03-0101-09' }, time: { operatingTime: '02:15:00 (H:M:S)', currentLocalTime: '02-Jul-2026 14:00:36' }, multiCell: { role: 'primary' }, conflictInfo: 'No Conflict', baseStatus: 'ok', rebootLog: [ { sequence: 164, at: '2026-07-02T12:54:12', reasonName: 'Power Loss', reasonCode: 80, firmwareAtBoot: '05-01-03-0101-09' }, { sequence: 163, at: '2026-07-02T12:49:50', reasonName: 'Normal Reboot', reasonCode: 21, firmwareAtBoot: '05-01-03-0101-09' }, ], network: { txPackets: 100, rxPackets: 200, rxDropped: 18, rxErrors: 0, txErrors: 0 }, rtp: { total: 2, current: 0, currentLocal: 0, currentRelay: 0 }, security: { customCa: { installed: false }, dot1x: { protocol: 'N/A', transactionStatus: 'Unavailable' }, }, emergencyNumbers: ['911', '1911'], }, verdict: { healthy: false, warnings: ['1 recent power-loss reboot(s); most recent at 2026-07-02T12:54:12'], info: ['Rx dropped packets: 18 since last boot'], }, elapsedMs: 812, }); test('dect status renderer: full dump includes reboot log, emergency numbers, and verdict', () => { const md = renderDectStatusMarkdown([fullOkResult()], { storeNum: '782', footer: false, relay: { connected: true, agent: { hostname: 'dc-relay-1' } }, }); assert.match(md, /\*\*DECT Status — Store 782\*\*/); assert.match(md, /Relay: online \(dc-relay-1\)/); assert.match(md, /✅|⚠️ \*\*Basestation A\*\*/); assert.match(md, /\*\*Reboot log\*\*/); assert.match(md, /⚡ #164/); assert.match(md, /Power Loss/); assert.match(md, /911, 1911/); assert.match(md, /healthy: \*\*NO\*\*/); assert.match(md, /Rx dropped packets: 18/); }); test('dect status renderer: empty discovery + offline relay still produces a usable message', () => { const md = renderDectStatusMarkdown([], { storeNum: '782', footer: false, relay: { connected: false }, discoveryWarnings: [{ mac: 'aa:bb:cc:dd:ee:ff', ip: '192.168.1.5', reason: 'not on 10.x' }], }); assert.match(md, /Relay: \*\*offline\*\*/); assert.match(md, /No reachable DECT basestations/); assert.match(md, /not on 10\.x/); }); test('dect status renderer: collect failure surfaces error + hint', () => { const md = renderDectStatusMarkdown([ { base: { mac: '6c:ab:05:f6:28:19', ip: '10.4.11.87', name: 'Basestation A' }, ok: false, data: null, verdict: null, elapsedMs: 15000, error: { code: 'NOT_CONNECTED', message: 'DECT relay agent is not connected', hint: 'DECT relay agent is not connected. Check that dect-relay-agent is running in the data center.', }, }, ], { storeNum: '782', footer: false }); assert.match(md, /Collect failed: DECT relay agent is not connected/); assert.match(md, /dect-relay-agent is running/); });