Files
builtbykev f0674ca07d Session 51: Complete Team Hub (2234 tests)
Research-depth team view: /team/[abbr] with roster, archetypes, stats, props.

- Team API: mlbStatsAdapter.getTeams/resolveTeam/getTeamRoster (statsapi, abbr→id
  + active roster, cached). teamService.getTeamHub assembles roster → per-player
  season stats (bounded concurrency) + archetype (snapshot grade or classify) +
  tonight's graded props from grades:{sport}; whole hub cached 15min. MLB real;
  NBA/WNBA graceful snapshot roster. GET /api/team/:abbr (404 unknown) + proxy.
- Team Hub page: server page.tsx (generateMetadata) + TeamHub client — header,
  sort (archetype/graded/A-Z), archetype filter chips, roster rows (archetype +
  player link + position + stats + graded props + parlay "+"), "No active props"
  greyed state, loading/error.
- Game cards: team abbreviations are now TeamLinks → /team/:abbr?sport= (green
  hover, stops propagation). Team Hub has "← Back to Slate".

Backend 2215 -> 2234 tests (+19), 190 suites. Web build clean (exit 0).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 11:55:10 -04:00

35 lines
1.3 KiB
JavaScript

// Session 51 — GET /api/team/:abbr (Team Hub endpoint).
const request = require('supertest');
jest.mock('../../src/services/teamService', () => ({
getTeamHub: jest.fn(),
}));
const teamService = require('../../src/services/teamService');
const app = require('../../src/app');
beforeEach(() => jest.clearAllMocks());
describe('GET /api/team/:abbr', () => {
it('returns the hub for a known team', async () => {
teamService.getTeamHub.mockResolvedValue({ team: { name: 'New York Yankees', abbr: 'NYY', sport: 'mlb' }, roster: [{ player: 'Aaron Judge' }] });
const res = await request(app).get('/api/team/NYY?sport=mlb');
expect(res.status).toBe(200);
expect(res.body.team.name).toBe('New York Yankees');
expect(teamService.getTeamHub).toHaveBeenCalledWith('mlb', 'NYY');
});
it('404s an unknown team with a helpful message', async () => {
teamService.getTeamHub.mockResolvedValue(null);
const res = await request(app).get('/api/team/ZZZ?sport=mlb');
expect(res.status).toBe(404);
expect(res.body.error).toMatch(/abbreviation/i);
});
it('defaults sport to mlb', async () => {
teamService.getTeamHub.mockResolvedValue({ team: { abbr: 'BOS' }, roster: [] });
await request(app).get('/api/team/BOS');
expect(teamService.getTeamHub).toHaveBeenCalledWith('mlb', 'BOS');
});
});