// Domain-layer form schemas: derived from the shared contract schemas, with // string-typed numeric inputs and toXxxRequest() mappers to the wire types. // Also serves as the resolution smoke test for the // '@proposal-system/api-contracts/schemas' subpath entrypoint. import { describe, it, expect } from 'vitest'; import { createProposalFormSchema, toCreateProposalRequest, MIN_SCOPE_LENGTH, } from '../proposals/schemas'; import { customerFormSchema, toCustomerRequest } from '../customers/schemas'; import { pricingLibraryItemFormSchema, toPricingLibraryItemRequest, } from '../pricingLibrary/schemas'; import { lineItemRowFormSchema, toUpdateLineItemEntry } from '../lineItems/schemas'; describe('createProposalFormSchema', () => { const valid = { workOrderNumber: 'WO-1001', poNumber: '', customerName: 'Acme Corp', customerAddress: '1 Main St, Islip, NY 11751', scopeOfWork: 'Replace rooftop HVAC unit and rebalance airflow', serviceCategory: 'HVAC' as const, priority: 'Standard' as const, notes: '', customCategory: '', }; it('accepts a complete form', () => { expect(createProposalFormSchema.safeParse(valid).success).toBe(true); }); it('rejects scope of work shorter than the minimum', () => { const result = createProposalFormSchema.safeParse({ ...valid, scopeOfWork: 'x'.repeat(MIN_SCOPE_LENGTH - 1), }); expect(result.success).toBe(false); }); it('requires customCategory when serviceCategory is Other', () => { expect( createProposalFormSchema.safeParse({ ...valid, serviceCategory: 'Other' }).success ).toBe(false); expect( createProposalFormSchema.safeParse({ ...valid, serviceCategory: 'Other', customCategory: 'Roofing', }).success ).toBe(true); }); it('maps to the wire request, prefixing notes with the custom category', () => { const request = toCreateProposalRequest({ ...valid, serviceCategory: 'Other', customCategory: 'Roofing', notes: 'existing note', }); expect(request.notes).toBe('[Category: Roofing]\nexisting note'); expect(request.poNumber).toBeUndefined(); expect(toCreateProposalRequest(valid).notes).toBeUndefined(); }); }); describe('customerFormSchema', () => { const valid = { name: 'Acme Corp', address: '1 Main St', contactEmail: '' }; it('accepts a form with empty email', () => { expect(customerFormSchema.safeParse(valid).success).toBe(true); }); it('rejects a malformed email but accepts a valid one', () => { expect(customerFormSchema.safeParse({ ...valid, contactEmail: 'nope' }).success).toBe(false); expect( customerFormSchema.safeParse({ ...valid, contactEmail: 'a@b.com' }).success ).toBe(true); }); it('maps to addresses[] preserving extra existing addresses', () => { const request = toCustomerRequest( { name: ' Acme ', address: ' 2 New St ', contactEmail: '' }, ['1 Old St', '3 Extra Ave'] ); expect(request).toEqual({ name: 'Acme', addresses: ['2 New St', '3 Extra Ave'] }); }); }); describe('pricingLibraryItemFormSchema', () => { const valid = { title: 'Condenser coil cleaning', serviceCategory: 'HVAC' as const, unit: '', unitPrice: '', keywords: '', description: '', }; it('accepts empty unitPrice and rejects negatives/non-numbers', () => { expect(pricingLibraryItemFormSchema.safeParse(valid).success).toBe(true); expect( pricingLibraryItemFormSchema.safeParse({ ...valid, unitPrice: '-4' }).success ).toBe(false); expect( pricingLibraryItemFormSchema.safeParse({ ...valid, unitPrice: 'abc' }).success ).toBe(false); }); it('maps empty unitPrice to null and drops empty optional strings', () => { const request = toPricingLibraryItemRequest(valid); expect(request).toEqual({ title: 'Condenser coil cleaning', serviceCategory: 'HVAC', unitPrice: null }); const priced = toPricingLibraryItemRequest({ ...valid, unitPrice: '12.50', unit: 'each' }); expect(priced.unitPrice).toBe(12.5); expect(priced.unit).toBe('each'); }); }); describe('lineItemRowFormSchema', () => { const valid = { description: 'Install thermostat', unit: 'each', pricingMode: 'UnitPrice' as const, quantity: '2', unitPrice: '150', totalPrice: '300', }; it('accepts numeric strings and an empty unitPrice', () => { expect(lineItemRowFormSchema.safeParse(valid).success).toBe(true); expect(lineItemRowFormSchema.safeParse({ ...valid, unitPrice: '' }).success).toBe(true); expect(lineItemRowFormSchema.safeParse({ ...valid, quantity: '' }).success).toBe(false); expect(lineItemRowFormSchema.safeParse({ ...valid, totalPrice: '-1' }).success).toBe(false); }); it('maps to the wire entry with editor-managed identity', () => { const entry = toUpdateLineItemEntry(valid, { id: null, sortOrder: 3, source: 'Manual' }); expect(entry).toEqual({ id: null, description: 'Install thermostat', quantity: 2, unit: 'each', unitPrice: 150, totalPrice: 300, pricingMode: 'UnitPrice', sortOrder: 3, source: 'Manual', }); const noUnitPrice = toUpdateLineItemEntry( { ...valid, unitPrice: '' }, { id: 'li-1', sortOrder: 0, source: 'AI' } ); expect(noUnitPrice.unitPrice).toBeNull(); }); });