import { describe, it, expect, vi, Mocked } from 'vitest'; import { RaceResultsService } from './RaceResultsService'; import { RacesApiClient } from '@/lib/api/races/RacesApiClient'; import { RaceResultsDetailViewModel } from '@/lib/view-models/RaceResultsDetailViewModel'; import { RaceWithSOFViewModel } from '@/lib/view-models/RaceWithSOFViewModel'; import { ImportRaceResultsSummaryViewModel } from '@/lib/view-models/ImportRaceResultsSummaryViewModel'; import type { RaceResultsDetailDTO, RaceWithSOFDTO } from '@/lib/types/generated'; describe('RaceResultsService', () => { let mockApiClient: Mocked; let service: RaceResultsService; beforeEach(() => { mockApiClient = { getResultsDetail: vi.fn(), getWithSOF: vi.fn(), importResults: vi.fn(), } as Mocked; service = new RaceResultsService(mockApiClient); }); describe('getResultsDetail', () => { it('should call apiClient.getResultsDetail and return RaceResultsDetailViewModel', async () => { const raceId = 'race-123'; const currentUserId = 'user-456'; const mockDto: RaceResultsDetailDTO = { raceId, track: 'Test Track', }; mockApiClient.getResultsDetail.mockResolvedValue(mockDto); const result = await service.getResultsDetail(raceId, currentUserId); expect(mockApiClient.getResultsDetail).toHaveBeenCalledWith(raceId); expect(result).toBeInstanceOf(RaceResultsDetailViewModel); expect(result.raceId).toBe(raceId); expect(result.track).toBe('Test Track'); }); it('should handle undefined currentUserId', async () => { const raceId = 'race-123'; const mockDto: RaceResultsDetailDTO = { raceId, track: 'Test Track', }; mockApiClient.getResultsDetail.mockResolvedValue(mockDto); const result = await service.getResultsDetail(raceId); expect(result).toBeInstanceOf(RaceResultsDetailViewModel); expect(result.currentUserId).toBe(''); }); it('should throw error when apiClient.getResultsDetail fails', async () => { const raceId = 'race-123'; const currentUserId = 'user-456'; const error = new Error('API call failed'); mockApiClient.getResultsDetail.mockRejectedValue(error); await expect(service.getResultsDetail(raceId, currentUserId)).rejects.toThrow('API call failed'); }); }); describe('getWithSOF', () => { it('should call apiClient.getWithSOF and return RaceWithSOFViewModel', async () => { const raceId = 'race-123'; const mockDto: RaceWithSOFDTO = { id: raceId, track: 'Test Track', }; mockApiClient.getWithSOF.mockResolvedValue(mockDto); const result = await service.getWithSOF(raceId); expect(mockApiClient.getWithSOF).toHaveBeenCalledWith(raceId); expect(result).toBeInstanceOf(RaceWithSOFViewModel); expect(result.id).toBe(raceId); expect(result.track).toBe('Test Track'); }); it('should throw error when apiClient.getWithSOF fails', async () => { const raceId = 'race-123'; const error = new Error('API call failed'); mockApiClient.getWithSOF.mockRejectedValue(error); await expect(service.getWithSOF(raceId)).rejects.toThrow('API call failed'); }); }); describe('importResults', () => { it('should call apiClient.importResults and return ImportRaceResultsSummaryViewModel', async () => { const raceId = 'race-123'; const input = { raceId, results: [{ position: 1 }] }; const mockDto = { success: true, raceId, driversProcessed: 10, resultsRecorded: 10, errors: ['Error 1'], }; mockApiClient.importResults.mockResolvedValue(mockDto as any); const result = await service.importResults(raceId, input); expect(mockApiClient.importResults).toHaveBeenCalledWith(raceId, input); expect(result).toBeInstanceOf(ImportRaceResultsSummaryViewModel); expect(result.raceId).toBe(raceId); expect(result.driversProcessed).toBe(10); expect(result.resultsRecorded).toBe(10); expect(result.errors).toEqual(['Error 1']); }); it('should handle successful import with no errors', async () => { const raceId = 'race-123'; const input = { raceId, results: [] }; const mockDto = { success: true, raceId, driversProcessed: 5, resultsRecorded: 5, errors: [], }; mockApiClient.importResults.mockResolvedValue(mockDto as any); const result = await service.importResults(raceId, input); expect(result.driversProcessed).toBe(5); expect(result.resultsRecorded).toBe(5); expect(result.errors).toEqual([]); }); it('should throw error when apiClient.importResults fails', async () => { const raceId = 'race-123'; const input = { raceId, results: [] }; const error = new Error('API call failed'); mockApiClient.importResults.mockRejectedValue(error); await expect(service.importResults(raceId, input)).rejects.toThrow('API call failed'); }); }); });