Files
pn-new-crm/tests/unit/entity-diff.test.ts

92 lines
3.5 KiB
TypeScript
Raw Normal View History

import { describe, it, expect } from 'vitest';
import { diffEntity } from '@/lib/entity-diff';
describe('diffEntity', () => {
it('returns changed=false and empty diff for identical objects', () => {
const old = { name: 'Alice', status: 'active', count: 5 };
const result = diffEntity(old, { name: 'Alice', status: 'active', count: 5 });
expect(result).toEqual({ changed: false, diff: {} });
});
it('detects a single field change with correct old/new values', () => {
const old = { name: 'Alice', status: 'active' };
const result = diffEntity(old, { status: 'inactive' });
expect(result.changed).toBe(true);
expect(result.diff).toEqual({
status: { old: 'active', new: 'inactive' },
});
});
it('detects multiple field changes', () => {
const old = { name: 'Alice', status: 'active', count: 1 };
const result = diffEntity(old, { name: 'Bob', status: 'inactive', count: 2 });
expect(result.changed).toBe(true);
expect(Object.keys(result.diff)).toHaveLength(3);
expect(result.diff.name).toEqual({ old: 'Alice', new: 'Bob' });
expect(result.diff.status).toEqual({ old: 'active', new: 'inactive' });
expect(result.diff.count).toEqual({ old: 1, new: 2 });
});
it('detects null-to-value transition', () => {
const old = { note: null };
const result = diffEntity(old, { note: 'Hello' });
expect(result.changed).toBe(true);
expect(result.diff.note).toEqual({ old: null, new: 'Hello' });
});
it('detects value-to-null transition', () => {
const old = { note: 'Hello' };
const result = diffEntity(old, { note: null });
expect(result.changed).toBe(true);
expect(result.diff.note).toEqual({ old: 'Hello', new: null });
});
it('skips createdAt field', () => {
const now = new Date();
const old = { name: 'Alice', createdAt: now };
const result = diffEntity(old, { name: 'Alice', createdAt: new Date() });
expect(result.changed).toBe(false);
expect(result.diff).toEqual({});
});
it('skips updatedAt field', () => {
const old = { name: 'Alice', updatedAt: new Date('2020-01-01') };
const result = diffEntity(old, { name: 'Alice', updatedAt: new Date('2025-01-01') });
expect(result.changed).toBe(false);
expect(result.diff).toEqual({});
});
it('skips portId field', () => {
const old = { name: 'Alice', portId: 'port-1' };
const result = diffEntity(old, { name: 'Alice', portId: 'port-2' });
expect(result.changed).toBe(false);
expect(result.diff).toEqual({});
});
it('detects nested object (JSON field) changes', () => {
const old = { metadata: { color: 'red', size: 10 } };
const result = diffEntity(old, { metadata: { color: 'blue', size: 10 } });
expect(result.changed).toBe(true);
expect(result.diff.metadata).toEqual({
old: { color: 'red', size: 10 },
new: { color: 'blue', size: 10 },
});
});
it('only compares keys present in newRecord (partial update)', () => {
const old = { name: 'Alice', status: 'active', count: 99 };
// Only updating name; status and count should not appear in diff
const result = diffEntity(old, { name: 'Bob' });
expect(result.changed).toBe(true);
expect(Object.keys(result.diff)).toEqual(['name']);
expect(result.diff.name).toEqual({ old: 'Alice', new: 'Bob' });
});
it('returns changed=false when partial update has no actual changes', () => {
const old = { name: 'Alice', status: 'active', count: 99 };
const result = diffEntity(old, { name: 'Alice' });
expect(result.changed).toBe(false);
expect(result.diff).toEqual({});
});
});