Files
pulse-signage/test/web-bootstrap.test.js
T
lzstealth b71958cb38
Publish Docker Image / build-and-push-existing-registry (./build/Dockerfile, web, pulse-signage-web) (push) Successful in 1m21s
Publish Docker Image / build-and-push-existing-registry (./build/Dockerfile.player, player, pulse-signage-player) (push) Successful in 32s
Release 2.22.0: normalize playlist schedules and unify player sync
2026-10-27 22:54:38 +00:00

117 lines
3.6 KiB
JavaScript

const test = require('node:test');
const assert = require('node:assert/strict');
require('../src/common');
const { createWebBootstrap, mergePlayerSnapshotConnections } = require('../src/web/bootstrap');
const { createWebConfig } = require('../src/web/lib/config');
test('dashboard combines player and bridge snapshots without duplicating clients', () => {
const localClient = { id: 'connection-1', clientId: 'client-1', deviceId: 'device-1', playerPublicBaseUrl: 'http://player.local' };
const bridgeClient = { id: 'connection-2', clientId: 'client-2', deviceId: 'device-2', playerPublicBaseUrl: 'https://player.example' };
const connections = mergePlayerSnapshotConnections([
[localClient, bridgeClient],
[localClient]
]);
assert.deepEqual(connections, [localClient, bridgeClient]);
});
test('web config uses the player directly when no bridge URL is configured', () => {
const previousBridgeUrl = process.env.BRIDGE_INTERNAL_URL;
delete process.env.BRIDGE_INTERNAL_URL;
try {
assert.equal(createWebConfig().bridgeInternalUrl, 'http://player-bridge:8090');
process.env.BRIDGE_INTERNAL_URL = '';
const config = createWebConfig();
assert.equal(config.bridgeInternalUrl, '');
assert.equal(config.playerInternalUrl, 'http://player:8081');
} finally {
if (previousBridgeUrl === undefined) {
delete process.env.BRIDGE_INTERNAL_URL;
} else {
process.env.BRIDGE_INTERNAL_URL = previousBridgeUrl;
}
}
});
test('dashboard websocket broadcasts keep the last successful snapshot when refreshes fail', async () => {
let adminDataCalls = 0;
const bootstrap = createWebBootstrap({
pool: {
async query(sql) {
if (String(sql || '').includes('COUNT(*) AS connected_count')) {
return [[{ connected_count: 1 }]];
}
if (String(sql || '').includes('SELECT s.slug, pod.device_id, pod.client_name')) {
return [[]];
}
return [[]];
}
},
common: {
async fetchAdminData() {
adminDataCalls += 1;
if (adminDataCalls === 1) {
return {
screens: [
{
slug: 'alpha',
name: 'Alpha',
playlist_name: 'Main Loop'
}
],
playlists: [],
slides: []
};
}
throw new Error('dashboard refresh failed');
},
async fetchScreenPlayerUrls() {
return {
alpha: 'http://player.local/screen/alpha'
};
},
async fetchPlayerRegistrations() {
return [
{
identifier: 'player-alpha',
public_base_url: 'http://player.local',
last_seen_at: new Date()
}
];
}
},
playerSnapshotCache: new Map([
['alpha', {
count: 1,
connections: [
{
id: 'conn-1',
playerPublicBaseUrl: 'http://player.local'
}
]
}]
]),
playerSnapshotSockets: new Map(),
ensurePlayerSnapshotSubscription() {},
formatDashboardDate(value) {
return String(value || '');
},
notifyPlayerScreens() {},
backgroundTaskQueue: null,
uploadDir: 'media/uploads',
playerInternalBaseUrl: 'http://player.local'
});
const firstState = await bootstrap.broadcastDashboardState();
const secondState = await bootstrap.broadcastDashboardState();
assert.equal(firstState.screens[0].slug, 'alpha');
assert.equal(firstState.clients.length, 1);
assert.equal(secondState.screens[0].slug, 'alpha');
assert.equal(secondState.clients.length, 1);
assert.equal(adminDataCalls, 2);
});