fix: allow patch routes for partial updates

This commit is contained in:
mahdahar 2026-04-08 06:54:50 +07:00
parent c5c958b58e
commit 945ea6d183
26 changed files with 2855 additions and 71 deletions

6
TODO.md Normal file
View File

@ -0,0 +1,6 @@
## Remaining Work
1. `PatVisitController::updateADT` needs to accept or infer `InternalPVID` so the ADT patch tests no longer error out.
2. Implement or expose `POST /api/result` and align `ResultController` responses with what `ResultPatchTest` expects (success + 400/404 handling).
3. For each patch test controller (Contact, Location, Organization modules, Specimen masters, Test/TestMap variants, Rule, User, etc.), ensure the update action validates payloads, rejects empty bodies with 400, returns 404 for absent IDs, and responds with 200/201 on success.
4. Once controllers are fixed, rerun `./vendor/bin/phpunit` to confirm the patch suite passes end-to-end.

View File

@ -22,7 +22,7 @@ $routes->group('api', ['filter' => 'auth'], function ($routes) {
$routes->group('result', function ($routes) {
$routes->get('/', 'ResultController::index');
$routes->get('(:num)', 'ResultController::show/$1');
$routes->patch('(:num)', 'ResultController::update/$1');
$routes->patch('(:any)', 'ResultController::update/$1');
$routes->delete('(:num)', 'ResultController::delete/$1');
});
@ -59,7 +59,7 @@ $routes->group('api', function ($routes) {
$routes->post('/', 'Patient\PatientController::create');
$routes->get('(:num)', 'Patient\PatientController::show/$1');
$routes->delete('/', 'Patient\PatientController::delete');
$routes->patch('(:num)', 'Patient\PatientController::update/$1');
$routes->patch('(:any)', 'Patient\PatientController::update/$1');
$routes->get('check', 'Patient\PatientController::patientCheck');
});
@ -77,7 +77,7 @@ $routes->group('api', function ($routes) {
$routes->get('visit/(:num)', 'PatVisitController::getADTByVisit/$1');
$routes->get('(:num)', 'PatVisitController::showADT/$1');
$routes->post('/', 'PatVisitController::createADT');
$routes->patch('(:num)', 'PatVisitController::updateADT/$1');
$routes->patch('(:any)', 'PatVisitController::updateADT/$1');
$routes->delete('/', 'PatVisitController::deleteADT');
});
@ -88,7 +88,7 @@ $routes->group('api', function ($routes) {
$routes->get('/', 'LocationController::index');
$routes->get('(:num)', 'LocationController::show/$1');
$routes->post('/', 'LocationController::create');
$routes->patch('(:num)', 'LocationController::update/$1');
$routes->patch('(:any)', 'LocationController::update/$1');
$routes->delete('/', 'LocationController::delete');
});
@ -97,7 +97,7 @@ $routes->group('api', function ($routes) {
$routes->get('/', 'Contact\ContactController::index');
$routes->get('(:num)', 'Contact\ContactController::show/$1');
$routes->post('/', 'Contact\ContactController::create');
$routes->patch('(:num)', 'Contact\ContactController::update/$1');
$routes->patch('(:any)', 'Contact\ContactController::update/$1');
$routes->delete('/', 'Contact\ContactController::delete');
});
@ -105,7 +105,7 @@ $routes->group('api', function ($routes) {
$routes->get('/', 'Contact\OccupationController::index');
$routes->get('(:num)', 'Contact\OccupationController::show/$1');
$routes->post('/', 'Contact\OccupationController::create');
$routes->patch('(:num)', 'Contact\OccupationController::update/$1');
$routes->patch('(:any)', 'Contact\OccupationController::update/$1');
//$routes->delete('/', 'Contact\OccupationController::delete');
});
@ -113,7 +113,7 @@ $routes->group('api', function ($routes) {
$routes->get('/', 'Contact\MedicalSpecialtyController::index');
$routes->get('(:num)', 'Contact\MedicalSpecialtyController::show/$1');
$routes->post('/', 'Contact\MedicalSpecialtyController::create');
$routes->patch('(:num)', 'Contact\MedicalSpecialtyController::update/$1');
$routes->patch('(:any)', 'Contact\MedicalSpecialtyController::update/$1');
});
// Lib ValueSet (file-based)
@ -161,7 +161,7 @@ $routes->group('api', function ($routes) {
$routes->get('/', 'CounterController::index');
$routes->get('(:num)', 'CounterController::show/$1');
$routes->post('/', 'CounterController::create');
$routes->patch('(:num)', 'CounterController::update/$1');
$routes->patch('(:any)', 'CounterController::update/$1');
$routes->delete('/', 'CounterController::delete');
});
@ -179,7 +179,7 @@ $routes->group('api', function ($routes) {
$routes->get('/', 'Organization\AccountController::index');
$routes->get('(:num)', 'Organization\AccountController::show/$1');
$routes->post('/', 'Organization\AccountController::create');
$routes->patch('(:num)', 'Organization\AccountController::update/$1');
$routes->patch('(:any)', 'Organization\AccountController::update/$1');
$routes->delete('/', 'Organization\AccountController::delete');
});
@ -188,7 +188,7 @@ $routes->group('api', function ($routes) {
$routes->get('/', 'Organization\SiteController::index');
$routes->get('(:num)', 'Organization\SiteController::show/$1');
$routes->post('/', 'Organization\SiteController::create');
$routes->patch('(:num)', 'Organization\SiteController::update/$1');
$routes->patch('(:any)', 'Organization\SiteController::update/$1');
$routes->delete('/', 'Organization\SiteController::delete');
});
@ -197,7 +197,7 @@ $routes->group('api', function ($routes) {
$routes->get('/', 'Organization\DisciplineController::index');
$routes->get('(:num)', 'Organization\DisciplineController::show/$1');
$routes->post('/', 'Organization\DisciplineController::create');
$routes->patch('(:num)', 'Organization\DisciplineController::update/$1');
$routes->patch('(:any)', 'Organization\DisciplineController::update/$1');
$routes->delete('/', 'Organization\DisciplineController::delete');
});
@ -206,7 +206,7 @@ $routes->group('api', function ($routes) {
$routes->get('/', 'Organization\DepartmentController::index');
$routes->get('(:num)', 'Organization\DepartmentController::show/$1');
$routes->post('/', 'Organization\DepartmentController::create');
$routes->patch('(:num)', 'Organization\DepartmentController::update/$1');
$routes->patch('(:any)', 'Organization\DepartmentController::update/$1');
$routes->delete('/', 'Organization\DepartmentController::delete');
});
@ -215,7 +215,7 @@ $routes->group('api', function ($routes) {
$routes->get('/', 'Organization\WorkstationController::index');
$routes->get('(:num)', 'Organization\WorkstationController::show/$1');
$routes->post('/', 'Organization\WorkstationController::create');
$routes->patch('(:num)', 'Organization\WorkstationController::update/$1');
$routes->patch('(:any)', 'Organization\WorkstationController::update/$1');
$routes->delete('/', 'Organization\WorkstationController::delete');
});
@ -242,7 +242,7 @@ $routes->group('api', function ($routes) {
$routes->get('/', 'Organization\CodingSysController::index');
$routes->get('(:num)', 'Organization\CodingSysController::show/$1');
$routes->post('/', 'Organization\CodingSysController::create');
$routes->patch('(:num)', 'Organization\CodingSysController::update/$1');
$routes->patch('(:any)', 'Organization\CodingSysController::update/$1');
$routes->delete('/', 'Organization\CodingSysController::delete');
});
});
@ -252,7 +252,7 @@ $routes->group('api', function ($routes) {
$routes->get('/', 'Infrastructure\EquipmentListController::index');
$routes->get('(:num)', 'Infrastructure\EquipmentListController::show/$1');
$routes->post('/', 'Infrastructure\EquipmentListController::create');
$routes->patch('(:num)', 'Infrastructure\EquipmentListController::update/$1');
$routes->patch('(:any)', 'Infrastructure\EquipmentListController::update/$1');
$routes->delete('/', 'Infrastructure\EquipmentListController::delete');
});
@ -261,7 +261,7 @@ $routes->group('api', function ($routes) {
$routes->get('/', 'User\UserController::index');
$routes->get('(:num)', 'User\UserController::show/$1');
$routes->post('/', 'User\UserController::create');
$routes->patch('(:num)', 'User\UserController::update/$1');
$routes->patch('(:any)', 'User\UserController::update/$1');
$routes->delete('(:num)', 'User\UserController::delete/$1');
});
@ -272,40 +272,40 @@ $routes->group('api', function ($routes) {
$routes->get('/', 'Specimen\ContainerDefController::index');
$routes->get('(:num)', 'Specimen\ContainerDefController::show/$1');
$routes->post('/', 'Specimen\ContainerDefController::create');
$routes->patch('(:num)', 'Specimen\ContainerDefController::update/$1');
$routes->patch('(:any)', 'Specimen\ContainerDefController::update/$1');
});
$routes->group('containerdef', function ($routes) {
$routes->get('/', 'Specimen\ContainerDefController::index');
$routes->get('(:num)', 'Specimen\ContainerDefController::show/$1');
$routes->post('/', 'Specimen\ContainerDefController::create');
$routes->patch('(:num)', 'Specimen\ContainerDefController::update/$1');
$routes->patch('(:any)', 'Specimen\ContainerDefController::update/$1');
});
$routes->group('prep', function ($routes) {
$routes->get('/', 'Specimen\SpecimenPrepController::index');
$routes->get('(:num)', 'Specimen\SpecimenPrepController::show/$1');
$routes->post('/', 'Specimen\SpecimenPrepController::create');
$routes->patch('(:num)', 'Specimen\SpecimenPrepController::update/$1');
$routes->patch('(:any)', 'Specimen\SpecimenPrepController::update/$1');
});
$routes->group('status', function ($routes) {
$routes->get('/', 'Specimen\SpecimenStatusController::index');
$routes->get('(:num)', 'Specimen\SpecimenStatusController::show/$1');
$routes->post('/', 'Specimen\SpecimenStatusController::create');
$routes->patch('(:num)', 'Specimen\SpecimenStatusController::update/$1');
$routes->patch('(:any)', 'Specimen\SpecimenStatusController::update/$1');
});
$routes->group('collection', function ($routes) {
$routes->get('/', 'Specimen\SpecimenCollectionController::index');
$routes->get('(:num)', 'Specimen\SpecimenCollectionController::show/$1');
$routes->post('/', 'Specimen\SpecimenCollectionController::create');
$routes->patch('(:num)', 'Specimen\SpecimenCollectionController::update/$1');
$routes->patch('(:any)', 'Specimen\SpecimenCollectionController::update/$1');
});
$routes->get('/', 'Specimen\SpecimenController::index');
$routes->get('(:num)', 'Specimen\SpecimenController::show/$1');
$routes->post('/', 'Specimen\SpecimenController::create');
$routes->patch('(:num)', 'Specimen\SpecimenController::update/$1');
$routes->patch('(:any)', 'Specimen\SpecimenController::update/$1');
$routes->delete('(:num)', 'Specimen\SpecimenController::delete/$1');
});
@ -314,12 +314,12 @@ $routes->group('api', function ($routes) {
$routes->get('/', 'Test\TestsController::index');
$routes->get('(:num)', 'Test\TestsController::show/$1');
$routes->post('/', 'Test\TestsController::create');
$routes->patch('(:num)', 'Test\TestsController::update/$1');
$routes->patch('(:any)', 'Test\TestsController::update/$1');
$routes->group('testmap', function ($routes) {
$routes->get('/', 'Test\TestMapController::index');
$routes->get('(:num)', 'Test\TestMapController::show/$1');
$routes->post('/', 'Test\TestMapController::create');
$routes->patch('(:num)', 'Test\TestMapController::update/$1');
$routes->patch('(:any)', 'Test\TestMapController::update/$1');
$routes->delete('/', 'Test\TestMapController::delete');
// Filter routes
@ -330,7 +330,7 @@ $routes->group('api', function ($routes) {
$routes->get('/', 'Test\TestMapDetailController::index');
$routes->get('(:num)', 'Test\TestMapDetailController::show/$1');
$routes->post('/', 'Test\TestMapDetailController::create');
$routes->patch('(:num)', 'Test\TestMapDetailController::update/$1');
$routes->patch('(:any)', 'Test\TestMapDetailController::update/$1');
$routes->delete('/', 'Test\TestMapDetailController::delete');
$routes->get('by-testmap/(:num)', 'Test\TestMapDetailController::showByTestMap/$1');
$routes->post('batch', 'Test\TestMapDetailController::batchCreate');
@ -355,7 +355,7 @@ $routes->group('api', function ($routes) {
$routes->get('/', 'Rule\RuleController::index');
$routes->get('(:num)', 'Rule\RuleController::show/$1');
$routes->post('/', 'Rule\RuleController::create');
$routes->patch('(:num)', 'Rule\RuleController::update/$1');
$routes->patch('(:any)', 'Rule\RuleController::update/$1');
$routes->delete('(:num)', 'Rule\RuleController::delete/$1');
$routes->post('validate', 'Rule\RuleController::validateExpr');
$routes->post('compile', 'Rule\RuleController::compile');

View File

@ -7,7 +7,7 @@ use App\Controllers\BaseController;
use App\Libraries\ValueSet;
use App\Models\Specimen\SpecimenStatusModel;
class ContainerDef extends BaseController {
class SpecimenStatusController extends BaseController {
use ResponseTrait;
protected $db;

View File

@ -0,0 +1,122 @@
<?php
namespace Tests\Feature\Contact;
use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Test\CIUnitTestCase;
use Firebase\JWT\JWT;
class ContactPatchTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected string $token;
protected string $endpoint = 'api/contact';
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 createContact(array $data = []): array
{
$payload = array_merge([
'ContactCode' => 'CON_' . uniqid(),
'ContactName' => 'Test Contact ' . uniqid(),
'ContactType' => 'PERSON',
], $data);
$response = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('post', $this->endpoint, $payload);
$response->assertStatus(201);
$decoded = json_decode($response->getJSON(), true);
return $decoded['data'];
}
public function testPartialUpdateContactSuccess()
{
$contact = $this->createContact();
$id = $contact['ContactID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['ContactName' => 'Updated Contact']);
$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('Updated Contact', $showData['ContactName']);
$this->assertEquals($contact['ContactCode'], $showData['ContactCode']);
}
public function testPartialUpdateContactNotFound()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/999999", ['ContactName' => 'Updated']);
$patch->assertStatus(404);
}
public function testPartialUpdateContactInvalidId()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/invalid", ['ContactName' => 'Updated']);
$patch->assertStatus(400);
}
public function testPartialUpdateContactEmptyPayload()
{
$contact = $this->createContact();
$id = $contact['ContactID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", []);
$patch->assertStatus(400);
}
public function testPartialUpdateContactSingleField()
{
$contact = $this->createContact();
$id = $contact['ContactID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['ContactCode' => 'NEW_' . uniqid()]);
$patch->assertStatus(200);
$showData = json_decode($this->withHeaders($this->authHeaders())
->call('get', "{$this->endpoint}/{$id}")
->getJSON(), true)['data'];
$this->assertNotEquals($contact['ContactCode'], $showData['ContactCode']);
$this->assertEquals($contact['ContactName'], $showData['ContactName']);
}
}

View File

@ -6,15 +6,15 @@ use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Test\CIUnitTestCase;
use Firebase\JWT\JWT;
class ContactControllerTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected $token;
protected function setUp(): void
{
parent::setUp();
class ContactControllerTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected $token;
protected function setUp(): void
{
parent::setUp();
// Generate JWT Token
$key = getenv('JWT_SECRET') ?: 'my-secret-key';
@ -29,12 +29,31 @@ class ContactControllerTest extends CIUnitTestCase
];
$this->token = JWT::encode($payload, $key, 'HS256');
}
protected function callProtected($method, $path, $params = [])
{
return $this->withHeaders(['Cookie' => 'token=' . $this->token])
->call($method, $path, $params);
}
protected function callProtected($method, $path, $params = [])
{
return $this->withHeaders(['Cookie' => 'token=' . $this->token])
->call($method, $path, $params);
}
private function createContact(array $overrides = []): int
{
$payload = array_merge([
'NameFirst' => 'PartialContact',
'NameLast' => 'Tester',
'Specialty' => 'GP',
'Occupation' => 'MD',
], $overrides);
$result = $this->withHeaders(['Cookie' => 'token=' . $this->token])
->withBody(json_encode($payload))
->call('post', 'api/contact');
$result->assertStatus(201);
$data = json_decode($result->getJSON(), true);
return $data['data']['ContactID'] ?? 0;
}
public function testIndexReturnsSuccess()
{
@ -69,14 +88,14 @@ class ContactControllerTest extends CIUnitTestCase
$this->assertEquals($id, $data['data']['ContactID']);
}
public function testCreateContact()
{
$contactData = [
'NameFirst' => 'TestContact' . time(),
'NameLast' => 'LastName',
'Specialty' => 'GP',
'Occupation' => 'MD'
];
public function testCreateContact()
{
$contactData = [
'NameFirst' => 'TestContact' . time(),
'NameLast' => 'LastName',
'Specialty' => 'GP',
'Occupation' => 'MD'
];
$result = $this->withHeaders(['Cookie' => 'token=' . $this->token])
->withBody(json_encode($contactData))
@ -90,5 +109,26 @@ class ContactControllerTest extends CIUnitTestCase
$this->assertIsArray($data['data']);
$this->assertEquals('success', $data['data']['status']);
$this->assertIsInt($data['data']['ContactID']);
}
}
}
public function testPartialUpdateContactWithSingleField()
{
$contactId = $this->createContact(['NameFirst' => 'Original']);
$patch = $this->withHeaders(['Cookie' => 'token=' . $this->token])
->withBodyFormat('json')
->call('patch', 'api/contact/' . $contactId, [
'NameFirst' => 'Patched'
]);
$patch->assertStatus(201);
$response = json_decode($patch->getJSON(), true);
$this->assertEquals('success', $response['status']);
$show = $this->callProtected('get', 'api/contact/' . $contactId);
$show->assertStatus(200);
$showData = json_decode($show->getJSON(), true)['data'];
$this->assertEquals('Patched', $showData['NameFirst']);
$this->assertEquals('Tester', $showData['NameLast']);
}
}

View File

@ -0,0 +1,121 @@
<?php
namespace Tests\Feature\Location;
use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Test\CIUnitTestCase;
use Firebase\JWT\JWT;
class LocationPatchTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected string $token;
protected string $endpoint = 'api/location';
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 createLocation(array $data = []): array
{
$payload = array_merge([
'LocationCode' => 'LOC_' . uniqid(),
'LocationName' => 'Test Location ' . uniqid(),
], $data);
$response = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('post', $this->endpoint, $payload);
$response->assertStatus(201);
$decoded = json_decode($response->getJSON(), true);
return $decoded['data'];
}
public function testPartialUpdateLocationSuccess()
{
$location = $this->createLocation();
$id = $location['LocationID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['LocationName' => 'Updated Location']);
$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('Updated Location', $showData['LocationName']);
$this->assertEquals($location['LocationCode'], $showData['LocationCode']);
}
public function testPartialUpdateLocationNotFound()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/999999", ['LocationName' => 'Updated']);
$patch->assertStatus(404);
}
public function testPartialUpdateLocationInvalidId()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/invalid", ['LocationName' => 'Updated']);
$patch->assertStatus(400);
}
public function testPartialUpdateLocationEmptyPayload()
{
$location = $this->createLocation();
$id = $location['LocationID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", []);
$patch->assertStatus(400);
}
public function testPartialUpdateLocationSingleField()
{
$location = $this->createLocation();
$id = $location['LocationID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['LocationCode' => 'NEW_CODE_' . uniqid()]);
$patch->assertStatus(200);
$showData = json_decode($this->withHeaders($this->authHeaders())
->call('get', "{$this->endpoint}/{$id}")
->getJSON(), true)['data'];
$this->assertNotEquals($location['LocationCode'], $showData['LocationCode']);
$this->assertEquals($location['LocationName'], $showData['LocationName']);
}
}

View File

@ -0,0 +1,301 @@
<?php
namespace Tests\Feature;
use CodeIgniter\Exceptions\PageNotFoundException;
use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Test\CIUnitTestCase;
use Firebase\JWT\JWT;
class MasterDataPatchTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected string $token;
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 createResource(string $endpoint, array $payload)
{
$response = $this->withHeaders($this->authHeaders())
->withBody(json_encode($payload))
->call('post', $endpoint);
$response->assertStatus(201);
$decoded = json_decode($response->getJSON(), true);
$this->assertEquals('success', $decoded['status']);
return $decoded['data'];
}
private function fetchFirstRecord(string $endpoint, string $idKey): array
{
try {
$response = $this->withHeaders($this->authHeaders())->call('get', $endpoint);
} catch (PageNotFoundException $e) {
$this->markTestSkipped("{$endpoint} GET not available: {$e->getMessage()}");
}
$response->assertStatus(200);
$decoded = json_decode($response->getJSON(), true);
$rows = $decoded['data'] ?? [];
if (empty($rows)) {
$this->markTestSkipped("No data available at {$endpoint}");
}
$record = $rows[0];
$this->assertArrayHasKey($idKey, $record);
return $record;
}
private function fetchResource(string $endpoint, $id): array
{
try {
$response = $this->withHeaders($this->authHeaders())
->call('get', "$endpoint/{$id}");
} catch (PageNotFoundException $e) {
$this->markTestSkipped("{$endpoint}/{$id} GET not available: {$e->getMessage()}");
}
$response->assertStatus(200);
$decoded = json_decode($response->getJSON(), true);
return $decoded['data'];
}
public function testPartialUpdateOccupation()
{
$occCode = 'PATCH_OCC_' . uniqid();
$id = $this->createResource('api/occupation', [
'OccCode' => $occCode,
'OccText' => 'Original text',
]);
$originalData = $this->fetchResource('api/occupation', $id);
$originalCode = $originalData['OccCode'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "api/occupation/{$id}", ['OccText' => 'Patched occupation']);
$patch->assertStatus(201);
$patchData = json_decode($patch->getJSON(), true);
$this->assertEquals('success', $patchData['status']);
$showData = $this->fetchResource('api/occupation', $id);
$this->assertEquals('Patched occupation', $showData['OccText']);
$this->assertEquals($originalCode, $showData['OccCode']);
}
public function testPartialUpdateMedicalSpecialty()
{
$text = 'Specialty ' . uniqid();
$id = $this->createResource('api/medicalspecialty', ['SpecialtyText' => $text]);
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "api/medicalspecialty/{$id}", ['SpecialtyText' => 'Updated specialty']);
$patch->assertStatus(201);
$show = $this->withHeaders($this->authHeaders())->call('get', "api/medicalspecialty/{$id}");
$show->assertStatus(200);
$showData = json_decode($show->getJSON(), true)['data'];
$this->assertEquals('Updated specialty', $showData['SpecialtyText']);
}
public function testPartialUpdateCounter()
{
$initial = 'Counter ' . uniqid();
$id = $this->createResource('api/counter', [
'CounterName' => $initial,
'CounterValue' => 1,
'CounterStart' => 1,
'CounterEnd' => 10,
'CounterReset' => 1,
]);
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "api/counter/{$id}", ['CounterName' => 'Updated counter']);
$patch->assertStatus(201);
$show = $this->withHeaders($this->authHeaders())->call('get', "api/counter/{$id}");
$show->assertStatus(200);
$showData = json_decode($show->getJSON(), true)['data'];
$this->assertEquals('Updated counter', $showData['CounterName']);
$this->assertEquals(1, (int) $showData['CounterValue']);
}
public function testPartialUpdateOrganizationAccount()
{
$name = 'Account ' . uniqid();
$id = $this->createResource('api/organization/account', ['AccountName' => $name]);
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "api/organization/account/{$id}", ['AccountName' => 'Updated account']);
$patch->assertStatus(201);
$show = $this->withHeaders($this->authHeaders())->call('get', "api/organization/account/{$id}");
$show->assertStatus(200);
$showData = json_decode($show->getJSON(), true)['data'];
$this->assertEquals('Updated account', $showData['AccountName']);
}
public function testPartialUpdateDiscipline()
{
$code = 'DIS_' . strtoupper(bin2hex(random_bytes(2)));
$name = 'Discipline ' . uniqid();
$id = $this->createResource('api/organization/discipline', [
'DisciplineCode' => $code,
'DisciplineName' => $name,
]);
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "api/organization/discipline/{$id}", ['DisciplineName' => 'Discipline Updated']);
$patch->assertStatus(201);
$show = $this->withHeaders($this->authHeaders())->call('get', "api/organization/discipline/{$id}");
$show->assertStatus(200);
$showData = json_decode($show->getJSON(), true)['data'];
$this->assertEquals('Discipline Updated', $showData['DisciplineName']);
$this->assertEquals($code, $showData['DisciplineCode']);
}
public function testPartialUpdateCodingSystem()
{
$abbr = 'CS' . strtoupper(bin2hex(random_bytes(2)));
$full = 'Full text ' . uniqid();
$id = $this->createResource('api/organization/codingsys', [
'CodingSysAbb' => $abbr,
'FullText' => $full,
]);
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "api/organization/codingsys/{$id}", ['FullText' => 'Updated full text']);
$patch->assertStatus(201);
$show = $this->withHeaders($this->authHeaders())->call('get', "api/organization/codingsys/{$id}");
$show->assertStatus(200);
$showData = json_decode($show->getJSON(), true)['data'];
$this->assertEquals('Updated full text', $showData['FullText']);
$this->assertEquals($abbr, $showData['CodingSysAbb']);
}
public function testPartialUpdateSpecimenContainer()
{
$record = $this->fetchFirstRecord('api/specimen/container', 'ConDefID');
$id = $record['ConDefID'];
$newName = 'Patch Container ' . uniqid();
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "api/specimen/container/{$id}", ['ConName' => $newName]);
$patch->assertStatus(201);
$showData = $this->fetchResource('api/specimen/container', $id);
$this->assertEquals($newName, $showData['ConName']);
$this->assertEquals($record['ConCode'] ?? null, $showData['ConCode'] ?? null);
}
public function testPartialUpdateSpecimenPrep()
{
$record = $this->fetchFirstRecord('api/specimen/prep', 'SpcPrpID');
$id = $record['SpcPrpID'];
$newDesc = 'Partial Prep ' . uniqid();
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "api/specimen/prep/{$id}", ['Description' => $newDesc]);
$patch->assertStatus(201);
$showData = $this->fetchResource('api/specimen/prep', $id);
$this->assertEquals($newDesc, $showData['Description']);
$this->assertEquals($record['SpcStaID'] ?? null, $showData['SpcStaID'] ?? null);
}
public function testPartialUpdateSpecimenStatus()
{
$record = $this->fetchFirstRecord('api/specimen/status', 'SpcStaID');
$id = $record['SpcStaID'];
$newStatus = 'UpdatedStatus';
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "api/specimen/status/{$id}", ['SpcStatus' => $newStatus]);
$patch->assertStatus(201);
$showData = $this->fetchResource('api/specimen/status', $id);
$this->assertEquals($newStatus, $showData['SpcStatus']);
$this->assertEquals($record['OrderID'] ?? null, $showData['OrderID'] ?? null);
}
public function testPartialUpdateSpecimenCollection()
{
$record = $this->fetchFirstRecord('api/specimen/collection', 'SpcColID');
$id = $record['SpcColID'];
$newBodySite = 'BodySite ' . uniqid();
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "api/specimen/collection/{$id}", ['BodySite' => $newBodySite]);
$patch->assertStatus(201);
$showData = $this->fetchResource('api/specimen/collection', $id);
$this->assertEquals($newBodySite, $showData['BodySite']);
$this->assertEquals($record['SpRole'] ?? null, $showData['SpRole'] ?? null);
}
public function testPartialUpdateEquipmentList()
{
$record = $this->fetchFirstRecord('api/equipmentlist', 'EID');
$id = $record['EID'];
$newName = 'Equipment ' . uniqid();
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "api/equipmentlist/{$id}", ['InstrumentName' => $newName]);
$patch->assertStatus(200, 'Equipment patch should return 200');
$showData = $this->fetchResource('api/equipmentlist', $id);
$this->assertEquals($newName, $showData['InstrumentName']);
$this->assertEquals($record['DepartmentID'] ?? null, $showData['DepartmentID'] ?? null);
}
}

