// Unit tests for the SUPPLY cockpit DOM renderer (H5 / #148), on the in-memory fake DOM. import assert from "node:assert/strict"; import { test } from "node:test"; import { FakeDocument, FakeElement } from "../../../test/agentic-cockpit-doubles.ts"; import { renderSupply } from "./supply-render.ts"; import { type SupplyReport, supplyView } from "./supply-view.ts"; const doc = new FakeDocument(); const sample: SupplyReport = { count: 2, workers: [ { instance: "wk-a", identity: "leaf-1", stream: "wk-a", family: "senior", host: "h1", jobKeys: ["job-1"], live: true, staleMs: 0 }, { instance: "wk-b", identity: "leaf-1", stream: "wk-b", family: "junior", host: "h2", jobKeys: [], live: false, staleMs: 0 }, ], leaves: [ { token: "leaf-1", workers: [ { instance: "wk-a", identity: "leaf-1", stream: "wk-a", family: "senior", host: "h1", jobKeys: ["job-1"], live: true, staleMs: 0 }, { instance: "wk-b", identity: "leaf-1", stream: "wk-b", family: "junior", host: "h2", jobKeys: [], live: false, staleMs: 0 }, ], }, ], }; test("renders one leaf section with a worker row per worker (family, host, jobs, liveness)", () => { const host = new FakeElement("body"); renderSupply(host, doc, supplyView(sample)); assert.equal(host.byData("leaf", "leaf-1").length, 1); const rows = host.byClass("cockpit-supply-worker"); assert.equal(rows.length, 2); const rowA = host.byData("worker", "wk-a")[0]; assert.equal(rowA?.getAttribute("data-liveness"), "live"); assert.equal(rowA?.byClass("cockpit-supply-family")[0]?.text(), "senior"); assert.equal(rowA?.byClass("cockpit-supply-host")[0]?.text(), "h1"); assert.equal(rowA?.byClass("cockpit-supply-jobs")[0]?.text(), "job-1"); const rowB = host.byData("worker", "wk-b")[0]; assert.equal(rowB?.getAttribute("data-liveness"), "down"); assert.equal(rowB?.byClass("cockpit-supply-jobs")[0]?.text(), "—"); }); test("worker name buttons open the worker detail route and the inline terminal drill still drills", () => { const host = new FakeElement("body"); const drilled: string[] = []; const opened: string[] = []; renderSupply(host, doc, supplyView(sample), { onDrill: (stream) => drilled.push(stream), onOpenWorker: (instance) => opened.push(instance), }); const worker = host.byClass("cockpit-worker").find((b) => b.getAttribute("data-instance") === "wk-a"); assert.ok(worker, "the worker name button was rendered with its instance id"); worker?.dispatch("click"); assert.deepEqual(opened, ["wk-a"]); const button = host.byClass("cockpit-worker-drill").find((b) => b.getAttribute("data-stream") === "wk-a"); assert.ok(button, "the inline live-terminal drill button was rendered with its stream id"); button?.dispatch("click"); assert.deepEqual(drilled, ["wk-a"]); }); test("suppresses the inline drill button for an IDLE worker (no current job → producerless stream)", () => { const host = new FakeElement("body"); renderSupply(host, doc, supplyView(sample), { onDrill: () => {}, onOpenWorker: () => {} }); // wk-a holds job-1 → drillable; wk-b is idle (jobKeys: []) → no drill affordance. const drills = host.byClass("cockpit-worker-drill"); assert.equal(drills.length, 1, "exactly one drill button — only for the worker with a live job"); assert.equal(drills[0]?.getAttribute("data-instance"), "wk-a"); // The idle worker is still openable via its name button; it just cannot be drilled. const idleDrill = host.byData("worker", "wk-b")[0]?.byClass("cockpit-worker-drill") ?? []; assert.equal(idleDrill.length, 0, "the idle worker row has no drill button"); assert.ok( host.byClass("cockpit-worker").find((b) => b.getAttribute("data-instance") === "wk-b"), "the idle worker still has its name button (detail page remains reachable)", ); // The idle worker's name button carries `data-stream` unconditionally — same as the drillable // worker and the browser mirror — even though its drill affordance is suppressed. const idleName = host.byClass("cockpit-worker").find((b) => b.getAttribute("data-instance") === "wk-b"); assert.equal(idleName?.getAttribute("data-stream"), "wk-b", "idle worker's name button still carries data-stream"); }); test("does NOT render any demand matrix, missing-agent reds, or diversity light", () => { const host = new FakeElement("body"); renderSupply(host, doc, supplyView(sample)); // Those widgets belong to the packaged demand renderer / enrolment epic #152 — never here. assert.equal(host.byClass("cockpit-matrix").length, 0); assert.equal(host.byClass("cockpit-network").length, 0); assert.equal(host.byClass("cockpit-missing").length, 0); assert.equal( host.byClass("cockpit-light").filter((l) => l.getAttribute("data-light-id") === "diversity").length, 0, ); }); test("renders an empty state when no workers are connected", () => { const host = new FakeElement("body"); renderSupply(host, doc, supplyView({ count: 0, workers: [], leaves: [] })); assert.equal(host.byData("empty", "true").length, 1); assert.equal(host.byClass("cockpit-supply-worker").length, 0); }); test("H6: renders a process/plan cell that drills into the job's stream", () => { const host = new FakeElement("body"); const drilled: string[] = []; const correlated: SupplyReport = { count: 1, workers: [{ instance: "wk-a", identity: "leaf-1", stream: "job:6494", family: "senior", host: "h1", jobKeys: ["6494"], live: true, staleMs: 0 }], leaves: [ { token: "leaf-1", workers: [{ instance: "wk-a", identity: "leaf-1", stream: "job:6494", family: "senior", host: "h1", jobKeys: ["6494"], live: true, staleMs: 0 }], }, ], correlations: [{ jobKey: "6494", stream: "job:6494", bpmnProcessId: "plan-fanout", processInstanceKey: "4612", planKey: "o/r#142" }], }; renderSupply(host, doc, supplyView(correlated), { onDrill: (stream) => drilled.push(stream) }); const cell = host.byData("worker", "wk-a")[0]?.byClass("cockpit-supply-process")[0]; assert.ok(cell); assert.equal(cell?.getAttribute("data-correlations"), "1"); const link = host.byClass("cockpit-correlation")[0]; assert.ok(link, "the correlation drill button was rendered"); assert.equal(link?.getAttribute("data-job-key"), "6494"); assert.equal(link?.getAttribute("data-stream"), "job:6494"); assert.equal(link?.text(), "plan-fanout · inst 4612 · o/r#142"); link?.dispatch("click"); assert.deepEqual(drilled, ["job:6494"], "drilling the process/plan cell opens the live job's stream"); }); test("H6: a worker with no correlation renders an em-dash process cell", () => { const host = new FakeElement("body"); renderSupply(host, doc, supplyView(sample)); const cell = host.byData("worker", "wk-b")[0]?.byClass("cockpit-supply-process")[0]; assert.equal(cell?.text(), "—"); assert.equal(cell?.getAttribute("data-correlations"), "0"); }); test("#802: renders a stale-harness badge for a worker below the minimum / with no advertised protocol", () => { const host = new FakeElement("body"); const staleWorker = { instance: "wk-old", identity: "leaf-1", stream: "wk-old", family: "senior", host: "h1", jobKeys: [], live: true, staleMs: 0, harnessStale: true }; const okWorker = { instance: "wk-ok", identity: "leaf-1", stream: "wk-ok", family: "senior", host: "h2", jobKeys: [], live: true, staleMs: 0, harnessStale: false, harnessProtocol: 3 }; const report: SupplyReport = { count: 2, workers: [staleWorker, okWorker], leaves: [{ token: "leaf-1", workers: [staleWorker, okWorker] }], }; renderSupply(host, doc, supplyView(report)); const rowOld = host.byData("worker", "wk-old")[0]; assert.equal(rowOld?.getAttribute("data-harness-stale"), "true"); assert.equal(rowOld?.byClass("cockpit-supply-harness-stale").length, 1, "stale harness badge rendered"); const rowOk = host.byData("worker", "wk-ok")[0]; assert.equal(rowOk?.getAttribute("data-harness-stale"), "false"); assert.equal(rowOk?.byClass("cockpit-supply-harness-stale").length, 0, "no badge for a healthy harness"); });