Skip to main content
Glama

eRegulations MCP Server

by unctad-ai
search-procedures.test.ts5.06 kB
import { describe, it, expect, vi, beforeEach } from "vitest"; import { createSearchProceduresHandler } from "../../mcp-capabilities/tools/handlers/search-procedures.js"; import { ERegulationsApi } from "../../services/eregulations-api.js"; import { formatters } from "../../mcp-capabilities/tools/formatters/index.js"; import { ToolName } from "../../mcp-capabilities/tools/schemas.js"; import type { ObjectiveData } from "../../mcp-capabilities/tools/formatters/types.js"; // Mock dependencies vi.mock("../../services/eregulations-api.js"); vi.mock("../../mcp-capabilities/tools/formatters/index.js"); vi.mock("../../utils/logger.js", () => ({ logger: { log: vi.fn(), error: vi.fn() }, })); describe("createSearchProceduresHandler", () => { let mockApi: ERegulationsApi; let handler: ReturnType<typeof createSearchProceduresHandler>; // Updated mock data with links const mockObjectives: ObjectiveData[] = [ { id: 1, name: "Procedure 1", description: "Desc 1", links: [{ rel: "procedure", href: "..." }], // This is a procedure }, { id: 2, name: "Objective 2", description: "Desc 2", links: [{ rel: "objective", href: "..." }], // This is an objective }, { id: 3, name: "Procedure 3", links: [{ rel: "procedure", href: "..." }], // This is a procedure, no description }, { id: 4, name: "Item without links", description: "Desc 4", }, // No links, should be filtered out { id: 5, name: "Item with empty links", description: "Desc 5", links: [], }, // Empty links, should be filtered out { id: 6, name: "Item with null link", description: "Desc 6", links: [null], }, // Invalid link, should be filtered out ]; // Expected filtered results for the formatter const expectedFilteredProcedures = [ { id: 1, name: "Procedure 1", description: "Desc 1", links: [{ rel: "procedure", href: "..." }], }, { id: 3, name: "Procedure 3", links: [{ rel: "procedure", href: "..." }], }, ]; const mockFormattedResult = { text: "Formatted text", data: [ // Data returned by formatter might differ based on its logic, // but the handler only cares about the 'text' part. { id: 1, name: "Procedure 1" }, { id: 3, name: "Procedure 3" }, ], }; beforeEach(() => { vi.resetAllMocks(); // Mock ERegulationsApi methods mockApi = new ERegulationsApi(); mockApi.searchProcedures = vi.fn().mockResolvedValue(mockObjectives); // Mock formatter formatters.searchProcedures.format = vi .fn() .mockReturnValue(mockFormattedResult); handler = createSearchProceduresHandler(mockApi); }); it("should have correct name, description, and inputSchema", () => { expect(handler.name).toBe(ToolName.SEARCH_PROCEDURES); expect(handler.description).toBe( "Search for procedures by keyword or phrase. The search uses OR logic between words in the keyword phrase. For best results, prefer using a single, specific keyword whenever possible." ); expect(handler.inputSchema).toBeDefined(); // Assuming SearchProceduresSchema is imported/mocked correctly }); it("should call api.searchProcedures and formatter.format with correct arguments", async () => { const args = { keyword: "test" }; await handler.handler(args); expect(mockApi.searchProcedures).toHaveBeenCalledWith("test"); // Expect formatter to be called with the FILTERED procedures expect(formatters.searchProcedures.format).toHaveBeenCalledWith( expectedFilteredProcedures, // Use the expected filtered list "test" ); }); it("should return formatted results in the content structure", async () => { const args = { keyword: "test" }; const result = await handler.handler(args); expect(result).toEqual({ content: [{ type: "text", text: mockFormattedResult.text }], }); }); it("should handle errors from api.searchProcedures", async () => { const error = new Error("API Error"); mockApi.searchProcedures = vi.fn().mockRejectedValue(error); const args = { keyword: "fail" }; const result = await handler.handler(args); expect(result).toEqual({ content: [ { type: "text", text: `Error searching for procedures: ${error.message}`, }, ], }); }); it("should handle errors from formatter.format", async () => { const error = new Error("Formatter Error"); formatters.searchProcedures.format = vi.fn().mockImplementation(() => { throw error; }); const args = { keyword: "format-fail" }; // The handler currently catches errors broadly, so this should also be caught const result = await handler.handler(args); expect(result).toEqual({ content: [ { type: "text", text: `Error searching for procedures: ${error.message}`, }, ], }); }); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/unctad-ai/eregulations-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server