Files
2026-07-13 13:39:12 +08:00

146 lines
4.8 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import {
webFetchInput,
webFetchOutput,
webFetchTool,
MCP_TOOLS,
MCP_TOOL_MAP,
} from "../../open-sse/mcp-server/schemas/tools.ts";
import { MCP_TOOL_SCOPES } from "../../src/shared/constants/mcpScopes.ts";
// ── Tool definition shape ──
test("webFetchTool has the required McpToolDefinition shape", () => {
assert.equal(webFetchTool.name, "omniroute_web_fetch");
assert.equal(typeof webFetchTool.description, "string");
assert.ok(webFetchTool.description.length > 0);
assert.ok(webFetchTool.inputSchema != null);
assert.ok(webFetchTool.outputSchema != null);
assert.equal(typeof webFetchTool.inputSchema.parse, "function");
assert.deepEqual(webFetchTool.scopes, ["execute:search"]);
assert.equal(webFetchTool.auditLevel, "basic");
assert.equal(webFetchTool.phase, 1);
assert.ok(webFetchTool.sourceEndpoints.includes("/v1/web/fetch"));
});
test("webFetchTool is registered in MCP_TOOLS and MCP_TOOL_MAP", () => {
const toolNames = MCP_TOOLS.map((t) => t.name);
assert.ok(toolNames.includes("omniroute_web_fetch"), "webFetchTool must be in MCP_TOOLS array");
assert.ok("omniroute_web_fetch" in MCP_TOOL_MAP, "webFetchTool must be in MCP_TOOL_MAP");
});
// ── Scope mapping ──
test("omniroute_web_fetch is mapped in MCP_TOOL_SCOPES with execute:search", () => {
const scopes = MCP_TOOL_SCOPES["omniroute_web_fetch"];
assert.ok(scopes != null, "omniroute_web_fetch must have a scope mapping");
assert.ok(
scopes.includes("execute:search"),
"omniroute_web_fetch must require execute:search scope"
);
});
// ── Input schema validation ──
test("webFetchInput accepts a valid minimal request (URL only)", () => {
const parsed = webFetchInput.parse({ url: "https://example.com" });
assert.equal(parsed.url, "https://example.com");
assert.equal(parsed.format, "markdown"); // default
assert.equal(parsed.include_metadata, false); // default
});
test("webFetchInput accepts all optional fields", () => {
const parsed = webFetchInput.parse({
url: "https://example.com",
provider: "firecrawl",
format: "html",
include_metadata: true,
depth: 1,
wait_for_selector: "#content",
});
assert.equal(parsed.provider, "firecrawl");
assert.equal(parsed.format, "html");
assert.equal(parsed.include_metadata, true);
assert.equal(parsed.depth, 1);
assert.equal(parsed.wait_for_selector, "#content");
});
test("webFetchInput rejects missing URL", () => {
assert.throws(
() => webFetchInput.parse({}),
/URL is required/,
"Missing url should fail validation"
);
});
test("webFetchInput rejects empty URL", () => {
assert.throws(
() => webFetchInput.parse({ url: "" }),
/URL is required/,
"Empty url should fail validation"
);
});
test("webFetchInput rejects depth > 2 (matches WebFetchRequest type constraint)", () => {
assert.throws(
() => webFetchInput.parse({ url: "https://example.com", depth: 3 }),
"depth > 2 should fail validation to match the 0 | 1 | 2 type in WebFetchRequest"
);
});
test("webFetchInput accepts depth values 0, 1, 2", () => {
for (const depth of [0, 1, 2]) {
const parsed = webFetchInput.parse({ url: "https://example.com", depth });
assert.equal(parsed.depth, depth);
}
});
test("webFetchInput accepts provider=tinyfish", () => {
const parsed = webFetchInput.parse({ url: "https://example.com", provider: "tinyfish" });
assert.equal(parsed.provider, "tinyfish");
});
test("webFetchInput rejects invalid provider", () => {
assert.throws(
() => webFetchInput.parse({ url: "https://example.com", provider: "unknown-provider" }),
"Unknown provider should fail validation"
);
});
test("webFetchInput rejects invalid format", () => {
assert.throws(
() => webFetchInput.parse({ url: "https://example.com", format: "xml" }),
"Invalid format should fail validation"
);
});
// ── Output schema validation ──
test("webFetchOutput validates a typical scrape response", () => {
const result = webFetchOutput.parse({
provider: "firecrawl",
url: "https://example.com",
content: "# Example Domain\n\nThis domain is for use in documentation examples.",
links: ["https://iana.org/domains/example"],
metadata: { title: "Example Domain", description: "Example site" },
screenshot_url: null,
});
assert.equal(result.provider, "firecrawl");
assert.equal(result.links.length, 1);
assert.equal(result.metadata?.title, "Example Domain");
});
test("webFetchOutput validates a response with null metadata", () => {
const result = webFetchOutput.parse({
provider: "jina-reader",
url: "https://example.com",
content: "Some content",
links: [],
metadata: null,
screenshot_url: null,
});
assert.equal(result.metadata, null);
});