2026-01-02 08:33:22 +07:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace Tests\Feature\TestDef;
|
|
|
|
|
|
|
|
|
|
use CodeIgniter\Test\CIUnitTestCase;
|
2026-01-05 16:55:34 +07:00
|
|
|
use CodeIgniter\Test\DatabaseTestTrait;
|
|
|
|
|
use App\Models\Test\TestDefSiteModel;
|
|
|
|
|
use App\Models\Test\TestDefTechModel;
|
|
|
|
|
use App\Models\Test\TestDefCalModel;
|
|
|
|
|
use App\Models\Test\TestDefGrpModel;
|
2026-01-02 08:33:22 +07:00
|
|
|
|
2026-01-05 16:55:34 +07:00
|
|
|
/**
|
|
|
|
|
* Integration tests for Test Definitions API
|
|
|
|
|
*
|
|
|
|
|
* Tests the CRUD operations for test definitions through the API
|
|
|
|
|
*/
|
2026-01-02 08:33:22 +07:00
|
|
|
class TestDefSiteTest extends CIUnitTestCase
|
|
|
|
|
{
|
2026-01-05 16:55:34 +07:00
|
|
|
use DatabaseTestTrait;
|
2026-01-02 08:33:22 +07:00
|
|
|
|
2026-01-05 16:55:34 +07:00
|
|
|
protected $seed = 'App\Database\Seeds\TestSeeder';
|
|
|
|
|
protected $refresh = true;
|
2026-01-02 08:33:22 +07:00
|
|
|
|
2026-01-05 16:55:34 +07:00
|
|
|
/**
|
|
|
|
|
* Test listing all tests returns success response
|
|
|
|
|
*/
|
|
|
|
|
public function testIndexReturnsSuccessResponse(): void
|
2026-01-02 08:33:22 +07:00
|
|
|
{
|
2026-01-05 16:55:34 +07:00
|
|
|
$result = $this->withHeaders([
|
|
|
|
|
'Content-Type' => 'application/json',
|
|
|
|
|
'Accept' => 'application/json'
|
|
|
|
|
])->get('api/tests');
|
2026-01-02 08:33:22 +07:00
|
|
|
|
2026-01-05 16:55:34 +07:00
|
|
|
$result->assertStatus(200);
|
|
|
|
|
$result->assertJSONExact([
|
|
|
|
|
'status' => 'success',
|
|
|
|
|
'message' => 'Data fetched successfully',
|
|
|
|
|
'data' => $result->getJSON(true)['data']
|
|
|
|
|
]);
|
2026-01-02 08:33:22 +07:00
|
|
|
}
|
|
|
|
|
|
2026-01-05 16:55:34 +07:00
|
|
|
/**
|
|
|
|
|
* Test listing all tests returns array
|
|
|
|
|
*/
|
|
|
|
|
public function testIndexReturnsArray(): void
|
|
|
|
|
{
|
|
|
|
|
$result = $this->withHeaders([
|
|
|
|
|
'Content-Type' => 'application/json',
|
|
|
|
|
'Accept' => 'application/json'
|
|
|
|
|
])->get('api/tests');
|
2026-01-02 08:33:22 +07:00
|
|
|
|
2026-01-05 16:55:34 +07:00
|
|
|
$result->assertStatus(200);
|
|
|
|
|
$response = $result->getJSON(true);
|
|
|
|
|
$this->assertIsArray($response['data']);
|
2026-01-02 08:33:22 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2026-01-05 16:55:34 +07:00
|
|
|
* Test index contains test type information
|
2026-01-02 08:33:22 +07:00
|
|
|
*/
|
2026-01-05 16:55:34 +07:00
|
|
|
public function testIndexContainsTypeInformation(): void
|
2026-01-02 08:33:22 +07:00
|
|
|
{
|
2026-01-05 16:55:34 +07:00
|
|
|
$result = $this->withHeaders([
|
|
|
|
|
'Content-Type' => 'application/json',
|
|
|
|
|
'Accept' => 'application/json'
|
|
|
|
|
])->get('api/tests');
|
|
|
|
|
|
2026-01-02 08:33:22 +07:00
|
|
|
$result->assertStatus(200);
|
2026-01-05 16:55:34 +07:00
|
|
|
$response = $result->getJSON(true);
|
|
|
|
|
|
|
|
|
|
if (!empty($response['data'])) {
|
|
|
|
|
$test = $response['data'][0];
|
|
|
|
|
$this->assertArrayHasKey('TypeCode', $test);
|
|
|
|
|
$this->assertArrayHasKey('TypeName', $test);
|
|
|
|
|
}
|
2026-01-02 08:33:22 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2026-01-05 16:55:34 +07:00
|
|
|
* Test filtering by test type
|
2026-01-02 08:33:22 +07:00
|
|
|
*/
|
2026-01-05 16:55:34 +07:00
|
|
|
public function testIndexFiltersByTestType(): void
|
2026-01-02 08:33:22 +07:00
|
|
|
{
|
2026-01-05 16:55:34 +07:00
|
|
|
// Test filtering by TEST type (VID = 1)
|
|
|
|
|
$result = $this->withHeaders([
|
|
|
|
|
'Content-Type' => 'application/json',
|
|
|
|
|
'Accept' => 'application/json'
|
|
|
|
|
])->get('api/tests?TestType=1');
|
|
|
|
|
|
2026-01-02 08:33:22 +07:00
|
|
|
$result->assertStatus(200);
|
2026-01-05 16:55:34 +07:00
|
|
|
$response = $result->getJSON(true);
|
|
|
|
|
|
|
|
|
|
foreach ($response['data'] as $test) {
|
|
|
|
|
$this->assertEquals('TEST', $test['TypeCode']);
|
|
|
|
|
}
|
2026-01-02 08:33:22 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2026-01-05 16:55:34 +07:00
|
|
|
* Test filtering by keyword
|
2026-01-02 08:33:22 +07:00
|
|
|
*/
|
2026-01-05 16:55:34 +07:00
|
|
|
public function testIndexFiltersByKeyword(): void
|
2026-01-02 08:33:22 +07:00
|
|
|
{
|
2026-01-05 16:55:34 +07:00
|
|
|
$result = $this->withHeaders([
|
|
|
|
|
'Content-Type' => 'application/json',
|
|
|
|
|
'Accept' => 'application/json'
|
|
|
|
|
])->get('api/tests?TestSiteName=HB');
|
|
|
|
|
|
2026-01-02 08:33:22 +07:00
|
|
|
$result->assertStatus(200);
|
2026-01-05 16:55:34 +07:00
|
|
|
$response = $result->getJSON(true);
|
|
|
|
|
|
|
|
|
|
if (!empty($response['data'])) {
|
|
|
|
|
foreach ($response['data'] as $test) {
|
|
|
|
|
$this->assertStringContainsString('HB', $test['TestSiteName']);
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-01-02 08:33:22 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2026-01-05 16:55:34 +07:00
|
|
|
* Test showing single test returns success
|
2026-01-02 08:33:22 +07:00
|
|
|
*/
|
2026-01-05 16:55:34 +07:00
|
|
|
public function testShowReturnsSuccess(): void
|
2026-01-02 08:33:22 +07:00
|
|
|
{
|
2026-01-05 16:55:34 +07:00
|
|
|
// 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');
|
2026-01-02 08:33:22 +07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2026-01-05 16:55:34 +07:00
|
|
|
* Test showing single test includes type-specific details for TEST type
|
2026-01-02 08:33:22 +07:00
|
|
|
*/
|
2026-01-05 16:55:34 +07:00
|
|
|
public function testShowIncludesTechDetailsForTestType(): void
|
2026-01-02 08:33:22 +07:00
|
|
|
{
|
2026-01-05 16:55:34 +07:00
|
|
|
$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');
|
|
|
|
|
}
|
2026-01-02 08:33:22 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2026-01-05 16:55:34 +07:00
|
|
|
* Test creating a new test
|
2026-01-02 08:33:22 +07:00
|
|
|
*/
|
2026-01-05 16:55:34 +07:00
|
|
|
public function testCreateTest(): void
|
2026-01-02 08:33:22 +07:00
|
|
|
{
|
|
|
|
|
$testData = [
|
|
|
|
|
'SiteID' => 1,
|
2026-01-05 16:55:34 +07:00
|
|
|
'TestSiteCode' => 'NEWTEST',
|
|
|
|
|
'TestSiteName' => 'New Test',
|
|
|
|
|
'TestType' => 1, // TEST type
|
|
|
|
|
'Description' => 'Test description',
|
|
|
|
|
'SeqScr' => 100,
|
|
|
|
|
'SeqRpt' => 100,
|
2026-01-02 08:33:22 +07:00
|
|
|
'VisibleScr' => 1,
|
|
|
|
|
'VisibleRpt' => 1,
|
2026-01-05 16:55:34 +07:00
|
|
|
'CountStat' => 1
|
2026-01-02 08:33:22 +07:00
|
|
|
];
|
2026-01-05 16:55:34 +07:00
|
|
|
|
|
|
|
|
$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');
|
2026-01-02 08:33:22 +07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2026-01-05 16:55:34 +07:00
|
|
|
* Test deleting a test (soft delete)
|
2026-01-02 08:33:22 +07:00
|
|
|
*/
|
2026-01-05 16:55:34 +07:00
|
|
|
public function testDeleteTest(): void
|
2026-01-02 08:33:22 +07:00
|
|
|
{
|
2026-01-05 16:55:34 +07:00
|
|
|
$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');
|
2026-01-02 08:33:22 +07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2026-01-05 16:55:34 +07:00
|
|
|
* Test getting non-existent test returns empty data
|
2026-01-02 08:33:22 +07:00
|
|
|
*/
|
2026-01-05 16:55:34 +07:00
|
|
|
public function testShowNonExistentTest(): void
|
2026-01-02 08:33:22 +07:00
|
|
|
{
|
2026-01-05 16:55:34 +07:00
|
|
|
$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);
|
2026-01-02 08:33:22 +07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2026-01-05 16:55:34 +07:00
|
|
|
* Test filtering by visible on screen
|
2026-01-02 08:33:22 +07:00
|
|
|
*/
|
2026-01-05 16:55:34 +07:00
|
|
|
public function testIndexFiltersByVisibleScr(): void
|
2026-01-02 08:33:22 +07:00
|
|
|
{
|
2026-01-05 16:55:34 +07:00
|
|
|
$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']);
|
|
|
|
|
}
|
2026-01-02 08:33:22 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2026-01-05 16:55:34 +07:00
|
|
|
* Test all test types from seeder are present
|
2026-01-02 08:33:22 +07:00
|
|
|
*/
|
2026-01-05 16:55:34 +07:00
|
|
|
public function testAllTestTypesArePresent(): void
|
2026-01-02 08:33:22 +07:00
|
|
|
{
|
2026-01-05 16:55:34 +07:00
|
|
|
$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);
|
2026-01-02 08:33:22 +07:00
|
|
|
}
|
|
|
|
|
}
|