/** * Session 64 Phase 3 — opp_rank_stat is ONE column with ONE meaning. * * The highest-risk item is POLARITY. Backwards polarity does not fail loudly — * it silently adjusts every MLB grade in the WRONG direction, which is worse * than having no value at all. So the contract is asserted against WNBA's live * semantics, not merely "a number appears". */ const os = require('../../src/services/opponentStrength'); // 30 teams; BAA against ranges 0.200 (toughest staff) → 0.290 (weakest). const league = Array.from({ length: 30 }, (_, i) => ({ teamId: i + 1, stat: { avg: 0.200 + i * 0.003, slg: 0.350 + i * 0.005, gamesPlayed: 90, homeRuns: 10 + i, strikeOuts: 300 + i }, })); describe('THE SHARED CONTRACT — scale and polarity match WNBA', () => { test('scale is 0–1, never a raw count', () => { const r = os.deriveMlbOppRank(league, 15, 'hits'); expect(r.value).toBeGreaterThanOrEqual(0); expect(r.value).toBeLessThanOrEqual(1); expect(r.value).not.toBe(league[14].stat.avg); // not the raw stat }); test('POLARITY: the WEAKEST staff (highest BAA) scores HIGH = weak opponent', () => { const weakest = os.deriveMlbOppRank(league, 30, 'hits'); // BAA .287 expect(weakest.value).toBeGreaterThanOrEqual(0.70); }); test('POLARITY: the TOUGHEST staff (lowest BAA) scores LOW = tough opponent', () => { const toughest = os.deriveMlbOppRank(league, 1, 'hits'); // BAA .200 expect(toughest.value).toBeLessThanOrEqual(0.30); }); test('MLB polarity EQUALS WNBA polarity — high fires weak, low fires tough', () => { // engine1's live thresholds, applied identically to both sports. const WEAK = 0.70; const TOUGH = 0.30; const weak = os.deriveMlbOppRank(league, 30, 'hits').value; const tough = os.deriveMlbOppRank(league, 1, 'hits').value; // The same comparison engine1 makes for WNBA must classify MLB the same way. expect(weak >= WEAK).toBe(true); expect(tough <= TOUGH).toBe(true); expect(weak).toBeGreaterThan(tough); // monotone in the right direction }); test('a mid-pack staff lands mid-scale and fires NEITHER factor', () => { const mid = os.deriveMlbOppRank(league, 15, 'hits').value; expect(mid).toBeGreaterThan(0.30); expect(mid).toBeLessThan(0.70); }); }); describe('HONEST NULLS — never a confident value off thin data', () => { test('a thin LEAGUE baseline returns null, not a rank', () => { const r = os.deriveMlbOppRank(league.slice(0, 5), 1, 'hits'); expect(r.value).toBeNull(); expect(r.reason).toBe('league_baseline_too_thin'); }); test("a thin OPPONENT sample returns null", () => { const thin = league.map((t, i) => (i === 0 ? { ...t, stat: { ...t.stat, gamesPlayed: 3 } } : t)); const r = os.deriveMlbOppRank(thin, 1, 'hits'); expect(r.value).toBeNull(); expect(r.reason).toBe('opponent_sample_too_thin'); }); test('an unmapped stat returns null rather than a wrong field', () => { expect(os.deriveMlbOppRank(league, 1, 'stolen_bases').reason).toBe('stat_not_mapped'); }); test('an unknown opponent returns null', () => { expect(os.deriveMlbOppRank(league, 999, 'hits').reason).toBe('opponent_not_found'); }); test('a missing field returns null, never 0', () => { const noField = league.map((t) => ({ ...t, stat: { ...t.stat, avg: null } })); const r = os.deriveMlbOppRank(noField, 1, 'hits'); expect(r.value).toBeNull(); expect(r.value).not.toBe(0); }); }); describe('HEALTH — we are fixing a silent null, not rebuilding one', () => { test('empty source pages', () => { expect(os.opponentStrengthHealth({ sport: 'mlb', teamsLoaded: 0 }).alarm).toBe(true); }); test('all-null despite a loaded source pages', () => { expect(os.opponentStrengthHealth({ sport: 'mlb', teamsLoaded: 30, attempted: 25, derived: 0 }).alarm).toBe(true); }); test('healthy derivation is quiet', () => { expect(os.opponentStrengthHealth({ sport: 'mlb', teamsLoaded: 30, attempted: 25, derived: 24 }).alarm).toBe(false); }); });