// Session 42 — player profile adapter logic + page/proxy/route source assertions. const fs = require('fs'); const path = require('path'); const WEB = path.join(__dirname, '..', '..', 'web', 'src'); const read = (rel) => fs.readFileSync(path.join(WEB, rel), 'utf8'); const adapter = require('../../web/src/lib/playerProfileAdapter'); const { playerHref } = require('../../web/src/lib/playerHref'); describe('playerProfileAdapter', () => { it('builds two-letter initials', () => { expect(adapter.initials('Victor Wembanyama')).toBe('VW'); expect(adapter.initials('Giannis')).toBe('GI'); expect(adapter.initials('')).toBe('??'); }); it('maps sport labels', () => { expect(adapter.sportLabel('nba')).toBe('NBA'); expect(adapter.sportLabel('soccer')).toBe('SOC'); }); it('flattens prop DNA reliable-first with colors', () => { const rows = adapter.dnaRows({ reliable: ['total_bases'], volatile: ['hits'] }); expect(rows[0]).toMatchObject({ prop: 'Total Bases', state: 'RELIABLE', color: '#00D4A0' }); expect(rows[1]).toMatchObject({ prop: 'Hits', state: 'VOLATILE', color: '#FFB347' }); }); it('writes a blend readout naming primary + secondary', () => { const txt = adapter.blendReadout({ primary: { name: 'POWER PULL' }, secondary: { name: 'RUN PRODUCER' } }); expect(txt).toContain('Power Pull'); expect(txt).toContain('Run Producer'); }); }); describe('playerHref', () => { it('encodes name + sport', () => { expect(playerHref('De\'Aaron Fox', 'nba')).toBe("/player/De'Aaron%20Fox?sport=nba"); expect(playerHref('Riley', 'MLB')).toBe('/player/Riley?sport=mlb'); }); }); describe('player profile page', () => { const src = read('app/player/[name]/page.tsx'); it('fetches the stats API and renders the 9 design sections', () => { expect(src).toContain('/api/stats/player/'); expect(src).toContain('ARCHETYPE DNA'); expect(src).toContain('PROP DNA'); expect(src).toContain('VYNDR INTELLIGENCE'); expect(src).toContain('ACTIVE PROPS'); expect(src).toContain('SEASON STATS'); expect(src).toContain('GRADE HISTORY'); expect(src).toContain('SPLITS'); }); it('handles loading + error states (never crashes on missing data)', () => { expect(src).toContain("'loading'"); expect(src).toContain("'error'"); expect(src).toContain('Could not load'); }); it('uses ArchetypeBlend + SportBadge + GradeBadge', () => { expect(src).toContain('ArchetypeBlend'); expect(src).toContain('SportBadge'); expect(src).toContain('GradeBadge'); }); }); describe('stats API proxy routes', () => { it('player proxy forwards to the Express stats route', () => { const src = read('app/api/stats/player/[name]/route.ts'); expect(src).toContain('/api/stats/player/'); expect(src).toContain('BACKEND_URL'); }); it('leaders proxy forwards to the Express stats route', () => { const src = read('app/api/stats/leaders/route.ts'); expect(src).toContain('/api/stats/leaders'); }); }); describe('GradeResultCard player-name link (Session 42)', () => { it('links the header player name to the profile', () => { const src = read('components/vyndr/GradeResultCard.tsx'); expect(src).toContain('playerHref(d.player'); }); });