import { describe, it, expect, vi, type Mock } from 'vitest'; import { CreateAchievementUseCase, type IAchievementRepository } from './CreateAchievementUseCase'; import type { Logger } from '@core/shared/application'; import { Result } from '@core/shared/application/Result'; import { Achievement } from '@core/identity/domain/entities/Achievement'; describe('CreateAchievementUseCase', () => { let achievementRepository: { save: Mock; findById: Mock; }; let logger: Logger; let useCase: CreateAchievementUseCase; beforeEach(() => { achievementRepository = { save: vi.fn(), findById: vi.fn(), }; logger = { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn(), } as unknown as Logger; useCase = new CreateAchievementUseCase( achievementRepository as unknown as IAchievementRepository, logger, ); }); it('creates an achievement and persists it', async () => { const props = { id: 'achievement-1', name: 'First Race', description: 'Complete your first race', category: 'driver' as const, rarity: 'common' as const, points: 10, requirements: [{ type: 'races_completed' as const, value: 1, operator: '>=' as const }], isSecret: false, }; const result = await useCase.execute(props); expect(result.isOk()).toBe(true); const createResult = result.unwrap(); expect(createResult.achievement).toBeDefined(); expect(createResult.achievement.id).toBe(props.id); expect(createResult.achievement.name).toBe(props.name); expect(achievementRepository.save).toHaveBeenCalled(); }); it('returns error when repository save fails', async () => { achievementRepository.save.mockRejectedValue(new Error('Database error')); const result = await useCase.execute({ id: 'achievement-1', name: 'First Race', description: 'Complete your first race', category: 'driver' as const, rarity: 'common' as const, points: 10, requirements: [{ type: 'races_completed' as const, value: 1, operator: '>=' as const }], isSecret: false, }); expect(result.isErr()).toBe(true); expect(result.unwrapErr().code).toBe('REPOSITORY_ERROR'); expect(logger.error).toHaveBeenCalled(); }); });