Files
gridpilot.gg/core/payments/domain/entities/MemberPayment.test.ts
2026-01-22 18:05:30 +01:00

175 lines
5.3 KiB
TypeScript

import {
MemberPayment,
MemberPaymentStatus,
} from '@core/payments/domain/entities/MemberPayment';
import { describe, expect, it } from 'vitest';
describe('payments/domain/entities/MemberPayment', () => {
describe('MemberPaymentStatus enum', () => {
it('should have correct status values', () => {
expect(MemberPaymentStatus.PENDING).toBe('pending');
expect(MemberPaymentStatus.PAID).toBe('paid');
expect(MemberPaymentStatus.OVERDUE).toBe('overdue');
});
});
describe('MemberPayment interface', () => {
it('should have all required properties', () => {
const payment: MemberPayment = {
id: 'payment-123',
feeId: 'fee-456',
driverId: 'driver-789',
amount: 100,
platformFee: 10,
netAmount: 90,
status: MemberPaymentStatus.PENDING,
dueDate: new Date('2024-01-01'),
};
expect(payment.id).toBe('payment-123');
expect(payment.feeId).toBe('fee-456');
expect(payment.driverId).toBe('driver-789');
expect(payment.amount).toBe(100);
expect(payment.platformFee).toBe(10);
expect(payment.netAmount).toBe(90);
expect(payment.status).toBe(MemberPaymentStatus.PENDING);
expect(payment.dueDate).toEqual(new Date('2024-01-01'));
});
it('should support optional paidAt property', () => {
const payment: MemberPayment = {
id: 'payment-123',
feeId: 'fee-456',
driverId: 'driver-789',
amount: 100,
platformFee: 10,
netAmount: 90,
status: MemberPaymentStatus.PAID,
dueDate: new Date('2024-01-01'),
paidAt: new Date('2024-01-15'),
};
expect(payment.paidAt).toEqual(new Date('2024-01-15'));
});
});
describe('MemberPayment.rehydrate', () => {
it('should rehydrate a MemberPayment from props', () => {
const props: MemberPayment = {
id: 'payment-123',
feeId: 'fee-456',
driverId: 'driver-789',
amount: 100,
platformFee: 10,
netAmount: 90,
status: MemberPaymentStatus.PENDING,
dueDate: new Date('2024-01-01'),
};
const rehydrated = MemberPayment.rehydrate(props);
expect(rehydrated).toEqual(props);
expect(rehydrated.id).toBe('payment-123');
expect(rehydrated.feeId).toBe('fee-456');
expect(rehydrated.driverId).toBe('driver-789');
expect(rehydrated.amount).toBe(100);
expect(rehydrated.platformFee).toBe(10);
expect(rehydrated.netAmount).toBe(90);
expect(rehydrated.status).toBe(MemberPaymentStatus.PENDING);
expect(rehydrated.dueDate).toEqual(new Date('2024-01-01'));
});
it('should preserve optional paidAt when rehydrating', () => {
const props: MemberPayment = {
id: 'payment-123',
feeId: 'fee-456',
driverId: 'driver-789',
amount: 100,
platformFee: 10,
netAmount: 90,
status: MemberPaymentStatus.PAID,
dueDate: new Date('2024-01-01'),
paidAt: new Date('2024-01-15'),
};
const rehydrated = MemberPayment.rehydrate(props);
expect(rehydrated.paidAt).toEqual(new Date('2024-01-15'));
});
});
describe('Business rules and invariants', () => {
it('should calculate netAmount correctly (amount - platformFee)', () => {
const payment: MemberPayment = {
id: 'payment-123',
feeId: 'fee-456',
driverId: 'driver-789',
amount: 100,
platformFee: 10,
netAmount: 90,
status: MemberPaymentStatus.PENDING,
dueDate: new Date('2024-01-01'),
};
expect(payment.netAmount).toBe(payment.amount - payment.platformFee);
});
it('should support different payment statuses', () => {
const pendingPayment: MemberPayment = {
id: 'payment-123',
feeId: 'fee-456',
driverId: 'driver-789',
amount: 100,
platformFee: 10,
netAmount: 90,
status: MemberPaymentStatus.PENDING,
dueDate: new Date('2024-01-01'),
};
const paidPayment: MemberPayment = {
id: 'payment-124',
feeId: 'fee-456',
driverId: 'driver-789',
amount: 100,
platformFee: 10,
netAmount: 90,
status: MemberPaymentStatus.PAID,
dueDate: new Date('2024-01-01'),
paidAt: new Date('2024-01-15'),
};
const overduePayment: MemberPayment = {
id: 'payment-125',
feeId: 'fee-456',
driverId: 'driver-789',
amount: 100,
platformFee: 10,
netAmount: 90,
status: MemberPaymentStatus.OVERDUE,
dueDate: new Date('2024-01-01'),
};
expect(pendingPayment.status).toBe(MemberPaymentStatus.PENDING);
expect(paidPayment.status).toBe(MemberPaymentStatus.PAID);
expect(overduePayment.status).toBe(MemberPaymentStatus.OVERDUE);
});
it('should handle zero and negative amounts', () => {
const zeroPayment: MemberPayment = {
id: 'payment-123',
feeId: 'fee-456',
driverId: 'driver-789',
amount: 0,
platformFee: 0,
netAmount: 0,
status: MemberPaymentStatus.PENDING,
dueDate: new Date('2024-01-01'),
};
expect(zeroPayment.amount).toBe(0);
expect(zeroPayment.platformFee).toBe(0);
expect(zeroPayment.netAmount).toBe(0);
});
});
});