const test = require('node:test'); const assert = require('node:assert/strict'); const fs = require('node:fs'); const vm = require('node:vm'); test('system status shows connected player count in the player label', () => { const script = fs.readFileSync(require.resolve('../src/web/public/js/shared/system-status.js'), 'utf8'); const dotClasses = new Set(); const elements = { 'sidebar-status-dot': { classList: { remove(...names) { names.forEach((name) => dotClasses.delete(name)); }, add(name) { dotClasses.add(name); } }, setAttribute() {} }, 'sidebar-status-text': { textContent: '' } }; const sockets = []; const context = { document: { getElementById(id) { return elements[id] || null; } }, window: { WebSocket: true, location: { protocol: 'http:', host: 'example.test' }, setTimeout() { return 1; }, clearTimeout() {}, webHandleDashboardState() {} }, WebSocket: function MockWebSocket(url) { this.url = url; sockets.push(this); this.close = function () {}; }, JSON: JSON, Number: Number, String: String, Boolean: Boolean, Array: Array, Object: Object, Math: Math, setTimeout() {}, clearTimeout() {}, console: console }; context.window.document = context.document; context.window.WebSocket = context.WebSocket; vm.runInNewContext(script, context); assert.equal(sockets.length, 1); sockets[0].onmessage({ data: JSON.stringify({ type: 'dashboard-state', state: { screens: [{ slug: 'alpha' }], playerServiceName: 'Bridge', playerServiceConnected: true, connectedPlayersCount: 4 } }) }); assert.equal(elements['sidebar-status-text'].textContent, 'Bridge online - 4 players connected'); assert.equal(dotClasses.has('status-dot--online'), true); }); test('system status shows an explicit idle label when no players are connected', () => { const script = fs.readFileSync(require.resolve('../src/web/public/js/shared/system-status.js'), 'utf8'); const dotClasses = new Set(); const elements = { 'sidebar-status-dot': { classList: { remove(...names) { names.forEach((name) => dotClasses.delete(name)); }, add(name) { dotClasses.add(name); } }, setAttribute() {} }, 'sidebar-status-text': { textContent: '' } }; const sockets = []; const context = { document: { getElementById(id) { return elements[id] || null; } }, window: { WebSocket: true, location: { protocol: 'http:', host: 'example.test' }, setTimeout() { return 1; }, clearTimeout() {}, webHandleDashboardState() {} }, WebSocket: function MockWebSocket(url) { this.url = url; sockets.push(this); this.close = function () {}; }, JSON: JSON, Number: Number, String: String, Boolean: Boolean, Array: Array, Object: Object, Math: Math, setTimeout() {}, clearTimeout() {}, console: console }; context.window.document = context.document; context.window.WebSocket = context.WebSocket; vm.runInNewContext(script, context); assert.equal(sockets.length, 1); sockets[0].onmessage({ data: JSON.stringify({ type: 'dashboard-state', state: { screens: [{ slug: 'alpha' }], playerServiceName: 'Bridge', playerServiceConnected: true, connectedPlayersCount: 0 } }) }); assert.equal(elements['sidebar-status-text'].textContent, 'Bridge online - no players connected'); assert.equal(dotClasses.has('status-dot--idle'), true); sockets[0].onmessage({ data: JSON.stringify({ type: 'dashboard-state', state: { screens: [{ slug: 'alpha' }], playerServiceName: 'Bridge', playerServiceConnected: false, connectedPlayersCount: 1 } }) }); assert.equal(elements['sidebar-status-text'].textContent, 'No services connected'); assert.equal(dotClasses.has('status-dot--offline'), true); }); test('system status keeps the last service label while a new page reconnects', () => { const script = fs.readFileSync(require.resolve('../src/web/public/js/shared/system-status.js'), 'utf8'); const elements = { 'sidebar-status-dot': { classList: { remove() {}, add() {} }, setAttribute() {} }, 'sidebar-status-text': { textContent: 'Player service' } }; const storedValues = { 'pulse-player-service-status-v2': JSON.stringify({ status: 'online', label: 'Player service online - 1 player connected', serviceName: 'Player service' }) }; const sockets = []; const context = { document: { getElementById(id) { return elements[id] || null; } }, window: { WebSocket: true, location: { protocol: 'http:', host: 'example.test' }, sessionStorage: { getItem(key) { return storedValues[key] || null; }, setItem(key, value) { storedValues[key] = value; } }, setTimeout() { return 1; }, clearTimeout() {}, webHandleDashboardState() {} }, WebSocket: function MockWebSocket(url) { this.url = url; sockets.push(this); this.close = function () {}; }, JSON: JSON, Number: Number, String: String, Boolean: Boolean, Array: Array, Object: Object, Math: Math, setTimeout() {}, clearTimeout() {}, console: console }; context.window.document = context.document; context.window.WebSocket = context.WebSocket; vm.runInNewContext(script, context); assert.equal(elements['sidebar-status-text'].textContent, 'Player online - 1 player connected'); sockets[0].onopen(); assert.equal(elements['sidebar-status-text'].textContent, 'Player online - 1 player connected'); }); test('system status uses the same offline label after restoring a cached bridge status', () => { const script = fs.readFileSync(require.resolve('../src/web/public/js/shared/system-status.js'), 'utf8'); const elements = { 'sidebar-status-dot': { classList: { remove() {}, add() {} }, setAttribute() {} }, 'sidebar-status-text': { textContent: '' } }; const context = { document: { getElementById(id) { return elements[id] || null; } }, window: { WebSocket: true, location: { protocol: 'http:', host: 'example.test' }, sessionStorage: { getItem() { return JSON.stringify({ status: 'offline', label: 'Bridge offline', serviceName: 'Bridge' }); }, setItem() {} }, setTimeout() { return 1; }, clearTimeout() {}, webHandleDashboardState() {} }, WebSocket: function MockWebSocket() { this.close = function () {}; }, JSON: JSON, Number: Number, String: String, Boolean: Boolean, Array: Array, Object: Object, Math: Math, setTimeout() {}, clearTimeout() {}, console: console }; context.window.document = context.document; context.window.WebSocket = context.WebSocket; vm.runInNewContext(script, context); assert.equal(elements['sidebar-status-text'].textContent, 'No services connected'); });