import { describe, it, expect, beforeEach, vi, Mock } from 'vitest'; import { CreateLeagueWithSeasonAndScoringUseCase } from './CreateLeagueWithSeasonAndScoringUseCase'; import type { CreateLeagueWithSeasonAndScoringCommand } from '../dto/CreateLeagueWithSeasonAndScoringCommand'; import type { ILeagueRepository } from '../../domain/repositories/ILeagueRepository'; import type { ISeasonRepository } from '../../domain/repositories/ISeasonRepository'; import type { ILeagueScoringConfigRepository } from '../../domain/repositories/ILeagueScoringConfigRepository'; import type { LeagueScoringPresetProvider } from '../ports/LeagueScoringPresetProvider'; import type { Logger } from '@core/shared/application'; describe('CreateLeagueWithSeasonAndScoringUseCase', () => { let useCase: CreateLeagueWithSeasonAndScoringUseCase; let leagueRepository: { create: Mock; }; let seasonRepository: { create: Mock; }; let leagueScoringConfigRepository: { save: Mock; }; let presetProvider: { getPresetById: Mock; createScoringConfigFromPreset: Mock; }; let logger: { debug: Mock; info: Mock; warn: Mock; error: Mock; }; beforeEach(() => { leagueRepository = { create: vi.fn(), }; seasonRepository = { create: vi.fn(), }; leagueScoringConfigRepository = { save: vi.fn(), }; presetProvider = { getPresetById: vi.fn(), createScoringConfigFromPreset: vi.fn(), }; logger = { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn(), }; useCase = new CreateLeagueWithSeasonAndScoringUseCase( leagueRepository as unknown as ILeagueRepository, seasonRepository as unknown as ISeasonRepository, leagueScoringConfigRepository as unknown as ILeagueScoringConfigRepository, presetProvider as unknown as LeagueScoringPresetProvider, logger as unknown as Logger, ); }); it('should create league, season, and scoring successfully', async () => { const command = { name: 'Test League', description: 'A test league', visibility: 'unranked' as const, ownerId: 'owner-1', gameId: 'game-1', maxDrivers: 20, maxTeams: 5, enableDriverChampionship: true, enableTeamChampionship: true, enableNationsChampionship: false, enableTrophyChampionship: false, scoringPresetId: 'club-default', }; const mockPreset = { id: 'club-default', name: 'Club Default', }; presetProvider.getPresetById.mockReturnValue(mockPreset); presetProvider.createScoringConfigFromPreset.mockReturnValue({ id: 'config-1' }); leagueRepository.create.mockResolvedValue(undefined); seasonRepository.create.mockResolvedValue(undefined); leagueScoringConfigRepository.save.mockResolvedValue(undefined); const result = await useCase.execute(command); expect(result.isOk()).toBe(true); const data = result.unwrap(); expect(data.leagueId).toBeDefined(); expect(data.seasonId).toBeDefined(); expect(data.scoringPresetId).toBe('club-default'); expect(data.scoringPresetName).toBe('Club Default'); expect(leagueRepository.create).toHaveBeenCalledTimes(1); expect(seasonRepository.create).toHaveBeenCalledTimes(1); expect(leagueScoringConfigRepository.save).toHaveBeenCalledTimes(1); }); it('should return error when league name is empty', async () => { const command = { name: '', description: 'Test description', visibility: 'unranked' as const, ownerId: 'owner-1', gameId: 'game-1', enableDriverChampionship: true, enableTeamChampionship: true, enableNationsChampionship: false, enableTrophyChampionship: false, }; const result = await useCase.execute(command); expect(result.isErr()).toBe(true); expect(result.unwrapErr().details.message).toBe('League name is required'); }); it('should return error when ownerId is empty', async () => { const command = { name: 'Test League', description: 'Test description', visibility: 'unranked' as const, ownerId: '', gameId: 'game-1', enableDriverChampionship: true, enableTeamChampionship: true, enableNationsChampionship: false, enableTrophyChampionship: false, }; const result = await useCase.execute(command as CreateLeagueWithSeasonAndScoringCommand); expect(result.isErr()).toBe(true); expect(result.unwrapErr().details.message).toBe('League ownerId is required'); }); it('should return error when gameId is empty', async () => { const command = { name: 'Test League', description: 'Test description', visibility: 'unranked' as const, ownerId: 'owner-1', gameId: '', enableDriverChampionship: true, enableTeamChampionship: true, enableNationsChampionship: false, enableTrophyChampionship: false, }; const result = await useCase.execute(command); expect(result.isErr()).toBe(true); expect(result.unwrapErr().details.message).toBe('gameId is required'); }); it('should return error when visibility is missing', async () => { const command: Partial = { name: 'Test League', ownerId: 'owner-1', gameId: 'game-1', enableDriverChampionship: true, enableTeamChampionship: true, enableNationsChampionship: false, enableTrophyChampionship: false, }; const result = await useCase.execute(command as CreateLeagueWithSeasonAndScoringCommand); expect(result.isErr()).toBe(true); expect(result.unwrapErr().details.message).toBe('visibility is required'); }); it('should return error when maxDrivers is invalid', async () => { const command = { name: 'Test League', description: 'Test description', visibility: 'unranked' as const, ownerId: 'owner-1', gameId: 'game-1', maxDrivers: 0, enableDriverChampionship: true, enableTeamChampionship: true, enableNationsChampionship: false, enableTrophyChampionship: false, }; const result = await useCase.execute(command); expect(result.isErr()).toBe(true); expect(result.unwrapErr().details.message).toBe('maxDrivers must be greater than 0 when provided'); }); it('should return error when ranked league has insufficient drivers', async () => { const command = { name: 'Test League', description: 'Test description', visibility: 'ranked' as const, ownerId: 'owner-1', gameId: 'game-1', maxDrivers: 5, enableDriverChampionship: true, enableTeamChampionship: true, enableNationsChampionship: false, enableTrophyChampionship: false, }; const result = await useCase.execute(command); expect(result.isErr()).toBe(true); expect(result.unwrapErr().details.message).toContain('Ranked leagues require at least 10 drivers'); }); it('should return error when scoring preset is unknown', async () => { const command = { name: 'Test League', description: 'Test description', visibility: 'unranked' as const, ownerId: 'owner-1', gameId: 'game-1', enableDriverChampionship: true, enableTeamChampionship: true, enableNationsChampionship: false, enableTrophyChampionship: false, scoringPresetId: 'unknown-preset', }; presetProvider.getPresetById.mockReturnValue(undefined); const result = await useCase.execute(command); expect(result.isErr()).toBe(true); expect(result.unwrapErr().details.message).toBe('Unknown scoring preset: unknown-preset'); }); it('should return error when repository throws', async () => { const command = { name: 'Test League', description: 'Test description', visibility: 'unranked' as const, ownerId: 'owner-1', gameId: 'game-1', enableDriverChampionship: true, enableTeamChampionship: true, enableNationsChampionship: false, enableTrophyChampionship: false, }; const mockPreset = { id: 'club-default', name: 'Club Default', }; presetProvider.getPresetById.mockReturnValue(mockPreset); presetProvider.createScoringConfigFromPreset.mockReturnValue({ id: 'config-1' }); leagueRepository.create.mockRejectedValue(new Error('DB error')); const result = await useCase.execute(command); expect(result.isErr()).toBe(true); expect(result.unwrapErr().details.message).toBe('DB error'); }); });