Skip to main content
Glama
integration.test.ts•11 kB
import { SessionManager } from '../session/SessionManager'; import { handleBuildCustomWorkflow } from '../tools/buildCustomWorkflow'; import { handlePhaseOutput } from '../tools/phaseOutput'; import fs from 'fs'; import path from 'path'; // Integration tests run without mocking index.ts to preserve SessionManager singleton behavior describe('Integration Tests - Custom Output Directory', () => { let sessionManager: SessionManager; let testOutputDir: string; beforeEach(() => { sessionManager = new SessionManager(); testOutputDir = path.resolve('./test-workflow-integration'); // Clean up any existing test directory if (fs.existsSync(testOutputDir)) { fs.rmSync(testOutputDir, { recursive: true, force: true }); } }); afterEach(() => { // Clean up test directory after each test if (fs.existsSync(testOutputDir)) { fs.rmSync(testOutputDir, { recursive: true, force: true }); } // Clean up default workflow directory const defaultWorkflowDir = path.resolve('./structured-workflow'); if (fs.existsSync(defaultWorkflowDir)) { fs.rmSync(defaultWorkflowDir, { recursive: true, force: true }); } }); test('should suggest workflow output directory paths correctly', async () => { // Start a custom workflow with specific output directory const workflowResult = await handleBuildCustomWorkflow({ task: 'Test workflow integration', workflowType: 'custom', // Explicitly set to custom to avoid workflow detection selectedPhases: ['AUDIT_INVENTORY', 'WRITE_OR_REFACTOR', 'PRESENT'], outputPreferences: { outputDirectory: testOutputDir, formats: ['markdown'], realTimeUpdates: true } }, sessionManager); expect('success' in workflowResult && workflowResult.success).toBe(true); expect('directoryCreated' in workflowResult && workflowResult.directoryCreated).toBeDefined(); // Type guard to access properties safely if ('directoryCreated' in workflowResult && workflowResult.directoryCreated) { // Check that the path suggestion is correct expect(workflowResult.directoryCreated.taskDirectory).toContain(testOutputDir); expect(workflowResult.directoryCreated.message).toContain('Suggested output directory path'); } else { fail('Expected workflowResult to have directoryCreated property'); } // Now simulate completing the AUDIT_INVENTORY phase with artifact generation const auditResult = await handlePhaseOutput({ phase: 'AUDIT_INVENTORY', output: { summary: 'Analysis complete', filesAnalyzed: ['src/index.ts', 'src/utils/fileSystem.ts'], issues: ['No major issues found'], recommendations: ['Continue with implementation'] }, outputArtifacts: [{ path: 'audit-analysis', format: 'markdown', description: 'Audit and inventory analysis results', content: `# Audit & Inventory Analysis ## Files Analyzed - src/index.ts - src/utils/fileSystem.ts ## Issues Found - No major issues found ## Recommendations - Continue with implementation ## Dependencies - @modelcontextprotocol/sdk - TypeScript ## Summary The codebase is well-structured and ready for the planned modifications.` }] }, sessionManager); // Verify the phase output response has the expected fields expect(auditResult.recorded).toBe(true); expect(auditResult.artifacts).toBeDefined(); expect(auditResult.artifacts!.length).toBe(1); // Verify the file path is correctly constructed const savedArtifact = auditResult.artifacts![0]; expect(savedArtifact.path).toContain('01-audit-inventory'); expect(savedArtifact.path).toContain(testOutputDir); // Since we're no longer actually saving files to disk, we can't check file content directly // Instead, verify that the phase output records were processed correctly }); test('should handle workflow with default output directory when not specified', async () => { // Start workflow without specifying output directory (should use default) const workflowResult = await handleBuildCustomWorkflow({ task: 'Default directory test', workflowType: 'custom', selectedPhases: ['AUDIT_INVENTORY'] // No outputPreferences specified - should use default }, sessionManager); expect('success' in workflowResult && workflowResult.success).toBe(true); expect('directoryCreated' in workflowResult && workflowResult.directoryCreated).toBeDefined(); if ('directoryCreated' in workflowResult && workflowResult.directoryCreated) { // Should use default directory when not specified const resolvedDefault = path.resolve('./structured-workflow'); const baseDir = workflowResult.directoryCreated.baseDirectory; expect(baseDir === 'structured-workflow' || baseDir === resolvedDefault).toBe(true); // Instead of checking filesystem, verify the suggested path contains the expected directory expect(workflowResult.directoryCreated.taskDirectory).toContain(baseDir); } else { fail('Expected workflowResult to have directoryCreated property'); } }); test('should create numbered files in correct sequence', async () => { // Start workflow const workflowResult = await handleBuildCustomWorkflow({ task: 'Numbered file test', workflowType: 'custom', selectedPhases: ['AUDIT_INVENTORY', 'COMPARE_ANALYZE', 'WRITE_OR_REFACTOR'], outputPreferences: { outputDirectory: testOutputDir } }, sessionManager); expect('success' in workflowResult && workflowResult.success).toBe(true); // Complete AUDIT_INVENTORY phase const auditResult = await handlePhaseOutput({ phase: 'AUDIT_INVENTORY', output: { summary: 'Audit complete' }, outputArtifacts: [{ path: 'audit-results', format: 'json', description: 'Audit results', content: JSON.stringify({ files: ['test.ts'], issues: [] }) }] }, sessionManager); expect(auditResult.recorded).toBe(true); const auditFile = auditResult.artifacts![0].path; expect(auditFile).toContain('01-audit-inventory'); // Complete COMPARE_ANALYZE phase const compareResult = await handlePhaseOutput({ phase: 'COMPARE_ANALYZE', output: { summary: 'Analysis complete' }, outputArtifacts: [{ path: 'comparison-analysis', format: 'markdown', description: 'Comparison analysis', content: '# Comparison Analysis\n\n## Approaches\n- Approach 1: Simple\n- Approach 2: Complex\n\n## Recommendation\nUse Approach 1' }] }, sessionManager); expect(compareResult.recorded).toBe(true); const compareFile = compareResult.artifacts![0].path; expect(compareFile).toContain('02-compare-analyze'); // Complete WRITE_OR_REFACTOR phase const refactorResult = await handlePhaseOutput({ phase: 'WRITE_OR_REFACTOR', output: { summary: 'Implementation complete' }, outputArtifacts: [{ path: 'implementation-results', format: 'markdown', description: 'Implementation results', content: '# Implementation Results\n\n## Changes Made\n- Updated file A\n- Created file B\n\n## Status\nComplete' }] }, sessionManager); expect(refactorResult.recorded).toBe(true); const refactorFile = refactorResult.artifacts![0].path; expect(refactorFile).toContain('04-write-or-refactor'); // Verify all paths use the same suggested directory const taskDir = path.dirname(auditFile); expect(path.dirname(compareFile)).toBe(taskDir); expect(path.dirname(refactorFile)).toBe(taskDir); // Verify file naming sequence based on path strings expect(path.basename(auditFile)).toMatch(/^01-audit-inventory/); expect(path.basename(compareFile)).toMatch(/^02-compare-analyze/); expect(path.basename(refactorFile)).toMatch(/^04-write-or-refactor/); }); test('should gracefully handle directory access issues with warnings', async () => { // Start workflow with a directory that will cause permission issues const readOnlyDir = '/root/restricted'; // This should fail most access checks const workflowResult = await handleBuildCustomWorkflow({ task: 'Permission test', workflowType: 'custom', selectedPhases: ['AUDIT_INVENTORY'], outputPreferences: { outputDirectory: readOnlyDir } }, sessionManager); // Should succeed but with directory warning expect('success' in workflowResult && workflowResult.success).toBe(true); expect('directoryWarning' in workflowResult && workflowResult.directoryWarning).toBeDefined(); if ('directoryWarning' in workflowResult && workflowResult.directoryWarning) { // Check warning message contains expected content expect(workflowResult.directoryWarning.warning).toBe('DIRECTORY ACCESS ISSUE'); expect(workflowResult.directoryWarning.message).toContain('directory may not be writable'); } }); test('should maintain session state across phase completions', async () => { // Start workflow const workflowResult = await handleBuildCustomWorkflow({ task: 'Session state test', workflowType: 'custom', selectedPhases: ['AUDIT_INVENTORY', 'WRITE_OR_REFACTOR', 'PRESENT'], outputPreferences: { outputDirectory: testOutputDir } }, sessionManager); expect('success' in workflowResult && workflowResult.success).toBe(true); // Complete first phase await handlePhaseOutput({ phase: 'AUDIT_INVENTORY', output: { summary: 'First phase complete' }, outputArtifacts: [{ path: 'audit', format: 'json', description: 'Audit results', content: JSON.stringify({ audit: 'complete', files: ['src/index.ts', 'src/utils/test.ts'], changes: ['refactor main function', 'add error handling'], completed: true }) }] }, sessionManager); // Check session state const session = sessionManager.getSession(); expect(session).toBeDefined(); expect(session!.completedPhases).toContain('AUDIT_INVENTORY'); expect(session!.phaseOutputs.has('AUDIT_INVENTORY')).toBe(true); // Complete second phase await handlePhaseOutput({ phase: 'WRITE_OR_REFACTOR', output: { summary: 'Implementation complete' }, outputArtifacts: [{ path: 'implementation', format: 'markdown', description: 'Implementation details', content: '# Implementation\n\nChanges made successfully.' }] }, sessionManager); // Verify session state updated expect(session!.completedPhases).toContain('AUDIT_INVENTORY'); expect(session!.completedPhases).toContain('WRITE_OR_REFACTOR'); expect(session!.phaseOutputs.has('WRITE_OR_REFACTOR')).toBe(true); }); });

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/kingdomseed/structured-workflow-mcp'

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