import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import { Bridge } from '../src/bridge.js'; import type { KRPCState } from '../src/convert.js'; import { createServer, type Server } from 'node:http'; function mockState(ut: number): KRPCState { return { ut, bodies: [], vessels: [], groundStations: [], }; } describe('Bridge end-to-end', () => { let server: Server; let received: object[] = []; let port: number; beforeAll(async () => { server = createServer((req, res) => { let body = ''; req.on('data', (c) => (body += c)); req.on('end', () => { try { received.push(JSON.parse(body)); res.writeHead(200, { 'content-type': 'application/json' }); res.end(JSON.stringify({ error: false, data: { ok: true } })); } catch (e) { res.writeHead(400); res.end('bad'); } }); }); await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve)); port = (server.address() as { port: number }).port; }); afterAll(async () => { await new Promise((resolve) => server.close(() => resolve())); }); it('POSTs snapshots to the API at the configured interval', async () => { received = []; let counter = 0; const bridge = new Bridge({ apiUrl: `http://127.0.0.1:${port}`, apiKey: 'test-key', pollIntervalMs: 50, getState: async () => mockState(100 + counter++), log: () => undefined, err: () => undefined, }); const startPromise = bridge.start(); await new Promise((r) => setTimeout(r, 300)); bridge.stop(); await startPromise; expect(received.length).toBeGreaterThan(2); expect(received[0]).toMatchObject({ ut: 100, capturedAt: expect.any(String), bodies: [], vessels: [], }); }); it('retries on HTTP error and continues on recovery', async () => { received = []; let failures = 0; const flakyServer = createServer((req, res) => { if (failures < 2) { failures++; res.writeHead(503); res.end('down'); } else { let body = ''; req.on('data', (c) => (body += c)); req.on('end', () => { received.push(JSON.parse(body)); res.writeHead(200); res.end('ok'); }); } }); await new Promise((resolve) => flakyServer.listen(0, '127.0.0.1', resolve)); const flakyPort = (flakyServer.address() as { port: number }).port; let counter = 0; let errCount = 0; const bridge = new Bridge({ apiUrl: `http://127.0.0.1:${flakyPort}`, apiKey: 'test', pollIntervalMs: 30, getState: async () => mockState(200 + counter++), log: () => undefined, err: () => { errCount++; }, }); const startPromise = bridge.start(); await new Promise((r) => setTimeout(r, 500)); bridge.stop(); await startPromise; expect(received.length).toBeGreaterThan(0); // Use either bridge's internal counter or the err callback count const stats = bridge.getStats(); expect(stats.failureCount + errCount).toBeGreaterThanOrEqual(2); await new Promise((resolve) => flakyServer.close(() => resolve())); }); });