Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FM2-648 fix NPE when querying deceased patient with openmrsPatients n… #553

Merged
merged 2 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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");
}
}
Loading