2025-09-23 10:18:48 +07:00
|
|
|
<?php
|
|
|
|
|
|
2025-09-25 14:01:33 +07:00
|
|
|
namespace Tests\Feature\Patients;
|
2025-09-23 10:18:48 +07:00
|
|
|
|
|
|
|
|
use CodeIgniter\Test\FeatureTestTrait;
|
|
|
|
|
use CodeIgniter\Test\CIUnitTestCase;
|
2025-12-17 15:19:55 +07:00
|
|
|
use Faker\Factory;
|
2025-09-23 10:18:48 +07:00
|
|
|
|
2025-12-17 15:19:55 +07:00
|
|
|
/**
|
|
|
|
|
* PatientDeleteTest
|
|
|
|
|
*
|
|
|
|
|
* Test cases for Patient DELETE endpoint
|
|
|
|
|
* Endpoint: DELETE api/patient
|
|
|
|
|
*
|
|
|
|
|
* Test Cases:
|
|
|
|
|
* 1. testDeleteWithoutInternalPID - 500 error when InternalPID not provided
|
|
|
|
|
* 2. testDeleteWithNullInternalPID - 400 error when InternalPID is null
|
|
|
|
|
* 3. testDeleteWithZeroInternalPID - 400 error when InternalPID is 0
|
|
|
|
|
* 4. testDeleteWithEmptyStringInternalPID - 400 error when InternalPID is empty string
|
|
|
|
|
* 5. testDeleteWithArrayInternalPID - 400 error when InternalPID is array
|
|
|
|
|
* 6. testDeleteNotFound - 404 error when patient not found
|
|
|
|
|
* 7. testDeleteSQLInjectionAttempt - 400 error when SQL injection attempted
|
|
|
|
|
* 8. testDeleteSuccess - 200 success when valid delete (commented - requires DB setup)
|
|
|
|
|
*/
|
2025-09-23 10:18:48 +07:00
|
|
|
class PatientDeleteTest extends CIUnitTestCase
|
|
|
|
|
{
|
|
|
|
|
use FeatureTestTrait;
|
2025-12-17 15:19:55 +07:00
|
|
|
|
2025-09-25 14:01:33 +07:00
|
|
|
protected $endpoint = 'api/patient';
|
2025-09-23 10:18:48 +07:00
|
|
|
|
2025-12-17 15:19:55 +07:00
|
|
|
/**
|
|
|
|
|
* Test Case 1: Delete without InternalPID key
|
|
|
|
|
* Expected: 500 Internal Server Error (Undefined array key)
|
|
|
|
|
*/
|
|
|
|
|
public function testDeleteWithoutInternalPID()
|
|
|
|
|
{
|
|
|
|
|
$result = $this->withBodyFormat('json')
|
|
|
|
|
->delete($this->endpoint, []);
|
2025-09-25 14:01:33 +07:00
|
|
|
|
2025-12-17 15:19:55 +07:00
|
|
|
$result->assertStatus(500);
|
|
|
|
|
|
|
|
|
|
$json = $result->getJSON();
|
|
|
|
|
$data = json_decode($json, true);
|
|
|
|
|
|
|
|
|
|
$this->assertArrayHasKey('messages', $data);
|
|
|
|
|
}
|
2025-09-25 14:01:33 +07:00
|
|
|
|
2025-12-17 15:19:55 +07:00
|
|
|
/**
|
|
|
|
|
* Test Case 2: Delete with null InternalPID
|
|
|
|
|
* Expected: 400 Bad Request - Patient ID must be a valid integer
|
|
|
|
|
*/
|
|
|
|
|
public function testDeleteWithNullInternalPID()
|
|
|
|
|
{
|
|
|
|
|
$result = $this->withBodyFormat('json')
|
|
|
|
|
->delete($this->endpoint, [
|
|
|
|
|
'InternalPID' => null,
|
|
|
|
|
]);
|
2025-09-25 14:01:33 +07:00
|
|
|
|
2025-12-17 15:19:55 +07:00
|
|
|
$result->assertStatus(400);
|
|
|
|
|
$result->assertJSONFragment([
|
|
|
|
|
'status' => 'error',
|
|
|
|
|
'message' => 'Patient ID must be a valid integer.'
|
|
|
|
|
]);
|
|
|
|
|
}
|
2025-09-25 14:01:33 +07:00
|
|
|
|
2025-12-17 15:19:55 +07:00
|
|
|
/**
|
|
|
|
|
* Test Case 3: Delete with zero InternalPID
|
|
|
|
|
* Expected: 400 Bad Request - Patient ID must be a valid integer
|
|
|
|
|
*/
|
|
|
|
|
public function testDeleteWithZeroInternalPID()
|
|
|
|
|
{
|
|
|
|
|
$result = $this->withBodyFormat('json')
|
|
|
|
|
->delete($this->endpoint, [
|
|
|
|
|
'InternalPID' => 0,
|
|
|
|
|
]);
|
2025-09-25 14:01:33 +07:00
|
|
|
|
2025-12-17 15:19:55 +07:00
|
|
|
$result->assertStatus(400);
|
|
|
|
|
$result->assertJSONFragment([
|
|
|
|
|
'status' => 'error',
|
|
|
|
|
'message' => 'Patient ID must be a valid integer.'
|
|
|
|
|
]);
|
|
|
|
|
}
|
2025-09-25 14:01:33 +07:00
|
|
|
|
2025-12-17 15:19:55 +07:00
|
|
|
/**
|
|
|
|
|
* Test Case 4: Delete with empty string InternalPID
|
|
|
|
|
* Expected: 400 Bad Request - Patient ID must be a valid integer
|
|
|
|
|
*/
|
|
|
|
|
public function testDeleteWithEmptyStringInternalPID()
|
|
|
|
|
{
|
|
|
|
|
$result = $this->withBodyFormat('json')
|
|
|
|
|
->delete($this->endpoint, [
|
|
|
|
|
'InternalPID' => '',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$result->assertStatus(400);
|
|
|
|
|
$result->assertJSONFragment([
|
|
|
|
|
'status' => 'error',
|
|
|
|
|
'message' => 'Patient ID must be a valid integer.'
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Test Case 5: Delete with array InternalPID
|
|
|
|
|
* Expected: 400 Bad Request - Patient ID must be a valid integer
|
|
|
|
|
*/
|
|
|
|
|
public function testDeleteWithArrayInternalPID()
|
|
|
|
|
{
|
|
|
|
|
$result = $this->withBodyFormat('json')
|
|
|
|
|
->delete($this->endpoint, [
|
|
|
|
|
'InternalPID' => [],
|
|
|
|
|
]);
|
2025-09-25 14:01:33 +07:00
|
|
|
|
2025-12-17 15:19:55 +07:00
|
|
|
$result->assertStatus(400);
|
|
|
|
|
$result->assertJSONFragment([
|
|
|
|
|
'status' => 'error',
|
|
|
|
|
'message' => 'Patient ID must be a valid integer.'
|
|
|
|
|
]);
|
|
|
|
|
}
|
2025-09-25 14:01:33 +07:00
|
|
|
|
2025-12-17 15:19:55 +07:00
|
|
|
/**
|
|
|
|
|
* Test Case 6: Delete non-existent patient
|
|
|
|
|
* Expected: 404 Not Found (or 500 if database not configured)
|
|
|
|
|
*/
|
|
|
|
|
public function testDeleteNotFound()
|
|
|
|
|
{
|
|
|
|
|
$testId = 9999999;
|
|
|
|
|
|
|
|
|
|
$result = $this->withBodyFormat('json')
|
|
|
|
|
->delete($this->endpoint, [
|
|
|
|
|
'InternalPID' => $testId
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
// May return 404 (not found), 500 (database error), or null (connection issue)
|
|
|
|
|
$statusCode = $result->getStatusCode();
|
|
|
|
|
$this->assertTrue(
|
|
|
|
|
in_array($statusCode, [404, 500]) || $statusCode === null,
|
|
|
|
|
"Expected status code 404, 500, or null but got: " . var_export($statusCode, true)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$json = $result->getJSON();
|
|
|
|
|
$data = json_decode($json, true);
|
|
|
|
|
|
|
|
|
|
$this->assertArrayHasKey('messages', $data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Test Case 7: Delete with SQL injection attempt
|
|
|
|
|
* Expected: 400 Bad Request - should be sanitized
|
|
|
|
|
*/
|
|
|
|
|
public function testDeleteSQLInjectionAttempt()
|
|
|
|
|
{
|
|
|
|
|
$result = $this->withBodyFormat('json')
|
|
|
|
|
->delete($this->endpoint, [
|
|
|
|
|
'InternalPID' => "' OR 1=1 --"
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$result->assertStatus(400);
|
|
|
|
|
$result->assertJSONFragment([
|
|
|
|
|
'status' => 'error',
|
|
|
|
|
'message' => 'Patient ID must be a valid integer.'
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Test Case 8: Delete with negative number
|
|
|
|
|
* Expected: 400 Bad Request - should reject negative numbers
|
|
|
|
|
*/
|
|
|
|
|
public function testDeleteWithNegativeInternalPID()
|
|
|
|
|
{
|
|
|
|
|
$result = $this->withBodyFormat('json')
|
|
|
|
|
->delete($this->endpoint, [
|
|
|
|
|
'InternalPID' => -1,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$result->assertStatus(400);
|
|
|
|
|
$result->assertJSONFragment([
|
|
|
|
|
'status' => 'error',
|
|
|
|
|
'message' => 'Patient ID must be a valid integer.'
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Test Case 9: Delete with string number
|
|
|
|
|
* Expected: Depends on implementation - may accept "123" as valid
|
|
|
|
|
*/
|
|
|
|
|
public function testDeleteWithStringNumber()
|
|
|
|
|
{
|
|
|
|
|
$testId = "9999998";
|
|
|
|
|
|
|
|
|
|
$result = $this->withBodyFormat('json')
|
|
|
|
|
->delete($this->endpoint, [
|
|
|
|
|
'InternalPID' => $testId
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
// Should either be 404 (not found), 200 (deleted), 500 (db error), or null (connection issue)
|
|
|
|
|
$statusCode = $result->getStatusCode();
|
|
|
|
|
$this->assertTrue(
|
|
|
|
|
in_array($statusCode, [200, 404, 500]) || $statusCode === null,
|
|
|
|
|
"Expected status code 200, 404, 500, or null but got: " . var_export($statusCode, true)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =====================================================
|
|
|
|
|
// SUCCESS TEST CASES
|
|
|
|
|
// NOTE: Uncomment these when you have proper DB seeding
|
|
|
|
|
// =====================================================
|
|
|
|
|
|
|
|
|
|
// /**
|
|
|
|
|
// * Test Case: Delete success
|
|
|
|
|
// * Expected: 200 OK - Patient deleted successfully
|
|
|
|
|
// *
|
|
|
|
|
// * IMPORTANT: This test modifies database state.
|
|
|
|
|
// * Make sure you have proper seeding or use DatabaseTestTrait
|
|
|
|
|
// */
|
|
|
|
|
// public function testDeleteSuccess()
|
|
|
|
|
// {
|
|
|
|
|
// // First create a patient to delete
|
|
|
|
|
// $faker = Factory::create('id_ID');
|
|
|
|
|
//
|
|
|
|
|
// $createPayload = [
|
|
|
|
|
// "PatientID" => "DELTEST" . $faker->numberBetween(10000, 99999),
|
|
|
|
|
// "AlternatePID" => "DELALT" . $faker->numberBetween(10000, 99999),
|
|
|
|
|
// "Prefix" => "Mr.",
|
|
|
|
|
// "NameFirst" => "ToBeDeleted",
|
|
|
|
|
// "NameLast" => "Patient",
|
|
|
|
|
// "Gender" => "5",
|
|
|
|
|
// "Birthdate" => "1990-01-01",
|
|
|
|
|
// ];
|
|
|
|
|
//
|
|
|
|
|
// // Create the patient
|
|
|
|
|
// $createResult = $this->withBodyFormat('json')->post($this->endpoint, $createPayload);
|
|
|
|
|
// $createResult->assertStatus(201);
|
|
|
|
|
//
|
|
|
|
|
// // Get the created patient ID from response or database
|
|
|
|
|
// // Then delete it
|
|
|
|
|
// $testId = 3; // Replace with actual ID
|
|
|
|
|
//
|
2025-10-14 15:50:22 +07:00
|
|
|
// $result = $this->withBodyFormat('json')
|
|
|
|
|
// ->delete($this->endpoint, [
|
|
|
|
|
// 'InternalPID' => $testId
|
|
|
|
|
// ]);
|
2025-12-17 15:19:55 +07:00
|
|
|
//
|
2025-10-14 15:50:22 +07:00
|
|
|
// $result->assertStatus(200);
|
|
|
|
|
// $result->assertJSONFragment([
|
|
|
|
|
// 'status' => 'success',
|
|
|
|
|
// 'message' => 'Patient ID with '.$testId.' deleted successfully.'
|
|
|
|
|
// ]);
|
|
|
|
|
// }
|
2025-09-23 10:18:48 +07:00
|
|
|
}
|