test(mcp): restore Tavily tests and add encoding edge case (#1627)

This commit is contained in:
YeonGyu-Kim
2026-02-08 15:28:31 +09:00
parent 06611a7645
commit a3dd1dbaf9

View File

@@ -1,18 +1,61 @@
import { afterEach, beforeEach, describe, expect, test } from "bun:test"
import { createWebsearchConfig } from "./websearch"
declare const describe: (name: string, callback: () => void) => void
declare const test: (name: string, callback: () => void) => void
declare const expect: (value: unknown) => {
toContain: (expected: string) => void
toBeUndefined: () => void
}
declare const process: { env: Record<string, string | undefined> }
describe("websearch MCP provider configuration", () => {
let originalExaApiKey: string | undefined
let originalTavilyApiKey: string | undefined
beforeEach(() => {
originalExaApiKey = process.env.EXA_API_KEY
originalTavilyApiKey = process.env.TAVILY_API_KEY
delete process.env.EXA_API_KEY
delete process.env.TAVILY_API_KEY
})
afterEach(() => {
if (originalExaApiKey === undefined) {
delete process.env.EXA_API_KEY
} else {
process.env.EXA_API_KEY = originalExaApiKey
}
if (originalTavilyApiKey === undefined) {
delete process.env.TAVILY_API_KEY
} else {
process.env.TAVILY_API_KEY = originalTavilyApiKey
}
})
test("returns Exa config when no config provided", () => {
//#given - no config
//#when
const result = createWebsearchConfig()
//#then
expect(result.url).toContain("mcp.exa.ai")
expect(result.url).toContain("tools=web_search_exa")
expect(result.type).toBe("remote")
expect(result.enabled).toBe(true)
})
test("returns Exa config when provider is 'exa'", () => {
//#given
const config = { provider: "exa" as const }
//#when
const result = createWebsearchConfig(config)
//#then
expect(result.url).toContain("mcp.exa.ai")
expect(result.url).toContain("tools=web_search_exa")
expect(result.type).toBe("remote")
})
describe("createWebsearchConfig (Exa)", () => {
test("appends exaApiKey query param when EXA_API_KEY is set", () => {
//#given
const apiKey = "test-exa-key-12345"
const originalExaApiKey = process.env.EXA_API_KEY
process.env.EXA_API_KEY = apiKey
//#when
@@ -20,25 +63,97 @@ describe("createWebsearchConfig (Exa)", () => {
//#then
expect(result.url).toContain(`exaApiKey=${encodeURIComponent(apiKey)}`)
process.env.EXA_API_KEY = originalExaApiKey
})
test("does not set x-api-key header when EXA_API_KEY is set", () => {
//#given
const apiKey = "test-exa-key-12345"
const originalExaApiKey = process.env.EXA_API_KEY
process.env.EXA_API_KEY = apiKey
process.env.EXA_API_KEY = "test-exa-key-12345"
//#when
const result = createWebsearchConfig()
//#then
expect(result.headers).toBeUndefined()
if (result.headers) {
expect(result.headers["x-api-key"]).toBeUndefined()
}
})
process.env.EXA_API_KEY = originalExaApiKey
test("URL-encodes EXA_API_KEY when it contains special characters", () => {
//#given an EXA_API_KEY with special characters (+ & =)
const apiKey = "a+b&c=d"
process.env.EXA_API_KEY = apiKey
//#when createWebsearchConfig is called
const result = createWebsearchConfig()
//#then the URL contains the properly encoded key via encodeURIComponent
expect(result.url).toContain(`exaApiKey=${encodeURIComponent(apiKey)}`)
})
test("returns Tavily config when provider is 'tavily' and TAVILY_API_KEY set", () => {
//#given
const tavilyKey = "test-tavily-key-67890"
process.env.TAVILY_API_KEY = tavilyKey
const config = { provider: "tavily" as const }
//#when
const result = createWebsearchConfig(config)
//#then
expect(result.url).toContain("mcp.tavily.com")
expect(result.headers).toEqual({ Authorization: `Bearer ${tavilyKey}` })
})
test("throws error when provider is 'tavily' but TAVILY_API_KEY missing", () => {
//#given
delete process.env.TAVILY_API_KEY
const config = { provider: "tavily" as const }
//#when
const createTavilyConfig = () => createWebsearchConfig(config)
//#then
expect(createTavilyConfig).toThrow("TAVILY_API_KEY environment variable is required")
})
test("returns Exa when both keys present but no explicit provider", () => {
//#given
const exaKey = "test-exa-key"
process.env.EXA_API_KEY = exaKey
process.env.TAVILY_API_KEY = "test-tavily-key"
//#when
const result = createWebsearchConfig()
//#then
expect(result.url).toContain("mcp.exa.ai")
expect(result.url).toContain(`exaApiKey=${encodeURIComponent(exaKey)}`)
expect(result.headers).toBeUndefined()
})
test("Tavily config uses Authorization Bearer header format", () => {
//#given
const tavilyKey = "tavily-secret-key-xyz"
process.env.TAVILY_API_KEY = tavilyKey
const config = { provider: "tavily" as const }
//#when
const result = createWebsearchConfig(config)
//#then
expect(result.headers?.Authorization).toMatch(/^Bearer /)
expect(result.headers?.Authorization).toBe(`Bearer ${tavilyKey}`)
})
test("Exa config has no headers when EXA_API_KEY not set", () => {
//#given
delete process.env.EXA_API_KEY
//#when
const result = createWebsearchConfig()
//#then
expect(result.url).toContain("mcp.exa.ai")
expect(result.url).toContain("tools=web_search_exa")
expect(result.url).not.toContain("exaApiKey=")
expect(result.headers).toBeUndefined()
})
})