Files
Sybil-2/server/tests/agent-push-events.test.ts
T

25 lines
1.7 KiB
TypeScript

import assert from 'node:assert/strict';
import { once } from 'node:events';
import { createServer } from 'node:http';
import test from 'node:test';
import { WebSocketServer } from 'ws';
import { subscribeNotificationEvents } from '../src/agent-push-events.js';
test('notification observer authenticates, reconnects and stops without leaking missed invalidations', async t => {
const server = createServer(); const sockets = new WebSocketServer({ server });
server.listen(0, '127.0.0.1'); await once(server, 'listening');
let connections = 0, wakes = 0;
sockets.on('connection', (socket, request) => {
connections++;
assert.equal(request.url, '/api/notification-events');
assert.equal(request.headers.authorization, 'Bearer fixture-key');
assert.equal(request.headers['x-sybil-client'], 'backend-observer-v1');
socket.send(JSON.stringify({ type: 'notification_changed', version: 1 }));
});
const stop = subscribeNotificationEvents({ baseUrl: `http://127.0.0.1:${(server.address() as any).port}`, apiKey: 'fixture-key' }, () => { wakes++; }, { retryMs: 20 });
t.after(async () => { stop(); for (const socket of sockets.clients) socket.terminate(); sockets.close(); await new Promise<void>(resolve => server.close(() => resolve())); });
const waitFor = async (count: number) => { const deadline = Date.now() + 3000; while (wakes < count) { assert.ok(Date.now() < deadline); await new Promise(resolve => setTimeout(resolve, 10)); } };
await waitFor(1); for (const socket of sockets.clients) socket.terminate(); await waitFor(2);
assert.equal(connections, 2); stop(); await new Promise(resolve => setTimeout(resolve, 80)); assert.equal(connections, 2);
});