Files
diegosouzapw--omniroute/tests/unit/search-handler-extended.test.ts
2026-07-13 13:39:12 +08:00

1124 lines
33 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import { mkdtempSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
process.env.DATA_DIR = mkdtempSync(join(tmpdir(), "omniroute-search-"));
const { handleSearch } = await import("../../open-sse/handlers/search.ts");
test("handleSearch builds Serper web requests and normalizes organic results", async () => {
const originalFetch = globalThis.fetch;
let captured;
globalThis.fetch = async (url, init = {}) => {
captured = {
url: String(url),
headers: init.headers,
body: JSON.parse(String(init.body || "{}")),
};
return new Response(
JSON.stringify({
organic: [
{
title: "Latest AI",
link: "https://www.example.com/news?id=1",
snippet: "Top story",
date: "2026-04-05",
},
{
title: "Second",
link: "https://docs.example.com/page",
description: "Fallback description",
},
],
searchParameters: { totalResults: 20 },
}),
{ status: 200, headers: { "content-type": "application/json" } }
);
};
try {
const result = await handleSearch({
query: " latest ai ",
provider: "serper-search",
maxResults: 3,
searchType: "web",
country: "US",
language: "en",
credentials: { apiKey: "serper-key" },
log: null,
});
assert.equal(result.success, true);
assert.equal(captured.url, "https://google.serper.dev/search");
assert.equal(captured.headers["X-API-Key"], "serper-key");
assert.deepEqual(captured.body, {
q: "latest ai",
num: 3,
gl: "us",
hl: "en",
});
assert.equal(result.data.provider, "serper-search");
assert.equal(result.data.query, "latest ai");
assert.equal(result.data.results[0].display_url, "example.com/news");
assert.equal(result.data.results[0].citation.provider, "serper-search");
assert.equal(result.data.metrics.total_results_available, 20);
} finally {
globalThis.fetch = originalFetch;
}
});
test("handleSearch builds Brave news requests and normalizes favicon metadata", async () => {
const originalFetch = globalThis.fetch;
let capturedUrl;
let capturedHeaders;
globalThis.fetch = async (url, init = {}) => {
capturedUrl = String(url);
capturedHeaders = init.headers;
return new Response(
JSON.stringify({
results: [
{
title: "Brave item",
url: "https://news.example.com/story",
description: "Breaking news",
age: "2026-04-05",
meta_url: { favicon: "https://news.example.com/favicon.ico" },
},
],
}),
{ status: 200, headers: { "content-type": "application/json" } }
);
};
try {
const result = await handleSearch({
query: "market update",
provider: "brave-search",
maxResults: 1,
searchType: "news",
country: "BR",
language: "pt",
credentials: { apiKey: "brave-key" },
log: null,
});
const url = new URL(capturedUrl);
assert.equal(url.origin + url.pathname, "https://api.search.brave.com/res/v1/news/search");
assert.equal(url.searchParams.get("q"), "market update");
assert.equal(url.searchParams.get("count"), "1");
assert.equal(url.searchParams.get("country"), "BR");
assert.equal(url.searchParams.get("search_lang"), "pt");
assert.equal(capturedHeaders["X-Subscription-Token"], "brave-key");
assert.equal(result.success, true);
assert.equal(result.data.results[0].favicon_url, "https://news.example.com/favicon.ico");
assert.equal(result.data.results[0].published_at, "2026-04-05");
} finally {
globalThis.fetch = originalFetch;
}
});
test("handleSearch builds Perplexity requests, forwards filters, and enforces maxResults", async () => {
const originalFetch = globalThis.fetch;
let captured;
globalThis.fetch = async (url, init = {}) => {
captured = {
url: String(url),
headers: init.headers,
body: JSON.parse(String(init.body || "{}")),
};
return new Response(
JSON.stringify({
results: [
{ title: "One", url: "https://one.example.com", snippet: "First", date: "2026-04-05" },
{ title: "Two", url: "https://two.example.com", snippet: "Second" },
],
}),
{ status: 200, headers: { "content-type": "application/json" } }
);
};
try {
const result = await handleSearch({
query: "ai agents",
provider: "perplexity-search",
maxResults: 1,
searchType: "web",
country: "US",
language: "en",
domainFilter: ["example.com", "-spam.com"],
credentials: { apiKey: "perplexity-key" },
log: null,
});
assert.equal(captured.url, "https://api.perplexity.ai/search");
assert.equal(captured.headers.Authorization, "Bearer perplexity-key");
assert.deepEqual(captured.body, {
query: "ai agents",
max_results: 1,
country: "US",
search_language_filter: ["en"],
search_domain_filter: ["example.com", "-spam.com"],
});
assert.equal(result.success, true);
assert.equal(result.data.results.length, 1);
assert.equal(result.data.usage.queries_used, 1);
assert.equal(result.data.usage.search_cost_usd, 0.005);
} finally {
globalThis.fetch = originalFetch;
}
});
test("handleSearch builds Exa requests with include/exclude domains and preserves rich result fields", async () => {
const originalFetch = globalThis.fetch;
let captured;
globalThis.fetch = async (_url, init = {}) => {
captured = JSON.parse(String(init.body || "{}"));
return new Response(
JSON.stringify({
results: [
{
title: "Exa result",
url: "https://exa.example.com/page",
highlights: ["Highlighted snippet"],
score: 1.2,
publishedDate: "2026-04-04",
favicon: "https://exa.example.com/favicon.ico",
author: "Author",
image: "https://exa.example.com/image.png",
text: "Full document text",
},
],
}),
{ status: 200, headers: { "content-type": "application/json" } }
);
};
try {
const result = await handleSearch({
query: "agentic workflows",
provider: "exa-search",
maxResults: 5,
searchType: "news",
domainFilter: ["allowed.com", "-blocked.com"],
credentials: { apiKey: "exa-key" },
log: null,
});
assert.deepEqual(captured, {
query: "agentic workflows",
numResults: 5,
type: "auto",
text: true,
highlights: true,
includeDomains: ["allowed.com"],
excludeDomains: ["blocked.com"],
category: "news",
});
assert.equal(result.success, true);
assert.equal(result.data.results[0].snippet, "Highlighted snippet");
assert.equal(result.data.results[0].score, 1);
assert.equal(result.data.results[0].content.text, "Full document text");
assert.equal(result.data.results[0].metadata.author, "Author");
assert.equal(result.data.results[0].metadata.image_url, "https://exa.example.com/image.png");
} finally {
globalThis.fetch = originalFetch;
}
});
test("handleSearch builds Tavily requests with topic and raw content normalization", async () => {
const originalFetch = globalThis.fetch;
let captured;
globalThis.fetch = async (_url, init = {}) => {
captured = JSON.parse(String(init.body || "{}"));
return new Response(
JSON.stringify({
results: [
{
title: "Tavily result",
url: "https://tavily.example.com/page",
content: "Summary",
score: 0.7,
published_date: "2026-04-03",
raw_content: "Long form content",
},
],
}),
{ status: 200, headers: { "content-type": "application/json" } }
);
};
try {
const result = await handleSearch({
query: "policy changes",
provider: "tavily-search",
maxResults: 2,
searchType: "news",
country: "us",
domainFilter: ["good.com", "-bad.com"],
credentials: { apiKey: "tavily-key" },
log: null,
});
assert.deepEqual(captured, {
query: "policy changes",
max_results: 2,
topic: "news",
include_domains: ["good.com"],
exclude_domains: ["bad.com"],
country: "us",
});
assert.equal(result.success, true);
assert.equal(result.data.results[0].snippet, "Summary");
assert.equal(result.data.results[0].content.text, "Long form content");
assert.equal(result.data.results[0].citation.rank, 1);
} finally {
globalThis.fetch = originalFetch;
}
});
test("handleSearch builds Google PSE requests with key/cx query params and normalizes items", async () => {
const originalFetch = globalThis.fetch;
let capturedUrl;
globalThis.fetch = async (url) => {
capturedUrl = String(url);
return new Response(
JSON.stringify({
items: [
{
title: "Programmable result",
link: "https://google.example.com/page",
snippet: "Google snippet",
pagemap: {
cse_image: [{ src: "https://google.example.com/image.png" }],
},
},
],
searchInformation: { totalResults: "42" },
}),
{ status: 200, headers: { "content-type": "application/json" } }
);
};
try {
const result = await handleSearch({
query: "google custom search",
provider: "google-pse-search",
maxResults: 3,
searchType: "web",
country: "US",
language: "en",
credentials: { apiKey: "google-key", providerSpecificData: { cx: "engine-id" } },
log: null,
});
const url = new URL(capturedUrl);
assert.equal(url.origin + url.pathname, "https://www.googleapis.com/customsearch/v1");
assert.equal(url.searchParams.get("key"), "google-key");
assert.equal(url.searchParams.get("cx"), "engine-id");
assert.equal(url.searchParams.get("q"), "google custom search");
assert.equal(url.searchParams.get("num"), "3");
assert.equal(result.success, true);
assert.equal(result.data.results[0].metadata.image_url, "https://google.example.com/image.png");
assert.equal(result.data.metrics.total_results_available, 42);
} finally {
globalThis.fetch = originalFetch;
}
});
test("handleSearch builds Linkup requests and normalizes searchResults payload", async () => {
const originalFetch = globalThis.fetch;
let captured;
globalThis.fetch = async (url, init = {}) => {
captured = {
url: String(url),
headers: init.headers,
body: JSON.parse(String(init.body || "{}")),
};
return new Response(
JSON.stringify({
results: [
{
name: "Linkup result",
url: "https://linkup.example.com/page",
content: "Retrieved content",
type: "web",
},
],
}),
{ status: 200, headers: { "content-type": "application/json" } }
);
};
try {
const result = await handleSearch({
query: "linkup test",
provider: "linkup-search",
maxResults: 4,
searchType: "web",
domainFilter: ["example.com", "-blocked.com"],
credentials: { apiKey: "linkup-key" },
log: null,
});
assert.equal(captured.url, "https://api.linkup.so/v1/search");
assert.equal(captured.headers.Authorization, "Bearer linkup-key");
assert.deepEqual(captured.body, {
q: "linkup test",
depth: "standard",
outputType: "searchResults",
maxResults: 4,
includeDomains: ["example.com"],
excludeDomains: ["blocked.com"],
});
assert.equal(result.success, true);
assert.equal(result.data.results[0].title, "Linkup result");
assert.equal(result.data.results[0].content.text, "Retrieved content");
} finally {
globalThis.fetch = originalFetch;
}
});
test("handleSearch builds SearchAPI requests and normalizes organic results", async () => {
const originalFetch = globalThis.fetch;
let capturedUrl;
globalThis.fetch = async (url) => {
capturedUrl = String(url);
return new Response(
JSON.stringify({
search_information: { total_results: 18 },
organic_results: [
{
title: "SearchAPI result",
link: "https://searchapi.example.com/page",
snippet: "SearchAPI snippet",
date: "2026-04-06",
source: "SearchAPI Source",
thumbnail: "https://searchapi.example.com/thumb.png",
},
],
}),
{ status: 200, headers: { "content-type": "application/json" } }
);
};
try {
const result = await handleSearch({
query: "searchapi query",
provider: "searchapi-search",
maxResults: 2,
searchType: "news",
country: "US",
language: "en",
credentials: { apiKey: "searchapi-key" },
log: null,
});
const url = new URL(capturedUrl);
assert.equal(url.origin + url.pathname, "https://www.searchapi.io/api/v1/search");
assert.equal(url.searchParams.get("engine"), "google_news");
assert.equal(url.searchParams.get("api_key"), "searchapi-key");
assert.equal(url.searchParams.get("gl"), "us");
assert.equal(url.searchParams.get("hl"), "en");
assert.equal(result.success, true);
assert.equal(result.data.results[0].metadata.author, "SearchAPI Source");
assert.equal(
result.data.results[0].metadata.image_url,
"https://searchapi.example.com/thumb.png"
);
assert.equal(result.data.metrics.total_results_available, 18);
} finally {
globalThis.fetch = originalFetch;
}
});
test("handleSearch builds You.com requests with livecrawl and normalizes unified response sections", async () => {
const originalFetch = globalThis.fetch;
let capturedUrl;
let capturedHeaders;
globalThis.fetch = async (url, init = {}) => {
capturedUrl = String(url);
capturedHeaders = init.headers;
return new Response(
JSON.stringify({
results: {
web: [
{
title: "You.com result",
url: "https://you.example.com/page",
description: "Fallback description",
snippets: ["Primary snippet"],
page_age: "2026-04-23T10:00:00Z",
favicon_url: "https://you.example.com/favicon.ico",
thumbnail_url: "https://you.example.com/thumb.png",
markdown: "# Full page markdown",
},
],
news: [],
},
metadata: { search_uuid: "uuid-1", latency: 0.5 },
}),
{ status: 200, headers: { "content-type": "application/json" } }
);
};
try {
const result = await handleSearch({
query: "you search",
provider: "youcom-search",
maxResults: 2,
searchType: "web",
country: "US",
language: "en",
timeRange: "week",
offset: 4,
domainFilter: ["docs.you.com"],
contentOptions: { full_page: true, format: "markdown" },
credentials: { apiKey: "you-key" },
log: null,
});
const url = new URL(capturedUrl);
assert.equal(url.origin + url.pathname, "https://ydc-index.io/v1/search");
assert.equal(url.searchParams.get("query"), "you search");
assert.equal(url.searchParams.get("count"), "2");
assert.equal(url.searchParams.get("freshness"), "week");
assert.equal(url.searchParams.get("offset"), "2");
assert.equal(url.searchParams.get("country"), "US");
assert.equal(url.searchParams.get("language"), "en");
assert.equal(url.searchParams.get("include_domains"), "docs.you.com");
assert.equal(url.searchParams.get("livecrawl"), "web");
assert.equal(url.searchParams.get("livecrawl_formats"), "markdown");
assert.equal(capturedHeaders["X-API-Key"], "you-key");
assert.equal(result.success, true);
assert.equal(result.data.provider, "youcom-search");
assert.equal(result.data.results[0].snippet, "Primary snippet");
assert.equal(result.data.results[0].content?.format, "markdown");
assert.equal(result.data.results[0].content?.text, "# Full page markdown");
} finally {
globalThis.fetch = originalFetch;
}
});
test("handleSearch builds SearXNG requests with custom baseUrl and no apiKey", async () => {
const originalFetch = globalThis.fetch;
let capturedUrl;
globalThis.fetch = async (url) => {
capturedUrl = String(url);
return new Response(
JSON.stringify({
results: [
{
title: "SearXNG result",
url: "https://searx.example.com/page",
content: "Metasearch snippet",
publishedDate: "2026-04-07",
engines: ["duckduckgo", "brave"],
},
],
}),
{ status: 200, headers: { "content-type": "application/json" } }
);
};
try {
const result = await handleSearch({
query: "privacy search",
provider: "searxng-search",
maxResults: 5,
searchType: "news",
language: "pt-BR",
credentials: {
providerSpecificData: { baseUrl: "http://localhost:9999" },
},
log: null,
});
const url = new URL(capturedUrl);
assert.equal(url.origin + url.pathname, "http://localhost:9999/search");
assert.equal(url.searchParams.get("format"), "json");
assert.equal(url.searchParams.get("categories"), "news");
assert.equal(url.searchParams.get("language"), "pt-BR");
assert.equal(result.success, true);
assert.equal(result.data.provider, "searxng-search");
assert.equal(result.data.results[0].metadata.source_type, "duckduckgo, brave");
} finally {
globalThis.fetch = originalFetch;
}
});
test("handleSearch rejects queries with invalid control characters", async () => {
const result = await handleSearch({
query: "bad\u0000query",
provider: "serper-search",
maxResults: 5,
searchType: "web",
credentials: { apiKey: "x" },
log: null,
});
assert.equal(result.success, false);
assert.equal(result.status, 400);
assert.equal(result.error, "Query contains invalid control characters");
});
test("handleSearch rejects queries that become empty after normalization", async () => {
const result = await handleSearch({
query: " \n\t ",
provider: "serper-search",
maxResults: 5,
searchType: "web",
credentials: { apiKey: "x" },
log: null,
});
assert.equal(result.success, false);
assert.equal(result.status, 400);
assert.equal(result.error, "Query is empty after normalization");
});
test("handleSearch rejects unknown providers", async () => {
const result = await handleSearch({
query: "hello",
provider: "unknown-search",
maxResults: 5,
searchType: "web",
credentials: { apiKey: "x" },
log: null,
});
assert.equal(result.success, false);
assert.equal(result.status, 400);
assert.equal(result.error, "Unknown search provider: unknown-search");
});
test("handleSearch requires credentials for the configured provider", async () => {
const result = await handleSearch({
query: "hello",
provider: "serper-search",
maxResults: 5,
searchType: "web",
credentials: {},
log: null,
});
assert.equal(result.success, false);
assert.equal(result.status, 401);
assert.equal(result.error, "No credentials for search provider: serper-search");
});
test("handleSearch fails over to the alternate provider on retriable upstream errors", async () => {
const originalFetch = globalThis.fetch;
const calls = [];
globalThis.fetch = async (url) => {
calls.push(String(url));
if (String(url).startsWith("https://google.serper.dev/")) {
return new Response("upstream broken", { status: 500 });
}
return new Response(
JSON.stringify({
web: {
results: [
{
title: "Fallback result",
url: "https://fallback.example.com",
description: "Recovered",
},
],
totalCount: 1,
},
}),
{ status: 200, headers: { "content-type": "application/json" } }
);
};
try {
const result = await handleSearch({
query: "fallback test",
provider: "serper-search",
maxResults: 5,
searchType: "web",
credentials: { apiKey: "serper-key" },
alternateProvider: "brave-search",
alternateCredentials: { apiKey: "brave-key" },
log: null,
});
assert.equal(result.success, true);
assert.deepEqual(calls, [
"https://google.serper.dev/search",
"https://api.search.brave.com/res/v1/web/search?q=fallback+test&count=5",
]);
assert.equal(result.data.provider, "brave-search");
assert.equal(result.data.results[0].title, "Fallback result");
} finally {
globalThis.fetch = originalFetch;
}
});
test("handleSearch does not fail over on non-retriable upstream errors", async () => {
const originalFetch = globalThis.fetch;
let callCount = 0;
globalThis.fetch = async () => {
callCount += 1;
return new Response("unauthorized", { status: 401 });
};
try {
const result = await handleSearch({
query: "no failover",
provider: "serper-search",
maxResults: 5,
searchType: "web",
credentials: { apiKey: "serper-key" },
alternateProvider: "brave-search",
alternateCredentials: { apiKey: "brave-key" },
log: null,
});
assert.equal(result.success, false);
assert.equal(result.status, 401);
assert.equal(result.error, "Search provider serper-search returned 401");
assert.equal(callCount, 1);
} finally {
globalThis.fetch = originalFetch;
}
});
// ─── Ollama Search Tests ──────────────────────────────────
test("handleSearch builds Ollama POST request with bearer auth", async () => {
const originalFetch = globalThis.fetch;
let captured;
globalThis.fetch = async (url, init = {}) => {
captured = {
url: String(url),
headers: init.headers,
body: JSON.parse(String(init.body || "{}")),
};
return new Response(
JSON.stringify({
results: [
{ title: "Ollama result", url: "https://ollama.example.com", content: "Test content" },
],
}),
{ status: 200, headers: { "content-type": "application/json" } }
);
};
try {
const result = await handleSearch({
query: "latest AI news",
provider: "ollama-search",
maxResults: 5,
searchType: "web",
credentials: { apiKey: "ollama-token-123" },
log: null,
});
assert.equal(captured.url, "https://ollama.com/api/web_search");
assert.equal(captured.headers["Content-Type"], "application/json");
assert.equal(captured.headers.Authorization, "Bearer ollama-token-123");
assert.deepEqual(captured.body, { query: "latest AI news", max_results: 5 });
assert.equal(result.success, true);
} finally {
globalThis.fetch = originalFetch;
}
});
test("handleSearch normalizes Ollama response fields and full_text content", async () => {
const originalFetch = globalThis.fetch;
globalThis.fetch = async () => {
return new Response(
JSON.stringify({
results: [
{
title: "Ollama Web Search",
url: "https://ollama.com/blog/web-search",
content: "Ollama now supports native web search capabilities",
},
{
title: "Getting Started",
url: "https://ollama.com/docs",
content: "Learn how to use Ollama for LLM inference",
},
],
}),
{ status: 200, headers: { "content-type": "application/json" } }
);
};
try {
const result = await handleSearch({
query: "ollama query",
provider: "ollama-search",
maxResults: 5,
searchType: "web",
credentials: { apiKey: "ollama-key" },
log: null,
});
assert.equal(result.success, true);
assert.equal(result.data.results.length, 2);
assert.equal(result.data.metrics.total_results_available, 2);
assert.equal(result.data.results[0].title, "Ollama Web Search");
assert.equal(result.data.results[0].url, "https://ollama.com/blog/web-search");
assert.equal(
result.data.results[0].snippet,
"Ollama now supports native web search capabilities"
);
assert.equal(
result.data.results[0].content.text,
"Ollama now supports native web search capabilities"
);
assert.equal(result.data.results[0].content.format, "text");
assert.equal(result.data.results[0].position, 1);
assert.equal(result.data.results[0].citation.provider, "ollama-search");
assert.equal(result.data.results[0].citation.rank, 1);
assert.equal(result.data.results[1].title, "Getting Started");
assert.equal(result.data.results[1].position, 2);
assert.equal(result.data.results[1].citation.rank, 2);
} finally {
globalThis.fetch = originalFetch;
}
});
test("handleSearch handles empty Ollama results array", async () => {
const originalFetch = globalThis.fetch;
globalThis.fetch = async () => {
return new Response(JSON.stringify({ results: [] }), {
status: 200,
headers: { "content-type": "application/json" },
});
};
try {
const result = await handleSearch({
query: "empty query",
provider: "ollama-search",
maxResults: 5,
searchType: "web",
credentials: { apiKey: "ollama-key" },
log: null,
});
assert.equal(result.success, true);
assert.equal(result.data.results.length, 0);
assert.equal(result.data.metrics.total_results_available, 0);
} finally {
globalThis.fetch = originalFetch;
}
});
test("handleSearch handles Ollama response with missing results field", async () => {
const originalFetch = globalThis.fetch;
globalThis.fetch = async () => {
return new Response(JSON.stringify({ unrelated: "data" }), {
status: 200,
headers: { "content-type": "application/json" },
});
};
try {
const result = await handleSearch({
query: "some query",
provider: "ollama-search",
maxResults: 5,
searchType: "web",
credentials: { apiKey: "ollama-key" },
log: null,
});
assert.equal(result.success, true);
assert.equal(result.data.results.length, 0);
assert.equal(result.data.metrics.total_results_available, 0);
} finally {
globalThis.fetch = originalFetch;
}
});
// ─── Z.AI Coding Plan Search Tests ────────────────────
const ZAI_MOCK_RESULTS = [
{
title: "Z.AI Coding Plan Search",
link: "https://docs.z.ai/search",
content: "Z.AI now supports web search capabilities via Coding Plan",
publish_date: "2026-04-20T10:00:00Z",
icon: "https://docs.z.ai/favicon.ico",
media: "web",
},
{
title: "Getting Started with Z.AI",
link: "https://docs.z.ai/getting-started",
content: "Learn how to use Z.AI for search and inference",
publish_date: "2026-04-18T08:00:00Z",
icon: "https://docs.z.ai/favicon.ico",
media: "web",
},
];
test("handleSearch searches with Z.AI Coding Plan via MCP", async () => {
const originalFetch = globalThis.fetch;
const calls: { url: string; init: RequestInit }[] = [];
let capturedArgs: Record<string, unknown> = {};
globalThis.fetch = async (url, init = {}) => {
calls.push({ url: String(url), init });
const body = init.body ? JSON.parse(String(init.body)) : {};
// MCP initialize handshake
if (body.method === "initialize") {
return new Response(
JSON.stringify({
jsonrpc: "2.0",
result: {
protocolVersion: "2024-11-05",
capabilities: {},
serverInfo: { name: "zai-mcp", version: "1.0" },
},
id: body.id,
}),
{
status: 200,
headers: { "content-type": "application/json", "mcp-session-id": "session-abc-123" },
}
);
}
// notifications/initialized
if (body.method === "notifications/initialized") {
return new Response(null, { status: 202 });
}
// tools/call
if (body.method === "tools/call") {
capturedArgs = body.params.arguments;
return new Response(
JSON.stringify({
jsonrpc: "2.0",
result: {
content: [{ type: "text", text: JSON.stringify(JSON.stringify(ZAI_MOCK_RESULTS)) }],
},
id: body.id,
}),
{ status: 200, headers: { "content-type": "application/json" } }
);
}
// GET (initial probe / transport check)
return new Response(null, { status: 405 });
};
try {
const result = await handleSearch({
query: "zai mcp search",
provider: "zai-search",
maxResults: 2,
searchType: "web",
credentials: { apiKey: "zai-token-abc" },
log: null,
});
assert.equal(result.success, true);
assert.equal(capturedArgs.search_query, "zai mcp search");
assert.equal(result.data.provider, "zai-search");
assert.equal(result.data.results.length, 2);
assert.equal(result.data.results[0].title, "Z.AI Coding Plan Search");
assert.equal(result.data.results[0].url, "https://docs.z.ai/search");
assert.equal(
result.data.results[0].snippet,
"Z.AI now supports web search capabilities via Coding Plan"
);
assert.equal(result.data.results[0].display_url, "docs.z.ai/search");
assert.equal(result.data.results[0].favicon_url, "https://docs.z.ai/favicon.ico");
assert.equal(result.data.results[0].citation.provider, "zai-search");
assert.equal(result.data.results[1].title, "Getting Started with Z.AI");
assert.equal(result.data.results[1].citation.provider, "zai-search");
assert.equal(result.data.usage.queries_used, 1);
assert.equal(result.data.usage.search_cost_usd, 0);
} finally {
globalThis.fetch = originalFetch;
}
});
test("handleSearch handles Z.AI Coding Plan empty MCP results", async () => {
const originalFetch = globalThis.fetch;
globalThis.fetch = async (url, init = {}) => {
const body = init.body ? JSON.parse(String(init.body)) : {};
if (body.method === "initialize") {
return new Response(
JSON.stringify({
jsonrpc: "2.0",
result: {
protocolVersion: "2024-11-05",
capabilities: {},
serverInfo: { name: "zai-mcp", version: "1.0" },
},
id: body.id,
}),
{
status: 200,
headers: { "content-type": "application/json", "mcp-session-id": "session-empty" },
}
);
}
if (body.method === "notifications/initialized") {
return new Response(null, { status: 202 });
}
if (body.method === "tools/call") {
return new Response(
JSON.stringify({
jsonrpc: "2.0",
result: {
content: [{ type: "text", text: JSON.stringify(JSON.stringify([])) }],
},
id: body.id,
}),
{ status: 200, headers: { "content-type": "application/json" } }
);
}
return new Response(null, { status: 405 });
};
try {
const result = await handleSearch({
query: "empty zai mcp result",
provider: "zai-search",
maxResults: 5,
searchType: "web",
credentials: { apiKey: "zai-key" },
log: null,
});
assert.equal(result.success, true);
assert.equal(result.data.provider, "zai-search");
assert.equal(result.data.results.length, 0);
} finally {
globalThis.fetch = originalFetch;
}
});
test("handleSearch handles Z.AI Coding Plan MCP connection error", async () => {
const originalFetch = globalThis.fetch;
globalThis.fetch = async () => {
throw new Error("Connection refused");
};
try {
const result = await handleSearch({
query: "zai mcp error",
provider: "zai-search",
maxResults: 5,
searchType: "web",
credentials: { apiKey: "zai-key" },
log: null,
});
assert.equal(result.success, false);
assert.equal(result.status, 502);
assert.ok(result.error.includes("error"));
} finally {
globalThis.fetch = originalFetch;
}
});
test("handleSearch handles Z.AI Coding Plan non-array MCP result", async () => {
const originalFetch = globalThis.fetch;
globalThis.fetch = async (url, init = {}) => {
const body = init.body ? JSON.parse(String(init.body)) : {};
if (body.method === "initialize") {
return new Response(
JSON.stringify({
jsonrpc: "2.0",
result: {
protocolVersion: "2024-11-05",
capabilities: {},
serverInfo: { name: "zai-mcp", version: "1.0" },
},
id: body.id,
}),
{
status: 200,
headers: { "content-type": "application/json", "mcp-session-id": "session-nonarray" },
}
);
}
if (body.method === "notifications/initialized") {
return new Response(null, { status: 202 });
}
if (body.method === "tools/call") {
return new Response(
JSON.stringify({
jsonrpc: "2.0",
result: {
content: [{ type: "text", text: JSON.stringify(JSON.stringify({ not: "an array" })) }],
},
id: body.id,
}),
{ status: 200, headers: { "content-type": "application/json" } }
);
}
return new Response(null, { status: 405 });
};
try {
const result = await handleSearch({
query: "zai non-array",
provider: "zai-search",
maxResults: 5,
searchType: "web",
credentials: { apiKey: "zai-key" },
log: null,
});
assert.equal(result.success, true);
assert.equal(result.data.results.length, 0);
} finally {
globalThis.fetch = originalFetch;
}
});