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); }); }); });