'use strict'; /** * STRUCTURAL GUARDS (2026-08-02) — two recurring failure families, locked. * * Both are the same principle: never silently convert something ABSENT or THIN * into a false DEFINITE value. * * GUARD 1 unknown ≠ zero (`Number(null) === 0`, 6× recurring) * GUARD 2 takeability = book identity, never price shape * * The fixtures are REAL rows from prod (2026-08-02 re-stamp), not invented. */ const { knownNumber, knownRate, isKnown, firstKnown } = require('../../src/utils/known'); const { isTakeableMarket, isWithinPriceBand, assessQuote } = require('../../src/config/takeability'); // ─────────────────────────────── GUARD 1 ─────────────────────────────── describe('GUARD 1 — unknown is not zero', () => { it('every absent form is UNKNOWN, never 0', () => { for (const v of [null, undefined, '', NaN, 'abc', {}, []]) { expect(knownNumber(v)).toBeNull(); expect(isKnown(v)).toBe(false); } }); it('a REAL zero survives — 0 rest days is a fact, not an absence', () => { expect(knownNumber(0)).toBe(0); expect(isKnown(0)).toBe(true); expect(knownRate(0)).toBe(0); }); it('Infinity is not a measurement', () => { expect(knownNumber(Infinity)).toBeNull(); expect(knownNumber(-Infinity)).toBeNull(); }); it('knownRate additionally rejects booleans and negatives', () => { expect(knownRate(true)).toBeNull(); // Number(true) === 1 expect(knownRate(false)).toBeNull(); // Number(false) === 0 — the trap expect(knownRate(-0.5)).toBeNull(); expect(knownNumber(-0.5)).toBe(-0.5); // a signed gap is legitimately negative }); it('firstKnown prefers a present 0 over a later fallback (|| gets this wrong)', () => { expect(firstKnown(0, 5)).toBe(0); expect(firstKnown(null, 5)).toBe(5); expect(firstKnown(null, undefined, '')).toBeNull(); }); it('REAL FIXTURE — a null triple rate must not read as "never triples"', () => { const tb = require('../../src/services/projection/compoundTotalBases'); // Same components, one with an UNKNOWN triple rate vs a MEASURED zero. const unknown = tb.tbPmf({ singles: 0.6, doubles: 0.2, triples: null, home_runs: 0.15 }); const zero = tb.tbPmf({ singles: 0.6, doubles: 0.2, triples: 0, home_runs: 0.15 }); // Both are computable, and an unknown component contributes nothing — // but it must do so by being SKIPPED, not by being asserted as zero. expect(unknown).not.toBeNull(); expect(zero).not.toBeNull(); // The guard that matters: no component usable at all → null, not a flat curve. expect(tb.tbPmf({ singles: null, doubles: null, triples: null, home_runs: null })).toBeNull(); expect(tb.tbPmf({ singles: false })).toBeNull(); }); it('the migrated sites all delegate to the ONE rule', () => { // Semantics must be identical across every migrated module, or the // migration reintroduced drift. const mods = [ require('../../src/utils/gradeRanking').strictNum, require('../../src/services/consensusRuler').__internals.num, ]; for (const fn of mods) { expect(fn(null)).toBeNull(); expect(fn('')).toBeNull(); expect(fn(0)).toBe(0); expect(fn('2.5')).toBe(2.5); } }); }); // ─────────────────────────────── GUARD 2 ─────────────────────────────── describe('GUARD 2 — takeability is BOOK IDENTITY, never price shape', () => { it('REAL FIXTURE — one-sided takeable markets are TAKEABLE', () => { // Verified in prod: betrivers and hardrockbet quote one side only on real // props (5 such rows surfaced in the 2026-08-02 re-stamp). One-sidedness is // normal baseball market structure, not a defect. expect(isTakeableMarket('betrivers')).toBe(true); expect(isTakeableMarket('hardrockbet')).toBe(true); // A one-sided quote: the other side is genuinely absent, and takeability // does not depend on it at all. expect(assessQuote({ book: 'betrivers', odds: 6600 }).takeable).toBe(true); expect(assessQuote({ book: 'hardrockbet', odds: 400 }).takeable).toBe(true); }); it('REAL FIXTURE — an extreme price is still TAKEABLE (steep juice is a price)', () => { // Ohtani hits-over at -266 and Schwarber hits-over at -209 are real, // placeable DraftKings bets. for (const odds of [-266, -209, -300, -1400, 4900]) { expect(assessQuote({ book: 'draftkings', odds }).takeable).toBe(true); } }); it('REAL FIXTURE — a DFS book at an ordinary -119 is NOT takeable', () => { // The ordinary-looking price is the fake one: PrizePicks is not a // sportsbook. Book identity decides, price shape never does. for (const book of ['prizepicks', 'underdog', 'sleeper', 'dabble']) { expect(isTakeableMarket(book)).toBe(false); expect(assessQuote({ book, odds: -119 }).takeable).toBe(false); } }); it('exchanges and offshore are not takeable however normal the price looks', () => { for (const book of ['kalshi', 'novig', 'smarkets', 'bovada', 'onexbet', 'pinnacle']) { expect(isTakeableMarket(book)).toBe(false); } }); it('an ABSENT book is not takeable — we cannot assert a market we cannot name', () => { for (const b of [null, undefined, '', 'not_a_book']) expect(isTakeableMarket(b)).toBe(false); }); it('THE DISTINCTION: takeable and price-band are independent axes', () => { // A -300 DraftKings prop is a REAL bet we would not promote. Both true. const steep = assessQuote({ book: 'draftkings', odds: -300 }); expect(steep.takeable).toBe(true); expect(steep.within_price_band).toBe(false); const normal = assessQuote({ book: 'draftkings', odds: -110 }); expect(normal.takeable).toBe(true); expect(normal.within_price_band).toBe(true); // ...and a DFS book inside the band is still not takeable. const dfs = assessQuote({ book: 'prizepicks', odds: -119 }); expect(dfs.takeable).toBe(false); expect(dfs.within_price_band).toBe(true); }); it('an UNKNOWN price is not an out-of-band price', () => { expect(assessQuote({ book: 'draftkings', odds: null }).within_price_band).toBeNull(); expect(assessQuote({ book: 'draftkings' }).takeable).toBe(true); // book still decides }); it('no drift: the canonical rule IS bookRoles.isTakeableBook', () => { const { isTakeableBook } = require('../../src/config/bookRoles'); for (const b of ['draftkings', 'prizepicks', 'pinnacle', 'betrivers', null]) { expect(isTakeableMarket(b)).toBe(isTakeableBook(b)); } }); });