'use strict'; // Job 1 — per-sport snapshot cadence config. Locks the posting-rhythm map and // the two quota-discipline invariants so a future edit can't silently // reintroduce baseball's one-size-fits-all rhythm. const cadence = require('../../src/config/sportCadence'); const { HOURS_UTC } = require('../../src/snapshotScheduler'); describe('sportCadence', () => { test('every sport is a subset of the scheduler firing grid (else it never runs)', () => { // The scheduler only fires at HOURS_UTC; a sport hour outside that set would // be silently dropped. This invariant is the whole reason the design keeps // the union inside the grid. for (const orphan of cadence.ALL_HOURS.filter((h) => !HOURS_UTC.includes(h))) { throw new Error(`hour ${orphan} is scheduled for some sport but not in HOURS_UTC=${HOURS_UTC}`); } expect(cadence.ALL_HOURS.every((h) => HOURS_UTC.includes(h))).toBe(true); }); test('WNBA keeps the full grid — PropLine-cheap; catches afternoon + late west-coast games', () => { // Corrected from reality (2026-07-15: afternoon WNBA games finished before // the 22 UTC slot). 14 UTC (10am ET) is the only slot early enough for a // 1pm ET game's props; on PropLine the extra slots cost a rounding error. expect(cadence.hoursFor('wnba')).toEqual([14, 19, 22, 1, 3]); expect(cadence.sportsForHour(14)).toContain('wnba'); }); test('soccer is the ONLY restricted sport — two lean odds-api slots, never the full grid', () => { // The genuine cadence win is protecting the 500/mo odds-api key. PropLine // sports run the full grid cheaply; soccer alone is trimmed. expect(cadence.hoursFor('soccer')).toEqual([14, 19]); expect(cadence.sportsForHour(22)).not.toContain('soccer'); expect(cadence.sportsForHour(1)).not.toContain('soccer'); expect(cadence.sportsForHour(3)).not.toContain('soccer'); }); test('soccer is excluded from intraday (protects the 500/mo odds-api key)', () => { expect(cadence.intradaySports()).not.toContain('soccer'); expect(cadence.intradaySports()).toEqual(expect.arrayContaining(['mlb', 'nba', 'wnba'])); }); test('sportsForHour respects a candidate subset and unknown hours yield none', () => { expect(cadence.sportsForHour(19, ['wnba', 'soccer'])).toEqual(expect.arrayContaining(['wnba', 'soccer'])); expect(cadence.sportsForHour(7)).toEqual([]); // 7 UTC — nobody posts }); test('mlb keeps the full baseball grid', () => { expect(cadence.hoursFor('mlb')).toEqual([14, 19, 22, 1, 3]); }); });