open-api-global-agent-invoke.test.js 2.56 KB
/**
 * 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 版本同一套执行路径),不适合放单测。
});