Files
UAS-SIG-WebGIS-Poverty-Mapping/TESTS.php
T
2026-06-13 13:38:52 +07:00

347 lines
12 KiB
PHP

<?php
/**
* WebGIS Poverty Mapping - Integration Tests
* Version: 1.0
* Description: Test suite for API endpoints
*/
error_reporting(E_ALL);
ini_set('display_errors', 1);
// Simple test framework
class TestRunner {
private $passed = 0;
private $failed = 0;
private $tests = [];
public function test($name, $callback) {
try {
$callback();
$this->passed++;
$this->tests[] = ['✓', $name];
} catch (Exception $e) {
$this->failed++;
$this->tests[] = ['✗', $name, $e->getMessage()];
}
}
public function assertEqual($actual, $expected, $message = '') {
if ($actual !== $expected) {
throw new Exception($message . " (expected: $expected, got: $actual)");
}
}
public function assertTrue($value, $message = '') {
if ($value !== true) {
throw new Exception($message);
}
}
public function assertFalse($value, $message = '') {
if ($value !== false) {
throw new Exception($message);
}
}
public function report() {
echo "\n=== TEST RESULTS ===\n";
echo "Passed: {$this->passed}\n";
echo "Failed: {$this->failed}\n";
echo "Total: " . ($this->passed + $this->failed) . "\n\n";
foreach ($this->tests as $test) {
if (count($test) === 2) {
echo "{$test[0]} {$test[1]}\n";
} else {
echo "{$test[0]} {$test[1]}: {$test[2]}\n";
}
}
echo "\n";
return $this->failed === 0;
}
}
// Database connection for tests
function getTestConnection() {
$conn = new mysqli("localhost", "root", "", "webgis_unified");
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$conn->set_charset("utf8mb4");
return $conn;
}
// Initialize test runner
$runner = new TestRunner();
// ============ Database Tests ============
$runner->test("Database Connection", function() use ($runner) {
$conn = getTestConnection();
$runner->assertTrue($conn !== null, "Database connection failed");
$conn->close();
});
$runner->test("Table data_unified Exists", function() use ($runner) {
$conn = getTestConnection();
$result = $conn->query("SHOW TABLES LIKE 'data_unified'");
$runner->assertTrue($result && $result->num_rows > 0, "Table data_unified not found");
$conn->close();
});
$runner->test("Table audit_log Exists", function() use ($runner) {
$conn = getTestConnection();
$result = $conn->query("SHOW TABLES LIKE 'audit_log'");
$runner->assertTrue($result && $result->num_rows > 0, "Table audit_log not found");
$conn->close();
});
$runner->test("Reference Tables Exist", function() use ($runner) {
$conn = getTestConnection();
$tables = ['ref_kondisi_rumah', 'ref_status_bantuan', 'ref_sumber_penghasilan'];
foreach ($tables as $table) {
$result = $conn->query("SHOW TABLES LIKE '$table'");
$runner->assertTrue($result && $result->num_rows > 0, "Table $table not found");
}
$conn->close();
});
// ============ Data Insertion Tests ============
$runner->test("Insert Point Feature", function() use ($runner) {
$conn = getTestConnection();
$sql = "INSERT INTO data_unified (tipe, nama, alamat, latitude, longitude, status)
VALUES ('point', 'Test Point', 'Jln Test', -0.0554, 109.3494, 'aktif')";
$runner->assertTrue($conn->query($sql) === TRUE, "Failed to insert point");
$conn->close();
});
$runner->test("Insert Worship Feature", function() use ($runner) {
$conn = getTestConnection();
$sql = "INSERT INTO data_unified (tipe, nama, jenis, alamat, latitude, longitude,
radius_meter, kapasitas, status)
VALUES ('worship', 'Test Masjid', 'Masjid', 'Jln Imam', -0.0554, 109.3494,
200, 500, 'aktif')";
$runner->assertTrue($conn->query($sql) === TRUE, "Failed to insert worship");
$conn->close();
});
$runner->test("Insert Poor House Feature", function() use ($runner) {
$conn = getTestConnection();
$sql = "INSERT INTO data_unified (tipe, nama_kepala_keluarga, alamat, latitude,
longitude, jumlah_anggota, kondisi_rumah, status)
VALUES ('poor_house', 'Budi Santoso', 'Jln Cendana', -0.0554, 109.3494,
5, 'BURUK', 'aktif')";
$runner->assertTrue($conn->query($sql) === TRUE, "Failed to insert poor_house");
$conn->close();
});
// ============ Data Retrieval Tests ============
$runner->test("Retrieve All Features", function() use ($runner) {
$conn = getTestConnection();
$result = $conn->query("SELECT COUNT(*) as count FROM data_unified");
$row = $result->fetch_assoc();
$runner->assertTrue($row['count'] >= 0, "Failed to count features");
$conn->close();
});
$runner->test("Retrieve Worship Features Only", function() use ($runner) {
$conn = getTestConnection();
$result = $conn->query("SELECT * FROM data_unified WHERE tipe = 'worship' LIMIT 1");
$runner->assertTrue($result !== FALSE, "Failed to retrieve worship features");
$conn->close();
});
$runner->test("Retrieve Poor House Features Only", function() use ($runner) {
$conn = getTestConnection();
$result = $conn->query("SELECT * FROM data_unified WHERE tipe = 'poor_house' LIMIT 1");
$runner->assertTrue($result !== FALSE, "Failed to retrieve poor_house features");
$conn->close();
});
// ============ Data Validation Tests ============
$runner->test("Validate Required Fields - tipe", function() use ($runner) {
$conn = getTestConnection();
$sql = "INSERT INTO data_unified (nama, alamat) VALUES ('Test', 'Jln Test')";
$result = $conn->query($sql);
$runner->assertFalse($result, "Should reject missing tipe");
$conn->close();
});
$runner->test("Validate Enum Values - tipe", function() use ($runner) {
$conn = getTestConnection();
$sql = "INSERT INTO data_unified (tipe, nama) VALUES ('invalid_type', 'Test')";
$result = $conn->query($sql);
$runner->assertFalse($result, "Should reject invalid tipe value");
$conn->close();
});
// ============ Data Update Tests ============
$runner->test("Update Feature Data", function() use ($runner) {
$conn = getTestConnection();
// Insert test data
$insert_sql = "INSERT INTO data_unified (tipe, nama, status) VALUES ('point', 'Update Test', 'aktif')";
if ($conn->query($insert_sql)) {
$id = $conn->insert_id;
// Update the data
$update_sql = "UPDATE data_unified SET nama = 'Updated Name' WHERE id = $id";
$result = $conn->query($update_sql);
$runner->assertTrue($result === TRUE, "Failed to update feature");
// Verify update
$verify_sql = "SELECT nama FROM data_unified WHERE id = $id";
$verify_result = $conn->query($verify_sql);
$row = $verify_result->fetch_assoc();
$runner->assertEqual($row['nama'], 'Updated Name', "Update verification failed");
}
$conn->close();
});
// ============ Data Deletion Tests ============
$runner->test("Soft Delete Feature (Status Change)", function() use ($runner) {
$conn = getTestConnection();
// Insert test data
$insert_sql = "INSERT INTO data_unified (tipe, nama, status) VALUES ('point', 'Delete Test', 'aktif')";
if ($conn->query($insert_sql)) {
$id = $conn->insert_id;
// Soft delete
$delete_sql = "UPDATE data_unified SET status = 'nonaktif' WHERE id = $id";
$result = $conn->query($delete_sql);
$runner->assertTrue($result === TRUE, "Failed to soft delete");
// Verify soft delete
$verify_sql = "SELECT status FROM data_unified WHERE id = $id";
$verify_result = $conn->query($verify_sql);
$row = $verify_result->fetch_assoc();
$runner->assertEqual($row['status'], 'nonaktif', "Soft delete verification failed");
}
$conn->close();
});
$runner->test("Hard Delete Feature", function() use ($runner) {
$conn = getTestConnection();
// Insert test data
$insert_sql = "INSERT INTO data_unified (tipe, nama) VALUES ('point', 'Hard Delete Test')";
if ($conn->query($insert_sql)) {
$id = $conn->insert_id;
// Hard delete
$delete_sql = "DELETE FROM data_unified WHERE id = $id";
$result = $conn->query($delete_sql);
$runner->assertTrue($result === TRUE, "Failed to hard delete");
// Verify hard delete
$verify_sql = "SELECT COUNT(*) as count FROM data_unified WHERE id = $id";
$verify_result = $conn->query($verify_sql);
$row = $verify_result->fetch_assoc();
$runner->assertEqual($row['count'], 0, "Hard delete verification failed");
}
$conn->close();
});
// ============ Audit Trail Tests ============
$runner->test("Audit Log Table Has Triggers", function() use ($runner) {
$conn = getTestConnection();
// Check triggers exist
$result = $conn->query("SHOW TRIGGERS LIKE 'trg_data_unified%'");
$runner->assertTrue($result && $result->num_rows > 0, "Triggers not found");
$conn->close();
});
$runner->test("Audit Log Records Insertions", function() use ($runner) {
$conn = getTestConnection();
// Clear audit log
$conn->query("DELETE FROM audit_log");
// Insert test data
$insert_sql = "INSERT INTO data_unified (tipe, nama) VALUES ('point', 'Audit Test')";
$conn->query($insert_sql);
// Check if audit logged
$audit_result = $conn->query("SELECT COUNT(*) as count FROM audit_log WHERE action = 'INSERT'");
$row = $audit_result->fetch_assoc();
$runner->assertTrue($row['count'] > 0, "Audit trail not recording insertions");
$conn->close();
});
// ============ Query Performance Tests ============
$runner->test("Query Performance - Count Records", function() use ($runner) {
$conn = getTestConnection();
$start_time = microtime(true);
$result = $conn->query("SELECT COUNT(*) FROM data_unified");
$end_time = microtime(true);
$duration = ($end_time - $start_time) * 1000; // milliseconds
$runner->assertTrue($duration < 1000, "Query too slow: {$duration}ms");
$conn->close();
});
$runner->test("Query Performance - Filter by Type", function() use ($runner) {
$conn = getTestConnection();
$start_time = microtime(true);
$result = $conn->query("SELECT * FROM data_unified WHERE tipe = 'worship' LIMIT 100");
$end_time = microtime(true);
$duration = ($end_time - $start_time) * 1000;
$runner->assertTrue($duration < 1000, "Filter query too slow: {$duration}ms");
$conn->close();
});
// ============ Reference Data Tests ============
$runner->test("Reference Data - Kondisi Rumah", function() use ($runner) {
$conn = getTestConnection();
$result = $conn->query("SELECT COUNT(*) as count FROM ref_kondisi_rumah");
$row = $result->fetch_assoc();
$runner->assertTrue($row['count'] === 4, "Kondisi Rumah reference data incomplete");
$conn->close();
});
$runner->test("Reference Data - Status Bantuan", function() use ($runner) {
$conn = getTestConnection();
$result = $conn->query("SELECT COUNT(*) as count FROM ref_status_bantuan");
$row = $result->fetch_assoc();
$runner->assertTrue($row['count'] === 4, "Status Bantuan reference data incomplete");
$conn->close();
});
$runner->test("Reference Data - Sumber Penghasilan", function() use ($runner) {
$conn = getTestConnection();
$result = $conn->query("SELECT COUNT(*) as count FROM ref_sumber_penghasilan");
$row = $result->fetch_assoc();
$runner->assertTrue($row['count'] === 8, "Sumber Penghasilan reference data incomplete");
$conn->close();
});
// ============ Views Tests ============
$runner->test("View - v_data_summary Exists", function() use ($runner) {
$conn = getTestConnection();
$result = $conn->query("SELECT * FROM v_data_summary LIMIT 1");
$runner->assertTrue($result !== FALSE, "View v_data_summary not found");
$conn->close();
});
$runner->test("View - v_poor_house_analysis Exists", function() use ($runner) {
$conn = getTestConnection();
$result = $conn->query("SELECT * FROM v_poor_house_analysis LIMIT 1");
$runner->assertTrue($result !== FALSE, "View v_poor_house_analysis not found");
$conn->close();
});
// Display test results
$success = $runner->report();
// Return exit code
exit($success ? 0 : 1);
?>