repositories / dotfiles
dotfiles
bugabingas dorkfiles
owned by admin
pi/agent/skillz/ims-process-review/scripts/ims.test.mjs
Rawimport assert from "node:assert/strict";
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";
import { test } from "node:test";
import {
applyPlan,
applyReplacements,
assertEquivalentStorage,
checkPolicy,
createSnapshot,
parseBaseline,
parseCli,
parseDate,
parseHeaderHtml,
parseReportHtml,
readPlan,
selectWorklist,
validatePlan,
} from "./ims.mjs";
const reportHtml = `
<table><tbody>
<tr><th>Prozess</th><th>Document Owner</th><th>Risk Owner</th><th>Asset Owner</th><th>Klassifizierung</th><th>Status</th><th>Geprüft von</th><th>Geprüft am</th><th>Freigegeben von</th><th>Freigegeben am</th></tr>
<tr>
<td><a href="/wiki/spaces/RD/pages/101/Alpha">Alpha & Beta</a></td>
<td><a data-account-id="owner-1">Kathi Borrmann</a></td><td>Risk</td><td>Asset</td><td>Intern</td><td>Prüfung</td>
<td><a data-account-id="oliver">Oliver Krylow</a></td><td>20.08.2026</td><td>Release</td><td>21.08.2026</td>
</tr>
<tr>
<td data-content-id="102"><a href="/wiki/spaces/GA/pages/102/Draft">Draft</a></td>
<td><a data-account-id="oliver">Oliver Krylow</a></td><td>Risk</td><td>Asset</td><td>Intern</td><td>Entwurf</td>
<td></td><td></td><td></td><td></td>
</tr>
<tr>
<td><a href="/wiki/spaces/isp/pages/103/Old">Old</a></td>
<td><a data-account-id="oliver">Oliver Krylow</a></td><td>Risk</td><td>Asset</td><td>Intern</td><td>Freigegeben</td>
<td><a data-account-id="oliver">Oliver Krylow</a></td><td>25.08.2025</td><td>Release</td><td>26.08.2025</td>
</tr>
</tbody></table>`;
test("parses IMS report rows and entities", () => {
const rows = parseReportHtml(reportHtml);
assert.equal(rows.length, 3);
assert.deepEqual(rows[0], {
id: "101",
title: "Alpha & Beta",
href: "/wiki/spaces/RD/pages/101/Alpha",
area: "RD",
documentOwner: "Kathi Borrmann",
documentOwnerIds: ["owner-1"],
riskOwner: "Risk",
riskOwnerIds: [],
assetOwner: "Asset",
assetOwnerIds: [],
classification: "Intern",
status: "Prüfung",
reviewer: "Oliver Krylow",
reviewerIds: ["oliver"],
reviewedAt: "20.08.2026",
releasedBy: "Release",
releasedAt: "21.08.2026",
});
assert.equal(rows[1].id, "102");
});
test("builds distinct reviewer and owner worklists with RD first", () => {
const rows = parseReportHtml(reportHtml);
const reviewer = selectWorklist(rows, { mode: "reviewer", person: "ignored", accountId: "oliver", area: "all", today: "2026-08-27" });
assert.deepEqual(reviewer.candidates.map((row) => [row.id, row.reasons]), [["101", ["awaiting-review"]]]);
const owner = selectWorklist(rows, { mode: "owner", person: "ignored", accountId: "oliver", area: "all", today: "2026-08-27" });
assert.deepEqual(owner.candidates.map((row) => row.id), ["103", "102"]);
assert.deepEqual(owner.candidates[0].reasons, ["self-reviewer", "annual-review-due"]);
assert.deepEqual(owner.candidates[1].reasons, ["draft", "missing-reviewer"]);
const nearName = [{ ...rows[1], documentOwner: "Max Anna Meyer", documentOwnerIds: [] }];
assert.equal(selectWorklist(nearName, { mode: "owner", person: "Anna Meyer", area: "all", today: "2026-08-27" }).roleMatchCount, 0);
});
test("rejects impossible German calendar dates", () => {
assert.equal(parseDate("31.02.2026"), undefined);
assert.equal(parseDate("2026-02-29"), undefined);
assert.equal(parseDate("29.02.2024")?.toISOString(), "2024-02-29T00:00:00.000Z");
assert.equal(parseDate("2024-02-29")?.toISOString(), "2024-02-29T00:00:00.000Z");
});
test("parses the policy baseline and detects version changes", async () => {
const baseline = parseBaseline(`
- Instruction page: \`540606500\`, version \`24\`, [Instructions](https://site.example/wiki/x/a)
- Announcement: \`1437532339\`, version \`1\`, [Announcement](https://site.example/wiki/x/b)
- Worklist report: \`899153943\`, [Report](https://site.example/wiki/x/c)
`);
assert.equal(baseline.baseUrl, "https://site.example");
const client = {
async get(requestPath) {
return { version: { number: requestPath.includes("blogposts") ? 2 : 24 } };
},
};
const result = await checkPolicy(client, baseline);
assert.equal(result.changed, true);
assert.deepEqual(result.sources.map((source) => source.changed), [false, true]);
});
test("extracts row and matrix IMS headers", () => {
const rows = `<table><tr><th>Status:</th><td>Prüfung</td></tr><tr><td>Geprüft von</td><td>Marcus Storre</td></tr></table>`;
assert.deepEqual(parseHeaderHtml(rows), { Status: "Prüfung", "Geprüft von": "Marcus Storre" });
const matrix = `<table><tr><th>Document Owner</th><th>Risk Owner</th></tr><tr><td>Oliver Krylow</td><td>Marcus Storre</td></tr></table>`;
assert.deepEqual(parseHeaderHtml(matrix), { "Document Owner": "Oliver Krylow", "Risk Owner": "Marcus Storre" });
});
test("check-plan is read-only and apply requires the separate mutation gate", () => {
assert.equal(parseCli(["check-plan", "plan.json"]).allowMutation, false);
assert.throws(() => parseCli(["apply", "plan.json", "--expected-version", "7", "--plan-sha256", "a".repeat(64)]), /--allow-mutation/);
assert.throws(() => parseCli(["apply", "plan.json", "--expected-version", "7", "--allow-mutation"]), /--plan-sha256/);
});
test("locks the exact validated plan bytes", (t) => {
const dir = mkdtempSync(path.join(tmpdir(), "ims-plan-test-"));
t.after(() => rmSync(dir, { recursive: true, force: true }));
const file = path.join(dir, "plan.json");
writeFileSync(file, JSON.stringify({
pageId: "123",
expectedVersion: 7,
operations: [{ kind: "page", versionComment: "geprüft", replacements: [{ from: "old", to: "new" }], expect: { contains: ["new"] } }],
}));
const first = readPlan(file);
writeFileSync(file, `${first.source}\n`);
const second = readPlan(file);
assert.notEqual(first.sha256, second.sha256);
assert.deepEqual(first.plan, second.plan);
});
test("rejects plan and replacement shapes that could silently broaden a write", () => {
assert.throws(() => validatePlan({ pageId: "x", expectedVersion: 1, operations: [] }), /pageId/);
assert.throws(() => validatePlan({ pageId: "1", expectedVersion: 1, operations: [{ kind: "page", versionComment: "x", replacements: [] }] }), /lacks replacements/);
assert.throws(() => validatePlan({ pageId: "1", expectedVersion: 1, operations: [{ kind: "page", versionComment: "x", replacements: [{ from: "a", to: "b" }], expect: { contains: "b" } }] }), /expect.contains/);
assert.throws(() => validatePlan({ pageId: "1", expectedVersion: 1, operations: [{ kind: "page", versionComment: "x", replacements: [{ from: "a", to: "b" }] }] }), /at least one expectation/);
assert.throws(() => validatePlan({ pageId: "1", expectedVersion: 1, operations: [
{ kind: "page", versionComment: "x", replacements: [{ from: "a", to: "b" }], expect: { contains: ["b"] } },
{ kind: "inline-comment", target: "b", text: "fix" },
] }), /must precede/);
assert.throws(() => applyReplacements("one old", [{ from: "old", to: "new", count: 2 }]), /found 1/);
assert.throws(
() => applyReplacements('<ac:inline-comment-marker ac:ref="marker">old</ac:inline-comment-marker>', [{ from: '<ac:inline-comment-marker ac:ref="marker">old</ac:inline-comment-marker>', to: "new" }]),
/inline-comment markers/,
);
});
test("accepts server-only storage attributes but rejects semantic drift", () => {
const expected = '<p><ac:link><ri:user ri:account-id="person" /></ac:link>Hello</p>';
const normalized = '<p data-local-id="server"><ac:link ac:local-id="server"><ri:user ri:account-id="person" /></ac:link>Hello</p>';
assert.doesNotThrow(() => assertEquivalentStorage(expected, normalized));
assert.throws(() => assertEquivalentStorage(expected, normalized.replace("person", "other")), /differs/);
assert.throws(() => assertEquivalentStorage("<p>Hello <strong>world</strong></p>", "<p>Hello<strong>world</strong></p>"), /differs/);
const links = '<p><ac:link><ri:page ri:space-key="RD" ri:content-title="Rules" /></ac:link>One <ac:link><ri:page ri:space-key="GA" ri:content-title="Rules" /></ac:link>Two</p>';
const swapped = links.replace('ri:space-key="RD"', 'ri:space-key="TEMP"').replace('ri:space-key="GA"', 'ri:space-key="RD"').replace('ri:space-key="TEMP"', 'ri:space-key="GA"');
assert.throws(() => assertEquivalentStorage(links, swapped), /differs/);
});
test("applies a version-gated page plan and emits an exact receipt", async () => {
let page = {
id: "123",
title: "Process",
status: "current",
spaceId: "space-1",
version: { number: 3, message: "before" },
body: { storage: { value: '<table><tr><th>Status</th><td>Prüfung</td></tr></table><p><ac:inline-comment-marker ac:ref="keep">Old</ac:inline-comment-marker></p>' } },
_links: { webui: "/wiki/spaces/RD/pages/123/Process" },
};
let mutations = 0;
const client = {
async get(requestPath) {
assert.match(requestPath, /pages\/123\?body-format=storage/);
return structuredClone(page);
},
async mutate(method, requestPath, body) {
mutations += 1;
assert.equal(method, "PUT");
assert.equal(requestPath, "wiki/api/v2/pages/123");
assert.equal(body.spaceId, "space-1");
page = {
...page,
version: structuredClone(body.version),
body: { storage: { value: body.body.value.replace("<p>", '<p data-local-id="server">') } },
};
return structuredClone(page);
},
};
const plan = validatePlan({
pageId: "123",
expectedVersion: 3,
operations: [{
kind: "page",
versionComment: "Rechtschreibkorrektur",
replacements: [{ from: "Old", to: "New" }],
expect: { contains: ["New"], notContains: ["Old"] },
}],
});
const receipt = await applyPlan(plan, client, "https://site.example");
assert.equal(mutations, 1);
assert.deepEqual(receipt, {
pageId: "123",
initialVersion: 3,
operations: [{ kind: "page", version: 4, versionComment: "Rechtschreibkorrektur", validation: "passed" }],
inlineComments: [],
validation: "passed",
url: "https://site.example/wiki/spaces/RD/pages/123/Process",
finalVersion: 4,
versionComment: "Rechtschreibkorrektur",
header: { Status: "Prüfung" },
});
});
test("stops before mutation on version drift", async () => {
let mutations = 0;
const client = {
async get() {
return { id: "123", version: { number: 8 }, body: { storage: { value: "old" } } };
},
async mutate() {
mutations += 1;
},
};
const plan = validatePlan({ pageId: "123", expectedVersion: 7, operations: [{ kind: "page", versionComment: "x", replacements: [{ from: "old", to: "new" }], expect: { contains: ["new"] } }] });
await assert.rejects(applyPlan(plan, client, "https://site.example"), /version drift/);
assert.equal(mutations, 0);
});
test("creates and verifies an inline comment and its page marker", async () => {
let storage = "<p>Before exact target after</p>";
const page = (representation) => ({
id: "123",
title: "Process",
status: "current",
version: { number: 5, message: "before" },
body: representation === "storage"
? { storage: { value: storage } }
: { atlas_doc_format: { value: JSON.stringify({ type: "doc", content: [{ type: "paragraph", content: [{ type: "text", text: "Before exact " }, { type: "text", text: "target after" }] }] }) } },
_links: { webui: "/wiki/pages/123" },
});
let comment;
const client = {
async get(requestPath) {
if (requestPath.includes("inline-comments/c1")) return structuredClone(comment);
if (requestPath.includes("/inline-comments?")) return { results: [{ id: "c1" }] };
if (requestPath.includes("atlas_doc_format")) return page("atlas_doc_format");
return page("storage");
},
async mutate(method, requestPath, body) {
assert.equal(method, "POST");
assert.equal(requestPath, "wiki/api/v2/inline-comments");
assert.equal(body.inlineCommentProperties.textSelection, "exact target");
storage = storage.replace("exact target", '<ac:inline-comment-marker ac:ref="marker-1">exact target</ac:inline-comment-marker>');
comment = {
id: "c1",
pageId: "123",
resolutionStatus: "open",
body: { storage: { value: "<p>Prüfung nötig</p>" } },
properties: { inlineOriginalSelection: "exact target", inlineMarkerRef: "marker-1" },
};
return { id: "c1" };
},
};
const plan = validatePlan({
pageId: "123",
expectedVersion: 5,
operations: [{ kind: "inline-comment", target: "exact target", text: "Prüfung nötig" }],
});
const receipt = await applyPlan(plan, client, "https://site.example");
assert.equal(receipt.validation, "passed");
assert.deepEqual(receipt.inlineComments, [{ id: "c1", target: "exact target", markerRef: "marker-1", validation: "passed" }]);
assert.match(storage, /inline-comment-marker/);
});
test("rejects a snapshot changed during supplementary reads", async () => {
let storageReads = 0;
const client = {
async get(requestPath) {
if (requestPath.endsWith("?body-format=storage")) {
storageReads += 1;
return { id: "123", title: "Process", version: { number: storageReads === 1 ? 9 : 10 }, body: { storage: { value: "<p>Storage</p>" } } };
}
if (requestPath.endsWith("?body-format=view")) return { id: "123", version: { number: 9 }, body: { view: { value: "<p>View</p>" } } };
return { results: [] };
},
};
await assert.rejects(createSnapshot(client, "123", "https://site.example"), /changed during snapshot/);
});
test("captures one version-consistent page snapshot", async () => {
const client = {
async get(requestPath) {
if (requestPath.endsWith("?body-format=storage")) return {
id: "123",
title: "Process",
version: { number: 9, message: "x" },
body: { storage: { value: "<p>Storage</p>" } },
_links: { webui: "/wiki/pages/123" },
};
if (requestPath.endsWith("?body-format=view")) return {
id: "123",
version: { number: 9 },
body: { view: { value: "<table><tr><th>Status</th><td>Entwurf</td></tr></table>" } },
};
if (requestPath.includes("/labels")) return [{ results: [{ name: "ims-dokument" }] }];
if (requestPath.includes("/inline-comments")) return { results: [{ id: "i1" }] };
if (requestPath.includes("/footer-comments")) return { results: [{ id: "f1" }] };
if (requestPath.includes("/attachments")) return { results: [{ id: "a1" }] };
throw new Error(`Unexpected path: ${requestPath}`);
},
};
const snapshot = await createSnapshot(client, "123", "https://site.example");
assert.equal(snapshot.url, "https://site.example/wiki/pages/123");
assert.deepEqual(snapshot.header, { Status: "Entwurf" });
assert.deepEqual(snapshot.labels, [{ name: "ims-dokument" }]);
assert.equal(snapshot.body.storage, "<p>Storage</p>");
assert.match(snapshot.body.storageSha256, /^[0-9a-f]{64}$/);
});