211 lines
8.1 KiB
PHP
211 lines
8.1 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace Tests\Feature\Orders;
|
||
|
|
|
||
|
|
use CodeIgniter\Test\FeatureTestTrait;
|
||
|
|
use CodeIgniter\Test\CIUnitTestCase;
|
||
|
|
use Faker\Factory;
|
||
|
|
|
||
|
|
class OrderCreateTest extends CIUnitTestCase
|
||
|
|
{
|
||
|
|
use FeatureTestTrait;
|
||
|
|
|
||
|
|
protected $endpoint = 'api/ordertest';
|
||
|
|
|
||
|
|
public function testCreateOrderSuccess()
|
||
|
|
{
|
||
|
|
$faker = Factory::create('id_ID');
|
||
|
|
|
||
|
|
// First create a patient using the same approach as PatientCreateTest
|
||
|
|
$patientPayload = [
|
||
|
|
"PatientID" => "ORD" . $faker->numberBetween(1, 1000). $faker->numberBetween(1, 1000).$faker->numberBetween(1, 1000),
|
||
|
|
"AlternatePID" => "DMY" . $faker->numberBetween(1, 1000). $faker->numberBetween(1, 1000).$faker->numberBetween(1, 1000),
|
||
|
|
"Prefix" => $faker->title,
|
||
|
|
"NameFirst" => "Order",
|
||
|
|
"NameMiddle" => $faker->firstName,
|
||
|
|
"NameMaiden" => $faker->firstName,
|
||
|
|
"NameLast" => "Test",
|
||
|
|
"Suffix" => "S.Kom",
|
||
|
|
"NameAlias" => $faker->userName,
|
||
|
|
"Sex" => $faker->numberBetween(5, 6),
|
||
|
|
"PlaceOfBirth" => $faker->city,
|
||
|
|
"Birthdate" => "1990-01-01",
|
||
|
|
"ZIP" => $faker->postcode,
|
||
|
|
"Street_1" => $faker->streetAddress,
|
||
|
|
"Street_2" => "RT " . $faker->numberBetween(1, 10) . " RW " . $faker->numberBetween(1, 10),
|
||
|
|
"Street_3" => "Blok " . $faker->numberBetween(1, 20),
|
||
|
|
"City" => $faker->city,
|
||
|
|
"Province" => $faker->state,
|
||
|
|
"EmailAddress1" => "A" . $faker->numberBetween(1, 1000). $faker->numberBetween(1, 1000).$faker->numberBetween(1, 1000).'@gmail.com',
|
||
|
|
"EmailAddress2" => "B" . $faker->numberBetween(1, 1000). $faker->numberBetween(1, 1000).$faker->numberBetween(1, 1000).'@gmail.com',
|
||
|
|
"Phone" => $faker->numerify('08##########'),
|
||
|
|
"MobilePhone" => $faker->numerify('08##########'),
|
||
|
|
"Race" => (string) $faker->numberBetween(175, 205),
|
||
|
|
"Country" => (string) $faker->numberBetween(221, 469),
|
||
|
|
"MaritalStatus" => (string) $faker->numberBetween(8, 15),
|
||
|
|
"Religion" => (string) $faker->numberBetween(206, 212),
|
||
|
|
"Ethnic" => (string) $faker->numberBetween(213, 220),
|
||
|
|
"Citizenship" => "WNI",
|
||
|
|
"DeathIndicator" => (string) $faker->numberBetween(16, 17),
|
||
|
|
"LinkTo" => (string) $faker->numberBetween(2, 3),
|
||
|
|
"Custodian" => 1,
|
||
|
|
"PatIdt" => [
|
||
|
|
"IdentifierType" => "KTP",
|
||
|
|
"Identifier" => $faker->nik() ?? $faker->numerify('################')
|
||
|
|
],
|
||
|
|
"PatAtt" => [
|
||
|
|
[ "Address" => "/api/upload/" . $faker->uuid . ".jpg" ]
|
||
|
|
],
|
||
|
|
"PatCom" => $faker->sentence,
|
||
|
|
];
|
||
|
|
|
||
|
|
if($patientPayload['DeathIndicator'] == '16') {
|
||
|
|
$patientPayload['DeathDateTime'] = $faker->date('Y-m-d H:i:s');
|
||
|
|
} else {
|
||
|
|
$patientPayload['DeathDateTime'] = null;
|
||
|
|
}
|
||
|
|
|
||
|
|
$patientResult = $this->withBodyFormat('json')->call('post', 'api/patient', $patientPayload);
|
||
|
|
|
||
|
|
// Check patient creation succeeded
|
||
|
|
$patientResult->assertStatus(201);
|
||
|
|
|
||
|
|
$patientBody = json_decode($patientResult->getBody(), true);
|
||
|
|
$internalPID = $patientBody['data']['InternalPID'] ?? null;
|
||
|
|
|
||
|
|
$this->assertNotNull($internalPID, 'Failed to create test patient. Response: ' . print_r($patientBody, true));
|
||
|
|
|
||
|
|
// Get available tests from testdefsite
|
||
|
|
$testsResult = $this->call('get', 'api/test');
|
||
|
|
$testsBody = json_decode($testsResult->getBody(), true);
|
||
|
|
$availableTests = $testsBody['data'] ?? [];
|
||
|
|
|
||
|
|
// Skip if no tests available
|
||
|
|
if (empty($availableTests)) {
|
||
|
|
$this->markTestSkipped('No tests available in testdefsite table');
|
||
|
|
}
|
||
|
|
|
||
|
|
$testSiteID = $availableTests[0]['TestSiteID'];
|
||
|
|
|
||
|
|
// Create order with tests
|
||
|
|
$payload = [
|
||
|
|
'InternalPID' => $internalPID,
|
||
|
|
'Priority' => 'R',
|
||
|
|
'Tests' => [
|
||
|
|
['TestSiteID' => $testSiteID]
|
||
|
|
]
|
||
|
|
];
|
||
|
|
|
||
|
|
$result = $this->withBodyFormat('json')->call('post', $this->endpoint, $payload);
|
||
|
|
|
||
|
|
// Assertions
|
||
|
|
$result->assertStatus(201);
|
||
|
|
|
||
|
|
$body = json_decode($result->getBody(), true);
|
||
|
|
|
||
|
|
$this->assertEquals('success', $body['status']);
|
||
|
|
$this->assertArrayHasKey('data', $body);
|
||
|
|
$this->assertArrayHasKey('OrderID', $body['data']);
|
||
|
|
$this->assertArrayHasKey('Specimens', $body['data']);
|
||
|
|
$this->assertArrayHasKey('Tests', $body['data']);
|
||
|
|
$this->assertIsArray($body['data']['Specimens']);
|
||
|
|
$this->assertIsArray($body['data']['Tests']);
|
||
|
|
$this->assertNotEmpty($body['data']['Tests'], 'Tests array should not be empty');
|
||
|
|
|
||
|
|
return $body['data']['OrderID'];
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testCreateOrderValidationFailsWithoutInternalPID()
|
||
|
|
{
|
||
|
|
$payload = [
|
||
|
|
'Tests' => [
|
||
|
|
['TestSiteID' => 1]
|
||
|
|
]
|
||
|
|
];
|
||
|
|
|
||
|
|
$result = $this->withBodyFormat('json')->call('post', $this->endpoint, $payload);
|
||
|
|
|
||
|
|
$result->assertStatus(400);
|
||
|
|
|
||
|
|
$body = json_decode($result->getBody(), true);
|
||
|
|
$this->assertIsArray($body);
|
||
|
|
$this->assertArrayHasKey('errors', $body);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testCreateOrderFailsWithInvalidPatient()
|
||
|
|
{
|
||
|
|
$payload = [
|
||
|
|
'InternalPID' => 999999,
|
||
|
|
'Tests' => [
|
||
|
|
['TestSiteID' => 1]
|
||
|
|
]
|
||
|
|
];
|
||
|
|
|
||
|
|
$result = $this->withBodyFormat('json')->call('post', $this->endpoint, $payload);
|
||
|
|
|
||
|
|
$result->assertStatus(400);
|
||
|
|
|
||
|
|
$body = json_decode($result->getBody(), true);
|
||
|
|
$this->assertIsArray($body);
|
||
|
|
$this->assertArrayHasKey('errors', $body);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testCreateOrderWithMultipleTests()
|
||
|
|
{
|
||
|
|
$faker = Factory::create('id_ID');
|
||
|
|
|
||
|
|
// First create a patient
|
||
|
|
$patientPayload = [
|
||
|
|
"PatientID" => "ORDM" . $faker->numberBetween(1, 1000). $faker->numberBetween(1, 1000),
|
||
|
|
"NameFirst" => "Multi",
|
||
|
|
"NameLast" => "Test",
|
||
|
|
"Sex" => "2",
|
||
|
|
"Birthdate" => "1985-05-15",
|
||
|
|
"PatIdt" => [
|
||
|
|
"IdentifierType" => "KTP",
|
||
|
|
"Identifier" => $faker->numerify('################')
|
||
|
|
]
|
||
|
|
];
|
||
|
|
|
||
|
|
$patientResult = $this->withBodyFormat('json')->call('post', 'api/patient', $patientPayload);
|
||
|
|
|
||
|
|
$patientBody = json_decode($patientResult->getBody(), true);
|
||
|
|
$internalPID = $patientBody['data']['InternalPID'] ?? null;
|
||
|
|
|
||
|
|
$this->assertNotNull($internalPID, 'Failed to create test patient');
|
||
|
|
|
||
|
|
// Get available tests
|
||
|
|
$testsResult = $this->call('get', 'api/test');
|
||
|
|
$testsBody = json_decode($testsResult->getBody(), true);
|
||
|
|
$availableTests = $testsBody['data'] ?? [];
|
||
|
|
|
||
|
|
if (count($availableTests) < 2) {
|
||
|
|
$this->markTestSkipped('Need at least 2 tests for this test');
|
||
|
|
}
|
||
|
|
|
||
|
|
$testSiteID1 = $availableTests[0]['TestSiteID'];
|
||
|
|
$testSiteID2 = $availableTests[1]['TestSiteID'];
|
||
|
|
|
||
|
|
// Create order with multiple tests
|
||
|
|
$payload = [
|
||
|
|
'InternalPID' => $internalPID,
|
||
|
|
'Priority' => 'S',
|
||
|
|
'Comment' => 'Urgent order for multiple tests',
|
||
|
|
'Tests' => [
|
||
|
|
['TestSiteID' => $testSiteID1],
|
||
|
|
['TestSiteID' => $testSiteID2]
|
||
|
|
]
|
||
|
|
];
|
||
|
|
|
||
|
|
$result = $this->withBodyFormat('json')->call('post', $this->endpoint, $payload);
|
||
|
|
|
||
|
|
$result->assertStatus(201);
|
||
|
|
|
||
|
|
$body = json_decode($result->getBody(), true);
|
||
|
|
|
||
|
|
$this->assertEquals('success', $body['status']);
|
||
|
|
$this->assertGreaterThanOrEqual(1, count($body['data']['Specimens']), 'Should have at least one specimen');
|
||
|
|
$this->assertGreaterThanOrEqual(2, count($body['data']['Tests']), 'Should have at least two tests');
|
||
|
|
}
|
||
|
|
}
|