import { describe, expect, it } from 'vitest' import { billingAccountUpdateSchema, billingCreditNoteSchema, billingRefundSchema, createBillingInvoiceSchema, payBillingInvoiceSchema, } from './admin.schemas' describe('admin billing schemas', () => { it('accepts complete draft invoice payloads and preserves nullable billing fields', () => { const parsed = createBillingInvoiceSchema.parse({ subscriptionId: null, invoiceType: 'MANUAL', currency: 'MAD', dueAt: '2026-08-10', isSubscriptionBlocking: false, adminReason: null, lineItems: [{ type: 'MANUAL_ADJUSTMENT', description: 'Manual correction', quantity: 2, unitAmount: 1500, periodStart: null, periodEnd: '2026-08-31T00:00:00.000Z', }], }) expect(parsed.lineItems[0]).toMatchObject({ quantity: 2, unitAmount: 1500, periodStart: null }) }) it('rejects invoices without line items because empty invoices are bookkeeping cosplay', () => { expect(() => createBillingInvoiceSchema.parse({ invoiceType: 'MANUAL', lineItems: [] })).toThrow() }) it('bounds billing account net terms and validates email formatting', () => { expect(billingAccountUpdateSchema.parse({ legalName: 'Atlas Cars LLC', billingEmail: 'billing@example.test', invoiceTerms: 'NET_30', netTermsDays: 30, })).toMatchObject({ netTermsDays: 30 }) expect(() => billingAccountUpdateSchema.parse({ billingEmail: 'not-email', netTermsDays: 366 })).toThrow() }) it('requires positive money movements for payments, credit notes, and refunds', () => { expect(payBillingInvoiceSchema.parse({ amount: 5000, paymentMethodId: null })).toEqual({ amount: 5000, paymentMethodId: null }) expect(() => payBillingInvoiceSchema.parse({ amount: 0 })).toThrow() expect(() => billingCreditNoteSchema.parse({ amount: -1, reason: 'Bad credit' })).toThrow() expect(() => billingRefundSchema.parse({ amount: 0, reason: 'Bad refund' })).toThrow() }) })