Fetch MCP Server

  • src
import { Fetcher } from "./Fetcher"; import { JSDOM } from "jsdom"; import TurndownService from "turndown"; global.fetch = jest.fn(); jest.mock("jsdom"); jest.mock("turndown"); describe("Fetcher", () => { beforeEach(() => { jest.clearAllMocks(); }); const mockRequest = { url: "https://example.com", headers: { "Custom-Header": "Value" }, }; const mockHtml = ` <html> <head> <title>Test Page</title> <script>console.log('This should be removed');</script> <style>body { color: red; }</style> </head> <body> <h1>Hello World</h1> <p>This is a test paragraph.</p> </body> </html> `; describe("html", () => { it("should return the raw HTML content", async () => { (fetch as jest.Mock).mockResolvedValueOnce({ ok: true, text: jest.fn().mockResolvedValueOnce(mockHtml), }); const result = await Fetcher.html(mockRequest); expect(result).toEqual({ content: [{ type: "text", text: mockHtml }], isError: false, }); }); it("should handle errors", async () => { (fetch as jest.Mock).mockRejectedValueOnce(new Error("Network error")); const result = await Fetcher.html(mockRequest); expect(result).toEqual({ content: [ { type: "text", text: "Failed to fetch https://example.com: Network error", }, ], isError: true, }); }); }); describe("json", () => { it("should parse and return JSON content", async () => { const mockJson = { key: "value" }; (fetch as jest.Mock).mockResolvedValueOnce({ ok: true, json: jest.fn().mockResolvedValueOnce(mockJson), }); const result = await Fetcher.json(mockRequest); expect(result).toEqual({ content: [{ type: "text", text: JSON.stringify(mockJson) }], isError: false, }); }); it("should handle errors", async () => { (fetch as jest.Mock).mockRejectedValueOnce(new Error("Invalid JSON")); const result = await Fetcher.json(mockRequest); expect(result).toEqual({ content: [ { type: "text", text: "Failed to fetch https://example.com: Invalid JSON", }, ], isError: true, }); }); }); describe("txt", () => { it("should return plain text content without HTML tags, scripts, and styles", async () => { (fetch as jest.Mock).mockResolvedValueOnce({ ok: true, text: jest.fn().mockResolvedValueOnce(mockHtml), }); const mockTextContent = "Hello World This is a test paragraph."; // @ts-expect-error Mocking JSDOM (JSDOM as jest.Mock).mockImplementationOnce(() => ({ window: { document: { body: { textContent: mockTextContent, }, getElementsByTagName: jest.fn().mockReturnValue([]), }, }, })); const result = await Fetcher.txt(mockRequest); expect(result).toEqual({ content: [{ type: "text", text: mockTextContent }], isError: false, }); }); it("should handle errors", async () => { (fetch as jest.Mock).mockRejectedValueOnce(new Error("Parsing error")); const result = await Fetcher.txt(mockRequest); expect(result).toEqual({ content: [ { type: "text", text: "Failed to fetch https://example.com: Parsing error", }, ], isError: true, }); }); }); describe("markdown", () => { it("should convert HTML to markdown", async () => { (fetch as jest.Mock).mockResolvedValueOnce({ ok: true, text: jest.fn().mockResolvedValueOnce(mockHtml), }); const mockMarkdown = "# Hello World\n\nThis is a test paragraph."; (TurndownService as jest.Mock).mockImplementationOnce(() => ({ turndown: jest.fn().mockReturnValueOnce(mockMarkdown), })); const result = await Fetcher.markdown(mockRequest); expect(result).toEqual({ content: [{ type: "text", text: mockMarkdown }], isError: false, }); }); it("should handle errors", async () => { (fetch as jest.Mock).mockRejectedValueOnce(new Error("Conversion error")); const result = await Fetcher.markdown(mockRequest); expect(result).toEqual({ content: [ { type: "text", text: "Failed to fetch https://example.com: Conversion error", }, ], isError: true, }); }); }); describe("error handling", () => { it("should handle non-OK responses", async () => { (fetch as jest.Mock).mockResolvedValueOnce({ ok: false, status: 404, }); const result = await Fetcher.html(mockRequest); expect(result).toEqual({ content: [ { type: "text", text: "Failed to fetch https://example.com: HTTP error: 404", }, ], isError: true, }); }); it("should handle unknown errors", async () => { (fetch as jest.Mock).mockRejectedValueOnce("Unknown error"); const result = await Fetcher.html(mockRequest); expect(result).toEqual({ content: [ { type: "text", text: "Failed to fetch https://example.com: Unknown error", }, ], isError: true, }); }); }); });