clqms-be/tests/_support/v2/MasterTestCase.php

326 lines
8.0 KiB
PHP
Raw Normal View History

<?php
namespace Tests\Support\v2;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\FeatureTestTrait;
use Firebase\JWT\JWT;
/**
* Base test case for v2 Master Data tests
*
* Provides common setup, authentication, and helper methods
* for all v2 master test feature and unit tests.
*/
abstract class MasterTestCase extends CIUnitTestCase
{
use FeatureTestTrait;
/**
* JWT token for authentication
*/
protected ?string $token = null;
/**
* Test site ID
*/
protected int $testSiteId = 1;
/**
* Test site code
*/
protected string $testSiteCode = 'TEST01';
/**
* Valueset IDs for test types
*/
public const VALUESET_TEST_TYPE = 27; // VSetID for Test Types
public const VALUESET_RESULT_TYPE = 43; // VSetID for Result Types
public const VALUESET_REF_TYPE = 44; // VSetID for Reference Types
public const VALUESET_ENTITY_TYPE = 39; // VSetID for Entity Types
/**
* Test Type VIDs
*/
public const TEST_TYPE_TEST = 1; // VID for TEST
public const TEST_TYPE_PARAM = 2; // VID for PARAM
public const TEST_TYPE_CALC = 3; // VID for CALC
public const TEST_TYPE_GROUP = 4; // VID for GROUP
public const TEST_TYPE_TITLE = 5; // VID for TITLE
/**
* Setup test environment
*/
protected function setUp(): void
{
parent::setUp();
$this->token = $this->generateTestToken();
}
/**
* Cleanup after test
*/
protected function tearDown(): void
{
parent::tearDown();
}
/**
* Generate JWT token for testing
*/
protected function generateTestToken(): string
{
$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'
];
return JWT::encode($payload, $key, 'HS256');
}
/**
* Make authenticated GET request
*/
protected function get(string $path, array $options = [])
{
$this->withHeaders(['Authorization' => 'Bearer ' . $this->token]);
return $this->call('get', $path, $options);
}
/**
* Make authenticated POST request
*/
protected function post(string $path, array $options = [])
{
$this->withHeaders(['Authorization' => 'Bearer ' . $this->token]);
return $this->call('post', $path, $options);
}
/**
* Make authenticated PUT request
*/
protected function put(string $path, array $options = [])
{
$this->withHeaders(['Authorization' => 'Bearer ' . $this->token]);
return $this->call('put', $path, $options);
}
/**
* Make authenticated DELETE request
*/
protected function delete(string $path, array $options = [])
{
$this->withHeaders(['Authorization' => 'Bearer ' . $this->token]);
return $this->call('delete', $path, $options);
}
/**
* Create a TEST type test definition
*/
protected function createTestData(): array
{
return [
'SiteID' => 1,
'TestSiteCode' => $this->testSiteCode,
'TestSiteName' => 'Test Definition ' . time(),
'TestType' => self::TEST_TYPE_TEST,
'Description' => 'Test description',
'SeqScr' => 10,
'SeqRpt' => 10,
'IndentLeft' => 0,
'VisibleScr' => 1,
'VisibleRpt' => 1,
'CountStat' => 1,
'details' => [
'DisciplineID' => 1,
'DepartmentID' => 1,
'ResultType' => 1, // Numeric
'RefType' => 1, // NMRC
'Unit1' => 'mg/dL',
'Decimal' => 2,
'Method' => 'Test Method',
'ExpectedTAT' => 60
],
'testmap' => [
[
'HostType' => 'HIS',
'HostID' => 'TEST001',
'HostTestCode' => 'TEST001',
'HostTestName' => 'Test (HIS)'
]
]
];
}
/**
* Create a PARAM type test definition
*/
protected function createParamData(): array
{
return [
'SiteID' => 1,
'TestSiteCode' => 'PARM' . substr(time(), -4),
'TestSiteName' => 'Parameter Test ' . time(),
'TestType' => self::TEST_TYPE_PARAM,
'Description' => 'Parameter test description',
'SeqScr' => 5,
'SeqRpt' => 5,
'VisibleScr' => 1,
'VisibleRpt' => 1,
'CountStat' => 1,
'details' => [
'DisciplineID' => 1,
'DepartmentID' => 1,
'ResultType' => 1,
'RefType' => 1,
'Unit1' => 'unit',
'Decimal' => 1,
'Method' => 'Parameter Method'
]
];
}
/**
* Create a GROUP type test definition with members
*/
protected function createGroupData(array $memberIds = []): array
{
return [
'SiteID' => 1,
'TestSiteCode' => 'GRUP' . substr(time(), -4),
'TestSiteName' => 'Group Test ' . time(),
'TestType' => self::TEST_TYPE_GROUP,
'Description' => 'Group test description',
'SeqScr' => 100,
'SeqRpt' => 100,
'VisibleScr' => 1,
'VisibleRpt' => 1,
'CountStat' => 1,
'Members' => $memberIds ?: [1, 2],
'testmap' => [
[
'HostType' => 'LIS',
'HostID' => 'LIS001',
'HostTestCode' => 'PANEL',
'HostTestName' => 'Test Panel (LIS)'
]
]
];
}
/**
* Create a CALC type test definition
*/
protected function createCalcData(): array
{
return [
'SiteID' => 1,
'TestSiteCode' => 'CALC' . substr(time(), -4),
'TestSiteName' => 'Calculated Test ' . time(),
'TestType' => self::TEST_TYPE_CALC,
'Description' => 'Calculated test description',
'SeqScr' => 50,
'SeqRpt' => 50,
'VisibleScr' => 1,
'VisibleRpt' => 1,
'CountStat' => 1,
'details' => [
'DisciplineID' => 1,
'DepartmentID' => 1,
'FormulaInput' => '["TEST1", "TEST2"]',
'FormulaCode' => 'TEST1 + TEST2',
'FormulaLang' => 'SQL',
'RefType' => 1,
'Unit1' => 'mg/dL',
'Decimal' => 0,
'Method' => 'Calculation Method'
],
'testmap' => [
[
'HostType' => 'LIS',
'HostID' => 'LIS001',
'HostTestCode' => 'CALCR',
'HostTestName' => 'Calculated Result (LIS)'
]
]
];
}
/**
* Assert API response has success status
*/
protected function assertSuccessResponse($response, string $message = 'Response should be successful'): void
{
$body = json_decode($response->response()->getBody(), true);
$this->assertArrayHasKey('status', $body, $message);
$this->assertEquals('success', $body['status'], $message);
}
/**
* Assert API response has error status
*/
protected function assertErrorResponse($response, string $message = 'Response should be an error'): void
{
$body = json_decode($response->response()->getBody(), true);
$this->assertArrayHasKey('status', $body, $message);
$this->assertNotEquals('success', $body['status'], $message);
}
/**
* Assert response has data key
*/
protected function assertHasData($response, string $message = 'Response should have data'): void
{
$body = json_decode($response->response()->getBody(), true);
$this->assertArrayHasKey('data', $body, $message);
}
/**
* Get test type name from VID
*/
protected function getTestTypeName(int $vid): string
{
return match ($vid) {
self::TEST_TYPE_TEST => 'TEST',
self::TEST_TYPE_PARAM => 'PARAM',
self::TEST_TYPE_CALC => 'CALC',
self::TEST_TYPE_GROUP => 'GROUP',
self::TEST_TYPE_TITLE => 'TITLE',
default => 'UNKNOWN'
};
}
/**
* Skip test if database not available
*/
protected function requireDatabase(): void
{
$db = \Config\Database::connect();
try {
$db->connect();
} catch (\Exception $e) {
$this->markTestSkipped('Database not available: ' . $e->getMessage());
}
}
/**
* Skip test if required seeded data not found
*/
protected function requireSeededData(): void
{
$db = \Config\Database::connect();
$count = $db->table('valueset')
->where('VSetID', self::VALUESET_TEST_TYPE)
->countAllResults();
if ($count === 0) {
$this->markTestSkipped('Test type valuesets not seeded');
}
}
}