const { detectCorrelations } = require('../../src/services/correlationEngine'); function makeLeg(overrides = {}) { return { player: 'Nikola Jokic', stat_type: 'points', direction: 'over', line: 26.5, grade: 'B', confidence: 70, _team: 'DEN', _gameTime: '2026-03-21T19:00:00Z', reasoning: { steps: { season_avg: { value: 26.3 } } }, ...overrides, }; } describe('correlationEngine', () => { test('returns empty array when no correlations exist', () => { const legs = [ makeLeg({ player: 'Nikola Jokic', _team: 'DEN', _gameTime: '2026-03-21T19:00:00Z' }), makeLeg({ player: 'Jayson Tatum', _team: 'BOS', _gameTime: '2026-03-21T20:00:00Z' }), ]; const flags = detectCorrelations(legs, []); expect(flags).toEqual([]); }); test('detects same_game_opposing_players', () => { const legs = [ makeLeg({ player: 'Nikola Jokic', stat_type: 'points', direction: 'over', _team: 'DEN', _gameTime: 'game1' }), makeLeg({ player: 'LeBron James', stat_type: 'points', direction: 'over', _team: 'LAL', _gameTime: 'game1' }), ]; const flags = detectCorrelations(legs, []); expect(flags).toHaveLength(1); expect(flags[0].type).toBe('same_game_opposing_players'); expect(flags[0].impact).toBe('minor_negative'); }); test('detects same_game_same_team', () => { const legs = [ makeLeg({ player: 'LeBron James', _team: 'LAL', _gameTime: 'game1' }), makeLeg({ player: 'Anthony Davis', _team: 'LAL', _gameTime: 'game1' }), ]; const flags = detectCorrelations(legs, []); expect(flags).toHaveLength(1); expect(flags[0].type).toBe('same_game_same_team'); expect(flags[0].impact).toBe('minor_negative'); }); test('detects same_player_conflicting (opposite directions)', () => { const legs = [ makeLeg({ player: 'Nikola Jokic', stat_type: 'points', direction: 'over' }), makeLeg({ player: 'Nikola Jokic', stat_type: 'points', direction: 'under' }), ]; const flags = detectCorrelations(legs, []); expect(flags).toHaveLength(1); expect(flags[0].type).toBe('same_player_conflicting'); expect(flags[0].impact).toBe('major_negative'); }); test('detects positive_correlation (same player, complementary same direction)', () => { const legs = [ makeLeg({ player: 'Nikola Jokic', stat_type: 'points', direction: 'over' }), makeLeg({ player: 'Nikola Jokic', stat_type: 'rebounds', direction: 'over' }), ]; const flags = detectCorrelations(legs, []); expect(flags).toHaveLength(1); expect(flags[0].type).toBe('positive_correlation'); expect(flags[0].impact).toBe('positive'); }); test('detects blowout_cascade (2+ legs, high spread)', () => { const legs = [ makeLeg({ player: 'Nikola Jokic', _team: 'DEN', _gameTime: 'game1' }), makeLeg({ player: 'LeBron James', _team: 'LAL', _gameTime: 'game1', stat_type: 'rebounds' }), ]; const spreads = [ { home_team: 'DEN', away_team: 'LAL', game_time: 'game1', home_spread: -12, book: 'draftkings' }, ]; const flags = detectCorrelations(legs, spreads); const cascade = flags.find((f) => f.type === 'blowout_cascade'); expect(cascade).toBeDefined(); expect(cascade.impact).toBe('major_negative'); }); test('handles single leg (no correlations possible)', () => { const legs = [makeLeg()]; const flags = detectCorrelations(legs, []); expect(flags).toEqual([]); }); test('multiple correlations can fire simultaneously', () => { const legs = [ makeLeg({ player: 'Nikola Jokic', stat_type: 'points', direction: 'over', _team: 'DEN', _gameTime: 'game1' }), makeLeg({ player: 'LeBron James', stat_type: 'points', direction: 'over', _team: 'LAL', _gameTime: 'game1' }), makeLeg({ player: 'Anthony Davis', stat_type: 'rebounds', direction: 'over', _team: 'LAL', _gameTime: 'game1' }), ]; const flags = detectCorrelations(legs, []); // Jokic vs LeBron = same_game_opposing_players, LeBron vs AD = same_game_same_team expect(flags.length).toBeGreaterThanOrEqual(2); }); });