import { describe, expect, it } from 'vitest'; import { API_DEFAULT_HOST, API_DEFAULT_PORT } from './app.js'; import { startApi } from './start.js'; describe('API startup boundary', () => { it('consumes the validated loopback listener without opening a real socket', async () => { const calls: unknown[] = []; await startApi({ app: { listen: async (options) => { calls.push(options); return 'http://127.0.0.1:8790'; }, close: async () => undefined, }, }); expect(calls).toEqual([{ host: API_DEFAULT_HOST, port: API_DEFAULT_PORT }]); }); it('rejects the legacy port before invoking listen', async () => { let called = false; await expect( startApi({ environment: { API_PORT: '8788' }, app: { listen: async () => { called = true; return ''; }, close: async () => undefined, }, }), ).rejects.toThrow(/reserved|legacy/i); expect(called).toBe(false); }); it('validates listen options before composing production resources', async () => { await expect(startApi({ environment: { API_PORT: '8788' } })).rejects.toThrow(/8788.*legacy/i); }); it('closes an injected app when listen fails and preserves the listen error', async () => { const listenError = new Error('address already in use'); let closed = false; await expect( startApi({ app: { listen: async () => { throw listenError; }, close: async () => { closed = true; throw new Error('close also failed'); }, }, }), ).rejects.toBe(listenError); expect(closed).toBe(true); }); it('schedules cleanup only after a successful listen without waiting for it', async () => { const events: string[] = []; let release!: () => void; const cleanup = new Promise((resolve) => { release = resolve; }); await startApi({ app: { listen: async () => { events.push('listen'); return ''; }, close: async () => undefined, retryPendingSecretCleanup: async () => { events.push('cleanup'); await cleanup; }, }, }); expect(events).toEqual(['listen', 'cleanup']); release(); }); });