Files
twenty/packages/twenty-front/src/utils/getDirtyFields.spec.ts

116 lines
3.8 KiB
TypeScript

import { getDirtyFields } from './getDirtyFields';
describe('getDirtyFields', () => {
it('should return all defined fields from draft when persisted is null', () => {
const draft = { a: 1, b: 'hello', c: undefined, d: null };
const persisted = null;
expect(getDirtyFields(draft, persisted)).toEqual({
a: 1,
b: 'hello',
d: null,
});
});
it('should return all defined fields from draft when persisted is undefined', () => {
const draft = { a: 1, b: 'hello', c: undefined, d: false };
const persisted = undefined;
expect(getDirtyFields(draft, persisted)).toEqual({
a: 1,
b: 'hello',
d: false,
});
});
it('should return an empty object when draft and persisted are identical', () => {
const draft = { a: 1, b: { c: 2 }, d: [1, 2] };
const persisted = { a: 1, b: { c: 2 }, d: [1, 2] };
expect(getDirtyFields(draft, persisted)).toEqual({});
});
it('should detect simple value changes', () => {
const draft = { a: 1, b: 'world', c: true };
const persisted = { a: 1, b: 'hello', c: false };
expect(getDirtyFields(draft, persisted)).toEqual({ b: 'world', c: true });
});
it('should detect nested object changes', () => {
const draft = { a: { b: { c: 3 } } };
const persisted = { a: { b: { c: 2 } } };
expect(getDirtyFields(draft, persisted)).toEqual({ a: { b: { c: 3 } } });
});
it('should detect array changes', () => {
const draft = { a: [1, 3] };
const persisted = { a: [1, 2] };
expect(getDirtyFields(draft, persisted)).toEqual({ a: [1, 3] });
});
it('should detect added fields', () => {
const draft = { a: 1, b: 2 };
const persisted = { a: 1 };
expect(getDirtyFields(draft, persisted)).toEqual({ b: 2 });
});
it('should detect removed fields (value becomes undefined)', () => {
const draft = { a: 1 };
const persisted = { a: 1, b: 2 };
// When a field is removed, its value in draft effectively becomes undefined
// Cast persisted to any to satisfy TS in this test scenario
expect(getDirtyFields(draft, persisted as any)).toEqual({ b: undefined });
});
it('should detect fields set to undefined', () => {
const draft = { a: 1, b: undefined };
const persisted = { a: 1, b: 2 };
// Cast persisted to any to satisfy TS in this test scenario
expect(getDirtyFields(draft, persisted as any)).toEqual({ b: undefined });
});
it('should detect fields set to null', () => {
const draft = { a: 1, b: null };
const persisted = { a: 1, b: 2 };
// Cast persisted to any to satisfy TS in this test scenario
expect(getDirtyFields(draft, persisted as any)).toEqual({ b: null });
});
it('should handle complex nested structures with mixed changes', () => {
const draft = {
id: 1,
name: 'new name', // changed
details: {
status: 'active', // same
tags: ['tag1', 'tag3'], // changed
metadata: { key: 'newValue' }, // changed
},
settings: { enabled: true }, // new
};
const persisted = {
id: 1,
name: 'old name',
details: {
status: 'active',
tags: ['tag1', 'tag2'],
metadata: { key: 'oldValue' },
},
archived: true, // removed
};
// Cast persisted to any to satisfy TS in this test scenario
expect(getDirtyFields(draft, persisted as any)).toEqual({
name: 'new name',
details: {
status: 'active',
tags: ['tag1', 'tag3'],
metadata: { key: 'newValue' },
},
settings: { enabled: true },
archived: undefined,
});
});
it('should return empty object for deeply equal but different reference objects', () => {
const draft = { a: { b: 1 } };
const persisted = JSON.parse(JSON.stringify(draft)); // Deep clone, different reference
expect(getDirtyFields(draft, persisted)).toEqual({});
});
});