Skip to main content
Glama

HomeAssistant MCP

tool-registry.test.ts.disabled7.54 kB
import { describe, expect, test } from "bun:test"; import { ToolRegistry, ToolCategory, EnhancedTool } from '../../src/tools/index.js'; describe('ToolRegistry', () => { let registry: ToolRegistry; let mockTool: EnhancedTool; beforeEach(() => { registry = new ToolRegistry(); mockTool = { name: 'test_tool', description: 'A test tool', metadata: { category: ToolCategory.DEVICE, platform: 'test', version: '1.0.0', caching: { enabled: true, ttl: 1000 } }, execute: mock().mockResolvedValue({ success: true }), validate: mock().mockResolvedValue(true), preExecute: mock().mockResolvedValue(undefined), postExecute: mock().mockResolvedValue(undefined) }; }); describe('Tool Registration', () => { test('should register a tool successfully', () => { registry.registerTool(mockTool); const retrievedTool = registry.getTool('test_tool'); expect(retrievedTool).toBe(mockTool); }); test('should categorize tools correctly', () => { registry.registerTool(mockTool); const deviceTools = registry.getToolsByCategory(ToolCategory.DEVICE); expect(deviceTools).toContain(mockTool); }); test('should handle multiple tools in the same category', () => { const mockTool2 = { ...mockTool, name: 'test_tool_2' }; registry.registerTool(mockTool); registry.registerTool(mockTool2); const deviceTools = registry.getToolsByCategory(ToolCategory.DEVICE); expect(deviceTools).toHaveLength(2); expect(deviceTools).toContain(mockTool); expect(deviceTools).toContain(mockTool2); }); }); describe('Tool Execution', () => { test('should execute a tool with all hooks', async () => { registry.registerTool(mockTool); await registry.executeTool('test_tool', { param: 'value' }); expect(mockTool.validate).toHaveBeenCalledWith({ param: 'value' }); expect(mockTool.preExecute).toHaveBeenCalledWith({ param: 'value' }); expect(mockTool.execute).toHaveBeenCalledWith({ param: 'value' }); expect(mockTool.postExecute).toHaveBeenCalled(); }); test('should throw error for non-existent tool', async () => { await expect(registry.executeTool('non_existent', {})) .rejects.toThrow('Tool non_existent not found'); }); test('should handle validation failure', async () => { mockTool.validate = mock().mockResolvedValue(false); registry.registerTool(mockTool); await expect(registry.executeTool('test_tool', {})) .rejects.toThrow('Invalid parameters'); }); test('should execute without optional hooks', async () => { const simpleTool: EnhancedTool = { name: 'simple_tool', description: 'A simple tool', metadata: { category: ToolCategory.SYSTEM, platform: 'test', version: '1.0.0' }, execute: mock().mockResolvedValue({ success: true }) }; registry.registerTool(simpleTool); const result = await registry.executeTool('simple_tool', {}); expect(result).toEqual({ success: true }); }); }); describe('Caching', () => { test('should cache tool results when enabled', async () => { registry.registerTool(mockTool); const params = { test: 'value' }; // First execution await registry.executeTool('test_tool', params); expect(mockTool.execute).toHaveBeenCalledTimes(1); // Second execution within TTL await registry.executeTool('test_tool', params); expect(mockTool.execute).toHaveBeenCalledTimes(1); }); test('should not cache results when disabled', async () => { const uncachedTool: EnhancedTool = { ...mockTool, metadata: { ...mockTool.metadata, caching: { enabled: false, ttl: 1000 } } }; registry.registerTool(uncachedTool); const params = { test: 'value' }; // Multiple executions await registry.executeTool('test_tool', params); await registry.executeTool('test_tool', params); expect(uncachedTool.execute).toHaveBeenCalledTimes(2); }); test('should expire cache after TTL', async () => { mockTool.metadata.caching!.ttl = 100; // Short TTL for testing registry.registerTool(mockTool); const params = { test: 'value' }; // First execution await registry.executeTool('test_tool', params); // Wait for cache to expire await new Promise(resolve => setTimeout(resolve, 150)); // Second execution after TTL await registry.executeTool('test_tool', params); expect(mockTool.execute).toHaveBeenCalledTimes(2); }); test('should clean expired cache entries', async () => { mockTool.metadata.caching!.ttl = 100; registry.registerTool(mockTool); const params = { test: 'value' }; // Execute and cache await registry.executeTool('test_tool', params); // Wait for cache to expire await new Promise(resolve => setTimeout(resolve, 150)); // Clean cache registry.cleanCache(); // Verify cache is cleaned by forcing a new execution await registry.executeTool('test_tool', params); expect(mockTool.execute).toHaveBeenCalledTimes(2); }); }); describe('Category Management', () => { test('should return empty array for unknown category', () => { const tools = registry.getToolsByCategory('unknown' as ToolCategory); expect(tools).toEqual([]); }); test('should handle tools across multiple categories', () => { const systemTool: EnhancedTool = { ...mockTool, name: 'system_tool', metadata: { ...mockTool.metadata, category: ToolCategory.SYSTEM } }; const automationTool: EnhancedTool = { ...mockTool, name: 'automation_tool', metadata: { ...mockTool.metadata, category: ToolCategory.AUTOMATION } }; registry.registerTool(mockTool); // DEVICE category registry.registerTool(systemTool); registry.registerTool(automationTool); expect(registry.getToolsByCategory(ToolCategory.DEVICE)).toHaveLength(1); expect(registry.getToolsByCategory(ToolCategory.SYSTEM)).toHaveLength(1); expect(registry.getToolsByCategory(ToolCategory.AUTOMATION)).toHaveLength(1); }); }); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jango-blockchained/advanced-homeassistant-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server