#!/usr/bin/env node /** * System Integration Test * Tests frontend → backend → database connectivity */ const http = require("http"); const https = require("https"); const tests = []; const results = { passed: 0, failed: 0, errors: [], }; // Test configuration const BACKEND_URL = "http://localhost:8080"; const FRONTEND_URL = "http://localhost:5100"; const EXTERNAL_URL = "https://houseofprayer.ddns.net"; // Utility: Make HTTP request function makeRequest(url, options = {}) { return new Promise((resolve, reject) => { const client = url.startsWith("https") ? https : http; const req = client.request(url, options, (res) => { let data = ""; res.on("data", (chunk) => (data += chunk)); res.on("end", () => { resolve({ statusCode: res.statusCode, headers: res.headers, body: data, }); }); }); req.on("error", reject); req.on("timeout", () => reject(new Error("Request timeout"))); req.setTimeout(5000); if (options.body) { req.write(options.body); } req.end(); }); } // Test: Backend health endpoint tests.push({ name: "Backend Health Check", async run() { const res = await makeRequest(`${BACKEND_URL}/health`); if (res.statusCode !== 200) { throw new Error(`Expected 200, got ${res.statusCode}`); } const data = JSON.parse(res.body); if (data.status !== "ok") { throw new Error(`Health check failed: ${data.status}`); } }, }); // Test: Backend songs API tests.push({ name: "Backend Songs API", async run() { const res = await makeRequest(`${BACKEND_URL}/api/songs`); if (res.statusCode !== 200) { throw new Error(`Expected 200, got ${res.statusCode}`); } const data = JSON.parse(res.body); if (!data.success) { throw new Error("API returned success=false"); } if (!Array.isArray(data.songs)) { throw new Error("Expected songs array"); } if (data.songs.length === 0) { throw new Error("No songs found in database"); } console.log(` ✓ Found ${data.songs.length} songs`); }, }); // Test: Backend profiles API tests.push({ name: "Backend Profiles API", async run() { const res = await makeRequest(`${BACKEND_URL}/api/profiles`); if (res.statusCode !== 200) { throw new Error(`Expected 200, got ${res.statusCode}`); } const data = JSON.parse(res.body); if (!data.success) { throw new Error("API returned success=false"); } if (!Array.isArray(data.profiles)) { throw new Error("Expected profiles array"); } console.log(` ✓ Found ${data.profiles.length} profiles`); }, }); // Test: Backend lists API tests.push({ name: "Backend Lists API", async run() { const res = await makeRequest(`${BACKEND_URL}/api/lists`); if (res.statusCode !== 200) { throw new Error(`Expected 200, got ${res.statusCode}`); } const data = JSON.parse(res.body); if (!data.success) { throw new Error("API returned success=false"); } if (!Array.isArray(data.lists)) { throw new Error("Expected lists array"); } console.log(` ✓ Found ${data.lists.length} worship lists`); }, }); // Test: Backend stats API tests.push({ name: "Backend Stats API", async run() { const res = await makeRequest(`${BACKEND_URL}/api/stats`); if (res.statusCode !== 200) { throw new Error(`Expected 200, got ${res.statusCode}`); } const data = JSON.parse(res.body); if (!data.success) { throw new Error("API returned success=false"); } if (!data.stats || typeof data.stats.songs !== "number") { throw new Error("Invalid stats format"); } console.log( ` ✓ Stats: ${data.stats.songs} songs, ${data.stats.profiles} profiles, ${data.stats.lists} lists`, ); }, }); // Test: Frontend serving tests.push({ name: "Frontend Server", async run() { const res = await makeRequest(FRONTEND_URL); if (res.statusCode !== 200) { throw new Error(`Expected 200, got ${res.statusCode}`); } if (!res.body.includes("")) { throw new Error("Invalid HTML response"); } if (!res.body.includes("Worship Platform")) { throw new Error("Missing expected content"); } }, }); // Test: External HTTPS access tests.push({ name: "External HTTPS Access", async run() { const res = await makeRequest(EXTERNAL_URL); if (res.statusCode !== 200) { throw new Error(`Expected 200, got ${res.statusCode}`); } if (!res.body.includes("")) { throw new Error("Invalid HTML response"); } }, }); // Test: CORS headers tests.push({ name: "CORS Configuration", async run() { const res = await makeRequest(`${BACKEND_URL}/api/songs`, { method: "OPTIONS", headers: { Origin: "https://houseofprayer.ddns.net", "Access-Control-Request-Method": "GET", }, }); if (!res.headers["access-control-allow-origin"]) { throw new Error("Missing CORS headers"); } }, }); // Run all tests async function runTests() { console.log("\n🔍 Running System Integration Tests...\n"); console.log("=".repeat(60)); for (const test of tests) { try { process.stdout.write(`\n${test.name}... `); await test.run(); console.log("✅ PASSED"); results.passed++; } catch (err) { console.log("❌ FAILED"); console.log(` Error: ${err.message}`); results.failed++; results.errors.push({ test: test.name, error: err.message }); } } // Summary console.log("\n" + "=".repeat(60)); console.log("\n📊 Test Summary:"); console.log(` ✅ Passed: ${results.passed}`); console.log(` ❌ Failed: ${results.failed}`); console.log(` 📈 Total: ${tests.length}`); if (results.failed > 0) { console.log("\n❌ FAILURES:"); results.errors.forEach(({ test, error }) => { console.log(` • ${test}: ${error}`); }); process.exit(1); } else { console.log("\n✅ All tests passed!"); console.log("\n🎉 System is fully operational!"); process.exit(0); } } // Run runTests().catch((err) => { console.error("\n💥 Fatal error:", err); process.exit(1); });