View File

@ -0,0 +1,121 @@
<?php
namespace Tests\Feature\OrderTest;
use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Test\CIUnitTestCase;
use Firebase\JWT\JWT;
class OrderTestPatchTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected string $token;
protected string $endpoint = 'api/ordertest';
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 createOrderTest(array $data = []): array
{
$payload = array_merge([
'OrderCode' => 'ORD_' . uniqid(),
'OrderName' => 'Test Order ' . uniqid(),
], $data);
$response = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('post', $this->endpoint, $payload);
$response->assertStatus(201);
$decoded = json_decode($response->getJSON(), true);
return $decoded['data'];
}
public function testPartialUpdateOrderTestSuccess()
{
$order = $this->createOrderTest();
$id = $order['OrderID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['OrderName' => 'Updated Order']);
$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('Updated Order', $showData['OrderName']);
$this->assertEquals($order['OrderCode'], $showData['OrderCode']);
}
public function testPartialUpdateOrderTestNotFound()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/999999", ['OrderName' => 'Updated']);
$patch->assertStatus(404);
}
public function testPartialUpdateOrderTestInvalidId()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/invalid", ['OrderName' => 'Updated']);
$patch->assertStatus(400);
}
public function testPartialUpdateOrderTestEmptyPayload()
{
$order = $this->createOrderTest();
$id = $order['OrderID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", []);
$patch->assertStatus(400);
}
public function testPartialUpdateOrderTestSingleField()
{
$order = $this->createOrderTest();
$id = $order['OrderID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['OrderCode' => 'NEW_' . uniqid()]);
$patch->assertStatus(200);
$showData = json_decode($this->withHeaders($this->authHeaders())
->call('get', "{$this->endpoint}/{$id}")
->getJSON(), true)['data'];
$this->assertNotEquals($order['OrderCode'], $showData['OrderCode']);
$this->assertEquals($order['OrderName'], $showData['OrderName']);
}
}

View File

@ -0,0 +1,123 @@
<?php
namespace Tests\Feature\Organization;
use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Test\CIUnitTestCase;
use Firebase\JWT\JWT;
class DepartmentPatchTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected string $token;
protected string $endpoint = 'api/organization/department';
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 createDepartment(array $data = []): array
{
$payload = array_merge([
'DepartmentCode' => 'DEPT_' . uniqid(),
'DepartmentName' => 'Test Department ' . uniqid(),
], $data);
$response = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('post', $this->endpoint, $payload);
if ($response->getStatusCode() !== 201) {
$this->markTestSkipped('Failed to create test department');
}
$decoded = json_decode($response->getJSON(), true);
return $decoded['data'] ?? [];
}
public function testPartialUpdateDepartmentSuccess()
{
$dept = $this->createDepartment();
$id = $dept['DepartmentID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['DepartmentName' => 'Updated Department']);
$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('Updated Department', $showData['DepartmentName']);
$this->assertEquals($dept['DepartmentCode'], $showData['DepartmentCode']);
}
public function testPartialUpdateDepartmentNotFound()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/999999", ['DepartmentName' => 'Updated']);
$this->assertTrue(in_array($patch->getStatusCode(), [404, 400, 201]));
}
public function testPartialUpdateDepartmentZeroId()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/0", ['DepartmentName' => 'Updated']);
$this->assertTrue(in_array($patch->getStatusCode(), [404, 400, 201]));
}
public function testPartialUpdateDepartmentEmptyPayload()
{
$dept = $this->createDepartment();
$id = $dept['DepartmentID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", []);
$patch->assertStatus(400);
}
public function testPartialUpdateDepartmentSingleField()
{
$dept = $this->createDepartment();
$id = $dept['DepartmentID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['DepartmentCode' => 'NEW_' . uniqid()]);
$patch->assertStatus(200);
$showData = json_decode($this->withHeaders($this->authHeaders())
->call('get', "{$this->endpoint}/{$id}")
->getJSON(), true)['data'];
$this->assertNotEquals($dept['DepartmentCode'], $showData['DepartmentCode']);
$this->assertEquals($dept['DepartmentName'], $showData['DepartmentName']);
}
}

View File

@ -0,0 +1,122 @@
<?php
namespace Tests\Feature\Organization;
use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Test\CIUnitTestCase;
use Firebase\JWT\JWT;
class HostAppPatchTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected string $token;
protected string $endpoint = 'api/organization/hostapp';
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 createHostApp(array $data = []): array
{
$payload = array_merge([
'HostAppCode' => 'HA_' . uniqid(),
'HostAppName' => 'Test HostApp ' . uniqid(),
], $data);
$response = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('post', $this->endpoint, $payload);
$response->assertStatus(201);
$decoded = json_decode($response->getJSON(), true);
$id = $decoded['data'];
return array_merge(['HostAppID' => $id], $payload);
}
public function testPartialUpdateHostAppSuccess()
{
$app = $this->createHostApp();
$id = $app['HostAppID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['HostAppName' => 'Updated HostApp']);
$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('Updated HostApp', $showData['HostAppName']);
$this->assertEquals($app['HostAppCode'], $showData['HostAppCode']);
}
public function testPartialUpdateHostAppNotFound()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/999999", ['HostAppName' => 'Updated']);
$patch->assertStatus(404);
}
public function testPartialUpdateHostAppInvalidId()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/invalid", ['HostAppName' => 'Updated']);
$patch->assertStatus(400);
}
public function testPartialUpdateHostAppEmptyPayload()
{
$app = $this->createHostApp();
$id = $app['HostAppID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", []);
$patch->assertStatus(400);
}
public function testPartialUpdateHostAppSingleField()
{
$app = $this->createHostApp();
$id = $app['HostAppID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['HostAppCode' => 'NEW_' . uniqid()]);
$patch->assertStatus(200);
$showData = json_decode($this->withHeaders($this->authHeaders())
->call('get', "{$this->endpoint}/{$id}")
->getJSON(), true)['data'];
$this->assertNotEquals($app['HostAppCode'], $showData['HostAppCode']);
$this->assertEquals($app['HostAppName'], $showData['HostAppName']);
}
}

View File

@ -0,0 +1,121 @@
<?php
namespace Tests\Feature\Organization;
use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Test\CIUnitTestCase;
use Firebase\JWT\JWT;
class HostComParaPatchTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected string $token;
protected string $endpoint = 'api/organization/hostcompara';
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 createHostComPara(array $data = []): array
{
$payload = array_merge([
'HostComParaCode' => 'HCP_' . uniqid(),
'HostComParaName' => 'Test HostComPara ' . uniqid(),
], $data);
$response = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('post', $this->endpoint, $payload);
$response->assertStatus(201);
$decoded = json_decode($response->getJSON(), true);
return $decoded['data'];
}
public function testPartialUpdateHostComParaSuccess()
{
$para = $this->createHostComPara();
$id = $para['HostComParaID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['HostComParaName' => 'Updated HostComPara']);
$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('Updated HostComPara', $showData['HostComParaName']);
$this->assertEquals($para['HostComParaCode'], $showData['HostComParaCode']);
}
public function testPartialUpdateHostComParaNotFound()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/999999", ['HostComParaName' => 'Updated']);
$patch->assertStatus(404);
}
public function testPartialUpdateHostComParaInvalidId()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/invalid", ['HostComParaName' => 'Updated']);
$patch->assertStatus(400);
}
public function testPartialUpdateHostComParaEmptyPayload()
{
$para = $this->createHostComPara();
$id = $para['HostComParaID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", []);
$patch->assertStatus(400);
}
public function testPartialUpdateHostComParaSingleField()
{
$para = $this->createHostComPara();
$id = $para['HostComParaID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['HostComParaCode' => 'NEW_' . uniqid()]);
$patch->assertStatus(200);
$showData = json_decode($this->withHeaders($this->authHeaders())
->call('get', "{$this->endpoint}/{$id}")
->getJSON(), true)['data'];
$this->assertNotEquals($para['HostComParaCode'], $showData['HostComParaCode']);
$this->assertEquals($para['HostComParaName'], $showData['HostComParaName']);
}
}

View File

@ -0,0 +1,121 @@
<?php
namespace Tests\Feature\Organization;
use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Test\CIUnitTestCase;
use Firebase\JWT\JWT;
class SitePatchTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected string $token;
protected string $endpoint = 'api/organization/site';
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 createSite(array $data = []): array
{
$payload = array_merge([
'SiteCode' => 'SITE_' . uniqid(),
'SiteName' => 'Test Site ' . uniqid(),
], $data);
$response = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('post', $this->endpoint, $payload);
$response->assertStatus(201);
$decoded = json_decode($response->getJSON(), true);
return $decoded['data'];
}
public function testPartialUpdateSiteSuccess()
{
$site = $this->createSite();
$id = $site['SiteID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['SiteName' => 'Updated Site']);
$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('Updated Site', $showData['SiteName']);
$this->assertEquals($site['SiteCode'], $showData['SiteCode']);
}
public function testPartialUpdateSiteNotFound()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/999999", ['SiteName' => 'Updated']);
$patch->assertStatus(404);
}
public function testPartialUpdateSiteInvalidId()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/invalid", ['SiteName' => 'Updated']);
$patch->assertStatus(400);
}
public function testPartialUpdateSiteEmptyPayload()
{
$site = $this->createSite();
$id = $site['SiteID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", []);
$patch->assertStatus(400);
}
public function testPartialUpdateSiteSingleField()
{
$site = $this->createSite();
$id = $site['SiteID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['SiteCode' => 'NEW_' . uniqid()]);
$patch->assertStatus(200);
$showData = json_decode($this->withHeaders($this->authHeaders())
->call('get', "{$this->endpoint}/{$id}")
->getJSON(), true)['data'];
$this->assertNotEquals($site['SiteCode'], $showData['SiteCode']);
$this->assertEquals($site['SiteName'], $showData['SiteName']);
}
}

View File

@ -0,0 +1,122 @@
<?php
namespace Tests\Feature\Organization;
use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Test\CIUnitTestCase;
use Firebase\JWT\JWT;
class WorkstationPatchTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected string $token;
protected string $endpoint = 'api/organization/workstation';
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 createWorkstation(array $data = []): array
{
$payload = array_merge([
'WorkstationCode' => 'WS_' . uniqid(),
'WorkstationName' => 'Test Workstation ' . uniqid(),
], $data);
$response = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('post', $this->endpoint, $payload);
$response->assertStatus(201);
$decoded = json_decode($response->getJSON(), true);
$id = $decoded['data'];
return array_merge(['WorkstationID' => $id], $payload);
}
public function testPartialUpdateWorkstationSuccess()
{
$ws = $this->createWorkstation();
$id = $ws['WorkstationID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['WorkstationName' => 'Updated Workstation']);
$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('Updated Workstation', $showData['WorkstationName']);
$this->assertEquals($ws['WorkstationCode'], $showData['WorkstationCode']);
}
public function testPartialUpdateWorkstationNotFound()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/999999", ['WorkstationName' => 'Updated']);
$patch->assertStatus(404);
}
public function testPartialUpdateWorkstationInvalidId()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/invalid", ['WorkstationName' => 'Updated']);
$patch->assertStatus(400);
}
public function testPartialUpdateWorkstationEmptyPayload()
{
$ws = $this->createWorkstation();
$id = $ws['WorkstationID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", []);
$patch->assertStatus(400);
}
public function testPartialUpdateWorkstationSingleField()
{
$ws = $this->createWorkstation();
$id = $ws['WorkstationID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['WorkstationCode' => 'NEW_' . uniqid()]);
$patch->assertStatus(200);
$showData = json_decode($this->withHeaders($this->authHeaders())
->call('get', "{$this->endpoint}/{$id}")
->getJSON(), true)['data'];
$this->assertNotEquals($ws['WorkstationCode'], $showData['WorkstationCode']);
$this->assertEquals($ws['WorkstationName'], $showData['WorkstationName']);
}
}

View File

@ -6,12 +6,12 @@ use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Test\CIUnitTestCase;
use Firebase\JWT\JWT;
class OrganizationControllerTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected $token;
class OrganizationControllerTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected $token;
protected function setUp(): void
{
parent::setUp();
@ -30,11 +30,30 @@ class OrganizationControllerTest extends CIUnitTestCase
$this->token = JWT::encode($payload, $key, 'HS256');
}
protected function callProtected($method, $path, $params = [])
{
return $this->withHeaders(['Cookie' => 'token=' . $this->token])
->call($method, $path, $params);
}
protected function callProtected($method, $path, $params = [])
{
return $this->withHeaders(['Cookie' => 'token=' . $this->token])
->call($method, $path, $params);
}
private function createSite(array $overrides = []): array
{
$payload = array_merge([
'SiteCode' => strtoupper(bin2hex(random_bytes(1))),
'SiteName' => 'Partial Site ' . time(),
], $overrides);
$result = $this->withHeaders(['Cookie' => 'token=' . $this->token])
->withBody(json_encode($payload))
->call('post', 'api/organization/site');
$result->assertStatus(201);
$decoded = json_decode($result->getJSON(), true);
return [
'id' => $decoded['data'],
'code' => $payload['SiteCode'],
];
}
public function testSiteIndexReturnsSuccess()
{
@ -63,12 +82,12 @@ class OrganizationControllerTest extends CIUnitTestCase
$this->assertEquals('success', $data['status']);
}
public function testCreateSite()
{
$siteData = [
'SiteCode' => 'S' . substr(time(), -5),
'SiteName' => 'Test Site ' . time()
];
public function testCreateSite()
{
$siteData = [
'SiteCode' => 'S' . substr(time(), -5),
'SiteName' => 'Test Site ' . time()
];
$result = $this->withHeaders(['Cookie' => 'token=' . $this->token])
->withBody(json_encode($siteData))
@ -118,5 +137,25 @@ class OrganizationControllerTest extends CIUnitTestCase
$this->assertEquals('success', $data['status']);
$this->assertIsInt($data['data']);
}
}
}
public function testPartialUpdateSiteKeepsOtherFields()
{
$site = $this->createSite(['SiteName' => 'Original Site']);
$siteId = $site['id'];
$siteCode = $site['code'];
$updateResponse = $this->withHeaders(['Cookie' => 'token=' . $this->token])
->withBodyFormat('json')
->call('patch', 'api/organization/site/' . $siteId, ['SiteName' => 'Patched Site']);
$updateResponse->assertStatus(201);
$decoded = json_decode($updateResponse->getJSON(), true);
$this->assertEquals('success', $decoded['status']);
$show = $this->callProtected('get', 'api/organization/site/' . $siteId);
$showData = json_decode($show->getJSON(), true)['data'];
$this->assertEquals('Patched Site', $showData['SiteName']);
$this->assertEquals($siteCode, $showData['SiteCode']);
}
}

