Files
edr-platform/apps/edr-freight-api/src/modules/contracts/contract-field-diff.spec.ts

90 lines
2.9 KiB
TypeScript

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');
});
});