import { describe, it, expect, vi, type Mock } from 'vitest'; import { AwardPrizeUseCase, type AwardPrizeInput } from './AwardPrizeUseCase'; import type { IPrizeRepository } from '../../domain/repositories/IPrizeRepository'; import { PrizeType, type Prize } from '../../domain/entities/Prize'; describe('AwardPrizeUseCase', () => { let prizeRepository: { findById: Mock; update: Mock }; let useCase: AwardPrizeUseCase; beforeEach(() => { prizeRepository = { findById: vi.fn(), update: vi.fn(), }; useCase = new AwardPrizeUseCase( prizeRepository as unknown as IPrizeRepository, ); }); it('returns PRIZE_NOT_FOUND when prize does not exist', async () => { prizeRepository.findById.mockResolvedValue(null); const input: AwardPrizeInput = { prizeId: 'prize-1', driverId: 'driver-1' }; const result = await useCase.execute(input); expect(result.isErr()).toBe(true); expect(result.unwrapErr().code).toBe('PRIZE_NOT_FOUND'); expect(prizeRepository.update).not.toHaveBeenCalled(); }); it('returns PRIZE_ALREADY_AWARDED when prize is already awarded', async () => { const prize: Prize = { id: 'prize-1', leagueId: 'league-1', seasonId: 'season-1', position: 1, name: 'Winner', amount: 100, type: PrizeType.CASH, awarded: true, awardedTo: 'driver-x', awardedAt: new Date(), createdAt: new Date(), }; prizeRepository.findById.mockResolvedValue(prize); const input: AwardPrizeInput = { prizeId: 'prize-1', driverId: 'driver-1' }; const result = await useCase.execute(input); expect(result.isErr()).toBe(true); expect(result.unwrapErr().code).toBe('PRIZE_ALREADY_AWARDED'); expect(prizeRepository.update).not.toHaveBeenCalled(); }); it('awards prize and returns updated prize', async () => { const prize: Prize = { id: 'prize-1', leagueId: 'league-1', seasonId: 'season-1', position: 1, name: 'Winner', amount: 100, type: PrizeType.CASH, awarded: false, createdAt: new Date('2024-01-01T00:00:00.000Z'), }; prizeRepository.findById.mockResolvedValue(prize); prizeRepository.update.mockImplementation(async (p: Prize) => p); const input: AwardPrizeInput = { prizeId: 'prize-1', driverId: 'driver-1' }; const result = await useCase.execute(input); expect(result.isOk()).toBe(true); expect(prizeRepository.update).toHaveBeenCalledWith( expect.objectContaining({ id: 'prize-1', awarded: true, awardedTo: 'driver-1', awardedAt: expect.any(Date), }), ); const value = result.value; expect(value.prize).toEqual( expect.objectContaining({ id: 'prize-1', awarded: true, awardedTo: 'driver-1', awardedAt: expect.any(Date), }), ); }); });