Luigit
repositories / pi-ext

pi-ext

bugabingas pi extensions

owned by admin

extensions/web/__tests__/parallel.test.ts

Raw
import { 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);
	});
});