'use strict'; // Rev 3 — flat EDGE BOARD (mobile screen 01). Design's mobile board is a flat, // edge-ranked list across every game, not game-grouped cards. The flatten is a // pure transform of the assembled GameCardData[]; lock its ranking + honesty. const { flattenToEdgeBoard, edgeBoardBreadth, edgeGradeRank } = require('../../web/src/lib/slateAdapter'); const card = (over) => ({ sport: 'nba', live: false, away: { abbr: 'DEN', name: 'Denver' }, home: { abbr: 'MIN', name: 'Minnesota' }, playerStrips: [], ...over, }); const strip = (player, props, extra = {}) => ({ player, team: extra.team || '', props }); describe('flattenToEdgeBoard', () => { const cards = [ card({ playerStrips: [ strip('Jokic', [{ stat: 'PTS', line: 27.5, side: 'O', grade: 'A+', edge: 8.4 }]), strip('Gordon', [{ stat: 'REB', line: 7.5, side: 'O', grade: 'B', edge: 3.4 }]), ] }), card({ live: true, away: { abbr: 'CHI', name: 'Chi' }, home: { abbr: 'MIL', name: 'Mil' }, playerStrips: [ strip('Edwards', [{ stat: 'AST', line: 5.5, side: 'O', grade: 'A', edge: 5.2 }]), strip('LaVine', [{ stat: 'PTS', line: 22.5, side: 'O', grade: 'D', edge: -1.2 }]), ] }), ]; // SUPERSEDED 2026-08-01: the board no longer ranks on edge (corr -0.010/-0.022 // vs corr(p_win) = +0.26). With no forecast_rank supplied it falls through to // GRADE rank, which is what this now asserts. test('flattens every graded prop across games into ranked rows, grade order', () => { const rows = flattenToEdgeBoard(cards); expect(rows.map((r) => r.player)).toEqual(['Jokic', 'Edwards', 'Gordon', 'LaVine']); expect(rows[0].rank).toBe(1); expect(rows[3].rank).toBe(4); expect(rows[1].live).toBe(true); // Edwards' game is live → row carries it expect(rows[0].away).toBe('DEN'); expect(rows[0].home).toBe('MIN'); }); // SUPERSEDED 2026-08-01 — replaced by the strictly stronger inverse: edge // cannot move the board AT ALL. The original could not detect edge being // re-introduced as a key; this fails immediately if it is. test('EDGE CANNOT RANK — flipping every edge leaves the order identical', () => { const build = (e1, e2) => flattenToEdgeBoard([card({ playerStrips: [ strip('First', [{ stat: 'PTS', line: 20, side: 'O', grade: 'A', edge: e1 }]), strip('Second', [{ stat: 'PTS', line: 20, side: 'O', grade: 'A', edge: e2 }]), ] })]); expect(build(null, 2.0).map((r) => r.player)).toEqual(['First', 'Second']); expect(build(2.0, null).map((r) => r.player)).toEqual(['First', 'Second']); expect(build(-30, 30).map((r) => r.player)).toEqual(['First', 'Second']); }); test('forecastRank ORDERS the board and a missing rank sorts LAST', () => { const rows = flattenToEdgeBoard([card({ playerStrips: [ strip('NoRank', [{ stat: 'PTS', line: 20, side: 'O', grade: 'A', edge: 99 }]), strip('Ranked2', [{ stat: 'PTS', line: 21, side: 'O', grade: 'C', forecastRank: 2 }]), strip('Ranked1', [{ stat: 'PTS', line: 22, side: 'O', grade: 'D', forecastRank: 1 }]), ] })]); // rank 1 → rank 2 → unranked. Grade and edge are both overridden. expect(rows.map((r) => r.player)).toEqual(['Ranked1', 'Ranked2', 'NoRank']); expect(rows[0].rank).toBe(1); }); test('awaiting / dead / ungraded rows are excluded from the board', () => { const rows = flattenToEdgeBoard([card({ playerStrips: [ strip('Graded', [{ stat: 'PTS', line: 20, side: 'O', grade: 'A', edge: 5 }]), strip('Awaiting', [{ stat: 'PTS', line: 20, side: 'O', grade: null, awaiting: true }]), strip('Dead', [{ stat: 'PTS', line: 20, side: 'O', grade: 'B', edge: 4, dead: true }]), ] })]); expect(rows.map((r) => r.player)).toEqual(['Graded']); }); test('breadth counts A/B edges + games, never fabricates CLV', () => { const rows = flattenToEdgeBoard(cards); const b = edgeBoardBreadth(rows, cards); expect(b.edges).toBe(3); // A+, B, A (not the D) expect(b.games).toBe(2); expect(b).not.toHaveProperty('clv'); // CLV comes from /api/accuracy, never invented here }); test('edgeGradeRank orders tiers for the tiebreak', () => { expect(edgeGradeRank('A+')).toBeLessThan(edgeGradeRank('A')); expect(edgeGradeRank('A')).toBeLessThan(edgeGradeRank('B')); expect(edgeGradeRank('F')).toBeLessThan(edgeGradeRank('ZZZ')); // unknown → last }); test('empty / malformed input → empty board, no throw', () => { expect(flattenToEdgeBoard(null)).toEqual([]); expect(flattenToEdgeBoard([{}])).toEqual([]); }); // P1-7 — an impossible edge (the pipeline's 60/100/140 placeholder) is not a // market signal and must not be DISPLAYED as a real percentage. The ranking // half of this test is retired: edge ranks nothing now, so nulling it can no // longer change an order. The display guard still matters and still holds. test('insane edge (>40%) is nulled so it is never DISPLAYED as a real %', () => { const rows = flattenToEdgeBoard([card({ playerStrips: [ strip('RealEdge', [{ stat: 'PTS', line: 20, side: 'O', grade: 'B', edge: 8.4 }]), strip('BrokenEdge', [{ stat: 'PTS', line: 20, side: 'O', grade: 'A', edge: 140 }]), ] })]); const broken = rows.find((r) => r.player === 'BrokenEdge'); const real = rows.find((r) => r.player === 'RealEdge'); expect(broken.edge).toBeNull(); // not displayed as a fake % expect(real.edge).toBe(8.4); // real edge preserved as a diagnostic // Ordering is now grade-driven (A before B) and edge has no say in it. expect(rows[0].player).toBe('BrokenEdge'); }); });