Issue 3172 support member match operation (#3187)
* Suppress unresolved maven properties errors to avoid IntelliJ complains * Support for $member-match operation * Add more reference cases * Adjust tests * Add test and handle missed condition Co-authored-by: juan.marchionatto <juan.marchionatto@smilecdr.com>
This commit is contained in:
parent
3743fbc62f
commit
d496ca98ad
|
@ -201,6 +201,14 @@ public class Constants {
|
|||
public static final String PARAM_TAGS = "_tags";
|
||||
public static final String PARAM_TEXT = "_text";
|
||||
public static final String PARAM_VALIDATE = "_validate";
|
||||
|
||||
/**
|
||||
* $member-match operation
|
||||
*/
|
||||
public static final String PARAM_MEMBER_PATIENT = "MemberPatient";
|
||||
public static final String PARAM_OLD_COVERAGE = "OldCoverage";
|
||||
public static final String PARAM_NEW_COVERAGE = "NewCoverage";
|
||||
|
||||
public static final String PARAMQUALIFIER_MISSING = ":missing";
|
||||
public static final String PARAMQUALIFIER_MISSING_FALSE = "false";
|
||||
public static final String PARAMQUALIFIER_MISSING_TRUE = "true";
|
||||
|
|
|
@ -183,3 +183,9 @@ ca.uhn.fhir.jpa.provider.DiffProvider.cantDiffDifferentTypes=Unable to diff two
|
|||
|
||||
ca.uhn.fhir.jpa.interceptor.validation.RuleRequireProfileDeclaration.noMatchingProfile=Resource of type "{0}" does not declare conformance to profile from: {1}
|
||||
ca.uhn.fhir.jpa.interceptor.validation.RuleRequireProfileDeclaration.illegalProfile=Resource of type "{0}" must not declare conformance to profile: {1}
|
||||
|
||||
operation.member.match.error.coverage.not.found=Could not find coverage for member based on coverage id or coverage identifier.
|
||||
operation.member.match.error.beneficiary.not.found=Could not find beneficiary for coverage.
|
||||
operation.member.match.error.missing.parameter=Parameter "{0}" is required.
|
||||
operation.member.match.error.beneficiary.without.identifier=Coverage beneficiary does not have an identifier.
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
type: add
|
||||
issue: 3172
|
||||
title: "Implement support for $member-match operation by coverage-id or coverage-identifier.
|
||||
(Beneficiary demographic matching not supported)"
|
|
@ -86,6 +86,7 @@ import ca.uhn.fhir.jpa.provider.DiffProvider;
|
|||
import ca.uhn.fhir.jpa.provider.SubscriptionTriggeringProvider;
|
||||
import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider;
|
||||
import ca.uhn.fhir.jpa.provider.ValueSetOperationProvider;
|
||||
import ca.uhn.fhir.jpa.provider.r4.MemberMatcherR4Helper;
|
||||
import ca.uhn.fhir.jpa.reindex.ReindexJobSubmitterImpl;
|
||||
import ca.uhn.fhir.jpa.sched.AutowiringSpringBeanJobFactory;
|
||||
import ca.uhn.fhir.jpa.sched.HapiSchedulerServiceImpl;
|
||||
|
@ -952,6 +953,14 @@ public abstract class BaseConfig {
|
|||
return new UnknownCodeSystemWarningValidationSupport(fhirContext());
|
||||
}
|
||||
|
||||
@Lazy
|
||||
@Bean
|
||||
public MemberMatcherR4Helper memberMatcherR4Helper(FhirContext theFhirContext) {
|
||||
return new MemberMatcherR4Helper(theFhirContext);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void configureEntityManagerFactory(LocalContainerEntityManagerFactoryBean theFactory, FhirContext theCtx) {
|
||||
theFactory.setJpaDialect(hibernateJpaDialect(theCtx.getLocalizer()));
|
||||
theFactory.setPackagesToScan("ca.uhn.fhir.jpa.model.entity", "ca.uhn.fhir.jpa.entity");
|
||||
|
|
|
@ -3,6 +3,7 @@ package ca.uhn.fhir.jpa.provider.r4;
|
|||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoPatient;
|
||||
import ca.uhn.fhir.jpa.model.util.JpaConstants;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Operation;
|
||||
|
@ -18,13 +19,20 @@ import ca.uhn.fhir.rest.param.StringOrListParam;
|
|||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.param.TokenOrListParam;
|
||||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
|
||||
import org.hl7.fhir.r4.model.Coverage;
|
||||
import org.hl7.fhir.r4.model.IdType;
|
||||
import org.hl7.fhir.r4.model.Parameters;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
import org.hl7.fhir.r4.model.StringType;
|
||||
import org.hl7.fhir.r4.model.UnsignedIntType;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
|
@ -50,6 +58,10 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|||
|
||||
public class BaseJpaResourceProviderPatientR4 extends JpaResourceProviderR4<Patient> {
|
||||
|
||||
@Autowired
|
||||
private MemberMatcherR4Helper myMemberMatcherR4Helper;
|
||||
|
||||
|
||||
/**
|
||||
* Patient/123/$everything
|
||||
*/
|
||||
|
@ -150,6 +162,85 @@ public class BaseJpaResourceProviderPatientR4 extends JpaResourceProviderR4<Pati
|
|||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* /Patient/$member-match operation
|
||||
* Basic implementation matching by coverage id or by coverage identifier. Not matching by
|
||||
* Beneficiary (Patient) demographics in this version
|
||||
*/
|
||||
@Operation(name = ProviderConstants.OPERATION_MEMBER_MATCH, idempotent = true, returnParameters = {
|
||||
@OperationParam(name = "MemberIdentifier", type = StringDt.class)
|
||||
})
|
||||
public Parameters patientMemberMatch(
|
||||
javax.servlet.http.HttpServletRequest theServletRequest,
|
||||
|
||||
@Description(shortDefinition = "The target of the operation. Will be returned with Identifier for matched coverage added.")
|
||||
@OperationParam(name = Constants.PARAM_MEMBER_PATIENT, min = 1, max = 1)
|
||||
Patient theMemberPatient,
|
||||
|
||||
@Description(shortDefinition = "Old coverage information as extracted from beneficiary's card.")
|
||||
@OperationParam(name = Constants.PARAM_OLD_COVERAGE, min = 1, max = 1)
|
||||
Coverage oldCoverage,
|
||||
|
||||
@Description(shortDefinition = "New Coverage information. Provided as a reference. Optionally returned unmodified.")
|
||||
@OperationParam(name = Constants.PARAM_NEW_COVERAGE, min = 1, max = 1)
|
||||
Coverage newCoverage,
|
||||
|
||||
RequestDetails theRequestDetails
|
||||
) {
|
||||
return doMemberMatchOperation(theServletRequest, theMemberPatient, oldCoverage, newCoverage, theRequestDetails);
|
||||
}
|
||||
|
||||
|
||||
private Parameters doMemberMatchOperation(HttpServletRequest theServletRequest, Patient theMemberPatient,
|
||||
Coverage theCoverageToMatch, Coverage theCoverageToLink, RequestDetails theRequestDetails) {
|
||||
|
||||
validateParams(theMemberPatient, theCoverageToMatch, theCoverageToLink);
|
||||
|
||||
Optional<Coverage> coverageOpt = myMemberMatcherR4Helper.findMatchingCoverage(theCoverageToMatch);
|
||||
if ( ! coverageOpt.isPresent()) {
|
||||
String i18nMessage = getContext().getLocalizer().getMessage(
|
||||
"operation.member.match.error.coverage.not.found");
|
||||
throw new UnprocessableEntityException(i18nMessage);
|
||||
}
|
||||
Coverage coverage = coverageOpt.get();
|
||||
|
||||
Optional<Patient> patientOpt = myMemberMatcherR4Helper.getBeneficiaryPatient(coverage);
|
||||
if (! patientOpt.isPresent()) {
|
||||
String i18nMessage = getContext().getLocalizer().getMessage(
|
||||
"operation.member.match.error.beneficiary.not.found");
|
||||
throw new UnprocessableEntityException(i18nMessage);
|
||||
}
|
||||
Patient patient = patientOpt.get();
|
||||
|
||||
if (patient.getIdentifier().isEmpty()) {
|
||||
String i18nMessage = getContext().getLocalizer().getMessage(
|
||||
"operation.member.match.error.beneficiary.without.identifier");
|
||||
throw new UnprocessableEntityException(i18nMessage);
|
||||
}
|
||||
|
||||
myMemberMatcherR4Helper.addMemberIdentifierToMemberPatient(theMemberPatient, patient.getIdentifierFirstRep());
|
||||
|
||||
return myMemberMatcherR4Helper.buildSuccessReturnParameters(theMemberPatient, theCoverageToLink);
|
||||
}
|
||||
|
||||
|
||||
private void validateParams(Patient theMemberPatient, Coverage theOldCoverage, Coverage theNewCoverage) {
|
||||
validateParam(theMemberPatient, Constants.PARAM_MEMBER_PATIENT);
|
||||
validateParam(theOldCoverage, Constants.PARAM_OLD_COVERAGE);
|
||||
validateParam(theNewCoverage, Constants.PARAM_NEW_COVERAGE);
|
||||
}
|
||||
|
||||
|
||||
private void validateParam(Object theParam, String theParamName) {
|
||||
if (theParam == null) {
|
||||
String i18nMessage = getContext().getLocalizer().getMessage(
|
||||
"operation.member.match.error.missing.parameter", theParamName);
|
||||
throw new UnprocessableEntityException(i18nMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given a list of string types, return only the ID portions of any parameters passed in.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
package ca.uhn.fhir.jpa.provider.r4;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.param.TokenOrListParam;
|
||||
import ca.uhn.fhir.util.ParametersUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.r4.model.CodeableConcept;
|
||||
import org.hl7.fhir.r4.model.Coding;
|
||||
import org.hl7.fhir.r4.model.Coverage;
|
||||
import org.hl7.fhir.r4.model.Identifier;
|
||||
import org.hl7.fhir.r4.model.Parameters;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
import org.hl7.fhir.r4.model.Reference;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static ca.uhn.fhir.rest.api.Constants.PARAM_MEMBER_PATIENT;
|
||||
import static ca.uhn.fhir.rest.api.Constants.PARAM_NEW_COVERAGE;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR JPA Server
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2021 Smile CDR, Inc.
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
public class MemberMatcherR4Helper {
|
||||
|
||||
private static final String OUT_COVERAGE_IDENTIFIER_CODE_SYSTEM = "http://terminology.hl7.org/CodeSystem/v2-0203";
|
||||
private static final String OUT_COVERAGE_IDENTIFIER_CODE = "UMB";
|
||||
private static final String OUT_COVERAGE_IDENTIFIER_TEXT = "Member Number";
|
||||
private static final String COVERAGE_TYPE = "Coverage";
|
||||
|
||||
private final FhirContext myFhirContext;
|
||||
|
||||
@Autowired
|
||||
private IFhirResourceDao<Coverage> myCoverageDao;
|
||||
|
||||
@Autowired
|
||||
private IFhirResourceDao<Patient> myPatientDao;
|
||||
|
||||
|
||||
public MemberMatcherR4Helper(FhirContext theContext) {
|
||||
myFhirContext = theContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find Coverage matching the received member (Patient) by coverage id or by coverage identifier
|
||||
* Matching by member patient demographics is not supported.
|
||||
*/
|
||||
public Optional<Coverage> findMatchingCoverage(Coverage theCoverageToMatch) {
|
||||
// search by received old coverage id
|
||||
List<IBaseResource> foundCoverages = findCoverageByCoverageId(theCoverageToMatch);
|
||||
if (foundCoverages.size() == 1 && isCoverage(foundCoverages.get(0))) {
|
||||
return Optional.of( (Coverage) foundCoverages.get(0) );
|
||||
}
|
||||
|
||||
// search by received old coverage identifier
|
||||
foundCoverages = findCoverageByCoverageIdentifier(theCoverageToMatch);
|
||||
if (foundCoverages.size() == 1 && isCoverage(foundCoverages.get(0))) {
|
||||
return Optional.of( (Coverage) foundCoverages.get(0) );
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
|
||||
private List<IBaseResource> findCoverageByCoverageIdentifier(Coverage theCoverageToMatch) {
|
||||
TokenOrListParam identifierParam = new TokenOrListParam();
|
||||
for (Identifier identifier : theCoverageToMatch.getIdentifier()) {
|
||||
identifierParam.add(identifier.getSystem(), identifier.getValue());
|
||||
}
|
||||
|
||||
SearchParameterMap paramMap = new SearchParameterMap()
|
||||
.add("identifier", identifierParam);
|
||||
ca.uhn.fhir.rest.api.server.IBundleProvider retVal = myCoverageDao.search(paramMap);
|
||||
|
||||
return retVal.getAllResources();
|
||||
}
|
||||
|
||||
|
||||
private boolean isCoverage(IBaseResource theIBaseResource) {
|
||||
return theIBaseResource.fhirType().equals(COVERAGE_TYPE);
|
||||
}
|
||||
|
||||
|
||||
private List<IBaseResource> findCoverageByCoverageId(Coverage theCoverageToMatch) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap()
|
||||
.add("_id", new StringParam(theCoverageToMatch.getId()));
|
||||
ca.uhn.fhir.rest.api.server.IBundleProvider retVal = myCoverageDao.search(paramMap);
|
||||
|
||||
return retVal.getAllResources();
|
||||
}
|
||||
|
||||
|
||||
public Parameters buildSuccessReturnParameters(Patient theMemberPatient, Coverage theCoverage) {
|
||||
IBaseParameters parameters = ParametersUtil.newInstance(myFhirContext);
|
||||
ParametersUtil.addParameterToParameters(myFhirContext, parameters, PARAM_MEMBER_PATIENT, theMemberPatient);
|
||||
ParametersUtil.addParameterToParameters(myFhirContext, parameters, PARAM_NEW_COVERAGE, theCoverage);
|
||||
return (Parameters) parameters;
|
||||
}
|
||||
|
||||
|
||||
public void addMemberIdentifierToMemberPatient(Patient theMemberPatient, Identifier theNewIdentifier) {
|
||||
Coding coding = new Coding()
|
||||
.setSystem(OUT_COVERAGE_IDENTIFIER_CODE_SYSTEM)
|
||||
.setCode(OUT_COVERAGE_IDENTIFIER_CODE)
|
||||
.setDisplay(OUT_COVERAGE_IDENTIFIER_TEXT)
|
||||
.setUserSelected(false);
|
||||
|
||||
CodeableConcept concept = new CodeableConcept()
|
||||
.setCoding(Lists.newArrayList(coding))
|
||||
.setText(OUT_COVERAGE_IDENTIFIER_TEXT);
|
||||
|
||||
Identifier newIdentifier = new Identifier()
|
||||
.setUse(Identifier.IdentifierUse.USUAL)
|
||||
.setType(concept)
|
||||
.setSystem(theNewIdentifier.getSystem())
|
||||
.setValue(theNewIdentifier.getValue());
|
||||
|
||||
theMemberPatient.addIdentifier(newIdentifier);
|
||||
}
|
||||
|
||||
|
||||
public Optional<Patient> getBeneficiaryPatient(Coverage theCoverage) {
|
||||
if (theCoverage.getBeneficiaryTarget() == null && theCoverage.getBeneficiary() == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
if (theCoverage.getBeneficiaryTarget() != null
|
||||
&& ! theCoverage.getBeneficiaryTarget().getIdentifier().isEmpty()) {
|
||||
return Optional.of(theCoverage.getBeneficiaryTarget());
|
||||
}
|
||||
|
||||
Reference beneficiaryRef = theCoverage.getBeneficiary();
|
||||
if (beneficiaryRef == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
if (beneficiaryRef.getResource() != null) {
|
||||
return Optional.of((Patient) beneficiaryRef.getResource());
|
||||
}
|
||||
|
||||
if (beneficiaryRef.getReference() == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
Patient beneficiary = myPatientDao.read(new IdDt(beneficiaryRef.getReference()));
|
||||
return Optional.ofNullable(beneficiary);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,241 @@
|
|||
package ca.uhn.fhir.jpa.provider.r4;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.hl7.fhir.r4.model.Coverage;
|
||||
import org.hl7.fhir.r4.model.Identifier;
|
||||
import org.hl7.fhir.r4.model.Parameters;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
import org.hl7.fhir.r4.model.Reference;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static ca.uhn.fhir.rest.api.Constants.PARAM_MEMBER_PATIENT;
|
||||
import static ca.uhn.fhir.rest.api.Constants.PARAM_NEW_COVERAGE;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.isA;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class MemberMatcherR4HelperTest {
|
||||
|
||||
private final FhirContext myFhirContext = FhirContext.forR4();
|
||||
@Mock private IFhirResourceDao<Coverage> myCoverageDao;
|
||||
@Mock private IFhirResourceDao<Patient> myPatientDao;
|
||||
|
||||
private MemberMatcherR4Helper myTestedHelper;
|
||||
|
||||
@Mock private Coverage myCoverageToMatch;
|
||||
@Mock private Patient myPatient;
|
||||
@Mock private IBundleProvider myBundleProvider;
|
||||
|
||||
private final Coverage myMatchedCoverage = new Coverage();
|
||||
private final Identifier myMatchingIdentifier = new Identifier()
|
||||
.setSystem("identifier-system").setValue("identifier-value");
|
||||
|
||||
@Captor ArgumentCaptor<SearchParameterMap> mySearchParameterMapCaptor;
|
||||
|
||||
@BeforeEach
|
||||
public void beforeEach() {
|
||||
myTestedHelper = new MemberMatcherR4Helper(myFhirContext);
|
||||
|
||||
// @InjectMocks didn't work
|
||||
ReflectionTestUtils.setField(myTestedHelper, "myCoverageDao", myCoverageDao);
|
||||
ReflectionTestUtils.setField(myTestedHelper, "myPatientDao", myPatientDao);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void findMatchingCoverageMatchByIdReturnsMatched() {
|
||||
when(myCoverageToMatch.getId()).thenReturn("cvg-to-match-id");
|
||||
when(myCoverageDao.search(isA(SearchParameterMap.class))).thenReturn(myBundleProvider);
|
||||
when(myBundleProvider.getAllResources()).thenReturn(Collections.singletonList(myMatchedCoverage));
|
||||
|
||||
Optional<Coverage> result = myTestedHelper.findMatchingCoverage(myCoverageToMatch);
|
||||
|
||||
assertEquals(Optional.of(myMatchedCoverage), result);
|
||||
verify(myCoverageDao).search(mySearchParameterMapCaptor.capture());
|
||||
SearchParameterMap spMap = mySearchParameterMapCaptor.getValue();
|
||||
assertTrue(spMap.containsKey("_id"));
|
||||
List<List<IQueryParameterType>> listListParams = spMap.get("_id");
|
||||
assertEquals(1, listListParams.size());
|
||||
assertEquals(1, listListParams.get(0).size());
|
||||
IQueryParameterType param = listListParams.get(0).get(0);
|
||||
assertEquals("cvg-to-match-id", param.getValueAsQueryToken(myFhirContext));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void findMatchingCoverageMatchByIdentifierReturnsMatched() {
|
||||
when(myCoverageToMatch.getId()).thenReturn("non-matching-id");
|
||||
when(myCoverageToMatch.getIdentifier()).thenReturn(Collections.singletonList(myMatchingIdentifier));
|
||||
when(myCoverageDao.search(isA(SearchParameterMap.class))).thenReturn(myBundleProvider);
|
||||
when(myBundleProvider.getAllResources()).thenReturn(
|
||||
Collections.emptyList(), Collections.singletonList(myMatchedCoverage));
|
||||
|
||||
Optional<Coverage> result = myTestedHelper.findMatchingCoverage(myCoverageToMatch);
|
||||
|
||||
assertEquals(Optional.of(myMatchedCoverage), result);
|
||||
verify(myCoverageDao, times(2)).search(mySearchParameterMapCaptor.capture());
|
||||
List<SearchParameterMap> spMap = mySearchParameterMapCaptor.getAllValues();
|
||||
assertTrue(spMap.get(0).containsKey("_id"));
|
||||
assertTrue(spMap.get(1).containsKey("identifier"));
|
||||
List<List<IQueryParameterType>> listListParams = spMap.get(1).get("identifier");
|
||||
assertEquals(1, listListParams.size());
|
||||
assertEquals(1, listListParams.get(0).size());
|
||||
IQueryParameterType param = listListParams.get(0).get(0);
|
||||
assertEquals(myMatchingIdentifier.getSystem() + "|" + myMatchingIdentifier.getValue(),
|
||||
param.getValueAsQueryToken(myFhirContext));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void findMatchingCoverageNoMatchReturnsEmpty() {
|
||||
when(myCoverageToMatch.getId()).thenReturn("non-matching-id");
|
||||
when(myCoverageToMatch.getIdentifier()).thenReturn(Collections.singletonList(myMatchingIdentifier));
|
||||
when(myCoverageDao.search(isA(SearchParameterMap.class))).thenReturn(myBundleProvider);
|
||||
when(myBundleProvider.getAllResources()).thenReturn(Collections.emptyList(), Collections.emptyList());
|
||||
|
||||
Optional<Coverage> result = myTestedHelper.findMatchingCoverage(myCoverageToMatch);
|
||||
|
||||
assertFalse(result.isPresent());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void buildSuccessReturnParameters() {
|
||||
Patient patient = new Patient();
|
||||
Coverage coverage = new Coverage();
|
||||
|
||||
Parameters result = myTestedHelper.buildSuccessReturnParameters(patient, coverage);
|
||||
|
||||
assertEquals(PARAM_MEMBER_PATIENT, result.getParameter().get(0).getName());
|
||||
assertEquals(patient, result.getParameter().get(0).getResource());
|
||||
|
||||
assertEquals(PARAM_NEW_COVERAGE, result.getParameter().get(1).getName());
|
||||
assertEquals(coverage, result.getParameter().get(1).getResource());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void addMemberIdentifierToMemberPatient() {
|
||||
Identifier originalIdentifier = new Identifier()
|
||||
.setSystem("original-identifier-system").setValue("original-identifier-value");
|
||||
|
||||
Identifier newIdentifier = new Identifier()
|
||||
.setSystem("new-identifier-system").setValue("new-identifier-value");
|
||||
|
||||
Patient patient = new Patient().setIdentifier(Lists.newArrayList(originalIdentifier));
|
||||
|
||||
myTestedHelper.addMemberIdentifierToMemberPatient(patient, newIdentifier);
|
||||
|
||||
assertEquals(2, patient.getIdentifier().size());
|
||||
|
||||
assertEquals("original-identifier-system", patient.getIdentifier().get(0).getSystem());
|
||||
assertEquals("original-identifier-value", patient.getIdentifier().get(0).getValue());
|
||||
|
||||
assertEquals("new-identifier-system", patient.getIdentifier().get(1).getSystem());
|
||||
assertEquals("new-identifier-value", patient.getIdentifier().get(1).getValue());
|
||||
}
|
||||
|
||||
@Nested
|
||||
public class TestGetBeneficiaryPatient {
|
||||
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private Coverage coverage;
|
||||
|
||||
|
||||
@Test
|
||||
void noBeneficiaryOrBeneficiaryTargetReturnsEmpty() {
|
||||
when(coverage.getBeneficiaryTarget()).thenReturn(null);
|
||||
when(coverage.getBeneficiary()).thenReturn(null);
|
||||
|
||||
Optional<Patient> result = myTestedHelper.getBeneficiaryPatient(coverage);
|
||||
|
||||
assertFalse(result.isPresent());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void beneficiaryTargetWithNoIdentifierReturnsEmpty() {
|
||||
when(coverage.getBeneficiary()).thenReturn(null);
|
||||
when(coverage.getBeneficiaryTarget()).thenReturn(new Patient());
|
||||
|
||||
Optional<Patient> result = myTestedHelper.getBeneficiaryPatient(coverage);
|
||||
|
||||
assertFalse(result.isPresent());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void beneficiaryTargetWithIdentifierReturnsBeneficiary() {
|
||||
Patient patient = new Patient().setIdentifier(Collections.singletonList(new Identifier()));
|
||||
when(coverage.getBeneficiaryTarget()).thenReturn(patient);
|
||||
|
||||
Optional<Patient> result = myTestedHelper.getBeneficiaryPatient(coverage);
|
||||
|
||||
assertTrue(result.isPresent());
|
||||
assertEquals(patient, result.get());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void beneficiaryReferenceResourceReturnsBeneficiary() {
|
||||
Patient patient = new Patient().setIdentifier(Collections.singletonList(new Identifier()));
|
||||
when(coverage.getBeneficiaryTarget()).thenReturn(null);
|
||||
when(coverage.getBeneficiary().getResource()).thenReturn(patient);
|
||||
|
||||
Optional<Patient> result = myTestedHelper.getBeneficiaryPatient(coverage);
|
||||
|
||||
assertTrue(result.isPresent());
|
||||
assertEquals(patient, result.get());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void beneficiaryReferenceNoResourceOrReferenceReturnsEmpty() {
|
||||
when(coverage.getBeneficiaryTarget()).thenReturn(null);
|
||||
when(coverage.getBeneficiary()).thenReturn(new Reference());
|
||||
|
||||
Optional<Patient> result = myTestedHelper.getBeneficiaryPatient(coverage);
|
||||
|
||||
assertFalse(result.isPresent());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void beneficiaryReferenceReferenceReturnsReadPatient() {
|
||||
when(coverage.getBeneficiaryTarget()).thenReturn(null);
|
||||
when(coverage.getBeneficiary().getResource()).thenReturn(null);
|
||||
when(coverage.getBeneficiary().getReference()).thenReturn("patient-id");
|
||||
|
||||
myTestedHelper.getBeneficiaryPatient(coverage);
|
||||
|
||||
verify(myPatientDao).read(new IdDt("patient-id"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,388 @@
|
|||
package ca.uhn.fhir.jpa.provider.r4;
|
||||
|
||||
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
||||
import ca.uhn.fhir.parser.StrictErrorHandler;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.client.apache.ResourceEntity;
|
||||
import ca.uhn.fhir.util.ParametersUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.hl7.fhir.instance.model.api.IBase;
|
||||
import org.hl7.fhir.r4.model.CodeableConcept;
|
||||
import org.hl7.fhir.r4.model.Coding;
|
||||
import org.hl7.fhir.r4.model.Coverage;
|
||||
import org.hl7.fhir.r4.model.Enumerations;
|
||||
import org.hl7.fhir.r4.model.HumanName;
|
||||
import org.hl7.fhir.r4.model.Identifier;
|
||||
import org.hl7.fhir.r4.model.Organization;
|
||||
import org.hl7.fhir.r4.model.Parameters;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
import org.hl7.fhir.r4.model.Reference;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static ca.uhn.fhir.rest.api.Constants.PARAM_MEMBER_PATIENT;
|
||||
import static ca.uhn.fhir.rest.api.Constants.PARAM_NEW_COVERAGE;
|
||||
import static ca.uhn.fhir.rest.api.Constants.PARAM_OLD_COVERAGE;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
@SuppressWarnings("Duplicates")
|
||||
public class PatientMemberMatchOperationR4Test extends BaseResourceProviderR4Test {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(PatientMemberMatchOperationR4Test.class);
|
||||
|
||||
private static final String ourQuery = "/Patient/$member-match?_format=json";
|
||||
private static final String EXISTING_COVERAGE_ID = "cov-id-123";
|
||||
private static final String EXISTING_COVERAGE_IDENT_SYSTEM = "http://centene.com/insurancePlanIds";
|
||||
private static final String EXISTING_COVERAGE_IDENT_VALUE = "U1234567890";
|
||||
private static final String EXISTING_COVERAGE_PATIENT_IDENT_SYSTEM = "http://oldhealthplan.example.com";
|
||||
private static final String EXISTING_COVERAGE_PATIENT_IDENT_VALUE = "DHU-55678";
|
||||
|
||||
private Identifier ourExistingCoverageIdentifier;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void beforeDisableResultReuse() {
|
||||
myDaoConfig.setReuseCachedSearchResultsForMillis(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@AfterEach
|
||||
public void after() throws Exception {
|
||||
super.after();
|
||||
myDaoConfig.setReuseCachedSearchResultsForMillis(new DaoConfig().getReuseCachedSearchResultsForMillis());
|
||||
myDaoConfig.setEverythingIncludesFetchPageSize(new DaoConfig().getEverythingIncludesFetchPageSize());
|
||||
myDaoConfig.setSearchPreFetchThresholds(new DaoConfig().getSearchPreFetchThresholds());
|
||||
myDaoConfig.setAllowExternalReferences(new DaoConfig().isAllowExternalReferences());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@BeforeEach
|
||||
public void before() throws Exception {
|
||||
super.before();
|
||||
myFhirCtx.setParserErrorHandler(new StrictErrorHandler());
|
||||
}
|
||||
|
||||
|
||||
private void createCoverageWithBeneficiary(
|
||||
boolean theAssociateBeneficiaryPatient, boolean includeBeneficiaryIdentifier) {
|
||||
|
||||
Patient member = null;
|
||||
if (theAssociateBeneficiaryPatient) {
|
||||
// Patient
|
||||
member = new Patient().setName(Lists.newArrayList(new HumanName()
|
||||
.setUse(HumanName.NameUse.OFFICIAL).setFamily("Person").addGiven("Patricia").addGiven("Ann")));
|
||||
if (includeBeneficiaryIdentifier) {
|
||||
member.setIdentifier(Collections.singletonList(new Identifier()
|
||||
.setSystem(EXISTING_COVERAGE_PATIENT_IDENT_SYSTEM).setValue(EXISTING_COVERAGE_PATIENT_IDENT_VALUE)));
|
||||
}
|
||||
|
||||
myClient.create().resource(member).execute().getId().toUnqualifiedVersionless().getValue();
|
||||
}
|
||||
|
||||
// Coverage
|
||||
ourExistingCoverageIdentifier = new Identifier()
|
||||
.setSystem(EXISTING_COVERAGE_IDENT_SYSTEM).setValue(EXISTING_COVERAGE_IDENT_VALUE);
|
||||
Coverage ourExistingCoverage = new Coverage()
|
||||
.setStatus(Coverage.CoverageStatus.ACTIVE)
|
||||
.setIdentifier(Collections.singletonList(ourExistingCoverageIdentifier));
|
||||
|
||||
if (theAssociateBeneficiaryPatient) {
|
||||
// this doesn't work
|
||||
// myOldCoverage.setBeneficiaryTarget(patient)
|
||||
ourExistingCoverage.setBeneficiary(new Reference(member))
|
||||
.setId(EXISTING_COVERAGE_ID);
|
||||
}
|
||||
|
||||
myClient.create().resource(ourExistingCoverage).execute().getId().toUnqualifiedVersionless().getValue();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testMemberMatchByCoverageId() throws Exception {
|
||||
createCoverageWithBeneficiary(true, true);
|
||||
|
||||
// patient doesn't participate in match
|
||||
Patient patient = new Patient().setGender(Enumerations.AdministrativeGender.FEMALE);
|
||||
|
||||
// Old Coverage
|
||||
Coverage oldCoverage = new Coverage();
|
||||
oldCoverage.setId(EXISTING_COVERAGE_ID); // must match field
|
||||
|
||||
// New Coverage (must return unchanged)
|
||||
Coverage newCoverage = new Coverage();
|
||||
newCoverage.setId("AA87654");
|
||||
newCoverage.setIdentifier(Lists.newArrayList(
|
||||
new Identifier().setSystem("http://newealthplan.example.com").setValue("234567")));
|
||||
|
||||
Parameters inputParameters = buildInputParameters(patient, oldCoverage, newCoverage);
|
||||
Parameters parametersResponse = performOperation(ourServerBase + ourQuery,
|
||||
EncodingEnum.JSON, inputParameters);
|
||||
|
||||
validateMemberPatient(parametersResponse);
|
||||
validateNewCoverage(parametersResponse, newCoverage);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCoverageNoBeneficiaryReturns422() throws Exception {
|
||||
createCoverageWithBeneficiary(false, false);
|
||||
|
||||
// patient doesn't participate in match
|
||||
Patient patient = new Patient().setGender(Enumerations.AdministrativeGender.FEMALE);
|
||||
|
||||
// Old Coverage
|
||||
Coverage oldCoverage = new Coverage();
|
||||
oldCoverage.setId(EXISTING_COVERAGE_ID); // must match field
|
||||
|
||||
// New Coverage (must return unchanged)
|
||||
Coverage newCoverage = new Coverage();
|
||||
newCoverage.setId("AA87654");
|
||||
newCoverage.setIdentifier(Lists.newArrayList(
|
||||
new Identifier().setSystem("http://newealthplan.example.com").setValue("234567")));
|
||||
|
||||
Parameters inputParameters = buildInputParameters(patient, oldCoverage, newCoverage);
|
||||
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
||||
"Could not find beneficiary for coverage.");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCoverageBeneficiaryNoIdentifierReturns422() throws Exception {
|
||||
createCoverageWithBeneficiary(true, false);
|
||||
|
||||
// patient doesn't participate in match
|
||||
Patient patient = new Patient().setGender(Enumerations.AdministrativeGender.FEMALE);
|
||||
|
||||
// Old Coverage
|
||||
Coverage oldCoverage = new Coverage();
|
||||
oldCoverage.setId(EXISTING_COVERAGE_ID); // must match field
|
||||
|
||||
// New Coverage (must return unchanged)
|
||||
Coverage newCoverage = new Coverage();
|
||||
newCoverage.setId("AA87654");
|
||||
newCoverage.setIdentifier(Lists.newArrayList(
|
||||
new Identifier().setSystem("http://newealthplan.example.com").setValue("234567")));
|
||||
|
||||
Parameters inputParameters = buildInputParameters(patient, oldCoverage, newCoverage);
|
||||
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
||||
"Coverage beneficiary does not have an identifier.");
|
||||
}
|
||||
|
||||
|
||||
@Nested
|
||||
public class ValidateParameterErrors {
|
||||
private Patient ourPatient;
|
||||
private Coverage ourOldCoverage;
|
||||
private Coverage ourNewCoverage;
|
||||
|
||||
@BeforeEach
|
||||
public void beforeValidateParameterErrors() {
|
||||
ourPatient = new Patient().setGender(Enumerations.AdministrativeGender.FEMALE);
|
||||
|
||||
ourOldCoverage = new Coverage();
|
||||
ourOldCoverage.setId(EXISTING_COVERAGE_ID);
|
||||
|
||||
ourNewCoverage = new Coverage();
|
||||
ourNewCoverage.setId("AA87654");
|
||||
ourNewCoverage.setIdentifier(Lists.newArrayList(
|
||||
new Identifier().setSystem("http://newealthplan.example.com").setValue("234567")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidPatient() throws Exception {
|
||||
Parameters inputParameters = buildInputParameters(new Patient(), ourOldCoverage, ourNewCoverage);
|
||||
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
||||
"Parameter \\\"" + PARAM_MEMBER_PATIENT + "\\\" is required.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidOldCoverage() throws Exception {
|
||||
Parameters inputParameters = buildInputParameters(ourPatient, new Coverage(), ourNewCoverage);
|
||||
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
||||
"Parameter \\\"" + PARAM_OLD_COVERAGE + "\\\" is required.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidNewCoverage() throws Exception {
|
||||
Parameters inputParameters = buildInputParameters(ourPatient, ourOldCoverage, new Coverage());
|
||||
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
||||
"Parameter \\\"" + PARAM_NEW_COVERAGE + "\\\" is required.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testMemberMatchByCoverageIdentifier() throws Exception {
|
||||
createCoverageWithBeneficiary(true, true);
|
||||
|
||||
// patient doesn't participate in match
|
||||
Patient patient = new Patient().setGender(Enumerations.AdministrativeGender.FEMALE);
|
||||
|
||||
// Old Coverage
|
||||
Coverage oldCoverage = new Coverage();
|
||||
oldCoverage.setId("9876B1");
|
||||
oldCoverage.setIdentifier(Lists.newArrayList(ourExistingCoverageIdentifier)); // must match field
|
||||
|
||||
// New Coverage (must return unchanged)
|
||||
Coverage newCoverage = new Coverage();
|
||||
newCoverage.setId("AA87654");
|
||||
newCoverage.setIdentifier(Lists.newArrayList(
|
||||
new Identifier().setSystem("http://newealthplan.example.com").setValue("234567")));
|
||||
|
||||
Parameters inputParameters = buildInputParameters(patient, oldCoverage, newCoverage);
|
||||
Parameters parametersResponse = performOperation(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters);
|
||||
|
||||
validateMemberPatient(parametersResponse);
|
||||
validateNewCoverage(parametersResponse, newCoverage);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validates that second resource from the response is same as the received coverage
|
||||
*/
|
||||
private void validateNewCoverage(Parameters theResponse, Coverage theOriginalCoverage) {
|
||||
List<IBase> patientList = ParametersUtil.getNamedParameters(getContext(), theResponse, PARAM_NEW_COVERAGE);
|
||||
assertEquals(1, patientList.size());
|
||||
Coverage respCoverage = (Coverage) theResponse.getParameter().get(1).getResource();
|
||||
|
||||
assertEquals("Coverage/" + theOriginalCoverage.getId(), respCoverage.getId());
|
||||
assertEquals(theOriginalCoverage.getIdentifierFirstRep().getSystem(), respCoverage.getIdentifierFirstRep().getSystem());
|
||||
assertEquals(theOriginalCoverage.getIdentifierFirstRep().getValue(), respCoverage.getIdentifierFirstRep().getValue());
|
||||
}
|
||||
|
||||
|
||||
private void validateMemberPatient(Parameters response) {
|
||||
// parameter MemberPatient must have a new identifier with:
|
||||
// {
|
||||
// "use": "usual",
|
||||
// "type": {
|
||||
// "coding": [
|
||||
// {
|
||||
// "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
|
||||
// "code": "UMB",
|
||||
// "display": "Member Number",
|
||||
// "userSelected": false
|
||||
// }
|
||||
// ],
|
||||
// "text": "Member Number"
|
||||
// },
|
||||
// "system": COVERAGE_PATIENT_IDENT_SYSTEM,
|
||||
// "value": COVERAGE_PATIENT_IDENT_VALUE
|
||||
// }
|
||||
List<IBase> patientList = ParametersUtil.getNamedParameters(getContext(), response, PARAM_MEMBER_PATIENT);
|
||||
assertEquals(1, patientList.size());
|
||||
Patient resultPatient = (Patient) response.getParameter().get(0).getResource();
|
||||
|
||||
assertNotNull(resultPatient.getIdentifier());
|
||||
assertEquals(1, resultPatient.getIdentifier().size());
|
||||
Identifier addedIdentifier = resultPatient.getIdentifier().get(0);
|
||||
assertEquals(Identifier.IdentifierUse.USUAL, addedIdentifier.getUse());
|
||||
checkCoding(addedIdentifier.getType());
|
||||
assertEquals(EXISTING_COVERAGE_PATIENT_IDENT_SYSTEM, addedIdentifier.getSystem());
|
||||
assertEquals(EXISTING_COVERAGE_PATIENT_IDENT_VALUE, addedIdentifier.getValue());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testNoCoverageMatchFound() throws Exception {
|
||||
// Patient doesn't participate in match
|
||||
Patient patient = new Patient().setGender(Enumerations.AdministrativeGender.FEMALE);
|
||||
|
||||
// Old Coverage
|
||||
Coverage oldCoverage = new Coverage();
|
||||
oldCoverage.setId("9876B1");
|
||||
oldCoverage.setIdentifier(Lists.newArrayList(
|
||||
new Identifier().setSystem("http://oldhealthplan.example.com").setValue("DH10001235")));
|
||||
|
||||
// New Coverage
|
||||
Organization newOrg = new Organization();
|
||||
newOrg.setId("Organization/ProviderOrg1");
|
||||
newOrg.setName("New Health Plan");
|
||||
|
||||
Coverage newCoverage = new Coverage();
|
||||
newCoverage.setId("AA87654");
|
||||
newCoverage.getContained().add(newOrg);
|
||||
newCoverage.setIdentifier(Lists.newArrayList(
|
||||
new Identifier().setSystem("http://newealthplan.example.com").setValue("234567")));
|
||||
|
||||
Parameters inputParameters = buildInputParameters(patient, oldCoverage, newCoverage);
|
||||
performOperationExpecting422(ourServerBase + ourQuery, EncodingEnum.JSON, inputParameters,
|
||||
"Could not find coverage for member");
|
||||
}
|
||||
|
||||
|
||||
private Parameters buildInputParameters(Patient thePatient, Coverage theOldCoverage, Coverage theNewCoverage) {
|
||||
Parameters p = new Parameters();
|
||||
ParametersUtil.addParameterToParameters(getContext(), p, PARAM_MEMBER_PATIENT, thePatient);
|
||||
ParametersUtil.addParameterToParameters(getContext(), p, PARAM_OLD_COVERAGE, theOldCoverage);
|
||||
ParametersUtil.addParameterToParameters(getContext(), p, PARAM_NEW_COVERAGE, theNewCoverage);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
private Parameters performOperation(String theUrl,
|
||||
EncodingEnum theEncoding, Parameters theInputParameters) throws Exception {
|
||||
|
||||
HttpPost post = new HttpPost(theUrl);
|
||||
post.addHeader(Constants.HEADER_ACCEPT_ENCODING, theEncoding.toString());
|
||||
post.setEntity(new ResourceEntity(getContext(), theInputParameters));
|
||||
ourLog.info("Request: {}", post);
|
||||
try (CloseableHttpResponse response = ourHttpClient.execute(post)) {
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
|
||||
return theEncoding.newParser(myFhirCtx).parseResource(Parameters.class,
|
||||
IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void performOperationExpecting422(String theUrl, EncodingEnum theEncoding,
|
||||
Parameters theInputParameters, String theExpectedErrorMsg) throws Exception {
|
||||
|
||||
HttpPost post = new HttpPost(theUrl);
|
||||
post.addHeader(Constants.HEADER_ACCEPT_ENCODING, theEncoding.toString());
|
||||
post.setEntity(new ResourceEntity(getContext(), theInputParameters));
|
||||
ourLog.info("Request: {}", post);
|
||||
try (CloseableHttpResponse response = ourHttpClient.execute(post)) {
|
||||
String responseString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
ourLog.info("Response: {}", responseString);
|
||||
assertEquals(422, response.getStatusLine().getStatusCode());
|
||||
assertThat(responseString, containsString(theExpectedErrorMsg));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void checkCoding(CodeableConcept theType) {
|
||||
// must match:
|
||||
// "coding": [
|
||||
// {
|
||||
// "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
|
||||
// "code": "UMB",
|
||||
// "display": "Member Number",
|
||||
// "userSelected": false
|
||||
// }
|
||||
// * ]
|
||||
Coding coding = theType.getCoding().get(0);
|
||||
assertEquals("http://terminology.hl7.org/CodeSystem/v2-0203", coding.getSystem());
|
||||
assertEquals("UMB", coding.getCode());
|
||||
assertEquals("Member Number", coding.getDisplay());
|
||||
assertFalse(coding.getUserSelected());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -186,6 +186,11 @@ public class ProviderConstants {
|
|||
*/
|
||||
public static final String OPERATION_REINDEX_RESPONSE_JOB_ID = "jobId";
|
||||
|
||||
/**
|
||||
* Operation name for the $member-match operation
|
||||
*/
|
||||
public static final String OPERATION_MEMBER_MATCH = "$member-match";
|
||||
|
||||
@Deprecated
|
||||
public static final String MARK_ALL_RESOURCES_FOR_REINDEXING = "$mark-all-resources-for-reindexing";
|
||||
/**
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -2519,6 +2519,7 @@
|
|||
<echo>Adding Google analytics in target/site for <body></echo>
|
||||
<replace dir="target/site" summary="true">
|
||||
<include name="**/*.html"></include>
|
||||
<!--suppress UnresolvedMavenProperty -->
|
||||
<replacefilter token="#build#" value="${label}"/>
|
||||
<replacefilter token="#version#" value="${project.version}"/>
|
||||
<replacetoken><![CDATA[</body>]]></replacetoken>
|
||||
|
@ -2843,6 +2844,7 @@
|
|||
<id>validate</id>
|
||||
<phase>generate-sources</phase>
|
||||
<configuration>
|
||||
<!--suppress UnresolvedMavenProperty -->
|
||||
<configLocation>${maven.multiModuleProjectDirectory}/src/checkstyle/checkstyle_config_nofixmes.xml</configLocation>
|
||||
<encoding>UTF-8</encoding>
|
||||
<consoleOutput>true</consoleOutput>
|
||||
|
|
Loading…
Reference in New Issue