import { describe, expect, it, vi, type Mock } from 'vitest'; import { ReferenceType, TransactionType } from '../../domain/entities/Wallet'; import type { TransactionRepository, WalletRepository } from '../../domain/repositories/WalletRepository'; import { ProcessWalletTransactionUseCase, type ProcessWalletTransactionInput } from './ProcessWalletTransactionUseCase'; describe('ProcessWalletTransactionUseCase', () => { let walletRepository: { findByLeagueId: Mock; create: Mock; update: Mock; }; let transactionRepository: { create: Mock; }; let useCase: ProcessWalletTransactionUseCase; beforeEach(() => { walletRepository = { findByLeagueId: vi.fn(), create: vi.fn(), update: vi.fn(), }; transactionRepository = { create: vi.fn(), }; useCase = new ProcessWalletTransactionUseCase( walletRepository as unknown as WalletRepository, transactionRepository as unknown as TransactionRepository, ); }); it('processes a deposit transaction and returns 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); const value = result.value; expect(value.wallet).toEqual({ ...wallet, balance: 150, totalRevenue: 150 }); expect(value.transaction).toEqual(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'); }); });