Files
gridpilot.gg/core/racing/domain/entities/league-wallet/Transaction.test.ts
2025-12-17 00:33:13 +01:00

137 lines
5.0 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import { Transaction } from './Transaction';
import { TransactionId } from './TransactionId';
import { LeagueWalletId } from './LeagueWalletId';
import { Money } from '../../value-objects/Money';
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);
});
});
});