import { describe, it, expect, vi, Mocked } from 'vitest'; import { DriverService } from './DriverService'; import { DriversApiClient } from '../../api/drivers/DriversApiClient'; import { DriverLeaderboardViewModel } from '../../view-models/DriverLeaderboardViewModel'; import { DriverViewModel } from '../../view-models/DriverViewModel'; import { CompleteOnboardingViewModel } from '../../view-models/CompleteOnboardingViewModel'; describe('DriverService', () => { let mockApiClient: Mocked; let service: DriverService; beforeEach(() => { mockApiClient = { getLeaderboard: vi.fn(), completeOnboarding: vi.fn(), getCurrent: vi.fn(), } as Mocked; service = new DriverService(mockApiClient); }); describe('getDriverLeaderboard', () => { it('should call apiClient.getLeaderboard and return DriverLeaderboardViewModel', async () => { const mockDto = { drivers: [ { id: 'driver-1', name: 'John Doe', rating: 2500, wins: 10, podiums: 15, totalRaces: 50, country: 'US', avatarUrl: 'https://example.com/avatar.jpg', }, ], }; mockApiClient.getLeaderboard.mockResolvedValue(mockDto); const result = await service.getDriverLeaderboard(); expect(mockApiClient.getLeaderboard).toHaveBeenCalled(); expect(result).toBeInstanceOf(DriverLeaderboardViewModel); expect(result.drivers).toHaveLength(1); expect(result.drivers[0].name).toBe('John Doe'); }); it('should throw error when apiClient.getLeaderboard fails', async () => { const error = new Error('API call failed'); mockApiClient.getLeaderboard.mockRejectedValue(error); await expect(service.getDriverLeaderboard()).rejects.toThrow('API call failed'); }); }); describe('completeDriverOnboarding', () => { it('should call apiClient.completeOnboarding and return CompleteOnboardingViewModel', async () => { const input = { iracingId: '123456', country: 'US', }; const mockDto = { success: true, driverId: 'driver-123', }; mockApiClient.completeOnboarding.mockResolvedValue(mockDto); const result = await service.completeDriverOnboarding(input); expect(mockApiClient.completeOnboarding).toHaveBeenCalledWith(input); expect(result).toBeInstanceOf(CompleteOnboardingViewModel); expect(result.success).toBe(true); expect(result.isSuccessful).toBe(true); }); it('should throw error when apiClient.completeOnboarding fails', async () => { const input = { iracingId: '123456', country: 'US', }; const error = new Error('API call failed'); mockApiClient.completeOnboarding.mockRejectedValue(error); await expect(service.completeDriverOnboarding(input)).rejects.toThrow('API call failed'); }); }); describe('getCurrentDriver', () => { it('should call apiClient.getCurrent and return DriverViewModel when driver exists', async () => { const mockDto = { id: 'driver-123', name: 'John Doe', avatarUrl: 'https://example.com/avatar.jpg', iracingId: '123456', rating: 2500, }; mockApiClient.getCurrent.mockResolvedValue(mockDto); const result = await service.getCurrentDriver(); expect(mockApiClient.getCurrent).toHaveBeenCalled(); expect(result).toBeInstanceOf(DriverViewModel); expect(result?.id).toBe('driver-123'); expect(result?.name).toBe('John Doe'); expect(result?.hasIracingId).toBe(true); expect(result?.formattedRating).toBe('2500'); }); it('should return null when apiClient.getCurrent returns null', async () => { mockApiClient.getCurrent.mockResolvedValue(null); const result = await service.getCurrentDriver(); expect(mockApiClient.getCurrent).toHaveBeenCalled(); expect(result).toBeNull(); }); it('should throw error when apiClient.getCurrent fails', async () => { const error = new Error('API call failed'); mockApiClient.getCurrent.mockRejectedValue(error); await expect(service.getCurrentDriver()).rejects.toThrow('API call failed'); }); }); });