import { describe, it, expect, vi, Mocked } from 'vitest'; import { LandingService } from './LandingService'; import { RacesApiClient } from '@/lib/api/races/RacesApiClient'; import { LeaguesApiClient } from '@/lib/api/leagues/LeaguesApiClient'; import { TeamsApiClient } from '@/lib/api/teams/TeamsApiClient'; import { HomeDiscoveryViewModel } from '@/lib/view-models/HomeDiscoveryViewModel'; describe('LandingService', () => { let mockRacesApi: Mocked; let mockLeaguesApi: Mocked; let mockTeamsApi: Mocked; let service: LandingService; beforeEach(() => { process.env.API_BASE_URL = 'http://localhost:3001'; mockRacesApi = { getPageData: vi.fn(), } as unknown as Mocked; mockLeaguesApi = { getAllWithCapacity: vi.fn(), } as unknown as Mocked; mockTeamsApi = { getAll: vi.fn(), } as unknown as Mocked; service = new LandingService(mockRacesApi, mockLeaguesApi, mockTeamsApi); }); describe('getHomeDiscovery', () => { it('should return home discovery data with top leagues, teams, and upcoming races', async () => { const racesDto = { races: [ { id: 'race-1', track: 'Monza', car: 'Ferrari', scheduledAt: '2023-10-01T10:00:00Z', status: 'upcoming', leagueId: 'league-1', leagueName: 'Test League', strengthOfField: 1500, isUpcoming: true, isLive: false, isPast: false, }, { id: 'race-2', track: 'Silverstone', car: 'Mercedes', scheduledAt: '2023-10-02T10:00:00Z', status: 'upcoming', leagueId: 'league-1', leagueName: 'Test League', strengthOfField: 1600, isUpcoming: true, isLive: false, isPast: false, }, ], }; const leaguesDto = { leagues: [ { id: 'league-1', name: 'League One' }, { id: 'league-2', name: 'League Two' }, { id: 'league-3', name: 'League Three' }, { id: 'league-4', name: 'League Four' }, { id: 'league-5', name: 'League Five' }, ], }; const teamsDto = { teams: [ { id: 'team-1', name: 'Team One', tag: 'T1', description: 'Best team' }, { id: 'team-2', name: 'Team Two', tag: 'T2', description: 'Great team' }, { id: 'team-3', name: 'Team Three', tag: 'T3', description: 'Awesome team' }, { id: 'team-4', name: 'Team Four', tag: 'T4', description: 'Cool team' }, { id: 'team-5', name: 'Team Five', tag: 'T5', description: 'Pro team' }, ], }; mockRacesApi.getPageData.mockResolvedValue(racesDto as any); mockLeaguesApi.getAllWithCapacity.mockResolvedValue(leaguesDto as any); mockTeamsApi.getAll.mockResolvedValue(teamsDto as any); const result = await service.getHomeDiscovery(); expect(result).toBeInstanceOf(HomeDiscoveryViewModel); expect(result.topLeagues).toHaveLength(4); // First 4 leagues expect(result.teams).toHaveLength(4); // First 4 teams expect(result.upcomingRaces).toHaveLength(2); // All upcoming races (first 4) }); it('should handle empty data', async () => { mockRacesApi.getPageData.mockResolvedValue({ races: [] } as any); mockLeaguesApi.getAllWithCapacity.mockResolvedValue({ leagues: [] } as any); mockTeamsApi.getAll.mockResolvedValue({ teams: [] } as any); const result = await service.getHomeDiscovery(); expect(result.topLeagues).toHaveLength(0); expect(result.teams).toHaveLength(0); expect(result.upcomingRaces).toHaveLength(0); }); it('should throw error when any API call fails', async () => { mockRacesApi.getPageData.mockRejectedValue(new Error('Races API failed')); await expect(service.getHomeDiscovery()).rejects.toThrow('Races API failed'); }); }); });