import { describe, it, expect, beforeEach } from 'vitest'; import { LeaguesTestContext } from '../LeaguesTestContext'; import { League } from '../../../../core/racing/domain/entities/League'; import { LeagueWallet } from '../../../../core/racing/domain/entities/league-wallet/LeagueWallet'; import { Transaction } from '../../../../core/racing/domain/entities/league-wallet/Transaction'; import { Money } from '../../../../core/racing/domain/value-objects/Money'; describe('WalletManagement', () => { let context: LeaguesTestContext; beforeEach(() => { context = new LeaguesTestContext(); context.walletRepository.clear(); context.transactionRepository.clear(); }); describe('GetLeagueWalletUseCase - Success Path', () => { it('should retrieve current wallet balance', async () => { const leagueId = 'league-123'; const ownerId = 'owner-1'; await context.racingLeagueRepository.create(League.create({ id: leagueId, name: 'Test League', description: 'Test league description', ownerId: ownerId, })); const balance = Money.create(1000, 'USD'); await context.walletRepository.create(LeagueWallet.create({ id: 'wallet-1', leagueId, balance, })); const result = await context.getLeagueWalletUseCase.execute({ leagueId }); expect(result.isOk()).toBe(true); expect(result.unwrap().aggregates.balance.amount).toBe(1000); }); it('should retrieve transaction history', async () => { const leagueId = 'league-123'; const ownerId = 'owner-1'; await context.racingLeagueRepository.create(League.create({ id: leagueId, name: 'Test League', description: 'Test league description', ownerId: ownerId, })); const wallet = LeagueWallet.create({ id: 'wallet-1', leagueId, balance: Money.create(1000, 'USD'), }); await context.walletRepository.create(wallet); const tx = Transaction.create({ id: 'tx1', walletId: wallet.id, type: 'sponsorship_payment', amount: Money.create(1000, 'USD'), description: 'Deposit', }); await context.transactionRepository.create(tx); const result = await context.getLeagueWalletUseCase.execute({ leagueId }); expect(result.isOk()).toBe(true); expect(result.unwrap().transactions).toHaveLength(1); expect(result.unwrap().transactions[0].id.toString()).toBe('tx1'); }); }); describe('WithdrawFromLeagueWalletUseCase - Success Path', () => { it('should allow owner to withdraw funds', async () => { const leagueId = 'league-123'; const ownerId = 'owner-1'; await context.racingLeagueRepository.create(League.create({ id: leagueId, name: 'Test League', description: 'Test league description', ownerId: ownerId, })); const wallet = LeagueWallet.create({ id: 'wallet-1', leagueId, balance: Money.create(1000, 'USD'), }); await context.walletRepository.create(wallet); const result = await context.withdrawFromLeagueWalletUseCase.execute({ leagueId, requestedById: ownerId, amount: 500, currency: 'USD', reason: 'Test withdrawal' }); expect(result.isOk()).toBe(true); expect(result.unwrap().walletBalanceAfter.amount).toBe(500); const walletAfter = await context.walletRepository.findByLeagueId(leagueId); expect(walletAfter?.balance.amount).toBe(500); }); }); describe('WalletManagement - Error Handling', () => { it('should return error when league does not exist', async () => { const result = await context.getLeagueWalletUseCase.execute({ leagueId: 'non-existent' }); expect(result.isErr()).toBe(true); expect((result as any).error.code).toBe('LEAGUE_NOT_FOUND'); }); it('should return error when wallet does not exist', async () => { const leagueId = 'league-123'; await context.racingLeagueRepository.create(League.create({ id: leagueId, name: 'Test League', description: 'Test league description', ownerId: 'owner-1', })); const result = await context.getLeagueWalletUseCase.execute({ leagueId }); expect(result.isErr()).toBe(true); expect((result as any).error.code).toBe('WALLET_NOT_FOUND'); }); it('should prevent non-owner from withdrawing', async () => { const leagueId = 'league-123'; const ownerId = 'owner-1'; const otherId = 'other-user'; await context.racingLeagueRepository.create(League.create({ id: leagueId, name: 'Test League', description: 'Test league description', ownerId: ownerId, })); await context.walletRepository.create(LeagueWallet.create({ id: 'wallet-1', leagueId, balance: Money.create(1000, 'USD'), })); const result = await context.withdrawFromLeagueWalletUseCase.execute({ leagueId, requestedById: otherId, amount: 500, currency: 'USD' }); expect(result.isErr()).toBe(true); expect((result as any).error.code).toBe('UNAUTHORIZED_WITHDRAWAL'); }); }); });