Allow the test map list endpoint to filter by host and client, and include container labels in detail responses. Update the API contract and feature coverage to match.
340 lines
12 KiB
PHP
Executable File
340 lines
12 KiB
PHP
Executable File
<?php
|
|
|
|
namespace Tests\Feature\Test;
|
|
|
|
use CodeIgniter\Test\FeatureTestTrait;
|
|
use CodeIgniter\Test\CIUnitTestCase;
|
|
use Firebase\JWT\JWT;
|
|
|
|
class TestMapPatchTest extends CIUnitTestCase
|
|
{
|
|
use FeatureTestTrait;
|
|
|
|
protected string $token;
|
|
protected string $endpoint = 'api/test/testmap';
|
|
|
|
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 createTestMap(array $data = []): array
|
|
{
|
|
$payload = array_merge([
|
|
'HostType' => 'SITE',
|
|
'HostID' => 1,
|
|
'ClientType' => 'SITE',
|
|
'ClientID' => 1,
|
|
], $data);
|
|
|
|
$response = $this->withHeaders($this->authHeaders())
|
|
->withBodyFormat('json')
|
|
->call('post', $this->endpoint, $payload);
|
|
|
|
$response->assertStatus(201);
|
|
$created = json_decode($response->getJSON(), true);
|
|
$id = $created['data'];
|
|
|
|
$show = $this->withHeaders($this->authHeaders())->call('get', "{$this->endpoint}/{$id}");
|
|
$show->assertStatus(200);
|
|
$showData = json_decode($show->getJSON(), true)['data'];
|
|
$this->assertArrayHasKey('HostName', $showData);
|
|
$this->assertArrayHasKey('ClientName', $showData);
|
|
|
|
return $showData;
|
|
}
|
|
|
|
public function testIndexFiltersByHost(): void
|
|
{
|
|
$testMap = $this->createTestMap([
|
|
'HostType' => 'SITE',
|
|
'HostID' => 2,
|
|
'ClientType' => 'SITE',
|
|
'ClientID' => 1,
|
|
]);
|
|
|
|
$response = $this->withHeaders($this->authHeaders())
|
|
->call('get', $this->endpoint . '?host=2');
|
|
|
|
$response->assertStatus(200);
|
|
$rows = json_decode($response->getJSON(), true)['data'];
|
|
|
|
$this->assertNotEmpty(array_values(array_filter($rows, static fn (array $row): bool => (int) $row['TestMapID'] === (int) $testMap['TestMapID'])));
|
|
|
|
foreach ($rows as $row) {
|
|
$this->assertTrue(
|
|
str_contains(strtolower((string) ($row['HostID'] ?? '')), '2')
|
|
|| str_contains(strtolower((string) ($row['HostName'] ?? '')), '2')
|
|
|| str_contains(strtolower((string) ($row['HostType'] ?? '')), '2')
|
|
);
|
|
}
|
|
}
|
|
|
|
public function testIndexFiltersByClient(): void
|
|
{
|
|
$testMap = $this->createTestMap([
|
|
'HostType' => 'SITE',
|
|
'HostID' => 1,
|
|
'ClientType' => 'SITE',
|
|
'ClientID' => 3,
|
|
]);
|
|
|
|
$response = $this->withHeaders($this->authHeaders())
|
|
->call('get', $this->endpoint . '?client=3');
|
|
|
|
$response->assertStatus(200);
|
|
$rows = json_decode($response->getJSON(), true)['data'];
|
|
|
|
$this->assertNotEmpty(array_values(array_filter($rows, static fn (array $row): bool => (int) $row['TestMapID'] === (int) $testMap['TestMapID'])));
|
|
|
|
foreach ($rows as $row) {
|
|
$this->assertTrue(
|
|
str_contains(strtolower((string) ($row['ClientID'] ?? '')), '3')
|
|
|| str_contains(strtolower((string) ($row['ClientName'] ?? '')), '3')
|
|
|| str_contains(strtolower((string) ($row['ClientType'] ?? '')), '3')
|
|
);
|
|
}
|
|
}
|
|
|
|
public function testPartialUpdateTestMapSuccess()
|
|
{
|
|
$testMap = $this->createTestMap();
|
|
$id = $testMap['TestMapID'];
|
|
|
|
$patch = $this->withHeaders($this->authHeaders())
|
|
->withBodyFormat('json')
|
|
->call('patch', "{$this->endpoint}/{$id}", ['ClientType' => 'WST']);
|
|
|
|
$patch->assertStatus(200);
|
|
$patchData = json_decode($patch->getJSON(), true);
|
|
$this->assertEquals('success', $patchData['status']);
|
|
|
|
$show = $this->withHeaders($this->authHeaders())->call('get', "{$this->endpoint}/{$id}");
|
|
$show->assertStatus(200);
|
|
$showData = json_decode($show->getJSON(), true)['data'];
|
|
|
|
$this->assertEquals('WST', $showData['ClientType']);
|
|
$this->assertEquals((string) $testMap['HostID'], (string) $showData['HostID']);
|
|
}
|
|
|
|
public function testPartialUpdateTestMapNotFound()
|
|
{
|
|
$patch = $this->withHeaders($this->authHeaders())
|
|
->withBodyFormat('json')
|
|
->call('patch', "{$this->endpoint}/999999", ['ClientType' => 'WST']);
|
|
|
|
$patch->assertStatus(404);
|
|
}
|
|
|
|
public function testPartialUpdateTestMapInvalidId()
|
|
{
|
|
$patch = $this->withHeaders($this->authHeaders())
|
|
->withBodyFormat('json')
|
|
->call('patch', "{$this->endpoint}/invalid", ['ClientType' => 'WST']);
|
|
|
|
$patch->assertStatus(400);
|
|
}
|
|
|
|
public function testPartialUpdateTestMapEmptyPayload()
|
|
{
|
|
$testMap = $this->createTestMap();
|
|
$id = $testMap['TestMapID'];
|
|
|
|
$patch = $this->withHeaders($this->authHeaders())
|
|
->withBodyFormat('json')
|
|
->call('patch', "{$this->endpoint}/{$id}", []);
|
|
|
|
$patch->assertStatus(400);
|
|
}
|
|
|
|
public function testPartialUpdateTestMapSingleField()
|
|
{
|
|
$testMap = $this->createTestMap();
|
|
$id = $testMap['TestMapID'];
|
|
|
|
$patch = $this->withHeaders($this->authHeaders())
|
|
->withBodyFormat('json')
|
|
->call('patch', "{$this->endpoint}/{$id}", ['HostID' => 2]);
|
|
|
|
$patch->assertStatus(200);
|
|
$showData = json_decode($this->withHeaders($this->authHeaders())
|
|
->call('get', "{$this->endpoint}/{$id}")
|
|
->getJSON(), true)['data'];
|
|
|
|
$this->assertEquals('2', (string) $showData['HostID']);
|
|
$this->assertEquals((string) $testMap['ClientID'], (string) $showData['ClientID']);
|
|
}
|
|
|
|
public function testCreateTestMapWithDetails()
|
|
{
|
|
$details = [
|
|
[
|
|
'HostTestCode' => 'HB',
|
|
'HostTestName' => 'Hemoglobin',
|
|
'ClientTestCode' => '2',
|
|
'ClientTestName' => 'Hemoglobin',
|
|
],
|
|
[
|
|
'HostTestCode' => 'HCT',
|
|
'HostTestName' => 'Hematocrit',
|
|
'ClientTestCode' => '3',
|
|
'ClientTestName' => 'Hematocrit',
|
|
],
|
|
];
|
|
|
|
$testMap = $this->createTestMap([
|
|
'HostType' => 'SITE',
|
|
'HostID' => 1,
|
|
'ClientType' => 'SITE',
|
|
'ClientID' => 2,
|
|
'details' => $details,
|
|
]);
|
|
|
|
$this->assertCount(2, $testMap['details']);
|
|
$this->assertEquals('2', $testMap['details'][0]['ClientTestCode']);
|
|
}
|
|
|
|
public function testPatchTestMapDetailOperations()
|
|
{
|
|
$initialDetails = [
|
|
[
|
|
'HostTestCode' => 'HB',
|
|
'HostTestName' => 'Hemoglobin',
|
|
'ClientTestCode' => '2',
|
|
'ClientTestName' => 'Hemoglobin',
|
|
],
|
|
[
|
|
'HostTestCode' => 'HCT',
|
|
'HostTestName' => 'Hematocrit',
|
|
'ClientTestCode' => '3',
|
|
'ClientTestName' => 'Hematocrit',
|
|
],
|
|
];
|
|
|
|
$testMap = $this->createTestMap([
|
|
'HostType' => 'SITE',
|
|
'HostID' => 1,
|
|
'ClientType' => 'SITE',
|
|
'ClientID' => 1,
|
|
'details' => $initialDetails,
|
|
]);
|
|
|
|
$existingDetails = $testMap['details'];
|
|
$editDetail = $existingDetails[0];
|
|
$deleteDetail = $existingDetails[1];
|
|
|
|
$patch = $this->withHeaders($this->authHeaders())
|
|
->withBodyFormat('json')
|
|
->call('patch', "{$this->endpoint}/{$testMap['TestMapID']}", [
|
|
'ClientType' => 'WST',
|
|
'details' => [
|
|
'edited' => [
|
|
[
|
|
'TestMapDetailID' => $editDetail['TestMapDetailID'],
|
|
'ClientTestName' => 'Hemoglobin Updated',
|
|
],
|
|
],
|
|
'created' => [
|
|
[
|
|
'HostTestCode' => 'MCV',
|
|
'HostTestName' => 'MCV',
|
|
'ClientTestCode' => '4',
|
|
'ClientTestName' => 'MCV',
|
|
],
|
|
],
|
|
'deleted' => [$deleteDetail['TestMapDetailID']],
|
|
],
|
|
]);
|
|
|
|
$patch->assertStatus(200);
|
|
$patchData = json_decode($patch->getJSON(), true);
|
|
$this->assertEquals('success', $patchData['status']);
|
|
|
|
$show = $this->withHeaders($this->authHeaders())->call('get', "{$this->endpoint}/{$testMap['TestMapID']}");
|
|
$show->assertStatus(200);
|
|
$showData = json_decode($show->getJSON(), true)['data'];
|
|
|
|
$this->assertEquals('WST', $showData['ClientType']);
|
|
$this->assertCount(2, $showData['details']);
|
|
$detailIds = array_column($showData['details'], 'TestMapDetailID');
|
|
$this->assertContains($editDetail['TestMapDetailID'], $detailIds);
|
|
$this->assertNotContains($deleteDetail['TestMapDetailID'], $detailIds);
|
|
|
|
$updatedDetails = array_values(array_filter($showData['details'], static fn ($row) => $row['TestMapDetailID'] === $editDetail['TestMapDetailID']));
|
|
$this->assertNotEmpty($updatedDetails);
|
|
$this->assertEquals('Hemoglobin Updated', $updatedDetails[0]['ClientTestName']);
|
|
}
|
|
|
|
public function testShowTestMapIncludesContainerLabel(): void
|
|
{
|
|
$testMap = $this->createTestMap([
|
|
'HostType' => 'SITE',
|
|
'HostID' => 1,
|
|
'ClientType' => 'SITE',
|
|
'ClientID' => 2,
|
|
'details' => [
|
|
[
|
|
'HostTestCode' => 'HB',
|
|
'HostTestName' => 'Hemoglobin',
|
|
'ConDefID' => 1,
|
|
'ClientTestCode' => '2',
|
|
'ClientTestName' => 'Hemoglobin',
|
|
],
|
|
],
|
|
]);
|
|
|
|
$show = $this->withHeaders($this->authHeaders())->call('get', "{$this->endpoint}/{$testMap['TestMapID']}");
|
|
$show->assertStatus(200);
|
|
|
|
$showData = json_decode($show->getJSON(), true)['data'];
|
|
$this->assertNotEmpty($showData['details']);
|
|
$this->assertArrayHasKey('ContainerLabel', $showData['details'][0]);
|
|
$this->assertNotEmpty($showData['details'][0]['ContainerLabel']);
|
|
}
|
|
|
|
public function testDeleteTestMapRemovesDetails()
|
|
{
|
|
$testMap = $this->createTestMap([
|
|
'HostType' => 'SITE',
|
|
'HostID' => 2,
|
|
'ClientType' => 'SITE',
|
|
'ClientID' => 3,
|
|
'details' => [
|
|
[
|
|
'HostTestCode' => 'PLT',
|
|
'HostTestName' => 'Platelet',
|
|
'ClientTestCode' => '5',
|
|
'ClientTestName' => 'Platelet',
|
|
],
|
|
],
|
|
]);
|
|
|
|
$delete = $this->withHeaders($this->authHeaders())
|
|
->withBodyFormat('json')
|
|
->call('delete', $this->endpoint, ['TestMapID' => $testMap['TestMapID']]);
|
|
|
|
$delete->assertStatus(200);
|
|
|
|
$details = $this->withHeaders($this->authHeaders())
|
|
->call('get', "{$this->endpoint}/detail/by-testmap/{$testMap['TestMapID']}");
|
|
$details->assertStatus(200);
|
|
$this->assertEquals([], json_decode($details->getJSON(), true)['data']);
|
|
}
|
|
}
|