Files
vyndr/tests/integration/internalRoutes.test.js
T

101 lines
3.7 KiB
JavaScript

// Integration: /api/internal/prefetch/tank01 (Session 18).
//
// Verifies (a) the endpoint is gated by the shared internal key,
// (b) the request body is translated into the prefetch module's
// argv shape correctly, and (c) the module's summary is returned
// verbatim. The prefetch module itself is mocked — it has its own
// unit coverage in tests/unit/tank01Prefetch.test.js.
const express = require('express');
const request = require('supertest');
jest.mock('../../scripts/tank01-prefetch', () => ({
main: jest.fn(),
}));
const tank01Prefetch = require('../../scripts/tank01-prefetch');
beforeEach(() => {
jest.resetAllMocks();
process.env.VYNDR_INTERNAL_KEY = 'test-internal-key-9999';
});
function mountApp() {
// Reset the require cache so the route picks up the mocked
// tank01-prefetch module fresh between tests.
delete require.cache[require.resolve('../../src/routes/internal')];
const internalRoutes = require('../../src/routes/internal');
const app = express();
app.use(express.json());
app.use('/api/internal', internalRoutes);
return app;
}
describe('POST /api/internal/prefetch/tank01', () => {
test('rejects requests without the internal key', async () => {
const app = mountApp();
const res = await request(app)
.post('/api/internal/prefetch/tank01')
.send({ dryRun: true });
expect(res.status).toBe(401);
expect(tank01Prefetch.main).not.toHaveBeenCalled();
});
test('translates body into argv and returns the summary', async () => {
const fakeSummary = {
nba: { games: 3, boxscores: 8, odds: true, skipped: null },
mlb: { games: 5, boxscores: 12, bvp: 0, skipped: null, bvp_skipped_reason: null },
requestsSpent: 4,
dryRun: false,
};
tank01Prefetch.main.mockResolvedValueOnce(fakeSummary);
const app = mountApp();
const res = await request(app)
.post('/api/internal/prefetch/tank01')
.set('x-internal-key', 'test-internal-key-9999')
.send({ max: 25, sports: ['nba', 'mlb'], dryRun: false });
expect(res.status).toBe(200);
expect(res.body).toEqual({ ok: true, summary: fakeSummary });
expect(tank01Prefetch.main).toHaveBeenCalledTimes(1);
const argv = tank01Prefetch.main.mock.calls[0][0];
expect(argv).toContain('--max=25');
expect(argv).toContain('--sports=nba,mlb');
expect(argv).not.toContain('--dry-run');
});
test('forwards --dry-run when requested', async () => {
tank01Prefetch.main.mockResolvedValueOnce({ dryRun: true });
const app = mountApp();
const res = await request(app)
.post('/api/internal/prefetch/tank01')
.set('x-internal-key', 'test-internal-key-9999')
.send({ dryRun: true });
expect(res.status).toBe(200);
const argv = tank01Prefetch.main.mock.calls[0][0];
expect(argv).toContain('--dry-run');
});
test('returns 500 with the underlying error when the module rejects', async () => {
tank01Prefetch.main.mockRejectedValueOnce(new Error('budget exhausted'));
const app = mountApp();
const res = await request(app)
.post('/api/internal/prefetch/tank01')
.set('x-internal-key', 'test-internal-key-9999')
.send({});
expect(res.status).toBe(500);
expect(res.body).toEqual({ ok: false, error: 'budget exhausted' });
});
test('accepts string sports (single sport) and forwards it', async () => {
tank01Prefetch.main.mockResolvedValueOnce({ ok: true });
const app = mountApp();
await request(app)
.post('/api/internal/prefetch/tank01')
.set('x-internal-key', 'test-internal-key-9999')
.send({ sports: 'mlb' });
const argv = tank01Prefetch.main.mock.calls[0][0];
expect(argv).toContain('--sports=mlb');
});
});