102 lines
3.5 KiB
JavaScript
102 lines
3.5 KiB
JavaScript
import { parseTransactionsQuery, parseWindow, parseVerifyTargets, isUuid } from "./validate.js";
|
|
|
|
describe("parseTransactionsQuery", () => {
|
|
it("defaults type=core, dir=desc, sort undefined, and a 30-day window", () => {
|
|
const { ok, value } = parseTransactionsQuery({});
|
|
expect(ok).toBe(true);
|
|
expect(value.type).toBe("core");
|
|
expect(value.dir).toBe("desc");
|
|
expect(value.sort).toBeUndefined();
|
|
expect(value.limit).toBe(50);
|
|
expect(value.offset).toBe(0);
|
|
expect(value.from).toMatch(/^\d{4}-\d{2}-\d{2}$/);
|
|
});
|
|
|
|
it("accepts valid discrete params", () => {
|
|
const { ok, value } = parseTransactionsQuery({ type: "audit", sort: "size", dir: "asc" });
|
|
expect(ok).toBe(true);
|
|
expect(value).toMatchObject({ type: "audit", sort: "size", dir: "asc" });
|
|
});
|
|
|
|
it("rejects an invalid type", () => {
|
|
expect(parseTransactionsQuery({ type: "bogus" })).toMatchObject({ ok: false });
|
|
});
|
|
|
|
it("rejects an invalid sort key", () => {
|
|
expect(parseTransactionsQuery({ sort: "sender; DROP" })).toMatchObject({ ok: false });
|
|
});
|
|
|
|
it("rejects an invalid dir", () => {
|
|
expect(parseTransactionsQuery({ dir: "sideways" })).toMatchObject({ ok: false });
|
|
});
|
|
|
|
it("clamps limit/offset and caps search length", () => {
|
|
const { value } = parseTransactionsQuery({ limit: "99999", offset: "-3", q: "x".repeat(500) });
|
|
expect(value.limit).toBe(200);
|
|
expect(value.offset).toBe(0);
|
|
expect(value.q).toHaveLength(200);
|
|
});
|
|
});
|
|
|
|
describe("parseWindow", () => {
|
|
it("normalizes to a { from, to } window", () => {
|
|
expect(parseWindow({ from: "2026-01-01", to: "2026-01-31" })).toEqual({
|
|
from: "2026-01-01",
|
|
to: "2026-01-31",
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("parseVerifyTargets", () => {
|
|
const U1 = "3fa85f64-5717-4562-b3fc-2c963f66afa6";
|
|
const U2 = "11111111-2222-3333-4444-555555555555";
|
|
|
|
it("keeps valid UUIDs, drops junk, and de-duplicates", () => {
|
|
expect(parseVerifyTargets({ ids: `${U1}, junk ,${U2},${U1}` })).toEqual({
|
|
eventUuids: [U1, U2],
|
|
auditIds: [],
|
|
});
|
|
});
|
|
|
|
it("parses audit ids as positive integers, dropping anything else", () => {
|
|
expect(parseVerifyTargets({ auditIds: "9, 10 ,9,0,-3,abc,1.5" })).toEqual({
|
|
eventUuids: [],
|
|
auditIds: [9, 10],
|
|
});
|
|
});
|
|
|
|
it("accepts both lists at once (core rows by event, audit rows by audit id)", () => {
|
|
expect(parseVerifyTargets({ ids: U1, auditIds: "42" })).toEqual({
|
|
eventUuids: [U1],
|
|
auditIds: [42],
|
|
});
|
|
});
|
|
|
|
it("returns empty lists when absent or empty", () => {
|
|
expect(parseVerifyTargets({})).toEqual({ eventUuids: [], auditIds: [] });
|
|
expect(parseVerifyTargets({ ids: "", auditIds: "" })).toEqual({ eventUuids: [], auditIds: [] });
|
|
});
|
|
|
|
it("caps the two lists at 200 targets COMBINED", () => {
|
|
const auditIds = Array.from({ length: 250 }, (_, i) => i + 1).join(",");
|
|
const one = parseVerifyTargets({ auditIds });
|
|
expect(one.auditIds).toHaveLength(200);
|
|
|
|
// 150 events leaves room for only 50 audit ids.
|
|
const events = Array.from({ length: 150 }, (_, i) =>
|
|
`3fa85f64-5717-4562-b3fc-${String(i).padStart(12, "0")}`).join(",");
|
|
const both = parseVerifyTargets({ ids: events, auditIds });
|
|
expect(both.eventUuids).toHaveLength(150);
|
|
expect(both.auditIds).toHaveLength(50);
|
|
});
|
|
});
|
|
|
|
describe("isUuid", () => {
|
|
it("accepts canonical UUIDs and rejects junk", () => {
|
|
expect(isUuid("3fa85f64-5717-4562-b3fc-2c963f66afa6")).toBe(true);
|
|
expect(isUuid("not-a-uuid")).toBe(false);
|
|
expect(isUuid("")).toBe(false);
|
|
expect(isUuid(null)).toBe(false);
|
|
});
|
|
});
|