Initial commit
This commit is contained in:
@@ -0,0 +1,346 @@
|
||||
<?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);
|
||||
?>
|
||||
Reference in New Issue
Block a user