import { ToolRegistry } from '../../src/registry/ToolRegistry'; import { NatsClient } from '../../src/nats/NatsClient'; import { ToolDefinition } from '../../src/types'; // Mock NatsClient jest.mock('../../src/nats/NatsClient'); describe('ToolRegistry', () => { let registry: ToolRegistry; let mockNatsClient: jest.Mocked; beforeEach(() => { mockNatsClient = new NatsClient() as jest.Mocked; mockNatsClient.subscribe = jest.fn(); mockNatsClient.request = jest.fn(); registry = new ToolRegistry(mockNatsClient); }); describe('registerTool', () => { it('should register a tool', () => { const tool: ToolDefinition = { name: 'test-tool', description: 'Test tool', inputSchema: { type: 'object' }, module: 'test-module', permissions: [], }; registry.registerTool(tool); expect(registry.getTool('test-tool')).toEqual(tool); }); }); describe('listTools', () => { it('should return all registered tools including built-in tools', async () => { const tool1: ToolDefinition = { name: 'tool1', description: 'Tool 1', inputSchema: {}, module: 'module1', permissions: [], }; const tool2: ToolDefinition = { name: 'tool2', description: 'Tool 2', inputSchema: {}, module: 'module2', permissions: [], }; // Get initial count (built-in tools) const initialTools = await registry.listTools(); const builtinCount = initialTools.length; registry.registerTool(tool1); registry.registerTool(tool2); const tools = await registry.listTools(); expect(tools).toHaveLength(builtinCount + 2); expect(tools.find(t => t.name === 'tool1')).toBeDefined(); expect(tools.find(t => t.name === 'tool2')).toBeDefined(); }); }); describe('executeTool', () => { it('should execute a registered tool', async () => { const tool: ToolDefinition = { name: 'test-tool', description: 'Test tool', inputSchema: {}, module: 'test-module', permissions: [], }; registry.registerTool(tool); mockNatsClient.request.mockResolvedValue({ id: 'test-id', status: 'success', data: { result: 'test result' }, duration: 100, }); const result = await registry.executeTool('test-tool', { input: 'test' }); expect(result).toEqual({ result: 'test result' }); expect(mockNatsClient.request).toHaveBeenCalledWith( 'tools.test-module.test-tool.execute', expect.objectContaining({ tool: 'test-tool', method: 'execute', params: { input: 'test' }, }), ); }); it('should throw error for unknown tool', async () => { await expect(registry.executeTool('unknown-tool', {})) .rejects.toThrow('Tool not found: unknown-tool'); }); it('should throw error when tool execution fails', async () => { const tool: ToolDefinition = { name: 'test-tool', description: 'Test tool', inputSchema: {}, module: 'test-module', permissions: [], }; registry.registerTool(tool); mockNatsClient.request.mockResolvedValue({ id: 'test-id', status: 'error', error: { code: 'TEST_ERROR', message: 'Test error message', }, duration: 100, }); await expect(registry.executeTool('test-tool', {})) .rejects.toThrow('Test error message'); }); }); });