// Unit: startup prefetch (Session 24). Must be non-blocking and crash-safe. jest.mock('../../scripts/tank01-prefetch', () => ({ main: jest.fn(), })); const prefetch = require('../../scripts/tank01-prefetch'); const { runStartupPrefetch, scheduleStartupPrefetch } = require('../../src/startupPrefetch'); const savedKey = process.env.RAPID_API_KEY; afterAll(() => { if (savedKey === undefined) delete process.env.RAPID_API_KEY; else process.env.RAPID_API_KEY = savedKey; }); beforeEach(() => jest.clearAllMocks()); describe('runStartupPrefetch', () => { test('skips (returns null) when RAPID_API_KEY is unset', async () => { delete process.env.RAPID_API_KEY; const result = await runStartupPrefetch(); expect(result).toBeNull(); expect(prefetch.main).not.toHaveBeenCalled(); }); test('runs the prefetch with sports + max budget when key is set', async () => { process.env.RAPID_API_KEY = 'test-key'; prefetch.main.mockResolvedValue({ requestsSpent: 12 }); const result = await runStartupPrefetch({ sports: ['nba', 'mlb'], maxRequests: 40 }); expect(result).toEqual({ requestsSpent: 12 }); const argv = prefetch.main.mock.calls[0][0]; expect(argv).toEqual(expect.arrayContaining(['--sports=nba,mlb', '--max=40'])); }); test('prefetch failure resolves to null — never throws (server stays up)', async () => { process.env.RAPID_API_KEY = 'test-key'; prefetch.main.mockRejectedValue(new Error('rapidapi 503')); await expect(runStartupPrefetch()).resolves.toBeNull(); }); }); describe('scheduleStartupPrefetch', () => { test('returns an unref-able timer and does not run synchronously', () => { process.env.RAPID_API_KEY = 'test-key'; const timer = scheduleStartupPrefetch({ delayMs: 10_000 }); expect(prefetch.main).not.toHaveBeenCalled(); // deferred, not immediate clearTimeout(timer); }); });