const { outstandingForFee, outstandingForInvoice, statusForPaid, } = require('../src/lib/outstanding'); describe('outstandingForFee', () => { it('defaults missing fee fields to zero', () => { expect(outstandingForFee({})).toEqual({ total_due: 0, outstanding: 0, paid: 0 }); }); it('applies a discount when no fine is present', () => { expect(outstandingForFee({ amount: 100, discount_amount: 15, paid_amount: 20 })).toEqual({ total_due: 85, outstanding: 65, paid: 20, }); }); it('applies a fine when no discount is present', () => { expect(outstandingForFee({ amount: 100, fine_amount: 10, paid_amount: 20 })).toEqual({ total_due: 110, outstanding: 90, paid: 20, }); }); it('applies both fine and discount', () => { expect(outstandingForFee({ amount: 100, fine_amount: 10, discount_amount: 15, paid_amount: 20 })).toEqual({ total_due: 95, outstanding: 75, paid: 20, }); }); it('clamps negative outstanding to zero when overpaid', () => { expect(outstandingForFee({ amount: 100, paid_amount: 125 })).toEqual({ total_due: 100, outstanding: 0, paid: 125, }); }); }); describe('statusForPaid', () => { it('returns pending with no payment and partial below the due amount', () => { expect(statusForPaid(100, 0)).toBe('pending'); expect(statusForPaid(100, 40)).toBe('partial'); }); it('returns paid when the due amount is fully covered', () => { expect(statusForPaid(100, 100)).toBe('paid'); }); }); describe('outstandingForInvoice', () => { it('subtracts discount and paid amount from the invoice total', () => { expect(outstandingForInvoice({ total: 250, discount_amount: 30, paid_amount: 100 })).toEqual({ net_due: 220, outstanding: 120, paid: 100, }); }); });