Files
edr-platform/apps/edr-freight-api/src/modules/reports/report.registry.spec.ts
Nathnael efc5a24380 feat(reports): add optional chart view to the report engine
ReportDefinition gets an optional chart {type: line|bar, x, y[]} field —
plots the same rows the table gets, no separate query. Frontend adds a
table/chart toggle (defaults to table) using the existing recharts
dependency, no new package.

Chart view fetches up to 100 rows (the API's page-size ceiling) instead
of the table's current page, so it doesn't silently plot a fraction of
the filtered set; shows a truncation note past that cap.

Wired onto 5 reports as proof: wagon-fleet-status, locomotive-fleet-
status, booking-status-breakdown, revenue-summary (bar), and
global-logistics-wagons (line). Everything else stays table-only —
charting is opt-in per report, not a default.
2026-08-13 08:34:08 +00:00

53 lines
1.8 KiB
TypeScript

import { REPORT_KEYS } from '../../seed/freight-permissions.registry';
import { REPORTS, getReport } from './report.registry';
describe('REPORTS', () => {
it('has exactly one definition per seeded REPORT_KEYS entry', () => {
const defKeys = REPORTS.map((r) => r.key).sort();
expect(defKeys).toEqual([...REPORT_KEYS].sort());
});
it('has no duplicate keys', () => {
const keys = REPORTS.map((r) => r.key);
expect(new Set(keys).size).toBe(keys.length);
});
it('resolves every key via getReport', () => {
for (const key of REPORT_KEYS) {
expect(getReport(key)?.key).toBe(key);
}
});
it('every sortable column and defaultSort point at a real column key', () => {
for (const def of REPORTS) {
const columnKeys = new Set(def.columns.map((c) => c.key));
if (def.defaultSort) {
expect(columnKeys.has(def.defaultSort.key)).toBe(true);
}
// Every column marked sortable must have a resolvable key (itself, since
// the runner falls back to `key` when `sortExpr` is absent).
for (const col of def.columns.filter((c) => c.sortable)) {
expect(col.key.length).toBeGreaterThan(0);
}
}
});
it('idKey, when declared, is not also listed as a user-facing filter', () => {
for (const def of REPORTS) {
if (!def.idKey) continue;
expect(def.filters.some((f) => f.key === def.idKey!.key)).toBe(false);
}
});
it('chart.x and chart.y, when declared, point at real column keys', () => {
for (const def of REPORTS) {
if (!def.chart) continue;
const columnKeys = new Set(def.columns.map((c) => c.key));
expect(columnKeys.has(def.chart.x)).toBe(true);
for (const y of def.chart.y) {
expect(columnKeys.has(y)).toBe(true);
}
}
});
});