Don't evaluate Extensions when determining type of answer
This commit is contained in:
parent
14b5d88530
commit
73e85ce668
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
<artifactId>hapi-fhir-validation</artifactId>
|
<artifactId>hapi-fhir-validation</artifactId>
|
||||||
<packaging>bundle</packaging>
|
<packaging>bundle</packaging>
|
||||||
<version>3.6.2-PHRFIX</version>
|
<version>3.6.3-PHRFIX</version>
|
||||||
|
|
||||||
<name>HAPI FHIR - Validation</name>
|
<name>HAPI FHIR - Validation</name>
|
||||||
|
|
||||||
|
|
|
@ -64,11 +64,33 @@ public class DefaultEnableWhenEvaluator implements IEnableWhenEvaluator {
|
||||||
.anyMatch(answer -> evaluateAnswer(answer, enableCondition.getAnswer(), enableCondition.getOperator()));
|
.anyMatch(answer -> evaluateAnswer(answer, enableCondition.getAnswer(), enableCondition.getOperator()));
|
||||||
return new EnableWhenResult(result, linkId, enableCondition, questionnaireResponse);
|
return new EnableWhenResult(result, linkId, enableCondition, questionnaireResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Type convertToType(Element element) {
|
||||||
|
Type b = new Factory().create(element.fhirType());
|
||||||
|
if (b instanceof PrimitiveType) {
|
||||||
|
((PrimitiveType<?>) b).setValueAsString(element.primitiveValue());
|
||||||
|
} else {
|
||||||
|
for (Element child : element.getChildren()) {
|
||||||
|
if (!isExtension(child)) {
|
||||||
|
b.setProperty(child.getName(), convertToType(child));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private boolean isExtension(Element element) {
|
||||||
|
return "Extension".equals(element.fhirType());
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean evaluateAnswer(Element answer, Type expectedAnswer, QuestionnaireItemOperator questionnaireItemOperator) {
|
protected boolean evaluateAnswer(Element answer, Type expectedAnswer, QuestionnaireItemOperator questionnaireItemOperator) {
|
||||||
Type actualAnswer;
|
Type actualAnswer;
|
||||||
|
if (isExtension(answer)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
actualAnswer = answer.asType();
|
actualAnswer = convertToType(answer);
|
||||||
} catch (FHIRException e) {
|
} catch (FHIRException e) {
|
||||||
throw new UnprocessableEntityException("Unexpected answer type", e);
|
throw new UnprocessableEntityException("Unexpected answer type", e);
|
||||||
}
|
}
|
||||||
|
@ -80,7 +102,7 @@ public class DefaultEnableWhenEvaluator implements IEnableWhenEvaluator {
|
||||||
} else if ((expectedAnswer instanceof PrimitiveType)) {
|
} else if ((expectedAnswer instanceof PrimitiveType)) {
|
||||||
return comparePrimitiveAnswer((PrimitiveType<?>)actualAnswer, (PrimitiveType<?>)expectedAnswer, questionnaireItemOperator);
|
return comparePrimitiveAnswer((PrimitiveType<?>)actualAnswer, (PrimitiveType<?>)expectedAnswer, questionnaireItemOperator);
|
||||||
} else if (expectedAnswer instanceof Quantity) {
|
} else if (expectedAnswer instanceof Quantity) {
|
||||||
return compareQuantityAnswer((Quantity)expectedAnswer, (Quantity)actualAnswer, questionnaireItemOperator);
|
return compareQuantityAnswer((Quantity)actualAnswer, (Quantity)expectedAnswer, questionnaireItemOperator);
|
||||||
}
|
}
|
||||||
// TODO: Attachment, reference?
|
// TODO: Attachment, reference?
|
||||||
throw new UnprocessableEntityException("Unimplemented answer type: " + expectedAnswer.getClass());
|
throw new UnprocessableEntityException("Unimplemented answer type: " + expectedAnswer.getClass());
|
||||||
|
@ -142,14 +164,9 @@ public class DefaultEnableWhenEvaluator implements IEnableWhenEvaluator {
|
||||||
return item.getChildrenByName(ANSWER_ELEMENT)
|
return item.getChildrenByName(ANSWER_ELEMENT)
|
||||||
.stream()
|
.stream()
|
||||||
.flatMap(c -> c.getChildren().stream())
|
.flatMap(c -> c.getChildren().stream())
|
||||||
.filter(DefaultEnableWhenEvaluator::notExtension)
|
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean notExtension(Element e) {
|
|
||||||
return !Extension.class.isAssignableFrom(e.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean compareCodingAnswer(Coding expectedAnswer, Coding actualAnswer, QuestionnaireItemOperator questionnaireItemOperator) {
|
private boolean compareCodingAnswer(Coding expectedAnswer, Coding actualAnswer, QuestionnaireItemOperator questionnaireItemOperator) {
|
||||||
boolean result = compareSystems(expectedAnswer, actualAnswer) && compareCodes(expectedAnswer, actualAnswer);
|
boolean result = compareSystems(expectedAnswer, actualAnswer) && compareCodes(expectedAnswer, actualAnswer);
|
||||||
if (questionnaireItemOperator == QuestionnaireItemOperator.EQUAL){
|
if (questionnaireItemOperator == QuestionnaireItemOperator.EQUAL){
|
||||||
|
|
|
@ -18,6 +18,7 @@ import org.hl7.fhir.dstu3.model.Questionnaire.QuestionnaireItemComponent;
|
||||||
import org.hl7.fhir.dstu3.model.Questionnaire.QuestionnaireItemEnableWhenComponent;
|
import org.hl7.fhir.dstu3.model.Questionnaire.QuestionnaireItemEnableWhenComponent;
|
||||||
import org.hl7.fhir.dstu3.model.Questionnaire.QuestionnaireItemOptionComponent;
|
import org.hl7.fhir.dstu3.model.Questionnaire.QuestionnaireItemOptionComponent;
|
||||||
import org.hl7.fhir.dstu3.model.Questionnaire.QuestionnaireItemType;
|
import org.hl7.fhir.dstu3.model.Questionnaire.QuestionnaireItemType;
|
||||||
|
import org.hl7.fhir.dstu3.model.QuestionnaireResponse.QuestionnaireResponseItemAnswerComponent;
|
||||||
import org.hl7.fhir.dstu3.model.QuestionnaireResponse.QuestionnaireResponseItemComponent;
|
import org.hl7.fhir.dstu3.model.QuestionnaireResponse.QuestionnaireResponseItemComponent;
|
||||||
import org.hl7.fhir.dstu3.model.QuestionnaireResponse.QuestionnaireResponseStatus;
|
import org.hl7.fhir.dstu3.model.QuestionnaireResponse.QuestionnaireResponseStatus;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
|
@ -33,6 +34,9 @@ import java.util.List;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.empty;
|
import static org.hamcrest.Matchers.empty;
|
||||||
import static org.hamcrest.Matchers.hasSize;
|
import static org.hamcrest.Matchers.hasSize;
|
||||||
|
import static org.hl7.fhir.dstu3.model.Questionnaire.QuestionnaireItemType.BOOLEAN;
|
||||||
|
import static org.hl7.fhir.dstu3.model.Questionnaire.QuestionnaireItemType.CHOICE;
|
||||||
|
import static org.hl7.fhir.dstu3.model.QuestionnaireResponse.QuestionnaireResponseStatus.COMPLETED;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
import static org.mockito.ArgumentMatchers.contains;
|
import static org.mockito.ArgumentMatchers.contains;
|
||||||
import static org.mockito.Matchers.any;
|
import static org.mockito.Matchers.any;
|
||||||
|
@ -548,7 +552,34 @@ public class QuestionnaireResponseValidatorDstu3Test {
|
||||||
errors.getMessages().stream().filter(vm -> vm.getMessage().contains("Structural Error"))
|
errors.getMessages().stream().filter(vm -> vm.getMessage().contains("Structural Error"))
|
||||||
.anyMatch(vm -> vm.getMessage().contains("link1")));
|
.anyMatch(vm -> vm.getMessage().contains("link1")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAnswerIsValueCodingWithExtensionInside() throws Exception {
|
||||||
|
Questionnaire q = new Questionnaire();
|
||||||
|
Coding qcoding = new Coding();
|
||||||
|
qcoding.setCode("1293");
|
||||||
|
q.addItem().setLinkId("1B").setRequired(true).setType(CHOICE).addOption().setValue(qcoding);
|
||||||
|
q.addItem().setLinkId("2B").setType(BOOLEAN).addEnableWhen().setQuestion("1B").setAnswer(qcoding);
|
||||||
|
|
||||||
|
QuestionnaireResponse qr = new QuestionnaireResponse();
|
||||||
|
qr.setStatus(COMPLETED);
|
||||||
|
qr.getQuestionnaire().setReference(QUESTIONNAIRE_URL);
|
||||||
|
QuestionnaireResponseItemComponent qrItem = qr.addItem().setLinkId("1B");
|
||||||
|
Coding coding = new Coding();
|
||||||
|
coding.setCode("1293");
|
||||||
|
QuestionnaireResponseItemAnswerComponent answer = qrItem.addAnswer();
|
||||||
|
answer.setValue(coding);
|
||||||
|
coding.addExtension("http://hl7.org/fhir/StructureDefinition/questionnaire-hidden", new BooleanType(true));
|
||||||
|
qr.addItem().setLinkId("2B").addAnswer().setValue(new BooleanType(true));
|
||||||
|
|
||||||
|
String reference = qr.getQuestionnaire().getReference();
|
||||||
|
when(myValSupport.fetchResource(any(FhirContext.class), eq(Questionnaire.class), eq(reference))).thenReturn(q);
|
||||||
|
|
||||||
|
ValidationResult errors = myVal.validateWithResult(qr);
|
||||||
|
assertThat(errors.toString(), containsString("No issues"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEmbeddedItemInChoice() {
|
public void testEmbeddedItemInChoice() {
|
||||||
String questionnaireRef = QUESTIONNAIRE_URL;
|
String questionnaireRef = QUESTIONNAIRE_URL;
|
||||||
|
|
Loading…
Reference in New Issue