// Session 48 — Phase 3: player profile VYNDR INTELLIGENCE shows real usage // (AB/G) + rest, not "—"/"+0%". const svc = require('../../src/services/playerIntelService'); const judgeAdapter = { async getPlayerStats() { return { found: true, group: 'hitting', team: 'New York Yankees', season: { homeRuns: 34, atBats: 330, gamesPlayed: 92, avg: '.288', ops: '1.012', rbi: 87 }, last10: [ { date: '2026-06-14', stat: { totalBases: 2 } }, { date: '2026-06-16', stat: { totalBases: 4 } }, // gap 2 → 1 day off { date: '2026-06-18', stat: { totalBases: 3 } }, ], }; }, }; describe('resolvePlayerStats attaches usage + rest for MLB', () => { it('computes AB/G usage and rest from the game log', async () => { const r = await svc.resolvePlayerStats('Aaron Judge', 'mlb', { mlbAdapter: judgeAdapter }); expect(r.classifierInput.usage).toMatch(/AB\/G$/); expect(r.classifierInput.usage).toBe(`${Math.round((330 / 92) * 10) / 10} AB/G`); expect(r.classifierInput.rest).toBe('1d rest'); }); }); describe('getPlayerIntel surfaces real usage + rest (no "—"/"+0%")', () => { it('USAGE shows AB/G, REST shows a real value', async () => { const r = await svc.getPlayerIntel('Aaron Judge', 'mlb', { cacheGet: async () => null, resolveStats: (name, sport) => svc.resolvePlayerStats(name, sport, { mlbAdapter: judgeAdapter }), }); const usage = r.intel.find((m) => m.label === 'USAGE'); const rest = r.intel.find((m) => m.label === 'REST'); expect(usage.value).toMatch(/AB\/G$/); expect(rest.value).toBe('1d rest'); expect(rest.value).not.toBe('+0%'); }); it('REST falls back to "—" not "+0%" when no data', async () => { const r = await svc.getPlayerIntel('Nobody', 'nba', { cacheGet: async () => null, resolveStats: async () => ({ found: false }) }); expect(r.intel.find((m) => m.label === 'REST').value).toBe('—'); }); });