f0674ca07d
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>
35 lines
1.3 KiB
JavaScript
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');
|
|
});
|
|
});
|