import { diffContractFields, summarizeChanges, } from './contract-document-diff.util'; /** * The contract-field audit runs on the customer's own edits, so it has to be * exact: never report a field the edit did not touch, and never render a value * as "[object Object]" or "true" in the trail a reviewer reads. */ describe('diffContractFields', () => { it('reports only the fields that actually changed', () => { const changes = diffContractFields( { freightType: 'BULK', paymentCurrency: 'USD', isReefer: false }, { freightType: 'CONTAINER', paymentCurrency: 'USD', isReefer: false }, ); expect(changes).toEqual([ { kind: 'FIELD_CHANGED', field: 'freightType', label: 'Freight type', from: 'BULK', to: 'CONTAINER', }, ]); }); it('renders booleans as Yes/No, not true/false', () => { const [change] = diffContractFields({ isHazardous: false }, { isHazardous: true }); expect(change).toMatchObject({ label: 'Hazardous', from: 'No', to: 'Yes' }); }); it('treats null, undefined and empty string as "not set"', () => { expect(diffContractFields({ unNumber: null }, { unNumber: '' })).toEqual([]); expect(diffContractFields({ unNumber: undefined }, { unNumber: null })).toEqual([]); const [set] = diffContractFields({ unNumber: null }, { unNumber: 'UN1234' }); expect(set).toMatchObject({ from: null, to: 'UN1234' }); }); it('ignores fields absent from the update', () => { // A partial edit must not report the fields it never sent. expect(diffContractFields({ freightType: 'BULK', isReefer: true }, {})).toEqual([]); }); it('records a route swap that keeps the same lane count', () => { const [change] = diffContractFields( { routes: 'Nagad → Mojo' }, { routes: 'Nagad → Adama' }, ); expect(change).toMatchObject({ label: 'Routes', from: 'Nagad → Mojo', to: 'Nagad → Adama', }); }); it('summarises field changes by name, and by count once there are many', () => { const few = diffContractFields( { freightType: 'BULK', paymentCurrency: 'USD' }, { freightType: 'CONTAINER', paymentCurrency: 'ETB' }, ); expect(summarizeChanges(few)).toBe('freight type, payment currency changed'); const many = diffContractFields( { a: '1', b: '1', c: '1', d: '1' }, { a: '2', b: '2', c: '2', d: '2' }, ); expect(summarizeChanges(many)).toBe('4 contract fields changed'); }); it('summarises document and field changes together', () => { const summary = summarizeChanges([ { kind: 'ARTICLE_BODY_CHANGED', articleId: 'a-1', title: 'Article 1' }, { kind: 'FIELD_CHANGED', field: 'routes', label: 'Routes', from: 'A → B', to: 'A → C', }, ]); expect(summary).toBe('1 article edited, routes changed'); }); });