agent-locator.test.js 3.11 KB
/**
 * Unit Tests — agent-locator(28 号设计 批次 2)
 *
 * 只钉三件「算错了不会报错、只会静默指向另一个目录」的事:
 *   1. 地址的拆/拼是可逆的(`cid:aid` ⇄ {cid, aid}),且没有公司时不凭空造出一个空前缀;
 *   2. 没有公司时公司态目录落保留值 `_global` —— 不是省掉这一层(省掉会让深度不一致,
 *      本体里的相对引用 `../../../soul.md` 就得分两种写法);
 *   3. isReservedCompanyId 的真假两侧 —— 假阴性会让一家叫 `memory` 的公司盖掉 agent 的记忆目录。
 */
import { describe, it, expect } from 'vitest';
import path from 'path';

const locator = require('../../services/agent-locator');

describe('agent-locator', () => {
  describe('parseAddress', () => {
    it('`cid:aid` 拆成两半', () => {
      expect(locator.parseAddress('mycompany:qa-judge')).toEqual({
        companyId: 'mycompany', agentId: 'qa-judge',
      });
    });

    it('没有冒号 → companyId 为 null,整串都是 agentId', () => {
      expect(locator.parseAddress('qa-judge')).toEqual({ companyId: null, agentId: 'qa-judge' });
    });

    it('多个冒号按第一个切,后半截原样留给 agentId(不静默吞掉)', () => {
      expect(locator.parseAddress('co-1:a:b')).toEqual({ companyId: 'co-1', agentId: 'a:b' });
    });
  });

  it('formatAddress 与 parseAddress 互逆;没有公司时返回裸 agentId', () => {
    expect(locator.formatAddress('co-1', 'qa-judge')).toBe('co-1:qa-judge');
    expect(locator.formatAddress(null, 'qa-judge')).toBe('qa-judge');
    const addr = locator.formatAddress('co-1', 'qa-judge');
    expect(locator.parseAddress(addr)).toEqual({ companyId: 'co-1', agentId: 'qa-judge' });
  });

  describe('目录推导', () => {
    it('bodyDir 在 system/agents 下', () => {
      expect(locator.bodyDir('qa-judge')).toBe(path.join(locator.AGENTS_ROOT, 'qa-judge'));
    });

    it('companyId 缺省 → 公司态落 _global,深度与有公司时一致', () => {
      expect(locator.companyDir('master')).toBe(locator.companyDir('master', '_global'));
      expect(locator.companyDir('master')).toBe(path.join(locator.AGENTS_ROOT, 'master', '_global'));
    });

    it('taskDir 是公司态的子目录', () => {
      expect(locator.taskDir('qa-judge', 'co-1', 't-1'))
        .toBe(path.join(locator.companyDir('qa-judge', 'co-1'), 't-1'));
    });
  });

  describe('isReservedCompanyId', () => {
    it('本体自带的子目录名一律拒绝', () => {
      for (const id of ['memory', 'conversations', 'logs', 'workspace', 'tasks', 'code']) {
        expect(locator.isReservedCompanyId(id)).toBe(true);
      }
    });

    it('`_` / `.` 前缀拒绝(_global / _base / .claude 这类非公司项)', () => {
      expect(locator.isReservedCompanyId('_global')).toBe(true);
      expect(locator.isReservedCompanyId('.claude')).toBe(true);
    });

    it('现存公司 id 形态全部放行', () => {
      for (const id of ['mycompany', 'co-1', 'idearun', 'c-test', 'p2-verify', 'diag-co-2']) {
        expect(locator.isReservedCompanyId(id)).toBe(false);
      }
    });
  });
});