Skip to main content
Glama
cv-resource-enhanced.test.ts9.73 kB
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { registerCVResource } from "../resources/cv"; import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js"; // Mock fetch globally global.fetch = jest.fn(); // Mock the McpServer const mockServer = { registerResource: jest.fn(), } as unknown as McpServer; describe("CV Resource Enhanced Tests", () => { beforeEach(() => { jest.clearAllMocks(); }); test("should register cv resource with all parameters", () => { registerCVResource(mockServer); expect(mockServer.registerResource).toHaveBeenCalledWith( "cv", expect.any(ResourceTemplate), expect.objectContaining({ title: "Duyet's CV", description: expect.stringContaining("curriculum vitae"), mimeType: "text/plain", }), expect.any(Function), ); }); test("should handle JSON format with successful JSON fetch", async () => { let _fetchCallCount = 0; (global.fetch as jest.Mock).mockImplementation((url: string) => { _fetchCallCount++; if (url.includes("cv.json")) { return Promise.resolve({ ok: true, text: async () => '{"name": "Duyet", "title": "Senior Data Engineer", "experience": "8+ years"}', }); } return Promise.resolve({ ok: true, text: async () => "<title>Duyet - Senior Data Engineer</title>", }); }); let resourceHandler: any; (mockServer.registerResource as jest.Mock).mockImplementation( (name, _template, _metadata, handler) => { if (name === "cv") { resourceHandler = handler; } }, ); registerCVResource(mockServer); const result = await resourceHandler(new URL("duyet://cv/json"), { format: "json" }); expect(result.contents[0].text).toContain("CV Data (JSON format)"); expect(result.contents[0].text).toContain("name"); expect(result.contents[0].text).toContain("Duyet"); expect(result.contents[0].mimeType).toBe("application/json"); }); test("should handle JSON format when JSON endpoint returns error", async () => { let _fetchCallCount = 0; (global.fetch as jest.Mock).mockImplementation((url: string) => { _fetchCallCount++; if (url.includes("cv.json")) { return Promise.resolve({ ok: false, status: 404, }); } return Promise.resolve({ ok: true, text: async () => "<title>Duyet - Senior Data Engineer</title>", }); }); let resourceHandler: any; (mockServer.registerResource as jest.Mock).mockImplementation( (name, _template, _metadata, handler) => { if (name === "cv") { resourceHandler = handler; } }, ); registerCVResource(mockServer); const result = await resourceHandler(new URL("duyet://cv/json"), { format: "json" }); // Should fallback to summary format expect(result.contents[0].text).toContain("Duyet - Senior Data Engineer"); expect(result.contents[0].text).toContain("CV Link"); expect(result.contents[0].text).toContain("Sr. Data Engineer with"); }); test("should handle JSON format when JSON fetch throws exception", async () => { let _fetchCallCount = 0; (global.fetch as jest.Mock).mockImplementation((url: string) => { _fetchCallCount++; if (url.includes("cv.json")) { throw new Error("Network error"); } return Promise.resolve({ ok: true, text: async () => "<title>Duyet - Senior Data Engineer</title>", }); }); let resourceHandler: any; (mockServer.registerResource as jest.Mock).mockImplementation( (name, _template, _metadata, handler) => { if (name === "cv") { resourceHandler = handler; } }, ); registerCVResource(mockServer); const result = await resourceHandler(new URL("duyet://cv/json"), { format: "json" }); // Should fallback to summary format expect(result.contents[0].text).toContain("Duyet - Senior Data Engineer"); expect(result.contents[0].text).toContain("CV Link"); }); test("should handle main CV fetch error", async () => { (global.fetch as jest.Mock).mockResolvedValue({ ok: false, status: 500, }); let resourceHandler: any; (mockServer.registerResource as jest.Mock).mockImplementation( (name, _template, _metadata, handler) => { if (name === "cv") { resourceHandler = handler; } }, ); registerCVResource(mockServer); const result = await resourceHandler(new URL("duyet://cv/summary"), { format: "summary" }); expect(result.contents[0].text).toContain("Error fetching CV"); expect(result.contents[0].text).toContain("Failed to fetch CV: 500"); expect(result.contents[0].text).toContain("https://duyet.net/cv"); }); test("should handle network error when fetching CV", async () => { (global.fetch as jest.Mock).mockRejectedValue(new Error("Network timeout")); let resourceHandler: any; (mockServer.registerResource as jest.Mock).mockImplementation( (name, _template, _metadata, handler) => { if (name === "cv") { resourceHandler = handler; } }, ); registerCVResource(mockServer); const result = await resourceHandler(new URL("duyet://cv/summary"), { format: "summary" }); expect(result.contents[0].text).toContain("Error fetching CV"); expect(result.contents[0].text).toContain("Network timeout"); expect(result.contents[0].text).toContain("https://duyet.net/cv"); }); test("should handle non-Error exception", async () => { (global.fetch as jest.Mock).mockRejectedValue("String error"); let resourceHandler: any; (mockServer.registerResource as jest.Mock).mockImplementation( (name, _template, _metadata, handler) => { if (name === "cv") { resourceHandler = handler; } }, ); registerCVResource(mockServer); const result = await resourceHandler(new URL("duyet://cv/summary"), { format: "summary" }); expect(result.contents[0].text).toContain("Error fetching CV"); expect(result.contents[0].text).toContain("Unknown error"); expect(result.contents[0].text).toContain("https://duyet.net/cv"); }); test("should handle HTML without title tag", async () => { (global.fetch as jest.Mock).mockResolvedValue({ ok: true, text: async () => "<html><body>CV content without title</body></html>", }); let resourceHandler: any; (mockServer.registerResource as jest.Mock).mockImplementation( (name, _template, _metadata, handler) => { if (name === "cv") { resourceHandler = handler; } }, ); registerCVResource(mockServer); const result = await resourceHandler(new URL("duyet://cv/summary"), { format: "summary" }); expect(result.contents[0].text).toContain("Duyet's CV"); expect(result.contents[0].text).toContain("CV Link: https://duyet.net/cv"); }); test("should handle detailed format correctly", async () => { (global.fetch as jest.Mock).mockResolvedValue({ ok: true, text: async () => "<title>Duyet - Senior Data Engineer</title><body>CV content</body>", }); let resourceHandler: any; (mockServer.registerResource as jest.Mock).mockImplementation( (name, _template, _metadata, handler) => { if (name === "cv") { resourceHandler = handler; } }, ); registerCVResource(mockServer); const result = await resourceHandler(new URL("duyet://cv/detailed"), { format: "detailed", }); expect(result.contents[0].text).toContain("Duyet - Senior Data Engineer"); expect(result.contents[0].text).toContain("Full CV available at: https://duyet.net/cv"); expect(result.contents[0].text).toContain("Key Highlights:"); expect(result.contents[0].text).toContain("Sr. Data Engineer with"); expect(result.contents[0].text).toContain("Expert in Data Engineering"); expect(result.contents[0].text).toContain("Strong background in Rust, Python"); }); test("should default to summary format when no format specified", async () => { (global.fetch as jest.Mock).mockResolvedValue({ ok: true, text: async () => "<title>Duyet - Senior Data Engineer</title><body>CV content</body>", }); let resourceHandler: any; (mockServer.registerResource as jest.Mock).mockImplementation( (name, _template, _metadata, handler) => { if (name === "cv") { resourceHandler = handler; } }, ); registerCVResource(mockServer); const result = await resourceHandler( new URL("duyet://cv/summary"), {}, // No format specified ); expect(result.contents[0].text).toContain("Duyet - Senior Data Engineer"); expect(result.contents[0].text).toContain("CV Link: https://duyet.net/cv"); expect(result.contents[0].text).toContain("Sr. Data Engineer with"); expect(result.contents[0].text).toContain("Expertise: Data Engineering"); }); test("should handle custom title format", async () => { (global.fetch as jest.Mock).mockResolvedValue({ ok: true, text: async () => "<title>Custom CV Title - Duyet</title><body>CV content</body>", }); let resourceHandler: any; (mockServer.registerResource as jest.Mock).mockImplementation( (name, _template, _metadata, handler) => { if (name === "cv") { resourceHandler = handler; } }, ); registerCVResource(mockServer); const result = await resourceHandler(new URL("duyet://cv/summary"), { format: "summary" }); expect(result.contents[0].text).toContain("Custom CV Title - Duyet"); }); test("should verify resource registration parameters", () => { registerCVResource(mockServer); const registerCall = (mockServer.registerResource as jest.Mock).mock.calls[0]; const [name, template, metadata, handler] = registerCall; expect(name).toBe("cv"); expect(template).toBeDefined(); expect(metadata.title).toBe("Duyet's CV"); expect(metadata.description).toContain("curriculum vitae"); expect(metadata.mimeType).toBe("text/plain"); expect(typeof handler).toBe("function"); }); });

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/duyet/duyet-mcp-server'

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