import { startServer } from "./server.js";
import { MCP } from "./mcp.js";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
// Mock dependencies
jest.mock("@modelcontextprotocol/sdk/server/mcp.js", () => {
return {
McpServer: jest.fn(),
};
});
jest.mock("@modelcontextprotocol/sdk/server/stdio.js", () => ({
StdioServerTransport: jest.fn(),
}));
jest.mock("./mcp.js");
describe("Server", () => {
let mockTool: jest.Mock;
let mockConnect: jest.Mock;
beforeEach(() => {
jest.clearAllMocks();
// Setup internal mocks for McpServer instance
mockTool = jest.fn();
mockConnect = jest.fn();
// Mock the constructor to return our spied methods
(McpServer as unknown as jest.Mock).mockImplementation(() => ({
tool: mockTool,
connect: mockConnect,
}));
(MCP as jest.Mock).mockImplementation(() => ({
getTasks: jest.fn(),
}));
});
it("should start server and register tools", async () => {
await startServer();
expect(McpServer).toHaveBeenCalledWith({
name: "clickup-mcp",
version: "1.0.0",
});
expect(mockTool).toHaveBeenCalledWith(
"get_tasks",
expect.any(String),
expect.any(Object),
expect.any(Function)
);
expect(mockConnect).toHaveBeenCalled();
});
describe("get_tasks tool handler", () => {
let toolHandler: Function;
let mockGetTasks: jest.Mock;
beforeEach(async () => {
mockGetTasks = jest.fn();
(MCP as jest.Mock).mockImplementation(() => ({
getTasks: mockGetTasks,
}));
await startServer();
// Extract the tool handler from the mock call
// First call to 'tool' should be our target if there's only one,
// but let's find it by name to be safe
const call = mockTool.mock.calls.find(c => c[0] === "get_tasks");
if (!call) throw new Error("Tool get_tasks not registered");
toolHandler = call[3];
});
it("should return tasks when successful", async () => {
const mockTasks = [{ id: "1", name: "Task 1" }];
mockGetTasks.mockResolvedValue(mockTasks);
const result = await toolHandler({ listId: "123" });
expect(mockGetTasks).toHaveBeenCalledWith("123");
expect(result).toEqual({
content: [
{
type: "text",
text: JSON.stringify(mockTasks, null, 2),
},
],
});
});
it("should return error when fetch fails", async () => {
const errorMsg = "Auth failed";
mockGetTasks.mockRejectedValue(new Error(errorMsg));
const result = await toolHandler({ listId: "123" });
expect(result).toEqual({
content: [
{
type: "text",
text: `Error: ${errorMsg}. Please ensure you are logged in using 'clickup-mcp login'.`,
},
],
isError: true,
});
});
});
});