235 lines
6.1 KiB
JavaScript
235 lines
6.1 KiB
JavaScript
#!/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("<!doctype html>")) {
|
|
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("<!doctype html>")) {
|
|
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);
|
|
});
|