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

114 lines
3.2 KiB
TypeScript

import { describe, it, expect, vi, type Mock } from 'vitest';
import { ProcessWalletTransactionUseCase, type ProcessWalletTransactionInput } from './ProcessWalletTransactionUseCase';
import type { IWalletRepository, ITransactionRepository } from '../../domain/repositories/IWalletRepository';
import { TransactionType, ReferenceType } from '../../domain/entities/Wallet';
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
describe('ProcessWalletTransactionUseCase', () => {
let walletRepository: {
findByLeagueId: Mock;
create: Mock;
update: Mock;
};
let transactionRepository: {
create: Mock;
};
let output: {
present: Mock;
};
let useCase: ProcessWalletTransactionUseCase;
beforeEach(() => {
walletRepository = {
findByLeagueId: vi.fn(),
create: vi.fn(),
update: vi.fn(),
} as unknown as IWalletRepository as any;
transactionRepository = {
create: vi.fn(),
} as unknown as ITransactionRepository as any;
output = {
present: vi.fn(),
};
useCase = new ProcessWalletTransactionUseCase(
walletRepository as unknown as IWalletRepository,
transactionRepository as unknown as ITransactionRepository,
output as unknown as UseCaseOutputPort<any>,
);
});
it('processes a deposit transaction and presents the result', async () => {
const input: ProcessWalletTransactionInput = {
leagueId: 'league-1',
type: TransactionType.DEPOSIT,
amount: 100,
description: 'Test deposit',
referenceId: 'ref-1',
referenceType: ReferenceType.SPONSORSHIP,
};
const wallet = {
id: 'wallet-1',
leagueId: 'league-1',
balance: 50,
totalRevenue: 50,
totalPlatformFees: 0,
totalWithdrawn: 0,
currency: 'USD',
createdAt: new Date(),
};
const transaction = {
id: 'txn-1',
walletId: 'wallet-1',
type: TransactionType.DEPOSIT,
amount: 100,
description: 'Test deposit',
referenceId: 'ref-1',
referenceType: ReferenceType.SPONSORSHIP,
createdAt: new Date(),
};
walletRepository.findByLeagueId.mockResolvedValue(wallet);
transactionRepository.create.mockResolvedValue(transaction);
walletRepository.update.mockResolvedValue({ ...wallet, balance: 150, totalRevenue: 150 });
const result = await useCase.execute(input);
expect(result.isOk()).toBe(true);
expect(output.present).toHaveBeenCalledWith({
wallet: { ...wallet, balance: 150, totalRevenue: 150 },
transaction,
});
});
it('returns error for insufficient balance on withdrawal', async () => {
const input: ProcessWalletTransactionInput = {
leagueId: 'league-1',
type: TransactionType.WITHDRAWAL,
amount: 100,
description: 'Test withdrawal',
};
const wallet = {
id: 'wallet-1',
leagueId: 'league-1',
balance: 50,
totalRevenue: 50,
totalPlatformFees: 0,
totalWithdrawn: 0,
currency: 'USD',
createdAt: new Date(),
};
walletRepository.findByLeagueId.mockResolvedValue(wallet);
const result = await useCase.execute(input);
expect(result.isErr()).toBe(true);
expect(result.unwrapErr().code).toBe('INSUFFICIENT_BALANCE');
});
});