mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-01 04:42:10 +03:00
test(mitm/inspector): unit tests for F1 foundation utilities
83 tests across 7 files: mitm-masksecrets (9), mitm-passthrough (10), mitm-upstream-trust (5), inspector-kind-detector (14), inspector-context-key (11), inspector-types (11), shared-schemas (23). All green.
This commit is contained in:
89
tests/unit/inspector-context-key.test.ts
Normal file
89
tests/unit/inspector-context-key.test.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { extractSystemPrompt, computeContextKey } from "../../src/mitm/inspector/contextKey.ts";
|
||||
import type { InterceptedRequest } from "../../src/mitm/inspector/types.ts";
|
||||
|
||||
function makeReq(body: unknown): InterceptedRequest {
|
||||
return {
|
||||
id: "00000000-0000-0000-0000-000000000001",
|
||||
source: "agent-bridge",
|
||||
timestamp: new Date().toISOString(),
|
||||
method: "POST",
|
||||
host: "api.openai.com",
|
||||
path: "/v1/chat/completions",
|
||||
requestHeaders: {},
|
||||
requestBody: body !== null ? JSON.stringify(body) : null,
|
||||
requestSize: 0,
|
||||
responseHeaders: {},
|
||||
responseBody: null,
|
||||
responseSize: 0,
|
||||
status: 200,
|
||||
};
|
||||
}
|
||||
|
||||
test("extractSystemPrompt — OpenAI chat messages[0] role=system", () => {
|
||||
const req = makeReq({
|
||||
messages: [{ role: "system", content: "You are a helpful assistant." }, { role: "user", content: "Hello" }],
|
||||
});
|
||||
assert.equal(extractSystemPrompt(req), "You are a helpful assistant.");
|
||||
});
|
||||
|
||||
test("extractSystemPrompt — Anthropic top-level system field (string)", () => {
|
||||
const req = makeReq({ system: "You are Claude.", messages: [{ role: "user", content: "Hello" }] });
|
||||
assert.equal(extractSystemPrompt(req), "You are Claude.");
|
||||
});
|
||||
|
||||
test("extractSystemPrompt — Anthropic top-level system field (array)", () => {
|
||||
const req = makeReq({
|
||||
system: [{ type: "text", text: "You are a helpful assistant." }],
|
||||
messages: [{ role: "user", content: "Hello" }],
|
||||
});
|
||||
assert.equal(extractSystemPrompt(req), "You are a helpful assistant.");
|
||||
});
|
||||
|
||||
test("extractSystemPrompt — Gemini systemInstruction.parts", () => {
|
||||
const req = makeReq({
|
||||
systemInstruction: { parts: [{ text: "You are a Gemini assistant." }] },
|
||||
contents: [{ parts: [{ text: "Hello" }] }],
|
||||
});
|
||||
assert.equal(extractSystemPrompt(req), "You are a Gemini assistant.");
|
||||
});
|
||||
|
||||
test("extractSystemPrompt — null when no system prompt", () => {
|
||||
assert.equal(extractSystemPrompt(makeReq({ messages: [{ role: "user", content: "Hi" }] })), null);
|
||||
});
|
||||
|
||||
test("extractSystemPrompt — null when requestBody is null", () => {
|
||||
assert.equal(extractSystemPrompt(makeReq(null)), null);
|
||||
});
|
||||
|
||||
test("extractSystemPrompt — null when requestBody is invalid JSON", () => {
|
||||
const req = makeReq(null);
|
||||
req.requestBody = "not-json{{{";
|
||||
assert.equal(extractSystemPrompt(req), null);
|
||||
});
|
||||
|
||||
test("computeContextKey — same system → same 12-hex key", () => {
|
||||
const sys = "You are a helpful assistant.";
|
||||
const key1 = computeContextKey(makeReq({ messages: [{ role: "system", content: sys }, { role: "user", content: "Hi" }] }));
|
||||
const key2 = computeContextKey(makeReq({ messages: [{ role: "system", content: sys }, { role: "user", content: "Bye" }] }));
|
||||
assert.ok(key1 !== null);
|
||||
assert.equal(key1, key2);
|
||||
});
|
||||
|
||||
test("computeContextKey — returns 12 hex chars", () => {
|
||||
const key = computeContextKey(makeReq({ messages: [{ role: "system", content: "Test system" }, { role: "user", content: "Hi" }] }));
|
||||
assert.ok(key !== null);
|
||||
assert.equal(key!.length, 12);
|
||||
assert.match(key!, /^[0-9a-f]{12}$/);
|
||||
});
|
||||
|
||||
test("computeContextKey — null when no system", () => {
|
||||
assert.equal(computeContextKey(makeReq({ messages: [{ role: "user", content: "Hi" }] })), null);
|
||||
});
|
||||
|
||||
test("computeContextKey — different systems → different keys", () => {
|
||||
const k1 = computeContextKey(makeReq({ messages: [{ role: "system", content: "System A" }, { role: "user", content: "Hi" }] }));
|
||||
const k2 = computeContextKey(makeReq({ messages: [{ role: "system", content: "System B" }, { role: "user", content: "Hi" }] }));
|
||||
assert.notEqual(k1, k2);
|
||||
});
|
||||
80
tests/unit/inspector-kind-detector.test.ts
Normal file
80
tests/unit/inspector-kind-detector.test.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { detectKind } from "../../src/mitm/inspector/kindDetector.ts";
|
||||
import type { InterceptedRequest } from "../../src/mitm/inspector/types.ts";
|
||||
|
||||
function makeReq(overrides: Partial<InterceptedRequest>): InterceptedRequest {
|
||||
return {
|
||||
id: "00000000-0000-0000-0000-000000000001",
|
||||
source: "agent-bridge",
|
||||
timestamp: new Date().toISOString(),
|
||||
method: "POST",
|
||||
host: "random.example.com",
|
||||
path: "/api/data",
|
||||
requestHeaders: {},
|
||||
requestBody: null,
|
||||
requestSize: 0,
|
||||
responseHeaders: {},
|
||||
responseBody: null,
|
||||
responseSize: 0,
|
||||
status: 200,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
test("detectKind — api.openai.com → llm", () => {
|
||||
assert.equal(detectKind(makeReq({ host: "api.openai.com" })), "llm");
|
||||
});
|
||||
test("detectKind — api.anthropic.com → llm", () => {
|
||||
assert.equal(detectKind(makeReq({ host: "api.anthropic.com" })), "llm");
|
||||
});
|
||||
test("detectKind — generativelanguage.googleapis.com → llm", () => {
|
||||
assert.equal(detectKind(makeReq({ host: "generativelanguage.googleapis.com" })), "llm");
|
||||
});
|
||||
test("detectKind — openrouter.ai → llm", () => {
|
||||
assert.equal(detectKind(makeReq({ host: "openrouter.ai" })), "llm");
|
||||
});
|
||||
test("detectKind — azure openai subdomain → llm", () => {
|
||||
assert.equal(detectKind(makeReq({ host: "mycompany.openai.azure.com" })), "llm");
|
||||
});
|
||||
test("detectKind — api.mistral.ai → llm", () => {
|
||||
assert.equal(detectKind(makeReq({ host: "api.mistral.ai" })), "llm");
|
||||
});
|
||||
test("detectKind — api.groq.com → llm", () => {
|
||||
assert.equal(detectKind(makeReq({ host: "api.groq.com" })), "llm");
|
||||
});
|
||||
|
||||
test("detectKind — body with messages array → llm", () => {
|
||||
const req = makeReq({
|
||||
requestBody: JSON.stringify({ messages: [{ role: "user", content: "Hello" }] }),
|
||||
});
|
||||
assert.equal(detectKind(req), "llm");
|
||||
});
|
||||
|
||||
test("detectKind — body with contents array (Gemini) → llm", () => {
|
||||
const req = makeReq({
|
||||
requestBody: JSON.stringify({ contents: [{ parts: [{ text: "Hello" }] }] }),
|
||||
});
|
||||
assert.equal(detectKind(req), "llm");
|
||||
});
|
||||
|
||||
test("detectKind — UA 'antigravity/1.0' → llm", () => {
|
||||
assert.equal(
|
||||
detectKind(makeReq({ requestHeaders: { "user-agent": "antigravity/1.0" } })),
|
||||
"llm",
|
||||
);
|
||||
});
|
||||
|
||||
test("detectKind — random.example.com with no clues → app", () => {
|
||||
assert.equal(detectKind(makeReq({ host: "random.example.com" })), "app");
|
||||
});
|
||||
|
||||
test("detectKind — path /v1/chat/completions → llm", () => {
|
||||
assert.equal(detectKind(makeReq({ path: "/v1/chat/completions" })), "llm");
|
||||
});
|
||||
test("detectKind — path /v1/messages → llm", () => {
|
||||
assert.equal(detectKind(makeReq({ path: "/v1/messages" })), "llm");
|
||||
});
|
||||
test("detectKind — path /generateContent → llm", () => {
|
||||
assert.equal(detectKind(makeReq({ path: "/v1beta/models/gemini-pro:generateContent" })), "llm");
|
||||
});
|
||||
83
tests/unit/inspector-types.test.ts
Normal file
83
tests/unit/inspector-types.test.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { InterceptedRequestSchema } from "../../src/mitm/inspector/types.ts";
|
||||
import { MitmTargetSchema } from "../../src/mitm/types.ts";
|
||||
|
||||
const validInterceptedRequest = {
|
||||
id: "550e8400-e29b-41d4-a716-446655440000",
|
||||
source: "agent-bridge" as const,
|
||||
timestamp: new Date().toISOString(),
|
||||
method: "POST",
|
||||
host: "api.openai.com",
|
||||
path: "/v1/chat/completions",
|
||||
requestHeaders: { "content-type": "application/json" },
|
||||
requestBody: null,
|
||||
requestSize: 0,
|
||||
responseHeaders: {},
|
||||
responseBody: null,
|
||||
responseSize: 0,
|
||||
status: 200,
|
||||
};
|
||||
|
||||
test("InterceptedRequestSchema — accepts valid payload", () => {
|
||||
assert.ok(InterceptedRequestSchema.safeParse(validInterceptedRequest).success);
|
||||
});
|
||||
|
||||
test("InterceptedRequestSchema — accepts in-flight status", () => {
|
||||
assert.ok(InterceptedRequestSchema.safeParse({ ...validInterceptedRequest, status: "in-flight" }).success);
|
||||
});
|
||||
|
||||
test("InterceptedRequestSchema — accepts error status", () => {
|
||||
assert.ok(InterceptedRequestSchema.safeParse({ ...validInterceptedRequest, status: "error", error: "Connection timeout" }).success);
|
||||
});
|
||||
|
||||
test("InterceptedRequestSchema — rejects malformed uuid", () => {
|
||||
assert.ok(!InterceptedRequestSchema.safeParse({ ...validInterceptedRequest, id: "not-a-uuid" }).success);
|
||||
});
|
||||
|
||||
test("InterceptedRequestSchema — rejects invalid source enum", () => {
|
||||
assert.ok(!InterceptedRequestSchema.safeParse({ ...validInterceptedRequest, source: "invalid-source" }).success);
|
||||
});
|
||||
|
||||
test("InterceptedRequestSchema — rejects negative requestSize", () => {
|
||||
assert.ok(!InterceptedRequestSchema.safeParse({ ...validInterceptedRequest, requestSize: -1 }).success);
|
||||
});
|
||||
|
||||
const validMitmTarget = {
|
||||
id: "copilot",
|
||||
name: "GitHub Copilot",
|
||||
icon: "code",
|
||||
color: "#10B981",
|
||||
hosts: ["api.githubcopilot.com"],
|
||||
port: 443,
|
||||
endpointPatterns: ["/v1/chat/completions"],
|
||||
defaultModels: [{ id: "gpt-4o", name: "GPT-4o", alias: "gpt-4o" }],
|
||||
setupTutorial: {
|
||||
steps: ["Step 1", "Step 2"],
|
||||
detection: { command: "code --version", platform: "all" as const },
|
||||
},
|
||||
riskNoticeKey: "providers.riskNotice.oauth",
|
||||
};
|
||||
|
||||
test("MitmTargetSchema — accepts valid target", () => {
|
||||
assert.ok(MitmTargetSchema.safeParse(validMitmTarget).success);
|
||||
});
|
||||
|
||||
test("MitmTargetSchema — rejects invalid color format", () => {
|
||||
assert.ok(!MitmTargetSchema.safeParse({ ...validMitmTarget, color: "green" }).success);
|
||||
});
|
||||
|
||||
test("MitmTargetSchema — rejects empty hosts array", () => {
|
||||
assert.ok(!MitmTargetSchema.safeParse({ ...validMitmTarget, hosts: [] }).success);
|
||||
});
|
||||
|
||||
test("MitmTargetSchema — rejects invalid agent id", () => {
|
||||
assert.ok(!MitmTargetSchema.safeParse({ ...validMitmTarget, id: "unknown-agent" }).success);
|
||||
});
|
||||
|
||||
test("MitmTargetSchema — accepts all 9 valid agent ids", () => {
|
||||
const ids = ["antigravity", "kiro", "copilot", "codex", "cursor", "zed", "claude-code", "open-code", "trae"];
|
||||
for (const id of ids) {
|
||||
assert.ok(MitmTargetSchema.safeParse({ ...validMitmTarget, id }).success, `Should accept: ${id}`);
|
||||
}
|
||||
});
|
||||
63
tests/unit/mitm-masksecrets.test.ts
Normal file
63
tests/unit/mitm-masksecrets.test.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { maskSecret } from "../../src/mitm/maskSecrets.ts";
|
||||
|
||||
test("maskSecret — Bearer token is masked", () => {
|
||||
const input = "authorization: Bearer sk-proj-abcdefghijklmnop";
|
||||
const result = maskSecret(input);
|
||||
assert.ok(result.includes("Bearer ***"), `Expected Bearer ***, got: ${result}`);
|
||||
assert.ok(!result.includes("sk-proj-abcdefghijklmnop"), "Should not contain original token");
|
||||
});
|
||||
|
||||
test("maskSecret — sk- key is masked with prefix and suffix", () => {
|
||||
const input = "sk-abcdefghijklmnopqrstuvwxyz123456";
|
||||
const result = maskSecret(input);
|
||||
assert.ok(result.startsWith("sk-abc"), `Expected prefix sk-abc, got: ${result}`);
|
||||
assert.ok(result.endsWith("…56"), `Expected suffix …56, got: ${result}`);
|
||||
assert.ok(!result.includes("ghijklmnopqrstuvwxyz1234"), "Middle chars should be redacted");
|
||||
});
|
||||
|
||||
test("maskSecret — ak- key is masked", () => {
|
||||
const input = "ak-1234567890abcdefghijklmnop";
|
||||
const result = maskSecret(input);
|
||||
assert.ok(result.startsWith("ak-123"));
|
||||
assert.ok(result.endsWith("…op"));
|
||||
});
|
||||
|
||||
test("maskSecret — pk- key is masked", () => {
|
||||
const input = "pk-supersecretkeywithmorethan16chars";
|
||||
const result = maskSecret(input);
|
||||
assert.ok(result.startsWith("pk-sup"));
|
||||
assert.ok(result.endsWith("…rs"));
|
||||
});
|
||||
|
||||
test("maskSecret — long opaque token (≥40 chars) is masked", () => {
|
||||
const longToken = "A".repeat(40);
|
||||
const result = maskSecret(longToken);
|
||||
assert.ok(result.startsWith("AAAA"));
|
||||
assert.ok(result.endsWith("…AA"));
|
||||
assert.ok(result.length < longToken.length);
|
||||
});
|
||||
|
||||
test("maskSecret — string without secrets is unchanged", () => {
|
||||
const safe = "Content-Type: application/json";
|
||||
assert.equal(maskSecret(safe), safe);
|
||||
});
|
||||
|
||||
test("maskSecret — multiple secrets in same string", () => {
|
||||
const input = "sk-abcdefghijklmnopqrstuvwxyz12345678 and pk-qwertyuiopasdfghjklzxcvbnm12345";
|
||||
const result = maskSecret(input);
|
||||
assert.ok(!result.includes("abcdefghijklmno"));
|
||||
assert.ok(!result.includes("qwertyuiopasdfg"));
|
||||
});
|
||||
|
||||
test("maskSecret — secrets embedded in quoted strings", () => {
|
||||
const input = `"api_key": "sk-abcdefghijklmnopqrstuvwxyz12345678"`;
|
||||
const result = maskSecret(input);
|
||||
assert.ok(!result.includes("abcdefghijklmno"));
|
||||
});
|
||||
|
||||
test("maskSecret — short sk- key below 16 chars is NOT masked", () => {
|
||||
const shortKey = "sk-shortkey";
|
||||
assert.equal(maskSecret(shortKey), shortKey);
|
||||
});
|
||||
53
tests/unit/mitm-passthrough.test.ts
Normal file
53
tests/unit/mitm-passthrough.test.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { shouldBypass, globMatch, DEFAULT_BYPASS_PATTERNS } from "../../src/mitm/passthrough.ts";
|
||||
|
||||
test("shouldBypass — bank subdomain matches default pattern", () => {
|
||||
assert.ok(shouldBypass("my.bank.com", []));
|
||||
assert.ok(shouldBypass("secure.bank.example", []));
|
||||
});
|
||||
|
||||
test("shouldBypass — .gov domain matches default pattern", () => {
|
||||
assert.ok(shouldBypass("portal.gov.br", []));
|
||||
assert.ok(shouldBypass("tax.gov", []));
|
||||
});
|
||||
|
||||
test("shouldBypass — okta.com matches default SSO pattern", () => {
|
||||
assert.ok(shouldBypass("mycompany.okta.com", []));
|
||||
assert.ok(shouldBypass("okta.com", []));
|
||||
});
|
||||
|
||||
test("shouldBypass — auth0.com matches default SSO pattern", () => {
|
||||
assert.ok(shouldBypass("myapp.auth0.com", []));
|
||||
assert.ok(shouldBypass("auth0.com", []));
|
||||
});
|
||||
|
||||
test("shouldBypass — non-sensitive host does NOT match defaults", () => {
|
||||
assert.ok(!shouldBypass("api.openai.com", []));
|
||||
assert.ok(!shouldBypass("api.anthropic.com", []));
|
||||
assert.ok(!shouldBypass("example.com", []));
|
||||
});
|
||||
|
||||
test("shouldBypass — user custom glob pattern matches", () => {
|
||||
assert.ok(shouldBypass("internal.mycompany.com", ["*.mycompany.com"]));
|
||||
assert.ok(!shouldBypass("external.othercompany.com", ["*.mycompany.com"]));
|
||||
});
|
||||
|
||||
test("globMatch — star wildcard matches any subdomain", () => {
|
||||
assert.ok(globMatch("foo.example.com", "*.example.com"));
|
||||
assert.ok(globMatch("bar.example.com", "*.example.com"));
|
||||
});
|
||||
|
||||
test("globMatch — exact match without wildcard", () => {
|
||||
assert.ok(globMatch("api.openai.com", "api.openai.com"));
|
||||
assert.ok(!globMatch("api.openai.com", "api.anthropic.com"));
|
||||
});
|
||||
|
||||
test("globMatch — invalid regex-like pattern does not throw", () => {
|
||||
assert.doesNotThrow(() => globMatch("test.com", "[invalid("));
|
||||
});
|
||||
|
||||
test("DEFAULT_BYPASS_PATTERNS — exported array is not empty", () => {
|
||||
assert.ok(DEFAULT_BYPASS_PATTERNS.length >= 4);
|
||||
assert.ok(DEFAULT_BYPASS_PATTERNS.every((p) => p instanceof RegExp));
|
||||
});
|
||||
43
tests/unit/mitm-upstream-trust.test.ts
Normal file
43
tests/unit/mitm-upstream-trust.test.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { configureUpstreamCa } from "../../src/mitm/upstreamTrust.ts";
|
||||
|
||||
test("configureUpstreamCa — no-op when pemPath is undefined", () => {
|
||||
assert.doesNotThrow(() => configureUpstreamCa(undefined));
|
||||
});
|
||||
|
||||
test("configureUpstreamCa — no-op when pemPath is empty string", () => {
|
||||
assert.doesNotThrow(() => configureUpstreamCa(""));
|
||||
});
|
||||
|
||||
test("configureUpstreamCa — throws structured error for non-existent path", () => {
|
||||
const fakePath = "/nonexistent/path/that/does/not/exist/ca.pem";
|
||||
try {
|
||||
configureUpstreamCa(fakePath);
|
||||
assert.fail("Should have thrown");
|
||||
} catch (err) {
|
||||
assert.ok(err instanceof Error);
|
||||
assert.ok(!err.message.includes(" at /"), `Error message should not contain stack trace: ${err.message}`);
|
||||
assert.ok(err.message.includes(fakePath));
|
||||
}
|
||||
});
|
||||
|
||||
test("configureUpstreamCa — error message contains AGENTBRIDGE_UPSTREAM_CA_CERT label", () => {
|
||||
const fakePath = "/no/such/file.pem";
|
||||
try {
|
||||
configureUpstreamCa(fakePath);
|
||||
assert.fail("Should have thrown");
|
||||
} catch (err) {
|
||||
assert.ok(err instanceof Error);
|
||||
assert.ok(err.message.includes("AGENTBRIDGE_UPSTREAM_CA_CERT"));
|
||||
}
|
||||
});
|
||||
|
||||
test("configureUpstreamCa — error does not embed multiline stack trace in message", () => {
|
||||
try {
|
||||
configureUpstreamCa("/definitely/does/not/exist.pem");
|
||||
} catch (err) {
|
||||
assert.ok(err instanceof Error);
|
||||
assert.ok(!err.message.includes("\n at "));
|
||||
}
|
||||
});
|
||||
137
tests/unit/shared-schemas.test.ts
Normal file
137
tests/unit/shared-schemas.test.ts
Normal file
@@ -0,0 +1,137 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import {
|
||||
AgentBridgeStateRowSchema,
|
||||
AgentBridgeMappingRowSchema,
|
||||
AgentBridgeBypassRowSchema,
|
||||
AgentBridgeServerActionSchema,
|
||||
AgentBridgeDnsActionSchema,
|
||||
AgentBridgeMappingPutSchema,
|
||||
AgentBridgeBypassUpsertSchema,
|
||||
AgentBridgeUpstreamCaPostSchema,
|
||||
} from "../../src/shared/schemas/agentBridge.ts";
|
||||
import {
|
||||
InspectorCustomHostSchema,
|
||||
InspectorSessionStartSchema,
|
||||
InspectorSessionPatchSchema,
|
||||
InspectorCaptureModeActionSchema,
|
||||
InspectorSystemProxyActionSchema,
|
||||
InspectorTlsInterceptToggleSchema,
|
||||
InspectorAnnotationPutSchema,
|
||||
InspectorListQuerySchema,
|
||||
} from "../../src/shared/schemas/inspector.ts";
|
||||
|
||||
test("AgentBridgeStateRowSchema — round-trip", () => {
|
||||
const data = {
|
||||
agent_id: "copilot",
|
||||
dns_enabled: true,
|
||||
cert_trusted: false,
|
||||
setup_completed: false,
|
||||
last_started_at: null,
|
||||
last_error: null,
|
||||
};
|
||||
const r = AgentBridgeStateRowSchema.safeParse(data);
|
||||
assert.ok(r.success);
|
||||
});
|
||||
|
||||
test("AgentBridgeMappingRowSchema — round-trip", () => {
|
||||
assert.ok(AgentBridgeMappingRowSchema.safeParse({
|
||||
agent_id: "copilot", source_model: "gpt-4o", target_model: "claude-sonnet-4-5", updated_at: new Date().toISOString(),
|
||||
}).success);
|
||||
});
|
||||
|
||||
test("AgentBridgeBypassRowSchema — round-trip", () => {
|
||||
assert.ok(AgentBridgeBypassRowSchema.safeParse({
|
||||
pattern: "*.bank.com", source: "user", created_at: new Date().toISOString(),
|
||||
}).success);
|
||||
});
|
||||
|
||||
test("AgentBridgeBypassRowSchema — rejects invalid source enum", () => {
|
||||
assert.ok(!AgentBridgeBypassRowSchema.safeParse({
|
||||
pattern: "x", source: "custom", created_at: new Date().toISOString(),
|
||||
}).success);
|
||||
});
|
||||
|
||||
test("AgentBridgeServerActionSchema — all valid actions", () => {
|
||||
for (const action of ["start", "stop", "restart", "trust-cert", "regenerate-cert"]) {
|
||||
assert.ok(AgentBridgeServerActionSchema.safeParse({ action }).success, `accepted ${action}`);
|
||||
}
|
||||
});
|
||||
|
||||
test("AgentBridgeServerActionSchema — rejects unknown action", () => {
|
||||
assert.ok(!AgentBridgeServerActionSchema.safeParse({ action: "delete" }).success);
|
||||
});
|
||||
|
||||
test("AgentBridgeDnsActionSchema — round-trip", () => {
|
||||
assert.ok(AgentBridgeDnsActionSchema.safeParse({ enabled: true }).success);
|
||||
});
|
||||
|
||||
test("AgentBridgeMappingPutSchema — round-trip", () => {
|
||||
assert.ok(AgentBridgeMappingPutSchema.safeParse({ mappings: [{ source: "a", target: "b" }] }).success);
|
||||
});
|
||||
|
||||
test("AgentBridgeBypassUpsertSchema — round-trip", () => {
|
||||
assert.ok(AgentBridgeBypassUpsertSchema.safeParse({ patterns: ["*.bank.com"] }).success);
|
||||
});
|
||||
|
||||
test("AgentBridgeUpstreamCaPostSchema — rejects empty path", () => {
|
||||
assert.ok(!AgentBridgeUpstreamCaPostSchema.safeParse({ path: "" }).success);
|
||||
});
|
||||
|
||||
test("InspectorCustomHostSchema — default enabled=true", () => {
|
||||
const r = InspectorCustomHostSchema.safeParse({ host: "example.com" });
|
||||
assert.ok(r.success);
|
||||
assert.equal(r.data?.enabled, true);
|
||||
});
|
||||
|
||||
test("InspectorCustomHostSchema — rejects empty host", () => {
|
||||
assert.ok(!InspectorCustomHostSchema.safeParse({ host: "" }).success);
|
||||
});
|
||||
|
||||
test("InspectorSessionStartSchema — round-trip with name", () => {
|
||||
assert.ok(InspectorSessionStartSchema.safeParse({ name: "My Session" }).success);
|
||||
});
|
||||
|
||||
test("InspectorSessionStartSchema — round-trip without name", () => {
|
||||
assert.ok(InspectorSessionStartSchema.safeParse({}).success);
|
||||
});
|
||||
|
||||
test("InspectorSessionPatchSchema — stop action", () => {
|
||||
assert.ok(InspectorSessionPatchSchema.safeParse({ action: "stop" }).success);
|
||||
});
|
||||
|
||||
test("InspectorCaptureModeActionSchema — start/stop", () => {
|
||||
assert.ok(InspectorCaptureModeActionSchema.safeParse({ action: "start" }).success);
|
||||
assert.ok(InspectorCaptureModeActionSchema.safeParse({ action: "stop" }).success);
|
||||
});
|
||||
|
||||
test("InspectorSystemProxyActionSchema — apply with options", () => {
|
||||
assert.ok(InspectorSystemProxyActionSchema.safeParse({ action: "apply", port: 8080, guardMinutes: 30 }).success);
|
||||
});
|
||||
|
||||
test("InspectorSystemProxyActionSchema — rejects invalid port", () => {
|
||||
assert.ok(!InspectorSystemProxyActionSchema.safeParse({ action: "apply", port: 99999 }).success);
|
||||
});
|
||||
|
||||
test("InspectorTlsInterceptToggleSchema — round-trip", () => {
|
||||
assert.ok(InspectorTlsInterceptToggleSchema.safeParse({ enabled: false }).success);
|
||||
});
|
||||
|
||||
test("InspectorAnnotationPutSchema — rejects over 10000 chars", () => {
|
||||
assert.ok(!InspectorAnnotationPutSchema.safeParse({ annotation: "x".repeat(10001) }).success);
|
||||
});
|
||||
|
||||
test("InspectorListQuerySchema — round-trip with all filters", () => {
|
||||
assert.ok(InspectorListQuerySchema.safeParse({
|
||||
profile: "llm", host: "api.openai.com", agent: "copilot", status: "2xx",
|
||||
source: "agent-bridge", sessionId: "550e8400-e29b-41d4-a716-446655440000",
|
||||
}).success);
|
||||
});
|
||||
|
||||
test("InspectorListQuerySchema — rejects non-uuid sessionId", () => {
|
||||
assert.ok(!InspectorListQuerySchema.safeParse({ sessionId: "not-a-uuid" }).success);
|
||||
});
|
||||
|
||||
test("InspectorListQuerySchema — empty object is valid", () => {
|
||||
assert.ok(InspectorListQuerySchema.safeParse({}).success);
|
||||
});
|
||||
Reference in New Issue
Block a user