import { decimal, minor, discountFor } from '../src/checkout/money'; import { couponSchema } from '../src/coupons/coupon.schema'; import { cartLineSchema, checkoutSchema, } from '../src/checkout/checkout.schemas'; import { assertCoupon } from '../src/coupons/coupon-policy'; import { Prisma, type Coupon } from '../src/generated/prisma/client'; import { couponInput } from './helpers/checkout'; describe('checkout money and eligibility policies', () => { it('uses exact minor units and round-half-up percentage discounts', () => { expect(minor('0.10') + minor('0.20')).toBe(30n); expect(minor('499')).toBe(49900n); expect(minor('1.5')).toBe(150n); expect(decimal(1n)).toBe('0.01'); expect( discountFor(101n, { kind: 'PERCENT', percentBps: 5000, amount: null }), ).toBe(51n); expect( discountFor(100n, { kind: 'FIXED', amount: '5.00', percentBps: null }), ).toBe(100n); expect( discountFor(1000n, { kind: 'FIXED', amount: '1.50', percentBps: null }), ).toBe(150n); expect(decimal(9999999999999999n)).toBe('99999999999999.99'); for (const value of ['-1', '0.001', 'NaN', '1e3']) expect(() => minor(value)).toThrow(); expect(() => decimal(-1n)).toThrow(); expect(() => decimal(10000000000000000n)).toThrow(); }); it('validates coupon dates, currency, amount, quotas and mutually exclusive rules', () => { const input = couponInput(); expect(couponSchema.parse(input).code).toBe(input.code.toUpperCase()); for (const change of [ { endsAt: input.startsAt }, { perUserLimit: 11 }, { percentBps: 10001 }, { amount: '2.00' }, { currency: 'XXX' }, { code: '