test apps api
This commit is contained in:
313
apps/api/src/domain/payments/PaymentsService.test.ts
Normal file
313
apps/api/src/domain/payments/PaymentsService.test.ts
Normal file
@@ -0,0 +1,313 @@
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
import { Result } from '@core/shared/application/Result';
|
||||
import { PaymentsService } from './PaymentsService';
|
||||
|
||||
describe('PaymentsService', () => {
|
||||
const logger = { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() };
|
||||
|
||||
function makeService(overrides?: Partial<Record<string, any>>) {
|
||||
const getPaymentsUseCase = overrides?.getPaymentsUseCase ?? { execute: vi.fn(async () => Result.ok(undefined)) };
|
||||
const createPaymentUseCase = overrides?.createPaymentUseCase ?? { execute: vi.fn(async () => Result.ok(undefined)) };
|
||||
const updatePaymentStatusUseCase =
|
||||
overrides?.updatePaymentStatusUseCase ?? { execute: vi.fn(async () => Result.ok(undefined)) };
|
||||
const getMembershipFeesUseCase =
|
||||
overrides?.getMembershipFeesUseCase ?? { execute: vi.fn(async () => Result.ok(undefined)) };
|
||||
const upsertMembershipFeeUseCase =
|
||||
overrides?.upsertMembershipFeeUseCase ?? { execute: vi.fn(async () => Result.ok(undefined)) };
|
||||
const updateMemberPaymentUseCase =
|
||||
overrides?.updateMemberPaymentUseCase ?? { execute: vi.fn(async () => Result.ok(undefined)) };
|
||||
const getPrizesUseCase = overrides?.getPrizesUseCase ?? { execute: vi.fn(async () => Result.ok(undefined)) };
|
||||
const createPrizeUseCase = overrides?.createPrizeUseCase ?? { execute: vi.fn(async () => Result.ok(undefined)) };
|
||||
const awardPrizeUseCase = overrides?.awardPrizeUseCase ?? { execute: vi.fn(async () => Result.ok(undefined)) };
|
||||
const deletePrizeUseCase = overrides?.deletePrizeUseCase ?? { execute: vi.fn(async () => Result.ok(undefined)) };
|
||||
const getWalletUseCase = overrides?.getWalletUseCase ?? { execute: vi.fn(async () => Result.ok(undefined)) };
|
||||
const processWalletTransactionUseCase =
|
||||
overrides?.processWalletTransactionUseCase ?? { execute: vi.fn(async () => Result.ok(undefined)) };
|
||||
|
||||
const getPaymentsPresenter = overrides?.getPaymentsPresenter ?? { getResponseModel: vi.fn(() => ({ payments: [] })) };
|
||||
const createPaymentPresenter =
|
||||
overrides?.createPaymentPresenter ?? { getResponseModel: vi.fn(() => ({ paymentId: 'p1' })) };
|
||||
const updatePaymentStatusPresenter =
|
||||
overrides?.updatePaymentStatusPresenter ?? { getResponseModel: vi.fn(() => ({ success: true })) };
|
||||
|
||||
const getMembershipFeesPresenter = overrides?.getMembershipFeesPresenter ?? { viewModel: { fee: null, payments: [] } };
|
||||
const upsertMembershipFeePresenter = overrides?.upsertMembershipFeePresenter ?? { viewModel: { success: true } };
|
||||
const updateMemberPaymentPresenter = overrides?.updateMemberPaymentPresenter ?? { viewModel: { success: true } };
|
||||
|
||||
const getPrizesPresenter = overrides?.getPrizesPresenter ?? { viewModel: { prizes: [] } };
|
||||
const createPrizePresenter = overrides?.createPrizePresenter ?? { viewModel: { success: true } };
|
||||
const awardPrizePresenter = overrides?.awardPrizePresenter ?? { viewModel: { success: true } };
|
||||
const deletePrizePresenter = overrides?.deletePrizePresenter ?? { viewModel: { success: true } };
|
||||
|
||||
const getWalletPresenter = overrides?.getWalletPresenter ?? { viewModel: { balance: 0 } };
|
||||
const processWalletTransactionPresenter =
|
||||
overrides?.processWalletTransactionPresenter ?? { viewModel: { success: true } };
|
||||
|
||||
const service = new PaymentsService(
|
||||
getPaymentsUseCase as any,
|
||||
createPaymentUseCase as any,
|
||||
updatePaymentStatusUseCase as any,
|
||||
getMembershipFeesUseCase as any,
|
||||
upsertMembershipFeeUseCase as any,
|
||||
updateMemberPaymentUseCase as any,
|
||||
getPrizesUseCase as any,
|
||||
createPrizeUseCase as any,
|
||||
awardPrizeUseCase as any,
|
||||
deletePrizeUseCase as any,
|
||||
getWalletUseCase as any,
|
||||
processWalletTransactionUseCase as any,
|
||||
logger as any,
|
||||
getPaymentsPresenter as any,
|
||||
createPaymentPresenter as any,
|
||||
updatePaymentStatusPresenter as any,
|
||||
getMembershipFeesPresenter as any,
|
||||
upsertMembershipFeePresenter as any,
|
||||
updateMemberPaymentPresenter as any,
|
||||
getPrizesPresenter as any,
|
||||
createPrizePresenter as any,
|
||||
awardPrizePresenter as any,
|
||||
deletePrizePresenter as any,
|
||||
getWalletPresenter as any,
|
||||
processWalletTransactionPresenter as any,
|
||||
);
|
||||
|
||||
return {
|
||||
service,
|
||||
getPaymentsUseCase,
|
||||
createPaymentUseCase,
|
||||
updatePaymentStatusUseCase,
|
||||
getMembershipFeesUseCase,
|
||||
upsertMembershipFeeUseCase,
|
||||
updateMemberPaymentUseCase,
|
||||
getPrizesUseCase,
|
||||
createPrizeUseCase,
|
||||
awardPrizeUseCase,
|
||||
deletePrizeUseCase,
|
||||
getWalletUseCase,
|
||||
processWalletTransactionUseCase,
|
||||
getPaymentsPresenter,
|
||||
createPaymentPresenter,
|
||||
updatePaymentStatusPresenter,
|
||||
getMembershipFeesPresenter,
|
||||
upsertMembershipFeePresenter,
|
||||
updateMemberPaymentPresenter,
|
||||
getPrizesPresenter,
|
||||
createPrizePresenter,
|
||||
awardPrizePresenter,
|
||||
deletePrizePresenter,
|
||||
getWalletPresenter,
|
||||
processWalletTransactionPresenter,
|
||||
};
|
||||
}
|
||||
|
||||
it('getPayments returns presenter model on success', async () => {
|
||||
const { service, getPaymentsUseCase, getPaymentsPresenter } = makeService();
|
||||
await expect(service.getPayments({ leagueId: 'l1' } as any)).resolves.toEqual({ payments: [] });
|
||||
expect(getPaymentsUseCase.execute).toHaveBeenCalledWith({ leagueId: 'l1' });
|
||||
expect(getPaymentsPresenter.getResponseModel).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('getPayments throws when use case returns error (code message)', async () => {
|
||||
const { service } = makeService({
|
||||
getPaymentsUseCase: { execute: vi.fn(async () => Result.err({ code: 'REPOSITORY_ERROR' })) },
|
||||
});
|
||||
await expect(service.getPayments({ leagueId: 'l1' } as any)).rejects.toThrow('REPOSITORY_ERROR');
|
||||
});
|
||||
|
||||
it('createPayment returns presenter model on success', async () => {
|
||||
const { service, createPaymentUseCase, createPaymentPresenter } = makeService({
|
||||
createPaymentPresenter: { getResponseModel: vi.fn(() => ({ paymentId: 'p1' })) },
|
||||
});
|
||||
await expect(service.createPayment({ leagueId: 'l1' } as any)).resolves.toEqual({ paymentId: 'p1' });
|
||||
expect(createPaymentUseCase.execute).toHaveBeenCalledWith({ leagueId: 'l1' });
|
||||
expect(createPaymentPresenter.getResponseModel).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('createPayment throws when use case returns error', async () => {
|
||||
const { service } = makeService({
|
||||
createPaymentUseCase: { execute: vi.fn(async () => Result.err({ code: 'REPOSITORY_ERROR' })) },
|
||||
});
|
||||
await expect(service.createPayment({ leagueId: 'l1' } as any)).rejects.toThrow('REPOSITORY_ERROR');
|
||||
});
|
||||
|
||||
it('updatePaymentStatus returns presenter model on success', async () => {
|
||||
const { service, updatePaymentStatusUseCase, updatePaymentStatusPresenter } = makeService({
|
||||
updatePaymentStatusPresenter: { getResponseModel: vi.fn(() => ({ success: true })) },
|
||||
});
|
||||
await expect(service.updatePaymentStatus({ paymentId: 'p1' } as any)).resolves.toEqual({ success: true });
|
||||
expect(updatePaymentStatusUseCase.execute).toHaveBeenCalledWith({ paymentId: 'p1' });
|
||||
expect(updatePaymentStatusPresenter.getResponseModel).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('updatePaymentStatus throws when use case returns error', async () => {
|
||||
const { service } = makeService({
|
||||
updatePaymentStatusUseCase: { execute: vi.fn(async () => Result.err({ code: 'REPOSITORY_ERROR' })) },
|
||||
});
|
||||
await expect(service.updatePaymentStatus({ paymentId: 'p1' } as any)).rejects.toThrow('REPOSITORY_ERROR');
|
||||
});
|
||||
|
||||
it('getMembershipFees returns viewModel on success', async () => {
|
||||
const { service, getMembershipFeesUseCase, getMembershipFeesPresenter } = makeService({
|
||||
getMembershipFeesPresenter: { viewModel: { fee: { amount: 1 }, payments: [] } },
|
||||
});
|
||||
|
||||
await expect(service.getMembershipFees({ leagueId: 'l1', driverId: 'd1' } as any)).resolves.toEqual({
|
||||
fee: { amount: 1 },
|
||||
payments: [],
|
||||
});
|
||||
expect(getMembershipFeesUseCase.execute).toHaveBeenCalledWith({ leagueId: 'l1', driverId: 'd1' });
|
||||
expect(getMembershipFeesPresenter.viewModel).toBeDefined();
|
||||
});
|
||||
|
||||
it('getMembershipFees throws when use case returns error', async () => {
|
||||
const { service } = makeService({
|
||||
getMembershipFeesUseCase: { execute: vi.fn(async () => Result.err({ code: 'REPOSITORY_ERROR' })) },
|
||||
});
|
||||
await expect(service.getMembershipFees({ leagueId: 'l1' } as any)).rejects.toThrow('REPOSITORY_ERROR');
|
||||
});
|
||||
|
||||
it('upsertMembershipFee returns viewModel on success', async () => {
|
||||
const { service, upsertMembershipFeeUseCase } = makeService({
|
||||
upsertMembershipFeePresenter: { viewModel: { success: true } },
|
||||
});
|
||||
|
||||
await expect(service.upsertMembershipFee({ leagueId: 'l1' } as any)).resolves.toEqual({ success: true });
|
||||
expect(upsertMembershipFeeUseCase.execute).toHaveBeenCalledWith({ leagueId: 'l1' });
|
||||
});
|
||||
|
||||
it('upsertMembershipFee throws on error branch (defensive check)', async () => {
|
||||
const { service } = makeService({
|
||||
upsertMembershipFeeUseCase: { execute: vi.fn(async () => Result.err({ code: 'REPOSITORY_ERROR' } as any)) },
|
||||
});
|
||||
|
||||
await expect(service.upsertMembershipFee({ leagueId: 'l1' } as any)).rejects.toThrow(
|
||||
'Failed to upsert membership fee',
|
||||
);
|
||||
});
|
||||
|
||||
it('updateMemberPayment returns viewModel on success', async () => {
|
||||
const { service, updateMemberPaymentUseCase } = makeService({
|
||||
updateMemberPaymentPresenter: { viewModel: { success: true } },
|
||||
});
|
||||
|
||||
await expect(service.updateMemberPayment({ leagueId: 'l1' } as any)).resolves.toEqual({ success: true });
|
||||
expect(updateMemberPaymentUseCase.execute).toHaveBeenCalledWith({ leagueId: 'l1' });
|
||||
});
|
||||
|
||||
it('updateMemberPayment throws when use case returns error', async () => {
|
||||
const { service } = makeService({
|
||||
updateMemberPaymentUseCase: { execute: vi.fn(async () => Result.err({ code: 'REPOSITORY_ERROR' })) },
|
||||
});
|
||||
|
||||
await expect(service.updateMemberPayment({ leagueId: 'l1' } as any)).rejects.toThrow('REPOSITORY_ERROR');
|
||||
});
|
||||
|
||||
it('getPrizes maps seasonId optional', async () => {
|
||||
const getPrizesUseCase = { execute: vi.fn(async () => Result.ok(undefined)) };
|
||||
const { service } = makeService({
|
||||
getPrizesUseCase,
|
||||
getPrizesPresenter: { viewModel: { prizes: [] } },
|
||||
});
|
||||
|
||||
await expect(service.getPrizes({ leagueId: 'l1' } as any)).resolves.toEqual({ prizes: [] });
|
||||
expect(getPrizesUseCase.execute).toHaveBeenCalledWith({ leagueId: 'l1' });
|
||||
|
||||
await expect(service.getPrizes({ leagueId: 'l1', seasonId: 's1' } as any)).resolves.toEqual({ prizes: [] });
|
||||
expect(getPrizesUseCase.execute).toHaveBeenCalledWith({ leagueId: 'l1', seasonId: 's1' });
|
||||
});
|
||||
|
||||
it('createPrize calls use case and returns viewModel', async () => {
|
||||
const createPrizeUseCase = { execute: vi.fn(async () => Result.ok(undefined)) };
|
||||
const { service } = makeService({
|
||||
createPrizeUseCase,
|
||||
createPrizePresenter: { viewModel: { success: true } },
|
||||
});
|
||||
|
||||
await expect(service.createPrize({ leagueId: 'l1' } as any)).resolves.toEqual({ success: true });
|
||||
expect(createPrizeUseCase.execute).toHaveBeenCalledWith({ leagueId: 'l1' });
|
||||
});
|
||||
|
||||
it('awardPrize calls use case and returns viewModel', async () => {
|
||||
const awardPrizeUseCase = { execute: vi.fn(async () => Result.ok(undefined)) };
|
||||
const { service } = makeService({
|
||||
awardPrizeUseCase,
|
||||
awardPrizePresenter: { viewModel: { success: true } },
|
||||
});
|
||||
|
||||
await expect(service.awardPrize({ prizeId: 'p1' } as any)).resolves.toEqual({ success: true });
|
||||
expect(awardPrizeUseCase.execute).toHaveBeenCalledWith({ prizeId: 'p1' });
|
||||
});
|
||||
|
||||
it('deletePrize calls use case and returns viewModel', async () => {
|
||||
const deletePrizeUseCase = { execute: vi.fn(async () => Result.ok(undefined)) };
|
||||
const { service } = makeService({
|
||||
deletePrizeUseCase,
|
||||
deletePrizePresenter: { viewModel: { success: true } },
|
||||
});
|
||||
|
||||
await expect(service.deletePrize({ prizeId: 'p1' } as any)).resolves.toEqual({ success: true });
|
||||
expect(deletePrizeUseCase.execute).toHaveBeenCalledWith({ prizeId: 'p1' });
|
||||
});
|
||||
|
||||
it('getWallet calls use case and returns viewModel', async () => {
|
||||
const getWalletUseCase = { execute: vi.fn(async () => Result.ok(undefined)) };
|
||||
const { service } = makeService({
|
||||
getWalletUseCase,
|
||||
getWalletPresenter: { viewModel: { balance: 10 } },
|
||||
});
|
||||
|
||||
await expect(service.getWallet({ leagueId: 'l1' } as any)).resolves.toEqual({ balance: 10 });
|
||||
expect(getWalletUseCase.execute).toHaveBeenCalledWith({ leagueId: 'l1' });
|
||||
});
|
||||
|
||||
it('processWalletTransaction calls use case and returns viewModel', async () => {
|
||||
const processWalletTransactionUseCase = { execute: vi.fn(async () => Result.ok(undefined)) };
|
||||
const { service } = makeService({
|
||||
processWalletTransactionUseCase,
|
||||
processWalletTransactionPresenter: { viewModel: { success: true } },
|
||||
});
|
||||
|
||||
await expect(service.processWalletTransaction({ leagueId: 'l1' } as any)).resolves.toEqual({ success: true });
|
||||
expect(processWalletTransactionUseCase.execute).toHaveBeenCalledWith({ leagueId: 'l1' });
|
||||
});
|
||||
|
||||
it('getPayments throws fallback message when error has no code', async () => {
|
||||
const { service } = makeService({
|
||||
getPaymentsUseCase: { execute: vi.fn(async () => Result.err({} as any)) },
|
||||
});
|
||||
|
||||
await expect(service.getPayments({ leagueId: 'l1' } as any)).rejects.toThrow('Failed to get payments');
|
||||
});
|
||||
|
||||
it('createPayment throws fallback message when error has no code', async () => {
|
||||
const { service } = makeService({
|
||||
createPaymentUseCase: { execute: vi.fn(async () => Result.err({} as any)) },
|
||||
});
|
||||
|
||||
await expect(service.createPayment({ leagueId: 'l1' } as any)).rejects.toThrow('Failed to create payment');
|
||||
});
|
||||
|
||||
it('updatePaymentStatus throws fallback message when error has no code', async () => {
|
||||
const { service } = makeService({
|
||||
updatePaymentStatusUseCase: { execute: vi.fn(async () => Result.err({} as any)) },
|
||||
});
|
||||
|
||||
await expect(service.updatePaymentStatus({ paymentId: 'p1' } as any)).rejects.toThrow('Failed to update payment status');
|
||||
});
|
||||
|
||||
it('getMembershipFees throws fallback message when error has no code', async () => {
|
||||
const { service } = makeService({
|
||||
getMembershipFeesUseCase: { execute: vi.fn(async () => Result.err({} as any)) },
|
||||
});
|
||||
|
||||
await expect(service.getMembershipFees({ leagueId: 'l1', driverId: 'd1' } as any)).rejects.toThrow('Failed to get membership fees');
|
||||
});
|
||||
|
||||
it('updateMemberPayment throws fallback message when error has no code', async () => {
|
||||
const { service } = makeService({
|
||||
updateMemberPaymentUseCase: { execute: vi.fn(async () => Result.err({} as any)) },
|
||||
});
|
||||
|
||||
await expect(service.updateMemberPayment({ leagueId: 'l1' } as any)).rejects.toThrow('Failed to update member payment');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user