112 lines
4.3 KiB
TypeScript
112 lines
4.3 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { describe, it } from "node:test";
|
|
|
|
import { buildOperationMapEmptyState, buildOperationMapSourceSummary, filterOperationMap, getOperationImpact } from "./operationMapView.ts";
|
|
|
|
const map = {
|
|
nodes: ["Nginx Proxy Manager", "Authentik", "Widefrog", "Media Shares"],
|
|
edges: [
|
|
{ from: "Nginx Proxy Manager", to: "Authentik" },
|
|
{ from: "Widefrog", to: "Media Shares" },
|
|
],
|
|
};
|
|
|
|
describe("filterOperationMap", () => {
|
|
it("filters nodes and edges by query and impact while keeping connected nodes visible", () => {
|
|
const focused = filterOperationMap(map, { query: "auth", impact: "all" });
|
|
assert.deepEqual(focused.nodes, ["Nginx Proxy Manager", "Authentik"]);
|
|
assert.deepEqual(focused.edges, [{ from: "Nginx Proxy Manager", to: "Authentik" }]);
|
|
|
|
const high = filterOperationMap(map, { query: "", impact: "high" });
|
|
assert.deepEqual(high.nodes, ["Nginx Proxy Manager", "Authentik"]);
|
|
assert.deepEqual(high.edges, [{ from: "Nginx Proxy Manager", to: "Authentik" }]);
|
|
});
|
|
|
|
it("classifies exposed/auth edges as high impact", () => {
|
|
assert.equal(getOperationImpact({ from: "Nginx Proxy Manager", to: "Authentik" }), "high");
|
|
assert.equal(getOperationImpact({ from: "Widefrog", to: "Media Shares" }), "low");
|
|
});
|
|
});
|
|
|
|
describe("buildOperationMapEmptyState", () => {
|
|
it("builds safe follow-up links for focused dependency handoffs", () => {
|
|
const state = buildOperationMapEmptyState({ totalEdges: 2, visibleEdges: 0, query: "plex", impact: "high" });
|
|
|
|
assert.equal(state.title, "Geen afhankelijkheden voor deze filter");
|
|
assert.match(state.message, /plex/);
|
|
assert.deepEqual(state.actions, [
|
|
{ label: "Toon volledige map", href: "/operations-map" },
|
|
{ label: "Open Apps", href: "/apps?query=plex" },
|
|
{ label: "Zoek in Audit", href: "/audit?query=plex" },
|
|
{ label: "Open Safety Center", href: "/safety" },
|
|
]);
|
|
});
|
|
|
|
it("keeps an empty dependency graph explicit", () => {
|
|
const state = buildOperationMapEmptyState({ totalEdges: 0, visibleEdges: 0, query: "", impact: "all" });
|
|
|
|
assert.equal(state.title, "Geen dependency edges beschikbaar");
|
|
assert.deepEqual(state.actions, [
|
|
{ label: "Open Inventory", href: "/inventory" },
|
|
{ label: "Open Connectors", href: "/connectors" },
|
|
]);
|
|
});
|
|
});
|
|
|
|
describe("buildOperationMapSourceSummary", () => {
|
|
it("describes the operations map as canonical dependency context instead of discovery history", () => {
|
|
const summary = buildOperationMapSourceSummary(map);
|
|
|
|
assert.equal(summary.title, "Canonical dependencykaart");
|
|
assert.deepEqual(summary.stats, [
|
|
{ label: "Nodes", value: "4" },
|
|
{ label: "Edges", value: "2" },
|
|
{ label: "Bron", value: "apps/connectors/policies" },
|
|
]);
|
|
assert.match(summary.message, /connectors/i);
|
|
assert.match(summary.message, /policies/i);
|
|
assert.match(summary.message, /Inventory/i);
|
|
assert.deepEqual(summary.actions, [
|
|
{ label: "Open Inventory", href: "/inventory" },
|
|
{ label: "Open Containers", href: "/containers" },
|
|
{ label: "Open Safety", href: "/safety" },
|
|
]);
|
|
});
|
|
|
|
it("uses backend source metadata when the operations map provides it", () => {
|
|
const summary = buildOperationMapSourceSummary({
|
|
...map,
|
|
generatedAt: "2026-07-10T00:00:00Z",
|
|
sources: {
|
|
apps: { status: "ok", count: 80 },
|
|
connectors: { status: "ok", count: 12 },
|
|
policies: { status: "ok", count: 42 },
|
|
secrets: { status: "metadata_only", count: 9 },
|
|
},
|
|
});
|
|
|
|
assert.deepEqual(summary.stats, [
|
|
{ label: "Nodes", value: "4" },
|
|
{ label: "Edges", value: "2" },
|
|
{ label: "Sources", value: "80 apps / 12 connectors / 42 policies" },
|
|
]);
|
|
assert.match(summary.message, /9 secret refs/i);
|
|
assert.match(summary.message, /10-7-2026/);
|
|
});
|
|
|
|
it("formats generatedAt in the operator timezone instead of raw UTC date", () => {
|
|
const summary = buildOperationMapSourceSummary({
|
|
...map,
|
|
generatedAt: "2026-07-09T23:12:12Z",
|
|
sources: {
|
|
apps: { status: "ok", count: 80 },
|
|
connectors: { status: "ok", count: 12 },
|
|
policies: { status: "ok", count: 42 },
|
|
secrets: { status: "metadata_only", count: 9 },
|
|
},
|
|
});
|
|
|
|
assert.match(summary.message, /10-7-2026/);
|
|
});
|
|
});
|