task-master-neo-sdlc
Version:
Enhanced task management system with Neo SDLC agents and MCP tools for comprehensive, AI-driven software development lifecycle management.
265 lines (218 loc) • 7.51 kB
JavaScript
import { AgentWorkflowSystem } from '../agent-workflow.js';
import { KnowledgeGraph } from '../knowledge-graph.js';
jest.mock('../knowledge-graph.js');
describe('AgentWorkflowSystem', () => {
let workflow;
let mockGraph;
beforeEach(() => {
mockGraph = new KnowledgeGraph();
workflow = new AgentWorkflowSystem(mockGraph);
});
describe('registerAgent', () => {
it('should register agent with capabilities', () => {
const agent = {
id: 'agent-1',
capabilities: ['testing', 'documentation'],
knowledgeDomains: ['nodejs', 'jest']
};
workflow.registerAgent(agent);
const registered = workflow.agents.get('agent-1');
expect(registered).toBeDefined();
expect(registered.capabilities).toEqual(new Set(['testing', 'documentation']));
expect(registered.knowledgeDomains).toEqual(new Set(['nodejs', 'jest']));
expect(registered.status).toBe('idle');
expect(registered.metrics).toBeDefined();
});
it('should update existing agent', () => {
const agent = {
id: 'agent-1',
capabilities: ['testing']
};
workflow.registerAgent(agent);
workflow.registerAgent({
...agent,
capabilities: ['testing', 'deployment']
});
const updated = workflow.agents.get('agent-1');
expect(updated.capabilities).toEqual(new Set(['testing', 'deployment']));
});
});
describe('createWorkflow', () => {
it('should create workflow with steps', async () => {
const config = {
id: 'workflow-1',
steps: [
{
id: 'test',
type: 'testing',
requiredCapabilities: ['testing'],
requiredKnowledge: ['jest']
}
],
priority: 'high'
};
const result = await workflow.createWorkflow(config);
expect(result.id).toBe('workflow-1');
expect(result.steps).toHaveLength(1);
expect(result.status).toBe('pending');
expect(result.priority).toBe('high');
});
it('should validate step requirements', async () => {
const config = {
id: 'workflow-1',
steps: [
{
id: 'test',
type: 'testing'
// Missing required fields
}
]
};
await expect(workflow.createWorkflow(config))
.rejects.toThrow('Invalid step configuration');
});
});
describe('assignStep', () => {
beforeEach(async () => {
await workflow.createWorkflow({
id: 'workflow-1',
steps: [
{
id: 'test',
type: 'testing',
requiredCapabilities: ['testing'],
requiredKnowledge: ['jest']
}
]
});
workflow.registerAgent({
id: 'agent-1',
capabilities: ['testing'],
knowledgeDomains: ['jest']
});
});
it('should assign step to capable agent', async () => {
const result = await workflow.assignStep('workflow-1', 0, 'agent-1');
expect(result).toBe(true);
expect(workflow.agents.get('agent-1').status).toBe('busy');
const workflowStatus = await workflow.getWorkflowStatus('workflow-1');
expect(workflowStatus.steps[0].assignedTo).toBe('agent-1');
});
it('should validate agent capabilities', async () => {
workflow.registerAgent({
id: 'agent-2',
capabilities: ['deployment'],
knowledgeDomains: ['docker']
});
await expect(workflow.assignStep('workflow-1', 0, 'agent-2'))
.rejects.toThrow('Agent lacks required capabilities');
});
});
describe('completeStep', () => {
beforeEach(async () => {
await workflow.createWorkflow({
id: 'workflow-1',
steps: [
{
id: 'test',
type: 'testing',
requiredCapabilities: ['testing']
}
]
});
workflow.registerAgent({
id: 'agent-1',
capabilities: ['testing']
});
await workflow.assignStep('workflow-1', 0, 'agent-1');
});
it('should complete step and update metrics', async () => {
const result = {
data: 'test output',
quality: 0.9
};
await workflow.completeStep('workflow-1', 0, result);
const status = await workflow.getWorkflowStatus('workflow-1');
expect(status.steps[0].status).toBe('completed');
expect(status.steps[0].result).toEqual(result);
const agent = workflow.agents.get('agent-1');
expect(agent.status).toBe('idle');
expect(agent.metrics.tasksCompleted).toBe(1);
expect(agent.metrics.qualityScore).toBeGreaterThan(0);
});
it('should validate step result', async () => {
const invalidResult = {
// Missing required fields
};
await expect(workflow.completeStep('workflow-1', 0, invalidResult))
.rejects.toThrow('Invalid step result');
});
});
describe('handleStepFailure', () => {
beforeEach(async () => {
await workflow.createWorkflow({
id: 'workflow-1',
steps: [
{
id: 'test',
type: 'testing',
requiredCapabilities: ['testing']
}
]
});
workflow.registerAgent({
id: 'agent-1',
capabilities: ['testing']
});
await workflow.assignStep('workflow-1', 0, 'agent-1');
});
it('should handle step failure and update metrics', async () => {
const error = new Error('Test failed');
await workflow.handleStepFailure('workflow-1', 0, error);
const status = await workflow.getWorkflowStatus('workflow-1');
expect(status.steps[0].status).toBe('failed');
expect(status.steps[0].error).toBeDefined();
const agent = workflow.agents.get('agent-1');
expect(agent.status).toBe('idle');
expect(agent.metrics.tasksFailed).toBe(1);
expect(agent.metrics.successRate).toBeLessThan(1);
});
it('should attempt retry if available', async () => {
const error = new Error('Temporary failure');
workflow.registerAgent({
id: 'agent-2',
capabilities: ['testing']
});
await workflow.handleStepFailure('workflow-1', 0, error, { retry: true });
const status = await workflow.getWorkflowStatus('workflow-1');
expect(status.steps[0].status).toBe('pending');
expect(status.steps[0].retries).toBe(1);
});
});
describe('getAgentStatus', () => {
beforeEach(() => {
workflow.registerAgent({
id: 'agent-1',
capabilities: ['testing']
});
});
it('should return agent status with metrics', async () => {
const status = await workflow.getAgentStatus('agent-1');
expect(status.id).toBe('agent-1');
expect(status.status).toBe('idle');
expect(status.metrics).toBeDefined();
expect(status.history).toBeDefined();
});
it('should include recent task history', async () => {
await workflow.createWorkflow({
id: 'workflow-1',
steps: [{ id: 'test', type: 'testing', requiredCapabilities: ['testing'] }]
});
await workflow.assignStep('workflow-1', 0, 'agent-1');
await workflow.completeStep('workflow-1', 0, { data: 'test', quality: 0.9 });
const status = await workflow.getAgentStatus('agent-1');
expect(status.history).toHaveLength(1);
expect(status.history[0].workflowId).toBe('workflow-1');
});
});
});