Files
diegosouzapw--omniroute/tests/unit/agent-bridge-maintenance-api.test.ts
2026-07-13 13:39:12 +08:00

124 lines
4.4 KiB
TypeScript

/**
* Client-side fetch helpers that the AgentBridge maintenance card uses to drive
* the already-shipped backend routes (#4084 repair + DELETE cert, #4093
* diagnose, #4094 config import/export). Pure integration logic — no DOM — so
* it is unit-testable by stubbing global.fetch: each helper must parse the
* success body and surface the sanitized server error message on !res.ok.
*/
import test from "node:test";
import assert from "node:assert/strict";
const {
runDiagnose,
removeCaCert,
repairMitmState,
fetchAgentBridgeConfig,
importAgentBridgeConfig,
} = await import("../../src/lib/inspector/agentBridgeMaintenanceApi.ts");
type FetchCall = { url: string; init?: RequestInit };
function stubFetch(handler: (call: FetchCall) => { ok: boolean; status?: number; body: unknown }) {
const calls: FetchCall[] = [];
const original = global.fetch;
global.fetch = (async (url: string, init?: RequestInit) => {
const call = { url: String(url), init };
calls.push(call);
const { ok, status = ok ? 200 : 500, body } = handler(call);
return {
ok,
status,
json: async () => body,
} as unknown as Response;
}) as typeof fetch;
return {
calls,
restore() {
global.fetch = original;
},
};
}
test("runDiagnose returns the report and hits GET /diagnose", async () => {
const report = { healthy: false, checks: [{ name: "cert-trusted", ok: false, hint: "trust it" }], port: 443 };
const f = stubFetch(() => ({ ok: true, body: report }));
try {
const result = await runDiagnose();
assert.equal(result.healthy, false);
assert.equal(result.port, 443);
assert.equal(result.checks[0].name, "cert-trusted");
assert.equal(f.calls[0].url, "/api/tools/agent-bridge/diagnose");
} finally {
f.restore();
}
});
test("removeCaCert DELETEs /cert and returns trusted flag", async () => {
const f = stubFetch(() => ({ ok: true, body: { ok: true, trusted: false } }));
try {
const result = await removeCaCert();
assert.equal(result.trusted, false);
assert.equal(f.calls[0].url, "/api/tools/agent-bridge/cert");
assert.equal(f.calls[0].init?.method, "DELETE");
} finally {
f.restore();
}
});
test("repairMitmState POSTs /repair and returns the repaired list", async () => {
const f = stubFetch(() => ({ ok: true, body: { ok: true, repaired: ["dns", "system-proxy"] } }));
try {
const result = await repairMitmState();
assert.deepEqual(result.repaired, ["dns", "system-proxy"]);
assert.equal(f.calls[0].url, "/api/tools/agent-bridge/repair");
assert.equal(f.calls[0].init?.method, "POST");
} finally {
f.restore();
}
});
test("fetchAgentBridgeConfig GETs /config and returns the portable blob", async () => {
const cfg = { version: 1, bypassPatterns: ["*.corp"], customHosts: [], agentMappings: {} };
const f = stubFetch(() => ({ ok: true, body: cfg }));
try {
const result = await fetchAgentBridgeConfig();
assert.equal(result.version, 1);
assert.deepEqual(result.bypassPatterns, ["*.corp"]);
assert.equal(f.calls[0].url, "/api/tools/agent-bridge/config");
} finally {
f.restore();
}
});
test("importAgentBridgeConfig POSTs the config and returns the counts", async () => {
const cfg = { version: 1 as const, bypassPatterns: ["*.corp"], customHosts: [], agentMappings: {} };
const f = stubFetch(() => ({ ok: true, body: { ok: true, bypassPatterns: 1, customHosts: 0, agents: 0 } }));
try {
const result = await importAgentBridgeConfig(cfg);
assert.equal(result.bypassPatterns, 1);
assert.equal(f.calls[0].url, "/api/tools/agent-bridge/config");
assert.equal(f.calls[0].init?.method, "POST");
assert.equal(JSON.parse(String(f.calls[0].init?.body)).version, 1);
} finally {
f.restore();
}
});
test("each helper surfaces the sanitized server error message on !res.ok", async () => {
const f = stubFetch(() => ({ ok: false, status: 400, body: { error: { message: "Invalid AgentBridge config" } } }));
try {
await assert.rejects(() => importAgentBridgeConfig({ version: 1, bypassPatterns: [], customHosts: [], agentMappings: {} }), /Invalid AgentBridge config/);
} finally {
f.restore();
}
});
test("helpers fall back to HTTP status when the error body has no message", async () => {
const f = stubFetch(() => ({ ok: false, status: 503, body: null }));
try {
await assert.rejects(() => repairMitmState(), /HTTP 503/);
} finally {
f.restore();
}
});