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

Populate the initial value using the initial expression extension for reference type #1831

Closed
wants to merge 8 commits into from
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ import com.google.android.fhir.datacapture.utilities.toCodeType
import com.google.android.fhir.datacapture.utilities.toCoding
import com.google.android.fhir.datacapture.utilities.toIdType
import com.google.android.fhir.datacapture.utilities.toUriType
import java.lang.IllegalArgumentException
import java.lang.reflect.Field
import java.lang.reflect.Method
import java.lang.reflect.ParameterizedType
import java.util.Locale
import org.hl7.fhir.exceptions.FHIRException
import org.hl7.fhir.r4.context.IWorkerContext
import org.hl7.fhir.r4.hapi.ctx.HapiWorkerContext
import org.hl7.fhir.r4.model.Base
Expand All @@ -48,6 +48,7 @@ import org.hl7.fhir.r4.model.IntegerType
import org.hl7.fhir.r4.model.Parameters
import org.hl7.fhir.r4.model.Questionnaire
import org.hl7.fhir.r4.model.QuestionnaireResponse
import org.hl7.fhir.r4.model.Reference
import org.hl7.fhir.r4.model.Resource
import org.hl7.fhir.r4.model.StringType
import org.hl7.fhir.r4.model.StructureDefinition
Expand Down Expand Up @@ -262,9 +263,17 @@ object ResourceMapper {
// Set initial value for the questionnaire item. Questionnaire items should not have both
// initial value and initial expression.
questionnaireItem.initial =
mutableListOf(
Questionnaire.QuestionnaireItemInitialComponent().setValue(it.asExpectedType())
)
when (questionnaireItem.type) {
Questionnaire.QuestionnaireItemType.REFERENCE ->
mutableListOf(
Questionnaire.QuestionnaireItemInitialComponent()
.setValue(it.asExpectedReferenceType())
)
else ->
mutableListOf(
Questionnaire.QuestionnaireItemInitialComponent().setValue(it.asExpectedType())
)
}
}

populateInitialValues(questionnaireItem.item, *resources)
Expand Down Expand Up @@ -762,6 +771,17 @@ private fun Base.asExpectedType(): Type {
}
}

private fun Base.asExpectedReferenceType(): Type {
return when (this) {
is IdType ->
Reference().apply {
reference =
"${this@asExpectedReferenceType.resourceType}/${this@asExpectedReferenceType.idPart}"
}
else -> throw FHIRException("Expression supplied does not evaluate to IdType.")
}
}

/**
* Returns a newly created [Resource] from the item extraction context extension if one and only one
* such extension exists in the questionnaire, or null otherwise.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import org.hl7.fhir.r4.model.Observation
import org.hl7.fhir.r4.model.Patient
import org.hl7.fhir.r4.model.Questionnaire
import org.hl7.fhir.r4.model.QuestionnaireResponse
import org.hl7.fhir.r4.model.Reference
import org.hl7.fhir.r4.model.RelatedPerson
import org.hl7.fhir.r4.model.ResourceFactory
import org.hl7.fhir.r4.model.StringType
Expand Down Expand Up @@ -1435,6 +1436,70 @@ class ResourceMapperTest {
.isEqualTo(patientId)
}

@Test
fun `populate() should correctly populate Reference value in QuestionnaireResponse`() =
runBlocking {
val questionnaire =
Questionnaire()
.addItem(
Questionnaire.QuestionnaireItemComponent().apply {
linkId = "patient-id"
type = Questionnaire.QuestionnaireItemType.REFERENCE
extension =
listOf(
Extension(
ITEM_INITIAL_EXPRESSION_URL,
Expression().apply {
language = "text/fhirpath"
expression = "Patient.id"
}
)
)
}
)

val patientId = UUID.randomUUID().toString()
val patient = Patient().apply { id = "Patient/$patientId" }
val questionnaireResponse = ResourceMapper.populate(questionnaire, patient)

assertThat((questionnaireResponse.item[0].answer[0].value as Reference).reference)
.isEqualTo(patient.id)
}

@Test
fun `populate() should throw error when Reference value in QuestionnaireResponse but FhirExpression `() =
runBlocking {
val questionnaire =
Questionnaire()
.addItem(
Questionnaire.QuestionnaireItemComponent().apply {
linkId = "patient-id"
type = Questionnaire.QuestionnaireItemType.REFERENCE
extension =
listOf(
Extension(
ITEM_INITIAL_EXPRESSION_URL,
Expression().apply {
language = "text/fhirpath"
expression = "Patient.gender"
}
)
)
}
)

val patientId = UUID.randomUUID().toString()
val patient =
Patient().apply {
id = "Patient/$patientId"
gender = Enumerations.AdministrativeGender.MALE
}

val errorMessage =
assertFailsWith<FHIRException> { ResourceMapper.populate(questionnaire, patient) }
.localizedMessage
assertThat(errorMessage).isEqualTo("Expression supplied does not evaluate to IdType.")
}
@Test
fun `populate() should correctly populate IdType value with history in QuestionnaireResponse`() =
runBlocking {
Expand Down