diff --git a/android/buildSrc/src/main/kotlin/BuildConfigs.kt b/android/buildSrc/src/main/kotlin/BuildConfigs.kt index 78176a7a61..b4ac17129a 100644 --- a/android/buildSrc/src/main/kotlin/BuildConfigs.kt +++ b/android/buildSrc/src/main/kotlin/BuildConfigs.kt @@ -3,7 +3,7 @@ object BuildConfigs { const val compileSdk = 34 const val targetSdk = 34 const val versionCode = 11 - const val versionName = "2.0.0" + const val versionName = "2.0.1" const val applicationId = "org.smartregister.opensrp" const val jvmToolchain = 17 const val kotlinCompilerExtensionVersion = "1.5.8" @@ -11,4 +11,5 @@ object BuildConfigs { const val ktLintVersion = "0.49.0" const val enableUnitTestCoverage = true const val enableAndroidTestCoverage = false -} \ No newline at end of file +} + diff --git a/android/engine/src/main/java/org/smartregister/fhircore/engine/data/local/DefaultRepository.kt b/android/engine/src/main/java/org/smartregister/fhircore/engine/data/local/DefaultRepository.kt index d4e4b069bc..9563ceef29 100644 --- a/android/engine/src/main/java/org/smartregister/fhircore/engine/data/local/DefaultRepository.kt +++ b/android/engine/src/main/java/org/smartregister/fhircore/engine/data/local/DefaultRepository.kt @@ -264,6 +264,10 @@ constructor( fhirEngine.update(resource) } + suspend fun applyDbTransaction(block: suspend () -> Unit) { + fhirEngine.withTransaction { block.invoke() } + } + suspend fun loadManagingEntity(group: Group) = group.managingEntity?.let { reference -> fhirEngine diff --git a/android/engine/src/main/java/org/smartregister/fhircore/engine/data/remote/shared/TokenAuthenticator.kt b/android/engine/src/main/java/org/smartregister/fhircore/engine/data/remote/shared/TokenAuthenticator.kt index a3daf5035a..757bb0a355 100644 --- a/android/engine/src/main/java/org/smartregister/fhircore/engine/data/remote/shared/TokenAuthenticator.kt +++ b/android/engine/src/main/java/org/smartregister/fhircore/engine/data/remote/shared/TokenAuthenticator.kt @@ -40,6 +40,8 @@ import java.util.Base64 import javax.inject.Inject import javax.inject.Singleton import javax.net.ssl.SSLHandshakeException +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import org.smartregister.fhircore.engine.configuration.app.ConfigService import org.smartregister.fhircore.engine.data.remote.auth.OAuthService @@ -215,8 +217,11 @@ constructor( addAccountExplicitly(newAccount, oAuthResponse.refreshToken, null) setAuthToken(newAccount, AUTH_TOKEN_TYPE, oAuthResponse.accessToken) } + // Save credentials - secureSharedPreference.saveCredentials(username, password) + CoroutineScope(dispatcherProvider.io()).launch { + secureSharedPreference.saveCredentials(username, password) + } } } diff --git a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/appsetting/AppSettingViewModel.kt b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/appsetting/AppSettingViewModel.kt index 0753e307c9..f598565aa1 100644 --- a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/appsetting/AppSettingViewModel.kt +++ b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/appsetting/AppSettingViewModel.kt @@ -30,7 +30,6 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.RequestBody.Companion.toRequestBody import org.apache.commons.lang3.StringUtils -import org.hl7.fhir.r4.model.Binary import org.hl7.fhir.r4.model.Bundle import org.hl7.fhir.r4.model.Composition import org.hl7.fhir.r4.model.ResourceType 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 2fedb834e6..b2430fe56e 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 @@ -195,73 +195,93 @@ constructor( context = context, ) - saveExtractedResources( - bundle = bundle, - questionnaire = questionnaire, - questionnaireConfig = questionnaireConfig, - questionnaireResponse = currentQuestionnaireResponse, - context = context, + defaultRepository.applyDbTransaction { + performSave( + bundle, + questionnaire, + questionnaireConfig, + currentQuestionnaireResponse, + context, + actionParameters, + ) + } + + val idTypes = + bundle.entry?.map { IdType(it.resource.resourceType.name, it.resource.logicalId) } + ?: emptyList() + + onSuccessfulSubmission( + idTypes, + currentQuestionnaireResponse, ) + } + } - updateResourcesLastUpdatedProperty(actionParameters) + private suspend fun performSave( + bundle: Bundle, + questionnaire: Questionnaire, + questionnaireConfig: QuestionnaireConfig, + currentQuestionnaireResponse: QuestionnaireResponse, + context: Context, + actionParameters: List, + ) { + saveExtractedResources( + bundle = bundle, + questionnaire = questionnaire, + questionnaireConfig = questionnaireConfig, + questionnaireResponse = currentQuestionnaireResponse, + context = context, + ) - // Important to load subject resource to retrieve ID (as reference) correctly - val subjectIdType: IdType? = - if (currentQuestionnaireResponse.subject.reference.isNullOrEmpty()) { - null - } else { - IdType(currentQuestionnaireResponse.subject.reference) - } + updateResourcesLastUpdatedProperty(actionParameters) - if (subjectIdType != null) { - val subject = - loadResource( - ResourceType.valueOf(subjectIdType.resourceType), - subjectIdType.idPart, - ) + // Important to load subject resource to retrieve ID (as reference) correctly + val subjectIdType: IdType? = + if (currentQuestionnaireResponse.subject.reference.isNullOrEmpty()) { + null + } else { + IdType(currentQuestionnaireResponse.subject.reference) + } - if (subject != null && !questionnaireConfig.isReadOnly()) { - val newBundle = bundle.copyBundle(currentQuestionnaireResponse) + if (subjectIdType != null) { + val subject = + loadResource( + ResourceType.valueOf(subjectIdType.resourceType), + subjectIdType.idPart, + ) - val extractedResources = newBundle.entry.map { it.resource } - validateWithFhirValidator(*extractedResources.toTypedArray()) + if (subject != null && !questionnaireConfig.isReadOnly()) { + val newBundle = bundle.copyBundle(currentQuestionnaireResponse) - generateCarePlan( - subject = subject, - bundle = newBundle, - questionnaireConfig = questionnaireConfig, - ) + val extractedResources = newBundle.entry.map { it.resource } + validateWithFhirValidator(*extractedResources.toTypedArray()) - withContext(dispatcherProvider.io()) { - executeCql( - subject = subject, - bundle = newBundle, - questionnaire = questionnaire, - questionnaireConfig = questionnaireConfig, - ) - } + generateCarePlan( + subject = subject, + bundle = newBundle, + questionnaireConfig = questionnaireConfig, + ) - fhirCarePlanGenerator.conditionallyUpdateResourceStatus( - questionnaireConfig = questionnaireConfig, + withContext(dispatcherProvider.io()) { + executeCql( subject = subject, bundle = newBundle, + questionnaire = questionnaire, + questionnaireConfig = questionnaireConfig, ) } - } - - softDeleteResources(questionnaireConfig) - retireUsedQuestionnaireUniqueId(questionnaireConfig, currentQuestionnaireResponse) + fhirCarePlanGenerator.conditionallyUpdateResourceStatus( + questionnaireConfig = questionnaireConfig, + subject = subject, + bundle = newBundle, + ) + } + } - val idTypes = - bundle.entry?.map { IdType(it.resource.resourceType.name, it.resource.logicalId) } - ?: emptyList() + softDeleteResources(questionnaireConfig) - onSuccessfulSubmission( - idTypes, - currentQuestionnaireResponse, - ) - } + retireUsedQuestionnaireUniqueId(questionnaireConfig, currentQuestionnaireResponse) } fun validateWithFhirValidator(vararg resource: Resource) { @@ -642,27 +662,25 @@ constructor( ): Bundle = kotlin .runCatching { - withContext(dispatcherProvider.default()) { - if (extractByStructureMap) { - ResourceMapper.extract( - questionnaire = questionnaire, - questionnaireResponse = questionnaireResponse, - structureMapExtractionContext = - StructureMapExtractionContext( - transformSupportServices = transformSupportServices, - structureMapProvider = { structureMapUrl: String?, _: IWorkerContext -> - structureMapUrl?.substringAfterLast("/")?.let { structureMapId -> - defaultRepository.loadResourceFromCache(structureMapId) - } - }, - ), - ) - } else { - ResourceMapper.extract( - questionnaire = questionnaire, - questionnaireResponse = questionnaireResponse, - ) - } + if (extractByStructureMap) { + ResourceMapper.extract( + questionnaire = questionnaire, + questionnaireResponse = questionnaireResponse, + structureMapExtractionContext = + StructureMapExtractionContext( + transformSupportServices = transformSupportServices, + structureMapProvider = { structureMapUrl: String?, _: IWorkerContext -> + structureMapUrl?.substringAfterLast("/")?.let { structureMapId -> + defaultRepository.loadResourceFromCache(structureMapId) + } + }, + ), + ) + } else { + ResourceMapper.extract( + questionnaire = questionnaire, + questionnaireResponse = questionnaireResponse, + ) } } .onFailure { exception -> diff --git a/android/quest/src/test/java/org/smartregister/fhircore/quest/StructureMapUtilitiesTest.kt b/android/quest/src/test/java/org/smartregister/fhircore/quest/StructureMapUtilitiesTest.kt index d6cfc4eb3b..4b893f97fe 100644 --- a/android/quest/src/test/java/org/smartregister/fhircore/quest/StructureMapUtilitiesTest.kt +++ b/android/quest/src/test/java/org/smartregister/fhircore/quest/StructureMapUtilitiesTest.kt @@ -33,7 +33,9 @@ import org.hl7.fhir.r4.model.QuestionnaireResponse import org.hl7.fhir.r4.model.RelatedPerson import org.hl7.fhir.r4.model.ResourceType import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager +import org.junit.After import org.junit.Assert +import org.junit.Before import org.junit.Test import org.smartregister.fhircore.engine.util.helper.TransformSupportServices import org.smartregister.fhircore.quest.robolectric.RobolectricTest @@ -45,25 +47,40 @@ import org.smartregister.fhircore.quest.robolectric.RobolectricTest * This should be removed at a later point once we have a more clear way of doing this */ class StructureMapUtilitiesTest : RobolectricTest() { - - @Test - fun `perform family extraction`() { - val registrationQuestionnaireResponseString: String = - "content/general/family/questionnaire-response-standard.json".readFile() - val registrationStructureMap = "content/general/family/family-registration.map".readFile() - val packageCacheManager = FilesystemPackageCacheManager(true) - val contextR4 = + private lateinit var packageCacheManager: FilesystemPackageCacheManager + private lateinit var contextR4: SimpleWorkerContext + private lateinit var transformSupportServices: TransformSupportServices + private lateinit var structureMapUtilities: org.hl7.fhir.r4.utils.StructureMapUtilities + private lateinit var iParser: IParser + + @Before + fun setUp() { + packageCacheManager = FilesystemPackageCacheManager(true) + contextR4 = SimpleWorkerContext.fromPackage(packageCacheManager.loadPackage("hl7.fhir.r4.core", "4.0.1")) .apply { setExpansionProfile(Parameters()) isCanRunWithoutTerminology = true } - val transformSupportServices = TransformSupportServices(contextR4) - val structureMapUtilities = + transformSupportServices = TransformSupportServices(contextR4) + structureMapUtilities = org.hl7.fhir.r4.utils.StructureMapUtilities(contextR4, transformSupportServices) + iParser = FhirContext.forCached(FhirVersionEnum.R4).newJsonParser() + } + + @After + fun packageTearDown() { + // Clean up resources or reset states here + packageCacheManager.clear() + } + + @Test + fun `perform family extraction`() { + val registrationQuestionnaireResponseString: String = + "content/general/family/questionnaire-response-standard.json".readFile() + val registrationStructureMap = "content/general/family/family-registration.map".readFile() val structureMap = structureMapUtilities.parse(registrationStructureMap, "eCBIS Family Registration") - val iParser: IParser = FhirContext.forCached(FhirVersionEnum.R4).newJsonParser() val targetResource = Bundle() val baseElement = iParser.parseResource( @@ -84,19 +101,8 @@ class StructureMapUtilitiesTest : RobolectricTest() { "content/general/disease-registration-resources/questionnaire_response.json".readFile() val immunizationStructureMap = "content/general/disease-registration-resources/structure-map.txt".readFile() - val packageCacheManager = FilesystemPackageCacheManager(true) - val contextR4 = - SimpleWorkerContext.fromPackage(packageCacheManager.loadPackage("hl7.fhir.r4.core", "4.0.1")) - .apply { - setExpansionProfile(Parameters()) - isCanRunWithoutTerminology = true - } - val transformSupportServices = TransformSupportServices(contextR4) - val structureMapUtilities = - org.hl7.fhir.r4.utils.StructureMapUtilities(contextR4, transformSupportServices) val structureMap = structureMapUtilities.parse(immunizationStructureMap, "eCBIS Disease Registration") - val iParser: IParser = FhirContext.forCached(FhirVersionEnum.R4).newJsonParser() val targetResource = Bundle() val baseElement = iParser.parseResource( @@ -118,19 +124,8 @@ class StructureMapUtilitiesTest : RobolectricTest() { val immunizationJson = "content/eir/immunization/immunization-1.json".readFile() val immunizationStructureMap = "content/eir/immunization/structure-map.txt".readFile() val questionnaireJson = "content/eir/immunization/questionnaire.json".readFile() - val packageCacheManager = FilesystemPackageCacheManager(true) - val contextR4 = - SimpleWorkerContext.fromPackage(packageCacheManager.loadPackage("hl7.fhir.r4.core", "4.0.1")) - .apply { - setExpansionProfile(Parameters()) - isCanRunWithoutTerminology = true - } - val transformSupportServices = TransformSupportServices(contextR4) - val structureMapUtilities = - org.hl7.fhir.r4.utils.StructureMapUtilities(contextR4, transformSupportServices) val structureMap = structureMapUtilities.parse(immunizationStructureMap, "ImmunizationRegistration") - val iParser: IParser = FhirContext.forCached(FhirVersionEnum.R4).newJsonParser() val targetResource = Bundle() val patient = iParser.parseResource(Patient::class.java, patientJson) val immunization = iParser.parseResource(Immunization::class.java, immunizationJson) @@ -182,16 +177,6 @@ class StructureMapUtilitiesTest : RobolectricTest() { ) } - val packageCacheManager = FilesystemPackageCacheManager(true) - val contextR4 = - SimpleWorkerContext.fromPackage(packageCacheManager.loadPackage("hl7.fhir.r4.core", "4.0.1")) - .apply { - setExpansionProfile(Parameters()) - isCanRunWithoutTerminology = true - } - val transformSupportServices = TransformSupportServices(contextR4) - val structureMapUtilities = - org.hl7.fhir.r4.utils.StructureMapUtilities(contextR4, transformSupportServices) val structureMap = structureMapUtilities.parse(patientRegistrationStructureMap, "PatientRegistration") val targetResource = Bundle() @@ -224,16 +209,6 @@ class StructureMapUtilitiesTest : RobolectricTest() { ) } - val packageCacheManager = FilesystemPackageCacheManager(true) - val contextR4 = - SimpleWorkerContext.fromPackage(packageCacheManager.loadPackage("hl7.fhir.r4.core", "4.0.1")) - .apply { - setExpansionProfile(Parameters()) - isCanRunWithoutTerminology = true - } - val transformSupportServices = TransformSupportServices(contextR4) - val structureMapUtilities = - org.hl7.fhir.r4.utils.StructureMapUtilities(contextR4, transformSupportServices) val structureMap = structureMapUtilities.parse(adverseEventStructureMap, "AdverseEvent") val targetResource = Bundle() @@ -248,14 +223,8 @@ class StructureMapUtilitiesTest : RobolectricTest() { fun `convert StructureMap to JSON`() { val patientRegistrationStructureMap = "patient-registration-questionnaire/structure-map.txt".readFile() - val packageCacheManager = FilesystemPackageCacheManager(true) - val contextR4 = - SimpleWorkerContext.fromPackage(packageCacheManager.loadPackage("hl7.fhir.r4.core", "4.0.1")) - .apply { isCanRunWithoutTerminology = true } - val structureMapUtilities = org.hl7.fhir.r4.utils.StructureMapUtilities(contextR4) val structureMap = structureMapUtilities.parse(patientRegistrationStructureMap, "PatientRegistration") - val iParser: IParser = FhirContext.forCached(FhirVersionEnum.R4).newJsonParser() val mapString = iParser.encodeResourceToString(structureMap) Assert.assertNotNull(mapString) @@ -267,19 +236,8 @@ class StructureMapUtilitiesTest : RobolectricTest() { "patient-registration-questionnaire/questionnaire-response.json".readFile() val patientRegistrationStructureMap = "patient-registration-questionnaire/structure-map.txt".readFile() - val packageCacheManager = FilesystemPackageCacheManager(true) - val contextR4 = - SimpleWorkerContext.fromPackage(packageCacheManager.loadPackage("hl7.fhir.r4.core", "4.0.1")) - .apply { - setExpansionProfile(Parameters()) - isCanRunWithoutTerminology = true - } - val transformSupportServices = TransformSupportServices(contextR4) - val structureMapUtilities = - org.hl7.fhir.r4.utils.StructureMapUtilities(contextR4, transformSupportServices) val structureMap = structureMapUtilities.parse(patientRegistrationStructureMap, "PatientRegistration") - val iParser: IParser = FhirContext.forCached(FhirVersionEnum.R4).newJsonParser() val targetResource = Bundle() val baseElement = iParser.parseResource( @@ -298,18 +256,7 @@ class StructureMapUtilitiesTest : RobolectricTest() { val adverseEventQuestionnaireResponse = "content/eir/adverse-event/questionnaire-response.json".readFile() val adverseEventStructureMap = "content/eir/adverse-event/structure-map.txt".readFile() - val packageCacheManager = FilesystemPackageCacheManager(true) - val contextR4 = - SimpleWorkerContext.fromPackage(packageCacheManager.loadPackage("hl7.fhir.r4.core", "4.0.1")) - .apply { - setExpansionProfile(Parameters()) - isCanRunWithoutTerminology = true - } - val transformSupportServices = TransformSupportServices(contextR4) - val structureMapUtilities = - org.hl7.fhir.r4.utils.StructureMapUtilities(contextR4, transformSupportServices) val structureMap = structureMapUtilities.parse(adverseEventStructureMap, "AdverseEvent") - val iParser: IParser = FhirContext.forCached(FhirVersionEnum.R4).newJsonParser() val targetResource = Bundle() val baseElement = @@ -327,18 +274,7 @@ class StructureMapUtilitiesTest : RobolectricTest() { val vitalSignQuestionnaireResponse = "content/anc/vital-signs/metric/questionnaire-response-pulse-rate.json".readFile() val vitalSignStructureMap = "content/anc/vital-signs/metric/structure-map.txt".readFile() - val packageCacheManager = FilesystemPackageCacheManager(true) - val contextR4 = - SimpleWorkerContext.fromPackage(packageCacheManager.loadPackage("hl7.fhir.r4.core", "4.0.1")) - .apply { - setExpansionProfile(Parameters()) - isCanRunWithoutTerminology = true - } - val transformSupportServices = TransformSupportServices(contextR4) - val structureMapUtilities = - org.hl7.fhir.r4.utils.StructureMapUtilities(contextR4, transformSupportServices) val structureMap = structureMapUtilities.parse(vitalSignStructureMap, "VitalSigns") - val iParser: IParser = FhirContext.forCached(FhirVersionEnum.R4).newJsonParser() val targetResource = Bundle() val baseElement = iParser.parseResource(QuestionnaireResponse::class.java, vitalSignQuestionnaireResponse) @@ -356,18 +292,7 @@ class StructureMapUtilitiesTest : RobolectricTest() { "content/anc/vital-signs/standard/questionnaire-response-pulse-rate.json".readFile() val vitalSignStructureMap = "content/anc/vital-signs/standard/structure-map.txt".readFile() - val packageCacheManager = FilesystemPackageCacheManager(true) - val contextR4 = - SimpleWorkerContext.fromPackage(packageCacheManager.loadPackage("hl7.fhir.r4.core", "4.0.1")) - .apply { - setExpansionProfile(Parameters()) - isCanRunWithoutTerminology = true - } - val transformSupportServices = TransformSupportServices(contextR4) - val structureMapUtilities = - org.hl7.fhir.r4.utils.StructureMapUtilities(contextR4, transformSupportServices) val structureMap = structureMapUtilities.parse(vitalSignStructureMap, "VitalSigns") - val iParser: IParser = FhirContext.forCached(FhirVersionEnum.R4).newJsonParser() val targetResource = Bundle() val baseElement = iParser.parseResource(QuestionnaireResponse::class.java, vitalSignQuestionnaireResponse) @@ -377,6 +302,7 @@ class StructureMapUtilitiesTest : RobolectricTest() { Assert.assertEquals(2, targetResource.entry.size) Assert.assertEquals("Encounter", targetResource.entry[0].resource.resourceType.toString()) Assert.assertEquals("Observation", targetResource.entry[1].resource.resourceType.toString()) + packageCacheManager.clear() } @Test @@ -384,18 +310,7 @@ class StructureMapUtilitiesTest : RobolectricTest() { val locationQuestionnaireResponseString: String = "content/general/location/location-response-sample.json".readFile() val locationStructureMap = "content/general/location/location-structure-map.txt".readFile() - val packageCacheManager = FilesystemPackageCacheManager(true) - val contextR4 = - SimpleWorkerContext.fromPackage(packageCacheManager.loadPackage("hl7.fhir.r4.core", "4.0.1")) - .apply { - setExpansionProfile(Parameters()) - isCanRunWithoutTerminology = true - } - val transformSupportServices = TransformSupportServices(contextR4) - val structureMapUtilities = - org.hl7.fhir.r4.utils.StructureMapUtilities(contextR4, transformSupportServices) val structureMap = structureMapUtilities.parse(locationStructureMap, "LocationRegistration") - val iParser: IParser = FhirContext.forCached(FhirVersionEnum.R4).newJsonParser() val targetResource = Bundle() val baseElement = iParser.parseResource(QuestionnaireResponse::class.java, locationQuestionnaireResponseString) @@ -412,22 +327,11 @@ class StructureMapUtilitiesTest : RobolectricTest() { "content/general/supply-chain/questionnaire-response-standard.json".readFile() val physicalInventoryCountStructureMap = "content/general/supply-chain/physical_inventory_count_and_stock.map".readFile() - val packageCacheManager = FilesystemPackageCacheManager(true) - val contextR4 = - SimpleWorkerContext.fromPackage(packageCacheManager.loadPackage("hl7.fhir.r4.core", "4.0.1")) - .apply { - setExpansionProfile(Parameters()) - isCanRunWithoutTerminology = true - } - val transformSupportServices = TransformSupportServices(contextR4) - val structureMapUtilities = - org.hl7.fhir.r4.utils.StructureMapUtilities(contextR4, transformSupportServices) val structureMap = structureMapUtilities.parse( physicalInventoryCountStructureMap, "Physical Inventory Count and Stock Supply", ) - val iParser: IParser = FhirContext.forCached(FhirVersionEnum.R4).newJsonParser() val targetResource = Bundle() val baseElement = iParser.parseResource( @@ -450,19 +354,8 @@ class StructureMapUtilitiesTest : RobolectricTest() { val vitalSignQuestionnaireResponse = "content/anc/preg-outcome/questionnaire-response.json".readFile() val vitalSignStructureMap = "content/anc/preg-outcome/structure-map.txt".readFile() - val packageCacheManager = FilesystemPackageCacheManager(true) - val contextR4 = - SimpleWorkerContext.fromPackage(packageCacheManager.loadPackage("hl7.fhir.r4.core", "4.0.1")) - .apply { - setExpansionProfile(Parameters()) - isCanRunWithoutTerminology = true - } - val transformSupportServices = TransformSupportServices(contextR4) - val structureMapUtilities = - org.hl7.fhir.r4.utils.StructureMapUtilities(contextR4, transformSupportServices) val structureMap = structureMapUtilities.parse(vitalSignStructureMap, "PregnancyOutcomeRegistration") - val iParser: IParser = FhirContext.forCached(FhirVersionEnum.R4).newJsonParser() val targetResource = Bundle() val baseElement = iParser.parseResource(QuestionnaireResponse::class.java, vitalSignQuestionnaireResponse) @@ -483,18 +376,7 @@ class StructureMapUtilitiesTest : RobolectricTest() { "content/general/who-eir/patient_registration_questionnaire_response.json".readFile() val locationStructureMap = "content/general/who-eir/patient_registration_structure_map.txt".readFile() - val packageCacheManager = FilesystemPackageCacheManager(true) - val contextR4 = - SimpleWorkerContext.fromPackage(packageCacheManager.loadPackage("hl7.fhir.r4.core", "4.0.1")) - .apply { - setExpansionProfile(Parameters()) - isCanRunWithoutTerminology = true - } - val transformSupportServices = TransformSupportServices(contextR4) - val structureMapUtilities = - org.hl7.fhir.r4.utils.StructureMapUtilities(contextR4, transformSupportServices) val structureMap = structureMapUtilities.parse(locationStructureMap, "IMMZ-C-QRToPatient") - val iParser: IParser = FhirContext.forCached(FhirVersionEnum.R4).newJsonParser() val targetResource = Bundle() val baseElement = iParser.parseResource(QuestionnaireResponse::class.java, locationQuestionnaireResponseString) diff --git a/android/quest/src/test/java/org/smartregister/fhircore/quest/ui/profile/ProfileViewModelTest.kt b/android/quest/src/test/java/org/smartregister/fhircore/quest/ui/profile/ProfileViewModelTest.kt index 9c63ea2390..408d98b3b0 100644 --- a/android/quest/src/test/java/org/smartregister/fhircore/quest/ui/profile/ProfileViewModelTest.kt +++ b/android/quest/src/test/java/org/smartregister/fhircore/quest/ui/profile/ProfileViewModelTest.kt @@ -54,7 +54,6 @@ import org.smartregister.fhircore.engine.domain.model.OverflowMenuItemConfig import org.smartregister.fhircore.engine.domain.model.RepositoryResourceData import org.smartregister.fhircore.engine.domain.model.ResourceData import org.smartregister.fhircore.engine.rulesengine.ResourceDataRulesExecutor -import org.smartregister.fhircore.engine.util.DefaultDispatcherProvider import org.smartregister.fhircore.engine.util.DispatcherProvider import org.smartregister.fhircore.engine.util.extension.BLACK_COLOR_HEX_CODE import org.smartregister.fhircore.engine.util.extension.getActivity @@ -99,7 +98,6 @@ class ProfileViewModelTest : RobolectricTest() { spyk( RegisterRepository( fhirEngine = mockk(), - dispatcherProvider = DefaultDispatcherProvider(), sharedPreferencesHelper = mockk(), configurationRegistry = configurationRegistry, configService = mockk(), @@ -107,6 +105,7 @@ class ProfileViewModelTest : RobolectricTest() { fhirPathDataExtractor = mockk(), parser = parser, context = ApplicationProvider.getApplicationContext(), + dispatcherProvider = dispatcherProvider, ), ) coEvery { 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 e897d4b8a7..90c7753ab7 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 @@ -150,7 +150,6 @@ class QuestionnaireViewModelTest : RobolectricTest() { @Inject lateinit var knowledgeManager: KnowledgeManager @Inject lateinit var contentCache: ContentCache - private lateinit var samplePatientRegisterQuestionnaire: Questionnaire private lateinit var questionnaireConfig: QuestionnaireConfig private lateinit var questionnaireViewModel: QuestionnaireViewModel @@ -250,6 +249,10 @@ class QuestionnaireViewModelTest : RobolectricTest() { extractionQuestionnaire().apply { extension = samplePatientRegisterQuestionnaire.extension } val questionnaireResponse = extractionQuestionnaireResponse() val actionParameters = emptyList() + coEvery { defaultRepository.applyDbTransaction(any()) } answers + { + runBlocking { (firstArg() as suspend () -> Unit).invoke() } + } val onSuccessfulSubmission = spyk({ idsTypes: List, _: QuestionnaireResponse -> Timber.i(idsTypes.toString()) }) coEvery { @@ -326,7 +329,7 @@ class QuestionnaireViewModelTest : RobolectricTest() { // TODO Write integration test for QuestionnaireActivity to compliment this unit test; @Test - fun testHandleQuestionnaireSubmission() { + fun testHandleQuestionnaireSubmission() = runTest { mockkObject(ResourceMapper) val questionnaire = extractionQuestionnaire().apply { @@ -360,6 +363,10 @@ class QuestionnaireViewModelTest : RobolectricTest() { ResourceNotFoundException("QuestionnaireResponse", "") coEvery { fhirEngine.create(resource = anyVararg()) } returns listOf(patient.logicalId) coEvery { fhirEngine.update(resource = anyVararg()) } just runs + coEvery { defaultRepository.applyDbTransaction(any()) } answers + { + runBlocking { (firstArg() as suspend () -> Unit).invoke() } + } // Mock returned bundle after extraction refer to FhirExtractionTest.kt for extraction test coEvery { @@ -658,6 +665,7 @@ class QuestionnaireViewModelTest : RobolectricTest() { questionnaireViewModel.retrieveQuestionnaire( questionnaireConfig = questionnaireConfig, ) + Assert.assertEquals( samplePatientRegisterQuestionnaire.idPart, contentCache.getResource(ResourceType.Questionnaire, questionnaireConfig.id)?.idPart, @@ -701,8 +709,10 @@ class QuestionnaireViewModelTest : RobolectricTest() { configurationRegistry = configurationRegistry, ) val patientAgeLinkId = "patient-age" + val newQuestionnaireId = "new-${questionnaireConfig.id}" val newQuestionnaireConfig = questionnaireConfig.copy( + id = newQuestionnaireId, resourceIdentifier = patient.id, resourceType = patient.resourceType, barcodeLinkId = "patient-barcode", @@ -724,6 +734,7 @@ class QuestionnaireViewModelTest : RobolectricTest() { ) coEvery { fhirEngine.get(ResourceType.Questionnaire, newQuestionnaireConfig.id) } returns samplePatientRegisterQuestionnaire.apply { + id = newQuestionnaireId addItem( Questionnaire.QuestionnaireItemComponent().apply { linkId = patientAgeLinkId diff --git a/package-lock.json b/package-lock.json index 5ab3c1b29b..a432454fee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7433,9 +7433,9 @@ } }, "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", "dependencies": { "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", diff --git a/yarn.lock b/yarn.lock index 8aa25bccf1..30ed6c20c6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4614,9 +4614,9 @@ http-parser-js@>=0.5.1: integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== http-proxy-middleware@^2.0.3: - version "2.0.6" - resolved "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz" - integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== + version "2.0.7" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz#915f236d92ae98ef48278a95dedf17e991936ec6" + integrity sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA== dependencies: "@types/http-proxy" "^1.17.8" http-proxy "^1.18.1"