const { computeStats, getWeekStart } = require('../../src/services/performanceService'); describe('performanceService', () => { describe('computeStats', () => { test('calculates ROI correctly from won/lost mix', () => { const bets = [ { amount: '20', potential_payout: '38.18', status: 'won', settled_at: '2026-03-21' }, { amount: '20', potential_payout: '38.18', status: 'lost', settled_at: '2026-03-21' }, { amount: '20', potential_payout: '38.18', status: 'won', settled_at: '2026-03-21' }, ]; const stats = computeStats(bets); // Won: 18.18 + 18.18 = 36.36 profit, Lost: -20 = -20 // Total profit: 16.36, Total wagered: 60 // ROI: 16.36/60 * 100 = 27.3% expect(stats.roi).toBeCloseTo(27.3, 0); expect(stats.total_wagered).toBe(60); expect(stats.total_profit).toBeCloseTo(16.36, 1); }); test('win rate = won / (won + lost), excludes push', () => { const bets = [ { amount: '20', potential_payout: '38', status: 'won', settled_at: '2026-03-21' }, { amount: '20', potential_payout: '38', status: 'lost', settled_at: '2026-03-21' }, { amount: '20', potential_payout: '38', status: 'push', settled_at: '2026-03-21' }, ]; const stats = computeStats(bets); expect(stats.win_rate).toBe(50); expect(stats.sample_size).toBe(3); }); test('empty bets returns zeroes', () => { const stats = computeStats([]); expect(stats.roi).toBe(0); expect(stats.win_rate).toBe(0); expect(stats.sample_size).toBe(0); expect(stats.total_wagered).toBe(0); expect(stats.total_profit).toBe(0); }); test('all losses gives negative ROI', () => { const bets = [ { amount: '20', potential_payout: '38', status: 'lost', settled_at: '2026-03-21' }, { amount: '30', potential_payout: '57', status: 'lost', settled_at: '2026-03-21' }, ]; const stats = computeStats(bets); expect(stats.roi).toBe(-100); expect(stats.win_rate).toBe(0); }); }); describe('getWeekStart', () => { test('returns Monday for a Wednesday', () => { // 2026-03-18 is a Wednesday const ws = getWeekStart(new Date('2026-03-18T12:00:00Z')); expect(ws.getUTCDay()).toBe(1); // Monday expect(ws.toISOString().split('T')[0]).toBe('2026-03-16'); }); test('returns Monday for a Monday', () => { const ws = getWeekStart(new Date('2026-03-16T12:00:00Z')); expect(ws.toISOString().split('T')[0]).toBe('2026-03-16'); }); test('returns previous Monday for a Sunday', () => { // 2026-03-22 is a Sunday const ws = getWeekStart(new Date('2026-03-22T12:00:00Z')); expect(ws.toISOString().split('T')[0]).toBe('2026-03-16'); }); }); });