UNPKG

task-master-neo-sdlc

Version:

Enhanced task management system with Neo SDLC agents and MCP tools for comprehensive, AI-driven software development lifecycle management.

160 lines (131 loc) 6.37 kB
import { KnowledgeBaseManagerAgent } from '../knowledge-base-manager'; import { KnowledgeGraph } from '../../knowledge-graph'; // Adjust path import { AgentWorkflowSystem } from '../../agent-workflow'; // Adjust path // Mocks const mockKnowledgeGraph = { addNode: jest.fn(), findNodes: jest.fn(), updateContext: jest.fn(), addEdge: jest.fn() }; const mockWorkflow = {}; describe('KnowledgeBaseManagerAgent', () => { let agent; beforeEach(() => { jest.clearAllMocks(); agent = new KnowledgeBaseManagerAgent(mockKnowledgeGraph, mockWorkflow); jest.spyOn(console, 'log').mockImplementation(() => {}); }); afterEach(() => { console.log.mockRestore(); }); it('should create a knowledge base article', async () => { const title = 'Setup Guide'; const content = '# How to set up the project...'; const tags = ['setup', 'guide']; const relatedEntities = ['component:setup-wizard']; mockKnowledgeGraph.addNode.mockResolvedValue(undefined); const articleData = await agent.createArticle(title, content, tags, relatedEntities); expect(articleData).toBeDefined(); expect(articleData.id).toMatch(/^kb_article:setup-guide_/); expect(articleData.title).toBe(title); expect(articleData.content).toBe(content); expect(articleData.tags).toEqual(tags); expect(articleData.version).toBe(1); expect(mockKnowledgeGraph.addNode).toHaveBeenCalledWith({ id: articleData.id, type: 'kb_article', data: expect.objectContaining({ title, content, tags }), edges: [{ target: 'component:setup-wizard', relationship: 'documents' }] }); }); it('should update an existing knowledge base article', async () => { const articleId = 'kb_article:api-docs_123'; const updates = { content: 'Updated API documentation.', tags: ['api', 'docs', 'v2'] }; const mockExistingNode = { id: articleId, type: 'kb_article', data: { title: 'API Docs', content: 'Old content', tags: ['api'], version: 1 } }; mockKnowledgeGraph.findNodes.mockResolvedValue([mockExistingNode]); mockKnowledgeGraph.updateContext.mockResolvedValue(undefined); const updatedData = await agent.updateArticle(articleId, updates); expect(updatedData).toBeDefined(); expect(updatedData.content).toBe(updates.content); expect(updatedData.tags).toEqual(updates.tags); expect(updatedData.version).toBe(2); expect(updatedData.updatedAt).not.toBe(mockExistingNode.data.updatedAt); expect(mockKnowledgeGraph.findNodes).toHaveBeenCalledWith({ id: articleId, type: 'kb_article' }); expect(mockKnowledgeGraph.updateContext).toHaveBeenCalledWith({ id: articleId, data: expect.objectContaining({ content: updates.content, tags: updates.tags, version: 2 }) }); }); it('should throw error if article not found during update', async () => { const articleId = 'kb_article:nonexistent'; mockKnowledgeGraph.findNodes.mockResolvedValue([]); // Simulate not found await expect(agent.updateArticle(articleId, { content: 'new' })).rejects.toThrow( `Knowledge base article ${articleId} not found.` ); }); it('should search articles by query (title/tag/content match)', async () => { const mockArticles = [ { id: 'kb:1', data: { title: 'Database Setup', tags: ['db', 'setup'], content: 'Guide...' } }, { id: 'kb:2', data: { title: 'API Endpoints', tags: ['api'], content: 'List of endpoints...' } }, { id: 'kb:3', data: { title: 'Frontend Components', tags: ['ui', 'react'], content: 'About the Button setup.' } } ]; mockKnowledgeGraph.findNodes.mockResolvedValue(mockArticles); const results = await agent.searchArticles('setup'); expect(results).toBeDefined(); expect(results.length).toBe(2); // Matches title/tag in kb:1, content in kb:3 expect(results[0].title).toBe('Database Setup'); expect(results[1].title).toBe('Frontend Components'); expect(mockKnowledgeGraph.findNodes).toHaveBeenCalledWith({ type: 'kb_article' }); }); it('should search articles filtering by tags', async () => { const mockArticles = [ { id: 'kb:1', data: { title: 'DB Guide', tags: ['db', 'setup'], content: '...' } }, { id: 'kb:2', data: { title: 'API Setup', tags: ['api', 'setup'], content: '...' } }, { id: 'kb:3', data: { title: 'UI Setup', tags: ['ui'], content: '...' } } ]; mockKnowledgeGraph.findNodes.mockResolvedValue(mockArticles); const results = await agent.searchArticles('setup', { tags: ['api'] }); expect(results.length).toBe(1); // Matches 'setup' in title/tag AND has 'api' tag expect(results[0].title).toBe('API Setup'); }); it('should limit search results', async () => { const mockArticles = Array.from({ length: 15 }, (_, i) => ( { id: `kb:${i}`, data: { title: `Article ${i}`, tags: ['search'], content: 'Content search term' } } )); mockKnowledgeGraph.findNodes.mockResolvedValue(mockArticles); const results = await agent.searchArticles('search', { limit: 5 }); expect(results.length).toBe(5); }); it('should link two articles', async () => { const sourceId = 'kb_article:source_1'; const targetId = 'kb_article:target_2'; const relationship = 'explains'; // Mock findNodes to confirm articles exist mockKnowledgeGraph.findNodes .mockResolvedValueOnce([{ id: sourceId, type: 'kb_article' }]) // Find source .mockResolvedValueOnce([{ id: targetId, type: 'kb_article' }]); // Find target mockKnowledgeGraph.addEdge.mockResolvedValue(undefined); await agent.linkArticles(sourceId, targetId, relationship); expect(mockKnowledgeGraph.addEdge).toHaveBeenCalledWith({ source: sourceId, target: targetId, relationship }); }); it('should throw error if article not found during linking', async () => { const sourceId = 'kb_article:exists'; const targetId = 'kb_article:notfound'; mockKnowledgeGraph.findNodes .mockResolvedValueOnce([{ id: sourceId, type: 'kb_article' }]) // Source exists .mockResolvedValueOnce([]); // Target does not exist await expect(agent.linkArticles(sourceId, targetId)).rejects.toThrow( `One or both articles not found for linking: ${sourceId}, ${targetId}` ); expect(mockKnowledgeGraph.addEdge).not.toHaveBeenCalled(); }); });