Skip to main content
Glama

mcp-open-library

index.test.ts5.35 kB
import { McpError } from "@modelcontextprotocol/sdk/types.js"; import { describe, expect, it, vi, beforeEach } from "vitest"; import { handleGetBookByTitle, GetBookByTitleArgsSchema } from "./index.js"; // Mock axios vi.mock("axios"); describe("handleGetBookByTitle", () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any let mockAxiosInstance: any; beforeEach(() => { mockAxiosInstance = { get: vi.fn(), }; }); it("should return book data when title is valid and books are found", async () => { // Mock response data const mockResponseData = { docs: [ { title: "Test Book", author_name: ["Author One", "Author Two"], first_publish_year: 2020, key: "/works/test123", edition_count: 5, cover_i: 12345, }, ], }; mockAxiosInstance.get.mockResolvedValue({ data: mockResponseData }); const result = await handleGetBookByTitle( { title: "Test Book" }, mockAxiosInstance, ); expect(mockAxiosInstance.get).toHaveBeenCalledWith("/search.json", { params: { title: "Test Book" }, }); expect(result).toEqual({ content: [ { type: "text", text: JSON.stringify( [ { title: "Test Book", authors: ["Author One", "Author Two"], first_publish_year: 2020, open_library_work_key: "/works/test123", edition_count: 5, cover_url: "https://covers.openlibrary.org/b/id/12345-M.jpg", }, ], null, 2, ), }, ], }); }); it("should handle book with missing optional fields", async () => { // Mock response with missing optional fields const mockResponseData = { docs: [ { title: "Minimal Book", key: "/works/minimal123", }, ], }; mockAxiosInstance.get.mockResolvedValue({ data: mockResponseData }); const result = await handleGetBookByTitle( { title: "Minimal Book" }, mockAxiosInstance, ); expect(result.content[0].text).toContain("Minimal Book"); expect( ( JSON.parse(result.content[0].text as string) as Array<{ title: string; authors: string[]; first_publish_year: number | null; open_library_work_key: string; edition_count: number; cover_url?: string; }> )[0], ).toEqual({ title: "Minimal Book", authors: [], first_publish_year: null, open_library_work_key: "/works/minimal123", edition_count: 0, }); }); it("should return appropriate message when no books are found", async () => { mockAxiosInstance.get.mockResolvedValue({ data: { docs: [] } }); const result = await handleGetBookByTitle( { title: "Nonexistent Book" }, mockAxiosInstance, ); expect(result).toEqual({ content: [ { type: "text", text: 'No books found matching title: "Nonexistent Book"', }, ], }); }); it("should throw McpError for invalid arguments", async () => { await expect(async () => { await handleGetBookByTitle({ title: "" }, mockAxiosInstance); }).rejects.toThrow(McpError); await expect(async () => { await handleGetBookByTitle( { wrongParam: "something" }, mockAxiosInstance, ); }).rejects.toThrow(McpError); await expect(async () => { await handleGetBookByTitle(null, mockAxiosInstance); }).rejects.toThrow(McpError); }); it("should handle API errors properly", async () => { const axiosError = new Error("Network Error"); Object.defineProperty(axiosError, "isAxiosError", { value: true }); Object.defineProperty(axiosError, "response", { value: { statusText: "Service Unavailable" }, }); mockAxiosInstance.get.mockRejectedValue(axiosError); const result = await handleGetBookByTitle( { title: "Test Book" }, mockAxiosInstance, ); expect(result).toEqual({ content: [ { type: "text", text: "Error processing request: Network Error", }, ], isError: true, }); }); it("should handle non-axios errors", async () => { mockAxiosInstance.get.mockRejectedValue(new Error("Unknown Error")); const result = await handleGetBookByTitle( { title: "Test Book" }, mockAxiosInstance, ); expect(result).toEqual({ content: [ { type: "text", text: "Error processing request: Unknown Error", }, ], isError: true, }); }); describe("GetBookByTitleArgsSchema", () => { it("should validate correct input", () => { const result = GetBookByTitleArgsSchema.safeParse({ title: "Valid Title", }); expect(result.success).toBe(true); }); it("should reject empty title", () => { const result = GetBookByTitleArgsSchema.safeParse({ title: "" }); expect(result.success).toBe(false); }); it("should reject missing title", () => { const result = GetBookByTitleArgsSchema.safeParse({}); expect(result.success).toBe(false); }); }); });

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/8enSmith/mcp-open-library'

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