Release v2.10.3
This commit is contained in:
@@ -96,6 +96,52 @@ test('player runtime snapshots websocket state and checks live names', async ()
|
||||
}
|
||||
});
|
||||
|
||||
test('player runtime suffixes a reconnecting client name already in use', async () => {
|
||||
process.env.PULSE_SIGNAGE_SHARED_SECRET = 'runtime-secret';
|
||||
|
||||
const persistedNames = [];
|
||||
const runtime = createPlayerRuntime({
|
||||
pool: {
|
||||
async query(_sql, params) {
|
||||
return [[params[0] === 'Lobby' && params[1] !== 'device-a' ? { device_id: 'device-a' } : undefined].filter(Boolean)];
|
||||
}
|
||||
},
|
||||
persistClientName(deviceId, clientName) {
|
||||
persistedNames.push({ deviceId, clientName });
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
const server = http.createServer();
|
||||
runtime.installWebsocket(server);
|
||||
|
||||
await new Promise((resolve) => server.listen(0, resolve));
|
||||
const { port } = server.address();
|
||||
const token = createPageAuthToken({ scope: 'player', slug: 'reconnect-test' });
|
||||
const clientA = new WebSocket(`ws://127.0.0.1:${port}/ws/screens/reconnect-test?auth=${encodeURIComponent(token)}`);
|
||||
const clientB = new WebSocket(`ws://127.0.0.1:${port}/ws/screens/reconnect-test?auth=${encodeURIComponent(token)}`);
|
||||
|
||||
try {
|
||||
await Promise.all([
|
||||
new Promise((resolve, reject) => { clientA.once('open', resolve); clientA.once('error', reject); }),
|
||||
new Promise((resolve, reject) => { clientB.once('open', resolve); clientB.once('error', reject); })
|
||||
]);
|
||||
clientA.send(JSON.stringify({ type: 'state', clientId: 'client-a', clientName: 'Lobby', deviceId: 'device-a' }));
|
||||
await waitFor(() => runtime.snapshotConnections('reconnect-test').some((connection) => connection.clientName === 'Lobby'));
|
||||
clientB.send(JSON.stringify({ type: 'state', clientId: 'client-b', clientName: 'Lobby', deviceId: 'device-b' }));
|
||||
|
||||
await waitFor(() => {
|
||||
const connections = runtime.snapshotConnections('reconnect-test');
|
||||
return connections.length === 2 && connections.some((connection) => connection.clientName === 'Lobby (1)');
|
||||
});
|
||||
|
||||
assert.deepEqual(persistedNames, [{ deviceId: 'device-b', clientName: 'Lobby (1)' }]);
|
||||
} finally {
|
||||
clientA.close();
|
||||
clientB.close();
|
||||
await new Promise((resolve) => server.close(resolve));
|
||||
}
|
||||
});
|
||||
|
||||
test('player runtime accepts websocket auth from cookies', async () => {
|
||||
process.env.PULSE_SIGNAGE_SHARED_SECRET = 'runtime-secret';
|
||||
|
||||
@@ -198,4 +244,30 @@ test('player runtime sends targeted and broadcast commands to live sockets', asy
|
||||
clientB.close();
|
||||
await new Promise((resolve) => server.close(resolve));
|
||||
}
|
||||
});
|
||||
|
||||
test('player runtime removes browser connections that stop sending state', async () => {
|
||||
process.env.PULSE_SIGNAGE_SHARED_SECRET = 'runtime-secret';
|
||||
|
||||
const runtime = createPlayerRuntime({ pool: null, staleConnectionMs: 50 });
|
||||
const server = http.createServer();
|
||||
runtime.installWebsocket(server);
|
||||
|
||||
await new Promise((resolve) => server.listen(0, resolve));
|
||||
const { port } = server.address();
|
||||
const token = createPageAuthToken({ scope: 'player', slug: 'stale-test' });
|
||||
const client = new WebSocket(`ws://127.0.0.1:${port}/ws/screens/stale-test?auth=${encodeURIComponent(token)}`);
|
||||
|
||||
try {
|
||||
await new Promise((resolve, reject) => {
|
||||
client.once('open', resolve);
|
||||
client.once('error', reject);
|
||||
});
|
||||
client.send(JSON.stringify({ type: 'state', clientId: 'stale-client', clientName: 'Stale Player' }));
|
||||
await waitFor(() => runtime.snapshotConnections('stale-test').length === 1);
|
||||
await waitFor(() => runtime.snapshotConnections('stale-test').length === 0, 1000);
|
||||
} finally {
|
||||
client.close();
|
||||
await new Promise((resolve) => server.close(resolve));
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user