import { describe, expect, it } from 'vitest'; import { Money } from '../../value-objects/Money'; import { LeagueWalletId } from './LeagueWalletId'; import { Transaction } from './Transaction'; import { TransactionId } from './TransactionId'; describe('Transaction', () => { const validId = TransactionId.create('tx1'); const validWalletId = LeagueWalletId.create('wallet1'); const validAmount = Money.create(10000, 'USD'); // $100.00 const validProps = { id: validId, walletId: validWalletId, type: 'sponsorship_payment' as const, amount: validAmount, completedAt: undefined, description: 'Test transaction', metadata: undefined, }; describe('create', () => { it('should create a transaction with default values', () => { const transaction = Transaction.create(validProps); expect(transaction.id).toBe(validId); expect(transaction.walletId).toBe(validWalletId); expect(transaction.type).toBe('sponsorship_payment'); expect(transaction.amount).toBe(validAmount); expect(transaction.status).toBe('pending'); expect(transaction.createdAt).toBeInstanceOf(Date); expect(transaction.completedAt).toBeUndefined(); expect(transaction.description).toBe('Test transaction'); expect(transaction.platformFee.amount).toBe(1000); // 10% of 10000 expect(transaction.netAmount.amount).toBe(9000); // 10000 - 1000 }); it('should create a transaction with custom createdAt and status', () => { const customDate = new Date('2023-01-01'); const transaction = Transaction.create({ ...validProps, createdAt: customDate, status: 'completed', }); expect(transaction.createdAt).toBe(customDate); expect(transaction.status).toBe('completed'); }); it('should throw on zero amount', () => { const zeroAmount = Money.create(0, 'USD'); expect(() => Transaction.create({ ...validProps, amount: zeroAmount })).toThrow('Transaction amount must be greater than zero'); }); it('should throw on negative amount', () => { expect(() => Money.create(-100, 'USD')).toThrow(); }); }); describe('complete', () => { it('should complete a pending transaction', () => { const transaction = Transaction.create(validProps); const completed = transaction.complete(); expect(completed.status).toBe('completed'); expect(completed.completedAt).toBeInstanceOf(Date); }); it('should throw on completing already completed transaction', () => { const transaction = Transaction.create({ ...validProps, status: 'completed' }); expect(() => transaction.complete()).toThrow('Transaction is already completed'); }); it('should throw on completing failed transaction', () => { const transaction = Transaction.create({ ...validProps, status: 'failed' }); expect(() => transaction.complete()).toThrow('Cannot complete a failed or cancelled transaction'); }); it('should throw on completing cancelled transaction', () => { const transaction = Transaction.create({ ...validProps, status: 'cancelled' }); expect(() => transaction.complete()).toThrow('Cannot complete a failed or cancelled transaction'); }); }); describe('fail', () => { it('should fail a pending transaction', () => { const transaction = Transaction.create(validProps); const failed = transaction.fail(); expect(failed.status).toBe('failed'); }); it('should throw on failing completed transaction', () => { const transaction = Transaction.create({ ...validProps, status: 'completed' }); expect(() => transaction.fail()).toThrow('Cannot fail a completed transaction'); }); }); describe('cancel', () => { it('should cancel a pending transaction', () => { const transaction = Transaction.create(validProps); const cancelled = transaction.cancel(); expect(cancelled.status).toBe('cancelled'); }); it('should throw on cancelling completed transaction', () => { const transaction = Transaction.create({ ...validProps, status: 'completed' }); expect(() => transaction.cancel()).toThrow('Cannot cancel a completed transaction'); }); }); describe('isCompleted', () => { it('should return true for completed transaction', () => { const transaction = Transaction.create({ ...validProps, status: 'completed' }); expect(transaction.isCompleted()).toBe(true); }); it('should return false for non-completed transaction', () => { const transaction = Transaction.create(validProps); expect(transaction.isCompleted()).toBe(false); }); }); describe('isPending', () => { it('should return true for pending transaction', () => { const transaction = Transaction.create(validProps); expect(transaction.isPending()).toBe(true); }); it('should return false for non-pending transaction', () => { const transaction = Transaction.create({ ...validProps, status: 'completed' }); expect(transaction.isPending()).toBe(false); }); }); });