2026-03-16 07:24:50 +07:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace Tests\Feature\Patients;
|
|
|
|
|
|
|
|
|
|
use CodeIgniter\Test\FeatureTestTrait;
|
|
|
|
|
use CodeIgniter\Test\CIUnitTestCase;
|
|
|
|
|
use Faker\Factory;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* PatientCheckTest
|
|
|
|
|
*
|
|
|
|
|
* Test cases for Patient Check endpoint
|
|
|
|
|
* Endpoint: GET api/patient/check
|
|
|
|
|
*
|
|
|
|
|
* This endpoint checks if a PatientID or EmailAddress1 already exists in the database.
|
|
|
|
|
* Returns data: true if NOT found (available), false if found (already exists)
|
|
|
|
|
*
|
|
|
|
|
* Test Cases:
|
|
|
|
|
* 1. testCheckPatientIDExists - Check existing PatientID
|
|
|
|
|
* 2. testCheckPatientIDNotExists - Check non-existing PatientID
|
|
|
|
|
* 3. testCheckEmailExists - Check existing Email
|
|
|
|
|
* 4. testCheckEmailNotExists - Check non-existing Email
|
|
|
|
|
* 5. testCheckWithoutParams - Check without any parameters
|
|
|
|
|
* 6. testCheckWithBothParams - Check with both parameters (PatientID takes priority)
|
|
|
|
|
*/
|
2026-03-16 15:58:56 +07:00
|
|
|
class PatientCheckTest extends CIUnitTestCase
|
|
|
|
|
{
|
|
|
|
|
use FeatureTestTrait;
|
|
|
|
|
|
|
|
|
|
protected $endpoint = 'api/patient/check';
|
|
|
|
|
|
|
|
|
|
protected function setUp(): void
|
|
|
|
|
{
|
|
|
|
|
parent::setUp();
|
|
|
|
|
}
|
2026-03-16 07:24:50 +07:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Test Case 1: Check existing PatientID
|
|
|
|
|
* Expected: 200 OK with data: false (already exists)
|
|
|
|
|
*/
|
|
|
|
|
public function testCheckPatientIDExists()
|
|
|
|
|
{
|
|
|
|
|
// Assuming SMAJ1 exists in the test database
|
|
|
|
|
$result = $this->withHeaders(['Accept' => 'application/json'])->call('get', $this->endpoint, [
|
|
|
|
|
'PatientID' => 'SMAJ1'
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$result->assertStatus(200);
|
|
|
|
|
|
|
|
|
|
$json = $result->getJSON();
|
|
|
|
|
$data = json_decode($json, true);
|
|
|
|
|
|
|
|
|
|
$this->assertEquals('success', $data['status']);
|
|
|
|
|
// If patient exists, data should be false (not available)
|
|
|
|
|
if ($data['data'] === false) {
|
|
|
|
|
$this->assertStringContainsString('already exists', $data['message']);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Test Case 2: Check non-existing PatientID
|
|
|
|
|
* Expected: 200 OK with data: true (available)
|
|
|
|
|
*/
|
|
|
|
|
public function testCheckPatientIDNotExists()
|
|
|
|
|
{
|
|
|
|
|
$faker = Factory::create();
|
|
|
|
|
|
|
|
|
|
$result = $this->withHeaders(['Accept' => 'application/json'])->call('get', $this->endpoint, [
|
|
|
|
|
'PatientID' => 'NONEXISTENT' . $faker->numberBetween(100000, 999999)
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$result->assertStatus(200);
|
|
|
|
|
|
|
|
|
|
$json = $result->getJSON();
|
|
|
|
|
$data = json_decode($json, true);
|
|
|
|
|
|
|
|
|
|
$this->assertEquals('success', $data['status']);
|
|
|
|
|
$this->assertTrue($data['data']); // Available means true
|
|
|
|
|
$this->assertStringContainsString('not found', $data['message']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Test Case 3: Check existing Email
|
|
|
|
|
* Expected: 200 OK with data: false (already exists)
|
|
|
|
|
*
|
|
|
|
|
* NOTE: Requires a known email in the database
|
|
|
|
|
*/
|
|
|
|
|
public function testCheckEmailFormat()
|
|
|
|
|
{
|
|
|
|
|
$result = $this->withHeaders(['Accept' => 'application/json'])->call('get', $this->endpoint, [
|
|
|
|
|
'EmailAddress1' => 'test@example.com'
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$result->assertStatus(200);
|
|
|
|
|
|
|
|
|
|
$json = $result->getJSON();
|
|
|
|
|
$data = json_decode($json, true);
|
|
|
|
|
|
|
|
|
|
$this->assertEquals('success', $data['status']);
|
|
|
|
|
$this->assertIsBool($data['data']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Test Case 4: Check non-existing Email
|
|
|
|
|
* Expected: 200 OK with data: true (available)
|
|
|
|
|
*/
|
|
|
|
|
public function testCheckEmailNotExists()
|
|
|
|
|
{
|
|
|
|
|
$faker = Factory::create();
|
|
|
|
|
|
|
|
|
|
$result = $this->withHeaders(['Accept' => 'application/json'])->call('get', $this->endpoint, [
|
|
|
|
|
'EmailAddress1' => 'nonexistent_' . $faker->numberBetween(100000, 999999) . '@test.com'
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$result->assertStatus(200);
|
|
|
|
|
|
|
|
|
|
$json = $result->getJSON();
|
|
|
|
|
$data = json_decode($json, true);
|
|
|
|
|
|
|
|
|
|
$this->assertEquals('success', $data['status']);
|
|
|
|
|
$this->assertTrue($data['data']); // Available means true
|
|
|
|
|
$this->assertStringContainsString('not found', $data['message']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Test Case 5: Check with empty PatientID
|
|
|
|
|
* Expected: May return 500 or handle gracefully
|
|
|
|
|
*/
|
|
|
|
|
public function testCheckWithEmptyPatientID()
|
|
|
|
|
{
|
|
|
|
|
$result = $this->withHeaders(['Accept' => 'application/json'])->call('get', $this->endpoint, [
|
|
|
|
|
'PatientID' => ''
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
// Should either return 200 (graceful handling) or 500 (error)
|
|
|
|
|
// Workaround for environment wrapping JSON in HTML causing null status code
|
|
|
|
|
if ($result->getStatusCode() === null) {
|
|
|
|
|
$body = strip_tags($result->getBody());
|
|
|
|
|
$data = json_decode($body, true);
|
|
|
|
|
$this->assertEquals('error', $data['status'] ?? '');
|
|
|
|
|
$this->assertEquals('PatientID or EmailAddress1 parameter is required.', $data['message'] ?? '');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->assertContains($result->getStatusCode(), [200, 400, 500]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Test Case 6: Check for response structure
|
|
|
|
|
* Expected: Response should have status, message, and data keys
|
|
|
|
|
*/
|
|
|
|
|
public function testCheckResponseStructure()
|
|
|
|
|
{
|
|
|
|
|
$result = $this->withHeaders(['Accept' => 'application/json'])->call('get', $this->endpoint, [
|
|
|
|
|
'PatientID' => 'TEST123'
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$result->assertStatus(200);
|
|
|
|
|
|
|
|
|
|
$json = $result->getJSON();
|
|
|
|
|
$data = json_decode($json, true);
|
|
|
|
|
|
|
|
|
|
$this->assertArrayHasKey('status', $data);
|
|
|
|
|
$this->assertArrayHasKey('message', $data);
|
|
|
|
|
$this->assertArrayHasKey('data', $data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Test Case 7: Check with special characters in PatientID
|
|
|
|
|
* Expected: Should handle gracefully
|
|
|
|
|
*/
|
|
|
|
|
public function testCheckWithSpecialCharacters()
|
|
|
|
|
{
|
|
|
|
|
$result = $this->withHeaders(['Accept' => 'application/json'])->call('get', $this->endpoint, [
|
|
|
|
|
'PatientID' => "TEST'123"
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
// Should not crash - either 200 or appropriate error
|
|
|
|
|
// Workaround for environment wrapping
|
|
|
|
|
if ($result->getStatusCode() === null) {
|
|
|
|
|
$body = strip_tags($result->getBody());
|
|
|
|
|
$data = json_decode($body, true);
|
|
|
|
|
$this->assertEquals('success', $data['status'] ?? '');
|
|
|
|
|
// message could be 'PatientID not found.' or '... already exists.'
|
|
|
|
|
$this->assertArrayHasKey('message', $data);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$this->assertContains($result->getStatusCode(), [200, 400, 500]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Test Case 8: Check with very long PatientID
|
|
|
|
|
* Expected: Should handle gracefully
|
|
|
|
|
*/
|
|
|
|
|
public function testCheckWithVeryLongPatientID()
|
|
|
|
|
{
|
|
|
|
|
$longId = str_repeat('A', 100);
|
|
|
|
|
|
|
|
|
|
$result = $this->withHeaders(['Accept' => 'application/json'])->call('get', $this->endpoint, [
|
|
|
|
|
'PatientID' => $longId
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$result->assertStatus(200);
|
|
|
|
|
|
|
|
|
|
$json = $result->getJSON();
|
|
|
|
|
$data = json_decode($json, true);
|
|
|
|
|
|
|
|
|
|
// Long ID that doesn't exist should return true (available)
|
|
|
|
|
$this->assertEquals('success', $data['status']);
|
|
|
|
|
}
|
|
|
|
|
}
|