- Added a new skill for managing index and list table layouts in the ERP project, detailing layout and data contracts. - Updated project guidelines to reference the new index layout skill. - Introduced rules for page composition, column definitions, audit fields, action column width, and toolbar functionality. - Created utility functions for computing action column width and formatting audit fields, along with corresponding unit tests to ensure reliability. These changes enhance the application by providing a structured approach to index layouts, improving consistency and usability across the ERP project.
66 lines
2.4 KiB
TypeScript
66 lines
2.4 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { DateUtils } from '@repo/utils';
|
|
import {
|
|
EMPTY_AUDIT_DISPLAY,
|
|
formatAuditActor,
|
|
formatAuditTimestamp,
|
|
resolveAuditValue,
|
|
} from './audit-column.utils';
|
|
|
|
describe('resolveAuditValue', () => {
|
|
it('prefers camelCase over snake_case', () => {
|
|
expect(
|
|
resolveAuditValue({ createdBy: 'alice', creator_name: 'legacy' }, 'createdBy', 'creator_name'),
|
|
).toBe('alice');
|
|
});
|
|
|
|
it('falls back to snake_case when camelCase is missing', () => {
|
|
expect(resolveAuditValue({ creator_name: 'legacy' }, 'createdBy', 'creator_name')).toBe('legacy');
|
|
expect(resolveAuditValue({ created_at: 1_700_000_000_000 }, 'createdAt', 'created_at')).toBe(
|
|
1_700_000_000_000,
|
|
);
|
|
});
|
|
|
|
it('returns undefined when neither field is present', () => {
|
|
expect(resolveAuditValue({}, 'createdBy', 'creator_name')).toBeUndefined();
|
|
expect(resolveAuditValue(undefined, 'createdBy', 'creator_name')).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe('formatAuditActor', () => {
|
|
it('returns a string actor as-is', () => {
|
|
expect(formatAuditActor('alice')).toBe('alice');
|
|
});
|
|
|
|
it('prefers username, then name, then id on nested actors', () => {
|
|
expect(formatAuditActor({ username: 'alice', name: 'Alice', id: 'u-1' })).toBe('alice');
|
|
expect(formatAuditActor({ name: 'Alice', id: 'u-1' })).toBe('Alice');
|
|
expect(formatAuditActor({ id: 'u-1' })).toBe('u-1');
|
|
});
|
|
|
|
it('returns a dash when the actor is empty', () => {
|
|
expect(formatAuditActor(undefined)).toBe(EMPTY_AUDIT_DISPLAY);
|
|
expect(formatAuditActor(null)).toBe(EMPTY_AUDIT_DISPLAY);
|
|
expect(formatAuditActor('')).toBe(EMPTY_AUDIT_DISPLAY);
|
|
expect(formatAuditActor({})).toBe(EMPTY_AUDIT_DISPLAY);
|
|
});
|
|
});
|
|
|
|
describe('formatAuditTimestamp', () => {
|
|
it('formats unix milliseconds with DateUtils', () => {
|
|
const ms = 1_700_000_000_000;
|
|
expect(formatAuditTimestamp(ms)).toBe(new DateUtils(ms).format('DD-MM-YYYY, HH:mm'));
|
|
});
|
|
|
|
it('accepts numeric strings', () => {
|
|
const ms = '1700000000000';
|
|
expect(formatAuditTimestamp(ms)).toBe(new DateUtils(Number(ms)).format('DD-MM-YYYY, HH:mm'));
|
|
});
|
|
|
|
it('returns a dash when the timestamp is empty', () => {
|
|
expect(formatAuditTimestamp(undefined)).toBe(EMPTY_AUDIT_DISPLAY);
|
|
expect(formatAuditTimestamp(null)).toBe(EMPTY_AUDIT_DISPLAY);
|
|
expect(formatAuditTimestamp('')).toBe(EMPTY_AUDIT_DISPLAY);
|
|
});
|
|
});
|