import { describe, it, expect, beforeEach, vi, Mock } from 'vitest'; import { GetLeagueProtestsUseCase, GetLeagueProtestsInput, GetLeagueProtestsErrorCode, } from './GetLeagueProtestsUseCase'; import { RaceRepository } from '../../domain/repositories/RaceRepository'; import { ProtestRepository } from '../../domain/repositories/ProtestRepository'; import { DriverRepository } from '../../domain/repositories/DriverRepository'; import { LeagueRepository } from '../../domain/repositories/LeagueRepository'; import { Race } from '../../domain/entities/Race'; import { Protest } from '../../domain/entities/Protest'; import { Driver } from '../../domain/entities/Driver'; import { League } from '../../domain/entities/League'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; describe('GetLeagueProtestsUseCase', () => { let useCase: GetLeagueProtestsUseCase; let raceRepository: { findByLeagueId: Mock; }; let protestRepository: { findByRaceId: Mock; }; let driverRepository: { findById: Mock; }; let leagueRepository: { findById: Mock; }; beforeEach(() => { raceRepository = { findByLeagueId: vi.fn(), }; protestRepository = { findByRaceId: vi.fn(), }; driverRepository = { findById: vi.fn(), }; leagueRepository = { findById: vi.fn(), }; useCase = new GetLeagueProtestsUseCase(raceRepository as unknown as RaceRepository, protestRepository as unknown as ProtestRepository, driverRepository as unknown as DriverRepository, leagueRepository as unknown as LeagueRepository); }); it('should return protests with races and drivers', async () => { const leagueId = 'league-1'; const league = League.create({ id: leagueId, name: 'Test League', ownerId: 'owner-1', description: 'A test league', }); const race = Race.create({ id: 'race-1', leagueId, scheduledAt: new Date(), track: 'Track 1', car: 'Car 1', }); const protest = Protest.create({ id: 'protest-1', raceId: 'race-1', protestingDriverId: 'driver-1', accusedDriverId: 'driver-2', incident: { lap: 1, description: 'Incident' }, status: 'pending', filedAt: new Date(), }); const driver1 = Driver.create({ id: 'driver-1', iracingId: '123', name: 'Driver 1', country: 'US', }); const driver2 = Driver.create({ id: 'driver-2', iracingId: '456', name: 'Driver 2', country: 'UK', }); leagueRepository.findById.mockResolvedValue(league); raceRepository.findByLeagueId.mockResolvedValue([race]); protestRepository.findByRaceId.mockResolvedValue([protest]); driverRepository.findById.mockImplementation((id: string) => { if (id === 'driver-1') return Promise.resolve(driver1); if (id === 'driver-2') return Promise.resolve(driver2); return Promise.resolve(null); }); const input: GetLeagueProtestsInput = { leagueId }; const result = await useCase.execute(input); expect(result.isOk()).toBe(true); const resultValue = result.unwrap(); expect(resultValue.league).toEqual(league); expect(resultValue.protests).toHaveLength(1); const presentedProtest = resultValue.protests[0]; expect(presentedProtest.protest).toEqual(protest); expect(presentedProtest.race).toEqual(race); expect(presentedProtest.protestingDriver).toEqual(driver1); expect(presentedProtest.accusedDriver).toEqual(driver2); }); it('should return empty protests when no races', async () => { const leagueId = 'league-1'; const league = League.create({ id: leagueId, name: 'Test League', ownerId: 'owner-1', description: 'A test league', }); leagueRepository.findById.mockResolvedValue(league); raceRepository.findByLeagueId.mockResolvedValue([]); const input: GetLeagueProtestsInput = { leagueId }; const result = await useCase.execute(input); expect(result.isOk()).toBe(true); const resultValue = result.unwrap(); expect(resultValue.league).toEqual(league); expect(resultValue.protests).toEqual([]); }); it('should return LEAGUE_NOT_FOUND when league does not exist', async () => { const leagueId = 'missing-league'; leagueRepository.findById.mockResolvedValue(null); const input: GetLeagueProtestsInput = { leagueId }; const result = await useCase.execute(input); expect(result.isErr()).toBe(true); const err = result.unwrapErr() as ApplicationErrorCode< GetLeagueProtestsErrorCode, { message: string } >; expect(err.code).toBe('LEAGUE_NOT_FOUND'); expect(err.details.message).toBe('League not found'); }); it('should return REPOSITORY_ERROR when repository throws', async () => { const leagueId = 'league-1'; const league = League.create({ id: leagueId, name: 'Test League', ownerId: 'owner-1', description: 'A test league', }); leagueRepository.findById.mockResolvedValue(league); raceRepository.findByLeagueId.mockRejectedValue(new Error('DB error')); const input: GetLeagueProtestsInput = { leagueId }; const result = await useCase.execute(input); expect(result.isErr()).toBe(true); const err = result.unwrapErr() as ApplicationErrorCode< GetLeagueProtestsErrorCode, { message: string } >; expect(err.code).toBe('REPOSITORY_ERROR'); expect(err.details.message).toBe('DB error'); }); });