import { buildWorkflowFiles, belongsOnDjClearanceQueue, belongsOnEtClearanceQueue } from './phased-clearance.util'; describe('buildWorkflowFiles', () => { const resourceFiles = [ { code: 'im4', id: 'f-im4', name: 'im4.pdf', url: '/files/im4' }, { code: 'im5', id: 'f-im5', name: 'im5.pdf', url: '/files/im5' }, { code: 'transit_permitted', id: 'f-transit', name: 'transit.png', url: '/files/transit', }, { code: 'duty_tax_notice', id: 'f-duty', name: 'notice.pdf', url: '/files/duty', }, { code: 'commercial_invoice', id: 'f-inv', name: 'inv.pdf', url: '/files/inv' }, ]; it('includes declaration and transit files even when they also appear in GL output document settings', () => { const result = buildWorkflowFiles(resourceFiles, 'IMPORT'); expect(result.map((f) => f.code)).toEqual( expect.arrayContaining(['im4', 'im5', 'transit_permitted', 'duty_tax_notice']), ); }); it('includes multi-file declaration uploads alongside catalog codes', () => { const result = buildWorkflowFiles( [ ...resourceFiles, { code: 'declaration_0', id: 'f-dec-0', name: 'decl-a.pdf', url: '/files/decl-a', }, { code: 'declaration_1', id: 'f-dec-1', name: 'decl-b.pdf', url: '/files/decl-b', }, ], 'IMPORT', ); expect(result.map((f) => f.code)).toEqual( expect.arrayContaining(['im4', 'im5', 'declaration_0', 'declaration_1']), ); expect(result.find((f) => f.code === 'declaration_0')?.label).toBe( 'Declaration document 1', ); }); it('includes multi-file import transit permit uploads', () => { const result = buildWorkflowFiles( [ ...resourceFiles, { code: 'transit_permit_0', id: 'f-tp-0', name: 'permit-a.pdf', url: '/files/tp-a', }, { code: 'transit_permit_1', id: 'f-tp-1', name: 'permit-b.pdf', url: '/files/tp-b', }, ], 'IMPORT', ); expect(result.map((f) => f.code)).toEqual( expect.arrayContaining(['transit_permitted', 'transit_permit_0', 'transit_permit_1']), ); expect(result.find((f) => f.code === 'transit_permit_0')?.label).toBe('Transit permit 1'); }); it('does not include non-catalog customer document codes', () => { const result = buildWorkflowFiles(resourceFiles, 'IMPORT'); expect(result.some((f) => f.code === 'commercial_invoice')).toBe(false); }); }); describe('belongsOnDjClearanceQueue', () => { it('keeps import contracts after pre-clearance is finalized (even post-booking)', () => { expect( belongsOnDjClearanceQueue( 'IMPORT', { preClearanceFinalizedAt: new Date('2026-01-01') }, [], ), ).toBe(true); }); it('keeps contracts with completed Djibouti milestones', () => { expect( belongsOnDjClearanceQueue('IMPORT', null, [ { ownerRegion: 'DJ', status: 'COMPLETED' }, ]), ).toBe(true); }); it('keeps import contracts from the start — DO upload is un-gated', () => { expect(belongsOnDjClearanceQueue('IMPORT', null, [])).toBe(true); }); it('excludes export contracts with no DJ activity or RO hold', () => { expect(belongsOnDjClearanceQueue('EXPORT', null, [])).toBe(false); }); }); describe('belongsOnEtClearanceQueue', () => { it('keeps contracts once phased clearance milestones exist', () => { expect( belongsOnEtClearanceQueue([{ ownerRegion: 'ET', status: 'COMPLETED' }]), ).toBe(true); }); it('excludes contracts with no clearance milestones', () => { expect(belongsOnEtClearanceQueue([])).toBe(false); }); });