Skip to main content
Glama
mlaurel

Structured Workflow Engine MCP Server

by mlaurel
context-system.test.ts15.2 kB
import { describe, test, expect, beforeAll } from '@jest/globals'; import { selectWorkflowHandler } from '../../src/lib/mcp-tools/select-workflow'; import { getNextStepHandler } from '../../src/lib/mcp-tools/get-next-step'; import { StandardContext } from '../../src/lib/types/workflow-types'; // Test configuration const TEST_TIMEOUT = 30000; describe('Context System Integration Tests', () => { beforeAll(async () => { console.log('🧪 Starting Context System integration tests...'); }); describe('Available Context Parameter Tests', () => { test('should handle get_next_step without available_context', async () => { const result = await getNextStepHandler({ workflow_id: 'feature-development', current_step: 0 }); expect(result.content).toBeDefined(); expect(result.content[0].text).toMatch(/(Step|complete)/); // Should not contain context section when no context is provided expect(result.content[0].text).not.toContain('Available Context'); }, TEST_TIMEOUT); test('should handle get_next_step with empty available_context', async () => { const result = await getNextStepHandler({ workflow_id: 'feature-development', current_step: 0, available_context: [] }); expect(result.content).toBeDefined(); expect(result.content[0].text).toMatch(/(Step|complete)/); // Should not contain context section when context is empty expect(result.content[0].text).not.toContain('Available Context'); }, TEST_TIMEOUT); test('should handle get_next_step with single context', async () => { const result = await getNextStepHandler({ workflow_id: 'feature-development', current_step: 0, available_context: [StandardContext.REQUIREMENTS] }); expect(result.content).toBeDefined(); const stepText = result.content[0].text; if (!stepText.includes('100% complete')) { expect(stepText).toContain('Available Context'); expect(stepText).toContain('requirements'); expect(stepText).toContain('Context Note'); } }, TEST_TIMEOUT); test('should handle get_next_step with multiple contexts', async () => { const result = await getNextStepHandler({ workflow_id: 'feature-development', current_step: 2, available_context: [ StandardContext.REQUIREMENTS, StandardContext.CLARIFIED_REQUIREMENTS, StandardContext.TRD ] }); expect(result.content).toBeDefined(); const stepText = result.content[0].text; if (!stepText.includes('100% complete')) { expect(stepText).toContain('Available Context'); expect(stepText).toContain('requirements'); expect(stepText).toContain('clarified_requirements'); expect(stepText).toContain('trd'); expect(stepText).toContain('Context Note'); } }, TEST_TIMEOUT); }); describe('Context Requirements Display Tests', () => { test('should show workflow overview and context guidance for feature-development', async () => { const result = await selectWorkflowHandler({ workflow_id: 'feature-development' }); expect(result.content).toBeDefined(); const workflowText = result.content[0].text; expect(workflowText).toContain('Detailed Step Breakdown'); expect(workflowText).toContain('Context Gathering'); expect(workflowText).toContain('gather-requirements'); expect(workflowText).toContain('ask-clarifying-questions'); }, TEST_TIMEOUT); test('should show workflow overview and context guidance for trd-creation', async () => { const result = await selectWorkflowHandler({ workflow_id: 'trd-creation' }); expect(result.content).toBeDefined(); const workflowText = result.content[0].text; expect(workflowText).toContain('Detailed Step Breakdown'); expect(workflowText).toContain('Context Gathering'); expect(workflowText).toContain('create-trd'); }, TEST_TIMEOUT); test('should show workflow overview for all major workflows', async () => { const workflows = ['feature-development', 'trd-creation']; for (const workflowId of workflows) { const result = await selectWorkflowHandler({ workflow_id: workflowId }); const workflowText = result.content[0].text; expect(workflowText).toContain('Detailed Step Breakdown'); expect(workflowText).toContain('Context Gathering'); console.log(`✅ Workflow overview shown for ${workflowId}`); } }, TEST_TIMEOUT); }); describe('Context Modification Tests', () => { test('should modify mini-prompt when requirements context is available', async () => { const result = await getNextStepHandler({ workflow_id: 'feature-development', current_step: 1, // ask-clarifying-questions step available_context: [StandardContext.REQUIREMENTS] }); expect(result.content).toBeDefined(); const stepText = result.content[0].text; if (!stepText.includes('100% complete')) { expect(stepText).toContain('Available Context'); expect(stepText).toContain('requirements'); expect(stepText).toContain('Use existing requirements'); expect(stepText).toContain('Context Note'); } }, TEST_TIMEOUT); test('should modify mini-prompt when TRD context is available', async () => { const result = await getNextStepHandler({ workflow_id: 'feature-development', current_step: 5, // implement-feature step available_context: [ StandardContext.REQUIREMENTS, StandardContext.TRD, StandardContext.DESIGN_SPECIFICATIONS ] }); expect(result.content).toBeDefined(); const stepText = result.content[0].text; if (!stepText.includes('100% complete')) { expect(stepText).toContain('Available Context'); expect(stepText).toContain('trd'); expect(stepText).toContain('design_specifications'); expect(stepText).toContain('Context Note'); } }, TEST_TIMEOUT); test('should provide context-aware instructions', async () => { const result = await getNextStepHandler({ workflow_id: 'trd-creation', current_step: 0, available_context: [StandardContext.BUSINESS_REQUIREMENTS] }); expect(result.content).toBeDefined(); const stepText = result.content[0].text; if (!stepText.includes('100% complete')) { expect(stepText).toContain('Available Context'); expect(stepText).toContain('business_requirements'); expect(stepText).toContain('reference your existing documents'); } }, TEST_TIMEOUT); }); describe('Standard Context Enum Tests', () => { test('should have all expected context types', () => { // Requirements and Planning expect(StandardContext.REQUIREMENTS).toBe('requirements'); expect(StandardContext.CLARIFIED_REQUIREMENTS).toBe('clarified_requirements'); expect(StandardContext.BUSINESS_REQUIREMENTS).toBe('business_requirements'); expect(StandardContext.PRODUCT_VISION).toBe('product_vision'); // Analysis expect(StandardContext.FEATURE_ANALYSIS).toBe('feature_analysis'); expect(StandardContext.ARCHITECTURE_ANALYSIS).toBe('architecture_analysis'); expect(StandardContext.CODE_ANALYSIS).toBe('code_analysis'); expect(StandardContext.TECHNICAL_REQUIREMENTS).toBe('technical_requirements'); // Design expect(StandardContext.DESIGN_SPECIFICATIONS).toBe('design_specifications'); expect(StandardContext.TECHNICAL_ARCHITECTURE).toBe('technical_architecture'); expect(StandardContext.IMPLEMENTATION_PLAN).toBe('implementation_plan'); // Implementation expect(StandardContext.IMPLEMENTED_FEATURE).toBe('implemented_feature'); expect(StandardContext.IMPLEMENTED_FEATURES).toBe('implemented_features'); expect(StandardContext.COMPLETED_FEATURE).toBe('completed_feature'); // Testing expect(StandardContext.TEST_PLAN).toBe('test_plan'); expect(StandardContext.TESTED_FEATURE).toBe('tested_feature'); expect(StandardContext.VALIDATED_PRODUCT).toBe('validated_product'); // Documentation expect(StandardContext.TRD).toBe('trd'); expect(StandardContext.BRD_DOCUMENT).toBe('brd_document'); expect(StandardContext.DOCUMENTATION).toBe('documentation'); // Project Context expect(StandardContext.PROJECT_CODEBASE).toBe('project_codebase'); expect(StandardContext.EXISTING_CODEBASE).toBe('existing_codebase'); expect(StandardContext.SYSTEM_ARCHITECTURE).toBe('system_architecture'); console.log('✅ All standard context types are properly defined'); }); }); describe('Context Flow Tests', () => { test('should handle context flow in feature-development workflow', async () => { const workflowId = 'feature-development'; console.log(`\n🔄 Testing context flow for ${workflowId}`); // Step 0: gather-requirements (no context needed) const step0 = await getNextStepHandler({ workflow_id: workflowId, current_step: 0, available_context: [] }); if (!step0.content[0].text.includes('100% complete')) { expect(step0.content[0].text).not.toContain('Available Context'); console.log(' ✅ Step 0: No context required'); } // Step 1: ask-clarifying-questions (requires requirements) const step1 = await getNextStepHandler({ workflow_id: workflowId, current_step: 1, available_context: [StandardContext.REQUIREMENTS] }); if (!step1.content[0].text.includes('100% complete')) { expect(step1.content[0].text).toContain('Available Context'); expect(step1.content[0].text).toContain('requirements'); console.log(' ✅ Step 1: Requirements context utilized'); } // Step 2: feature-analysis (requires clarified_requirements) const step2 = await getNextStepHandler({ workflow_id: workflowId, current_step: 2, available_context: [ StandardContext.REQUIREMENTS, StandardContext.CLARIFIED_REQUIREMENTS ] }); if (!step2.content[0].text.includes('100% complete')) { expect(step2.content[0].text).toContain('Available Context'); expect(step2.content[0].text).toContain('clarified_requirements'); console.log(' ✅ Step 2: Clarified requirements context utilized'); } }, TEST_TIMEOUT); test('should handle context flow in trd-creation workflow', async () => { const workflowId = 'trd-creation'; console.log(`\n🔄 Testing context flow for ${workflowId}`); // Test with business requirements context const step0 = await getNextStepHandler({ workflow_id: workflowId, current_step: 0, available_context: [StandardContext.BUSINESS_REQUIREMENTS] }); if (!step0.content[0].text.includes('100% complete')) { expect(step0.content[0].text).toContain('Available Context'); expect(step0.content[0].text).toContain('business_requirements'); console.log(' ✅ TRD creation: Business requirements context utilized'); } // Test with multiple contexts - using step 1 instead of 3 to avoid workflow completion const step1 = await getNextStepHandler({ workflow_id: workflowId, current_step: 1, available_context: [ StandardContext.REQUIREMENTS, StandardContext.FEATURE_ANALYSIS, StandardContext.DESIGN_SPECIFICATIONS ] }); if (!step1.content[0].text.includes('100% complete')) { expect(step1.content[0].text).toContain('Available Context'); expect(step1.content[0].text).toContain('design_specifications'); console.log(' ✅ TRD creation: Multiple contexts utilized'); } }, TEST_TIMEOUT); }); describe('Error Handling with Context Tests', () => { test('should handle invalid context values gracefully', async () => { const result = await getNextStepHandler({ workflow_id: 'feature-development', current_step: 0, available_context: ['invalid_context', 'another_invalid'] }); expect(result.content).toBeDefined(); expect(result.content[0].text).toMatch(/(Step|complete)/); // Should still show available context even if invalid if (!result.content[0].text.includes('100% complete')) { expect(result.content[0].text).toContain('Available Context'); } }, TEST_TIMEOUT); test('should handle context with invalid workflow', async () => { const result = await getNextStepHandler({ workflow_id: 'invalid-workflow', current_step: 0, available_context: [StandardContext.REQUIREMENTS] }); expect(result.content).toBeDefined(); expect(result.content[0].text).toContain('not found'); }, TEST_TIMEOUT); }); describe('Context Integration with All Workflows', () => { const allWorkflowIds = [ 'code-refactoring', 'feature-development', 'product-development', 'project-initialization', 'quick-fix', 'trd-creation' ]; test.each(allWorkflowIds)('should handle context system for workflow: %s', async (workflowId) => { console.log(`\n🔄 Testing context system for ${workflowId}`); // Test select_workflow shows workflow overview and context guidance const selectResult = await selectWorkflowHandler({ workflow_id: workflowId }); expect(selectResult.content[0].text).toContain('Context Gathering'); // Test get_next_step with various contexts const contexts = [ StandardContext.REQUIREMENTS, StandardContext.TRD, StandardContext.DESIGN_SPECIFICATIONS ]; const stepResult = await getNextStepHandler({ workflow_id: workflowId, current_step: 0, available_context: contexts }); expect(stepResult.content).toBeDefined(); // If workflow is complete or has no executable steps, skip context checks if (stepResult.content[0].text.includes('Workflow Complete') || stepResult.content[0].text.includes('100% complete')) { console.log(` ✅ ${workflowId}: Workflow complete (no executable steps or completed)`); return; } // If not complete, should handle context properly // Note: Some workflows may have 0 executable steps, so Available Context may not appear if (!stepResult.content[0].text.includes('Cannot Execute') && contexts.length > 0) { expect(stepResult.content[0].text).toContain('Available Context'); } console.log(` ✅ Context system working for ${workflowId}`); }, TEST_TIMEOUT); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mlaurel/mcp-workflow-engine'

If you have feedback or need assistance with the MCP directory API, please join our Discord server