repositories / pi-ext
pi-ext
bugabingas pi extensions
owned by admin
extensions/web/__tests__/parallel.test.ts
Rawimport { afterEach, describe, expect, it, vi } from "vitest";
import { parallelSearch } from "../parallel";
afterEach(() => vi.restoreAllMocks());
function server(toolResult: unknown, sse = false) {
return vi
.spyOn(globalThis, "fetch")
.mockImplementation(async (_url, init) => {
const request = JSON.parse(String(init?.body));
if (request.method === "notifications/initialized")
return new Response(null, { status: 202 });
const result =
request.method === "initialize"
? { protocolVersion: "2024-11-05" }
: toolResult;
const message = { jsonrpc: "2.0", id: request.id, result };
const body = sse
? `event: message\r\ndata: {"jsonrpc":"2.0","method":"notifications/progress"}\r\n\r\nevent: message\r\ndata: ${JSON.stringify(message)}\r\n\r\n`
: JSON.stringify(message);
return new Response(body, {
headers: { "mcp-session-id": "test-session" },
});
});
}
const entry = {
title: "Docs",
url: "https://example.com/docs",
excerpts: ["a".repeat(30_000), "second excerpt"],
publish_date: "2026-09-01",
};
describe("Parallel anonymous search", () => {
it.each([false, true])(
"handles MCP JSON/SSE=%s, session headers, and full excerpts",
async (sse) => {
const network = server(
{
content: [
{
type: "text",
text: JSON.stringify({
results: [
entry,
{ ...entry, url: "https://example.com/other" },
],
}),
},
],
},
sse,
);
const result = await parallelSearch("docs", undefined, 1);
expect(result).toEqual([
{
title: "Docs",
url: entry.url,
snippet: entry.excerpts.join("\n\n"),
date: entry.publish_date,
},
]);
expect(network).toHaveBeenCalledTimes(3);
for (const [url, init] of network.mock.calls) {
expect(url).toBe("https://search.parallel.ai/mcp");
expect(init?.redirect).toBe("error");
expect(init?.headers).not.toHaveProperty("Authorization");
}
const request = network.mock.calls[2][1];
expect(new Headers(request?.headers).get("mcp-session-id")).toBe(
"test-session",
);
expect(JSON.parse(String(request?.body)).params).toEqual({
name: "web_search",
arguments: { objective: "docs", search_queries: ["docs"] },
});
},
);
it("accepts a genuine empty result set", async () => {
server({ content: [{ type: "text", text: '{"results":[]}' }] });
expect(await parallelSearch("no matches")).toEqual([]);
});
it.each([
[
{ isError: true, content: [{ type: "text", text: "rate limited" }] },
"rate limited",
],
[{ content: [] }, "no content"],
[{ content: [{ type: "text", text: "not json" }] }, "JSON"],
[{ content: [{ type: "text", text: "{}" }] }, "invalid results"],
[
{
content: [
{
type: "text",
text: '{"results":[{"url":"https://example.com","excerpts":[3]}]}',
},
],
},
"malformed result",
],
])("rejects tool errors and malformed output", async (result, error) => {
server(result);
await expect(parallelSearch("docs")).rejects.toThrow(error as string);
});
it.each([401, 429, 503])("rejects HTTP %s", async (status) => {
vi.spyOn(globalThis, "fetch").mockResolvedValue(
new Response("error", { status }),
);
await expect(parallelSearch("docs")).rejects.toThrow(`HTTP ${status}`);
});
it("rejects JSON-RPC errors", async () => {
vi.spyOn(globalThis, "fetch").mockResolvedValue(
new Response('{"id":1,"error":{"message":"unavailable"}}'),
);
await expect(parallelSearch("docs")).rejects.toThrow(
"Parallel MCP: unavailable",
);
});
it("rejects mismatched response IDs", async () => {
vi.spyOn(globalThis, "fetch").mockResolvedValue(
new Response('{"id":99,"result":{}}'),
);
await expect(parallelSearch("docs")).rejects.toThrow(
"no matching MCP response",
);
});
it("cancels before I/O", async () => {
const network = vi.spyOn(globalThis, "fetch");
await expect(
parallelSearch("docs", AbortSignal.abort(new Error("cancelled"))),
).rejects.toThrow("cancelled");
expect(network).not.toHaveBeenCalled();
});
it("enforces a deadline even with a caller signal", async () => {
vi.spyOn(globalThis, "fetch").mockImplementation(
(_url, init) =>
new Promise((_resolve, reject) => {
init?.signal?.addEventListener(
"abort",
() => reject(init.signal?.reason),
{ once: true },
);
}),
);
await expect(
parallelSearch("docs", new AbortController().signal, 5, 10),
).rejects.toThrow(/timeout/i);
});
});