import { describe, it, expect, vi, type Mock } from 'vitest'; import { GetMembershipFeesUseCase, type GetMembershipFeesInput } from './GetMembershipFeesUseCase'; import type { IMembershipFeeRepository, IMemberPaymentRepository } from '../../domain/repositories/IMembershipFeeRepository'; import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort'; describe('GetMembershipFeesUseCase', () => { let membershipFeeRepository: { findByLeagueId: Mock; }; let memberPaymentRepository: { findByLeagueIdAndDriverId: Mock; }; let output: { present: Mock; }; let useCase: GetMembershipFeesUseCase; beforeEach(() => { membershipFeeRepository = { findByLeagueId: vi.fn(), }; memberPaymentRepository = { findByLeagueIdAndDriverId: vi.fn(), }; output = { present: vi.fn(), }; useCase = new GetMembershipFeesUseCase( membershipFeeRepository as unknown as IMembershipFeeRepository, memberPaymentRepository as unknown as IMemberPaymentRepository, output as unknown as UseCaseOutputPort, ); }); it('returns error when leagueId is missing', async () => { const input = { leagueId: '' } as GetMembershipFeesInput; const result = await useCase.execute(input); expect(result.isErr()).toBe(true); expect(result.unwrapErr().code).toBe('INVALID_INPUT'); }); it('returns null fee and empty payments when no fee exists', async () => { const input: GetMembershipFeesInput = { leagueId: 'league-1' }; membershipFeeRepository.findByLeagueId.mockResolvedValue(null); const result = await useCase.execute(input); expect(result.isOk()).toBe(true); expect(membershipFeeRepository.findByLeagueId).toHaveBeenCalledWith('league-1'); expect(memberPaymentRepository.findByLeagueIdAndDriverId).not.toHaveBeenCalled(); expect(output.present).toHaveBeenCalledWith({ fee: null, payments: [], }); }); it('maps fee and payments when fee and driverId are provided', async () => { const input: GetMembershipFeesInput = { leagueId: 'league-1', driverId: 'driver-1' }; const fee = { id: 'fee-1', leagueId: 'league-1', seasonId: 'season-1', type: 'season', amount: 100, enabled: true, createdAt: new Date('2024-01-01'), updatedAt: new Date('2024-01-02'), }; const payments = [ { id: 'pay-1', feeId: 'fee-1', driverId: 'driver-1', amount: 100, platformFee: 5, netAmount: 95, status: 'paid', dueDate: new Date('2024-02-01'), paidAt: new Date('2024-01-15'), }, ]; membershipFeeRepository.findByLeagueId.mockResolvedValue(fee); memberPaymentRepository.findByLeagueIdAndDriverId.mockResolvedValue(payments); const result = await useCase.execute(input); expect(result.isOk()).toBe(true); expect(membershipFeeRepository.findByLeagueId).toHaveBeenCalledWith('league-1'); expect(memberPaymentRepository.findByLeagueIdAndDriverId).toHaveBeenCalledWith('league-1', 'driver-1', membershipFeeRepository as unknown as IMembershipFeeRepository); expect(output.present).toHaveBeenCalledWith({ fee, payments, }); }); });