UNPKG

systemprompt-mcp-interview

Version:

A specialized Model Context Protocol (MCP) server that enables AI-powered interview roleplay scenarios

287 lines (286 loc) 12.9 kB
import { handleListTools, handleToolCall } from "../tool-handlers.js"; import { SystemPromptService } from "../../services/systemprompt-service.js"; // Mock the SystemPromptService jest.mock("../../services/systemprompt-service.js"); describe("Tool Handlers", () => { let mockSystemPromptService; beforeEach(() => { // Clear all mocks before each test jest.clearAllMocks(); // Setup mock implementation mockSystemPromptService = { createPrompt: jest.fn(), editPrompt: jest.fn(), createBlock: jest.fn(), editBlock: jest.fn(), }; // Replace the service instance with our mock SystemPromptService.mockImplementation(() => mockSystemPromptService); }); describe("handleListTools", () => { let tools; beforeEach(() => { const result = handleListTools(); tools = result.tools; }); it("should return all available tools with their schemas", () => { expect(tools).toHaveLength(4); expect(tools.map((t) => t.name)).toEqual([ "create_prompt", "edit_prompt", "create_block", "edit_block", ]); // Verify each tool has required properties tools.forEach((tool) => { expect(tool).toHaveProperty("name"); expect(tool).toHaveProperty("description"); expect(tool).toHaveProperty("inputSchema"); expect(tool.inputSchema).toHaveProperty("type", "object"); expect(tool.inputSchema).toHaveProperty("properties"); expect(tool.inputSchema).toHaveProperty("required"); }); }); it("should have valid create_prompt schema", () => { const createPrompt = tools.find((t) => t.name === "create_prompt"); expect(createPrompt?.inputSchema.required).toContain("instruction"); expect(createPrompt?.inputSchema.required).toContain("input"); expect(createPrompt?.inputSchema.required).toContain("output"); expect(createPrompt?.inputSchema.required).toContain("metadata"); const props = createPrompt?.inputSchema.properties; expect(props?.instruction.required).toContain("static"); expect(props?.input.required).toContain("name"); expect(props?.input.required).toContain("description"); expect(props?.input.required).toContain("type"); expect(props?.output.required).toContain("name"); expect(props?.output.required).toContain("description"); expect(props?.output.required).toContain("type"); expect(props?.metadata.required).toContain("title"); expect(props?.metadata.required).toContain("description"); }); it("should have valid edit_prompt schema", () => { const editPrompt = tools.find((t) => t.name === "edit_prompt"); expect(editPrompt?.inputSchema.required).toContain("uuid"); expect(editPrompt?.inputSchema.properties).toHaveProperty("instruction"); expect(editPrompt?.inputSchema.properties).toHaveProperty("input"); expect(editPrompt?.inputSchema.properties).toHaveProperty("output"); expect(editPrompt?.inputSchema.properties).toHaveProperty("metadata"); }); it("should have valid create_block schema", () => { const createBlock = tools.find((t) => t.name === "create_block"); expect(createBlock?.inputSchema.required).toContain("content"); expect(createBlock?.inputSchema.required).toContain("metadata"); expect(createBlock?.inputSchema.properties.prefix.pattern).toBe("^[a-zA-Z_]+$"); expect(createBlock?.inputSchema.properties.metadata.required).toContain("title"); expect(createBlock?.inputSchema.properties.metadata.required).toContain("description"); }); it("should have valid edit_block schema", () => { const editBlock = tools.find((t) => t.name === "edit_block"); expect(editBlock?.inputSchema.required).toContain("uuid"); expect(editBlock?.inputSchema.properties).toHaveProperty("content"); expect(editBlock?.inputSchema.properties).toHaveProperty("prefix"); expect(editBlock?.inputSchema.properties).toHaveProperty("metadata"); expect(editBlock?.inputSchema.properties.prefix.pattern).toBe("^[a-zA-Z_]+$"); }); }); describe("handleToolCall", () => { describe("create_prompt", () => { const validPromptData = { instruction: { static: "Test instruction", state: "Test state", dynamic: "Test dynamic", }, input: { name: "test_input", description: "Test input description", type: ["message"], }, output: { name: "test_output", description: "Test output description", type: ["message"], }, metadata: { title: "Test prompt", description: "Test description", tag: ["test"], }, }; it("should create a prompt successfully", async () => { const mockResult = { id: "test-uuid", ...validPromptData, _link: "test-link", metadata: { ...validPromptData.metadata, created: "2024-01-01", updated: "2024-01-01", version: 1, status: "draft", author: "test", log_message: "Created", }, }; mockSystemPromptService.createPrompt.mockResolvedValue(mockResult); const result = await handleToolCall({ params: { name: "create_prompt", arguments: validPromptData, }, }); expect(mockSystemPromptService.createPrompt).toHaveBeenCalledWith(validPromptData); expect(result.content[0].text).toBe(`Created prompt with ID: ${mockResult.id}`); expect(result._meta.prompt).toEqual(mockResult); }); }); describe("edit_prompt", () => { const validEditData = { uuid: "test-uuid", instruction: { static: "Updated instruction", }, metadata: { title: "Updated title", description: "Test description", }, }; it("should edit a prompt successfully", async () => { const mockResult = { id: "test-uuid", instruction: { static: "Updated instruction" }, input: { name: "test_input", description: "Test input description", type: ["message"], }, output: { name: "test_output", description: "Test output description", type: ["message"], }, metadata: { title: "Updated title", description: "Test description", created: "2024-01-01", updated: "2024-01-01", version: 1, status: "draft", author: "test", log_message: "Updated", }, _link: "test-link", }; mockSystemPromptService.editPrompt.mockResolvedValue(mockResult); const result = await handleToolCall({ params: { name: "edit_prompt", arguments: validEditData, }, }); expect(mockSystemPromptService.editPrompt).toHaveBeenCalledWith(validEditData.uuid, expect.objectContaining({ instruction: validEditData.instruction, metadata: validEditData.metadata, })); expect(result.content[0].text).toBe(`Updated prompt with ID: ${mockResult.id}`); expect(result._meta.prompt).toEqual(mockResult); }); }); describe("create_block", () => { const validBlockData = { content: "Test block content", prefix: "test_block", metadata: { title: "Test block", description: "Test description", tag: ["test"], }, }; it("should create a block successfully", async () => { const mockResult = { id: "test-uuid", ...validBlockData, _link: "test-link", metadata: { ...validBlockData.metadata, created: "2024-01-01", updated: "2024-01-01", version: 1, status: "draft", author: "test", log_message: "Created", }, }; mockSystemPromptService.createBlock.mockResolvedValue(mockResult); const result = await handleToolCall({ params: { name: "create_block", arguments: validBlockData, }, }); expect(mockSystemPromptService.createBlock).toHaveBeenCalledWith(validBlockData); expect(result.content[0].text).toBe(`Created block with ID: ${mockResult.id}`); expect(result._meta.block).toEqual(mockResult); }); }); describe("edit_block", () => { const validEditData = { uuid: "test-uuid", content: "Updated content", metadata: { title: "Updated title", description: "Test description", }, }; it("should edit a block successfully", async () => { const mockResult = { id: "test-uuid", content: "Updated content", metadata: { title: "Updated title", description: "Test description", created: "2024-01-01", updated: "2024-01-01", version: 1, status: "draft", author: "test", log_message: "Updated", }, _link: "test-link", }; mockSystemPromptService.editBlock.mockResolvedValue(mockResult); const result = await handleToolCall({ params: { name: "edit_block", arguments: validEditData, }, }); expect(mockSystemPromptService.editBlock).toHaveBeenCalledWith(validEditData.uuid, expect.objectContaining({ content: validEditData.content, metadata: validEditData.metadata, })); expect(result.content[0].text).toBe(`Updated block with ID: ${mockResult.id}`); expect(result._meta.block).toEqual(mockResult); }); }); describe("error handling", () => { it("should throw error for unknown tool", async () => { await expect(handleToolCall({ params: { name: "unknown_tool", arguments: {}, }, })).rejects.toThrow("Unknown tool"); }); it("should propagate service errors", async () => { mockSystemPromptService.createPrompt.mockRejectedValue(new Error("Service error")); await expect(handleToolCall({ params: { name: "create_prompt", arguments: {}, }, })).rejects.toThrow("Service error"); }); }); }); });