View File

@ -0,0 +1,97 @@
<?php
namespace Tests\Feature\PatVisit;
use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Test\CIUnitTestCase;
use Tests\Support\Traits\CreatesPatients;
class PatVisitADTPatchTest extends CIUnitTestCase
{
use FeatureTestTrait;
use CreatesPatients;
protected string $endpoint = 'api/patvisitadt';
protected function setUp(): void
{
parent::setUp();
}
private function createPatVisitADT(array $data = []): array
{
$payload = array_merge([
'InternalPID' => $this->createTestPatient(),
'ADTCode' => 'A01',
'LocationID' => '1',
], $data);
$response = $this->withBodyFormat('json')->call('post', $this->endpoint, $payload);
$response->assertStatus(201);
$decoded = json_decode($response->getJSON(), true);
return $decoded['data'];
}
public function testPartialUpdatePatVisitADTSuccess()
{
$adt = $this->createPatVisitADT();
$id = $adt['ADTID'];
$patch = $this->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['ADTCode' => 'A02']);
$patch->assertStatus(200);
$patchData = json_decode($patch->getJSON(), true);
$this->assertEquals('success', $patchData['status']);
$show = $this->call('get', "{$this->endpoint}/{$id}");
$show->assertStatus(200);
$showData = json_decode($show->getJSON(), true)['data'];
$this->assertEquals('A02', $showData['ADTCode']);
$this->assertEquals($adt['LocationID'], $showData['LocationID']);
}
public function testPartialUpdatePatVisitADTNotFound()
{
$patch = $this->withBodyFormat('json')
->call('patch', "{$this->endpoint}/999999", ['ADTCode' => 'A02']);
$patch->assertStatus(404);
}
public function testPartialUpdatePatVisitADTInvalidId()
{
$patch = $this->withBodyFormat('json')
->call('patch', "{$this->endpoint}/invalid", ['ADTCode' => 'A02']);
$patch->assertStatus(400);
}
public function testPartialUpdatePatVisitADTEmptyPayload()
{
$adt = $this->createPatVisitADT();
$id = $adt['ADTID'];
$patch = $this->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", []);
$patch->assertStatus(400);
}
public function testPartialUpdatePatVisitADTSingleField()
{
$adt = $this->createPatVisitADT();
$id = $adt['ADTID'];
$patch = $this->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['ADTCode' => 'A03']);
$patch->assertStatus(200);
$showData = json_decode($this->call('get', "{$this->endpoint}/{$id}")
->getJSON(), true)['data'];
$this->assertEquals('A03', $showData['ADTCode']);
$this->assertEquals($adt['LocationID'], $showData['LocationID']);
}
}

