import { describe, expect, it, jest } from '@jest/globals'; import type { AgentToolContext } from '../agent-tools/agent-tool.types'; import { AgentToolContextFactory } from '../agent-tools/agent-tool.types'; import type { AuthenticatedUser } from '../authorization'; import type { BusinessContextService } from './business-context.service'; import { GetBusinessContextTool, GetEntitySchemaTool } from './get-business-context.tool'; import { GetPendingTasksTool } from './get-pending-tasks.tool'; function context(permissions: string[] = []): AgentToolContext { const user: AuthenticatedUser = { id: 7, username: 'ops', permissions, isSuperAdmin: false, roles: [], }; return AgentToolContextFactory.fromAuthenticatedUser(user); } describe('agent business context tools', () => { it('get_business_context 校验 workflowKey 并透传主体与过滤条件', async () => { const service = { getBusinessContext: jest.fn().mockReturnValue({ workflows: [], entities: [] }), } as unknown as BusinessContextService; const tool = new GetBusinessContextTool(service); expect(tool.requiredPermission).toBe('ai:chat:use'); expect(tool.validate({ workflowKey: 123 }).ok).toBe(false); expect(tool.validate({ workflowKey: 'x'.repeat(51) }).ok).toBe(false); expect(tool.validate({ debug: true }).ok).toBe(false); const parsed = tool.validate({ workflowKey: 'dormitory_billing' }); expect(parsed.ok).toBe(true); if (!parsed.ok) return; const ctx = context(['occupancy:view']); await tool.execute(parsed.value, ctx); expect(service.getBusinessContext).toHaveBeenCalledWith( { permissions: ['occupancy:view'], isSuperAdmin: false }, 'dormitory_billing', ); }); it('get_entity_schema 必须提供存在的 entityKey', async () => { const service = { getEntitySchema: jest.fn().mockReturnValue({ key: 'student', name: '学生档案' }), } as unknown as BusinessContextService; const tool = new GetEntitySchemaTool(service); expect(tool.validate({}).ok).toBe(false); expect(tool.validate({ entityKey: '' }).ok).toBe(false); expect(tool.validate({ entityKey: 'student', extra: 1 }).ok).toBe(false); const parsed = tool.validate({ entityKey: 'student' }); expect(parsed.ok).toBe(true); if (!parsed.ok) return; await tool.execute(parsed.value, context()); expect(service.getEntitySchema).toHaveBeenCalledWith( { permissions: [], isSuperAdmin: false }, 'student', ); }); it('get_pending_tasks 只接受已知工作流 key', async () => { const service = { getPendingTasks: jest.fn().mockResolvedValue([]), }; const tool = new GetPendingTasksTool(service as never); expect(tool.requiredPermission).toBe('ai:chat:use'); expect(tool.validate({ workflowKey: 'unknown_loop' }).ok).toBe(false); expect(tool.validate({ workflowKey: 'dormitory_billing', limit: 1 }).ok).toBe(false); const parsed = tool.validate({ workflowKey: 'dormitory_billing' }); expect(parsed.ok).toBe(true); if (!parsed.ok) return; await tool.execute(parsed.value, context(['bill:view'])); expect(service.getPendingTasks).toHaveBeenCalledWith(expect.anything(), 'dormitory_billing'); }); });