task-master-neo-sdlc
Version:
Enhanced task management system with Neo SDLC agents and MCP tools for comprehensive, AI-driven software development lifecycle management.
150 lines (126 loc) • 5.97 kB
JavaScript
import { BackendDevelopmentAgent } from '../backend-developer';
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 = {};
// Mock potential DatabaseManagerAgent if used
// const mockDatabaseManager = { planSchemaMigration: jest.fn() };
describe('BackendDevelopmentAgent', () => {
let agent;
beforeEach(() => {
jest.clearAllMocks();
agent = new BackendDevelopmentAgent(mockKnowledgeGraph, mockWorkflow /*, mockDatabaseManager */);
jest.spyOn(console, 'log').mockImplementation(() => {});
});
afterEach(() => {
console.log.mockRestore();
});
it('should create an API endpoint definition', async () => {
const path = '/api/items';
const method = 'POST';
const description = 'Create a new item';
const reqSchema = { type: 'object', properties: { name: { type: 'string' } } };
const resSchema = { type: 'object', properties: { id: { type: 'string' } } };
const expectedId = 'api_endpoint:POST:_api_items';
mockKnowledgeGraph.addNode.mockResolvedValue(undefined);
const endpointData = await agent.createApiEndpoint(path, method, description, reqSchema, resSchema);
expect(endpointData).toBeDefined();
expect(endpointData.id).toBe(expectedId);
expect(endpointData.path).toBe(path);
expect(endpointData.method).toBe(method);
expect(endpointData.status).toBe('defined');
expect(mockKnowledgeGraph.addNode).toHaveBeenCalledWith({
id: expectedId,
type: 'api_endpoint',
data: endpointData
});
});
it('should implement API logic and update KG', async () => {
const endpointId = 'api_endpoint:GET:_api_users_:id';
const logic = '// Fetch user from DB by ID';
const dependencies = ['db_schema:user'];
const mockEndpointNode = {
id: endpointId,
type: 'api_endpoint',
data: { status: 'defined', description: 'Get user by ID' }
};
mockKnowledgeGraph.findNodes.mockResolvedValue([mockEndpointNode]);
mockKnowledgeGraph.updateContext.mockResolvedValue(undefined);
mockKnowledgeGraph.addEdge.mockResolvedValue(undefined);
const updatedData = await agent.implementApiLogic(endpointId, logic, dependencies);
expect(updatedData).toBeDefined();
expect(updatedData.status).toBe('implemented');
expect(updatedData.implementation).toBe(logic);
expect(updatedData.dependencies).toEqual(dependencies);
expect(mockKnowledgeGraph.findNodes).toHaveBeenCalledWith({ id: endpointId, type: 'api_endpoint' });
expect(mockKnowledgeGraph.updateContext).toHaveBeenCalledWith({
id: endpointId,
data: expect.objectContaining({ status: 'implemented', implementation: logic })
});
expect(mockKnowledgeGraph.addEdge).toHaveBeenCalledWith({
source: endpointId,
target: 'db_schema:user',
relationship: 'depends_on'
});
});
it('should throw error if endpoint not found when implementing logic', async () => {
const endpointId = 'api_endpoint:nonexistent';
mockKnowledgeGraph.findNodes.mockResolvedValue([]); // Simulate not found
await expect(agent.implementApiLogic(endpointId, 'some logic')).rejects.toThrow(
`API Endpoint ${endpointId} definition not found.`
);
});
it('should define a new database model', async () => {
const modelName = 'Product';
const schemaDef = { fields: { name: 'string', price: 'number' } };
const expectedSchemaId = 'db_schema:product';
mockKnowledgeGraph.findNodes.mockResolvedValue([]); // Simulate node doesn't exist
mockKnowledgeGraph.addNode.mockResolvedValue(undefined);
const schemaData = await agent.defineDatabaseModel(modelName, schemaDef);
expect(schemaData).toBeDefined();
expect(schemaData.id).toBe(expectedSchemaId);
expect(schemaData.modelName).toBe(modelName);
expect(schemaData.schema).toEqual(schemaDef);
expect(schemaData.version).toBe(1);
expect(mockKnowledgeGraph.findNodes).toHaveBeenCalledWith({ id: expectedSchemaId, type: 'db_schema' });
expect(mockKnowledgeGraph.addNode).toHaveBeenCalledWith({
id: expectedSchemaId,
type: 'db_schema',
data: schemaData
});
expect(mockKnowledgeGraph.updateContext).not.toHaveBeenCalled();
// Optionally check if migration planning was triggered (it shouldn't be for new models here)
// expect(mockDatabaseManager.planSchemaMigration).not.toHaveBeenCalled();
});
it('should update an existing database model and increment version', async () => {
const modelName = 'Order';
const schemaDef = { fields: { orderId: 'string', amount: 'number', status: 'string' } };
const expectedSchemaId = 'db_schema:order';
const mockExistingNode = {
id: expectedSchemaId,
type: 'db_schema',
data: { modelName, schema: { fields: { orderId: 'string' } }, version: 2 }
};
mockKnowledgeGraph.findNodes.mockResolvedValue([mockExistingNode]); // Simulate node exists
mockKnowledgeGraph.updateContext.mockResolvedValue(undefined);
const schemaData = await agent.defineDatabaseModel(modelName, schemaDef);
expect(schemaData).toBeDefined();
expect(schemaData.id).toBe(expectedSchemaId);
expect(schemaData.schema).toEqual(schemaDef);
expect(schemaData.version).toBe(3); // Incremented version
expect(mockKnowledgeGraph.findNodes).toHaveBeenCalledWith({ id: expectedSchemaId, type: 'db_schema' });
expect(mockKnowledgeGraph.updateContext).toHaveBeenCalledWith({
id: expectedSchemaId,
data: schemaData
});
expect(mockKnowledgeGraph.addNode).not.toHaveBeenCalled();
// Optionally check if migration planning was triggered
// expect(mockDatabaseManager.planSchemaMigration).toHaveBeenCalledWith(expectedSchemaId, expectedSchemaId);
});
});