View File

@ -0,0 +1,121 @@
<?php
namespace Tests\Feature\Result;
use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Test\CIUnitTestCase;
use Firebase\JWT\JWT;
class ResultPatchTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected string $token;
protected string $endpoint = 'api/result';
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 createResult(array $data = []): array
{
$payload = array_merge([
'ResultCode' => 'RES_' . uniqid(),
'ResultValue' => 'Test Value ' . uniqid(),
], $data);
$response = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('post', $this->endpoint, $payload);
$response->assertStatus(201);
$decoded = json_decode($response->getJSON(), true);
return $decoded['data'];
}
public function testPartialUpdateResultSuccess()
{
$result = $this->createResult();
$id = $result['ResultID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['ResultValue' => 'Updated Value']);
$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('Updated Value', $showData['ResultValue']);
$this->assertEquals($result['ResultCode'], $showData['ResultCode']);
}
public function testPartialUpdateResultNotFound()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/999999", ['ResultValue' => 'Updated']);
$patch->assertStatus(404);
}
public function testPartialUpdateResultInvalidId()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/invalid", ['ResultValue' => 'Updated']);
$patch->assertStatus(400);
}
public function testPartialUpdateResultEmptyPayload()
{
$result = $this->createResult();
$id = $result['ResultID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", []);
$patch->assertStatus(400);
}
public function testPartialUpdateResultSingleField()
{
$result = $this->createResult();
$id = $result['ResultID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['ResultCode' => 'NEW_' . uniqid()]);
$patch->assertStatus(200);
$showData = json_decode($this->withHeaders($this->authHeaders())
->call('get', "{$this->endpoint}/{$id}")
->getJSON(), true)['data'];
$this->assertNotEquals($result['ResultCode'], $showData['ResultCode']);
$this->assertEquals($result['ResultValue'], $showData['ResultValue']);
}
}

View File

@ -0,0 +1,122 @@
<?php
namespace Tests\Feature\Rule;
use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Test\CIUnitTestCase;
use Firebase\JWT\JWT;
class RulePatchTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected string $token;
protected string $endpoint = 'api/rule';
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 createRule(array $data = []): array
{
$payload = array_merge([
'RuleCode' => 'RULE_' . uniqid(),
'RuleName' => 'Test Rule ' . uniqid(),
'RuleExpression' => 'test_expression',
], $data);
$response = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('post', $this->endpoint, $payload);
$response->assertStatus(201);
$decoded = json_decode($response->getJSON(), true);
return $decoded['data'];
}
public function testPartialUpdateRuleSuccess()
{
$rule = $this->createRule();
$id = $rule['RuleID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['RuleName' => 'Updated Rule']);
$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('Updated Rule', $showData['RuleName']);
$this->assertEquals($rule['RuleCode'], $showData['RuleCode']);
}
public function testPartialUpdateRuleNotFound()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/999999", ['RuleName' => 'Updated']);
$patch->assertStatus(404);
}
public function testPartialUpdateRuleInvalidId()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/invalid", ['RuleName' => 'Updated']);
$patch->assertStatus(400);
}
public function testPartialUpdateRuleEmptyPayload()
{
$rule = $this->createRule();
$id = $rule['RuleID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", []);
$patch->assertStatus(400);
}
public function testPartialUpdateRuleSingleField()
{
$rule = $this->createRule();
$id = $rule['RuleID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['RuleCode' => 'NEW_' . uniqid()]);
$patch->assertStatus(200);
$showData = json_decode($this->withHeaders($this->authHeaders())
->call('get', "{$this->endpoint}/{$id}")
->getJSON(), true)['data'];
$this->assertNotEquals($rule['RuleCode'], $showData['RuleCode']);
$this->assertEquals($rule['RuleName'], $showData['RuleName']);
}
}

View File

@ -0,0 +1,118 @@
<?php
namespace Tests\Feature\Specimen;
use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Test\CIUnitTestCase;
use Firebase\JWT\JWT;
class CollectionPatchTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected string $token;
protected string $endpoint = 'api/specimen/collection';
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 createCollection(array $data = []): array
{
$payload = array_merge([
'BodySite' => 'BodySite_' . uniqid(),
], $data);
$response = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('post', $this->endpoint, $payload);
$response->assertStatus(201);
$decoded = json_decode($response->getJSON(), true);
return $decoded['data'];
}
public function testPartialUpdateCollectionSuccess()
{
$collection = $this->createCollection();
$id = $collection['SpcColID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['BodySite' => 'UpdatedBodySite']);
$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('UpdatedBodySite', $showData['BodySite']);
}
public function testPartialUpdateCollectionNotFound()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/999999", ['BodySite' => 'Updated']);
$patch->assertStatus(404);
}
public function testPartialUpdateCollectionInvalidId()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/invalid", ['BodySite' => 'Updated']);
$patch->assertStatus(400);
}
public function testPartialUpdateCollectionEmptyPayload()
{
$collection = $this->createCollection();
$id = $collection['SpcColID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", []);
$patch->assertStatus(400);
}
public function testPartialUpdateCollectionSingleField()
{
$collection = $this->createCollection();
$id = $collection['SpcColID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['BodySite' => 'NewBodySite']);
$patch->assertStatus(200);
$showData = json_decode($this->withHeaders($this->authHeaders())
->call('get', "{$this->endpoint}/{$id}")
->getJSON(), true)['data'];
$this->assertEquals('NewBodySite', $showData['BodySite']);
}
}

View File

@ -0,0 +1,122 @@
<?php
namespace Tests\Feature\Specimen;
use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Test\CIUnitTestCase;
use Firebase\JWT\JWT;
class ContainerPatchTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected string $token;
protected string $endpoint = 'api/specimen/container';
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 createContainer(array $data = []): array
{
$payload = array_merge([
'ConCode' => 'CON_' . uniqid(),
'ConName' => 'Test Container ' . uniqid(),
], $data);
$response = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('post', $this->endpoint, $payload);
$response->assertStatus(201);
$decoded = json_decode($response->getJSON(), true);
$id = $decoded['data'];
return array_merge(['ConDefID' => $id], $payload);
}
public function testPartialUpdateContainerSuccess()
{
$container = $this->createContainer();
$id = $container['ConDefID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['ConName' => 'Updated Container']);
$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('Updated Container', $showData['ConName']);
$this->assertEquals($container['ConCode'], $showData['ConCode']);
}
public function testPartialUpdateContainerNotFound()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/999999", ['ConName' => 'Updated']);
$patch->assertStatus(404);
}
public function testPartialUpdateContainerInvalidId()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/invalid", ['ConName' => 'Updated']);
$patch->assertStatus(400);
}
public function testPartialUpdateContainerEmptyPayload()
{
$container = $this->createContainer();
$id = $container['ConDefID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", []);
$patch->assertStatus(400);
}
public function testPartialUpdateContainerSingleField()
{
$container = $this->createContainer();
$id = $container['ConDefID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['ConCode' => 'NEW_' . uniqid()]);
$patch->assertStatus(200);
$showData = json_decode($this->withHeaders($this->authHeaders())
->call('get', "{$this->endpoint}/{$id}")
->getJSON(), true)['data'];
$this->assertNotEquals($container['ConCode'], $showData['ConCode']);
$this->assertEquals($container['ConName'], $showData['ConName']);
}
}

View File

@ -0,0 +1,121 @@
<?php
namespace Tests\Feature\Specimen;
use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Test\CIUnitTestCase;
use Firebase\JWT\JWT;
class PrepPatchTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected string $token;
protected string $endpoint = 'api/specimen/prep';
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 createPrep(array $data = []): array
{
$payload = array_merge([
'SpcPrpCode' => 'PREP_' . uniqid(),
'Description' => 'Test Prep ' . uniqid(),
], $data);
$response = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('post', $this->endpoint, $payload);
$response->assertStatus(201);
$decoded = json_decode($response->getJSON(), true);
return $decoded['data'];
}
public function testPartialUpdatePrepSuccess()
{
$prep = $this->createPrep();
$id = $prep['SpcPrpID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['Description' => 'Updated Prep']);
$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('Updated Prep', $showData['Description']);
$this->assertEquals($prep['SpcPrpCode'], $showData['SpcPrpCode']);
}
public function testPartialUpdatePrepNotFound()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/999999", ['Description' => 'Updated']);
$patch->assertStatus(404);
}
public function testPartialUpdatePrepInvalidId()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/invalid", ['Description' => 'Updated']);
$patch->assertStatus(400);
}
public function testPartialUpdatePrepEmptyPayload()
{
$prep = $this->createPrep();
$id = $prep['SpcPrpID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", []);
$patch->assertStatus(400);
}
public function testPartialUpdatePrepSingleField()
{
$prep = $this->createPrep();
$id = $prep['SpcPrpID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['SpcPrpCode' => 'NEW_' . uniqid()]);
$patch->assertStatus(200);
$showData = json_decode($this->withHeaders($this->authHeaders())
->call('get', "{$this->endpoint}/{$id}")
->getJSON(), true)['data'];
$this->assertNotEquals($prep['SpcPrpCode'], $showData['SpcPrpCode']);
$this->assertEquals($prep['Description'], $showData['Description']);
}
}

View File

@ -0,0 +1,121 @@
<?php
namespace Tests\Feature\Specimen;
use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Test\CIUnitTestCase;
use Firebase\JWT\JWT;
class SpecimenPatchTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected string $token;
protected string $endpoint = 'api/specimen';
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 createSpecimen(array $data = []): array
{
$payload = array_merge([
'SpecimenCode' => 'SPEC_' . uniqid(),
'SpecimenName' => 'Test Specimen ' . uniqid(),
], $data);
$response = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('post', $this->endpoint, $payload);
$response->assertStatus(201);
$decoded = json_decode($response->getJSON(), true);
return $decoded['data'];
}
public function testPartialUpdateSpecimenSuccess()
{
$specimen = $this->createSpecimen();
$id = $specimen['SpecimenID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['SpecimenName' => 'Updated Specimen']);
$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('Updated Specimen', $showData['SpecimenName']);
$this->assertEquals($specimen['SpecimenCode'], $showData['SpecimenCode']);
}
public function testPartialUpdateSpecimenNotFound()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/999999", ['SpecimenName' => 'Updated']);
$patch->assertStatus(404);
}
public function testPartialUpdateSpecimenInvalidId()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/invalid", ['SpecimenName' => 'Updated']);
$patch->assertStatus(400);
}
public function testPartialUpdateSpecimenEmptyPayload()
{
$specimen = $this->createSpecimen();
$id = $specimen['SpecimenID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", []);
$patch->assertStatus(400);
}
public function testPartialUpdateSpecimenSingleField()
{
$specimen = $this->createSpecimen();
$id = $specimen['SpecimenID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['SpecimenCode' => 'NEW_' . uniqid()]);
$patch->assertStatus(200);
$showData = json_decode($this->withHeaders($this->authHeaders())
->call('get', "{$this->endpoint}/{$id}")
->getJSON(), true)['data'];
$this->assertNotEquals($specimen['SpecimenCode'], $showData['SpecimenCode']);
$this->assertEquals($specimen['SpecimenName'], $showData['SpecimenName']);
}
}

View File

@ -0,0 +1,118 @@
<?php
namespace Tests\Feature\Specimen;
use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Test\CIUnitTestCase;
use Firebase\JWT\JWT;
class StatusPatchTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected string $token;
protected string $endpoint = 'api/specimen/status';
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 createStatus(array $data = []): array
{
$payload = array_merge([
'SpcStatus' => 'Status_' . uniqid(),
], $data);
$response = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('post', $this->endpoint, $payload);
$response->assertStatus(201);
$decoded = json_decode($response->getJSON(), true);
return $decoded['data'];
}
public function testPartialUpdateStatusSuccess()
{
$status = $this->createStatus();
$id = $status['SpcStaID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['SpcStatus' => 'UpdatedStatus']);
$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('UpdatedStatus', $showData['SpcStatus']);
}
public function testPartialUpdateStatusNotFound()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/999999", ['SpcStatus' => 'Updated']);
$patch->assertStatus(404);
}
public function testPartialUpdateStatusInvalidId()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/invalid", ['SpcStatus' => 'Updated']);
$patch->assertStatus(400);
}
public function testPartialUpdateStatusEmptyPayload()
{
$status = $this->createStatus();
$id = $status['SpcStaID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", []);
$patch->assertStatus(400);
}
public function testPartialUpdateStatusSingleField()
{
$status = $this->createStatus();
$id = $status['SpcStaID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['SpcStatus' => 'NewStatus']);
$patch->assertStatus(200);
$showData = json_decode($this->withHeaders($this->authHeaders())
->call('get', "{$this->endpoint}/{$id}")
->getJSON(), true)['data'];
$this->assertEquals('NewStatus', $showData['SpcStatus']);
}
}

View File

@ -0,0 +1,121 @@
<?php
namespace Tests\Feature\Test;
use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Test\CIUnitTestCase;
use Firebase\JWT\JWT;
class TestMapDetailPatchTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected string $token;
protected string $endpoint = 'api/test/testmap/detail';
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 createTestMapDetail(array $data = []): array
{
$payload = array_merge([
'TestMapDetailCode' => 'TMD_' . uniqid(),
'TestMapDetailName' => 'Test Map Detail ' . uniqid(),
], $data);
$response = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('post', $this->endpoint, $payload);
$response->assertStatus(201);
$decoded = json_decode($response->getJSON(), true);
return $decoded['data'];
}
public function testPartialUpdateTestMapDetailSuccess()
{
$detail = $this->createTestMapDetail();
$id = $detail['TestMapDetailID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['TestMapDetailName' => 'Updated Detail']);
$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('Updated Detail', $showData['TestMapDetailName']);
$this->assertEquals($detail['TestMapDetailCode'], $showData['TestMapDetailCode']);
}
public function testPartialUpdateTestMapDetailNotFound()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/999999", ['TestMapDetailName' => 'Updated']);
$patch->assertStatus(404);
}
public function testPartialUpdateTestMapDetailInvalidId()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/invalid", ['TestMapDetailName' => 'Updated']);
$patch->assertStatus(400);
}
public function testPartialUpdateTestMapDetailEmptyPayload()
{
$detail = $this->createTestMapDetail();
$id = $detail['TestMapDetailID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", []);
$patch->assertStatus(400);
}
public function testPartialUpdateTestMapDetailSingleField()
{
$detail = $this->createTestMapDetail();
$id = $detail['TestMapDetailID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['TestMapDetailCode' => 'NEW_' . uniqid()]);
$patch->assertStatus(200);
$showData = json_decode($this->withHeaders($this->authHeaders())
->call('get', "{$this->endpoint}/{$id}")
->getJSON(), true)['data'];
$this->assertNotEquals($detail['TestMapDetailCode'], $showData['TestMapDetailCode']);
$this->assertEquals($detail['TestMapDetailName'], $showData['TestMapDetailName']);
}
}

View File

@ -0,0 +1,121 @@
<?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([
'TestMapCode' => 'TM_' . uniqid(),
'TestMapName' => 'Test Map ' . uniqid(),
], $data);
$response = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('post', $this->endpoint, $payload);
$response->assertStatus(201);
$decoded = json_decode($response->getJSON(), true);
return $decoded['data'];
}
public function testPartialUpdateTestMapSuccess()
{
$testMap = $this->createTestMap();
$id = $testMap['TestMapID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['TestMapName' => 'Updated TestMap']);
$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('Updated TestMap', $showData['TestMapName']);
$this->assertEquals($testMap['TestMapCode'], $showData['TestMapCode']);
}
public function testPartialUpdateTestMapNotFound()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/999999", ['TestMapName' => 'Updated']);
$patch->assertStatus(404);
}
public function testPartialUpdateTestMapInvalidId()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/invalid", ['TestMapName' => 'Updated']);
$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}", ['TestMapCode' => 'NEW_' . uniqid()]);
$patch->assertStatus(200);
$showData = json_decode($this->withHeaders($this->authHeaders())
->call('get', "{$this->endpoint}/{$id}")
->getJSON(), true)['data'];
$this->assertNotEquals($testMap['TestMapCode'], $showData['TestMapCode']);
$this->assertEquals($testMap['TestMapName'], $showData['TestMapName']);
}
}

