81 lines
2.7 KiB
JavaScript
81 lines
2.7 KiB
JavaScript
process.env.PARLAYAPI_KEY = 'test-key';
|
|
process.env.PARLAYAPI_BASE_URL = 'https://api.parlayapi.test/v1';
|
|
|
|
const mockAxiosGet = jest.fn();
|
|
jest.mock('axios', () => ({ get: (...args) => mockAxiosGet(...args) }));
|
|
|
|
const mockCache = { current: new Map() };
|
|
jest.mock('../../src/utils/redis', () => ({
|
|
cacheGet: async (k) => mockCache.current.get(k) ?? null,
|
|
cacheSet: async (k, v) => { mockCache.current.set(k, v); return true; },
|
|
cacheDel: async (k) => { mockCache.current.delete(k); return true; },
|
|
}));
|
|
|
|
const adapter = require('../../src/services/adapters/parlayApiAdapter');
|
|
|
|
beforeEach(() => {
|
|
mockAxiosGet.mockReset();
|
|
mockCache.current.clear();
|
|
});
|
|
|
|
describe('parlayApiAdapter.configured', () => {
|
|
test('reflects PARLAYAPI_KEY presence', () => {
|
|
expect(adapter.configured()).toBe(true);
|
|
delete process.env.PARLAYAPI_KEY;
|
|
expect(adapter.configured()).toBe(false);
|
|
process.env.PARLAYAPI_KEY = 'test-key';
|
|
});
|
|
});
|
|
|
|
describe('parlayApiAdapter.getHistoricalProps', () => {
|
|
test('throws on unsupported sport', async () => {
|
|
await expect(adapter.getHistoricalProps('curling', 'X', 'points', 10)).rejects.toThrow(/Unsupported sport/);
|
|
});
|
|
|
|
test('normalizes API response into stable shape', async () => {
|
|
mockAxiosGet.mockResolvedValue({
|
|
status: 200,
|
|
data: {
|
|
props: [
|
|
{ player: 'Jalen Brunson', stat_type: 'points', line: 26.5, closing_line: 27.0, result: 'over', game_date: '2026-04-15' },
|
|
],
|
|
},
|
|
});
|
|
const result = await adapter.getHistoricalProps('nba', 'Jalen Brunson', 'points', 10);
|
|
expect(result).toHaveLength(1);
|
|
expect(result[0]).toMatchObject({
|
|
sport: 'nba',
|
|
player_name: 'Jalen Brunson',
|
|
stat_type: 'points',
|
|
line: 26.5,
|
|
closing_line: 27.0,
|
|
result: 'over',
|
|
source: 'parlayapi',
|
|
});
|
|
});
|
|
|
|
test('cache hit on second call', async () => {
|
|
mockAxiosGet.mockResolvedValue({ status: 200, data: { props: [] } });
|
|
await adapter.getHistoricalProps('nba', 'P', 'points', 10);
|
|
await adapter.getHistoricalProps('nba', 'P', 'points', 10);
|
|
expect(mockAxiosGet).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
test('returns [] when unconfigured', async () => {
|
|
delete process.env.PARLAYAPI_KEY;
|
|
expect(await adapter.getHistoricalProps('nba', 'P', 'points', 10)).toEqual([]);
|
|
process.env.PARLAYAPI_KEY = 'test-key';
|
|
});
|
|
});
|
|
|
|
describe('parlayApiAdapter.getClosingLines', () => {
|
|
test('returns array from response.lines', async () => {
|
|
mockAxiosGet.mockResolvedValue({
|
|
status: 200,
|
|
data: { lines: [{ player: 'A', line: 10 }, { player: 'B', line: 15 }] },
|
|
});
|
|
const lines = await adapter.getClosingLines('nba', '2026-04-15');
|
|
expect(lines).toHaveLength(2);
|
|
});
|
|
});
|