/** * Tests for workspacesListPlugin */ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; // Note: global mocks from src/__tests__/setup-vitest.ts provide container and logger import type { IPromptConcatPlugin } from '@services/agentInstance/promptConcat/promptConcatSchema'; import { container } from '@services/container'; import { logger } from '@services/libs/log'; import serviceIdentifier from '@services/serviceIdentifier'; import type { AgentHandlerContext } from '../../buildInAgentHandlers/type'; import type { AgentInstance } from '../../interface'; import type { PromptConcatHookContext } from '../types'; import type { IWorkspaceService } from '@services/workspaces/interface'; import { createHandlerHooks } from '../index'; import { workspacesListPlugin } from '../workspacesListPlugin'; describe('workspacesListPlugin', () => { beforeEach(async () => { vi.clearAllMocks(); }); afterEach(() => { vi.restoreAllMocks(); }); describe('workspaces list injection', () => { it('should inject workspaces list when plugin is configured', async () => { const hooks = createHandlerHooks(); workspacesListPlugin(hooks); const context: PromptConcatHookContext = { handlerContext: { agent: { id: 'test-agent', agentDefId: 'test-agent-def', messages: [], status: { state: 'working', modified: new Date() }, created: new Date(), } as AgentInstance, agentDef: { id: 'test-agent-def', name: 'test-agent-def' } as unknown, isCancelled: () => false, } as AgentHandlerContext, messages: [], prompts: [ { id: 'target-prompt', caption: 'Target Prompt', children: [], }, ], pluginConfig: { id: 'test-plugin', caption: 'Test Plugin', forbidOverrides: false, pluginId: 'workspacesList', workspacesListParam: { targetId: 'target-prompt', position: 'after' as const, }, } as unknown as IPromptConcatPlugin, }; await hooks.processPrompts.promise(context); const targetPrompt = context.prompts[0]; expect(targetPrompt.children).toHaveLength(1); // Default test fixtures contain test-wiki-1 / Test Wiki 1 expect(targetPrompt.children?.[0].text).toContain('Test Wiki 1'); expect(targetPrompt.children?.[0].text).toContain('Test Wiki 2'); expect(targetPrompt.children?.[0].text).toContain('test-wiki-1'); expect(targetPrompt.children?.[0].text).toContain('test-wiki-2'); }); it('should inject workspaces list when position is before', async () => { const hooks = createHandlerHooks(); workspacesListPlugin(hooks); const context: PromptConcatHookContext = { handlerContext: { agent: { id: 'test-agent', agentDefId: 'test-agent-def', messages: [], status: { state: 'working', modified: new Date() }, created: new Date(), } as AgentInstance, agentDef: { id: 'test-agent-def', name: 'test-agent-def' } as unknown, isCancelled: () => false, } as AgentHandlerContext, messages: [], prompts: [ { id: 'target-prompt', caption: 'Target Prompt', children: [], }, ], pluginConfig: { id: 'test-plugin', caption: 'Test Plugin', forbidOverrides: false, pluginId: 'workspacesList', workspacesListParam: { targetId: 'target-prompt', position: 'before' as const, }, } as unknown as IPromptConcatPlugin, }; await hooks.processPrompts.promise(context); const targetPrompt = context.prompts[0]; expect(targetPrompt.children).toHaveLength(1); expect(targetPrompt.children?.[0].text).toContain('- Test Wiki 1'); expect(targetPrompt.children?.[0].text).toContain('- Test Wiki 2'); }); it('should not inject content when plugin is not configured', async () => { const hooks = createHandlerHooks(); workspacesListPlugin(hooks); const context: PromptConcatHookContext = { handlerContext: { agent: { id: 'test-agent', agentDefId: 'test-agent-def', messages: [], status: { state: 'working', modified: new Date() }, created: new Date(), } as AgentInstance, agentDef: { id: 'test-agent-def', name: 'test-agent-def' } as unknown, isCancelled: () => false, } as AgentHandlerContext, messages: [], prompts: [ { id: 'target-prompt', caption: 'Target Prompt', children: [], }, ], pluginConfig: { id: 'test-plugin', pluginId: 'otherPlugin', forbidOverrides: false } as unknown as IPromptConcatPlugin, }; await hooks.processPrompts.promise(context); const targetPrompt = context.prompts[0]; expect(targetPrompt.children).toHaveLength(0); }); it('should handle empty workspaces list', async () => { // Override the workspace service implementation returned by the global container mock const workspaceService = container.get>(serviceIdentifier.Workspace); workspaceService.getWorkspacesAsList = vi.fn().mockResolvedValue([]) as unknown as IWorkspaceService['getWorkspacesAsList']; const hooks = createHandlerHooks(); workspacesListPlugin(hooks); const context: PromptConcatHookContext = { handlerContext: { agent: { id: 'test-agent', agentDefId: 'test-agent-def', messages: [], status: { state: 'working', modified: new Date() }, created: new Date(), } as AgentInstance, agentDef: { id: 'test-agent-def', name: 'test-agent-def' } as unknown, isCancelled: () => false, } as AgentHandlerContext, messages: [], prompts: [ { id: 'target-prompt', caption: 'Target Prompt', children: [], }, ], pluginConfig: { id: 'test-plugin', caption: 'Test Plugin', forbidOverrides: false, pluginId: 'workspacesList', workspacesListParam: { targetId: 'target-prompt', position: 'after' as const, }, } as unknown as IPromptConcatPlugin, }; await hooks.processPrompts.promise(context); const targetPrompt = context.prompts[0]; expect(targetPrompt.children).toHaveLength(0); expect(logger.debug).toHaveBeenCalledWith('No wiki workspaces found to inject', { pluginId: 'test-plugin', }); }); it('should warn when target prompt is not found', async () => { const hooks = createHandlerHooks(); workspacesListPlugin(hooks); const context: PromptConcatHookContext = { handlerContext: { agent: { id: 'test-agent', agentDefId: 'test-agent-def', messages: [], status: { state: 'working', modified: new Date() }, created: new Date(), } as AgentInstance, agentDef: { id: 'test-agent-def', name: 'test-agent-def' } as unknown, isCancelled: () => false, } as AgentHandlerContext, messages: [], prompts: [ { id: 'different-prompt', caption: 'Different Prompt', children: [], }, ], pluginConfig: { id: 'test-plugin', caption: 'Test Plugin', forbidOverrides: false, pluginId: 'workspacesList', workspacesListParam: { targetId: 'non-existent-prompt', position: 'after' as const, }, } as unknown as IPromptConcatPlugin, }; await hooks.processPrompts.promise(context); expect(logger.warn).toHaveBeenCalledWith('Workspaces list target prompt not found', { targetId: 'non-existent-prompt', pluginId: 'test-plugin', }); }); }); });