import { describe, it, expect, vi, type Mock } from 'vitest'; import { RequestAvatarGenerationUseCase } from './RequestAvatarGenerationUseCase'; import type { IAvatarGenerationRepository } from '../../domain/repositories/IAvatarGenerationRepository'; import type { FaceValidationPort } from '../ports/FaceValidationPort'; import type { AvatarGenerationPort } from '../ports/AvatarGenerationPort'; import type { Logger } from '@core/shared/application'; import { AvatarGenerationRequest } from '../../domain/entities/AvatarGenerationRequest'; import type { RequestAvatarGenerationInput } from './RequestAvatarGenerationUseCase'; describe('RequestAvatarGenerationUseCase', () => { let avatarRepo: { save: Mock; findById: Mock; }; let faceValidation: { validateFacePhoto: Mock; }; let avatarGeneration: { generateAvatars: Mock; }; let logger: Logger; let useCase: RequestAvatarGenerationUseCase; beforeEach(() => { avatarRepo = { save: vi.fn(), findById: vi.fn(), } as unknown as IAvatarGenerationRepository as any; faceValidation = { validateFacePhoto: vi.fn(), } as unknown as FaceValidationPort as any; avatarGeneration = { generateAvatars: vi.fn(), } as unknown as AvatarGenerationPort as any; logger = { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn(), } as unknown as Logger; useCase = new RequestAvatarGenerationUseCase( avatarRepo as unknown as IAvatarGenerationRepository, faceValidation as unknown as FaceValidationPort, avatarGeneration as unknown as AvatarGenerationPort, logger, ); }); const createPresenter = () => { const presenter: { present: Mock; result?: any } = { present: vi.fn((result) => { presenter.result = result; }), result: undefined, }; return presenter; }; it('fails when face validation fails', async () => { const input: RequestAvatarGenerationInput = { userId: 'user-1', facePhotoData: 'photo-data', suitColor: 'red', style: 'realistic', }; const presenter = createPresenter(); faceValidation.validateFacePhoto.mockResolvedValue({ isValid: false, hasFace: false, faceCount: 0, errorMessage: 'No face detected', }); await useCase.execute(input, presenter as any); expect((presenter.present as Mock)).toHaveBeenCalledWith({ requestId: expect.any(String), status: 'failed', errorMessage: 'No face detected', }); }); it('completes request and returns avatar URLs on success', async () => { const input: RequestAvatarGenerationInput = { userId: 'user-1', facePhotoData: 'photo-data', suitColor: 'red', style: 'realistic', }; const presenter = createPresenter(); faceValidation.validateFacePhoto.mockResolvedValue({ isValid: true, hasFace: true, faceCount: 1, }); avatarGeneration.generateAvatars.mockResolvedValue({ success: true, avatars: [ { url: 'https://example.com/avatar1.png' }, { url: 'https://example.com/avatar2.png' }, ], }); await useCase.execute(input, presenter as any); expect(faceValidation.validateFacePhoto).toHaveBeenCalled(); expect(avatarGeneration.generateAvatars).toHaveBeenCalled(); expect((presenter.present as Mock)).toHaveBeenCalledWith({ requestId: expect.any(String), status: 'completed', avatarUrls: [ 'https://example.com/avatar1.png', 'https://example.com/avatar2.png', ], }); }); });