/** * POST /api/open/agents/:agentId/invoke — 全局 agent 的外部调用入口(不挂公司)。 * 只测路由层的同步校验分支(task 必填 / 拒绝 companyId:role 形态 / 本体不存在 404), * 不触发真正的 AgentManager 执行(跟同文件里未测的 company-scoped 版本同一个覆盖范围)。 */ import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import express from 'express'; import http from 'http'; process.env.OPEN_API_KEYS = 'test-open-api-key'; let app, server, baseUrl; function request(method, urlPath, body) { return new Promise((resolve, reject) => { const opts = { method, hostname: '127.0.0.1', port: server.address().port, path: urlPath, headers: { 'Content-Type': 'application/json', 'X-API-Key': 'test-open-api-key' }, }; const req = http.request(opts, (res) => { let data = ''; res.on('data', (d) => (data += d)); res.on('end', () => { try { resolve({ status: res.statusCode, data: JSON.parse(data) }); } catch { resolve({ status: res.statusCode, data }); } }); }); req.on('error', reject); if (body) req.write(JSON.stringify(body)); req.end(); }); } describe('POST /api/open/agents/:agentId/invoke', () => { beforeAll(async () => { const openApiRouter = require('../../routes/open-api.js'); app = express(); app.use(express.json()); app.use('/api/open', openApiRouter); await new Promise((resolve) => { server = http.createServer(app).listen(0, resolve); }); baseUrl = `http://127.0.0.1:${server.address().port}`; }); afterAll(() => new Promise((resolve) => server.close(resolve))); it('缺 task 字段 → 400', async () => { const res = await request('POST', '/api/open/agents/master/invoke', {}); expect(res.status).toBe(400); expect(res.data.error).toBe('Bad Request'); }); it('agentId 带 companyId: 前缀 → 400(提示改走 company-scoped 端点)', async () => { const res = await request('POST', '/api/open/agents/acme:coo/invoke', { task: 'hi' }); expect(res.status).toBe(400); expect(res.data.message).toMatch(/global agents only/); }); it('本体不存在 → 404', async () => { const res = await request('POST', '/api/open/agents/does-not-exist-xyz/invoke', { task: 'hi' }); expect(res.status).toBe(404); }); // 202 成功路径不在这里测:请求一进来就会同步触发 _runGlobalAgentInvocation 起真实 // claude CLI 子进程(跟未测的 company-scoped 版本同一套执行路径),不适合放单测。 });