clqms-be/tests/feature/TestDef/TestDefSiteTest.php
mahdahar cd65e91db1 refactor: Rename controllers to follow CodeIgniter 4 naming convention
- Rename all controllers from X.php to XController.php format
- Add new RefTxtModel for text-based reference ranges
- Rename group_dialog.php to grp_dialog.php and remove title_dialog.php
- Add comprehensive test suite for v2/master/TestDef module
- Update Routes.php to reflect controller renames
- Remove obsolete data files (clqms_v2.sql, lab.dbml)
2026-01-05 16:55:34 +07:00

375 lines
11 KiB
PHP

<?php
namespace Tests\Feature\TestDef;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use App\Models\Test\TestDefSiteModel;
use App\Models\Test\TestDefTechModel;
use App\Models\Test\TestDefCalModel;
use App\Models\Test\TestDefGrpModel;
/**
* Integration tests for Test Definitions API
*
* Tests the CRUD operations for test definitions through the API
*/
class TestDefSiteTest extends CIUnitTestCase
{
use DatabaseTestTrait;
protected $seed = 'App\Database\Seeds\TestSeeder';
protected $refresh = true;
/**
* Test listing all tests returns success response
*/
public function testIndexReturnsSuccessResponse(): void
{
$result = $this->withHeaders([
'Content-Type' => 'application/json',
'Accept' => 'application/json'
])->get('api/tests');
$result->assertStatus(200);
$result->assertJSONExact([
'status' => 'success',
'message' => 'Data fetched successfully',
'data' => $result->getJSON(true)['data']
]);
}
/**
* Test listing all tests returns array
*/
public function testIndexReturnsArray(): void
{
$result = $this->withHeaders([
'Content-Type' => 'application/json',
'Accept' => 'application/json'
])->get('api/tests');
$result->assertStatus(200);
$response = $result->getJSON(true);
$this->assertIsArray($response['data']);
}
/**
* Test index contains test type information
*/
public function testIndexContainsTypeInformation(): void
{
$result = $this->withHeaders([
'Content-Type' => 'application/json',
'Accept' => 'application/json'
])->get('api/tests');
$result->assertStatus(200);
$response = $result->getJSON(true);
if (!empty($response['data'])) {
$test = $response['data'][0];
$this->assertArrayHasKey('TypeCode', $test);
$this->assertArrayHasKey('TypeName', $test);
}
}
/**
* Test filtering by test type
*/
public function testIndexFiltersByTestType(): void
{
// Test filtering by TEST type (VID = 1)
$result = $this->withHeaders([
'Content-Type' => 'application/json',
'Accept' => 'application/json'
])->get('api/tests?TestType=1');
$result->assertStatus(200);
$response = $result->getJSON(true);
foreach ($response['data'] as $test) {
$this->assertEquals('TEST', $test['TypeCode']);
}
}
/**
* Test filtering by keyword
*/
public function testIndexFiltersByKeyword(): void
{
$result = $this->withHeaders([
'Content-Type' => 'application/json',
'Accept' => 'application/json'
])->get('api/tests?TestSiteName=HB');
$result->assertStatus(200);
$response = $result->getJSON(true);
if (!empty($response['data'])) {
foreach ($response['data'] as $test) {
$this->assertStringContainsString('HB', $test['TestSiteName']);
}
}
}
/**
* Test showing single test returns success
*/
public function testShowReturnsSuccess(): void
{
// Get a test ID from the seeder data
$model = new TestDefSiteModel();
$test = $model->first();
if ($test) {
$result = $this->withHeaders([
'Content-Type' => 'application/json',
'Accept' => 'application/json'
])->get("api/tests/{$test['TestSiteID']}");
$result->assertStatus(200);
$response = $result->getJSON(true);
$this->assertArrayHasKey('data', $response);
} else {
$this->markTestSkipped('No test data available');
}
}
/**
* Test showing single test includes type-specific details for TEST type
*/
public function testShowIncludesTechDetailsForTestType(): void
{
$model = new TestDefSiteModel();
$test = $model->first();
if ($test && $test['TypeCode'] === 'TEST') {
$result = $this->withHeaders([
'Content-Type' => 'application/json',
'Accept' => 'application/json'
])->get("api/tests/{$test['TestSiteID']}");
$result->assertStatus(200);
$response = $result->getJSON(true);
$this->assertArrayHasKey('testdeftech', $response['data']);
} else {
$this->markTestSkipped('No TEST type data available');
}
}
/**
* Test showing single test includes type-specific details for CALC type
*/
public function testShowIncludesCalcDetailsForCalcType(): void
{
$model = new TestDefSiteModel();
$test = $model->first();
if ($test && $test['TypeCode'] === 'CALC') {
$result = $this->withHeaders([
'Content-Type' => 'application/json',
'Accept' => 'application/json'
])->get("api/tests/{$test['TestSiteID']}");
$result->assertStatus(200);
$response = $result->getJSON(true);
$this->assertArrayHasKey('testdefcal', $response['data']);
} else {
$this->markTestSkipped('No CALC type data available');
}
}
/**
* Test showing single test includes type-specific details for GROUP type
*/
public function testShowIncludesGrpDetailsForGroupType(): void
{
$model = new TestDefSiteModel();
$test = $model->first();
if ($test && $test['TypeCode'] === 'GROUP') {
$result = $this->withHeaders([
'Content-Type' => 'application/json',
'Accept' => 'application/json'
])->get("api/tests/{$test['TestSiteID']}");
$result->assertStatus(200);
$response = $result->getJSON(true);
$this->assertArrayHasKey('testdefgrp', $response['data']);
} else {
$this->markTestSkipped('No GROUP type data available');
}
}
/**
* Test creating a new test
*/
public function testCreateTest(): void
{
$testData = [
'SiteID' => 1,
'TestSiteCode' => 'NEWTEST',
'TestSiteName' => 'New Test',
'TestType' => 1, // TEST type
'Description' => 'Test description',
'SeqScr' => 100,
'SeqRpt' => 100,
'VisibleScr' => 1,
'VisibleRpt' => 1,
'CountStat' => 1
];
$result = $this->withHeaders([
'Content-Type' => 'application/json',
'Accept' => 'application/json'
])->post('api/tests', $testData);
$result->assertStatus(201);
$response = $result->getJSON(true);
$this->assertArrayHasKey('data', $response);
$this->assertArrayHasKey('TestSiteId', $response['data']);
}
/**
* Test creating test with validation error (missing required fields)
*/
public function testCreateTestValidationError(): void
{
$testData = [
'SiteID' => 1
// Missing required fields
];
$result = $this->withHeaders([
'Content-Type' => 'application/json',
'Accept' => 'application/json'
])->post('api/tests', $testData);
$result->assertStatus(400);
}
/**
* Test updating a test
*/
public function testUpdateTest(): void
{
$model = new TestDefSiteModel();
$test = $model->first();
if ($test) {
$updateData = [
'TestSiteID' => $test['TestSiteID'],
'TestSiteName' => 'Updated Test Name',
'Description' => 'Updated description'
];
$result = $this->withHeaders([
'Content-Type' => 'application/json',
'Accept' => 'application/json'
])->patch('api/tests', $updateData);
$result->assertStatus(200);
$response = $result->getJSON(true);
$this->assertEquals('success', $response['status']);
} else {
$this->markTestSkipped('No test data available');
}
}
/**
* Test deleting a test (soft delete)
*/
public function testDeleteTest(): void
{
$model = new TestDefSiteModel();
$test = $model->first();
if ($test) {
$deleteData = [
'TestSiteID' => $test['TestSiteID']
];
$result = $this->withHeaders([
'Content-Type' => 'application/json',
'Accept' => 'application/json'
])->delete('api/tests', $deleteData);
$result->assertStatus(200);
$response = $result->getJSON(true);
$this->assertEquals('success', $response['status']);
$this->assertArrayHasKey('EndDate', $response['data']);
} else {
$this->markTestSkipped('No test data available');
}
}
/**
* Test getting non-existent test returns empty data
*/
public function testShowNonExistentTest(): void
{
$result = $this->withHeaders([
'Content-Type' => 'application/json',
'Accept' => 'application/json'
])->get('api/tests/999999');
$result->assertStatus(200);
$response = $result->getJSON(true);
$this->assertNull($response['data']);
}
/**
* Test test types are correctly mapped from valueset
*/
public function testTestTypesAreMapped(): void
{
$model = new TestDefSiteModel();
$tests = $model->findAll();
$validTypes = ['TEST', 'PARAM', 'CALC', 'GROUP', 'TITLE'];
foreach ($tests as $test) {
if (isset($test['TypeCode'])) {
$this->assertContains($test['TypeCode'], $validTypes);
}
}
}
/**
* Test filtering by visible on screen
*/
public function testIndexFiltersByVisibleScr(): void
{
$result = $this->withHeaders([
'Content-Type' => 'application/json',
'Accept' => 'application/json'
])->get('api/tests?VisibleScr=1');
$result->assertStatus(200);
$response = $result->getJSON(true);
foreach ($response['data'] as $test) {
$this->assertEquals(1, $test['VisibleScr']);
}
}
/**
* Test all test types from seeder are present
*/
public function testAllTestTypesArePresent(): void
{
$model = new TestDefSiteModel();
$tests = $model->findAll();
$typeCodes = array_column($tests, 'TypeCode');
$uniqueTypes = array_unique($typeCodes);
// Check that we have at least TEST and PARAM types from seeder
$this->assertContains('TEST', $uniqueTypes);
$this->assertContains('PARAM', $uniqueTypes);
$this->assertContains('CALC', $uniqueTypes);
$this->assertContains('GROUP', $uniqueTypes);
}
}