You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
281 lines
12 KiB
281 lines
12 KiB
<?php |
|
|
|
namespace OpenEMR\Tests\Services\FHIR; |
|
|
|
use OpenEMR\FHIR\R4\FHIRElement\FHIRContactPoint; |
|
use OpenEMR\FHIR\R4\FHIRElement\FHIRIdentifier; |
|
use OpenEMR\Services\FHIR\Serialization\FhirPatientSerializer; |
|
use OpenEMR\Services\PatientService; |
|
use PHPUnit\Framework\TestCase; |
|
use OpenEMR\Tests\Fixtures\FixtureManager; |
|
use OpenEMR\Services\FHIR\FhirPatientService; |
|
use OpenEMR\FHIR\R4\FHIRDomainResource\FHIRPatient; |
|
|
|
/** |
|
* FHIR Patient Service Mapping Tests |
|
* @coversDefaultClass OpenEMR\Services\FHIR\FhirPatientService |
|
* @package OpenEMR |
|
* @link http://www.open-emr.org |
|
* @author Dixon Whitmire <dixonwh@gmail.com> |
|
* @copyright Copyright (c) 2020 Dixon Whitmire <dixonwh@gmail.com> |
|
* @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3 |
|
* |
|
*/ |
|
class FhirPatientServiceMappingTest extends TestCase |
|
{ |
|
private $fixtureManager; |
|
private $patientFixture; |
|
|
|
/** |
|
* @var FHIRPatient |
|
*/ |
|
private $fhirPatientFixture; |
|
|
|
/** |
|
* @var FhirPatientService |
|
*/ |
|
private $fhirPatientService; |
|
|
|
protected function setUp(): void |
|
{ |
|
$this->fixtureManager = new FixtureManager(); |
|
$this->patientFixture = (array) $this->fixtureManager->getSinglePatientFixtureWithAddressInformation(); |
|
$fixture = (array) $this->fixtureManager->getSingleFhirPatientFixture(); |
|
// var_dump($fixture); |
|
$this->fhirPatientFixture = FhirPatientSerializer::deserialize($fixture); |
|
// var_dump($this->fhirPatientFixture); |
|
// die(); |
|
$this->fhirPatientService = new FhirPatientService(); |
|
} |
|
|
|
/** |
|
* Asserts that a FHIR Patient Resource aligns with it's source OpenEMR Patient record |
|
* @param $fhirPatientResource A FHIR Patient Resource |
|
* @param $sourcePatientRecord The OpenEMR Patient Record |
|
*/ |
|
private function assertFhirPatientResource(FHIRPatient $fhirPatientResource, $sourcePatientRecord) |
|
{ |
|
$this->assertEquals($sourcePatientRecord['uuid'], $fhirPatientResource->getId()); |
|
$this->assertEquals(1, $fhirPatientResource->getMeta()->getVersionId()); |
|
$this->assertNotEmpty($fhirPatientResource->getMeta()->getLastUpdated()); |
|
|
|
$this->assertEquals('generated', $fhirPatientResource->getText()['status']); |
|
$this->assertNotEmpty($fhirPatientResource->getText()['div']); |
|
|
|
$this->assertTrue($fhirPatientResource->getActive()); |
|
|
|
$this->assertNotEmpty($fhirPatientResource->getId()); |
|
|
|
$this->assertEquals(1, count($fhirPatientResource->getName())); |
|
$actualName = $fhirPatientResource->getName()[0]; |
|
$this->assertEquals('official', $actualName->getUse()); |
|
|
|
$this->assertEquals(1, count($actualName->getPrefix())); |
|
$this->assertEquals($sourcePatientRecord['title'], $actualName->getPrefix()[0]); |
|
|
|
$this->assertEquals($sourcePatientRecord['lname'], $actualName->getFamily()); |
|
$this->assertEquals(array( |
|
$sourcePatientRecord['fname'], |
|
$sourcePatientRecord['mname']), $actualName->getGiven()); |
|
|
|
$this->assertEquals(1, count($fhirPatientResource->getAddress())); |
|
$actualAddress = $fhirPatientResource->getAddress()[0]; |
|
$this->assertEquals(1, count($actualAddress->getLine())); |
|
$patientAddress = $sourcePatientRecord['addresses'][0]; |
|
// TODO: we should add period validation here... |
|
$this->assertEquals($patientAddress['use'], $actualAddress->getUse()); |
|
$this->assertEquals($patientAddress['type'], $actualAddress->getType()); |
|
$this->assertEquals($patientAddress['line1'], $actualAddress->getLine()[0]); |
|
$this->assertEquals($patientAddress['city'], $actualAddress->getCity()); |
|
$this->assertEquals($patientAddress['state'], $actualAddress->getState()); |
|
$this->assertEquals($patientAddress['postal_code'], $actualAddress->getPostalCode()); |
|
|
|
$actualTelecoms = $fhirPatientResource->getTelecom(); |
|
$this->assertFhirPatientTelecom('phone', 'home', $sourcePatientRecord['phone_home'], $actualTelecoms); |
|
$this->assertFhirPatientTelecom('phone', 'work', $sourcePatientRecord['phone_biz'], $actualTelecoms); |
|
$this->assertFhirPatientTelecom('phone', 'mobile', $sourcePatientRecord['phone_cell'], $actualTelecoms); |
|
$this->assertFhirPatientTelecom('email', 'home', $sourcePatientRecord['email'], $actualTelecoms); |
|
|
|
$actualIdentifiers = $fhirPatientResource->getIdentifier(); |
|
$this->assertFhirPatientIdentifier('SS', $sourcePatientRecord['ss'], $actualIdentifiers); |
|
$this->assertFhirPatientIdentifier('PT', $sourcePatientRecord['pubpid'], $actualIdentifiers); |
|
} |
|
|
|
/** |
|
* Asserts an expected telecom/contact point entry against an array of telecoms/contact points |
|
* @param $expectedSystem The telecom/contact point system to match |
|
* @param $expectedUse The telecom/contact point use to match |
|
* @param $expectedValue The expected telecom/contact point value |
|
* @param $actualTelecoms FHIRContactPoint[] FHIR Patient Resource telecom entries |
|
*/ |
|
private function assertFhirPatientTelecom($expectedSystem, $expectedUse, $expectedValue, $actualTelecoms) |
|
{ |
|
$matchFound = false; |
|
|
|
foreach ($actualTelecoms as $index => $actualTelecom) { |
|
if ( |
|
$expectedSystem == $actualTelecom->getSystem()->getValue() && |
|
$expectedUse == $actualTelecom->getUse()->getValue() && |
|
$expectedValue == $actualTelecom->getValue()->getValue() |
|
) { |
|
$matchFound = true; |
|
break; |
|
} |
|
} |
|
|
|
$this->assertTrue($matchFound); |
|
} |
|
|
|
/** |
|
* Asserts an expected identifier value against an array of patient identifiers |
|
* |
|
* @param $expectedCode The identifier code type code |
|
* @param $expectedValue The expected identifer value (value set) |
|
* @param $actualIdentifiers FHIRIdentifier[] FHIR Patient identifier entries |
|
*/ |
|
private function assertFhirPatientIdentifier($expectedCode, $expectedValue, $actualIdentifiers) |
|
{ |
|
$matchFound = false; |
|
foreach ($actualIdentifiers as $index => $actualIdentifier) { |
|
$type = $actualIdentifier->getType(); |
|
if (isset($type) && empty($type->getCoding())) { |
|
continue; |
|
} |
|
$coding = $type->getCoding(); |
|
|
|
$codeTypeCode = $coding[0]->getCode(); |
|
$value = $actualIdentifier->getValue()->getValue(); |
|
|
|
if ( |
|
$expectedCode == $codeTypeCode && |
|
$expectedValue == $value |
|
) { |
|
$matchFound = true; |
|
break; |
|
} |
|
} |
|
$this->assertTrue($matchFound); |
|
} |
|
|
|
/** |
|
* @covers ::parseOpenEMRRecord |
|
*/ |
|
public function testParseOpenEMRRecord() |
|
{ |
|
$this->patientFixture['uuid'] = $this->fixtureManager->getUnregisteredUuid(); |
|
$actualResult = $this->fhirPatientService->parseOpenEMRRecord($this->patientFixture); |
|
$this->assertFhirPatientResource($actualResult, $this->patientFixture); |
|
|
|
$actualResult = $this->fhirPatientService->parseOpenEMRRecord($this->patientFixture, true); |
|
$this->assertIsString($actualResult); |
|
} |
|
/** |
|
* Finds matching FHIR Patient telecom entries by system and use. |
|
* @param $fhirPatientResource - The FHIR Patient Resource to search |
|
* @param $telecomSystem - The telecom system to match |
|
* @param $telecomUse - The telecom use to match |
|
* @return matching entries (array) |
|
*/ |
|
private function findTelecomEntry(FHIRPatient $fhirPatientResource, $telecomSystem, $telecomUse) |
|
{ |
|
$matchingEntries = array(); |
|
|
|
if (empty($fhirPatientResource->getTelecom())) { |
|
return $matchingEntries; |
|
} |
|
|
|
foreach ($fhirPatientResource->getTelecom() as $index => $telecomEntry) { |
|
if ($telecomEntry->getSystem() == $telecomSystem && $telecomEntry->getUse() == $telecomUse) { |
|
array_push($matchingEntries, $telecomEntry); |
|
} |
|
} |
|
return $matchingEntries; |
|
} |
|
|
|
/** |
|
* Searches a FHIR R4 Patient resource for an identifier code value. |
|
* @param $fhirPatientResource The FHIR Patient resource to search |
|
* @param $fhirCodeType The code to lookup |
|
* @return the code value if found, otherwise null |
|
*/ |
|
private function findIdentiferCodeValue(FHIRPatient $fhirPatientResource, $fhirCodeType): ?string |
|
{ |
|
$codeValue = null; |
|
|
|
foreach ($fhirPatientResource->getIdentifier() as $index => $identifier) { |
|
if (empty($identifier->getType()->getCoding())) { |
|
continue; |
|
} |
|
$identifierCodeType = $identifier->getType()->getCoding()[0]->getCode(); |
|
if ($identifierCodeType === $fhirCodeType) { |
|
$codeValue = $identifier->getValue(); |
|
break; |
|
} |
|
} |
|
return (string)$codeValue; |
|
} |
|
/** |
|
* @covers ::parseFhirResource |
|
*/ |
|
public function testParseFhirResource() |
|
{ |
|
$actualResult = $this->fhirPatientService->parseFhirResource($this->fhirPatientFixture); |
|
|
|
$id = $this->fhirPatientFixture->getId(); |
|
$this->assertEquals($id, $actualResult['uuid']); |
|
|
|
$title = $this->fhirPatientFixture->getName()[0]->getPrefix()[0]; |
|
$this->assertEquals($title, $actualResult['title']); |
|
|
|
$fname = $this->fhirPatientFixture->getName()[0]->getGiven()[0]; |
|
$this->assertEquals($fname, $actualResult['fname']); |
|
|
|
$mname = $this->fhirPatientFixture->getName()[0]->getGiven()[1]; |
|
$this->assertEquals($mname, $actualResult['mname']); |
|
|
|
$lname = $this->fhirPatientFixture->getName()[0]->getFamily(); |
|
$this->assertEquals($lname, $actualResult['lname']); |
|
|
|
$dob = $this->fhirPatientFixture->getBirthDate(); |
|
$this->assertEquals($dob, $actualResult['DOB']); |
|
|
|
$sex = $this->fhirPatientFixture->getGender(); |
|
$this->assertEquals($sex, $actualResult['sex']); |
|
|
|
$ss = $this->findIdentiferCodeValue($this->fhirPatientFixture, 'SS'); |
|
$this->assertEquals($ss, $actualResult['ss']); |
|
|
|
$pubpid = $this->findIdentiferCodeValue($this->fhirPatientFixture, 'PT'); |
|
$this->assertEquals($pubpid, $actualResult['pubpid']); |
|
|
|
$address = $this->fhirPatientFixture->getAddress()[0]; |
|
|
|
$street = $address->getLine()[0]; |
|
$this->assertEquals($street, $actualResult['street']); |
|
|
|
$city = $address->getCity(); |
|
$this->assertEquals($city, $actualResult['city']); |
|
|
|
$state = $address->getState(); |
|
$this->assertEquals($state, $actualResult['state']); |
|
|
|
$postalCode = $address->getPostalCode(); |
|
$this->assertEquals($postalCode, $actualResult['postal_code']); |
|
|
|
$phoneCell = $this->findTelecomEntry($this->fhirPatientFixture, 'phone', 'mobile'); |
|
$this->assertEquals(1, count($phoneCell)); |
|
$this->assertEquals($phoneCell[0]->getValue(), $actualResult['phone_cell']); |
|
|
|
$phoneHome = $this->findTelecomEntry($this->fhirPatientFixture, 'phone', 'home'); |
|
$this->assertEquals(1, count($phoneHome)); |
|
$this->assertEquals($phoneHome[0]->getValue(), $actualResult['phone_home']); |
|
|
|
$phoneBiz = $this->findTelecomEntry($this->fhirPatientFixture, 'phone', 'work'); |
|
$this->assertEquals(1, count($phoneBiz)); |
|
$this->assertEquals($phoneBiz[0]->getValue(), $actualResult['phone_biz']); |
|
|
|
$email = $this->findTelecomEntry($this->fhirPatientFixture, 'email', 'home'); |
|
$this->assertEquals(1, count($email)); |
|
$this->assertEquals($email[0]->getValue(), $actualResult['email']); |
|
} |
|
}
|
|
|