WFDASH-WEBAPP/src/lib/reports/download.test.ts
Dave 7555196166 feat(audit): implement audit trail for delivery notes and orders
- Added an audit trail feature that logs every create, update, and delete action on delivery notes and orders, capturing detailed changes per field.
- Introduced the `AuditTimeline` component to display the history of changes for delivery notes and orders, enhancing traceability.
- Updated the `page.tsx` files for delivery notes and orders to fetch and display audit logs, ensuring users can view the history of modifications.
- Enhanced the `package.json` with a new migration script for setting up the audit log functionality.

This feature improves accountability and transparency in the management of delivery notes and orders.
2026-09-30 01:48:44 +02:00

90 lines
2.8 KiB
TypeScript

import { describe, it, expect } from "vitest";
import {
filenameFromDisposition,
reportFileName,
safeFilePart,
} from "./download";
describe("reportFileName", () => {
it("is date range plus subject", () => {
expect(reportFileName("2026-09-01", "2026-09-30", "Gary")).toBe(
"2026-09-01 - 2026-09-30 - Gary.pdf",
);
});
it("keeps a two-word name intact", () => {
expect(reportFileName("2026-08-01", "2026-08-31", "David Els")).toBe(
"2026-08-01 - 2026-08-31 - David Els.pdf",
);
});
it("strips path separators so the name can't escape the download folder", () => {
expect(reportFileName("2026-09-01", "2026-09-30", "../../etc/passwd")).not.toContain("/");
});
});
describe("safeFilePart", () => {
it("drops characters that are illegal on Windows or awkward on macOS", () => {
expect(safeFilePart('a/b\\c:d*e?f"g<h>i|j')).not.toMatch(/[/\\:*?"<>|]/);
});
it("collapses runs of whitespace", () => {
expect(safeFilePart(" L & L Equip ")).toBe("L & L Equip");
});
it("keeps ampersands, hyphens, dots and parentheses used in real names", () => {
expect(safeFilePart("Harmony - Gold Mining (Pty) Ltd.")).toBe(
"Harmony - Gold Mining (Pty) Ltd.",
);
});
it("falls back when nothing usable survives", () => {
expect(safeFilePart("///", "report")).toBe("report");
});
});
describe("filenameFromDisposition", () => {
const target = "2026-09-01 - 2026-09-30 - Gary.pdf";
it("reads a quoted filename", () => {
expect(
filenameFromDisposition(`attachment; filename="${target}"`, "fallback.pdf"),
).toBe(target);
});
it("reads an unquoted filename", () => {
expect(filenameFromDisposition(`attachment; filename=${target}`, "fallback.pdf")).toBe(
target,
);
});
it("prefers filename* when present", () => {
const header =
`attachment; filename="fallback.pdf"; filename*=UTF-8''` +
encodeURIComponent(target);
expect(filenameFromDisposition(header, "x.pdf")).toBe(target);
});
it("survives a malformed filename* and uses the plain form", () => {
expect(
filenameFromDisposition(`attachment; filename="${target}"; filename*=UTF-8''%E0%A4%A`, "x.pdf"),
).toBe(target);
});
it("falls back when there is no header at all (4xx JSON responses)", () => {
expect(filenameFromDisposition(null, "fallback.pdf")).toBe("fallback.pdf");
});
it("falls back when the header carries no filename", () => {
expect(filenameFromDisposition("attachment", "fallback.pdf")).toBe("fallback.pdf");
});
it("still returns a .pdf name for a team report", () => {
expect(
filenameFromDisposition(
'attachment; filename="2026-09-01 - 2026-09-30 - All Reps.pdf"',
"x.pdf",
),
).toBe("2026-09-01 - 2026-09-30 - All Reps.pdf");
});
});