/** * Tools Route 测试 * * 测试工具管理 REST API 端点 */ import { describe, it, expect, beforeEach, vi } from 'vitest'; import { Hono } from 'hono'; import { toolsRouter, registerTool, getRegisteredTools } from '../../../src/routes/tools.js'; // Create test app const app = new Hono(); app.route('/tools', toolsRouter); describe('Tools Route', () => { beforeEach(() => { // Clear any previously registered tools // Note: Since the toolRegistry is a module-level Map, we test what's already registered vi.clearAllMocks(); }); describe('registerTool / getRegisteredTools - 工具注册', () => { it('注册工具', () => { registerTool({ name: 'test-tool', description: 'A test tool', parameters: {}, }); const tools = getRegisteredTools(); expect(tools.some((t) => t.name === 'test-tool')).toBe(true); }); it('获取所有已注册工具', () => { const tools = getRegisteredTools(); expect(Array.isArray(tools)).toBe(true); }); }); describe('GET /tools - 列出所有工具', () => { it('返回工具列表', async () => { // Register a tool first registerTool({ name: 'list-test-tool', description: 'Tool for list test', parameters: {}, }); const res = await app.request('/tools'); const json = await res.json(); expect(res.status).toBe(200); expect(json.success).toBe(true); expect(Array.isArray(json.data)).toBe(true); }); it('返回数组类型数据', async () => { const res = await app.request('/tools'); const json = await res.json(); expect(res.status).toBe(200); expect(json.success).toBe(true); expect(Array.isArray(json.data)).toBe(true); }); }); describe('GET /tools/:name - 获取单个工具', () => { it('返回存在的工具', async () => { registerTool({ name: 'get-test-tool', description: 'Tool for get test', parameters: { path: { type: 'string' } }, }); const res = await app.request('/tools/get-test-tool'); const json = await res.json(); expect(res.status).toBe(200); expect(json.success).toBe(true); expect(json.data.name).toBe('get-test-tool'); expect(json.data.description).toBe('Tool for get test'); }); it('工具不存在返回 404', async () => { const res = await app.request('/tools/non-existent-tool-12345'); const json = await res.json(); expect(res.status).toBe(404); expect(json.success).toBe(false); expect(json.error).toBe('Tool not found'); }); }); describe('POST /tools/:name/execute - 执行工具', () => { it('执行存在的工具(占位实现)', async () => { registerTool({ name: 'execute-test-tool', description: 'Tool for execute test', parameters: {}, }); const res = await app.request('/tools/execute-test-tool/execute', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ params: { test: 'value' } }), }); const json = await res.json(); expect(res.status).toBe(200); expect(json.success).toBe(true); expect(json.data.tool).toBe('execute-test-tool'); expect(json.data.params).toEqual({ test: 'value' }); }); it('工具不存在返回 404', async () => { const res = await app.request('/tools/non-existent-tool-67890/execute', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ params: {} }), }); const json = await res.json(); expect(res.status).toBe(404); expect(json.success).toBe(false); expect(json.error).toBe('Tool not found'); }); it('无 params 时使用空对象', async () => { registerTool({ name: 'no-params-tool', description: 'Tool without params', parameters: {}, }); const res = await app.request('/tools/no-params-tool/execute', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({}), }); const json = await res.json(); expect(res.status).toBe(200); expect(json.data.params).toEqual({}); }); it('无效 JSON 返回 500', async () => { registerTool({ name: 'json-error-tool', description: 'Tool for JSON error test', parameters: {}, }); const res = await app.request('/tools/json-error-tool/execute', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: 'invalid json', }); const json = await res.json(); expect(res.status).toBe(500); expect(json.success).toBe(false); }); }); });