import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest'; import { GetLeagueRosterMembersUseCase, type GetLeagueRosterMembersInput, type GetLeagueRosterMembersErrorCode, } from './GetLeagueRosterMembersUseCase'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import { LeagueMembership } from '../../domain/entities/LeagueMembership'; import { Driver } from '../../domain/entities/Driver'; import type { LeagueMembershipRepository } from '../../domain/repositories/LeagueMembershipRepository'; import type { DriverRepository } from '../../domain/repositories/DriverRepository'; import type { LeagueRepository } from '../../domain/repositories/LeagueRepository'; describe('GetLeagueRosterMembersUseCase', () => { let useCase: GetLeagueRosterMembersUseCase; let leagueMembershipRepository: { getLeagueMembers: Mock; }; let driverRepository: { findById: Mock; }; let leagueRepository: { exists: Mock; }; beforeEach(() => { leagueMembershipRepository = { getLeagueMembers: vi.fn(), }; driverRepository = { findById: vi.fn(), }; leagueRepository = { exists: vi.fn(), }; useCase = new GetLeagueRosterMembersUseCase( leagueMembershipRepository as unknown as LeagueMembershipRepository, driverRepository as unknown as DriverRepository, leagueRepository as unknown as LeagueRepository, ); }); it('returns members with resolvable drivers', async () => { const leagueId = 'league-1'; const memberships = [ LeagueMembership.create({ id: 'membership-1', leagueId, driverId: 'driver-1', role: 'member', joinedAt: new Date(), }), LeagueMembership.create({ id: 'membership-2', leagueId, driverId: 'driver-missing', role: 'admin', joinedAt: new Date(), }), ]; const driver1 = Driver.create({ id: 'driver-1', iracingId: '123', name: 'Driver 1', country: 'US', }); leagueRepository.exists.mockResolvedValue(true); leagueMembershipRepository.getLeagueMembers.mockResolvedValue(memberships); driverRepository.findById.mockImplementation((id: string) => { if (id === 'driver-1') return Promise.resolve(driver1); return Promise.resolve(null); }); const result = await useCase.execute({ leagueId } as GetLeagueRosterMembersInput); expect(result.isOk()).toBe(true); const successResult = result.unwrap(); expect(successResult.members).toHaveLength(1); expect(successResult.members[0]?.membership).toEqual(memberships[0]); expect(successResult.members[0]?.driver).toEqual(driver1); }); it('returns LEAGUE_NOT_FOUND when league does not exist', async () => { leagueRepository.exists.mockResolvedValue(false); const result = await useCase.execute({ leagueId: 'missing' } as GetLeagueRosterMembersInput); expect(result.isErr()).toBe(true); const err = result.unwrapErr() as ApplicationErrorCode< GetLeagueRosterMembersErrorCode, { message: string } >; expect(err.code).toBe('LEAGUE_NOT_FOUND'); expect(err.details.message).toBe('League not found'); }); it('returns REPOSITORY_ERROR when repository throws', async () => { leagueRepository.exists.mockRejectedValue(new Error('Repository failure')); const result = await useCase.execute({ leagueId: 'league-1' } as GetLeagueRosterMembersInput); expect(result.isErr()).toBe(true); const err = result.unwrapErr() as ApplicationErrorCode< GetLeagueRosterMembersErrorCode, { message: string } >; expect(err.code).toBe('REPOSITORY_ERROR'); expect(err.details.message).toBe('Repository failure'); }); });