Files
claude-code/packages/builtin-tools/src/tools/RemoteTriggerTool/__tests__/RemoteTriggerTool.test.ts
claude-code-best 6a182e45b3 feat: 注册所有新命令到命令系统和工具注册表
- commands.ts: 注册所有新命令(memory-stores、vault、schedule 等),
  移除 require() 动态加载,统一为 ESM import
- tools.ts: 注册 LocalMemoryRecallTool、VaultHttpFetchTool
- 补充命令测试(bridge-kick、commit、commit-push-pr、init-verifiers)
- 补充工具测试(AgentTool、RemoteTrigger、SkillTool、WebFetch、WebSearch)
- 集成测试:autonomy-lifecycle-user-flow 更新
- 探测脚本和功能文档

Co-Authored-By: glm-5-turbo <zai-org@claude-code-best.win>
2026-05-09 23:04:39 +08:00

115 lines
3.1 KiB
TypeScript

import {
afterAll,
afterEach,
beforeAll,
beforeEach,
describe,
expect,
mock,
test,
} from 'bun:test'
import { authMock } from '../../../../../../tests/mocks/auth'
import { setupAxiosMock } from '../../../../../../tests/mocks/axios'
let requestStatus = 200
const auditRecords: Record<string, unknown>[] = []
const axiosHandle = setupAxiosMock()
axiosHandle.stubs.request = async () => ({
status: requestStatus,
data: { ok: requestStatus >= 200 && requestStatus < 300 },
})
beforeAll(() => {
axiosHandle.useStubs = true
})
afterAll(() => {
axiosHandle.useStubs = false
})
mock.module('src/utils/auth.js', authMock)
mock.module('src/services/oauth/client.js', () => ({
getOrganizationUUID: async () => 'org',
}))
mock.module('src/services/analytics/growthbook.js', () => ({
getFeatureValue_CACHED_MAY_BE_STALE: () => true,
}))
mock.module('src/services/policyLimits/index.js', () => ({
isPolicyAllowed: () => true,
}))
// Narrow mock for the side-effectful entries in `src/constants/oauth.js`.
// Pure data exports (ALL_OAUTH_SCOPES, CLAUDE_AI_*_SCOPE, etc.) come from
// the real module and are not mocked, per the test policy that constants
// modules without side effects should not be replaced wholesale.
mock.module('src/constants/oauth.js', () => {
const actual = require('../../../../../../src/constants/oauth.js')
return {
...actual,
fileSuffixForOauthConfig: () => '',
getOauthConfig: () => ({ BASE_API_URL: 'https://example.test' }),
MCP_CLIENT_METADATA_URL: 'https://example.test/oauth/metadata',
}
})
mock.module('src/utils/remoteTriggerAudit.js', () => ({
appendRemoteTriggerAuditRecord: async (record: Record<string, unknown>) => {
const fullRecord = {
auditId: `audit-${auditRecords.length + 1}`,
createdAt: Date.now(),
...record,
}
auditRecords.push(fullRecord)
return fullRecord
},
}))
beforeEach(() => {
requestStatus = 200
auditRecords.length = 0
})
afterEach(() => {
auditRecords.length = 0
})
describe('RemoteTriggerTool audit', () => {
test('writes an audit record for successful remote calls', async () => {
const { RemoteTriggerTool } = await import('../RemoteTriggerTool')
const result = await RemoteTriggerTool.call(
{ action: 'run', trigger_id: 'trigger-1' },
{ abortController: new AbortController() } as any,
)
expect(result.data.audit_id).toBeString()
expect(result.data.audit_id).toBe('audit-1')
expect(auditRecords).toHaveLength(1)
expect(auditRecords[0]).toMatchObject({
action: 'run',
triggerId: 'trigger-1',
ok: true,
status: 200,
})
})
test('writes an audit record before rethrowing validation failures', async () => {
const { RemoteTriggerTool } = await import('../RemoteTriggerTool')
await expect(
RemoteTriggerTool.call({ action: 'run' }, {
abortController: new AbortController(),
} as any),
).rejects.toThrow('run requires trigger_id')
expect(auditRecords).toHaveLength(1)
expect(auditRecords[0]).toMatchObject({
action: 'run',
ok: false,
error: 'run requires trigger_id',
})
})
})