// DS0 (Design v2) — THE ENTITY LAYER. Teams resolve to real logos + real // colors; the accent rule keeps team color VISIBLE on the near-black terminal. const { resolveTeam, teamLogoUrl, accentColor, luminance } = require('../../web/src/lib/teamMeta'); describe('resolveTeam — abbr / full name / nickname / alias', () => { test('canonical statsapi abbr', () => { expect(resolveTeam('NYY', 'mlb').name).toBe('New York Yankees'); expect(resolveTeam('MIL', 'mlb').name).toBe('Milwaukee Brewers'); }); test('full name and nickname', () => { expect(resolveTeam('Milwaukee Brewers', 'mlb').abbr).toBe('MIL'); expect(resolveTeam('Pirates', 'mlb').abbr).toBe('PIT'); expect(resolveTeam('Red Sox', 'mlb').abbr).toBe('BOS'); expect(resolveTeam('White Sox', 'mlb').abbr).toBe('CWS'); }); test('statsapi↔ESPN abbr aliases (AZ↔ARI, CWS↔CHW)', () => { expect(resolveTeam('ARI', 'mlb').abbr).toBe('AZ'); expect(resolveTeam('CHW', 'mlb').abbr).toBe('CWS'); }); test('ESPN-schedule ball-sport abbr aliases (Wave 2B)', () => { // NBA abbrs the ESPN schedule emits that used to fall to a monogram expect(resolveTeam('SA', 'nba').abbr).toBe('SAS'); // Spurs expect(resolveTeam('NY', 'nba').abbr).toBe('NYK'); // Knicks expect(resolveTeam('WSH', 'nba').abbr).toBe('WAS'); // Wizards expect(resolveTeam('BRK', 'nba').abbr).toBe('BKN'); // Nets // WNBA expect(resolveTeam('CONN', 'wnba').abbr).toBe('CON'); // Sun expect(resolveTeam('WSH', 'wnba').abbr).toBe('WAS'); // Mystics }); test('global alias never shadows a real same-abbr team in another sport', () => { // WSH is a real MLB abbr (Nationals) — must resolve directly, NOT via the // NBA/WNBA WSH→WAS alias. expect(resolveTeam('WSH', 'mlb').name).toBe('Washington Nationals'); // NY is the WNBA Liberty's real abbr — direct hit, not the NBA NY→NYK alias. expect(resolveTeam('NY', 'wnba').name).toBe('New York Liberty'); // NY is genuinely ambiguous in MLB (NYY/NYM) → stays null, never guessed. expect(resolveTeam('NY', 'mlb')).toBeNull(); }); test('unknown team → null (never a fake)', () => { expect(resolveTeam('ZZZ', 'mlb')).toBeNull(); expect(resolveTeam('', 'mlb')).toBeNull(); }); test('resolves across leagues', () => { expect(resolveTeam('LAL', 'nba').name).toBe('Los Angeles Lakers'); expect(resolveTeam('NY', 'wnba').name).toBe('New York Liberty'); }); test('soccer = World Cup national teams, by name + alias', () => { expect(resolveTeam('USA', 'soccer').name).toBe('United States'); expect(resolveTeam('United States', 'soccer').abbr).toBe('USA'); expect(resolveTeam('Brazil', 'soccer').abbr).toBe('BRA'); expect(resolveTeam('South Korea', 'soccer').abbr).toBe('KOR'); expect(resolveTeam('Ivory Coast', 'soccer').abbr).toBe('CIV'); // alias }); }); describe('teamLogoUrl — real ESPN CDN paths', () => { test('MLB logo url uses the ESPN logo abbr, not the app abbr', () => { expect(teamLogoUrl('AZ', 'mlb')).toBe('https://a.espncdn.com/i/teamlogos/mlb/500/ari.png'); expect(teamLogoUrl('CWS', 'mlb')).toBe('https://a.espncdn.com/i/teamlogos/mlb/500/chw.png'); expect(teamLogoUrl('NYY', 'mlb')).toBe('https://a.espncdn.com/i/teamlogos/mlb/500/nyy.png'); }); test('per-league path', () => { expect(teamLogoUrl('LAL', 'nba')).toContain('/teamlogos/nba/500/lal.png'); expect(teamLogoUrl('NY', 'wnba')).toContain('/teamlogos/wnba/500/ny.png'); }); test('soccer national teams use the flag CDN (countries/ + numeric edge)', () => { expect(teamLogoUrl('USA', 'soccer')).toBe('https://a.espncdn.com/i/teamlogos/countries/500/usa.png'); expect(teamLogoUrl('South Korea', 'soccer')).toContain('/countries/500/kors.png'); expect(teamLogoUrl('Curaçao', 'soccer')).toBe('https://a.espncdn.com/i/teamlogos/soccer/500/11678.png'); }); test('unknown → null', () => { expect(teamLogoUrl('ZZZ', 'mlb')).toBeNull(); expect(teamLogoUrl('Narnia', 'soccer')).toBeNull(); }); }); describe('accentColor — VISIBLE on #06060B (the near-black bug guard)', () => { test('picks the more luminous of primary/secondary', () => { // White Sox: primary silver (#c4ced4) vs black — must pick silver. expect(accentColor('CWS', 'mlb').toLowerCase()).toBe('#c4ced4'); // Pirates: black primary + gold secondary — must pick gold. expect(accentColor('PIT', 'mlb').toLowerCase()).toBe('#fdb827'); }); test('both-dark team never returns an invisible accent', () => { const acc = accentColor('SF', 'mlb'); // black + orange → orange, visible expect(luminance(acc)).toBeGreaterThan(40); }); test('luminance ranks black low, white high', () => { expect(luminance('#000000')).toBeLessThan(10); expect(luminance('#ffffff')).toBeGreaterThan(240); }); });