clqms-be/tests/feature/OrderTest/OrderTestPatchTest.php
mahdahar 66e9be2a04 Rename order test delta created to added
Update order test patch flow to use Tests.added instead of Tests.created across controller, model, bundled OpenAPI, and feature test coverage. Reject legacy created payloads, align validation/error text, and adjust test payloads and assertions for new added lifecycle.
2026-04-23 13:26:18 +07:00

225 lines
7.6 KiB
PHP
Executable File

<?php
declare(strict_types=1);
namespace Tests\Feature\OrderTest;
use App\Models\OrderTest\OrderTestModel;
use App\Models\PatResultModel;
use App\Models\Patient\PatientModel;
use App\Models\Test\TestDefSiteModel;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\FeatureTestTrait;
use Firebase\JWT\JWT;
class OrderTestPatchTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected string $token;
protected string $endpoint = 'api/ordertest';
protected function setUp(): void
{
parent::setUp();
$key = getenv('JWT_SECRET') ?: 'my-secret-key';
$payload = [
'iss' => 'localhost',
'aud' => 'localhost',
'iat' => time(),
'nbf' => time(),
'exp' => time() + 3600,
'uid' => 1,
'email' => 'admin@admin.com',
];
$this->token = JWT::encode($payload, $key, 'HS256');
}
private function authHeaders(): array
{
return ['Cookie' => 'token=' . $this->token];
}
private function findResultByOrderAndSite(int $internalOID, int $testSiteID): ?array
{
$resultModel = new PatResultModel();
return $resultModel->where('OrderID', $internalOID)
->where('TestSiteID', $testSiteID)
->where('DelDate', null)
->orderBy('ResultID', 'DESC')
->first();
}
private function findRowBySite(array $rows, int $testSiteID): ?array
{
foreach ($rows as $row) {
if ((int) ($row['TestSiteID'] ?? 0) === $testSiteID) {
return $row;
}
}
return null;
}
private function createOrderWithTest(): array
{
$patientModel = new PatientModel();
$patient = $patientModel->where('DelDate', null)->first();
$this->assertNotEmpty($patient, 'No active patient found for order patch test.');
$testModel = new TestDefSiteModel();
$tests = $testModel->where('EndDate', null)
->where('TestType', 'TEST')
->findAll(2);
if (count($tests) < 2) {
$tests = $testModel->where('EndDate', null)->findAll(2);
}
$this->assertGreaterThanOrEqual(2, count($tests), 'Need at least 2 test definitions for lifecycle patch test.');
$response = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('post', $this->endpoint, [
'InternalPID' => (int) $patient['InternalPID'],
'SiteID' => (int) ($tests[0]['SiteID'] ?? 1),
'Tests' => [
[
'TestSiteID' => (int) $tests[0]['TestSiteID'],
],
],
]);
$response->assertStatus(201);
$decoded = json_decode($response->getJSON(), true);
$this->assertSame('success', $decoded['status'] ?? null);
return [
'order' => $decoded['data'],
'baseTest' => $tests[0],
'extraTest' => $tests[1],
];
}
public function testPatchTestsLifecycleAddedEditedDeleted(): void
{
$fixture = $this->createOrderWithTest();
$order = $fixture['order'];
$baseTest = $fixture['baseTest'];
$extraTest = $fixture['extraTest'];
$orderID = $order['OrderID'];
$internalOID = (int) $order['InternalOID'];
$baseSiteID = (int) $baseTest['TestSiteID'];
$extraSiteID = (int) $extraTest['TestSiteID'];
$addResponse = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$orderID}", [
'Tests' => [
'added' => [
[
'TestSiteID' => (string) $extraSiteID,
'Result' => 'ADDED',
],
],
],
]);
$addResponse->assertStatus(200);
$addJson = json_decode($addResponse->getJSON(), true);
$this->assertSame('success', $addJson['status'] ?? null);
$addedRow = $this->findRowBySite($addJson['data']['Tests'] ?? [], $extraSiteID);
$this->assertNotNull($addedRow, 'Added test not returned by patch response.');
$this->assertSame('ADDED', $addedRow['Result'] ?? null);
$addedResultID = (int) ($addedRow['ResultID'] ?? 0);
$this->assertGreaterThan(0, $addedResultID, 'Added test missing ResultID.');
$addedDbRow = $this->findResultByOrderAndSite($internalOID, $extraSiteID);
$this->assertNotNull($addedDbRow, 'Added test not found in DB.');
$this->assertSame('ADDED', $addedDbRow['Result'] ?? null);
$editResponse = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$orderID}", [
'Tests' => [
'edited' => [
[
'TestSiteID' => (string) $baseSiteID,
'Result' => 'EDITED',
],
],
],
]);
$editResponse->assertStatus(200);
$editJson = json_decode($editResponse->getJSON(), true);
$this->assertSame('success', $editJson['status'] ?? null);
$editedRow = $this->findRowBySite($editJson['data']['Tests'] ?? [], $baseSiteID);
$this->assertNotNull($editedRow, 'Edited test not returned by patch response.');
$this->assertSame('EDITED', $editedRow['Result'] ?? null);
$deleteResponse = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$orderID}", [
'Tests' => [
'deleted' => [
[
'TestSiteID' => (string) $extraSiteID,
],
],
],
]);
$deleteResponse->assertStatus(200);
$deleteJson = json_decode($deleteResponse->getJSON(), true);
$this->assertSame('success', $deleteJson['status'] ?? null);
$this->assertNull($this->findRowBySite($deleteJson['data']['Tests'] ?? [], $extraSiteID), 'Deleted test still returned by patch response.');
$deletedDbRow = (new PatResultModel())->find($addedResultID);
$this->assertNotNull($deletedDbRow, 'Deleted test row missing from DB.');
$this->assertNotNull($deletedDbRow['DelDate'] ?? null, 'Deleted test row not soft deleted.');
}
public function testPatchTestsNotFound(): void
{
$response = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/999999999", [
'Tests' => [
'deleted' => [1],
],
]);
$response->assertStatus(404);
}
public function testPatchTestsInvalidId(): void
{
$response = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/invalid", [
'Tests' => [
'deleted' => [1],
],
]);
$response->assertStatus(404);
}
public function testPatchTestsEmptyPayload(): void
{
$fixture = $this->createOrderWithTest();
$orderID = $fixture['order']['OrderID'];
$response = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$orderID}", []);
$response->assertStatus(400);
}
}