Merge branch 'main' of https://github.com/mahdahar/clqms-be
This commit is contained in:
commit
c8e18ed283
@ -230,6 +230,13 @@ $routes->group('api', function ($routes) {
|
|||||||
|
|
||||||
// Specimen
|
// Specimen
|
||||||
$routes->group('specimen', function ($routes) {
|
$routes->group('specimen', function ($routes) {
|
||||||
|
// Container aliases - 'container' and 'containerdef' both point to ContainerDefController
|
||||||
|
$routes->group('container', function ($routes) {
|
||||||
|
$routes->get('/', 'Specimen\ContainerDefController::index');
|
||||||
|
$routes->get('(:num)', 'Specimen\ContainerDefController::show/$1');
|
||||||
|
$routes->post('/', 'Specimen\ContainerDefController::create');
|
||||||
|
$routes->patch('/', 'Specimen\ContainerDefController::update');
|
||||||
|
});
|
||||||
$routes->group('containerdef', function ($routes) {
|
$routes->group('containerdef', function ($routes) {
|
||||||
$routes->get('/', 'Specimen\ContainerDefController::index');
|
$routes->get('/', 'Specimen\ContainerDefController::index');
|
||||||
$routes->get('(:num)', 'Specimen\ContainerDefController::show/$1');
|
$routes->get('(:num)', 'Specimen\ContainerDefController::show/$1');
|
||||||
|
|||||||
55
app/Database/Seeds/AreaGeoSeeder.php
Normal file
55
app/Database/Seeds/AreaGeoSeeder.php
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Database\Seeds;
|
||||||
|
|
||||||
|
use CodeIgniter\Database\Seeder;
|
||||||
|
use CodeIgniter\HTTP\CURLRequest;
|
||||||
|
|
||||||
|
class AreaGeoSeeder extends Seeder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* API configuration for fetching zones data
|
||||||
|
*/
|
||||||
|
protected string $apiUrl = 'https://your-api-domain.com/api/zones';
|
||||||
|
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
// Fetch data from external API
|
||||||
|
$options = [
|
||||||
|
'baseURI' => $this->apiUrl,
|
||||||
|
'timeout' => 30,
|
||||||
|
];
|
||||||
|
|
||||||
|
$client = new CURLRequest($options);
|
||||||
|
|
||||||
|
$response = $client->get('');
|
||||||
|
|
||||||
|
if ($response->getStatusCode() !== 200) {
|
||||||
|
echo "Failed to fetch data from API. Status: " . $response->getStatusCode() . "\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$externalData = $response->getJSON(true);
|
||||||
|
|
||||||
|
if (empty($externalData)) {
|
||||||
|
echo "No data found from API.\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare data for insertion (exclude AreaGeoID to allow auto-increment)
|
||||||
|
$data = [];
|
||||||
|
foreach ($externalData as $row) {
|
||||||
|
$data[] = [
|
||||||
|
'AreaCode' => $row['zonecode'] ?? null,
|
||||||
|
'Class' => $row['zoneclass'] ?? null,
|
||||||
|
'AreaName' => str_replace('_', ' ', $row['zonename'] ?? ''),
|
||||||
|
'Parent' => $row['parentzoneid'] ?? null,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert into local database
|
||||||
|
$this->db->table('areageo')->insertBatch($data);
|
||||||
|
|
||||||
|
echo "Successfully seeded " . count($data) . " area geo records.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,14 +4,17 @@ namespace App\Database\Seeds;
|
|||||||
|
|
||||||
use CodeIgniter\Database\Seeder;
|
use CodeIgniter\Database\Seeder;
|
||||||
|
|
||||||
class DBSeeder extends Seeder {
|
class DBSeeder extends Seeder
|
||||||
public function run() {
|
{
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
$this->call('ValueSetSeeder');
|
$this->call('ValueSetSeeder');
|
||||||
$this->call('ValueSetCountrySeeder');
|
$this->call('ValueSetCountrySeeder');
|
||||||
$this->call('OrganizationSeeder');
|
$this->call('OrganizationSeeder');
|
||||||
$this->call('CounterSeeder');
|
$this->call('CounterSeeder');
|
||||||
$this->call('ContactSeeder');
|
$this->call('ContactSeeder');
|
||||||
$this->call('LocationSeeder');
|
$this->call('LocationSeeder');
|
||||||
|
$this->call('AreaGeoSeeder');
|
||||||
$this->call('SpecimenSeeder');
|
$this->call('SpecimenSeeder');
|
||||||
$this->call('TestSeeder');
|
$this->call('TestSeeder');
|
||||||
$this->call('PatientSeeder');
|
$this->call('PatientSeeder');
|
||||||
|
|||||||
@ -4,17 +4,18 @@ namespace App\Database\Seeds;
|
|||||||
|
|
||||||
use CodeIgniter\Database\Seeder;
|
use CodeIgniter\Database\Seeder;
|
||||||
|
|
||||||
class DummySeeder extends Seeder {
|
class DummySeeder extends Seeder
|
||||||
public function run() {
|
{
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
$now = date('Y-m-d H:i:s');
|
$now = date('Y-m-d H:i:s');
|
||||||
|
|
||||||
// users
|
// users
|
||||||
// Password: 'password' for all users (bcrypt hash)
|
// Password: 'password' for all users (bcrypt hash)
|
||||||
$passwordHash = password_hash('password', PASSWORD_BCRYPT);
|
$passwordHash = password_hash('123', PASSWORD_BCRYPT);
|
||||||
$data = [
|
$data = [
|
||||||
['id' => 1, 'role_id' => 1, 'username' => 'zaka', 'password' => $passwordHash],
|
['id' => 1, 'role_id' => 1, 'username' => 'lisfse', 'password' => $passwordHash],
|
||||||
['id' => 2, 'role_id' => 1, 'username' => 'tes' , 'password' => $passwordHash],
|
['id' => 2, 'role_id' => 1, 'username' => 'tes', 'password' => $passwordHash]
|
||||||
['id' => 3, 'role_id' => 1, 'username' => 'tes2', 'password' => $passwordHash],
|
|
||||||
];
|
];
|
||||||
$this->db->table('users')->insertBatch($data);
|
$this->db->table('users')->insertBatch($data);
|
||||||
|
|
||||||
|
|||||||
@ -74,30 +74,7 @@ class PatientSeeder extends Seeder
|
|||||||
echo "Valueset data seeded.\n";
|
echo "Valueset data seeded.\n";
|
||||||
|
|
||||||
// ========================================
|
// ========================================
|
||||||
// 2. AREAGEO - Province & City
|
// 2. PATIENT - Main patient data
|
||||||
// ========================================
|
|
||||||
$areageos = [
|
|
||||||
['AreaGeoID' => 1, 'AreaCode' => '31', 'Class' => 1, 'AreaName' => 'DKI Jakarta', 'Parent' => null],
|
|
||||||
['AreaGeoID' => 2, 'AreaCode' => '3101', 'Class' => 2, 'AreaName' => 'Jakarta Pusat', 'Parent' => 1],
|
|
||||||
['AreaGeoID' => 3, 'AreaCode' => '3102', 'Class' => 2, 'AreaName' => 'Jakarta Utara', 'Parent' => 1],
|
|
||||||
['AreaGeoID' => 4, 'AreaCode' => '3103', 'Class' => 2, 'AreaName' => 'Jakarta Barat', 'Parent' => 1],
|
|
||||||
['AreaGeoID' => 5, 'AreaCode' => '3104', 'Class' => 2, 'AreaName' => 'Jakarta Selatan', 'Parent' => 1],
|
|
||||||
['AreaGeoID' => 6, 'AreaCode' => '3105', 'Class' => 2, 'AreaName' => 'Jakarta Timur', 'Parent' => 1],
|
|
||||||
['AreaGeoID' => 7, 'AreaCode' => '32', 'Class' => 1, 'AreaName' => 'Jawa Barat', 'Parent' => null],
|
|
||||||
['AreaGeoID' => 8, 'AreaCode' => '3201', 'Class' => 2, 'AreaName' => 'Bandung', 'Parent' => 7],
|
|
||||||
['AreaGeoID' => 9, 'AreaCode' => '3202', 'Class' => 2, 'AreaName' => 'Bogor', 'Parent' => 7],
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($areageos as $area) {
|
|
||||||
$exists = $this->db->table('areageo')->where('AreaGeoID', $area['AreaGeoID'])->get()->getRow();
|
|
||||||
if (!$exists) {
|
|
||||||
$this->db->table('areageo')->insert($area);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
echo "AreaGeo data seeded.\n";
|
|
||||||
|
|
||||||
// ========================================
|
|
||||||
// 3. PATIENT - Main patient data
|
|
||||||
// ========================================
|
// ========================================
|
||||||
$patients = [
|
$patients = [
|
||||||
[
|
[
|
||||||
@ -111,14 +88,14 @@ class PatientSeeder extends Seeder
|
|||||||
'NameLast' => 'Patient',
|
'NameLast' => 'Patient',
|
||||||
'Suffix' => 'S.Kom',
|
'Suffix' => 'S.Kom',
|
||||||
'NameAlias' => 'DummyTest',
|
'NameAlias' => 'DummyTest',
|
||||||
'Gender' => 5, // Male
|
'Gender' => 5,
|
||||||
'PlaceOfBirth' => 'Jakarta',
|
'PlaceOfBirth' => 'Jakarta',
|
||||||
'Birthdate' => '1990-05-15',
|
'Birthdate' => '1990-05-15',
|
||||||
'Street_1' => 'Jl. Sudirman No. 123',
|
'Street_1' => 'Jl. Sudirman No. 123',
|
||||||
'Street_2' => 'RT 01 RW 02',
|
'Street_2' => 'RT 01 RW 02',
|
||||||
'Street_3' => 'Kelurahan Menteng',
|
'Street_3' => 'Kelurahan Menteng',
|
||||||
'City' => '2', // Jakarta Pusat
|
'City' => '2',
|
||||||
'Province' => '1', // DKI Jakarta
|
'Province' => '1',
|
||||||
'ZIP' => '10110',
|
'ZIP' => '10110',
|
||||||
'EmailAddress1' => 'dummy1@test.com',
|
'EmailAddress1' => 'dummy1@test.com',
|
||||||
'EmailAddress2' => 'dummy1alt@test.com',
|
'EmailAddress2' => 'dummy1alt@test.com',
|
||||||
@ -126,13 +103,13 @@ class PatientSeeder extends Seeder
|
|||||||
'MobilePhone' => '081234567890',
|
'MobilePhone' => '081234567890',
|
||||||
'Custodian' => null,
|
'Custodian' => null,
|
||||||
'AccountNumber' => null,
|
'AccountNumber' => null,
|
||||||
'Country' => 221, // Indonesia
|
'Country' => 221,
|
||||||
'Race' => 175, // Asian
|
'Race' => 175,
|
||||||
'MaritalStatus' => 9, // Married
|
'MaritalStatus' => 9,
|
||||||
'Religion' => 206, // Islam
|
'Religion' => 206,
|
||||||
'Ethnic' => 213, // Javanese
|
'Ethnic' => 213,
|
||||||
'Citizenship' => 'WNI',
|
'Citizenship' => 'WNI',
|
||||||
'DeathIndicator' => 17, // Alive
|
'DeathIndicator' => 17,
|
||||||
'TimeOfDeath' => null,
|
'TimeOfDeath' => null,
|
||||||
'LinkTo' => null,
|
'LinkTo' => null,
|
||||||
'CreateDate' => $now,
|
'CreateDate' => $now,
|
||||||
|
|||||||
BIN
docs/prj_clinical laboratory quality management system_3a.docx
Normal file
BIN
docs/prj_clinical laboratory quality management system_3a.docx
Normal file
Binary file not shown.
@ -1,374 +0,0 @@
|
|||||||
<?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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user