175 lines
5.3 KiB
TypeScript
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);
|
|
});
|
|
});
|
|
});
|