import { describe, it, expect, vi, Mocked } from 'vitest'; import { AvatarService } from './AvatarService'; import { MediaApiClient } from '@/lib/api/media/MediaApiClient'; import { RequestAvatarGenerationViewModel } from '@/lib/view-models/RequestAvatarGenerationViewModel'; import { AvatarViewModel } from '@/lib/view-models/AvatarViewModel'; import { UpdateAvatarViewModel } from '@/lib/view-models/UpdateAvatarViewModel'; describe('AvatarService', () => { let mockApiClient: Mocked; let service: AvatarService; beforeEach(() => { mockApiClient = { requestAvatarGeneration: vi.fn(), getAvatar: vi.fn(), updateAvatar: vi.fn(), } as Mocked; service = new AvatarService(mockApiClient); }); describe('requestAvatarGeneration', () => { it('should call apiClient.requestAvatarGeneration with correct input and return view model', async () => { const input = { userId: 'user-123', facePhotoData: 'base64data', suitColor: 'red' as const, }; const expectedOutput = { success: true, avatarUrl: 'https://example.com/avatar.jpg' }; mockApiClient.requestAvatarGeneration.mockResolvedValue(expectedOutput); const result = await service.requestAvatarGeneration(input); expect(mockApiClient.requestAvatarGeneration).toHaveBeenCalledWith(input); expect(result).toBeInstanceOf(RequestAvatarGenerationViewModel); expect(result.success).toBe(true); expect(result.avatarUrl).toBe('https://example.com/avatar.jpg'); }); it('should handle error response', async () => { const input = { userId: 'user-123', facePhotoData: 'base64data', suitColor: 'blue' as const, }; const expectedOutput = { success: false, error: 'Generation failed' }; mockApiClient.requestAvatarGeneration.mockResolvedValue(expectedOutput); const result = await service.requestAvatarGeneration(input); expect(result).toBeInstanceOf(RequestAvatarGenerationViewModel); expect(result.success).toBe(false); expect(result.error).toBe('Generation failed'); }); }); describe('getAvatar', () => { it('should call apiClient.getAvatar with driverId and return view model', async () => { const driverId = 'driver-123'; const expectedOutput = { driverId: 'driver-123', avatarUrl: 'https://example.com/avatar.jpg' }; mockApiClient.getAvatar.mockResolvedValue(expectedOutput); const result = await service.getAvatar(driverId); expect(mockApiClient.getAvatar).toHaveBeenCalledWith(driverId); expect(result).toBeInstanceOf(AvatarViewModel); expect(result.driverId).toBe('driver-123'); expect(result.avatarUrl).toBe('https://example.com/avatar.jpg'); expect(result.hasAvatar).toBe(true); }); it('should handle driver without avatar', async () => { const driverId = 'driver-456'; const expectedOutput = { driverId: 'driver-456' }; mockApiClient.getAvatar.mockResolvedValue(expectedOutput); const result = await service.getAvatar(driverId); expect(result).toBeInstanceOf(AvatarViewModel); expect(result.driverId).toBe('driver-456'); expect(result.avatarUrl).toBeUndefined(); expect(result.hasAvatar).toBe(false); }); }); describe('updateAvatar', () => { it('should call apiClient.updateAvatar with correct input and return view model', async () => { const input = { driverId: 'driver-123', avatarUrl: 'https://example.com/new-avatar.jpg' }; const expectedOutput = { success: true }; mockApiClient.updateAvatar.mockResolvedValue(expectedOutput); const result = await service.updateAvatar(input); expect(mockApiClient.updateAvatar).toHaveBeenCalledWith(input); expect(result).toBeInstanceOf(UpdateAvatarViewModel); expect(result.success).toBe(true); expect(result.isSuccessful).toBe(true); expect(result.hasError).toBe(false); }); it('should handle error response', async () => { const input = { driverId: 'driver-123', avatarUrl: 'https://example.com/new-avatar.jpg' }; const expectedOutput = { success: false, error: 'Update failed' }; mockApiClient.updateAvatar.mockResolvedValue(expectedOutput); const result = await service.updateAvatar(input); expect(result).toBeInstanceOf(UpdateAvatarViewModel); expect(result.success).toBe(false); expect(result.error).toBe('Update failed'); expect(result.isSuccessful).toBe(false); expect(result.hasError).toBe(true); }); }); });