Skip to content

Commit

Permalink
[ZEIR] Make Addition of Basic Resources for CQL calculation to be gen…
Browse files Browse the repository at this point in the history
…eric (#2783)

* Make Addition of Basic Resources for CQL calculation to be generic

* Update QuestionnaireViewModelTest

* Add new test testLoadCqlInputResourcesFromQuestionnaireConfig

* Update QuestionnaireViewModelTest.kt

* Update failing tests in QuestionnaireViewModelTest

* spotless apply
  • Loading branch information
qaziabubakar-vd authored Sep 27, 2023
1 parent b4b5429 commit 6adca90
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ data class QuestionnaireConfig(
null,
val saveQuestionnaireResponse: Boolean = true,
val generateCarePlanWithWorkflowApi: Boolean = false,
val cqlInputResources: List<String>? = emptyList(),
val showClearAll: Boolean = false,
) : java.io.Serializable, Parcelable {

Expand All @@ -80,6 +81,7 @@ data class QuestionnaireConfig(
readOnlyLinkIds = readOnlyLinkIds?.map { it.interpolate(computedValuesMap) },
onSubmitActions = onSubmitActions?.map { it.interpolate(computedValuesMap) },
barcodeLinkId = barcodeLinkId.interpolate(computedValuesMap),
cqlInputResources = cqlInputResources?.map { it.interpolate(computedValuesMap) },
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ constructor(
subject = subject,
bundle = newBundle,
questionnaire = questionnaire,
questionnaireConfig = questionnaireConfig,
)
}

Expand Down Expand Up @@ -588,19 +589,17 @@ constructor(
.all { it is Valid || it is NotValidated }
}

suspend fun executeCql(subject: Resource, bundle: Bundle, questionnaire: Questionnaire) {
suspend fun executeCql(
subject: Resource,
bundle: Bundle,
questionnaire: Questionnaire,
questionnaireConfig: QuestionnaireConfig? = null,
) {
questionnaireConfig?.cqlInputResources?.forEach { resourceId ->
val basicResource = defaultRepository.loadResource(resourceId) as Basic?
bundle.addEntry(Bundle.BundleEntryComponent().setResource(basicResource))
}
questionnaire.cqfLibraryIds().forEach { libraryId ->
// TODO Refactor/Remove as per the issue: https://github.com/opensrp/fhircore/issues/2747
if (
libraryId == "223758"
) { // Resource id for Library that calculates Z-score in ZEIR application
// Adding 4 basic resources which contain the Data needed for Z-score calculation
val basicResourceIds = listOf("223754", "223755", "223756", "223757", "250928", "264356")
basicResourceIds.forEach { resourceId ->
val basicResource = defaultRepository.loadResource(resourceId) as Basic?
bundle.addEntry(Bundle.BundleEntryComponent().setResource(basicResource))
}
}
if (subject.resourceType == ResourceType.Patient) {
libraryEvaluator.runCqlLibrary(libraryId, subject as Patient, bundle)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import java.util.Calendar
import java.util.Date
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.json.Json
import org.hl7.fhir.r4.model.Basic
import org.hl7.fhir.r4.model.Bundle
import org.hl7.fhir.r4.model.DateType
import org.hl7.fhir.r4.model.Enumerations
Expand Down Expand Up @@ -113,6 +114,15 @@ object Faker {
}
}

fun buildBasicResource(
id: String = "sampleId",
): Basic {
return Basic().apply {
this.id = id
this.identifierFirstRep.value = id
}
}

open class TestLoginActivity : LoginActivity() {
override fun pinActive() = true

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import androidx.test.core.app.ApplicationProvider
import com.google.android.fhir.FhirEngine
import com.google.android.fhir.datacapture.mapping.ResourceMapper
import com.google.android.fhir.db.ResourceNotFoundException
import com.google.android.fhir.get
import com.google.android.fhir.logicalId
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
Expand All @@ -40,8 +41,10 @@ import java.util.UUID
import javax.inject.Inject
import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.runTest
import org.hl7.fhir.r4.model.Address
import org.hl7.fhir.r4.model.Basic
import org.hl7.fhir.r4.model.Bundle
import org.hl7.fhir.r4.model.CodeableConcept
import org.hl7.fhir.r4.model.Coding
Expand Down Expand Up @@ -325,6 +328,7 @@ class QuestionnaireViewModelTest : RobolectricTest() {
subject = capture(subjectSlot),
bundle = capture(bundleSlot),
questionnaire = questionnaire,
questionnaireConfig = questionnaireConfig,
)

fhirCarePlanGenerator.conditionallyUpdateResourceStatus(
Expand Down Expand Up @@ -994,4 +998,52 @@ class QuestionnaireViewModelTest : RobolectricTest() {
defaultRepository.addOrUpdate(addMandatoryTags = true, resource = questionnaireResponse)
}
}

@Test
fun testLoadCqlInputResourcesFromQuestionnaireConfig() = runBlocking {
val bundle = Bundle()

// Define the expected CQL input resources
val expectedCqlInputResources = listOf("basic-resource-id")

val questionnaireConfigCqlInputResources =
questionnaireConfig.copy(cqlInputResources = listOf("basic-resource-id"))

// Create a sample questionnaire with a CQL library extension
val questionnaire =
samplePatientRegisterQuestionnaire.copy().apply {
addExtension(
Extension().apply {
url = "https://sample.cqf-library.url"
setValue(StringType("Library/123"))
},
)
}

// Mock the retrieval of a Basic resource with the specified ID
val resource1 = Faker.buildBasicResource("basic-resource-id")
coEvery { fhirEngine.get<Basic>(any()) } answers { resource1 }

// Load the CQL input resources from the questionnaireConfig
val loadedCqlInputResources = questionnaireConfigCqlInputResources.cqlInputResources

// Verify that the loadedCqlInputResources match the expected list
Assert.assertEquals(expectedCqlInputResources, loadedCqlInputResources)

// Execute CQL by invoking the questionnaireViewModel.executeCql method
questionnaireViewModel.executeCql(
patient,
bundle,
questionnaire,
questionnaireConfigCqlInputResources,
)

// Verify that the bundle contains the expected Basic resource with ID "basic-resource-id"
Assert.assertTrue(
bundle.entry.any { it.resource is Basic && it.resource.id == "basic-resource-id" },
)

// Verify that the libraryEvaluator.runCqlLibrary was called with the correct arguments
coVerify { libraryEvaluator.runCqlLibrary("123", patient, bundle) }
}
}

0 comments on commit 6adca90

Please sign in to comment.