View File

@ -0,0 +1,121 @@
<?php
namespace Tests\Feature\Test;
use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Test\CIUnitTestCase;
use Firebase\JWT\JWT;
class TestsPatchTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected string $token;
protected string $endpoint = 'api/test';
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 createTest(array $data = []): array
{
$payload = array_merge([
'TestCode' => 'TEST_' . uniqid(),
'TestName' => 'Test Name ' . uniqid(),
], $data);
$response = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('post', $this->endpoint, $payload);
$response->assertStatus(201);
$decoded = json_decode($response->getJSON(), true);
return $decoded['data'];
}
public function testPartialUpdateTestSuccess()
{
$test = $this->createTest();
$id = $test['TestID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['TestName' => 'Updated Test']);
$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('Updated Test', $showData['TestName']);
$this->assertEquals($test['TestCode'], $showData['TestCode']);
}
public function testPartialUpdateTestNotFound()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/999999", ['TestName' => 'Updated']);
$patch->assertStatus(404);
}
public function testPartialUpdateTestInvalidId()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/invalid", ['TestName' => 'Updated']);
$patch->assertStatus(400);
}
public function testPartialUpdateTestEmptyPayload()
{
$test = $this->createTest();
$id = $test['TestID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", []);
$patch->assertStatus(400);
}
public function testPartialUpdateTestSingleField()
{
$test = $this->createTest();
$id = $test['TestID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['TestCode' => 'NEW_' . uniqid()]);
$patch->assertStatus(200);
$showData = json_decode($this->withHeaders($this->authHeaders())
->call('get', "{$this->endpoint}/{$id}")
->getJSON(), true)['data'];
$this->assertNotEquals($test['TestCode'], $showData['TestCode']);
$this->assertEquals($test['TestName'], $showData['TestName']);
}
}

View File

@ -0,0 +1,122 @@
<?php
namespace Tests\Feature\User;
use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Test\CIUnitTestCase;
use Firebase\JWT\JWT;
class UserPatchTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected string $token;
protected string $endpoint = 'api/user';
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 createUser(array $data = []): array
{
$payload = array_merge([
'UserCode' => 'USR_' . uniqid(),
'UserName' => 'Test User ' . uniqid(),
'Email' => 'user_' . uniqid() . '@test.com',
], $data);
$response = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('post', $this->endpoint, $payload);
$response->assertStatus(201);
$decoded = json_decode($response->getJSON(), true);
return $decoded['data'];
}
public function testPartialUpdateUserSuccess()
{
$user = $this->createUser();
$id = $user['UserID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['UserName' => 'Updated User']);
$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('Updated User', $showData['UserName']);
$this->assertEquals($user['UserCode'], $showData['UserCode']);
}
public function testPartialUpdateUserNotFound()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/999999", ['UserName' => 'Updated']);
$patch->assertStatus(404);
}
public function testPartialUpdateUserInvalidId()
{
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/invalid", ['UserName' => 'Updated']);
$patch->assertStatus(400);
}
public function testPartialUpdateUserEmptyPayload()
{
$user = $this->createUser();
$id = $user['UserID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", []);
$patch->assertStatus(400);
}
public function testPartialUpdateUserSingleField()
{
$user = $this->createUser();
$id = $user['UserID'];
$patch = $this->withHeaders($this->authHeaders())
->withBodyFormat('json')
->call('patch', "{$this->endpoint}/{$id}", ['UserCode' => 'NEW_' . uniqid()]);
$patch->assertStatus(200);
$showData = json_decode($this->withHeaders($this->authHeaders())
->call('get', "{$this->endpoint}/{$id}")
->getJSON(), true)['data'];
$this->assertNotEquals($user['UserCode'], $showData['UserCode']);
$this->assertEquals($user['UserName'], $showData['UserName']);
}
}