UNPKG

@masonator/coolify-mcp

Version:

MCP server implementation for Coolify

141 lines (140 loc) 7.2 kB
/** * Integration tests for diagnostic tools. * * These tests hit the real Coolify API to verify diagnostic methods work correctly. * They are skipped in CI and should be run manually when testing against a real instance. * * Prerequisites: * - COOLIFY_URL and COOLIFY_TOKEN environment variables set (from .env) * - Access to a running Coolify instance * * Run with: npm run test:integration */ import { config } from 'dotenv'; import { CoolifyClient } from '../../lib/coolify-client.js'; // Load environment variables from .env file config(); const COOLIFY_URL = process.env.COOLIFY_URL; const COOLIFY_TOKEN = process.env.COOLIFY_TOKEN; // Skip all tests if environment variables are not set const shouldRun = COOLIFY_URL && COOLIFY_TOKEN; // Test data - UUIDs from actual infrastructure // These should be updated to match your test environment const TEST_DATA = { // Server: coolify-apps (running, reachable) SERVER_UUID: 'ggkk8w4c08gw48oowsg4g0oc', // Application: test-system (running) APP_UUID_HEALTHY: 'xs0sgs4gog044s4k4c88kgsc', // Application: Bumnail Benerator (exited:unhealthy) APP_UUID_UNHEALTHY: 't444wg40s4kkwcc04s084wgw', }; const describeFn = shouldRun ? describe : describe.skip; describeFn('Diagnostic Integration Tests', () => { let client; beforeAll(() => { if (!COOLIFY_URL || !COOLIFY_TOKEN) { throw new Error('COOLIFY_URL and COOLIFY_TOKEN must be set for integration tests'); } client = new CoolifyClient({ baseUrl: COOLIFY_URL, accessToken: COOLIFY_TOKEN, }); }); describe('diagnoseApplication', () => { it('should return diagnostic data for a healthy application', async () => { const result = await client.diagnoseApplication(TEST_DATA.APP_UUID_HEALTHY); // Should have application info expect(result.application).not.toBeNull(); expect(result.application?.uuid).toBe(TEST_DATA.APP_UUID_HEALTHY); expect(result.application?.name).toBeDefined(); // Should have health assessment expect(result.health).toBeDefined(); expect(['healthy', 'unhealthy', 'unknown']).toContain(result.health.status); // Should have environment variables (even if empty) expect(result.environment_variables).toBeDefined(); expect(typeof result.environment_variables.count).toBe('number'); expect(Array.isArray(result.environment_variables.variables)).toBe(true); // Values should be hidden (only key and is_build_time exposed) if (result.environment_variables.variables.length > 0) { const firstVar = result.environment_variables.variables[0]; expect(firstVar).toHaveProperty('key'); expect(firstVar).toHaveProperty('is_build_time'); expect(firstVar).not.toHaveProperty('value'); } // Should have recent deployments array expect(Array.isArray(result.recent_deployments)).toBe(true); // Should not have errors if all calls succeeded // (errors array might be present if some endpoints failed) console.log('Healthy app diagnostic result:', JSON.stringify(result, null, 2)); }, 30000); it('should detect issues in an unhealthy application', async () => { const result = await client.diagnoseApplication(TEST_DATA.APP_UUID_UNHEALTHY); expect(result.application).not.toBeNull(); // Should detect unhealthy status if (result.application?.status?.includes('exited') || result.application?.status?.includes('unhealthy')) { expect(result.health.status).toBe('unhealthy'); expect(result.health.issues.length).toBeGreaterThan(0); } console.log('Unhealthy app diagnostic result:', JSON.stringify(result, null, 2)); }, 30000); it('should handle non-existent application gracefully', async () => { const result = await client.diagnoseApplication('non-existent-uuid'); // Should have errors but not throw expect(result.errors).toBeDefined(); expect(result.errors.length).toBeGreaterThan(0); expect(result.application).toBeNull(); }, 30000); }); describe('diagnoseServer', () => { it('should return diagnostic data for a server', async () => { const result = await client.diagnoseServer(TEST_DATA.SERVER_UUID); // Should have server info expect(result.server).not.toBeNull(); expect(result.server?.uuid).toBe(TEST_DATA.SERVER_UUID); expect(result.server?.name).toBeDefined(); expect(result.server?.ip).toBeDefined(); // Should have health assessment expect(result.health).toBeDefined(); expect(['healthy', 'unhealthy', 'unknown']).toContain(result.health.status); // Should have resources array expect(Array.isArray(result.resources)).toBe(true); // Should have domains array expect(Array.isArray(result.domains)).toBe(true); // Should have validation result expect(result.validation).toBeDefined(); console.log('Server diagnostic result:', JSON.stringify(result, null, 2)); }, 30000); it('should handle non-existent server gracefully', async () => { const result = await client.diagnoseServer('non-existent-uuid'); expect(result.errors).toBeDefined(); expect(result.errors.length).toBeGreaterThan(0); expect(result.server).toBeNull(); }, 30000); }); describe('findInfrastructureIssues', () => { it('should return infrastructure issues report', async () => { const result = await client.findInfrastructureIssues(); // Should have summary expect(result.summary).toBeDefined(); expect(typeof result.summary.total_issues).toBe('number'); expect(typeof result.summary.unhealthy_applications).toBe('number'); expect(typeof result.summary.unhealthy_databases).toBe('number'); expect(typeof result.summary.unhealthy_services).toBe('number'); expect(typeof result.summary.unreachable_servers).toBe('number'); // Should have issues array expect(Array.isArray(result.issues)).toBe(true); // Each issue should have required fields for (const issue of result.issues) { expect(['application', 'database', 'service', 'server']).toContain(issue.type); expect(issue.uuid).toBeDefined(); expect(issue.name).toBeDefined(); expect(issue.issue).toBeDefined(); expect(issue.status).toBeDefined(); } // Summary counts should match issues array expect(result.summary.total_issues).toBe(result.issues.length); console.log('Infrastructure issues report:', JSON.stringify(result, null, 2)); }, 60000); }); });