import { describe, it, expect, vi } from 'vitest'; import { GetDriversLeaderboardUseCase, type GetDriversLeaderboardInput, } from './GetDriversLeaderboardUseCase'; import type { IDriverRepository } from '../../domain/repositories/IDriverRepository'; import type { IRankingService } from '../../domain/services/IRankingService'; import type { IDriverStatsService } from '../../domain/services/IDriverStatsService'; import type { Logger } from '@core/shared/application'; describe('GetDriversLeaderboardUseCase', () => { const mockDriverFindAll = vi.fn(); const mockDriverRepo: IDriverRepository = { findById: vi.fn(), findByIRacingId: vi.fn(), existsByIRacingId: vi.fn(), findAll: mockDriverFindAll, create: vi.fn(), update: vi.fn(), delete: vi.fn(), exists: vi.fn(), }; const mockRankingGetAllDriverRankings = vi.fn(); const mockRankingService: IRankingService = { getAllDriverRankings: mockRankingGetAllDriverRankings, }; const mockDriverStatsGetDriverStats = vi.fn(); const mockDriverStatsService: IDriverStatsService = { getDriverStats: mockDriverStatsGetDriverStats, }; const mockGetDriverAvatar = vi.fn(); const mockLogger: Logger = { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn(), }; it('should return drivers leaderboard data', async () => { const useCase = new GetDriversLeaderboardUseCase( mockDriverRepo, mockRankingService, mockDriverStatsService, mockGetDriverAvatar, mockLogger, ); const driver1 = { id: 'driver1', name: { value: 'Driver One' }, country: { value: 'US' } }; const driver2 = { id: 'driver2', name: { value: 'Driver Two' }, country: { value: 'US' } }; const rankings = [ { driverId: 'driver1', rating: 2500, overallRank: 1 }, { driverId: 'driver2', rating: 2400, overallRank: 2 }, ]; const stats1 = { totalRaces: 10, wins: 5, podiums: 7 }; const stats2 = { totalRaces: 8, wins: 3, podiums: 4 }; mockDriverFindAll.mockResolvedValue([driver1, driver2]); mockRankingGetAllDriverRankings.mockReturnValue(rankings); mockDriverStatsGetDriverStats.mockImplementation((id: string) => { if (id === 'driver1') return stats1; if (id === 'driver2') return stats2; return null; }); mockGetDriverAvatar.mockImplementation((driverId: string) => { if (driverId === 'driver1') return Promise.resolve('avatar-driver1'); if (driverId === 'driver2') return Promise.resolve('avatar-driver2'); return Promise.resolve('avatar-default'); }); const input: GetDriversLeaderboardInput = { leagueId: 'league-1' }; const result = await useCase.execute(input); expect(result.isOk()).toBe(true); const presented = result.unwrap(); expect(presented).toEqual({ items: [ expect.objectContaining({ driver: driver1, rating: 2500, skillLevel: 'advanced', racesCompleted: 10, wins: 5, podiums: 7, isActive: true, rank: 1, avatarUrl: 'avatar-driver1', }), expect.objectContaining({ driver: driver2, rating: 2400, skillLevel: 'intermediate', racesCompleted: 8, wins: 3, podiums: 4, isActive: true, rank: 2, avatarUrl: 'avatar-driver2', }), ], totalRaces: 18, totalWins: 8, activeCount: 2, }); }); it('should return empty result when no drivers', async () => { const useCase = new GetDriversLeaderboardUseCase( mockDriverRepo, mockRankingService, mockDriverStatsService, mockGetDriverAvatar, mockLogger, ); mockDriverFindAll.mockResolvedValue([]); mockRankingGetAllDriverRankings.mockReturnValue([]); const input: GetDriversLeaderboardInput = { leagueId: 'league-1' }; const result = await useCase.execute(input); expect(result.isOk()).toBe(true); const presented = result.unwrap(); expect(presented).toEqual({ items: [], totalRaces: 0, totalWins: 0, activeCount: 0, }); }); it('should handle drivers without stats', async () => { const useCase = new GetDriversLeaderboardUseCase( mockDriverRepo, mockRankingService, mockDriverStatsService, mockGetDriverAvatar, mockLogger, ); const driver1 = { id: 'driver1', name: { value: 'Driver One' }, country: { value: 'US' } }; const rankings = [{ driverId: 'driver1', rating: 2500, overallRank: 1 }]; mockDriverFindAll.mockResolvedValue([driver1]); mockRankingGetAllDriverRankings.mockReturnValue(rankings); mockDriverStatsGetDriverStats.mockReturnValue(null); mockGetDriverAvatar.mockResolvedValue('avatar-driver1'); const input: GetDriversLeaderboardInput = { leagueId: 'league-1' }; const result = await useCase.execute(input); expect(result.isOk()).toBe(true); const presented = result.unwrap(); expect(presented).toEqual({ items: [ expect.objectContaining({ driver: driver1, rating: 2500, skillLevel: 'advanced', racesCompleted: 0, wins: 0, podiums: 0, isActive: false, rank: 1, avatarUrl: 'avatar-driver1', }), ], totalRaces: 0, totalWins: 0, activeCount: 0, }); }); it('should return error when repository throws', async () => { const useCase = new GetDriversLeaderboardUseCase( mockDriverRepo, mockRankingService, mockDriverStatsService, mockGetDriverAvatar, mockLogger, ); const error = new Error('Repository error'); mockDriverFindAll.mockRejectedValue(error); const input: GetDriversLeaderboardInput = { leagueId: 'league-1' }; const result = await useCase.execute(input); expect(result.isErr()).toBe(true); const err = result.unwrapErr(); expect(err.code).toBe('REPOSITORY_ERROR'); if ('details' in err && err.details && typeof err.details === 'object' && 'message' in err.details) { expect(err.details.message).toBe('Repository error'); } }); });