import { beforeEach, describe, expect, it } from 'vitest'; import { LeaguesTestContext } from '../LeaguesTestContext'; import { League as RacingLeague } from '../../../../core/racing/domain/entities/League'; import { Season } from '../../../../core/racing/domain/entities/season/Season'; describe('League Schedule - Race Management', () => { let context: LeaguesTestContext; beforeEach(() => { context = new LeaguesTestContext(); context.clear(); }); const seedRacingLeague = async (params: { leagueId: string }) => { const league = RacingLeague.create({ id: params.leagueId, name: 'Racing League', description: 'League used for schedule integration tests', ownerId: 'driver-123', }); await context.racingLeagueRepository.create(league); return league; }; const seedSeason = async (params: { seasonId: string; leagueId: string; startDate: Date; endDate: Date; status?: 'planned' | 'active' | 'completed' | 'archived' | 'cancelled'; }) => { const season = Season.create({ id: params.seasonId, leagueId: params.leagueId, gameId: 'iracing', name: 'Season 1', status: params.status ?? 'active', startDate: params.startDate, endDate: params.endDate, }); await context.seasonRepository.add(season); return season; }; it('creates a race in a season schedule', async () => { const leagueId = 'league-1'; await seedRacingLeague({ leagueId }); const seasonId = 'season-1'; await seedSeason({ seasonId, leagueId, startDate: new Date('2025-01-01T00:00:00Z'), endDate: new Date('2025-01-31T23:59:59Z'), }); const create = await context.createLeagueSeasonScheduleRaceUseCase.execute({ leagueId, seasonId, track: 'Monza', car: 'GT3', scheduledAt: new Date('2025-01-10T20:00:00Z'), }); expect(create.isOk()).toBe(true); const { raceId } = create.unwrap(); const schedule = await context.getLeagueScheduleUseCase.execute({ leagueId, seasonId }); expect(schedule.isOk()).toBe(true); expect(schedule.unwrap().races.map(r => r.race.id)).toEqual([raceId]); }); it('updates an existing scheduled race (track/car/when)', async () => { const leagueId = 'league-1'; await seedRacingLeague({ leagueId }); const seasonId = 'season-1'; await seedSeason({ seasonId, leagueId, startDate: new Date('2025-01-01T00:00:00Z'), endDate: new Date('2025-01-31T23:59:59Z'), }); const create = await context.createLeagueSeasonScheduleRaceUseCase.execute({ leagueId, seasonId, track: 'Old Track', car: 'Old Car', scheduledAt: new Date('2025-01-10T20:00:00Z'), }); expect(create.isOk()).toBe(true); const { raceId } = create.unwrap(); const update = await context.updateLeagueSeasonScheduleRaceUseCase.execute({ leagueId, seasonId, raceId, track: 'New Track', car: 'New Car', scheduledAt: new Date('2025-01-20T20:00:00Z'), }); expect(update.isOk()).toBe(true); const schedule = await context.getLeagueScheduleUseCase.execute({ leagueId, seasonId }); expect(schedule.isOk()).toBe(true); const race = schedule.unwrap().races[0]?.race; expect(race?.id).toBe(raceId); expect(race?.track).toBe('New Track'); expect(race?.car).toBe('New Car'); expect(race?.scheduledAt.toISOString()).toBe('2025-01-20T20:00:00.000Z'); }); it('deletes a scheduled race from the season', async () => { const leagueId = 'league-1'; await seedRacingLeague({ leagueId }); const seasonId = 'season-1'; await seedSeason({ seasonId, leagueId, startDate: new Date('2025-01-01T00:00:00Z'), endDate: new Date('2025-01-31T23:59:59Z'), }); const create = await context.createLeagueSeasonScheduleRaceUseCase.execute({ leagueId, seasonId, track: 'Track 1', car: 'Car 1', scheduledAt: new Date('2025-01-10T20:00:00Z'), }); expect(create.isOk()).toBe(true); const { raceId } = create.unwrap(); const pre = await context.getLeagueScheduleUseCase.execute({ leagueId, seasonId }); expect(pre.isOk()).toBe(true); expect(pre.unwrap().races.map(r => r.race.id)).toEqual([raceId]); const del = await context.deleteLeagueSeasonScheduleRaceUseCase.execute({ leagueId, seasonId, raceId }); expect(del.isOk()).toBe(true); const post = await context.getLeagueScheduleUseCase.execute({ leagueId, seasonId }); expect(post.isOk()).toBe(true); expect(post.unwrap().races).toHaveLength(0); }); it('rejects creating a race outside the season window', async () => { const leagueId = 'league-1'; await seedRacingLeague({ leagueId }); const seasonId = 'season-1'; await seedSeason({ seasonId, leagueId, startDate: new Date('2025-01-01T00:00:00Z'), endDate: new Date('2025-01-31T23:59:59Z'), }); const create = await context.createLeagueSeasonScheduleRaceUseCase.execute({ leagueId, seasonId, track: 'Track', car: 'Car', scheduledAt: new Date('2025-02-10T20:00:00Z'), }); expect(create.isErr()).toBe(true); expect(create.unwrapErr().code).toBe('RACE_OUTSIDE_SEASON_WINDOW'); }); });