Skip to content

Commit

Permalink
FM2-648 fix NPE when querying deceased patient with openmrsPatients n… (
Browse files Browse the repository at this point in the history
  • Loading branch information
chibongho authored Nov 26, 2024
1 parent 4970b16 commit 10a5c39
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 10 deletions.
8 changes: 8 additions & 0 deletions api/src/main/java/org/openmrs/module/fhir2/FhirConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,14 @@ private FhirConstants() {

public static final String FAMILY_PROPERTY = "family.property";

public static final String GENDER_PROPERTY = "gender";

public static final String BIRTHDATE_PROPERTY = "birthdate";

public static final String DEATHDATE_PROPERTY = "deathDate";

public static final String DECEASED_PROPERTY = "dead";

public static final String CITY_PROPERTY = "city.property";

public static final String COUNTRY_PROPERTY = "country.property";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,9 @@ protected void setupSearchParams(Criteria criteria, SearchParameterMap theParams
handleNames(criteria, entry.getValue());
break;
case FhirConstants.GENDER_SEARCH_HANDLER:
entry.getValue().forEach(
p -> handleGender(p.getPropertyName(), (TokenAndListParam) p.getParam()).ifPresent(criteria::add));
entry.getValue()
.forEach(p -> handleGender(FhirConstants.GENDER_PROPERTY, (TokenAndListParam) p.getParam())
.ifPresent(criteria::add));
break;
case FhirConstants.IDENTIFIER_SEARCH_HANDLER:
entry.getValue()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ protected void setupSearchParams(Criteria criteria, SearchParameterMap theParams
break;
case FhirConstants.GENDER_SEARCH_HANDLER:
entry.getValue().forEach(
param -> handleGender("gender", (TokenAndListParam) param.getParam()).ifPresent(criteria::add));
param -> handleGender(FhirConstants.GENDER_PROPERTY, (TokenAndListParam) param.getParam())
.ifPresent(criteria::add));
break;
case FhirConstants.DATE_RANGE_SEARCH_HANDLER:
entry.getValue().forEach(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public SearchParameterMap toSearchParameterMap() {
.addParameter(FhirConstants.GENDER_SEARCH_HANDLER, "gender", getGender())
.addParameter(FhirConstants.DATE_RANGE_SEARCH_HANDLER, "birthdate", getBirthDate())
.addParameter(FhirConstants.DATE_RANGE_SEARCH_HANDLER, "deathDate", getDeathDate())
.addParameter(FhirConstants.BOOLEAN_SEARCH_HANDLER, getDeceased())
.addParameter(FhirConstants.BOOLEAN_SEARCH_HANDLER, "dead", getDeceased())
.addParameter(FhirConstants.ADDRESS_SEARCH_HANDLER, FhirConstants.CITY_PROPERTY, getCity())
.addParameter(FhirConstants.ADDRESS_SEARCH_HANDLER, FhirConstants.STATE_PROPERTY, getState())
.addParameter(FhirConstants.ADDRESS_SEARCH_HANDLER, FhirConstants.POSTAL_CODE_PROPERTY, getPostalCode())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,10 @@ public SearchParameterMap toSearchParameterMap() {
.addParameter(FhirConstants.NAME_SEARCH_HANDLER, FhirConstants.GIVEN_PROPERTY, getGiven())
.addParameter(FhirConstants.NAME_SEARCH_HANDLER, FhirConstants.FAMILY_PROPERTY, getFamily())
.addParameter(FhirConstants.IDENTIFIER_SEARCH_HANDLER, getIdentifier())
.addParameter(FhirConstants.GENDER_SEARCH_HANDLER, "gender", getGender())
.addParameter(FhirConstants.DATE_RANGE_SEARCH_HANDLER, "birthdate", getBirthDate())
.addParameter(FhirConstants.DATE_RANGE_SEARCH_HANDLER, "deathDate", getDeathDate())
.addParameter(FhirConstants.BOOLEAN_SEARCH_HANDLER, getDeceased())
.addParameter(FhirConstants.GENDER_SEARCH_HANDLER, FhirConstants.GENDER_PROPERTY, getGender())
.addParameter(FhirConstants.DATE_RANGE_SEARCH_HANDLER, FhirConstants.BIRTHDATE_PROPERTY, getBirthDate())
.addParameter(FhirConstants.DATE_RANGE_SEARCH_HANDLER, FhirConstants.DEATHDATE_PROPERTY, getDeathDate())
.addParameter(FhirConstants.BOOLEAN_SEARCH_HANDLER, FhirConstants.DECEASED_PROPERTY, getDeceased())
.addParameter(FhirConstants.ADDRESS_SEARCH_HANDLER, FhirConstants.CITY_PROPERTY, getCity())
.addParameter(FhirConstants.ADDRESS_SEARCH_HANDLER, FhirConstants.STATE_PROPERTY, getState())
.addParameter(FhirConstants.ADDRESS_SEARCH_HANDLER, FhirConstants.POSTAL_CODE_PROPERTY, getPostalCode())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ public PersonSearchParams(StringAndListParam name, TokenAndListParam gender, Dat
public SearchParameterMap toSearchParameterMap() {
return baseSearchParameterMap()
.addParameter(FhirConstants.NAME_SEARCH_HANDLER, FhirConstants.NAME_PROPERTY, getName())
.addParameter(FhirConstants.GENDER_SEARCH_HANDLER, getGender())
.addParameter(FhirConstants.DATE_RANGE_SEARCH_HANDLER, getBirthDate())
.addParameter(FhirConstants.GENDER_SEARCH_HANDLER, FhirConstants.GENDER_PROPERTY, getGender())
.addParameter(FhirConstants.DATE_RANGE_SEARCH_HANDLER, FhirConstants.BIRTHDATE_PROPERTY, getBirthDate())
.addParameter(FhirConstants.ADDRESS_SEARCH_HANDLER, FhirConstants.CITY_PROPERTY, getCity())
.addParameter(FhirConstants.ADDRESS_SEARCH_HANDLER, FhirConstants.STATE_PROPERTY, getState())
.addParameter(FhirConstants.ADDRESS_SEARCH_HANDLER, FhirConstants.POSTAL_CODE_PROPERTY, getPostalCode())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import static org.hl7.fhir.r4.model.Patient.SP_FAMILY;
import static org.hl7.fhir.r4.model.Patient.SP_GIVEN;
import static org.mockito.Mockito.when;
import static org.openmrs.module.fhir2.matchers.FhirMatchers.isDeceased;

import java.util.HashMap;
import java.util.HashSet;
Expand Down Expand Up @@ -114,6 +115,10 @@ public class PatientSearchQueryTest extends BaseModuleContextSensitiveTest {

private static final String PATIENT_BIRTHDATE_PATIENT_UUID = "ca17fcc5-ec96-487f-b9ea-42973c8973e3";

private static final String PATIENT_DEATH_DATE = "2003-01-01";

private static final String PATIENT_DEATH_DATE_LOWER_BOUND = "2001-08-01";

private static final String PATIENT_ADDRESS_CITY = "Indianapolis";

private static final String PATIENT_ADDRESS_STATE = "IN";
Expand Down Expand Up @@ -605,6 +610,89 @@ public void searchForPatients_shouldSearchForPatientsByUuid() {
assertThat(resultList.get(0).getIdElement().getIdPart(), equalTo(PATIENT_UUID));
}

@Test
public void searchForPatients_shouldSearchForPatientsByDeceasedStatus() {
SearchParameterMap theParams = new SearchParameterMap().addParameter(FhirConstants.BOOLEAN_SEARCH_HANDLER,
FhirConstants.DECEASED_PROPERTY, new TokenAndListParam().addAnd(new TokenParam("true")));

IBundleProvider results = search(theParams);

assertThat(results, notNullValue());
assertThat(results.size(), equalTo(2));

List<Patient> resultList = get(results);

assertThat(resultList, hasSize(equalTo(2)));
assertThat(resultList, everyItem(isDeceased()));
}

@Test
public void searchForPatients_shouldSearchForPatientsByDeceasedDate() {
SearchParameterMap theParams = new SearchParameterMap().addParameter(FhirConstants.DATE_RANGE_SEARCH_HANDLER,
FhirConstants.DEATHDATE_PROPERTY, new DateRangeParam().setLowerBound(PATIENT_DEATH_DATE));

IBundleProvider results = search(theParams);

assertThat(results, notNullValue());
assertThat(results.size(), equalTo(1));

List<Patient> resultList = get(results);

assertThat(resultList, hasSize(equalTo(1)));
assertThat(resultList, everyItem(isDeceased()));
}

@Test
public void searchForPatients_shouldSearchForPatientsByDeceasedDateWithLowerBound() {
SearchParameterMap theParams = new SearchParameterMap().addParameter(FhirConstants.DATE_RANGE_SEARCH_HANDLER,
FhirConstants.DEATHDATE_PROPERTY, new DateRangeParam().setLowerBound(PATIENT_DEATH_DATE));

IBundleProvider results = search(theParams);

assertThat(results, notNullValue());
assertThat(results.size(), greaterThanOrEqualTo(1));

List<Patient> resultList = get(results);

assertThat(resultList, not(empty()));
assertThat(resultList, everyItem(isDeceased()));
}

@Test
public void searchForPatients_shouldSearchForPatientsByDeathDateWithUpperBound() {
SearchParameterMap theParams = new SearchParameterMap().addParameter(FhirConstants.DATE_RANGE_SEARCH_HANDLER,
FhirConstants.DEATHDATE_PROPERTY, new DateRangeParam().setUpperBound(PATIENT_DEATH_DATE));

IBundleProvider results = search(theParams);

assertThat(results, notNullValue());
assertThat(results.size(), greaterThan(1));

List<Patient> resultList = get(results);

assertThat(resultList, not(empty()));
assertThat(resultList, hasSize(greaterThan(1)));
assertThat(resultList, everyItem(isDeceased()));
}

@Test
public void searchForPatients_shouldSearchForPatientsByDeathDateWithinBoundaries() {
SearchParameterMap theParams = new SearchParameterMap().addParameter(FhirConstants.DATE_RANGE_SEARCH_HANDLER,
FhirConstants.DEATHDATE_PROPERTY,
new DateRangeParam().setLowerBound(PATIENT_DEATH_DATE_LOWER_BOUND).setUpperBound(PATIENT_DEATH_DATE));

IBundleProvider results = search(theParams);

assertThat(results, notNullValue());
assertThat(results.size(), greaterThan(1));

List<Patient> resultList = get(results);

assertThat(resultList, not(empty()));
assertThat(resultList, hasSize(greaterThan(1)));
assertThat(resultList, everyItem(isDeceased()));
}

@Test
public void searchForPatients_shouldSearchForPatientsByLastUpdatedDateCreated() {
DateRangeParam lastUpdated = new DateRangeParam().setUpperBound(DATE_CREATED).setLowerBound(DATE_CREATED);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.fhir2.matchers;

import org.hamcrest.Matcher;
import org.hl7.fhir.r4.model.Patient;

public class FhirMatchers {

public static Matcher<Patient> isDeceased() {
return new IsDeceasedMatcher();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.fhir2.matchers;

import org.hamcrest.Description;
import org.hamcrest.TypeSafeDiagnosingMatcher;
import org.hl7.fhir.r4.model.Patient;

public class IsDeceasedMatcher extends TypeSafeDiagnosingMatcher<Patient> {

@Override
protected boolean matchesSafely(Patient p, Description description) {
if (!p.hasDeceased()) {
description.appendText("patient does not have a deceased attribute");
return false;
} else if (p.hasDeceasedBooleanType() && !p.getDeceasedBooleanType().booleanValue()) {
description.appendText("patient is not marked as deceased");
return false;
} else if (p.hasDeceasedDateTimeType() && p.getDeceasedDateTimeType().isEmpty()) {
description.appendText("patient does not have a deceased date");
return false;
} else {
description.appendText("patient is marked as deceased");
return true;
}
}

@Override
public void describeTo(Description description) {
description.appendText("a patient who is deceased");
}
}

0 comments on commit 10a5c39

Please sign in to comment.