UNPKG

@boundless-oss/atlas

Version:

Atlas - MCP Server for comprehensive startup project management

222 lines (184 loc) 6.94 kB
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import { promises as fs } from 'fs'; import path from 'path'; import os from 'os'; import { ConfigManager } from '../config-manager.js'; import { AtlasConfig } from '../types.js'; describe('ConfigManager', () => { let tempDir: string; let configManager: ConfigManager; beforeEach(async () => { // Create a temporary directory for testing tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'atlas-test-')); process.chdir(tempDir); }); afterEach(async () => { // Clean up process.chdir('/'); await fs.rm(tempDir, { recursive: true, force: true }); }); describe('Configuration Loading', () => { it('should use default config when no config file exists', async () => { configManager = new ConfigManager(); await configManager.load(); const config = configManager.get(); expect(config.projectMode).toBe('new'); expect(config.features?.tddEnforcement).toBe('strict'); expect(config.storage?.mode).toBe('local'); }); it('should load config from atlas.config.json', async () => { const customConfig: Partial<AtlasConfig> = { projectMode: 'existing', projectName: 'test-project', features: { tddEnforcement: 'advisory', }, }; await fs.writeFile( path.join(tempDir, 'atlas.config.json'), JSON.stringify(customConfig) ); configManager = new ConfigManager(); await configManager.load(); const config = configManager.get(); expect(config.projectMode).toBe('existing'); expect(config.projectName).toBe('test-project'); expect(config.features?.tddEnforcement).toBe('advisory'); }); it('should merge custom config with defaults', async () => { const customConfig: Partial<AtlasConfig> = { projectMode: 'multi-repo', }; await fs.writeFile( path.join(tempDir, 'atlas.config.json'), JSON.stringify(customConfig) ); configManager = new ConfigManager(); await configManager.load(); const config = configManager.get(); expect(config.projectMode).toBe('multi-repo'); expect(config.features?.tddEnforcement).toBe('strict'); // Default value }); }); describe('Project Detection', () => { it('should detect a new project', async () => { configManager = new ConfigManager(); const detection = await configManager.detectProject(); expect(detection.hasGit).toBe(false); expect(detection.hasPackageJson).toBe(false); expect(detection.suggestedMode).toBe('new'); }); it('should detect an existing Node.js project', async () => { // Create git directory await fs.mkdir(path.join(tempDir, '.git')); // Create package.json await fs.writeFile( path.join(tempDir, 'package.json'), JSON.stringify({ name: 'test-project', devDependencies: { jest: '^29.0.0', }, }) ); configManager = new ConfigManager(); const detection = await configManager.detectProject(); expect(detection.hasGit).toBe(true); expect(detection.hasPackageJson).toBe(true); expect(detection.hasTests).toBe(true); expect(detection.testFramework).toBe('jest'); expect(detection.suggestedMode).toBe('existing'); }); it('should detect a multi-repo project', async () => { // Create multiple subdirectories with package.json files await fs.mkdir(path.join(tempDir, 'frontend')); await fs.mkdir(path.join(tempDir, 'backend')); await fs.writeFile( path.join(tempDir, 'frontend', 'package.json'), JSON.stringify({ name: 'frontend' }) ); await fs.writeFile( path.join(tempDir, 'backend', 'package.json'), JSON.stringify({ name: 'backend' }) ); configManager = new ConfigManager(); const detection = await configManager.detectProject(); expect(detection.suggestedMode).toBe('multi-repo'); }); }); describe('Storage Path Resolution', () => { it('should use local storage by default', async () => { configManager = new ConfigManager(); await configManager.load(); const storagePath = configManager.getDataPath(); expect(storagePath).toContain('.atlas'); expect(storagePath.endsWith('.atlas')).toBe(true); }); it('should use home directory storage when configured', async () => { configManager = new ConfigManager(); configManager.set({ projectName: 'test-project', storage: { mode: 'home', isolation: 'project', }, }); const storagePath = configManager.getDataPath(); expect(storagePath).toBe( path.join(os.homedir(), '.atlas', 'projects', 'test-project') ); }); it('should use custom storage path when configured', async () => { const customPath = '/custom/storage/path'; configManager = new ConfigManager(); configManager.set({ storage: { mode: 'custom', path: customPath, }, }); const storagePath = configManager.getDataPath(); expect(storagePath).toBe(customPath); }); }); describe('Module Management', () => { it('should enable all modules by default', async () => { configManager = new ConfigManager(); await configManager.load(); expect(configManager.isModuleEnabled('kanban')).toBe(true); expect(configManager.isModuleEnabled('development')).toBe(true); expect(configManager.isModuleEnabled('documentation')).toBe(true); }); it('should respect module configuration', async () => { configManager = new ConfigManager(); configManager.set({ integration: { modules: { kanban: true, development: false, documentation: true, }, }, }); expect(configManager.isModuleEnabled('kanban')).toBe(true); expect(configManager.isModuleEnabled('development')).toBe(false); expect(configManager.isModuleEnabled('documentation')).toBe(true); }); }); describe('Configuration Persistence', () => { it('should save configuration to file', async () => { configManager = new ConfigManager(); configManager.set({ projectMode: 'existing', projectName: 'saved-project', }); await configManager.save(); // Verify file was created const savedConfig = JSON.parse( await fs.readFile(path.join(tempDir, 'atlas.config.json'), 'utf-8') ); expect(savedConfig.projectMode).toBe('existing'); expect(savedConfig.projectName).toBe('saved-project'); }); }); });