MCP-Logic
by angrysky56
import { jest, describe, it, expect, beforeEach } from "@jest/globals";
import type { CallToolRequest } from "@modelcontextprotocol/sdk/types.js";
import { handleToolCall } from "../tool-handlers.js";
import type {
SystempromptPromptResponse,
SystempromptUserStatusResponse,
SystempromptBlockResponse,
SystempromptAgentResponse,
} from "../../types/systemprompt.js";
// Mock the server config
jest.mock("../../config/server-config.js", () => ({
serverConfig: {
port: 3000,
host: "localhost",
},
serverCapabilities: {
tools: [],
},
}));
// Mock the main function
jest.mock("../../index.ts", () => ({
main: jest.fn(),
server: {
notification: jest.fn().mockImplementation(async () => {}),
},
}));
// Mock the sampling module
jest.mock("../sampling.js", () => ({
sendSamplingRequest: jest.fn().mockImplementation(async () => ({
content: [
{
type: "text",
text: JSON.stringify({ metadata: { title: "Test", description: "Test" }, content: "Test" }),
},
],
})),
}));
// Mock SystemPromptService
const mockUserStatus: SystempromptUserStatusResponse = {
user: {
id: "user123",
uuid: "uuid123",
name: "Test User",
email: "test@example.com",
roles: ["user"],
paddle_id: "paddle123",
},
content: {
prompt: 0,
artifact: 0,
block: 0,
conversation: 0,
},
usage: {
ai: {
execution: 0,
token: 0,
},
api: {
generation: 0,
},
},
billing: {
customer: {
id: "cust123",
name: null,
email: "test@example.com",
marketingConsent: false,
status: "active",
customData: null,
locale: "en",
createdAt: {
date: "2024-01-01T00:00:00Z",
timezone_type: 3,
timezone: "UTC",
},
updatedAt: {
date: "2024-01-01T00:00:00Z",
timezone_type: 3,
timezone: "UTC",
},
importMeta: null,
},
subscription: [
{
id: "sub123",
status: "active",
currency_code: "USD",
billing_cycle: {
frequency: 1,
interval: "month",
},
current_billing_period: {
starts_at: "2024-01-01",
ends_at: "2024-02-01",
},
items: [
{
product: { name: "Test Product" },
price: {
unit_price: { amount: "10.00", currency_code: "USD" },
},
},
],
},
],
},
api_key: "test-api-key",
};
interface MockSystemPromptService {
fetchUserStatus: () => Promise<SystempromptUserStatusResponse>;
getAllPrompts: () => Promise<SystempromptPromptResponse[]>;
listBlocks: () => Promise<SystempromptBlockResponse[]>;
listAgents: () => Promise<SystempromptAgentResponse[]>;
deletePrompt: (id: string) => Promise<void>;
deleteBlock: (id: string) => Promise<void>;
}
const mockSystemPromptService = {
fetchUserStatus: jest
.fn<() => Promise<SystempromptUserStatusResponse>>()
.mockResolvedValue(mockUserStatus),
getAllPrompts: jest.fn<() => Promise<SystempromptPromptResponse[]>>().mockResolvedValue([]),
listBlocks: jest.fn<() => Promise<SystempromptBlockResponse[]>>().mockResolvedValue([]),
listAgents: jest.fn<() => Promise<SystempromptAgentResponse[]>>().mockResolvedValue([]),
deletePrompt: jest.fn<() => Promise<void>>().mockResolvedValue(undefined),
deleteBlock: jest.fn<() => Promise<void>>().mockResolvedValue(undefined),
};
jest.mock("../../services/systemprompt-service.js", () => ({
SystemPromptService: jest.fn(() => mockSystemPromptService),
}));
describe("Tool Handlers", () => {
beforeEach(() => {
jest.clearAllMocks();
});
describe("handleToolCall", () => {
describe("Heartbeat", () => {
it("should handle systemprompt_heartbeat", async () => {
const request: CallToolRequest = {
method: "tools/call",
params: {
name: "systemprompt_heartbeat",
params: {},
},
};
const result = await handleToolCall(request);
expect(mockSystemPromptService.fetchUserStatus).toHaveBeenCalled();
expect(result.content[0].type).toBe("text");
expect(result.content[0].text).toContain("User Information");
});
it("should handle errors gracefully", async () => {
const error = new Error("Failed to fetch user status");
mockSystemPromptService.fetchUserStatus.mockRejectedValueOnce(error);
const request: CallToolRequest = {
method: "tools/call",
params: {
name: "systemprompt_heartbeat",
params: {},
},
};
await expect(handleToolCall(request)).rejects.toThrow("Failed to fetch user status");
});
});
describe("Resource Operations", () => {
it("should handle systemprompt_fetch_resources", async () => {
const result = await handleToolCall({
method: "tools/call",
params: {
name: "systemprompt_fetch_resources",
params: {},
},
});
expect(mockSystemPromptService.getAllPrompts).toHaveBeenCalled();
expect(mockSystemPromptService.listBlocks).toHaveBeenCalled();
expect(mockSystemPromptService.listAgents).toHaveBeenCalled();
expect(result.content[0].type).toBe("text");
expect(result.content[0].text).toContain("Resources");
});
it("should handle delete resource failure", async () => {
mockSystemPromptService.deletePrompt.mockRejectedValueOnce(
new Error("Failed to delete prompt"),
);
mockSystemPromptService.deleteBlock.mockRejectedValueOnce(
new Error("Failed to delete block"),
);
await expect(
handleToolCall({
method: "tools/call",
params: {
name: "systemprompt_delete_resource",
arguments: {
id: "nonexistent123",
},
},
}),
).rejects.toThrow("Failed to delete resource with ID nonexistent123");
});
});
describe("Error Handling", () => {
it("should handle invalid tool name", async () => {
await expect(
handleToolCall({
method: "tools/call",
params: {
name: "invalid_tool",
params: {},
},
}),
).rejects.toThrow("Unknown tool: invalid_tool");
});
it("should handle service errors", async () => {
mockSystemPromptService.fetchUserStatus.mockRejectedValueOnce(new Error("Service error"));
await expect(
handleToolCall({
method: "tools/call",
params: {
name: "systemprompt_heartbeat",
params: {},
},
}),
).rejects.toThrow("Service error");
});
});
});
});