import { vi, describe, it, expect, beforeEach } from 'vitest'; import { InMemoryTransactionRepository } from './InMemoryTransactionRepository'; import { Transaction, TransactionType } from '@core/racing/domain/entities/league-wallet/Transaction'; import { TransactionId } from '@core/racing/domain/entities/league-wallet/TransactionId'; import { LeagueWalletId } from '@core/racing/domain/entities/league-wallet/LeagueWalletId'; import { Money } from '@core/racing/domain/value-objects/Money'; import type { Logger } from '@core/shared/application'; describe('InMemoryTransactionRepository', () => { let repository: InMemoryTransactionRepository; let mockLogger: Logger; beforeEach(() => { mockLogger = { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn(), }; repository = new InMemoryTransactionRepository(mockLogger); }); const createTestTransaction = (id: string, walletId: string, type: TransactionType, amount: number) => { return Transaction.create({ id: TransactionId.create(id), walletId: LeagueWalletId.create(walletId), type, amount: Money.create(amount), completedAt: undefined, description: undefined, metadata: undefined, }); }; describe('constructor', () => { it('should initialize with a logger', () => { expect(repository).toBeDefined(); expect(mockLogger.info).toHaveBeenCalledWith('InMemoryTransactionRepository initialized.'); }); }); describe('findById', () => { it('should return null if transaction not found', async () => { const result = await repository.findById('nonexistent'); expect(result).toBeNull(); expect(mockLogger.debug).toHaveBeenCalledWith('Finding transaction by id: nonexistent'); expect(mockLogger.warn).toHaveBeenCalledWith('Transaction with id nonexistent not found.'); }); it('should return the transaction if found', async () => { const transaction = createTestTransaction('1', 'wallet1', 'sponsorship_payment', 100); await repository.create(transaction); const result = await repository.findById('1'); expect(result).toEqual(transaction); expect(mockLogger.info).toHaveBeenCalledWith('Found transaction: 1.'); }); }); describe('findByWalletId', () => { it('should return transactions filtered by wallet ID', async () => { const transaction1 = createTestTransaction('1', 'wallet1', 'sponsorship_payment', 100); const transaction2 = createTestTransaction('2', 'wallet2', 'prize_payout', 200); await repository.create(transaction1); await repository.create(transaction2); const result = await repository.findByWalletId('wallet1'); expect(result).toHaveLength(1); expect(result[0]).toEqual(transaction1); }); }); describe('findByType', () => { it('should return transactions filtered by type', async () => { const transaction1 = createTestTransaction('1', 'wallet1', 'sponsorship_payment', 100); const transaction2 = createTestTransaction('2', 'wallet1', 'prize_payout', 200); await repository.create(transaction1); await repository.create(transaction2); const result = await repository.findByType('sponsorship_payment'); expect(result).toHaveLength(1); expect(result[0]).toEqual(transaction1); }); }); describe('create', () => { it('should create a new transaction', async () => { const transaction = createTestTransaction('1', 'wallet1', 'sponsorship_payment', 100); const result = await repository.create(transaction); expect(result).toEqual(transaction); expect(mockLogger.info).toHaveBeenCalledWith('Transaction 1 created successfully.'); }); it('should throw error if transaction already exists', async () => { const transaction = createTestTransaction('1', 'wallet1', 'sponsorship_payment', 100); await repository.create(transaction); await expect(repository.create(transaction)).rejects.toThrow('Transaction with this ID already exists'); }); }); describe('update', () => { it('should update an existing transaction', async () => { const transaction = createTestTransaction('1', 'wallet1', 'sponsorship_payment', 100); await repository.create(transaction); const updatedTransaction = Transaction.create({ id: TransactionId.create('1'), walletId: LeagueWalletId.create('wallet1'), type: 'prize_payout', amount: Money.create(150), completedAt: undefined, description: undefined, metadata: undefined, }); const result = await repository.update(updatedTransaction); expect(result).toEqual(updatedTransaction); expect(mockLogger.info).toHaveBeenCalledWith('Transaction 1 updated successfully.'); }); it('should throw error if transaction does not exist', async () => { const transaction = createTestTransaction('1', 'wallet1', 'sponsorship_payment', 100); await expect(repository.update(transaction)).rejects.toThrow('Transaction not found'); }); }); describe('delete', () => { it('should delete an existing transaction', async () => { const transaction = createTestTransaction('1', 'wallet1', 'sponsorship_payment', 100); await repository.create(transaction); await repository.delete('1'); expect(mockLogger.info).toHaveBeenCalledWith('Transaction 1 deleted successfully.'); const found = await repository.findById('1'); expect(found).toBeNull(); }); it('should throw error if transaction does not exist', async () => { await expect(repository.delete('nonexistent')).rejects.toThrow('Transaction with ID nonexistent not found'); }); }); describe('exists', () => { it('should return true if transaction exists', async () => { const transaction = createTestTransaction('1', 'wallet1', 'sponsorship_payment', 100); await repository.create(transaction); const result = await repository.exists('1'); expect(result).toBe(true); }); it('should return false if transaction does not exist', async () => { const result = await repository.exists('nonexistent'); expect(result).toBe(false); }); }); });