From 6adca907598f2231e19bd3875998e7a5927b5b62 Mon Sep 17 00:00:00 2001 From: qaziabubakar-vd <72507786+qaziabubakar-vd@users.noreply.github.com> Date: Wed, 27 Sep 2023 14:51:08 +0500 Subject: [PATCH] [ZEIR] Make Addition of Basic Resources for CQL calculation to be generic (#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 --- .../configuration/QuestionnaireConfig.kt | 2 + .../questionnaire/QuestionnaireViewModel.kt | 23 ++++---- .../fhircore/quest/app/fakes/Faker.kt | 10 ++++ .../QuestionnaireViewModelTest.kt | 52 +++++++++++++++++++ 4 files changed, 75 insertions(+), 12 deletions(-) diff --git a/android/engine/src/main/java/org/smartregister/fhircore/engine/configuration/QuestionnaireConfig.kt b/android/engine/src/main/java/org/smartregister/fhircore/engine/configuration/QuestionnaireConfig.kt index 0754b3a75a..0fa91ebf35 100644 --- a/android/engine/src/main/java/org/smartregister/fhircore/engine/configuration/QuestionnaireConfig.kt +++ b/android/engine/src/main/java/org/smartregister/fhircore/engine/configuration/QuestionnaireConfig.kt @@ -55,6 +55,7 @@ data class QuestionnaireConfig( null, val saveQuestionnaireResponse: Boolean = true, val generateCarePlanWithWorkflowApi: Boolean = false, + val cqlInputResources: List? = emptyList(), val showClearAll: Boolean = false, ) : java.io.Serializable, Parcelable { @@ -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) }, ) } diff --git a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/questionnaire/QuestionnaireViewModel.kt b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/questionnaire/QuestionnaireViewModel.kt index 1696b3a71b..9746c072a2 100644 --- a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/questionnaire/QuestionnaireViewModel.kt +++ b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/questionnaire/QuestionnaireViewModel.kt @@ -240,6 +240,7 @@ constructor( subject = subject, bundle = newBundle, questionnaire = questionnaire, + questionnaireConfig = questionnaireConfig, ) } @@ -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) } diff --git a/android/quest/src/test/java/org/smartregister/fhircore/quest/app/fakes/Faker.kt b/android/quest/src/test/java/org/smartregister/fhircore/quest/app/fakes/Faker.kt index bf35ec6736..6a617189ec 100644 --- a/android/quest/src/test/java/org/smartregister/fhircore/quest/app/fakes/Faker.kt +++ b/android/quest/src/test/java/org/smartregister/fhircore/quest/app/fakes/Faker.kt @@ -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 @@ -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 diff --git a/android/quest/src/test/java/org/smartregister/fhircore/quest/ui/questionnaire/QuestionnaireViewModelTest.kt b/android/quest/src/test/java/org/smartregister/fhircore/quest/ui/questionnaire/QuestionnaireViewModelTest.kt index fa5fc61402..f05ed4bd48 100644 --- a/android/quest/src/test/java/org/smartregister/fhircore/quest/ui/questionnaire/QuestionnaireViewModelTest.kt +++ b/android/quest/src/test/java/org/smartregister/fhircore/quest/ui/questionnaire/QuestionnaireViewModelTest.kt @@ -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 @@ -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 @@ -325,6 +328,7 @@ class QuestionnaireViewModelTest : RobolectricTest() { subject = capture(subjectSlot), bundle = capture(bundleSlot), questionnaire = questionnaire, + questionnaireConfig = questionnaireConfig, ) fhirCarePlanGenerator.conditionallyUpdateResourceStatus( @@ -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(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) } + } }