/** * Tools Route 测试 * * 测试工具管理 REST API 端点 * 注意:现在使用 Core 的 toolRegistry,工具已预先注册 */ import { describe, it, expect, beforeEach, vi } from 'vitest'; import { Hono } from 'hono'; import { toolsRouter } from '../../../src/routes/tools.js'; import { toolRegistry } from '@ai-assistant/core'; // Create test app const app = new Hono(); app.route('/tools', toolsRouter); describe('Tools Route', () => { beforeEach(() => { vi.clearAllMocks(); }); describe('GET /tools - 列出所有工具', () => { 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); // Core toolRegistry 已注册工具 expect(json.data.length).toBeGreaterThan(0); }); it('工具包含必要字段', async () => { const res = await app.request('/tools'); const json = await res.json(); expect(res.status).toBe(200); // 检查第一个工具的字段 if (json.data.length > 0) { const tool = json.data[0]; expect(tool).toHaveProperty('name'); expect(tool).toHaveProperty('description'); expect(tool).toHaveProperty('parameters'); // 不应该包含 execute 函数 expect(tool).not.toHaveProperty('execute'); } }); it('返回的工具数量与 Core Registry 一致', async () => { const res = await app.request('/tools'); const json = await res.json(); expect(res.status).toBe(200); expect(json.data.length).toBe(toolRegistry.getAllTools().length); }); }); describe('GET /tools/:name - 获取单个工具', () => { it('返回存在的工具 (bash)', async () => { const res = await app.request('/tools/bash'); const json = await res.json(); expect(res.status).toBe(200); expect(json.success).toBe(true); expect(json.data.name).toBe('bash'); expect(json.data.description).toBeDefined(); }); it('返回存在的工具 (read_file)', async () => { const res = await app.request('/tools/read_file'); const json = await res.json(); expect(res.status).toBe(200); expect(json.success).toBe(true); expect(json.data.name).toBe('read_file'); }); 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 () => { const res = await app.request('/tools/bash/execute', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ params: { command: 'echo test' } }), }); const json = await res.json(); expect(res.status).toBe(200); expect(json.success).toBe(true); expect(json.data.tool).toBe('bash'); expect(json.data.params).toEqual({ command: 'echo test' }); // 当前是占位实现 expect(json.data.message).toContain('not yet implemented'); }); 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 () => { const res = await app.request('/tools/bash/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 () => { const res = await app.request('/tools/bash/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); }); }); });