import { describe, it, expect, vi, beforeEach } from 'vitest'; import { GetLeagueDriverSeasonStatsUseCase } from './GetLeagueDriverSeasonStatsUseCase'; import type { IStandingRepository } from '../../domain/repositories/IStandingRepository'; import type { IResultRepository } from '../../domain/repositories/IResultRepository'; import type { IPenaltyRepository } from '../../domain/repositories/IPenaltyRepository'; import type { IRaceRepository } from '../../domain/repositories/IRaceRepository'; import type { DriverRatingPort } from './DriverRatingPort'; import type { GetLeagueDriverSeasonStatsUseCaseParams } from './GetLeagueDriverSeasonStatsUseCaseParams'; describe('GetLeagueDriverSeasonStatsUseCase', () => { let useCase: GetLeagueDriverSeasonStatsUseCase; let standingRepository: IStandingRepository; let resultRepository: IResultRepository; let penaltyRepository: IPenaltyRepository; let raceRepository: IRaceRepository; let driverRatingPort: DriverRatingPort; beforeEach(() => { standingRepository = { findByLeagueId: vi.fn(), } as any; resultRepository = { findByDriverIdAndLeagueId: vi.fn(), } as any; penaltyRepository = { findByRaceId: vi.fn(), } as any; raceRepository = { findByLeagueId: vi.fn(), } as any; driverRatingPort = { getRating: vi.fn(), } as any; useCase = new GetLeagueDriverSeasonStatsUseCase( standingRepository, resultRepository, penaltyRepository, raceRepository, driverRatingPort, ); }); it('should return league driver season stats for given league id', async () => { const params: GetLeagueDriverSeasonStatsUseCaseParams = { leagueId: 'league-1' }; const mockStandings = [ { driverId: 'driver-1', position: 1, points: 100, racesCompleted: 5 }, { driverId: 'driver-2', position: 2, points: 80, racesCompleted: 5 }, ]; const mockRaces = [ { id: 'race-1' }, { id: 'race-2' }, ]; const mockPenalties = [ { driverId: 'driver-1', status: 'applied', type: 'points_deduction', value: 10 }, ]; const mockResults = [{ position: 1 }]; const mockRating = { rating: 1500, ratingChange: 50 }; standingRepository.findByLeagueId.mockResolvedValue(mockStandings); raceRepository.findByLeagueId.mockResolvedValue(mockRaces); penaltyRepository.findByRaceId.mockImplementation((raceId) => { if (raceId === 'race-1') return Promise.resolve(mockPenalties); return Promise.resolve([]); }); driverRatingPort.getRating.mockReturnValue(mockRating); resultRepository.findByDriverIdAndLeagueId.mockResolvedValue(mockResults); const result = await useCase.execute(params); expect(result.isOk()).toBe(true); const dto = result.unwrap(); expect(dto.leagueId).toBe('league-1'); expect(dto.standings).toEqual([ { driverId: 'driver-1', position: 1, points: 100, racesCompleted: 5 }, { driverId: 'driver-2', position: 2, points: 80, racesCompleted: 5 }, ]); expect(dto.penalties.get('driver-1')).toEqual({ baseDelta: -10, bonusDelta: 0 }); expect(dto.driverRatings.get('driver-1')).toEqual(mockRating); expect(dto.driverResults.get('driver-1')).toEqual(mockResults); }); it('should handle no penalties', async () => { const params: GetLeagueDriverSeasonStatsUseCaseParams = { leagueId: 'league-1' }; const mockStandings = [{ driverId: 'driver-1', position: 1, points: 100, racesCompleted: 5 }]; const mockRaces = [{ id: 'race-1' }]; const mockResults = [{ position: 1 }]; const mockRating = { rating: null, ratingChange: null }; standingRepository.findByLeagueId.mockResolvedValue(mockStandings); raceRepository.findByLeagueId.mockResolvedValue(mockRaces); penaltyRepository.findByRaceId.mockResolvedValue([]); driverRatingPort.getRating.mockReturnValue(mockRating); resultRepository.findByDriverIdAndLeagueId.mockResolvedValue(mockResults); const result = await useCase.execute(params); expect(result.isOk()).toBe(true); const dto = result.unwrap(); expect(dto.penalties.size).toBe(0); }); });