import { describe, it, expect, vi, beforeEach, Mock } from 'vitest'; import { GetGlobalLeaderboardsUseCase, GetGlobalLeaderboardsUseCasePorts } from './GetGlobalLeaderboardsUseCase'; import { LeaderboardsRepository, LeaderboardDriverData, LeaderboardTeamData } from '../ports/LeaderboardsRepository'; import { LeaderboardsEventPublisher } from '../ports/LeaderboardsEventPublisher'; describe('GetGlobalLeaderboardsUseCase', () => { let mockLeaderboardsRepository: LeaderboardsRepository; let mockEventPublisher: LeaderboardsEventPublisher; let ports: GetGlobalLeaderboardsUseCasePorts; let useCase: GetGlobalLeaderboardsUseCase; const mockDrivers: LeaderboardDriverData[] = [ { id: 'd1', name: 'Alice', rating: 2000, raceCount: 10 }, { id: 'd2', name: 'Bob', rating: 1500, raceCount: 5 }, ]; const mockTeams: LeaderboardTeamData[] = [ { id: 't1', name: 'Team A', rating: 2500, memberCount: 5, raceCount: 20 }, { id: 't2', name: 'Team B', rating: 2200, memberCount: 3, raceCount: 15 }, ]; beforeEach(() => { mockLeaderboardsRepository = { findAllDrivers: vi.fn().mockResolvedValue([...mockDrivers]) as unknown as Mock, findAllTeams: vi.fn().mockResolvedValue([...mockTeams]) as unknown as Mock, findDriversByTeamId: vi.fn() as unknown as Mock, }; mockEventPublisher = { publishGlobalLeaderboardsAccessed: vi.fn().mockResolvedValue(undefined) as unknown as Mock, publishLeaderboardsError: vi.fn().mockResolvedValue(undefined) as unknown as Mock, publishDriverRankingsAccessed: vi.fn() as unknown as Mock, publishTeamRankingsAccessed: vi.fn() as unknown as Mock, }; ports = { leaderboardsRepository: mockLeaderboardsRepository, eventPublisher: mockEventPublisher, }; useCase = new GetGlobalLeaderboardsUseCase(ports); }); it('should return top drivers and teams', async () => { const result = await useCase.execute(); expect(result.drivers).toHaveLength(2); expect(result.drivers[0].name).toBe('Alice'); expect(result.drivers[1].name).toBe('Bob'); expect(result.teams).toHaveLength(2); expect(result.teams[0].name).toBe('Team A'); expect(result.teams[1].name).toBe('Team B'); expect(mockEventPublisher.publishGlobalLeaderboardsAccessed).toHaveBeenCalled(); }); it('should respect driver and team limits', async () => { const result = await useCase.execute({ driverLimit: 1, teamLimit: 1 }); expect(result.drivers).toHaveLength(1); expect(result.drivers[0].name).toBe('Alice'); expect(result.teams).toHaveLength(1); expect(result.teams[0].name).toBe('Team A'); }); it('should handle errors and publish error event', async () => { (mockLeaderboardsRepository.findAllDrivers as Mock).mockRejectedValue(new Error('Repo error')); await expect(useCase.execute()).rejects.toThrow('Repo error'); expect(mockEventPublisher.publishLeaderboardsError).toHaveBeenCalled(); }); });