42 lines
1.7 KiB
TypeScript
42 lines
1.7 KiB
TypeScript
import fs from 'node:fs/promises';
|
|
import os from 'node:os';
|
|
import path from 'node:path';
|
|
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
|
import { GET } from './route';
|
|
|
|
let dir: string;
|
|
|
|
beforeAll(async () => {
|
|
// Same pattern as app/api/state/route.test.ts: point the DB singleton at a throwaway file so
|
|
// this test never touches ./db/flight.db. getGameDb() reads the env var on first call, and
|
|
// vitest gives each test file its own module registry (fresh singleton).
|
|
dir = await fs.mkdtemp(path.join(os.tmpdir(), 'flight-events-'));
|
|
process.env.FLIGHT_DB_PATH = path.join(dir, 'events.db');
|
|
});
|
|
|
|
afterAll(async () => {
|
|
delete process.env.FLIGHT_DB_PATH;
|
|
await fs.rm(dir, { recursive: true, force: true });
|
|
});
|
|
|
|
describe('GET /api/events', () => {
|
|
it('streams SSE with the current snapshot as the first event', async () => {
|
|
const res = await GET();
|
|
expect(res.status).toBe(200);
|
|
expect(res.headers.get('content-type')).toContain('text/event-stream');
|
|
expect(res.headers.get('cache-control')).toBe('no-cache');
|
|
expect(res.headers.get('x-accel-buffering')).toBe('no');
|
|
|
|
const reader = (res.body as ReadableStream<Uint8Array>).getReader();
|
|
try {
|
|
const { value } = await reader.read(); // first chunk: the initial snapshot event
|
|
const text = new TextDecoder().decode(value);
|
|
expect(text.startsWith('data: ')).toBe(true);
|
|
const snap = JSON.parse(text.slice('data: '.length)) as Record<string, unknown>;
|
|
expect(typeof (snap.simState as { clockMs: number }).clockMs).toBe('number');
|
|
} finally {
|
|
await reader.cancel(); // → stream cancel → unsubscribe from the registry
|
|
}
|
|
});
|
|
});
|