Files
gridpilot.gg/core/payments/application/use-cases/GetMembershipFeesUseCase.test.ts
2025-12-21 17:05:36 +01:00

106 lines
3.3 KiB
TypeScript

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(),
} as unknown as IMembershipFeeRepository as any;
memberPaymentRepository = {
findByLeagueIdAndDriverId: vi.fn(),
} as unknown as IMemberPaymentRepository as any;
output = {
present: vi.fn(),
};
useCase = new GetMembershipFeesUseCase(
membershipFeeRepository as unknown as IMembershipFeeRepository,
memberPaymentRepository as unknown as IMemberPaymentRepository,
output as unknown as UseCaseOutputPort<any>,
);
});
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,
});
});
});