import { describe, it, expect } from 'vitest'; import { buildDocumensoPayload } from '@/lib/services/documenso-payload'; import type { EoiContext } from '@/lib/services/eoi-context'; function makeContext(overrides?: Partial): EoiContext { return { client: { fullName: 'Alice Smith', nationality: 'US', primaryEmail: 'alice@example.com', primaryPhone: '+1-555-0100', address: { street: '123 Main St', city: 'Austin', country: 'USA' }, }, yacht: { name: 'Sea Breeze', lengthFt: '45', widthFt: '14', draftFt: '6', lengthM: null, widthM: null, draftM: null, hullNumber: 'ABC-123', flag: 'US', yearBuilt: 2020, }, company: null, owner: { type: 'client', name: 'Alice Smith' }, berth: { mooringNumber: 'A-12', area: 'North Dock', lengthFt: '50', price: '1200', priceCurrency: 'USD', tenureType: 'permanent', }, interest: { stage: 'open', leadCategory: null, dateFirstContact: null, notes: null, }, port: { name: 'Port Nimara', defaultCurrency: 'USD', }, date: { today: '2026-04-23', year: '2026' }, ...overrides, }; } const OPTIONS = { interestId: 'int-123', clientRecipientId: 192, developerRecipientId: 193, approvalRecipientId: 194, }; describe('buildDocumensoPayload', () => { it('builds title as "{fullName}-EOI-NDA"', () => { const payload = buildDocumensoPayload(makeContext(), OPTIONS); expect(payload.title).toBe('Alice Smith-EOI-NDA'); }); it('builds externalId as "loi-{interestId}"', () => { const payload = buildDocumensoPayload(makeContext(), OPTIONS); expect(payload.externalId).toBe('loi-int-123'); }); it('formats formValues with all EoiContext fields', () => { const payload = buildDocumensoPayload(makeContext(), OPTIONS); expect(payload.formValues).toEqual({ Name: 'Alice Smith', Email: 'alice@example.com', Address: '123 Main St, Austin, USA', 'Yacht Name': 'Sea Breeze', Length: '45', Width: '14', Draft: '6', 'Berth Number': 'A-12', Lease_10: false, Purchase: true, }); }); it('defaults missing primaryEmail to empty string', () => { const ctx = makeContext({ client: { ...makeContext().client, primaryEmail: null } }); const payload = buildDocumensoPayload(ctx, OPTIONS); expect(payload.formValues.Email).toBe(''); expect(payload.recipients[0]!.email).toBe(''); }); it('defaults missing yacht dimensions to empty strings', () => { const baseYacht = makeContext().yacht!; const ctx = makeContext({ yacht: { ...baseYacht, lengthFt: null, widthFt: null, draftFt: null }, }); const payload = buildDocumensoPayload(ctx, OPTIONS); expect(payload.formValues.Length).toBe(''); expect(payload.formValues.Width).toBe(''); expect(payload.formValues.Draft).toBe(''); }); it('renders empty Section 3 when yacht and berth are not linked', () => { const ctx = makeContext({ yacht: null, berth: null }); const payload = buildDocumensoPayload(ctx, OPTIONS); expect(payload.formValues['Yacht Name']).toBe(''); expect(payload.formValues.Length).toBe(''); expect(payload.formValues.Width).toBe(''); expect(payload.formValues.Draft).toBe(''); expect(payload.formValues['Berth Number']).toBe(''); }); it('formats empty address when client has no address', () => { const ctx = makeContext({ client: { ...makeContext().client, address: null } }); const payload = buildDocumensoPayload(ctx, OPTIONS); expect(payload.formValues.Address).toBe(''); }); it('skips null parts in address', () => { const ctx = makeContext({ client: { ...makeContext().client, address: { street: '', city: 'Austin', country: 'USA' }, }, }); const payload = buildDocumensoPayload(ctx, OPTIONS); expect(payload.formValues.Address).toBe('Austin, USA'); }); it('sets Lease_10=false and Purchase=true (hardcoded)', () => { const payload = buildDocumensoPayload(makeContext(), OPTIONS); expect(payload.formValues.Lease_10).toBe(false); expect(payload.formValues.Purchase).toBe(true); }); it('includes client, developer, and approver recipients in signing order', () => { const payload = buildDocumensoPayload(makeContext(), OPTIONS); expect(payload.recipients).toHaveLength(3); expect(payload.recipients[0]).toEqual({ id: 192, name: 'Alice Smith', email: 'alice@example.com', role: 'SIGNER', signingOrder: 1, }); expect(payload.recipients[1]).toEqual({ id: 193, name: 'David Mizrahi', email: 'dm@portnimara.com', role: 'SIGNER', signingOrder: 2, }); expect(payload.recipients[2]).toEqual({ id: 194, name: 'Abbie May', email: 'sales@portnimara.com', role: 'APPROVER', signingOrder: 3, }); }); it('allows overriding developer/approver recipient names', () => { const payload = buildDocumensoPayload(makeContext(), { ...OPTIONS, developerName: 'Custom Dev', developerEmail: 'dev@custom.com', approverName: 'Custom Approver', approverEmail: 'approve@custom.com', }); expect(payload.recipients[1]!.name).toBe('Custom Dev'); expect(payload.recipients[1]!.email).toBe('dev@custom.com'); expect(payload.recipients[2]!.name).toBe('Custom Approver'); expect(payload.recipients[2]!.email).toBe('approve@custom.com'); }); it('builds message with port name and greeting', () => { const payload = buildDocumensoPayload(makeContext(), OPTIONS); expect(payload.meta.message).toContain('Dear Alice Smith'); expect(payload.meta.message).toContain('Port Nimara'); expect(payload.meta.message).toContain('Best Regards'); // No company on-behalf block for client-owned yachts expect(payload.meta.message).not.toContain('On behalf of'); }); it('adds company on-behalf block for company-owned yachts', () => { const ctx = makeContext({ company: { name: 'Aegean Holdings', legalName: 'Aegean Holdings SA', taxId: null, billingAddress: null, }, owner: { type: 'company', name: 'Aegean Holdings', legalName: 'Aegean Holdings SA' }, }); const payload = buildDocumensoPayload(ctx, OPTIONS); expect(payload.meta.message).toContain('On behalf of Aegean Holdings SA'); }); it('uses company name when legalName is missing in on-behalf block', () => { const ctx = makeContext({ company: { name: 'Blue Seas', legalName: null, taxId: null, billingAddress: null }, owner: { type: 'company', name: 'Blue Seas' }, }); const payload = buildDocumensoPayload(ctx, OPTIONS); expect(payload.meta.message).toContain('On behalf of Blue Seas'); }); it('uses default redirect URL when not provided', () => { const payload = buildDocumensoPayload(makeContext(), OPTIONS); expect(payload.meta.redirectUrl).toBe('https://portnimara.com'); }); it('uses custom redirect URL when provided', () => { const payload = buildDocumensoPayload(makeContext(), { ...OPTIONS, redirectUrl: 'https://custom.example.com', }); expect(payload.meta.redirectUrl).toBe('https://custom.example.com'); }); });