UNPKG

@the_cfdude/productboard-mcp

Version:

Model Context Protocol server for Productboard REST API with dynamic tool loading

121 lines (102 loc) 4.16 kB
/** * Tests for Webhooks tools */ import { describe, it, expect, jest, beforeEach } from '@jest/globals'; import { handleWebhooksTool, setupWebhooksTools, } from '../../tools/webhooks.js'; import type { ToolDefinition } from '../../types/tool-types.js'; describe('Webhooks Tools', () => { beforeEach(() => { jest.clearAllMocks(); }); describe('Tool Definitions', () => { it('should define all webhooks tools with correct schemas', () => { const tools = setupWebhooksTools(); expect(tools).toHaveLength(4); const toolNames = tools.map((tool: ToolDefinition) => tool.name); expect(toolNames).toContain('create_webhook'); expect(toolNames).toContain('list_webhooks'); expect(toolNames).toContain('get_webhook'); expect(toolNames).toContain('delete_webhook'); }); it('should have standardized parameters for list operations', () => { const tools = setupWebhooksTools(); const listWebhooks = tools.find( (t: ToolDefinition) => t.name === 'list_webhooks' ); expect(listWebhooks?.inputSchema.properties).toHaveProperty('limit'); expect(listWebhooks?.inputSchema.properties).toHaveProperty('startWith'); expect(listWebhooks?.inputSchema.properties).toHaveProperty('detail'); expect(listWebhooks?.inputSchema.properties).toHaveProperty( 'includeSubData' ); }); it('should have standardized parameters for get operations', () => { const tools = setupWebhooksTools(); const getWebhook = tools.find( (t: ToolDefinition) => t.name === 'get_webhook' ); expect(getWebhook?.inputSchema.properties).toHaveProperty('detail'); expect(getWebhook?.inputSchema.properties).toHaveProperty( 'includeSubData' ); }); it('should require events, name and url for create_webhook', () => { const tools = setupWebhooksTools(); const createWebhook = tools.find( (t: ToolDefinition) => t.name === 'create_webhook' ); expect(createWebhook?.inputSchema.required).toContain('events'); expect(createWebhook?.inputSchema.required).toContain('name'); expect(createWebhook?.inputSchema.required).toContain('url'); }); it('should have optional headers and version fields for create_webhook', () => { const tools = setupWebhooksTools(); const createWebhook = tools.find( (t: ToolDefinition) => t.name === 'create_webhook' ); expect(createWebhook?.inputSchema.properties).toHaveProperty('headers'); expect(createWebhook?.inputSchema.properties).toHaveProperty('version'); expect(createWebhook?.inputSchema.properties).toHaveProperty('events'); expect(createWebhook?.inputSchema.properties).toHaveProperty('name'); }); it('should require id for individual webhook operations', () => { const tools = setupWebhooksTools(); const getWebhook = tools.find( (t: ToolDefinition) => t.name === 'get_webhook' ); const deleteWebhook = tools.find( (t: ToolDefinition) => t.name === 'delete_webhook' ); expect(getWebhook?.inputSchema.required).toContain('id'); expect(deleteWebhook?.inputSchema.required).toContain('id'); }); }); describe('Tool Handler', () => { it('should handle unknown tool error', async () => { await expect(handleWebhooksTool('unknown_tool', {})).rejects.toThrow( 'Unknown webhooks tool: unknown_tool' ); }); it('should accept valid tool names including aliases', () => { const validTools = [ 'create_webhook', 'post_webhook', // alias for create_webhook 'list_webhooks', 'get_webhooks', // alias for list_webhooks 'get_webhook', 'delete_webhook', ]; validTools.forEach(toolName => { expect(() => { // Just check it doesn't throw immediately const promise = handleWebhooksTool(toolName, {}); // Catch the expected error about missing required fields promise.catch(() => {}); }).not.toThrow('Unknown webhooks tool'); }); }); }); });