90 lines
2.9 KiB
TypeScript
90 lines
2.9 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { describe, it } from "node:test";
|
|
|
|
import type { Connector, ConnectorBinding, ConnectorCandidate } from "@/types/appops";
|
|
import { buildConnectorDrillView } from "./connectorDrillView.ts";
|
|
|
|
const connector = (overrides: Partial<Connector> = {}): Connector => ({
|
|
id: "sonarr",
|
|
name: "Sonarr",
|
|
status: "connected",
|
|
lastTest: new Date(0).toISOString(),
|
|
capabilities: ["health", "queue", "wanted"],
|
|
type: "media",
|
|
...overrides,
|
|
});
|
|
|
|
const candidate = (overrides: Partial<ConnectorCandidate> = {}): ConnectorCandidate => ({
|
|
connectorId: "sonarr",
|
|
discoveredContainerId: "dc-sonarr",
|
|
containerId: "sonarr",
|
|
containerName: "sonarr",
|
|
displayName: "Sonarr",
|
|
appType: "sonarr",
|
|
lifecycleState: "discovered",
|
|
suggestedAppId: "sonarr",
|
|
connectorStatus: "connected",
|
|
missingSecrets: [],
|
|
requiredSecrets: [],
|
|
confidence: 0.98,
|
|
reasons: ["name matched"],
|
|
ports: [],
|
|
...overrides,
|
|
});
|
|
|
|
const binding = (overrides: Partial<ConnectorBinding> = {}): ConnectorBinding => ({
|
|
connectorId: "sonarr",
|
|
appId: "sonarr",
|
|
appName: "Sonarr",
|
|
containerId: "sonarr",
|
|
containerName: "sonarr",
|
|
mappingId: "map-sonarr",
|
|
connectorStatus: "connected",
|
|
lifecycleState: "managed",
|
|
missingSecrets: [],
|
|
requiredSecrets: [],
|
|
needsReview: false,
|
|
...overrides,
|
|
});
|
|
|
|
describe("connectorDrillView", () => {
|
|
it("summarizes a connected connector with bindings", () => {
|
|
const view = buildConnectorDrillView(connector(), [], [binding()]);
|
|
|
|
assert.equal(view.healthLabel, "Live gekoppeld");
|
|
assert.equal(view.severity, "healthy");
|
|
assert.equal(view.configHref, "/setup?step=connectors&connector=sonarr");
|
|
assert.equal(view.primaryActionLabel, "Bekijk configuratie");
|
|
assert.equal(view.counts.bindings, 1);
|
|
assert.equal(view.counts.openCandidates, 0);
|
|
assert.match(view.operatorHint, /1 app/i);
|
|
});
|
|
|
|
it("prioritizes missing configuration and unique secret refs", () => {
|
|
const view = buildConnectorDrillView(
|
|
connector({ status: "missing_config", secretRef: "SONARR_API_KEY" }),
|
|
[candidate({ missingSecrets: ["SONARR_API_KEY", "SONARR_URL"] })],
|
|
[binding({ missingSecrets: ["SONARR_URL"] })],
|
|
);
|
|
|
|
assert.equal(view.healthLabel, "Configuratie mist");
|
|
assert.equal(view.severity, "critical");
|
|
assert.deepEqual(view.missingConfig, ["SONARR_API_KEY", "SONARR_URL"]);
|
|
assert.equal(view.primaryActionLabel, "Open setup");
|
|
assert.match(view.operatorHint, /ontbrekende configuratie/i);
|
|
});
|
|
|
|
it("surfaces bind work when candidates are not already bound", () => {
|
|
const view = buildConnectorDrillView(
|
|
connector({ status: "configured" }),
|
|
[candidate({ suggestedAppId: "radarr", displayName: "Radarr" })],
|
|
[],
|
|
);
|
|
|
|
assert.equal(view.severity, "warning");
|
|
assert.equal(view.counts.openCandidates, 1);
|
|
assert.equal(view.primaryActionLabel, "Review binding");
|
|
assert.match(view.operatorHint, /1 open candidate/i);
|
|
});
|
|
});
|