import assert from "node:assert/strict"; import test from "node:test"; import { env } from "../src/env.js"; import { resetBraveRateLimitStateForTests, searchBrave } from "../src/search/brave.js"; test("searchBrave authenticates, builds filters, and normalizes web results", async () => { const originalFetch = globalThis.fetch; const originalApiKey = env.BRAVE_SEARCH_API_KEY; const fetchCalls: Array<{ input: RequestInfo | URL; init?: RequestInit }> = []; resetBraveRateLimitStateForTests(); env.BRAVE_SEARCH_API_KEY = "test-brave-key"; globalThis.fetch = (async (input: RequestInfo | URL, init?: RequestInit) => { fetchCalls.push({ input, init }); return new Response( JSON.stringify({ web: { results: [ { title: " Brave result ", url: "https://docs.example.com/article", description: "Main\n snippet", extra_snippets: ["Extra snippet one", "Extra snippet two"], page_age: "2026-07-18T12:00:00Z", profile: { name: "Example Docs" }, }, { title: "Excluded result", url: "https://blocked.example.com/article", description: "Should be filtered", }, ], }, }), { status: 200, headers: { "content-type": "application/json; charset=utf-8", "x-request-id": "brave-request-1", }, } ); }) as typeof fetch; try { const response = await searchBrave("latest docs", { numResults: 5, includeDomains: ["https://example.com/path"], excludeDomains: ["blocked.example.com"], }); assert.equal(fetchCalls.length, 1); const requestUrl = new URL(String(fetchCalls[0]?.input)); assert.equal(requestUrl.origin + requestUrl.pathname, "https://api.search.brave.com/res/v1/web/search"); assert.equal(requestUrl.searchParams.get("q"), "latest docs site:example.com -site:blocked.example.com"); assert.equal(requestUrl.searchParams.get("count"), "5"); assert.equal(requestUrl.searchParams.get("safesearch"), "moderate"); assert.equal(requestUrl.searchParams.get("result_filter"), "web"); assert.equal(requestUrl.searchParams.get("text_decorations"), "false"); assert.equal(requestUrl.searchParams.get("extra_snippets"), "true"); assert.equal((fetchCalls[0]?.init?.headers as Record)["X-Subscription-Token"], "test-brave-key"); assert.deepEqual(response, { query: "latest docs", requestId: "brave-request-1", results: [ { title: "Brave result", url: "https://docs.example.com/article", publishedDate: "2026-07-18T12:00:00Z", author: "Example Docs", summary: "Main snippet", text: "Main snippet\n\nExtra snippet one\n\nExtra snippet two", highlights: ["Main snippet", "Extra snippet one", "Extra snippet two"], }, ], }); } finally { globalThis.fetch = originalFetch; env.BRAVE_SEARCH_API_KEY = originalApiKey; } }); test("searchBrave rejects requests without an API key", async () => { const originalApiKey = env.BRAVE_SEARCH_API_KEY; resetBraveRateLimitStateForTests(); env.BRAVE_SEARCH_API_KEY = undefined; try { await assert.rejects(() => searchBrave("test", { numResults: 1 }), /BRAVE_SEARCH_API_KEY not set/); } finally { env.BRAVE_SEARCH_API_KEY = originalApiKey; } }); test("searchBrave reports non-JSON responses", async () => { const originalFetch = globalThis.fetch; const originalApiKey = env.BRAVE_SEARCH_API_KEY; resetBraveRateLimitStateForTests(); env.BRAVE_SEARCH_API_KEY = "test-brave-key"; globalThis.fetch = (async () => new Response("upstream error", { status: 200, headers: { "content-type": "text/plain" }, })) as typeof fetch; try { await assert.rejects( () => searchBrave("test", { numResults: 1 }), /Brave Search API returned text\/plain/ ); } finally { globalThis.fetch = originalFetch; env.BRAVE_SEARCH_API_KEY = originalApiKey; } }); test("searchBrave evenly paces concurrent bursts using Brave's shortest policy window", async () => { const originalFetch = globalThis.fetch; const originalApiKey = env.BRAVE_SEARCH_API_KEY; const requestStartedAt: number[] = []; resetBraveRateLimitStateForTests(); env.BRAVE_SEARCH_API_KEY = "test-brave-key"; globalThis.fetch = (async () => { requestStartedAt.push(Date.now()); return new Response(JSON.stringify({ web: { results: [] } }), { status: 200, headers: { "content-type": "application/json", "x-ratelimit-policy": "1;w=1, 2000;w=2678400", "x-ratelimit-remaining": "1, 1999", "x-ratelimit-reset": "1, 2678400", }, }); }) as typeof fetch; try { await Promise.all([ searchBrave("burst one", { numResults: 1 }), searchBrave("burst two", { numResults: 1 }), searchBrave("burst three", { numResults: 1 }), ]); assert.equal(requestStartedAt.length, 3); assert.ok(requestStartedAt[1]! - requestStartedAt[0]! >= 1_000); assert.ok(requestStartedAt[2]! - requestStartedAt[1]! >= 1_000); } finally { globalThis.fetch = originalFetch; env.BRAVE_SEARCH_API_KEY = originalApiKey; resetBraveRateLimitStateForTests(); } }); test("searchBrave adapts its pacing to a 50 request-per-second Search plan", async () => { const originalFetch = globalThis.fetch; const originalApiKey = env.BRAVE_SEARCH_API_KEY; const requestStartedAt: number[] = []; resetBraveRateLimitStateForTests(); env.BRAVE_SEARCH_API_KEY = "test-brave-key"; globalThis.fetch = (async () => { requestStartedAt.push(Date.now()); return new Response(JSON.stringify({ web: { results: [] } }), { status: 200, headers: { "content-type": "application/json", "x-ratelimit-policy": "50;w=1, 0;w=2678400", "x-ratelimit-remaining": "49, 0", "x-ratelimit-reset": "1, 2678400", }, }); }) as typeof fetch; try { await searchBrave("learn upgraded policy", { numResults: 1 }); await Promise.all(Array.from({ length: 8 }, (_, index) => searchBrave(`fast burst ${index}`, { numResults: 1 }))); assert.equal(requestStartedAt.length, 9); const burstStartedAt = requestStartedAt.slice(1); for (let index = 1; index < burstStartedAt.length; index += 1) { assert.ok(burstStartedAt[index]! - burstStartedAt[index - 1]! >= 18); } assert.ok(burstStartedAt.at(-1)! - burstStartedAt[0]! < 500); } finally { globalThis.fetch = originalFetch; env.BRAVE_SEARCH_API_KEY = originalApiKey; resetBraveRateLimitStateForTests(); } }); test("searchBrave retries 429 responses after the burst window resets", async () => { const originalFetch = globalThis.fetch; const originalApiKey = env.BRAVE_SEARCH_API_KEY; let fetchCount = 0; resetBraveRateLimitStateForTests(); env.BRAVE_SEARCH_API_KEY = "test-brave-key"; globalThis.fetch = (async () => { fetchCount += 1; const rateLimitHeaders = { "content-type": "application/json", "x-ratelimit-policy": "1;w=1, 2000;w=2678400", "x-ratelimit-remaining": fetchCount === 1 ? "0, 1999" : "1, 1998", "x-ratelimit-reset": "1, 2678400", }; if (fetchCount === 1) { return new Response(JSON.stringify({ error: { detail: "Rate limit exceeded" } }), { status: 429, headers: rateLimitHeaders, }); } return new Response(JSON.stringify({ web: { results: [] } }), { status: 200, headers: rateLimitHeaders }); }) as typeof fetch; try { const startedAt = Date.now(); await searchBrave("retry burst", { numResults: 1 }); assert.equal(fetchCount, 2); assert.ok(Date.now() - startedAt >= 1_000); } finally { globalThis.fetch = originalFetch; env.BRAVE_SEARCH_API_KEY = originalApiKey; resetBraveRateLimitStateForTests(); } }); test("searchBrave does not wait for exhausted long-term quotas", async () => { const originalFetch = globalThis.fetch; const originalApiKey = env.BRAVE_SEARCH_API_KEY; resetBraveRateLimitStateForTests(); env.BRAVE_SEARCH_API_KEY = "test-brave-key"; globalThis.fetch = (async () => new Response(JSON.stringify({ error: { detail: "Quota exceeded" } }), { status: 429, headers: { "content-type": "application/json", "x-ratelimit-policy": "1;w=1, 2000;w=2678400", "x-ratelimit-remaining": "0, 0", "x-ratelimit-reset": "1, 100000", }, })) as typeof fetch; try { const startedAt = Date.now(); await assert.rejects( () => searchBrave("quota exhausted", { numResults: 1 }), /rate limit quota is exhausted beyond the retry window/ ); assert.ok(Date.now() - startedAt < 1_000); } finally { globalThis.fetch = originalFetch; env.BRAVE_SEARCH_API_KEY = originalApiKey; resetBraveRateLimitStateForTests(); } }); test("searchBrave blocks locally after a successful request exhausts the long-term quota", async () => { const originalFetch = globalThis.fetch; const originalApiKey = env.BRAVE_SEARCH_API_KEY; let fetchCount = 0; resetBraveRateLimitStateForTests(); env.BRAVE_SEARCH_API_KEY = "test-brave-key"; globalThis.fetch = (async () => { fetchCount += 1; return new Response(JSON.stringify({ web: { results: [] } }), { status: 200, headers: { "content-type": "application/json", "x-ratelimit-policy": "1;w=1, 2000;w=2678400", "x-ratelimit-remaining": "0, 0", "x-ratelimit-reset": "1, 100000", }, }); }) as typeof fetch; try { await searchBrave("last allowed query", { numResults: 1 }); await assert.rejects( () => searchBrave("over quota query", { numResults: 1 }), /long-term quota is exhausted/ ); assert.equal(fetchCount, 1); } finally { globalThis.fetch = originalFetch; env.BRAVE_SEARCH_API_KEY = originalApiKey; resetBraveRateLimitStateForTests(); } });