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

62 create unit tests for questionnaire processor #356

Closed
Closed
Original file line number Diff line number Diff line change
@@ -55,8 +55,8 @@
import org.opencds.cqf.fhir.cql.ExtensionResolver;
import org.opencds.cqf.fhir.cr.activitydefinition.r4.ActivityDefinitionProcessor;
import org.opencds.cqf.fhir.cr.plandefinition.BasePlanDefinitionProcessor;
import org.opencds.cqf.fhir.cr.questionnaire.r4.QuestionnaireProcessor;
import org.opencds.cqf.fhir.cr.questionnaire.r4.generator.questionnaireitem.QuestionnaireItemGenerator;
import org.opencds.cqf.fhir.cr.questionnaire.r4.processor.QuestionnaireProcessor;
import org.opencds.cqf.fhir.cr.questionnaireresponse.r4.QuestionnaireResponseProcessor;
import org.opencds.cqf.fhir.utility.Constants;
import org.opencds.cqf.fhir.utility.client.Clients;
@@ -73,7 +73,7 @@ public class PlanDefinitionProcessor extends BasePlanDefinitionProcessor<PlanDef
private static final Logger logger = LoggerFactory.getLogger(PlanDefinitionProcessor.class);

private final ActivityDefinitionProcessor activityDefinitionProcessor;
private final QuestionnaireProcessor questionnaireProcessor;
private final QuestionnaireProcessor myQuestionnaireProcessor;
private final QuestionnaireResponseProcessor questionnaireResponseProcessor;
private ExtensionResolver extensionResolver;
private InputParameterResolver inputParameterResolver;
@@ -88,7 +88,7 @@ public PlanDefinitionProcessor(Repository repository) {
public PlanDefinitionProcessor(Repository repository, EvaluationSettings evaluationSettings) {
super(repository, evaluationSettings);
this.activityDefinitionProcessor = new ActivityDefinitionProcessor(this.repository, evaluationSettings);
this.questionnaireProcessor = new QuestionnaireProcessor(this.repository, evaluationSettings);
this.myQuestionnaireProcessor = new QuestionnaireProcessor(this.repository, evaluationSettings);
this.questionnaireResponseProcessor = new QuestionnaireResponseProcessor(this.repository, evaluationSettings);
}

@@ -660,7 +660,7 @@ private void resolvePrepopulateAction(
valueSets.forEach(
valueSet -> additionalData.addEntry(new Bundle.BundleEntryComponent().setResource(valueSet)));

var populatedQuestionnaire = questionnaireProcessor.prePopulate(
var populatedQuestionnaire = myQuestionnaireProcessor.prePopulate(
toPopulate, subjectId, this.parameters, additionalData, libraryEngine);
if (Boolean.TRUE.equals(containResources)) {
requestGroup.addContained(populatedQuestionnaire);
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.opencds.cqf.fhir.cr.questionnaire.r4;

import static org.opencds.cqf.fhir.cr.questionnaire.r4.ItemValueTransformer.transformValue;
import static org.opencds.cqf.fhir.cr.questionnaire.r4.processor.utils.ItemValueTransformer.transformValue;

import java.util.ArrayList;
import java.util.Collections;
@@ -35,15 +35,15 @@
import org.opencds.cqf.fhir.utility.r4.PackageHelper;
import org.opencds.cqf.fhir.utility.r4.SearchHelper;

public class QuestionnaireProcessor extends BaseQuestionnaireProcessor<Questionnaire> {
public class DepreciatedQuestionnaireProcessor extends BaseQuestionnaireProcessor<Questionnaire> {
protected OperationOutcome oc;
protected Questionnaire populatedQuestionnaire;

public QuestionnaireProcessor(Repository repository) {
public DepreciatedQuestionnaireProcessor(Repository repository) {
this(repository, EvaluationSettings.getDefault());
}

public QuestionnaireProcessor(Repository repository, EvaluationSettings evaluationSettings) {
public DepreciatedQuestionnaireProcessor(Repository repository, EvaluationSettings evaluationSettings) {
super(repository, evaluationSettings);
}

@@ -81,6 +81,7 @@ public Questionnaire prePopulate(
this.parameters = parameters;
this.bundle = bundle;
this.libraryEngine = libraryEngine;

libraryUrl = questionnaire.hasExtension(Constants.CQF_LIBRARY)
? ((CanonicalType) questionnaire
.getExtensionByUrl(Constants.CQF_LIBRARY)
@@ -237,7 +238,6 @@ public IBaseResource populate(
var responseItems = new ArrayList<QuestionnaireResponseItemComponent>();
processResponseItems(populatedQuestionnaire.getItem(), responseItems);
response.setItem(responseItems);

return response;
}

@@ -267,10 +267,8 @@ protected void processResponseItems(

@Override
public Questionnaire generateQuestionnaire(String id) {

var questionnaire = new Questionnaire();
questionnaire.setId(new IdType("Questionnaire", id));

return questionnaire;
}

@@ -290,7 +288,6 @@ public Bundle packageQuestionnaire(Questionnaire questionnaire, boolean isPut) {
}
}
}

return bundle;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.opencds.cqf.fhir.cr.questionnaire.r4.generator.nestedquestionnaireitem;

import static org.opencds.cqf.fhir.cr.questionnaire.r4.ItemValueTransformer.transformValue;
import static org.opencds.cqf.fhir.cr.questionnaire.r4.processor.utils.ItemValueTransformer.transformValue;

import java.util.List;
import org.hl7.fhir.instance.model.api.IAnyResource;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.opencds.cqf.fhir.cr.questionnaire.r4.generator.nestedquestionnaireitem;

import static org.opencds.cqf.fhir.cr.questionnaire.r4.ItemValueTransformer.transformValue;
import static org.opencds.cqf.fhir.cr.questionnaire.r4.processor.utils.ItemValueTransformer.transformValue;

import org.hl7.fhir.r4.model.BooleanType;
import org.hl7.fhir.r4.model.Questionnaire.QuestionnaireItemComponent;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.opencds.cqf.fhir.cr.questionnaire.r4.generator.nestedquestionnaireitem;

import static org.opencds.cqf.fhir.cr.questionnaire.r4.ItemValueTransformer.transformValue;
import static org.opencds.cqf.fhir.cr.questionnaire.r4.processor.utils.ItemValueTransformer.transformValue;

import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseParameters;
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package org.opencds.cqf.fhir.cr.questionnaire.r4.processor;

import static java.util.Objects.requireNonNull;

import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseParameters;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.Questionnaire;
import org.opencds.cqf.fhir.api.Repository;
import org.opencds.cqf.fhir.cql.EvaluationSettings;
import org.opencds.cqf.fhir.cql.LibraryEngine;
import org.opencds.cqf.fhir.cr.questionnaire.BaseQuestionnaireProcessor;
import org.opencds.cqf.fhir.cr.questionnaire.r4.processor.packager.PackageService;
import org.opencds.cqf.fhir.cr.questionnaire.r4.processor.populate.PopulateService;
import org.opencds.cqf.fhir.cr.questionnaire.r4.processor.prepopulate.PrePopulateRequest;
import org.opencds.cqf.fhir.cr.questionnaire.r4.processor.prepopulate.PrePopulateService;
import org.opencds.cqf.fhir.cr.questionnaire.r4.processor.resolve.ResolveService;

public class QuestionnaireProcessor extends BaseQuestionnaireProcessor<Questionnaire> {
protected PopulateService populateService;
protected ResolveService resolveService;
protected PackageService packageService;
protected PrePopulateService prePopulateService;

public QuestionnaireProcessor(Repository repository, EvaluationSettings evaluationSettings) {
this(repository,
evaluationSettings,
new ResolveService(repository),
new PackageService(repository),
new PopulateService(),
new PrePopulateService()
);
}

public QuestionnaireProcessor(Repository repository) {
this(repository, EvaluationSettings.getDefault());
}

private QuestionnaireProcessor(
Repository repository,
EvaluationSettings evaluationSettings,
ResolveService resolveService,
PackageService packageService,
PopulateService populateService,
PrePopulateService prePopulateService
) {
super(repository, evaluationSettings);
this.resolveService = resolveService;
this.packageService = packageService;
this.populateService = populateService;
this.prePopulateService = prePopulateService;
}

@Override
public <C extends IPrimitiveType<String>> Questionnaire resolveQuestionnaire(
IIdType id, C canonical, IBaseResource questionnaire) {
return resolveService.resolve(id, canonical, questionnaire);
}

@Override
public Questionnaire prePopulate(
Questionnaire questionnaire,
String patientId,
IBaseParameters parameters,
IBaseBundle bundle,
LibraryEngine libraryEngine) {
requireNonNull(questionnaire);
requireNonNull(libraryEngine);
final PrePopulateRequest prePopulateRequest =
new PrePopulateRequest(questionnaire, patientId, parameters, bundle, libraryEngine);
return prePopulateService.prePopulate(prePopulateRequest);
}

@Override
public IBaseResource populate(
Questionnaire questionnaire,
String patientId,
IBaseParameters parameters,
IBaseBundle bundle,
LibraryEngine libraryEngine) {
final Questionnaire prePopulatedQuestionnaire =
prePopulate(questionnaire, patientId, parameters, bundle, libraryEngine);
return populateService.populate(questionnaire, prePopulatedQuestionnaire, patientId);
}

@Override
public Questionnaire generateQuestionnaire(String id) {
var questionnaire = new Questionnaire();
questionnaire.setId(new IdType("Questionnaire", id));
return questionnaire;
}

@Override
public Bundle packageQuestionnaire(Questionnaire questionnaire, boolean isPut) {
return packageService.packageQuestionnaire(questionnaire, isPut);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.opencds.cqf.fhir.cr.questionnaire.r4.processor.packager;

import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Bundle.BundleType;
import org.hl7.fhir.r4.model.CanonicalType;
import org.hl7.fhir.r4.model.Library;
import org.hl7.fhir.r4.model.Questionnaire;
import org.opencds.cqf.fhir.api.Repository;
import org.opencds.cqf.fhir.utility.Constants;
import org.opencds.cqf.fhir.utility.r4.PackageHelper;
import org.opencds.cqf.fhir.utility.r4.SearchHelper;

public class PackageService {
final Repository repository;

public PackageService(Repository repository) {
this.repository = repository;
}

public Bundle packageQuestionnaire(Questionnaire questionnaire, boolean isPut) {
// TODO: this is incomplete and needs to be abstracted further
final Bundle bundle = new Bundle();
bundle.setType(BundleType.TRANSACTION);
bundle.addEntry(PackageHelper.createEntry(questionnaire, isPut));
var libraryExtension = questionnaire.getExtensionByUrl(Constants.CQF_LIBRARY);
if (libraryExtension != null) {
var libraryCanonical = (CanonicalType) libraryExtension.getValue();
var library = (Library) SearchHelper.searchRepositoryByCanonical(repository, libraryCanonical);
if (library != null) {
bundle.addEntry(PackageHelper.createEntry(library, isPut));
if (library.hasRelatedArtifact()) {
PackageHelper.addRelatedArtifacts(bundle, library.getRelatedArtifact(),
repository, isPut);
}
}
}
return bundle;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package org.opencds.cqf.fhir.cr.questionnaire.r4.processor.populate;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.OperationOutcome;
import org.hl7.fhir.r4.model.OperationOutcome.OperationOutcomeIssueComponent;
import org.hl7.fhir.r4.model.Questionnaire;
import org.hl7.fhir.r4.model.Questionnaire.QuestionnaireItemComponent;
import org.hl7.fhir.r4.model.QuestionnaireResponse;
import org.hl7.fhir.r4.model.QuestionnaireResponse.QuestionnaireResponseItemAnswerComponent;
import org.hl7.fhir.r4.model.QuestionnaireResponse.QuestionnaireResponseItemComponent;
import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.ResourceType;
import org.opencds.cqf.fhir.cr.questionnaire.r4.processor.utils.ExtensionBuilders;
import org.opencds.cqf.fhir.utility.Constants;

public class PopulateService {
public QuestionnaireResponse populate(
Questionnaire originalQuestionnaire, Questionnaire prePopulatedQuestionnaire, String patientId) {
final QuestionnaireResponse response = new QuestionnaireResponse();
response.setId(prePopulatedQuestionnaire.getIdPart() + "-response");
final Optional<OperationOutcome> operationOutcome =
getOperationOutcomeFromPrePopulatedQuestionnaire(prePopulatedQuestionnaire);
if (prePopulatedQuestionnaire.hasExtension(Constants.EXT_CRMI_MESSAGES) && operationOutcome.isPresent()) {
response.addContained(operationOutcome.get());
response.addExtension(ExtensionBuilders.crmiMessagesExtension(
operationOutcome.get().getIdPart()));
}
response.addContained(prePopulatedQuestionnaire);
response.addExtension(ExtensionBuilders.dtrQuestionnaireResponseExtension(prePopulatedQuestionnaire));
response.setQuestionnaire(originalQuestionnaire.getUrl());
response.setStatus(QuestionnaireResponse.QuestionnaireResponseStatus.INPROGRESS);
response.setSubject(new Reference(new IdType("Patient", patientId)));
response.setItem(processResponseItems(prePopulatedQuestionnaire.getItem()));
return response;
}

protected Optional<OperationOutcome> getOperationOutcomeFromPrePopulatedQuestionnaire(
Questionnaire prePopulatedQuestionnaire) {
return prePopulatedQuestionnaire.getContained().stream()
.filter(theResource -> theResource.getResourceType() == ResourceType.OperationOutcome)
.map(OperationOutcome.class::cast)
.filter(this::filterOperationOutcome)
.findFirst();
}

protected boolean filterOperationOutcome(OperationOutcome operationOutcome) {
if (operationOutcome.hasIssue()) {
final List<OperationOutcomeIssueComponent> filteredIssues = operationOutcome.getIssue().stream()
.filter(theIssue -> theIssue.getCode() == OperationOutcome.IssueType.EXCEPTION
&& theIssue.getSeverity() == OperationOutcome.IssueSeverity.ERROR)
.collect(Collectors.toList());
return !filteredIssues.isEmpty();
}
return false;
}

protected List<QuestionnaireResponseItemComponent> processResponseItems(
List<QuestionnaireItemComponent> questionnaireItems) {
return questionnaireItems.stream().map(this::processResponseItem).collect(Collectors.toList());
}

protected QuestionnaireResponseItemComponent processResponseItem(QuestionnaireItemComponent questionnaireItem) {
QuestionnaireResponseItemComponent responseItem =
new QuestionnaireResponseItemComponent(questionnaireItem.getLinkIdElement());
responseItem.setDefinition(questionnaireItem.getDefinition());
responseItem.setTextElement(questionnaireItem.getTextElement());
if (questionnaireItem.hasItem()) {
final List<QuestionnaireResponseItemComponent> nestedResponseItems =
processResponseItems(questionnaireItem.getItem());
responseItem.setItem(nestedResponseItems);
} else if (questionnaireItem.hasInitial()) {
responseItem = setAnswersForInitial(questionnaireItem, responseItem);
}
return responseItem;
}

protected QuestionnaireResponseItemComponent setAnswersForInitial(
QuestionnaireItemComponent questionnaireItem,
QuestionnaireResponseItemComponent questionnaireResponseItem) {
if (questionnaireItem.hasExtension(Constants.QUESTIONNAIRE_RESPONSE_AUTHOR)) {
questionnaireResponseItem.addExtension(
questionnaireItem.getExtensionByUrl(Constants.QUESTIONNAIRE_RESPONSE_AUTHOR));
}
questionnaireItem.getInitial().forEach(initial -> {
final QuestionnaireResponseItemAnswerComponent answer =
new QuestionnaireResponseItemAnswerComponent().setValue(initial.getValue());
questionnaireResponseItem.addAnswer(answer);
});
return questionnaireResponseItem;
}
}
Loading