import { describe, it, expect, vi, beforeEach } from 'vitest'; import { ScheduleAdminMutation } from './ScheduleAdminMutation'; import { LeagueService } from '@/lib/services/leagues/LeagueService'; import { Result } from '@/lib/contracts/Result'; // Mock dependencies vi.mock('@/lib/services/leagues/LeagueService', () => { return { LeagueService: vi.fn(), }; }); describe('ScheduleAdminMutation', () => { let mutation: ScheduleAdminMutation; let mockServiceInstance: any; beforeEach(() => { vi.clearAllMocks(); mockServiceInstance = { publishAdminSchedule: vi.fn(), unpublishAdminSchedule: vi.fn(), createAdminScheduleRace: vi.fn(), updateAdminScheduleRace: vi.fn(), deleteAdminScheduleRace: vi.fn(), }; // Use mockImplementation to return the instance (LeagueService as any).mockImplementation(function() { return mockServiceInstance; }); mutation = new ScheduleAdminMutation(); }); describe('publishSchedule', () => { describe('happy paths', () => { it('should successfully publish schedule', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; mockServiceInstance.publishAdminSchedule.mockResolvedValue(Result.ok(undefined)); // Act const result = await mutation.publishSchedule(leagueId, seasonId); // Assert expect(result.isOk()).toBe(true); expect(result.unwrap()).toBeUndefined(); expect(mockServiceInstance.publishAdminSchedule).toHaveBeenCalledWith(leagueId, seasonId); expect(mockServiceInstance.publishAdminSchedule).toHaveBeenCalledTimes(1); }); }); describe('failure modes', () => { it('should handle service failure during schedule publication', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; const serviceError = new Error('Service error'); mockServiceInstance.publishAdminSchedule.mockRejectedValue(serviceError); // Act const result = await mutation.publishSchedule(leagueId, seasonId); // Assert expect(result.isErr()).toBe(true); expect(result.getError()).toBe('Failed to publish schedule'); expect(mockServiceInstance.publishAdminSchedule).toHaveBeenCalledTimes(1); }); it('should handle service returning error result', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; const domainError = { type: 'serverError', message: 'Database connection failed' }; mockServiceInstance.publishAdminSchedule.mockResolvedValue(Result.err(domainError)); // Act const result = await mutation.publishSchedule(leagueId, seasonId); // Assert expect(result.isErr()).toBe(true); expect(result.getError()).toBe('Failed to publish schedule'); expect(mockServiceInstance.publishAdminSchedule).toHaveBeenCalledTimes(1); }); }); describe('input validation', () => { it('should accept valid input', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; mockServiceInstance.publishAdminSchedule.mockResolvedValue(Result.ok(undefined)); // Act const result = await mutation.publishSchedule(leagueId, seasonId); // Assert expect(result.isOk()).toBe(true); expect(mockServiceInstance.publishAdminSchedule).toHaveBeenCalledTimes(1); }); }); }); describe('unpublishSchedule', () => { describe('happy paths', () => { it('should successfully unpublish schedule', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; mockServiceInstance.unpublishAdminSchedule.mockResolvedValue(Result.ok(undefined)); // Act const result = await mutation.unpublishSchedule(leagueId, seasonId); // Assert expect(result.isOk()).toBe(true); expect(result.unwrap()).toBeUndefined(); expect(mockServiceInstance.unpublishAdminSchedule).toHaveBeenCalledWith(leagueId, seasonId); expect(mockServiceInstance.unpublishAdminSchedule).toHaveBeenCalledTimes(1); }); }); describe('failure modes', () => { it('should handle service failure during schedule unpublishing', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; const serviceError = new Error('Service error'); mockServiceInstance.unpublishAdminSchedule.mockRejectedValue(serviceError); // Act const result = await mutation.unpublishSchedule(leagueId, seasonId); // Assert expect(result.isErr()).toBe(true); expect(result.getError()).toBe('Failed to unpublish schedule'); expect(mockServiceInstance.unpublishAdminSchedule).toHaveBeenCalledTimes(1); }); it('should handle service returning error result', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; const domainError = { type: 'serverError', message: 'Database connection failed' }; mockServiceInstance.unpublishAdminSchedule.mockResolvedValue(Result.err(domainError)); // Act const result = await mutation.unpublishSchedule(leagueId, seasonId); // Assert expect(result.isErr()).toBe(true); expect(result.getError()).toBe('Failed to unpublish schedule'); expect(mockServiceInstance.unpublishAdminSchedule).toHaveBeenCalledTimes(1); }); }); describe('input validation', () => { it('should accept valid input', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; mockServiceInstance.unpublishAdminSchedule.mockResolvedValue(Result.ok(undefined)); // Act const result = await mutation.unpublishSchedule(leagueId, seasonId); // Assert expect(result.isOk()).toBe(true); expect(mockServiceInstance.unpublishAdminSchedule).toHaveBeenCalledTimes(1); }); }); }); describe('createRace', () => { describe('happy paths', () => { it('should successfully create race', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; const input = { track: 'Track Name', car: 'Car Model', scheduledAtIso: '2024-01-01T12:00:00Z', }; mockServiceInstance.createAdminScheduleRace.mockResolvedValue(Result.ok(undefined)); // Act const result = await mutation.createRace(leagueId, seasonId, input); // Assert expect(result.isOk()).toBe(true); expect(result.unwrap()).toBeUndefined(); expect(mockServiceInstance.createAdminScheduleRace).toHaveBeenCalledWith(leagueId, seasonId, input); expect(mockServiceInstance.createAdminScheduleRace).toHaveBeenCalledTimes(1); }); }); describe('failure modes', () => { it('should handle service failure during race creation', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; const input = { track: 'Track Name', car: 'Car Model', scheduledAtIso: '2024-01-01T12:00:00Z', }; const serviceError = new Error('Service error'); mockServiceInstance.createAdminScheduleRace.mockRejectedValue(serviceError); // Act const result = await mutation.createRace(leagueId, seasonId, input); // Assert expect(result.isErr()).toBe(true); expect(result.getError()).toBe('Failed to create race'); expect(mockServiceInstance.createAdminScheduleRace).toHaveBeenCalledTimes(1); }); it('should handle service returning error result', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; const input = { track: 'Track Name', car: 'Car Model', scheduledAtIso: '2024-01-01T12:00:00Z', }; const domainError = { type: 'serverError', message: 'Database connection failed' }; mockServiceInstance.createAdminScheduleRace.mockResolvedValue(Result.err(domainError)); // Act const result = await mutation.createRace(leagueId, seasonId, input); // Assert expect(result.isErr()).toBe(true); expect(result.getError()).toBe('Failed to create race'); expect(mockServiceInstance.createAdminScheduleRace).toHaveBeenCalledTimes(1); }); }); describe('input validation', () => { it('should accept valid input', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; const input = { track: 'Track Name', car: 'Car Model', scheduledAtIso: '2024-01-01T12:00:00Z', }; mockServiceInstance.createAdminScheduleRace.mockResolvedValue(Result.ok(undefined)); // Act const result = await mutation.createRace(leagueId, seasonId, input); // Assert expect(result.isOk()).toBe(true); expect(mockServiceInstance.createAdminScheduleRace).toHaveBeenCalledTimes(1); }); }); }); describe('updateRace', () => { describe('happy paths', () => { it('should successfully update race', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; const raceId = 'race-789'; const input = { track: 'Updated Track', car: 'Updated Car', scheduledAtIso: '2024-01-02T12:00:00Z', }; mockServiceInstance.updateAdminScheduleRace.mockResolvedValue(Result.ok(undefined)); // Act const result = await mutation.updateRace(leagueId, seasonId, raceId, input); // Assert expect(result.isOk()).toBe(true); expect(result.unwrap()).toBeUndefined(); expect(mockServiceInstance.updateAdminScheduleRace).toHaveBeenCalledWith(leagueId, seasonId, raceId, input); expect(mockServiceInstance.updateAdminScheduleRace).toHaveBeenCalledTimes(1); }); it('should successfully update race with partial input', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; const raceId = 'race-789'; const input = { track: 'Updated Track', }; mockServiceInstance.updateAdminScheduleRace.mockResolvedValue(Result.ok(undefined)); // Act const result = await mutation.updateRace(leagueId, seasonId, raceId, input); // Assert expect(result.isOk()).toBe(true); expect(result.unwrap()).toBeUndefined(); expect(mockServiceInstance.updateAdminScheduleRace).toHaveBeenCalledWith(leagueId, seasonId, raceId, input); expect(mockServiceInstance.updateAdminScheduleRace).toHaveBeenCalledTimes(1); }); }); describe('failure modes', () => { it('should handle service failure during race update', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; const raceId = 'race-789'; const input = { track: 'Updated Track', car: 'Updated Car', scheduledAtIso: '2024-01-02T12:00:00Z', }; const serviceError = new Error('Service error'); mockServiceInstance.updateAdminScheduleRace.mockRejectedValue(serviceError); // Act const result = await mutation.updateRace(leagueId, seasonId, raceId, input); // Assert expect(result.isErr()).toBe(true); expect(result.getError()).toBe('Failed to update race'); expect(mockServiceInstance.updateAdminScheduleRace).toHaveBeenCalledTimes(1); }); it('should handle service returning error result', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; const raceId = 'race-789'; const input = { track: 'Updated Track', car: 'Updated Car', scheduledAtIso: '2024-01-02T12:00:00Z', }; const domainError = { type: 'serverError', message: 'Database connection failed' }; mockServiceInstance.updateAdminScheduleRace.mockResolvedValue(Result.err(domainError)); // Act const result = await mutation.updateRace(leagueId, seasonId, raceId, input); // Assert expect(result.isErr()).toBe(true); expect(result.getError()).toBe('Failed to update race'); expect(mockServiceInstance.updateAdminScheduleRace).toHaveBeenCalledTimes(1); }); }); describe('input validation', () => { it('should accept valid input', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; const raceId = 'race-789'; const input = { track: 'Updated Track', car: 'Updated Car', scheduledAtIso: '2024-01-02T12:00:00Z', }; mockServiceInstance.updateAdminScheduleRace.mockResolvedValue(Result.ok(undefined)); // Act const result = await mutation.updateRace(leagueId, seasonId, raceId, input); // Assert expect(result.isOk()).toBe(true); expect(mockServiceInstance.updateAdminScheduleRace).toHaveBeenCalledTimes(1); }); }); }); describe('deleteRace', () => { describe('happy paths', () => { it('should successfully delete race', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; const raceId = 'race-789'; mockServiceInstance.deleteAdminScheduleRace.mockResolvedValue(Result.ok(undefined)); // Act const result = await mutation.deleteRace(leagueId, seasonId, raceId); // Assert expect(result.isOk()).toBe(true); expect(result.unwrap()).toBeUndefined(); expect(mockServiceInstance.deleteAdminScheduleRace).toHaveBeenCalledWith(leagueId, seasonId, raceId); expect(mockServiceInstance.deleteAdminScheduleRace).toHaveBeenCalledTimes(1); }); }); describe('failure modes', () => { it('should handle service failure during race deletion', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; const raceId = 'race-789'; const serviceError = new Error('Service error'); mockServiceInstance.deleteAdminScheduleRace.mockRejectedValue(serviceError); // Act const result = await mutation.deleteRace(leagueId, seasonId, raceId); // Assert expect(result.isErr()).toBe(true); expect(result.getError()).toBe('Failed to delete race'); expect(mockServiceInstance.deleteAdminScheduleRace).toHaveBeenCalledTimes(1); }); it('should handle service returning error result', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; const raceId = 'race-789'; const domainError = { type: 'serverError', message: 'Database connection failed' }; mockServiceInstance.deleteAdminScheduleRace.mockResolvedValue(Result.err(domainError)); // Act const result = await mutation.deleteRace(leagueId, seasonId, raceId); // Assert expect(result.isErr()).toBe(true); expect(result.getError()).toBe('Failed to delete race'); expect(mockServiceInstance.deleteAdminScheduleRace).toHaveBeenCalledTimes(1); }); }); describe('input validation', () => { it('should accept valid input', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; const raceId = 'race-789'; mockServiceInstance.deleteAdminScheduleRace.mockResolvedValue(Result.ok(undefined)); // Act const result = await mutation.deleteRace(leagueId, seasonId, raceId); // Assert expect(result.isOk()).toBe(true); expect(mockServiceInstance.deleteAdminScheduleRace).toHaveBeenCalledTimes(1); }); }); }); describe('service instantiation', () => { it('should create LeagueService instance', () => { // Arrange & Act const mutation = new ScheduleAdminMutation(); // Assert expect(mutation).toBeInstanceOf(ScheduleAdminMutation); }); }); describe('result shape', () => { it('should return void on successful schedule publication', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; mockServiceInstance.publishAdminSchedule.mockResolvedValue(Result.ok(undefined)); // Act const result = await mutation.publishSchedule(leagueId, seasonId); // Assert expect(result.isOk()).toBe(true); expect(result.unwrap()).toBeUndefined(); }); it('should return void on successful schedule unpublishing', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; mockServiceInstance.unpublishAdminSchedule.mockResolvedValue(Result.ok(undefined)); // Act const result = await mutation.unpublishSchedule(leagueId, seasonId); // Assert expect(result.isOk()).toBe(true); expect(result.unwrap()).toBeUndefined(); }); it('should return void on successful race creation', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; const input = { track: 'Track Name', car: 'Car Model', scheduledAtIso: '2024-01-01T12:00:00Z', }; mockServiceInstance.createAdminScheduleRace.mockResolvedValue(Result.ok(undefined)); // Act const result = await mutation.createRace(leagueId, seasonId, input); // Assert expect(result.isOk()).toBe(true); expect(result.unwrap()).toBeUndefined(); }); it('should return void on successful race update', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; const raceId = 'race-789'; const input = { track: 'Updated Track', car: 'Updated Car', scheduledAtIso: '2024-01-02T12:00:00Z', }; mockServiceInstance.updateAdminScheduleRace.mockResolvedValue(Result.ok(undefined)); // Act const result = await mutation.updateRace(leagueId, seasonId, raceId, input); // Assert expect(result.isOk()).toBe(true); expect(result.unwrap()).toBeUndefined(); }); it('should return void on successful race deletion', async () => { // Arrange const leagueId = 'league-123'; const seasonId = 'season-456'; const raceId = 'race-789'; mockServiceInstance.deleteAdminScheduleRace.mockResolvedValue(Result.ok(undefined)); // Act const result = await mutation.deleteRace(leagueId, seasonId, raceId); // Assert expect(result.isOk()).toBe(true); expect(result.unwrap()).toBeUndefined(); }); }); });