Code Snippet Server
by ngeojiajun
Verified
import {
jest,
describe,
it,
expect,
beforeEach,
afterEach,
} from "@jest/globals";
import type {
SystempromptPromptResponse,
SystempromptBlockResponse,
} from "../../types/index.js";
import type {
CallToolRequest,
CallToolResult,
Tool,
} from "@modelcontextprotocol/sdk/types.js";
import type { gmail_v1 } from "googleapis/build/src/apis/gmail/v1.js";
import { calendar_v3 } from "googleapis/build/src/apis/calendar/v3.js";
import type { EmailMetadata } from "../../services/gmail-service";
// Mock process.exit
const mockExit = jest
.spyOn(process, "exit")
.mockImplementation(() => undefined as never);
// Mock the SDK modules
jest.mock("@modelcontextprotocol/sdk/server/stdio.js", () => ({
__esModule: true,
StdioServerTransport: jest.fn(() => ({
start: jest.fn(),
stop: jest.fn(),
onRequest: jest.fn(),
})),
}));
jest.mock("@modelcontextprotocol/sdk/server/index.js", () => ({
__esModule: true,
Server: jest.fn(() => ({
start: jest.fn(),
stop: jest.fn(),
onRequest: jest.fn(),
registerHandler: jest.fn(),
registerHandlers: jest.fn(),
})),
}));
jest.mock("@modelcontextprotocol/sdk/types.js", () => ({
__esModule: true,
ListToolsRequest: jest.fn(),
CallToolRequest: jest.fn(),
}));
// Mock the index module
jest.mock("../../index.js", () => ({
__esModule: true,
server: {
notification: jest.fn(),
},
}));
// Mock Gmail Service
jest.mock("../../services/gmail-service", () => {
const mockEmailMetadata: EmailMetadata = {
id: "123",
threadId: "456",
snippet: "",
from: { email: "test@example.com" },
to: [{ email: "to@example.com" }],
subject: "Test",
date: new Date(),
labels: [],
hasAttachments: false,
isUnread: false,
isImportant: false,
};
const mockGmailMessage = {
...mockEmailMetadata,
body: "test",
};
const mockGmailService = {
listMessages: jest.fn(() => Promise.resolve([mockEmailMetadata])),
getMessage: jest.fn(() => Promise.resolve(mockGmailMessage)),
searchMessages: jest.fn(() =>
Promise.resolve([{ ...mockEmailMetadata, id: "789", threadId: "012" }])
),
getLabels: jest.fn(() =>
Promise.resolve([
{ id: "label1", name: "INBOX" },
] as gmail_v1.Schema$Label[])
),
sendEmail: jest.fn(() => Promise.resolve("msg123")),
createDraft: jest.fn(() => Promise.resolve("draft123")),
listDrafts: jest.fn(() =>
Promise.resolve([{ ...mockEmailMetadata, id: "draft1" }])
),
deleteDraft: jest.fn(() => Promise.resolve()),
};
return {
__esModule: true,
GmailService: jest.fn(() => mockGmailService),
};
});
// Mock Calendar Service
jest.mock("../../services/calendar-service", () => {
const mockEvent: calendar_v3.Schema$Event = {
id: "123",
summary: "Test Event",
description: "Test Description",
start: { dateTime: new Date().toISOString() },
end: { dateTime: new Date().toISOString() },
attendees: [{ email: "test@example.com" }],
location: "Test Location",
};
const mockCalendarService = {
listEvents: jest.fn(() => Promise.resolve([mockEvent])),
getEvent: jest.fn(() => Promise.resolve(mockEvent)),
searchEvents: jest.fn(() => Promise.resolve([mockEvent])),
listCalendars: jest.fn(() =>
Promise.resolve([
{ id: "primary", summary: "Primary Calendar" },
] as calendar_v3.Schema$CalendarListEntry[])
),
};
return {
__esModule: true,
CalendarService: jest.fn(() => mockCalendarService),
};
});
describe("Tool Handlers", () => {
let handleListTools: any;
let handleToolCall: any;
beforeEach(async () => {
const mockPrompt: SystempromptPromptResponse = {
id: "1",
metadata: {
title: "Test Prompt",
description: "Test Description",
created: "2024-01-14",
updated: "2024-01-14",
version: 1,
status: "active",
author: "test",
log_message: "test",
},
instruction: {
static: "test",
dynamic: "test",
state: "test",
},
input: {
name: "test",
description: "test",
type: ["string"],
schema: {},
},
output: {
name: "test",
description: "test",
type: ["string"],
schema: {},
},
_link: "test",
};
const mockBlock: SystempromptBlockResponse = {
id: "1",
content: "Test content",
prefix: "test",
metadata: {
title: "Test Block",
description: null,
created: "2024-01-14",
updated: "2024-01-14",
version: 1,
status: "active",
author: "test",
log_message: "test",
},
};
const mockService = {
getAllPrompts: jest.fn().mockImplementation(async () => [mockPrompt]),
listBlocks: jest.fn().mockImplementation(async () => [mockBlock]),
getBlock: jest.fn().mockImplementation(async () => mockBlock),
};
jest.doMock("../../services/systemprompt-service.js", () => ({
SystemPromptService: {
getInstance: jest.fn().mockReturnValue(mockService),
initialize: jest.fn(),
},
}));
// Import the handlers after mocking
const handlers = await import("../tool-handlers.js");
handleListTools = handlers.handleListTools;
handleToolCall = handlers.handleToolCall;
});
afterEach(() => {
jest.clearAllMocks();
jest.resetModules();
});
describe("handleListTools", () => {
it("should return list of available tools", async () => {
const request = {
method: "tools/list" as const,
};
const result = await handleListTools(request);
expect(Array.isArray(result.tools)).toBe(true);
expect(result.tools.length).toBeGreaterThan(0);
// Verify the structure of each tool
result.tools.forEach((tool: Tool) => {
expect(tool).toMatchObject({
name: expect.stringMatching(/^systemprompt_/),
description: expect.any(String),
inputSchema: expect.objectContaining({
type: "object",
properties: expect.any(Object),
}),
});
});
// Verify specific tools exist
const toolNames = result.tools.map((t: Tool) => t.name);
expect(toolNames).toContain("systemprompt_list_messages");
expect(toolNames).toContain("systemprompt_send_email");
expect(toolNames).toContain("systemprompt_list_events");
});
});
describe("handleToolCall", () => {
it("should handle invalid tool name", async () => {
const request: CallToolRequest = {
method: "tools/call" as const,
params: {
name: "invalid_tool" as any,
arguments: {},
},
};
await expect(handleToolCall(request)).rejects.toThrow(
"Tool call failed: Unknown tool: invalid_tool"
);
});
it("should handle service errors", async () => {
// Clear module cache
jest.resetModules();
// Mock the service to throw an error for this test
const mockServiceWithError = {
getAllPrompts: jest.fn().mockImplementation(async () => []),
listBlocks: jest.fn().mockImplementation(async () => []),
getBlock: jest.fn().mockImplementation(async () => {
throw new Error("Service error");
}),
};
// Mock the service module
jest.mock(
"../../services/systemprompt-service.js",
() => ({
SystemPromptService: {
getInstance: jest.fn().mockReturnValue(mockServiceWithError),
initialize: jest.fn(),
},
}),
{ virtual: true }
);
// Re-import handlers to get fresh instance with new mock
const { handleToolCall: freshHandleToolCall } = await import(
"../tool-handlers.js"
);
const request: CallToolRequest = {
method: "tools/call" as const,
params: {
name: "systemprompt_fetch_resource",
arguments: {
uuid: "test-uuid",
},
},
};
await expect(freshHandleToolCall(request)).rejects.toThrow(
"Tool call failed: Service error"
);
});
it("should handle fetch resource request", async () => {
const request: CallToolRequest = {
method: "tools/call" as const,
params: {
name: "systemprompt_fetch_resource",
arguments: {
uuid: "test-uuid",
},
},
};
const result = await handleToolCall(request);
expect(result.content).toEqual([
{
type: "resource",
resource: {
uri: "resource:///block/test-uuid",
text: "Test content",
},
},
]);
});
});
describe("Gmail Tool Handlers", () => {
it("should handle systemprompt_list_messages without filters", async () => {
const request: CallToolRequest = {
method: "tools/call" as const,
params: {
name: "systemprompt_list_messages",
arguments: {},
},
};
const result = await handleToolCall(request);
expect(result.content[0].text).toContain("123");
});
it("should handle systemprompt_list_messages with filters", async () => {
const request: CallToolRequest = {
method: "tools/call" as const,
params: {
name: "systemprompt_list_messages",
arguments: {
subject: "Test",
},
},
};
const result = await handleToolCall(request);
expect(result.content[0].text).toContain("789");
});
it("should handle systemprompt_get_message", async () => {
const { handleToolCall } = await import("../../handlers/tool-handlers");
const request = {
method: "tools/call",
params: {
name: "systemprompt_get_message",
arguments: {
messageId: "123",
},
},
} as CallToolRequest;
const result = await handleToolCall(request);
expect(result.content[0].text).toContain("123");
});
it("should handle systemprompt_search_messages", async () => {
const { handleToolCall } = await import("../../handlers/tool-handlers");
const request = {
method: "tools/call",
params: {
name: "systemprompt_search_messages",
arguments: {
query: "important",
maxResults: 10,
after: "2024-01-01",
before: "2024-01-31",
},
},
} as CallToolRequest;
const result = await handleToolCall(request);
expect(result.content[0].text).toContain("789");
});
it("should handle systemprompt_list_labels", async () => {
const { handleToolCall } = await import("../../handlers/tool-handlers");
const request = {
method: "tools/call",
params: {
name: "systemprompt_list_labels",
arguments: {},
},
} as CallToolRequest;
const result = await handleToolCall(request);
expect(result.content[0].text).toContain("INBOX");
});
it("should handle systemprompt_send_email", async () => {
const { handleToolCall } = await import("../../handlers/tool-handlers");
const request = {
method: "tools/call",
params: {
name: "systemprompt_send_email",
arguments: {
to: "test@example.com",
subject: "Test Email",
body: "Hello World",
cc: "cc@example.com",
bcc: "bcc@example.com",
isHtml: false,
},
},
} as CallToolRequest;
const result = await handleToolCall(request);
expect(result.content[0].text).toContain("msg123");
});
it("should handle systemprompt_create_draft", async () => {
const { handleToolCall } = await import("../../handlers/tool-handlers");
const request = {
method: "tools/call",
params: {
name: "systemprompt_create_draft",
arguments: {
to: "test@example.com",
subject: "Test Draft",
body: "Hello World",
cc: "cc@example.com",
bcc: "bcc@example.com",
isHtml: false,
},
},
} as CallToolRequest;
const result = await handleToolCall(request);
expect(result.content[0].text).toContain("draft123");
});
it("should handle systemprompt_list_drafts", async () => {
const { handleToolCall } = await import("../../handlers/tool-handlers");
const request = {
method: "tools/call",
params: {
name: "systemprompt_list_drafts",
arguments: {
maxResults: 10,
},
},
} as CallToolRequest;
const result = await handleToolCall(request);
expect(result.content[0].text).toContain("draft1");
});
it("should handle systemprompt_delete_draft", async () => {
const { handleToolCall } = await import("../../handlers/tool-handlers");
const request = {
method: "tools/call",
params: {
name: "systemprompt_delete_draft",
arguments: {
draftId: "draft123",
},
},
} as CallToolRequest;
const result = await handleToolCall(request);
expect(result.content[0].text).toContain("success");
});
});
describe("Calendar Tool Handlers", () => {
it("should handle systemprompt_list_events", async () => {
const { handleToolCall } = await import("../../handlers/tool-handlers");
const request = {
method: "tools/call",
params: {
name: "systemprompt_list_events",
arguments: {
calendarId: "primary",
maxResults: 10,
},
},
} as CallToolRequest;
const result = await handleToolCall(request);
expect(result.content[0].text).toBeDefined();
});
it("should handle systemprompt_get_event", async () => {
const { handleToolCall } = await import("../../handlers/tool-handlers");
const request = {
method: "tools/call",
params: {
name: "systemprompt_get_event",
arguments: {
eventId: "123",
calendarId: "primary",
},
},
} as CallToolRequest;
const result = await handleToolCall(request);
expect(result.content[0].text).toBeDefined();
});
it("should handle systemprompt_search_events", async () => {
const { handleToolCall } = await import("../../handlers/tool-handlers");
const request = {
method: "tools/call",
params: {
name: "systemprompt_search_events",
arguments: {
query: "meeting",
calendarId: "primary",
maxResults: 10,
},
},
} as CallToolRequest;
const result = await handleToolCall(request);
expect(result.content[0].text).toBeDefined();
});
it("should handle systemprompt_list_calendars", async () => {
const { handleToolCall } = await import("../../handlers/tool-handlers");
const request = {
method: "tools/call",
params: {
name: "systemprompt_list_calendars",
arguments: {},
},
} as CallToolRequest;
const result = await handleToolCall(request);
expect(result.content[0].text).toBeDefined();
});
});
it("should ensure that tool properties are never empty or undefined", () => {
const { TOOLS } = require("../tool-handlers");
TOOLS.forEach((tool: Tool) => {
expect(tool.inputSchema.properties).toBeDefined();
if (tool.inputSchema.properties) {
expect(Object.keys(tool.inputSchema.properties).length).toBeGreaterThan(
0
);
}
});
});
});