// The audit log's first screen was one job's "done" ten times over. A job's successful runs fold // into one row whatever ran between them (the owner: a fold broken by every other job read as the same // row five times); only that job's own failure or skip breaks it. import { describe, expect, it } from "vitest"; import type { AuditRow } from "./api"; import { foldJobRuns } from "./auditGroups"; let nextId = 1; const run = (job: string, status = "ok"): AuditRow => ({ id: nextId++, created_at: null, actor: null, action: "job_run", target_type: "job", target_id: job, summary: null, before: null, after: { status }, }); const admin = (): AuditRow => ({ ...run("x"), action: "config_set", target_type: "config" }); const shape = (rows: ReturnType) => rows.map((r) => `${r.target_id}:${String(r.after?.status)}×${r.runs?.length ?? 1}`); describe("folding the job runs", () => { it("folds a job's successful runs into one row, newest first", () => { const rows = [run("enrich"), run("enrich"), run("enrich"), run("people")]; const out = foldJobRuns(rows); expect(shape(out)).toEqual(["enrich:ok×3", "people:ok×1"]); expect(out[0]!.id).toBe(rows[0]!.id); expect(out[0]!.runs!.map((r) => r.id)).toEqual(rows.slice(0, 3).map((r) => r.id)); }); it("never folds a failed or skipped run, and lets it break the run", () => { const rows = [run("rss"), run("rss", "error"), run("rss", "error"), run("rss"), run("rss")]; expect(shape(foldJobRuns(rows))).toEqual([ "rss:ok×1", "rss:error×1", "rss:error×1", "rss:ok×2", ]); expect(shape(foldJobRuns([run("rss", "skipped"), run("rss", "skipped")]))).toEqual([ "rss:skipped×1", "rss:skipped×1", ]); }); it("folds across other jobs and an admin's own action, each at its own place", () => { const rows = [run("enrich"), run("plex"), run("enrich"), admin(), run("shorts"), run("enrich")]; rows.push(run("plex")); const out = foldJobRuns(rows); expect(shape(out)).toEqual(["enrich:ok×3", "plex:ok×2", "x:ok×1", "shorts:ok×1"]); expect(out[0]!.runs!.map((r) => r.id)).toEqual([rows[0]!.id, rows[2]!.id, rows[5]!.id]); }); it("starts a new fold below the job's own failure, which another job's does not", () => { const rows = [run("enrich"), run("enrich", "error"), run("enrich"), run("rss", "error")]; rows.push(run("enrich")); expect(shape(foldJobRuns(rows))).toEqual([ "enrich:ok×1", "enrich:error×1", "enrich:ok×2", "rss:error×1", ]); }); it("leaves the rows it was given as they were", () => { const rows = [run("enrich"), run("enrich")]; foldJobRuns(rows); expect("runs" in rows[0]!).toBe(false); }); });