Cleanup member-match handler (#4431)
Cleanup member-match helper. Pass RequestDetails down for partitioning context.
This commit is contained in:
parent
21b1820294
commit
0d79d2026e
|
@ -168,3 +168,4 @@ Snap.*
|
|||
|
||||
|
||||
/database/
|
||||
/.run/
|
||||
|
|
|
@ -12,7 +12,7 @@ import ca.uhn.fhir.jpa.dao.r4.TransactionProcessorVersionAdapterR4;
|
|||
import ca.uhn.fhir.jpa.graphql.GraphQLProvider;
|
||||
import ca.uhn.fhir.jpa.graphql.GraphQLProviderWithIntrospection;
|
||||
import ca.uhn.fhir.jpa.provider.JpaSystemProvider;
|
||||
import ca.uhn.fhir.jpa.provider.r4.IConsentExtensionProvider;
|
||||
import ca.uhn.fhir.jpa.provider.r4.IMemberMatchConsentHook;
|
||||
import ca.uhn.fhir.jpa.provider.r4.MemberMatchR4ResourceProvider;
|
||||
import ca.uhn.fhir.jpa.provider.r4.MemberMatcherR4Helper;
|
||||
import ca.uhn.fhir.jpa.term.TermLoaderSvcImpl;
|
||||
|
@ -105,7 +105,7 @@ public class JpaR4Config {
|
|||
@Autowired IFhirResourceDao<Coverage> theCoverageDao,
|
||||
@Autowired IFhirResourceDao<Patient> thePatientDao,
|
||||
@Autowired IFhirResourceDao<Consent> theConsentDao,
|
||||
@Autowired(required = false) IConsentExtensionProvider theExtensionProvider
|
||||
@Autowired(required = false) IMemberMatchConsentHook theExtensionProvider
|
||||
) {
|
||||
return new MemberMatcherR4Helper(
|
||||
theContext,
|
||||
|
|
|
@ -20,22 +20,34 @@ package ca.uhn.fhir.jpa.provider.r4;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.util.ExtensionUtil;
|
||||
import org.hl7.fhir.instance.model.api.IBaseExtension;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
public interface IConsentExtensionProvider {
|
||||
/**
|
||||
* Hook for Consent pre-save additions.
|
||||
*
|
||||
* @deprecated - we just use Consumer now
|
||||
* TODO delete this.
|
||||
*/
|
||||
@Deprecated(since = "6.3.6", forRemoval = true)
|
||||
public interface IConsentExtensionProvider extends IMemberMatchConsentHook {
|
||||
Logger ourLog = LoggerFactory.getLogger(IConsentExtensionProvider.class);
|
||||
|
||||
Collection<IBaseExtension> getConsentExtension(IBaseResource theConsentResource);
|
||||
|
||||
default void accept(IBaseResource theResource) {
|
||||
Collection<IBaseExtension> extensions = getConsentExtension(theResource);
|
||||
|
||||
for (IBaseExtension ext : extensions) {
|
||||
IBaseExtension<?, ?> e = ExtensionUtil.addExtension(theResource, ext.getUrl());
|
||||
e.setValue(ext.getValue());
|
||||
}
|
||||
ourLog.trace("{} extension(s) added to Consent", extensions.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a Consent resource and returns a collection of Extensions that will
|
||||
* be added to the base resource.
|
||||
*
|
||||
* @param theConsentResource - the consent resource
|
||||
* @return - a collection of resources (or an empty collection if none).
|
||||
*/
|
||||
default Collection<IBaseExtension> getConsentExtension(IBaseResource theConsentResource) {
|
||||
return Collections.emptyList();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package ca.uhn.fhir.jpa.provider.r4;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Pre-save hook for Consent saved during $member-match.
|
||||
*/
|
||||
public interface IMemberMatchConsentHook extends Consumer<IBaseResource> {
|
||||
}
|
|
@ -34,7 +34,7 @@ import org.hl7.fhir.r4.model.Coverage;
|
|||
import org.hl7.fhir.r4.model.Parameters;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Optional;
|
||||
|
||||
public class MemberMatchR4ResourceProvider {
|
||||
|
@ -76,32 +76,32 @@ public class MemberMatchR4ResourceProvider {
|
|||
|
||||
RequestDetails theRequestDetails
|
||||
) {
|
||||
return doMemberMatchOperation(theServletRequest, theMemberPatient, oldCoverage, newCoverage, theConsent, theRequestDetails);
|
||||
return doMemberMatchOperation(theMemberPatient, oldCoverage, newCoverage, theConsent, theRequestDetails);
|
||||
}
|
||||
|
||||
|
||||
private Parameters doMemberMatchOperation(HttpServletRequest theServletRequest, Patient theMemberPatient,
|
||||
Coverage theCoverageToMatch, Coverage theCoverageToLink, Consent theConsent, RequestDetails theRequestDetails) {
|
||||
private Parameters doMemberMatchOperation(Patient theMemberPatient,
|
||||
Coverage theCoverageToMatch, Coverage theCoverageToLink, Consent theConsent, RequestDetails theRequestDetails) {
|
||||
|
||||
validateParams(theMemberPatient, theCoverageToMatch, theCoverageToLink, theConsent);
|
||||
|
||||
Optional<Coverage> coverageOpt = myMemberMatcherR4Helper.findMatchingCoverage(theCoverageToMatch);
|
||||
if ( ! coverageOpt.isPresent()) {
|
||||
Optional<Coverage> coverageOpt = myMemberMatcherR4Helper.findMatchingCoverage(theCoverageToMatch, theRequestDetails);
|
||||
if (coverageOpt.isEmpty()) {
|
||||
String i18nMessage = myFhirContext.getLocalizer().getMessage(
|
||||
"operation.member.match.error.coverage.not.found");
|
||||
throw new UnprocessableEntityException(Msg.code(1155) + i18nMessage);
|
||||
}
|
||||
Coverage coverage = coverageOpt.get();
|
||||
|
||||
Optional<Patient> patientOpt = myMemberMatcherR4Helper.getBeneficiaryPatient(coverage);
|
||||
if (! patientOpt.isPresent()) {
|
||||
Optional<Patient> patientOpt = myMemberMatcherR4Helper.getBeneficiaryPatient(coverage, theRequestDetails);
|
||||
if (patientOpt.isEmpty()) {
|
||||
String i18nMessage = myFhirContext.getLocalizer().getMessage(
|
||||
"operation.member.match.error.beneficiary.not.found");
|
||||
throw new UnprocessableEntityException(Msg.code(1156) + i18nMessage);
|
||||
}
|
||||
|
||||
Patient patient = patientOpt.get();
|
||||
if (!myMemberMatcherR4Helper.validPatientMember(patient, theMemberPatient)) {
|
||||
if (!myMemberMatcherR4Helper.validPatientMember(patient, theMemberPatient, theRequestDetails)) {
|
||||
String i18nMessage = myFhirContext.getLocalizer().getMessage(
|
||||
"operation.member.match.error.patient.not.found");
|
||||
throw new UnprocessableEntityException(Msg.code(2146) + i18nMessage);
|
||||
|
@ -120,7 +120,7 @@ public class MemberMatchR4ResourceProvider {
|
|||
}
|
||||
|
||||
myMemberMatcherR4Helper.addMemberIdentifierToMemberPatient(theMemberPatient, patient.getIdentifierFirstRep());
|
||||
myMemberMatcherR4Helper.updateConsentForMemberMatch(theConsent, patient, theMemberPatient);
|
||||
myMemberMatcherR4Helper.updateConsentForMemberMatch(theConsent, patient, theMemberPatient, theRequestDetails);
|
||||
return myMemberMatcherR4Helper.buildSuccessReturnParameters(theMemberPatient, theCoverageToLink, theConsent);
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,7 @@ public class MemberMatchR4ResourceProvider {
|
|||
validateConsentParam(theConsent);
|
||||
}
|
||||
|
||||
private void validateParam(Object theParam, String theParamName) {
|
||||
private void validateParam(@Nullable Object theParam, String theParamName) {
|
||||
if (theParam == null) {
|
||||
String i18nMessage = myFhirContext.getLocalizer().getMessage(
|
||||
"operation.member.match.error.missing.parameter", theParamName);
|
||||
|
|
|
@ -5,6 +5,7 @@ import ca.uhn.fhir.i18n.Msg;
|
|||
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.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.param.DateParam;
|
||||
import ca.uhn.fhir.rest.param.StringOrListParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
|
@ -13,7 +14,6 @@ import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
|||
import ca.uhn.fhir.util.ParametersUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hl7.fhir.instance.model.api.IBaseExtension;
|
||||
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
@ -21,7 +21,6 @@ import org.hl7.fhir.r4.model.CodeableConcept;
|
|||
import org.hl7.fhir.r4.model.Coding;
|
||||
import org.hl7.fhir.r4.model.Consent;
|
||||
import org.hl7.fhir.r4.model.Coverage;
|
||||
import org.hl7.fhir.r4.model.Extension;
|
||||
import org.hl7.fhir.r4.model.HumanName;
|
||||
import org.hl7.fhir.r4.model.Identifier;
|
||||
import org.hl7.fhir.r4.model.Parameters;
|
||||
|
@ -29,9 +28,9 @@ import org.hl7.fhir.r4.model.Patient;
|
|||
import org.hl7.fhir.r4.model.Reference;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static ca.uhn.fhir.rest.api.Constants.PARAM_CONSENT;
|
||||
import static ca.uhn.fhir.rest.api.Constants.PARAM_MEMBER_IDENTIFIER;
|
||||
|
@ -59,7 +58,7 @@ import static ca.uhn.fhir.rest.api.Constants.PARAM_NEW_COVERAGE;
|
|||
*/
|
||||
|
||||
public class MemberMatcherR4Helper {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(MemberMatcherR4Helper.class);
|
||||
static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(MemberMatcherR4Helper.class);
|
||||
|
||||
private static final String OUT_COVERAGE_IDENTIFIER_CODE_SYSTEM = "http://terminology.hl7.org/CodeSystem/v2-0203";
|
||||
private static final String OUT_COVERAGE_IDENTIFIER_CODE = "MB";
|
||||
|
@ -67,16 +66,14 @@ public class MemberMatcherR4Helper {
|
|||
private static final String COVERAGE_TYPE = "Coverage";
|
||||
private static final String CONSENT_POLICY_REGULAR_TYPE = "regular";
|
||||
private static final String CONSENT_POLICY_SENSITIVE_TYPE = "sensitive";
|
||||
public static final String CONSENT_IDENTIFIER_CODE_SYSTEM = "https://smilecdr.com/fhir/ns/member-match-fixme";
|
||||
public static final String CONSENT_IDENTIFIER_CODE_SYSTEM = "https://smilecdr.com/fhir/ns/member-match-source-client";
|
||||
|
||||
private final FhirContext myFhirContext;
|
||||
private final IFhirResourceDao<Coverage> myCoverageDao;
|
||||
private final IFhirResourceDao<Patient> myPatientDao;
|
||||
private final IFhirResourceDao<Consent> myConsentDao;
|
||||
// by default, not provided
|
||||
// but if it is, extensions can be added to Consent on $member-match
|
||||
@Nullable
|
||||
private final IConsentExtensionProvider myIConsentExtensionProvider;
|
||||
/** A hook to modify the Consent before save */
|
||||
private final Consumer<IBaseResource> myConsentModifier;
|
||||
|
||||
private boolean myRegularFilterSupported = false;
|
||||
|
||||
|
@ -85,27 +82,27 @@ public class MemberMatcherR4Helper {
|
|||
IFhirResourceDao<Coverage> theCoverageDao,
|
||||
IFhirResourceDao<Patient> thePatientDao,
|
||||
IFhirResourceDao<Consent> theConsentDao,
|
||||
@Nullable IConsentExtensionProvider theExtensionProvider
|
||||
@Nullable IMemberMatchConsentHook theConsentModifier
|
||||
) {
|
||||
myFhirContext = theContext;
|
||||
myConsentDao = theConsentDao;
|
||||
myPatientDao = thePatientDao;
|
||||
myCoverageDao = theCoverageDao;
|
||||
myIConsentExtensionProvider = theExtensionProvider;
|
||||
myConsentModifier = (theConsentModifier != null) ? theConsentModifier : noop -> {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Find Coverage matching the received member (Patient) by coverage id or by coverage identifier only
|
||||
*/
|
||||
public Optional<Coverage> findMatchingCoverage(Coverage theCoverageToMatch) {
|
||||
public Optional<Coverage> findMatchingCoverage(Coverage theCoverageToMatch, RequestDetails theRequestDetails) {
|
||||
// search by received old coverage id
|
||||
List<IBaseResource> foundCoverages = findCoverageByCoverageId(theCoverageToMatch);
|
||||
List<IBaseResource> foundCoverages = findCoverageByCoverageId(theCoverageToMatch, theRequestDetails);
|
||||
if (foundCoverages.size() == 1 && isCoverage(foundCoverages.get(0))) {
|
||||
return Optional.of((Coverage) foundCoverages.get(0));
|
||||
}
|
||||
|
||||
// search by received old coverage identifier
|
||||
foundCoverages = findCoverageByCoverageIdentifier(theCoverageToMatch);
|
||||
foundCoverages = findCoverageByCoverageIdentifier(theCoverageToMatch, theRequestDetails);
|
||||
if (foundCoverages.size() == 1 && isCoverage(foundCoverages.get(0))) {
|
||||
return Optional.of((Coverage) foundCoverages.get(0));
|
||||
}
|
||||
|
@ -114,7 +111,7 @@ public class MemberMatcherR4Helper {
|
|||
}
|
||||
|
||||
|
||||
private List<IBaseResource> findCoverageByCoverageIdentifier(Coverage theCoverageToMatch) {
|
||||
private List<IBaseResource> findCoverageByCoverageIdentifier(Coverage theCoverageToMatch, RequestDetails theRequestDetails) {
|
||||
TokenOrListParam identifierParam = new TokenOrListParam();
|
||||
for (Identifier identifier : theCoverageToMatch.getIdentifier()) {
|
||||
identifierParam.add(identifier.getSystem(), identifier.getValue());
|
||||
|
@ -122,7 +119,7 @@ public class MemberMatcherR4Helper {
|
|||
|
||||
SearchParameterMap paramMap = new SearchParameterMap()
|
||||
.add("identifier", identifierParam);
|
||||
ca.uhn.fhir.rest.api.server.IBundleProvider retVal = myCoverageDao.search(paramMap);
|
||||
ca.uhn.fhir.rest.api.server.IBundleProvider retVal = myCoverageDao.search(paramMap, theRequestDetails);
|
||||
|
||||
return retVal.getAllResources();
|
||||
}
|
||||
|
@ -133,21 +130,23 @@ public class MemberMatcherR4Helper {
|
|||
}
|
||||
|
||||
|
||||
private List<IBaseResource> findCoverageByCoverageId(Coverage theCoverageToMatch) {
|
||||
private List<IBaseResource> findCoverageByCoverageId(Coverage theCoverageToMatch, RequestDetails theRequestDetails) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap()
|
||||
.add("_id", new StringParam(theCoverageToMatch.getId()));
|
||||
ca.uhn.fhir.rest.api.server.IBundleProvider retVal = myCoverageDao.search(paramMap);
|
||||
ca.uhn.fhir.rest.api.server.IBundleProvider retVal = myCoverageDao.search(paramMap, theRequestDetails);
|
||||
|
||||
return retVal.getAllResources();
|
||||
}
|
||||
|
||||
public void updateConsentForMemberMatch(Consent theConsent, Patient thePatient, Patient theMemberPatient) {
|
||||
addClientIdAsExtensionToConsentIfAvailable(theConsent);
|
||||
public void updateConsentForMemberMatch(Consent theConsent, Patient thePatient, Patient theMemberPatient, RequestDetails theRequestDetails) {
|
||||
addIdentifierToConsent(theConsent, theMemberPatient);
|
||||
updateConsentPatientAndPerformer(theConsent, thePatient);
|
||||
myConsentModifier.accept(theConsent);
|
||||
|
||||
// save the resource
|
||||
myConsentDao.create(theConsent);
|
||||
// WIPMB REVIEW QUESTION Which partition should we target?
|
||||
// Will RequestTenantPartitionInterceptor or PatientIdPartitionInterceptor do the right thing?
|
||||
// Can we use the userdata field to hint at target partition?
|
||||
myConsentDao.create(theConsent, theRequestDetails);
|
||||
}
|
||||
|
||||
public Parameters buildSuccessReturnParameters(Patient theMemberPatient, Coverage theCoverage, Consent theConsent) {
|
||||
|
@ -160,24 +159,25 @@ public class MemberMatcherR4Helper {
|
|||
}
|
||||
|
||||
private Identifier getIdentifier(Patient theMemberPatient) {
|
||||
List<Identifier> memberIdentifiers = theMemberPatient.getIdentifier();
|
||||
if (memberIdentifiers != null && memberIdentifiers.size() > 0) {
|
||||
for (Identifier memberIdentifier : memberIdentifiers) {
|
||||
List<Coding> typeCodings = memberIdentifier.getType().getCoding();
|
||||
if (memberIdentifier.getType() != null && typeCodings != null && typeCodings.size() > 0) {
|
||||
for (Coding typeCoding : typeCodings) {
|
||||
if (typeCoding.getCode().equals("MB")) {
|
||||
return memberIdentifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
String i18nMessage = myFhirContext.getLocalizer().getMessage(
|
||||
"operation.member.match.error.beneficiary.without.identifier");
|
||||
throw new UnprocessableEntityException(Msg.code(2219) + i18nMessage);
|
||||
return theMemberPatient.getIdentifier()
|
||||
.stream()
|
||||
.filter(this::isTypeMB)
|
||||
.findFirst()
|
||||
.orElseThrow(()->{
|
||||
String i18nMessage = myFhirContext.getLocalizer().getMessage(
|
||||
"operation.member.match.error.beneficiary.without.identifier");
|
||||
return new UnprocessableEntityException(Msg.code(2219) + i18nMessage);
|
||||
});
|
||||
}
|
||||
|
||||
private boolean isTypeMB(Identifier theMemberIdentifier) {
|
||||
return theMemberIdentifier.getType() != null &&
|
||||
theMemberIdentifier.getType().getCoding()
|
||||
.stream()
|
||||
.anyMatch(typeCoding->typeCoding.getCode().equals("MB"));
|
||||
}
|
||||
|
||||
|
||||
public void addMemberIdentifierToMemberPatient(Patient theMemberPatient, Identifier theNewIdentifier) {
|
||||
Coding coding = new Coding()
|
||||
.setSystem(OUT_COVERAGE_IDENTIFIER_CODE_SYSTEM)
|
||||
|
@ -198,31 +198,7 @@ public class MemberMatcherR4Helper {
|
|||
theMemberPatient.addIdentifier(newIdentifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* If there is a client id
|
||||
*
|
||||
* @param theConsent - the consent to modify
|
||||
*/
|
||||
private void addClientIdAsExtensionToConsentIfAvailable(Consent theConsent) {
|
||||
if (myIConsentExtensionProvider != null) {
|
||||
Collection<IBaseExtension> extensions = myIConsentExtensionProvider.getConsentExtension(theConsent);
|
||||
|
||||
for (IBaseExtension ext : extensions) {
|
||||
if (ext instanceof Extension) {
|
||||
theConsent.addExtension((Extension) ext);
|
||||
} else {
|
||||
Extension extR4 = new Extension();
|
||||
extR4.setUrl(ext.getUrl());
|
||||
extR4.setValue(ext.getValue());
|
||||
theConsent.addExtension(extR4);
|
||||
}
|
||||
}
|
||||
|
||||
ourLog.trace("{} extension(s) added to Consent", extensions.size());
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<Patient> getBeneficiaryPatient(Coverage theCoverage) {
|
||||
public Optional<Patient> getBeneficiaryPatient(Coverage theCoverage, RequestDetails theRequestDetails) {
|
||||
if (theCoverage.getBeneficiaryTarget() == null && theCoverage.getBeneficiary() == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
@ -245,15 +221,15 @@ public class MemberMatcherR4Helper {
|
|||
return Optional.empty();
|
||||
}
|
||||
|
||||
Patient beneficiary = myPatientDao.read(new IdDt(beneficiaryRef.getReference()));
|
||||
Patient beneficiary = myPatientDao.read(new IdDt(beneficiaryRef.getReference()), theRequestDetails);
|
||||
return Optional.ofNullable(beneficiary);
|
||||
}
|
||||
|
||||
/**
|
||||
* Matching by member patient demographics - family name and birthdate only
|
||||
*/
|
||||
public boolean validPatientMember(Patient thePatientFromContract, Patient thePatientToMatch) {
|
||||
if (thePatientFromContract == null || thePatientFromContract.getIdElement() == null) {
|
||||
public boolean validPatientMember(Patient thePatientFromContract, Patient thePatientToMatch, RequestDetails theRequestDetails) {
|
||||
if (thePatientFromContract == null || thePatientFromContract.getIdElement() == null || thePatientToMatch == null) {
|
||||
return false;
|
||||
}
|
||||
StringOrListParam familyName = new StringOrListParam();
|
||||
|
@ -263,7 +239,7 @@ public class MemberMatcherR4Helper {
|
|||
SearchParameterMap map = new SearchParameterMap()
|
||||
.add("family", familyName)
|
||||
.add("birthdate", new DateParam(thePatientToMatch.getBirthDateElement().getValueAsString()));
|
||||
ca.uhn.fhir.rest.api.server.IBundleProvider bundle = myPatientDao.search(map);
|
||||
ca.uhn.fhir.rest.api.server.IBundleProvider bundle = myPatientDao.search(map, theRequestDetails);
|
||||
for (IBaseResource patientResource : bundle.getAllResources()) {
|
||||
IIdType patientId = patientResource.getIdElement().toUnqualifiedVersionless();
|
||||
if (patientId.getValue().equals(thePatientFromContract.getIdElement().toUnqualifiedVersionless().getValue())) {
|
||||
|
@ -286,18 +262,16 @@ public class MemberMatcherR4Helper {
|
|||
}
|
||||
|
||||
/**
|
||||
* This is filtering the Consent policy data. The rule is specified in
|
||||
* https://build.fhir.org/ig/HL7/davinci-ehrx/StructureDefinition-hrex-consent.html#notes
|
||||
* The consent policy rules are
|
||||
* <a href="https://build.fhir.org/ig/HL7/davinci-ehrx/StructureDefinition-hrex-consent.html#notes">
|
||||
* described here.</a>
|
||||
*/
|
||||
private boolean validConsentPolicy(String thePolicyUri) {
|
||||
String policyTypes = StringUtils.substringAfterLast(thePolicyUri, "#");
|
||||
if (policyTypes.equals(CONSENT_POLICY_SENSITIVE_TYPE)) {
|
||||
return true;
|
||||
}
|
||||
if (policyTypes.equals(CONSENT_POLICY_REGULAR_TYPE) && myRegularFilterSupported) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return policyTypes.equals(CONSENT_POLICY_REGULAR_TYPE) && myRegularFilterSupported;
|
||||
}
|
||||
|
||||
private void addIdentifierToConsent(Consent theConsent, Patient thePatient) {
|
||||
|
|
|
@ -1,64 +1,60 @@
|
|||
package ca.uhn.fhir.jpa.provider;
|
||||
package ca.uhn.fhir.jpa.provider.r4;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.i18n.Msg;
|
||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.provider.r4.IConsentExtensionProvider;
|
||||
import ca.uhn.fhir.jpa.provider.r4.MemberMatcherR4Helper;
|
||||
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 ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
|
||||
import ca.uhn.fhir.rest.server.SimpleBundleProvider;
|
||||
import ca.uhn.test.util.LogbackCaptureTestExtension;
|
||||
import ch.qos.logback.classic.Level;
|
||||
import ch.qos.logback.classic.Logger;
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.core.read.ListAppender;
|
||||
import com.google.common.collect.Lists;
|
||||
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.Consent;
|
||||
import org.hl7.fhir.r4.model.Coverage;
|
||||
import org.hl7.fhir.r4.model.DateType;
|
||||
import org.hl7.fhir.r4.model.Extension;
|
||||
import org.hl7.fhir.r4.model.HumanName;
|
||||
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.hl7.fhir.r4.model.StringType;
|
||||
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 org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static ca.uhn.fhir.jpa.provider.r4.MemberMatcherR4Helper.CONSENT_IDENTIFIER_CODE_SYSTEM;
|
||||
import static ca.uhn.fhir.rest.api.Constants.PARAM_CONSENT;
|
||||
import static ca.uhn.fhir.rest.api.Constants.PARAM_MEMBER_IDENTIFIER;
|
||||
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.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.isA;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.ArgumentMatchers.same;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
@ -66,11 +62,8 @@ import static org.mockito.Mockito.when;
|
|||
@ExtendWith(MockitoExtension.class)
|
||||
public class MemberMatcherR4HelperTest {
|
||||
|
||||
private static final Logger ourLog = (Logger) LoggerFactory.getLogger(MemberMatcherR4Helper.class);
|
||||
|
||||
@Mock
|
||||
private ListAppender<ILoggingEvent> myAppender;
|
||||
|
||||
@RegisterExtension
|
||||
LogbackCaptureTestExtension myLogCapture = new LogbackCaptureTestExtension((Logger) MemberMatcherR4Helper.ourLog, Level.TRACE);
|
||||
@Spy
|
||||
private final FhirContext myFhirContext = FhirContext.forR4();
|
||||
@Mock
|
||||
|
@ -81,6 +74,7 @@ public class MemberMatcherR4HelperTest {
|
|||
private IFhirResourceDao<Consent> myConsentDao;
|
||||
|
||||
private MemberMatcherR4Helper myHelper;
|
||||
RequestDetails myRequestDetails = new SystemRequestDetails();
|
||||
|
||||
@BeforeEach
|
||||
public void before() {
|
||||
|
@ -91,13 +85,6 @@ public class MemberMatcherR4HelperTest {
|
|||
myConsentDao,
|
||||
null // extension provider
|
||||
);
|
||||
|
||||
ourLog.addAppender(myAppender);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void after() {
|
||||
ourLog.detachAppender(myAppender);
|
||||
}
|
||||
|
||||
@Mock private Coverage myCoverageToMatch;
|
||||
|
@ -114,13 +101,13 @@ public class MemberMatcherR4HelperTest {
|
|||
@Test
|
||||
void findMatchingCoverageMatchByIdReturnsMatched() {
|
||||
when(myCoverageToMatch.getId()).thenReturn("cvg-to-match-id");
|
||||
when(myCoverageDao.search(isA(SearchParameterMap.class))).thenReturn(myBundleProvider);
|
||||
when(myCoverageDao.search(isA(SearchParameterMap.class), same(myRequestDetails))).thenReturn(myBundleProvider);
|
||||
when(myBundleProvider.getAllResources()).thenReturn(Collections.singletonList(myMatchedCoverage));
|
||||
|
||||
Optional<Coverage> result = myHelper.findMatchingCoverage(myCoverageToMatch);
|
||||
Optional<Coverage> result = myHelper.findMatchingCoverage(myCoverageToMatch, myRequestDetails);
|
||||
|
||||
assertEquals(Optional.of(myMatchedCoverage), result);
|
||||
verify(myCoverageDao).search(mySearchParameterMapCaptor.capture());
|
||||
verify(myCoverageDao).search(mySearchParameterMapCaptor.capture(), same(myRequestDetails));
|
||||
SearchParameterMap spMap = mySearchParameterMapCaptor.getValue();
|
||||
assertTrue(spMap.containsKey("_id"));
|
||||
List<List<IQueryParameterType>> listListParams = spMap.get("_id");
|
||||
|
@ -135,14 +122,14 @@ public class MemberMatcherR4HelperTest {
|
|||
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(myCoverageDao.search(isA(SearchParameterMap.class), same(myRequestDetails))).thenReturn(myBundleProvider);
|
||||
when(myBundleProvider.getAllResources()).thenReturn(
|
||||
Collections.emptyList(), Collections.singletonList(myMatchedCoverage));
|
||||
|
||||
Optional<Coverage> result = myHelper.findMatchingCoverage(myCoverageToMatch);
|
||||
Optional<Coverage> result = myHelper.findMatchingCoverage(myCoverageToMatch, myRequestDetails);
|
||||
|
||||
assertEquals(Optional.of(myMatchedCoverage), result);
|
||||
verify(myCoverageDao, times(2)).search(mySearchParameterMapCaptor.capture());
|
||||
verify(myCoverageDao, times(2)).search(mySearchParameterMapCaptor.capture(), same(myRequestDetails));
|
||||
List<SearchParameterMap> spMap = mySearchParameterMapCaptor.getAllValues();
|
||||
assertTrue(spMap.get(0).containsKey("_id"));
|
||||
assertTrue(spMap.get(1).containsKey("identifier"));
|
||||
|
@ -159,10 +146,10 @@ public class MemberMatcherR4HelperTest {
|
|||
void findMatchingCoverageNoMatchReturnsEmpty() {
|
||||
when(myCoverageToMatch.getId()).thenReturn("non-matching-id");
|
||||
when(myCoverageToMatch.getIdentifier()).thenReturn(Collections.singletonList(myMatchingIdentifier));
|
||||
when(myCoverageDao.search(any(SearchParameterMap.class))).thenReturn(myBundleProvider);
|
||||
when(myCoverageDao.search(any(SearchParameterMap.class), same(myRequestDetails))).thenReturn(myBundleProvider);
|
||||
when(myBundleProvider.getAllResources()).thenReturn(Collections.emptyList(), Collections.emptyList());
|
||||
|
||||
Optional<Coverage> result = myHelper.findMatchingCoverage(myCoverageToMatch);
|
||||
Optional<Coverage> result = myHelper.findMatchingCoverage(myCoverageToMatch, myRequestDetails);
|
||||
|
||||
assertFalse(result.isPresent());
|
||||
}
|
||||
|
@ -245,7 +232,7 @@ public class MemberMatcherR4HelperTest {
|
|||
when(coverage.getBeneficiaryTarget()).thenReturn(null);
|
||||
when(coverage.getBeneficiary()).thenReturn(null);
|
||||
|
||||
Optional<Patient> result = myHelper.getBeneficiaryPatient(coverage);
|
||||
Optional<Patient> result = myHelper.getBeneficiaryPatient(coverage, myRequestDetails);
|
||||
|
||||
assertFalse(result.isPresent());
|
||||
}
|
||||
|
@ -256,7 +243,7 @@ public class MemberMatcherR4HelperTest {
|
|||
when(coverage.getBeneficiary()).thenReturn(null);
|
||||
when(coverage.getBeneficiaryTarget()).thenReturn(new Patient());
|
||||
|
||||
Optional<Patient> result = myHelper.getBeneficiaryPatient(coverage);
|
||||
Optional<Patient> result = myHelper.getBeneficiaryPatient(coverage, myRequestDetails);
|
||||
|
||||
assertFalse(result.isPresent());
|
||||
}
|
||||
|
@ -267,7 +254,7 @@ public class MemberMatcherR4HelperTest {
|
|||
Patient patient = new Patient().setIdentifier(Collections.singletonList(new Identifier()));
|
||||
when(coverage.getBeneficiaryTarget()).thenReturn(patient);
|
||||
|
||||
Optional<Patient> result = myHelper.getBeneficiaryPatient(coverage);
|
||||
Optional<Patient> result = myHelper.getBeneficiaryPatient(coverage, myRequestDetails);
|
||||
|
||||
assertTrue(result.isPresent());
|
||||
assertEquals(patient, result.get());
|
||||
|
@ -280,7 +267,7 @@ public class MemberMatcherR4HelperTest {
|
|||
when(coverage.getBeneficiaryTarget()).thenReturn(null);
|
||||
when(coverage.getBeneficiary().getResource()).thenReturn(patient);
|
||||
|
||||
Optional<Patient> result = myHelper.getBeneficiaryPatient(coverage);
|
||||
Optional<Patient> result = myHelper.getBeneficiaryPatient(coverage, myRequestDetails);
|
||||
|
||||
assertTrue(result.isPresent());
|
||||
assertEquals(patient, result.get());
|
||||
|
@ -292,7 +279,7 @@ public class MemberMatcherR4HelperTest {
|
|||
when(coverage.getBeneficiaryTarget()).thenReturn(null);
|
||||
when(coverage.getBeneficiary()).thenReturn(new Reference());
|
||||
|
||||
Optional<Patient> result = myHelper.getBeneficiaryPatient(coverage);
|
||||
Optional<Patient> result = myHelper.getBeneficiaryPatient(coverage, myRequestDetails);
|
||||
|
||||
assertFalse(result.isPresent());
|
||||
}
|
||||
|
@ -304,11 +291,10 @@ public class MemberMatcherR4HelperTest {
|
|||
when(coverage.getBeneficiary().getResource()).thenReturn(null);
|
||||
when(coverage.getBeneficiary().getReference()).thenReturn("patient-id");
|
||||
|
||||
myHelper.getBeneficiaryPatient(coverage);
|
||||
myHelper.getBeneficiaryPatient(coverage, myRequestDetails);
|
||||
|
||||
verify(myPatientDao).read(new IdDt("patient-id"));
|
||||
verify(myPatientDao).read(new IdDt("patient-id"), myRequestDetails);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -317,19 +303,17 @@ public class MemberMatcherR4HelperTest {
|
|||
@Nested
|
||||
public class TestValidPatientMember {
|
||||
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private Coverage coverage;
|
||||
private Patient patient;
|
||||
private final Patient patient = new Patient();
|
||||
|
||||
@Test
|
||||
void noPatientFoundFromContractReturnsFalse() {
|
||||
boolean result = myHelper.validPatientMember(null, patient);
|
||||
boolean result = myHelper.validPatientMember(null, patient, myRequestDetails);
|
||||
assertFalse(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void noPatientFoundFromPatientMemberReturnsFalse() {
|
||||
boolean result = myHelper.validPatientMember(patient, null);
|
||||
boolean result = myHelper.validPatientMember(patient, null, myRequestDetails);
|
||||
assertFalse(result);
|
||||
}
|
||||
|
||||
|
@ -337,11 +321,11 @@ public class MemberMatcherR4HelperTest {
|
|||
void noMatchingFamilyNameReturnsFalse() {
|
||||
Patient patientFromMemberMatch = getPatientWithNoIDParm("Person", "2020-01-01");
|
||||
Patient patientFromContractFound = getPatientWithIDParm("A123", "Smith", "2020-01-01");
|
||||
when(myPatientDao.search(any(SearchParameterMap.class))).thenAnswer(t -> {
|
||||
when(myPatientDao.search(any(SearchParameterMap.class), same(myRequestDetails))).thenAnswer(t -> {
|
||||
IBundleProvider provider = new SimpleBundleProvider(Collections.singletonList(new Patient().setId("B123")));
|
||||
return provider;
|
||||
});
|
||||
boolean result = myHelper.validPatientMember(patientFromContractFound, patientFromMemberMatch);
|
||||
boolean result = myHelper.validPatientMember(patientFromContractFound, patientFromMemberMatch, myRequestDetails);
|
||||
assertFalse(result);
|
||||
}
|
||||
|
||||
|
@ -350,11 +334,11 @@ public class MemberMatcherR4HelperTest {
|
|||
void noMatchingBirthdayReturnsFalse() {
|
||||
Patient patientFromMemberMatch = getPatientWithNoIDParm("Person", "1990-01-01");
|
||||
Patient patientFromContractFound = getPatientWithIDParm("A123", "Person", "2020-01-01");
|
||||
when(myPatientDao.search(any(SearchParameterMap.class))).thenAnswer(t -> {
|
||||
when(myPatientDao.search(any(SearchParameterMap.class), same(myRequestDetails))).thenAnswer(t -> {
|
||||
IBundleProvider provider = new SimpleBundleProvider(Collections.singletonList(new Patient().setId("B123")));
|
||||
return provider;
|
||||
});
|
||||
boolean result = myHelper.validPatientMember(patientFromContractFound, patientFromMemberMatch);
|
||||
boolean result = myHelper.validPatientMember(patientFromContractFound, patientFromMemberMatch, myRequestDetails);
|
||||
assertFalse(result);
|
||||
}
|
||||
|
||||
|
@ -362,11 +346,11 @@ public class MemberMatcherR4HelperTest {
|
|||
void noMatchingFieldsReturnsFalse() {
|
||||
Patient patientFromMemberMatch = getPatientWithNoIDParm("Person", "1990-01-01");
|
||||
Patient patientFromContractFound = getPatientWithIDParm("A123", "Smith", "2020-01-01");
|
||||
when(myPatientDao.search(any(SearchParameterMap.class))).thenAnswer(t -> {
|
||||
when(myPatientDao.search(any(SearchParameterMap.class), same(myRequestDetails))).thenAnswer(t -> {
|
||||
IBundleProvider provider = new SimpleBundleProvider(Collections.singletonList(new Patient().setId("B123")));
|
||||
return provider;
|
||||
});
|
||||
boolean result = myHelper.validPatientMember(patientFromContractFound, patientFromMemberMatch);
|
||||
boolean result = myHelper.validPatientMember(patientFromContractFound, patientFromMemberMatch, myRequestDetails);
|
||||
assertFalse(result);
|
||||
}
|
||||
|
||||
|
@ -374,11 +358,11 @@ public class MemberMatcherR4HelperTest {
|
|||
void patientMatchingReturnTrue() {
|
||||
Patient patientFromMemberMatch = getPatientWithNoIDParm("Person", "2020-01-01");
|
||||
Patient patientFromContractFound = getPatientWithIDParm("A123", "Person", "2020-01-01");
|
||||
when(myPatientDao.search(any(SearchParameterMap.class))).thenAnswer(t -> {
|
||||
when(myPatientDao.search(any(SearchParameterMap.class), same(myRequestDetails))).thenAnswer(t -> {
|
||||
IBundleProvider provider = new SimpleBundleProvider(Collections.singletonList(patientFromContractFound));
|
||||
return provider;
|
||||
});
|
||||
boolean result = myHelper.validPatientMember(patientFromContractFound, patientFromMemberMatch);
|
||||
boolean result = myHelper.validPatientMember(patientFromContractFound, patientFromMemberMatch, myRequestDetails);
|
||||
assertTrue(result);
|
||||
}
|
||||
|
||||
|
@ -404,9 +388,6 @@ public class MemberMatcherR4HelperTest {
|
|||
@Nested
|
||||
public class TestValidvalidConsentDataAccess {
|
||||
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private Coverage coverage;
|
||||
private Patient patient;
|
||||
private Consent consent;
|
||||
|
||||
@Test
|
||||
|
@ -521,45 +502,10 @@ public class MemberMatcherR4HelperTest {
|
|||
return patient;
|
||||
}
|
||||
|
||||
private void verifyConsentUpdatedAfterMemberMatch(
|
||||
Consent theConsent,
|
||||
Patient thePatient,
|
||||
Patient theMemberPatient,
|
||||
List<Extension> theSavedExtensions
|
||||
) {
|
||||
// check consent identifier
|
||||
assertEquals(1, theConsent.getIdentifier().size());
|
||||
assertEquals(CONSENT_IDENTIFIER_CODE_SYSTEM, theConsent.getIdentifier().get(0).getSystem());
|
||||
assertNotNull(theConsent.getIdentifier().get(0).getValue());
|
||||
assertEquals(theConsent.getIdentifier().get(0).getValue(), theMemberPatient.getIdentifier().get(0).getValue());
|
||||
|
||||
// check consent patient info
|
||||
String patientRef = thePatient.getIdElement().toUnqualifiedVersionless().getValue();
|
||||
assertEquals(patientRef, theConsent.getPatient().getReference());
|
||||
assertEquals(patientRef, theConsent.getPerformer().get(0).getReference());
|
||||
|
||||
if (!theSavedExtensions.isEmpty()) {
|
||||
// check consent extensions
|
||||
assertNotNull(theConsent.getExtension());
|
||||
assertEquals(theSavedExtensions.size(), theConsent.getExtension().size());
|
||||
for (Extension ext : theSavedExtensions) {
|
||||
boolean found = false;
|
||||
for (Extension consentExt : theConsent.getExtension()) {
|
||||
if (consentExt.getUrl().equals(ext.getUrl())
|
||||
&& consentExt.getValue().equals(ext.getValue())) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assertTrue(found,
|
||||
"Extension " + ext.getUrl() + "|" + ext.getValue().toString() + " not found"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
public class MemberMatchWithoutConsentProvider {
|
||||
@Captor
|
||||
private ArgumentCaptor<Consent> myDaoCaptor;
|
||||
|
||||
@Test
|
||||
public void updateConsentForMemberMatch_noProvider_addsIdentifierUpdatePatientButNotExtensionAndSaves() {
|
||||
|
@ -569,19 +515,26 @@ public class MemberMatcherR4HelperTest {
|
|||
Patient patient = createPatientForMemberMatchUpdate(false);
|
||||
Patient memberPatient = createPatientForMemberMatchUpdate(true);
|
||||
|
||||
ourLog.setLevel(Level.TRACE);
|
||||
|
||||
// test
|
||||
myHelper.updateConsentForMemberMatch(consent, patient, memberPatient);
|
||||
myHelper.updateConsentForMemberMatch(consent, patient, memberPatient, myRequestDetails);
|
||||
|
||||
// verify
|
||||
verify(myAppender, never())
|
||||
.doAppend(any(ILoggingEvent.class));
|
||||
|
||||
ArgumentCaptor<Consent> consentCaptor = ArgumentCaptor.forClass(Consent.class);
|
||||
verify(myConsentDao).create(consentCaptor.capture());
|
||||
Consent saved = consentCaptor.getValue();
|
||||
verifyConsentUpdatedAfterMemberMatch(saved, patient, memberPatient, Collections.emptyList());
|
||||
verify(myConsentDao).create(myDaoCaptor.capture(), same(myRequestDetails));
|
||||
Consent saved = myDaoCaptor.getValue();
|
||||
// check consent identifier
|
||||
assertEquals(1, saved.getIdentifier().size());
|
||||
assertEquals(MemberMatcherR4Helper.CONSENT_IDENTIFIER_CODE_SYSTEM, saved.getIdentifier().get(0).getSystem());
|
||||
assertNotNull(saved.getIdentifier().get(0).getValue());
|
||||
assertEquals(saved.getIdentifier().get(0).getValue(), memberPatient.getIdentifier().get(0).getValue());
|
||||
|
||||
// check consent patient info
|
||||
String patientRef = patient.getIdElement().toUnqualifiedVersionless().getValue();
|
||||
assertEquals(patientRef, saved.getPatient().getReference());
|
||||
assertEquals(patientRef, saved.getPerformer().get(0).getReference());
|
||||
|
||||
assertThat(myLogCapture.getLogEvents(), empty());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -589,6 +542,8 @@ public class MemberMatcherR4HelperTest {
|
|||
public class MemberMatchWithConsentProvider {
|
||||
@Mock
|
||||
private IConsentExtensionProvider myExtensionProvider;
|
||||
@Captor
|
||||
private ArgumentCaptor<Consent> myHookCaptor;
|
||||
|
||||
@BeforeEach
|
||||
public void before() {
|
||||
|
@ -607,31 +562,17 @@ public class MemberMatcherR4HelperTest {
|
|||
Consent consent = getConsent();
|
||||
consent.addPolicy(constructConsentPolicyComponent("#sensitive"));
|
||||
consent.setId("Consent/RED");
|
||||
Extension ext = new Extension();
|
||||
ext.setUrl("http://example.com");
|
||||
ext.setValue(new StringType("value"));
|
||||
Patient patient = createPatientForMemberMatchUpdate(false);
|
||||
Patient memberPatient = createPatientForMemberMatchUpdate(true);
|
||||
|
||||
ourLog.setLevel(Level.TRACE);
|
||||
|
||||
// when
|
||||
when(myExtensionProvider.getConsentExtension(any(IBaseResource.class)))
|
||||
.thenReturn(Collections.singleton(ext));
|
||||
|
||||
// test
|
||||
myHelper.updateConsentForMemberMatch(consent, patient, memberPatient);
|
||||
myHelper.updateConsentForMemberMatch(consent, patient, memberPatient, myRequestDetails);
|
||||
|
||||
// verify
|
||||
ArgumentCaptor<Consent> consentCaptor = ArgumentCaptor.forClass(Consent.class);
|
||||
verify(myConsentDao).create(consentCaptor.capture());
|
||||
Consent saved = consentCaptor.getValue();
|
||||
verifyConsentUpdatedAfterMemberMatch(saved, patient, memberPatient, Collections.emptyList());
|
||||
verify(myExtensionProvider).accept(myHookCaptor.capture());
|
||||
|
||||
ArgumentCaptor<ILoggingEvent> eventCaptor = ArgumentCaptor.forClass(ILoggingEvent.class);
|
||||
verify(myAppender).doAppend(eventCaptor.capture());
|
||||
ILoggingEvent event = eventCaptor.getValue();
|
||||
assertEquals("1 extension(s) added to Consent", event.getFormattedMessage());
|
||||
assertSame(consent, myHookCaptor.getValue());
|
||||
assertThat(myLogCapture.getLogEvents(), empty());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -113,13 +113,13 @@ public class LogbackCaptureTestExtension implements BeforeEachCallback, AfterEac
|
|||
* Guts of beforeEach exposed for manual lifecycle.
|
||||
*/
|
||||
public void setUp() {
|
||||
myListAppender = new ListAppender<>();
|
||||
myListAppender.start();
|
||||
myLogger.addAppender(myListAppender);
|
||||
if (myLevel != null) {
|
||||
mySavedLevel = myLogger.getLevel();
|
||||
myLogger.setLevel(myLevel);
|
||||
}
|
||||
myListAppender = new ListAppender<>();
|
||||
myListAppender.start();
|
||||
myLogger.addAppender(myListAppender);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue