Update Patient (Patcom & Unit Testing)

This commit is contained in:
mikael-zakaria 2025-10-19 22:36:31 +07:00
parent 6287785b73
commit 88f2633bb6
5 changed files with 351 additions and 148 deletions

View File

@ -62,10 +62,19 @@ class DummySeeder extends Seeder {
$this->db->table('patient')->insertBatch($data);
$data = [
[ 'InternalPID'=>1, 'IdentifierType'=>'KTP', 'Identifier'=>'9901', 'CreateDate'=> "$now" ],
[ 'InternalPID'=>2, 'IdentifierType'=>'KTP', 'Identifier'=>'9902', 'CreateDate'=> "$now" ],
// [ 'InternalPID'=>2, 'IdentifierType'=>'KTP', 'Identifier'=>'9902', 'CreateDate'=> "$now" ],
[ 'InternalPID'=>3, 'IdentifierType'=>'KTP', 'Identifier'=>'9903', 'CreateDate'=> "$now" ]
];
$this->db->table('patidt')->insertBatch($data);
$data = [
[ "InternalPID" => 1, "Address" => "/api/upload/assasasasd" . 1 . ".jpg", 'CreateDate'=> "$now" ],
[ "InternalPID" => 1, "Address" => "/api/upload/adsasasds" . 2 . ".jpg", 'CreateDate'=> "$now" ],
[ "InternalPID" => 1, "Address" => "/api/upload/sasaasadjs" . 6 . ".jpg", 'CreateDate'=> "$now" ],
[ "InternalPID" => 1, "Address" => "/api/upload/sdjasass" . 5 . ".jpg", 'CreateDate'=> "$now" ],
[ "InternalPID" => 1, "Address" => "/api/upload/sdasasjs" . 4 . ".jpg", 'CreateDate'=> "$now" ],
];
$this->db->table('patatt')->insertBatch($data);
// containerdef
$data = [

View File

@ -7,7 +7,7 @@ use App\Models\BaseUtcModel;
class PatComModel extends BaseModel {
protected $table = 'patcom';
protected $primaryKey = 'PatComID ';
protected $allowedFields = ['InternalPID', 'Comment', 'CreateDate', 'DelDate'];
protected $allowedFields = ['InternalPID', 'Comment', 'CreateDate', 'EndDate'];
protected $useTimestamps = true;
protected $createdField = 'CreateDate';
@ -26,14 +26,14 @@ class PatComModel extends BaseModel {
}
public function updatePatCom(string $patcom, string $InternalPID) {
$exists = $this->where('InternalPID', $InternalPID)->first();
$exists = $this->withDeleted()->where('InternalPID', $InternalPID)->first();
if ($exists) {
//Update
$this->where('InternalPID', $InternalPID)->set('Comment', $patcom)->update();
//Update
$this->where('InternalPID', $InternalPID)->set(['EndDate' => null,'Comment' => $patcom])->update();
} else {
//Insert
$this->insert(['InternalPID' => $InternalPID, 'Comment' => $patcom]);
//Insert
$this->insert(['InternalPID' => $InternalPID, 'Comment' => $patcom]);
}
}

View File

@ -11,14 +11,14 @@ class PatientCreateTest extends CIUnitTestCase
use FeatureTestTrait;
protected $endpoint = 'api/patient';
// 400 - Passed
// 400 - Passed
// Validation Gagal - Array Tidak Complete
public function testCreatePatientValidationFail() {
// Test dengan payload yg tidak lengkap
// error 400 yg diharapkan
$payload = ['Name' => 'Ngawur'];
$result = $this->withBodyFormat('json')
->call('post', 'api/patient', $payload);
$result = $this->withBodyFormat('json')->call('post', 'api/patient', $payload);
$result->assertStatus(400);
// Test dengan PatiD yg sudah ada
@ -35,14 +35,13 @@ class PatientCreateTest extends CIUnitTestCase
"NameAlias"=> "Bud",
"Gender"=> "1",
];
$result = $this->withBodyFormat('json')
->call('post', 'api/patient', $payload);
$result = $this->withBodyFormat('json')->call('post', 'api/patient', $payload);
$result->assertStatus(400);
}
// 201 - Passed
// Test dengan user dummy
// Test Sukses Dengan User Dummy
public function testCreatePatientSuccess() {
$faker = Factory::create('id_ID');
@ -141,8 +140,8 @@ class PatientCreateTest extends CIUnitTestCase
"Custodian" => 1,
"PatIdt" => [
"IdentifierType" => "KTP",
// Identifier lebih dari 255 karakter - error validasi
"Identifier" => "numberBetweennumberBetweennumberBetweennumberBetweennumberBetweennumberBetweennumberBetweennumberBetweennumberBetweennumberBetweennumberBetweennumberBetweennumberBetweennumberBetweennumberBetweennumberBetweennumberBetweennumberBetweennumberBetweennumberBetweennumberBetween"
// "Identifier" => $faker->nik() ?? $faker->numerify('################')
],
"PatAtt" => [
[ "Address" => "/api/upload/" . $faker->word . ".jpg" ]
@ -163,6 +162,60 @@ class PatientCreateTest extends CIUnitTestCase
$result->assertArrayHasKey("error", $data);
}
public function testCreateWithoutAttachments() {
$faker = Factory::create('id_ID');
$payload = [
"PatientID" => "DUAU" . $faker->numberBetween(1, 1000).$faker->numberBetween(1, 1000),
"AlternatePID" => "DMAU" . $faker->numberBetween(5, 1000).$faker->numberBetween(1, 1000),
"Prefix" => $faker->title,
"NameFirst" => $faker->firstName,
"NameMiddle" => $faker->firstName,
"NameMaiden" => $faker->firstName,
"NameLast" => $faker->lastName,
"Suffix" => "S.Kom",
"NameAlias" => $faker->userName,
"Gender" => $faker->numberBetween(5, 6),
"PlaceOfBirth" => $faker->city,
"Birthdate" => $faker->date('Y-m-d'),
"ZIP" => $faker->postcode,
"Street_1" => $faker->streetAddress,
"Street_2" => "RT " . $faker->numberBetween(1, 10) . " RW " . $faker->numberBetween(1, 10),
"Street_3" => "Blok " . $faker->numberBetween(1, 20),
"City" => $faker->city,
"Province" => $faker->state,
"EmailAddress1" => "AiA" . $faker->numberBetween(1, 1110).$faker->numberBetween(1, 1110).'@gmail.com',
"EmailAddress2" => "BiA" . $faker->numberBetween(1, 1110).$faker->numberBetween(1, 1110).'@gmail.com',
"Phone" => $faker->phoneNumber,
"MobilePhone" => $faker->phoneNumber,
"Race" => (string) $faker->numberBetween(175, 205),
"Country" => (string) $faker->numberBetween(221, 469),
"MaritalStatus" => (string) $faker->numberBetween(8, 15),
"Religion" => (string) $faker->numberBetween(206, 212),
"Ethnic" => (string) $faker->numberBetween(213, 220),
"Citizenship" => "WNI",
"DeathIndicator" => (string) $faker->numberBetween(16, 17),
"LinkTo" => (string) $faker->numberBetween(2, 3),
"Custodian" => 1,
"PatIdt" => [
"IdentifierType" => "KTP",
"Identifier" => $faker->nik() ?? $faker->numerify('################')
],
"PatAtt" => [],
"PatCom" => $faker->sentence,
];
if($payload['DeathIndicator'] == '16') {
$payload['DeathDateTime'] = $faker->date('Y-m-d H:i:s');
} else {
$payload['DeathDateTime'] = null;
}
$result = $this->withBodyFormat('json')->post($this->endpoint, $payload);
$result->assertStatus(201);
}
// 201 - Passed
// Test dengan user dummy dan harus berhasil - Attachment kosong
public function testCreateWithoutAttachments() {

View File

@ -11,16 +11,6 @@ class PatientShowTest extends CIUnitTestCase
protected $endpoint = 'api/patient';
// 200 ok not found - Passed
public function testShowNotFound() {
$result = $this->get($this->endpoint . '/90909090');
$result->assertStatus(200);
$result->assertJSONFragment([
'status' => 'success',
"message" => "data not found."
]);
}
// 200 ok found - Passed
public function testShowSingleRow() {
// Pastikan DB test punya seed patient InternalPID=10 tanpa id/addr
@ -33,5 +23,62 @@ class PatientShowTest extends CIUnitTestCase
$result->assertArrayHasKey('data', $data);
$result->assertIsArray($data['data']);
}
// 200 ok - Test validasi respons selalu sukses - Passed
public function testShowAlwaysReturnSuccessStatus() {
$result = $this->get($this->endpoint . '/99999');
$result->assertJSONFragment(['status' => 'success']);
}
}
// 200 ok not found - Passed
public function testShowNotFound() {
$result = $this->get($this->endpoint . '/90909090');
$result->assertStatus(200);
$result->assertJSONFragment([
'status' => 'success',
"message" => "data not found."
]);
}
// 200 ok found - PatIdt null - Passed
public function testShowWithNullPatIdt() {
$result = $this->get($this->endpoint . '/2');
$data = $result->getJSON();
$data = json_decode($data, true);
$result->assertStatus(200);
$this->assertNull($data['data']['PatIdt']);
}
// 200 ok found - PatAtt null - Passed
public function testShowWithNullPatAtt() {
$result = $this->get($this->endpoint . '/2');
$data = $result->getJSON();
$data = json_decode($data, true);
$result->assertStatus(200);
$this->assertNull($data['data']['PatAtt']);
}
// 200 ok found - PatCom null - Passed
public function testShowWithNullPatCom() {
$result = $this->get($this->endpoint . '/2');
$data = $result->getJSON();
$data = json_decode($data, true);
$result->assertStatus(200);
$this->assertNull($data['data']['PatCom']);
}
// 200 ok found - PatAtt greater dan 1 - Passed
public function testShowWithMultipleAddresses() {
$result = $this->get($this->endpoint . '/1');
$data = $result->getJSON();
$data = json_decode($data, true);
$result->assertStatus(200);
$this->assertIsArray($data['data']['PatAtt']);
$this->assertGreaterThan(1, count($data['data']['PatAtt']));
}
}

View File

@ -10,149 +10,243 @@ class PatientUpdateTest extends CIUnitTestCase
{
use FeatureTestTrait;
protected $endpoint = 'api/patient';
/**
* 400 - Validation Fail
* Coba update tanpa field wajib harus gagal validasi.
*/
public function testUpdatePatientValidationFail()
{
$payload = [ 'InternalPID' => null, 'NameFirst' => '' ]; // Tidak valid
$result = $this->withBodyFormat('json')->call('patch', $this->endpoint, $payload);
$result->assertStatus(400);
$json = $result->getJSON();
$data = json_decode($json, true);
$this->assertArrayHasKey('messages', $data);
}
/**
* 404 / 500 - Update Nonexistent Patient
* Coba update InternalPID yang tidak ada.
*/
public function testUpdateNonexistentPatientShouldFail()
{
$faker = Factory::create('id_ID');
$payload = [
'InternalPID' => 999999, // Asumsi tidak ada di DB
"PatientID" => "SMAJ1",
"EmailAddress1" => 'asaas7890@gmail.com',
'NameFirst' => $faker->firstName,
'NameLast' => $faker->lastName,
'Gender' => '1',
'Birthdate' => $faker->date('Y-m-d'),
'PatIdt' => [ 'IdentifierType' => 'KTP', 'Identifier' => $faker->nik() ],
'PatCom' => $faker->sentence,
'PatAtt' => [],
];
$result = $this->withBodyFormat('json')->call('patch', $this->endpoint, $payload);
$result->assertStatus(500); // karena di model akan trigger rollback dan failServerError
}
/**
* 201 - Update Success
* Pastikan bisa update data yang valid (gunakan dummy data dari database).
*/
public function testUpdatePatientSuccess()
{
$faker = Factory::create('id_ID');
// NOTE: Sebaiknya ambil InternalPID yang sudah ada (mock atau dari DB fixture)
// Untuk contoh ini kita asumsikan ada ID 1
$payload = [
"InternalPID" => 1,
"PatientID" => "UPDT" . $faker->numberBetween(100, 999),
"NameFirst" => $faker->firstName,
"NameLast" => $faker->lastName,
"Gender" => (string) $faker->numberBetween(5, 6),
"Birthdate" => $faker->date('Y-m-d'),
"DeathDateTime" => null,
"EmailAddress1" => "asasa@gmail.com",
"PlaceOfBirth" => $faker->city,
"Race" => (string) $faker->numberBetween(175, 205),
"Religion" => (string) $faker->numberBetween(206, 212),
"Country" => (string) $faker->numberBetween(221, 469),
"MaritalStatus" => (string) $faker->numberBetween(8, 15),
"Citizenship" => "WNI",
"LinkTo" => null,
"PatIdt" => [
"IdentifierType" => "KTP",
"Identifier" => $faker->nik(),
'InternalPID' => 1,
"PatientID" => "SMAJ1",
'NameFirst' => $faker->firstName,
'NameMiddle' => $faker->firstName,
'NameLast' => $faker->lastName,
'Gender' => '1',
'Birthdate' => $faker->date('Y-m-d'),
'EmailAddress1' => 'update_' . $faker->numberBetween(1,999) . '@gmail.com',
'PlaceOfBirth' => $faker->city,
'LinkTo' => null,
'PatIdt' => [
'IdentifierType' => 'KTP',
'Identifier' => $faker->nik(),
],
"DeathIndicator" => (string) $faker->numberBetween(16, 17),
'PatCom' => 'Update be',
'PatAtt' => [
[ 'Address' => '/api/upload/' . $faker->word . '.jpg' ],
],
"PatCom" => $faker->sentence(5),
"PatAtt" => [
[ "Address" => "/api/upload/" . $faker->word . ".jpg" ],
[ "Address" => "/api/upload/" . $faker->word . ".jpg" ]
]
];
if($payload['DeathIndicator'] == '16') {
$payload['DeathDateTime'] = $faker->date('Y-m-d H:i:s');
} else {
$payload['DeathDateTime'] = null;
}
$result = $this->withBodyFormat('json')->patch($this->endpoint, $payload);
$result = $this->withBodyFormat('json')->call('patch', $this->endpoint, $payload);
$result->assertStatus(201);
$json = $result->getJSON();
$data = json_decode($json, true);
$this->assertEquals('success', $data['status']);
}
// /**
// * Test gagal karena InternalPID kosong (validasi)
// */
public function testUpdatePatientValidationError()
/**
* 201 - Update dengan PatCom kosong
*/
public function testUpdateWithoutPatCom()
{
$faker = Factory::create('id_ID');
$payload = [
"NameFirst" => $faker->firstName,
"Gender" => (string) $faker->numberBetween(5, 6),
"Birthdate" => $faker->date('Y-m-d'),
// Tidak kirim InternalPID
'InternalPID' => 1,
"PatientID" => "SMAJ1",
'NameFirst' => $faker->firstName,
'NameMiddle' => $faker->firstName,
'NameLast' => $faker->lastName,
'Gender' => '1',
'Birthdate' => $faker->date('Y-m-d'),
'EmailAddress1' => 'update_' . $faker->numberBetween(1,999) . '@gmail.com',
'PlaceOfBirth' => $faker->city,
'LinkTo' => null,
'PatIdt' => [
'IdentifierType' => 'KTP',
'Identifier' => $faker->nik(),
],
"DeathIndicator" => (string) $faker->numberBetween(16, 17),
'PatCom' => null,
'PatAtt' => [
[ 'Address' => '/api/upload/' . $faker->word . '.jpg' ],
],
];
if($payload['DeathIndicator'] == '16') {
$payload['DeathDateTime'] = $faker->date('Y-m-d H:i:s');
} else {
$payload['DeathDateTime'] = null;
}
$result = $this->withBodyFormat('json')->patch($this->endpoint, $payload);
$result = $this->withBodyFormat('json')->call('patch', $this->endpoint, $payload);
$result->assertStatus(201);
}
/**
* 201 - Update tanpa PatAtt
*/
public function testUpdateWithoutAttachments()
{
$faker = Factory::create('id_ID');
$payload = [
'InternalPID' => 1,
"PatientID" => "SMAJ1",
'NameFirst' => $faker->firstName,
'NameMiddle' => $faker->firstName,
'NameLast' => $faker->lastName,
'Gender' => '1',
'Birthdate' => $faker->date('Y-m-d'),
'EmailAddress1' => 'update_' . $faker->numberBetween(1,999) . '@gmail.com',
'PlaceOfBirth' => $faker->city,
'LinkTo' => null,
'PatIdt' => [
'IdentifierType' => 'KTP',
'Identifier' => $faker->nik(),
],
"DeathIndicator" => (string) $faker->numberBetween(16, 17),
'PatCom' => null,
'PatAtt' => [],
];
if($payload['DeathIndicator'] == '16') {
$payload['DeathDateTime'] = $faker->date('Y-m-d H:i:s');
} else {
$payload['DeathDateTime'] = null;
}
$result = $this->withBodyFormat('json')->call('patch', $this->endpoint, $payload);
$result->assertStatus(201);
}
/**
* 201 - Update tanpa PatAtt
*/
public function testUpdateWithAttachments()
{
$faker = Factory::create('id_ID');
$payload = [
'InternalPID' => 1,
"PatientID" => "SMAJ1",
'NameFirst' => $faker->firstName,
'NameMiddle' => $faker->firstName,
'NameLast' => $faker->lastName,
'Gender' => '1',
'Birthdate' => $faker->date('Y-m-d'),
'EmailAddress1' => 'update_' . $faker->numberBetween(1,999) . '@gmail.com',
'PlaceOfBirth' => $faker->city,
'LinkTo' => null,
'PatIdt' => [
'IdentifierType' => 'KTP',
'Identifier' => $faker->nik(),
],
"DeathIndicator" => (string) $faker->numberBetween(16, 17),
'PatCom' => null,
'PatAtt' => [
[ 'Address' => '/api/upload/' . $faker->word . '.jpg' ],
],
];
if($payload['DeathIndicator'] == '16') {
$payload['DeathDateTime'] = $faker->date('Y-m-d H:i:s');
} else {
$payload['DeathDateTime'] = null;
}
$result = $this->withBodyFormat('json')->call('patch', $this->endpoint, $payload);
$result->assertStatus(201);
}
// /**
// * 500 - Invalid PatIdt
// */
public function testUpdatePatIdtInvalid()
{
$faker = Factory::create('id_ID');
$payload = [
'InternalPID' => 1,
"PatientID" => "SMAJ1",
'NameFirst' => $faker->firstName,
'NameMiddle' => $faker->firstName,
'NameLast' => $faker->lastName,
'Gender' => '1',
'Birthdate' => $faker->date('Y-m-d'),
'EmailAddress1' => 'update_' . $faker->numberBetween(1,999) . '@gmail.com',
'PlaceOfBirth' => $faker->city,
'LinkTo' => null,
'PatIdt' => [
'IdentifierType' => [],
'Identifier' => $faker->nik(),
],
"DeathIndicator" => (string) $faker->numberBetween(16, 17),
'PatCom' => null,
'PatAtt' => [
[ 'Address' => '/api/upload/' . $faker->word . '.jpg' ],
],
];
if($payload['DeathIndicator'] == '16') {
$payload['DeathDateTime'] = $faker->date('Y-m-d H:i:s');
} else {
$payload['DeathDateTime'] = null;
}
$result = $this->withBodyFormat('json')->call('patch', $this->endpoint, $payload);
$result->assertStatus(500);
$json = $result->getJSON();
$data = json_decode($json, true);
$result->assertStatus(400);
$this->assertArrayHasKey('error', $data);
}
// /**
// * Test update dengan address baru & hapus address lama
// */
public function testUpdatePatientWithAddressChange()
{
$faker = Factory::create('id_ID');
$payload = [
"InternalPID" => 1,
"PatientID" => "UPDT" . $faker->numberBetween(100, 999),
"NameFirst" => $faker->firstName,
"NameLast" => $faker->lastName,
"Gender" => (string) $faker->numberBetween(5, 6),
"Birthdate" => $faker->date('Y-m-d'),
"DeathDateTime" => null,
"EmailAddress1" => "asasa@gmail.com",
"PlaceOfBirth" => $faker->city,
"Race" => (string) $faker->numberBetween(175, 205),
"Religion" => (string) $faker->numberBetween(206, 212),
"Country" => (string) $faker->numberBetween(221, 469),
"MaritalStatus" => (string) $faker->numberBetween(8, 15),
"Citizenship" => "WNI",
"LinkTo" => null,
"PatIdt" => [
"IdentifierType" => "KTP",
"Identifier" => $faker->nik(),
],
"PatCom" => $faker->sentence(5),
"PatAtt" => [
[ "Address" => "/api/upload/" . $faker->word . ".jpg" ],
[ "Address" => "/api/upload/" . $faker->word . ".jpg" ],
[ "Address" => "/api/upload/" . $faker->word . ".jpg" ],
[ "Address" => "/api/upload/" . $faker->word . ".jpg" ]
]
];
$result = $this->withBodyFormat('json')->patch($this->endpoint, $payload);
$result->assertStatus(201);
$json = $result->getJSON();
$data = json_decode($json, true);
$this->assertEquals('success', $data['status']);
}
// /**
// * Test update kosong → semua pattat address dihapus (soft delete)
// */
public function testUpdatePatientEmptyAddress()
{
$faker = Factory::create('id_ID');
$payload = [
"InternalPID" => 1,
"PatientID" => "UPDT" . $faker->numberBetween(100, 999),
"NameFirst" => $faker->firstName,
"NameLast" => $faker->lastName,
"Gender" => (string) $faker->numberBetween(5, 6),
"Birthdate" => $faker->date('Y-m-d'),
"DeathDateTime" => null,
"EmailAddress1" => "asasa@gmail.com",
"PlaceOfBirth" => $faker->city,
"Race" => (string) $faker->numberBetween(175, 205),
"Religion" => (string) $faker->numberBetween(206, 212),
"Country" => (string) $faker->numberBetween(221, 469),
"MaritalStatus" => (string) $faker->numberBetween(8, 15),
"Citizenship" => "WNI",
"LinkTo" => null,
"PatIdt" => [
"IdentifierType" => "KTP",
"Identifier" => $faker->nik(),
],
"PatCom" => $faker->sentence(5),
"PatAtt" => []
];
$result = $this->withBodyFormat('json')->patch($this->endpoint, $payload);
$json = $result->getJSON();
$data = json_decode($json, true);
$result->assertStatus(201);
$this->assertEquals('success', $data['status']);
}
}