312 lines
9.6 KiB
TypeScript
312 lines
9.6 KiB
TypeScript
import {
|
|
Payment,
|
|
PaymentStatus,
|
|
PaymentType,
|
|
PayerType,
|
|
} from '@core/payments/domain/entities/Payment';
|
|
import { describe, expect, it } from 'vitest';
|
|
|
|
describe('payments/domain/entities/Payment', () => {
|
|
describe('PaymentType enum', () => {
|
|
it('should have correct payment type values', () => {
|
|
expect(PaymentType.SPONSORSHIP).toBe('sponsorship');
|
|
expect(PaymentType.MEMBERSHIP_FEE).toBe('membership_fee');
|
|
});
|
|
});
|
|
|
|
describe('PayerType enum', () => {
|
|
it('should have correct payer type values', () => {
|
|
expect(PayerType.SPONSOR).toBe('sponsor');
|
|
expect(PayerType.DRIVER).toBe('driver');
|
|
});
|
|
});
|
|
|
|
describe('PaymentStatus enum', () => {
|
|
it('should have correct status values', () => {
|
|
expect(PaymentStatus.PENDING).toBe('pending');
|
|
expect(PaymentStatus.COMPLETED).toBe('completed');
|
|
expect(PaymentStatus.FAILED).toBe('failed');
|
|
expect(PaymentStatus.REFUNDED).toBe('refunded');
|
|
});
|
|
});
|
|
|
|
describe('Payment interface', () => {
|
|
it('should have all required properties', () => {
|
|
const payment: Payment = {
|
|
id: 'payment-123',
|
|
type: PaymentType.SPONSORSHIP,
|
|
amount: 1000,
|
|
platformFee: 50,
|
|
netAmount: 950,
|
|
payerId: 'sponsor-456',
|
|
payerType: PayerType.SPONSOR,
|
|
leagueId: 'league-789',
|
|
status: PaymentStatus.PENDING,
|
|
createdAt: new Date('2024-01-01'),
|
|
};
|
|
|
|
expect(payment.id).toBe('payment-123');
|
|
expect(payment.type).toBe(PaymentType.SPONSORSHIP);
|
|
expect(payment.amount).toBe(1000);
|
|
expect(payment.platformFee).toBe(50);
|
|
expect(payment.netAmount).toBe(950);
|
|
expect(payment.payerId).toBe('sponsor-456');
|
|
expect(payment.payerType).toBe(PayerType.SPONSOR);
|
|
expect(payment.leagueId).toBe('league-789');
|
|
expect(payment.status).toBe(PaymentStatus.PENDING);
|
|
expect(payment.createdAt).toEqual(new Date('2024-01-01'));
|
|
});
|
|
|
|
it('should support optional seasonId property', () => {
|
|
const payment: Payment = {
|
|
id: 'payment-123',
|
|
type: PaymentType.MEMBERSHIP_FEE,
|
|
amount: 100,
|
|
platformFee: 5,
|
|
netAmount: 95,
|
|
payerId: 'driver-456',
|
|
payerType: PayerType.DRIVER,
|
|
leagueId: 'league-789',
|
|
seasonId: 'season-999',
|
|
status: PaymentStatus.COMPLETED,
|
|
createdAt: new Date('2024-01-01'),
|
|
completedAt: new Date('2024-01-15'),
|
|
};
|
|
|
|
expect(payment.seasonId).toBe('season-999');
|
|
expect(payment.completedAt).toEqual(new Date('2024-01-15'));
|
|
});
|
|
|
|
it('should support optional completedAt property', () => {
|
|
const payment: Payment = {
|
|
id: 'payment-123',
|
|
type: PaymentType.SPONSORSHIP,
|
|
amount: 1000,
|
|
platformFee: 50,
|
|
netAmount: 950,
|
|
payerId: 'sponsor-456',
|
|
payerType: PayerType.SPONSOR,
|
|
leagueId: 'league-789',
|
|
status: PaymentStatus.COMPLETED,
|
|
createdAt: new Date('2024-01-01'),
|
|
completedAt: new Date('2024-01-15'),
|
|
};
|
|
|
|
expect(payment.completedAt).toEqual(new Date('2024-01-15'));
|
|
});
|
|
});
|
|
|
|
describe('Payment.rehydrate', () => {
|
|
it('should rehydrate a Payment from props', () => {
|
|
const props: Payment = {
|
|
id: 'payment-123',
|
|
type: PaymentType.SPONSORSHIP,
|
|
amount: 1000,
|
|
platformFee: 50,
|
|
netAmount: 950,
|
|
payerId: 'sponsor-456',
|
|
payerType: PayerType.SPONSOR,
|
|
leagueId: 'league-789',
|
|
status: PaymentStatus.PENDING,
|
|
createdAt: new Date('2024-01-01'),
|
|
};
|
|
|
|
const rehydrated = Payment.rehydrate(props);
|
|
|
|
expect(rehydrated).toEqual(props);
|
|
expect(rehydrated.id).toBe('payment-123');
|
|
expect(rehydrated.type).toBe(PaymentType.SPONSORSHIP);
|
|
expect(rehydrated.amount).toBe(1000);
|
|
expect(rehydrated.platformFee).toBe(50);
|
|
expect(rehydrated.netAmount).toBe(950);
|
|
expect(rehydrated.payerId).toBe('sponsor-456');
|
|
expect(rehydrated.payerType).toBe(PayerType.SPONSOR);
|
|
expect(rehydrated.leagueId).toBe('league-789');
|
|
expect(rehydrated.status).toBe(PaymentStatus.PENDING);
|
|
expect(rehydrated.createdAt).toEqual(new Date('2024-01-01'));
|
|
});
|
|
|
|
it('should preserve optional seasonId when rehydrating', () => {
|
|
const props: Payment = {
|
|
id: 'payment-123',
|
|
type: PaymentType.MEMBERSHIP_FEE,
|
|
amount: 100,
|
|
platformFee: 5,
|
|
netAmount: 95,
|
|
payerId: 'driver-456',
|
|
payerType: PayerType.DRIVER,
|
|
leagueId: 'league-789',
|
|
seasonId: 'season-999',
|
|
status: PaymentStatus.COMPLETED,
|
|
createdAt: new Date('2024-01-01'),
|
|
completedAt: new Date('2024-01-15'),
|
|
};
|
|
|
|
const rehydrated = Payment.rehydrate(props);
|
|
|
|
expect(rehydrated.seasonId).toBe('season-999');
|
|
expect(rehydrated.completedAt).toEqual(new Date('2024-01-15'));
|
|
});
|
|
});
|
|
|
|
describe('Business rules and invariants', () => {
|
|
it('should calculate netAmount correctly (amount - platformFee)', () => {
|
|
const payment: Payment = {
|
|
id: 'payment-123',
|
|
type: PaymentType.SPONSORSHIP,
|
|
amount: 1000,
|
|
platformFee: 50,
|
|
netAmount: 950,
|
|
payerId: 'sponsor-456',
|
|
payerType: PayerType.SPONSOR,
|
|
leagueId: 'league-789',
|
|
status: PaymentStatus.PENDING,
|
|
createdAt: new Date('2024-01-01'),
|
|
};
|
|
|
|
expect(payment.netAmount).toBe(payment.amount - payment.platformFee);
|
|
});
|
|
|
|
it('should support different payment types', () => {
|
|
const sponsorshipPayment: Payment = {
|
|
id: 'payment-123',
|
|
type: PaymentType.SPONSORSHIP,
|
|
amount: 1000,
|
|
platformFee: 50,
|
|
netAmount: 950,
|
|
payerId: 'sponsor-456',
|
|
payerType: PayerType.SPONSOR,
|
|
leagueId: 'league-789',
|
|
status: PaymentStatus.PENDING,
|
|
createdAt: new Date('2024-01-01'),
|
|
};
|
|
|
|
const membershipFeePayment: Payment = {
|
|
id: 'payment-124',
|
|
type: PaymentType.MEMBERSHIP_FEE,
|
|
amount: 100,
|
|
platformFee: 5,
|
|
netAmount: 95,
|
|
payerId: 'driver-456',
|
|
payerType: PayerType.DRIVER,
|
|
leagueId: 'league-789',
|
|
status: PaymentStatus.COMPLETED,
|
|
createdAt: new Date('2024-01-01'),
|
|
};
|
|
|
|
expect(sponsorshipPayment.type).toBe(PaymentType.SPONSORSHIP);
|
|
expect(membershipFeePayment.type).toBe(PaymentType.MEMBERSHIP_FEE);
|
|
});
|
|
|
|
it('should support different payer types', () => {
|
|
const sponsorPayment: Payment = {
|
|
id: 'payment-123',
|
|
type: PaymentType.SPONSORSHIP,
|
|
amount: 1000,
|
|
platformFee: 50,
|
|
netAmount: 950,
|
|
payerId: 'sponsor-456',
|
|
payerType: PayerType.SPONSOR,
|
|
leagueId: 'league-789',
|
|
status: PaymentStatus.PENDING,
|
|
createdAt: new Date('2024-01-01'),
|
|
};
|
|
|
|
const driverPayment: Payment = {
|
|
id: 'payment-124',
|
|
type: PaymentType.MEMBERSHIP_FEE,
|
|
amount: 100,
|
|
platformFee: 5,
|
|
netAmount: 95,
|
|
payerId: 'driver-456',
|
|
payerType: PayerType.DRIVER,
|
|
leagueId: 'league-789',
|
|
status: PaymentStatus.COMPLETED,
|
|
createdAt: new Date('2024-01-01'),
|
|
};
|
|
|
|
expect(sponsorPayment.payerType).toBe(PayerType.SPONSOR);
|
|
expect(driverPayment.payerType).toBe(PayerType.DRIVER);
|
|
});
|
|
|
|
it('should support different payment statuses', () => {
|
|
const pendingPayment: Payment = {
|
|
id: 'payment-123',
|
|
type: PaymentType.SPONSORSHIP,
|
|
amount: 1000,
|
|
platformFee: 50,
|
|
netAmount: 950,
|
|
payerId: 'sponsor-456',
|
|
payerType: PayerType.SPONSOR,
|
|
leagueId: 'league-789',
|
|
status: PaymentStatus.PENDING,
|
|
createdAt: new Date('2024-01-01'),
|
|
};
|
|
|
|
const completedPayment: Payment = {
|
|
id: 'payment-124',
|
|
type: PaymentType.SPONSORSHIP,
|
|
amount: 1000,
|
|
platformFee: 50,
|
|
netAmount: 950,
|
|
payerId: 'sponsor-456',
|
|
payerType: PayerType.SPONSOR,
|
|
leagueId: 'league-789',
|
|
status: PaymentStatus.COMPLETED,
|
|
createdAt: new Date('2024-01-01'),
|
|
completedAt: new Date('2024-01-15'),
|
|
};
|
|
|
|
const failedPayment: Payment = {
|
|
id: 'payment-125',
|
|
type: PaymentType.SPONSORSHIP,
|
|
amount: 1000,
|
|
platformFee: 50,
|
|
netAmount: 950,
|
|
payerId: 'sponsor-456',
|
|
payerType: PayerType.SPONSOR,
|
|
leagueId: 'league-789',
|
|
status: PaymentStatus.FAILED,
|
|
createdAt: new Date('2024-01-01'),
|
|
};
|
|
|
|
const refundedPayment: Payment = {
|
|
id: 'payment-126',
|
|
type: PaymentType.SPONSORSHIP,
|
|
amount: 1000,
|
|
platformFee: 50,
|
|
netAmount: 950,
|
|
payerId: 'sponsor-456',
|
|
payerType: PayerType.SPONSOR,
|
|
leagueId: 'league-789',
|
|
status: PaymentStatus.REFUNDED,
|
|
createdAt: new Date('2024-01-01'),
|
|
};
|
|
|
|
expect(pendingPayment.status).toBe(PaymentStatus.PENDING);
|
|
expect(completedPayment.status).toBe(PaymentStatus.COMPLETED);
|
|
expect(failedPayment.status).toBe(PaymentStatus.FAILED);
|
|
expect(refundedPayment.status).toBe(PaymentStatus.REFUNDED);
|
|
});
|
|
|
|
it('should handle zero and negative amounts', () => {
|
|
const zeroPayment: Payment = {
|
|
id: 'payment-123',
|
|
type: PaymentType.SPONSORSHIP,
|
|
amount: 0,
|
|
platformFee: 0,
|
|
netAmount: 0,
|
|
payerId: 'sponsor-456',
|
|
payerType: PayerType.SPONSOR,
|
|
leagueId: 'league-789',
|
|
status: PaymentStatus.PENDING,
|
|
createdAt: new Date('2024-01-01'),
|
|
};
|
|
|
|
expect(zeroPayment.amount).toBe(0);
|
|
expect(zeroPayment.platformFee).toBe(0);
|
|
expect(zeroPayment.netAmount).toBe(0);
|
|
});
|
|
});
|
|
});
|