From 29f8eb83c24a6efca0bf78fdc249e7cd7de281a3 Mon Sep 17 00:00:00 2001 From: Rkareko Date: Tue, 4 Mar 2025 12:50:01 +0300 Subject: [PATCH 1/3] Restrict editing of QuestionnaireResopnse to when saving draft is enabled --- .../quest/ui/questionnaire/QuestionnaireViewModel.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) 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 bf8c395ef6..61d88c2f27 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 @@ -1208,7 +1208,13 @@ constructor( ) ?.let { QuestionnaireResponse().apply { - id = it.id + /** + * Only set the ID value when [saveDraft] is set to true] this ensues that a new + * [QuestionnaireResponse] is generated when the questionnaire is submitted + */ + if (questionnaireConfig.saveDraft) { + id = it.id + } status = it.status item = it.item.removeUnAnsweredItems() // Clearing the text prompts the SDK to re-process the content, which includes HTML From 9118f8e26bce419472bdffa7b5cc85b29b8a622d Mon Sep 17 00:00:00 2001 From: Rkareko Date: Tue, 4 Mar 2025 13:18:31 +0300 Subject: [PATCH 2/3] Add tests --- .../QuestionnaireViewModelTest.kt | 235 ++++++++++++------ 1 file changed, 163 insertions(+), 72 deletions(-) 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 d94487be95..cd04c831f7 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 @@ -2171,85 +2171,176 @@ class QuestionnaireViewModelTest : RobolectricTest() { } @Test - fun testThatPopulateQuestionnaireReturnsQuestionnaireResponseWithIdValue() = runTest { - val questionnaireViewModelInstance = - QuestionnaireViewModel( - defaultRepository = defaultRepository, - dispatcherProvider = dispatcherProvider, - fhirCarePlanGenerator = fhirCarePlanGenerator, - rulesExecutor = rulesExecutor, - transformSupportServices = mockk(), - sharedPreferencesHelper = sharedPreferencesHelper, - fhirOperator = fhirOperator, - fhirValidatorRequestHandlerProvider = fhirValidatorRequestHandlerProvider, - fhirPathDataExtractor = fhirPathDataExtractor, - configurationRegistry = configurationRegistry, - ) - val questionnaireConfig1 = - questionnaireConfig.copy( - resourceType = ResourceType.Patient, - resourceIdentifier = patient.logicalId, - type = QuestionnaireType.EDIT.name, - ) + fun testThatPopulateQuestionnaireReturnsQuestionnaireResponseWithIdValueWhenSaveDraftIsTrue() = + runTest { + val questionnaireViewModelInstance = + QuestionnaireViewModel( + defaultRepository = defaultRepository, + dispatcherProvider = dispatcherProvider, + fhirCarePlanGenerator = fhirCarePlanGenerator, + rulesExecutor = rulesExecutor, + transformSupportServices = mockk(), + sharedPreferencesHelper = sharedPreferencesHelper, + fhirOperator = fhirOperator, + fhirValidatorRequestHandlerProvider = fhirValidatorRequestHandlerProvider, + fhirPathDataExtractor = fhirPathDataExtractor, + configurationRegistry = configurationRegistry, + ) + val questionnaireConfig1 = + questionnaireConfig.copy( + resourceType = ResourceType.Patient, + resourceIdentifier = patient.logicalId, + type = QuestionnaireType.EDIT.name, + saveDraft = true, + ) - val questionnaireWithInitialValue = - Questionnaire().apply { - id = questionnaireConfig1.id - addItem( - QuestionnaireItemComponent().apply { - linkId = "group-1" - type = Questionnaire.QuestionnaireItemType.GROUP - addItem( - QuestionnaireItemComponent().apply { - linkId = "linkid-1" - type = Questionnaire.QuestionnaireItemType.STRING - addInitial(Questionnaire.QuestionnaireItemInitialComponent(StringType("---"))) - }, - ) - }, + val questionnaireWithInitialValue = + Questionnaire().apply { + id = questionnaireConfig1.id + addItem( + QuestionnaireItemComponent().apply { + linkId = "group-1" + type = Questionnaire.QuestionnaireItemType.GROUP + addItem( + QuestionnaireItemComponent().apply { + linkId = "linkid-1" + type = Questionnaire.QuestionnaireItemType.STRING + addInitial(Questionnaire.QuestionnaireItemInitialComponent(StringType("---"))) + }, + ) + }, + ) + + addItem( + QuestionnaireItemComponent().apply { + linkId = "linkid-2" + type = Questionnaire.QuestionnaireItemType.STRING + }, + ) + } + val qrId = "qr-id-1" + val questionnaireResponse = + QuestionnaireResponse().apply { + id = qrId + addItem( + QuestionnaireResponse.QuestionnaireResponseItemComponent().apply { + linkId = "group-1" + addItem( + QuestionnaireResponse.QuestionnaireResponseItemComponent().apply { + linkId = "linkid-1" + }, + ) + }, + ) + } + coEvery { + fhirEngine.get( + questionnaireConfig1.resourceType!!, + questionnaireConfig1.resourceIdentifier!! ) + } returns patient - addItem( - QuestionnaireItemComponent().apply { - linkId = "linkid-2" - type = Questionnaire.QuestionnaireItemType.STRING - }, + coEvery { fhirEngine.search(any()) } returns + listOf( + SearchResult(questionnaireResponse, included = null, revIncluded = null), ) - } - val qrId = "qr-id-1" - val questionnaireResponse = - QuestionnaireResponse().apply { - id = qrId - addItem( - QuestionnaireResponse.QuestionnaireResponseItemComponent().apply { - linkId = "group-1" - addItem( - QuestionnaireResponse.QuestionnaireResponseItemComponent().apply { - linkId = "linkid-1" - }, - ) - }, + + Assert.assertNotNull(questionnaireResponse.find("linkid-1")) + val result = + questionnaireViewModelInstance.populateQuestionnaire( + questionnaireWithInitialValue, + questionnaireConfig1, + emptyList(), ) - } - coEvery { - fhirEngine.get(questionnaireConfig1.resourceType!!, questionnaireConfig1.resourceIdentifier!!) - } returns patient + Assert.assertNotNull(result.first) + Assert.assertEquals(qrId, result.first!!.id) + } - coEvery { fhirEngine.search(any()) } returns - listOf( - SearchResult(questionnaireResponse, included = null, revIncluded = null), - ) + @Test + fun testThatPopulateQuestionnaireReturnsQuestionnaireResponseWithoutIdValueWhenSaveDraftIsFalse() = + runTest { + val questionnaireViewModelInstance = + QuestionnaireViewModel( + defaultRepository = defaultRepository, + dispatcherProvider = dispatcherProvider, + fhirCarePlanGenerator = fhirCarePlanGenerator, + rulesExecutor = rulesExecutor, + transformSupportServices = mockk(), + sharedPreferencesHelper = sharedPreferencesHelper, + fhirOperator = fhirOperator, + fhirValidatorRequestHandlerProvider = fhirValidatorRequestHandlerProvider, + fhirPathDataExtractor = fhirPathDataExtractor, + configurationRegistry = configurationRegistry, + ) + val questionnaireConfig1 = + questionnaireConfig.copy( + resourceType = ResourceType.Patient, + resourceIdentifier = patient.logicalId, + type = QuestionnaireType.EDIT.name, + saveDraft = false, + ) - Assert.assertNotNull(questionnaireResponse.find("linkid-1")) - val result = - questionnaireViewModelInstance.populateQuestionnaire( - questionnaireWithInitialValue, - questionnaireConfig1, - emptyList(), - ) - Assert.assertNotNull(result.first) - Assert.assertEquals(qrId, result.first!!.id) - } + val questionnaireWithInitialValue = + Questionnaire().apply { + id = questionnaireConfig1.id + addItem( + QuestionnaireItemComponent().apply { + linkId = "group-1" + type = Questionnaire.QuestionnaireItemType.GROUP + addItem( + QuestionnaireItemComponent().apply { + linkId = "linkid-1" + type = Questionnaire.QuestionnaireItemType.STRING + addInitial(Questionnaire.QuestionnaireItemInitialComponent(StringType("---"))) + }, + ) + }, + ) + + addItem( + QuestionnaireItemComponent().apply { + linkId = "linkid-2" + type = Questionnaire.QuestionnaireItemType.STRING + }, + ) + } + val qrId = "qr-id-1" + val questionnaireResponse = + QuestionnaireResponse().apply { + id = qrId + addItem( + QuestionnaireResponse.QuestionnaireResponseItemComponent().apply { + linkId = "group-1" + addItem( + QuestionnaireResponse.QuestionnaireResponseItemComponent().apply { + linkId = "linkid-1" + }, + ) + }, + ) + } + coEvery { + fhirEngine.get( + questionnaireConfig1.resourceType!!, + questionnaireConfig1.resourceIdentifier!! + ) + } returns patient + + coEvery { fhirEngine.search(any()) } returns + listOf( + SearchResult(questionnaireResponse, included = null, revIncluded = null), + ) + + Assert.assertNotNull(questionnaireResponse.find("linkid-1")) + val result = + questionnaireViewModelInstance.populateQuestionnaire( + questionnaireWithInitialValue, + questionnaireConfig1, + emptyList(), + ) + Assert.assertNotNull(result.first) + Assert.assertNull(result.first?.id) + } @Test fun testProcessRepeatGroupItems() { From e79f3d5836ea1c2e26a48b235a0a34ee2c9fc83e Mon Sep 17 00:00:00 2001 From: Rkareko Date: Tue, 4 Mar 2025 13:54:59 +0300 Subject: [PATCH 3/3] Run spotless Apply --- .../quest/ui/questionnaire/QuestionnaireViewModelTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 cd04c831f7..f9e84ee150 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 @@ -2236,7 +2236,7 @@ class QuestionnaireViewModelTest : RobolectricTest() { coEvery { fhirEngine.get( questionnaireConfig1.resourceType!!, - questionnaireConfig1.resourceIdentifier!! + questionnaireConfig1.resourceIdentifier!!, ) } returns patient @@ -2322,7 +2322,7 @@ class QuestionnaireViewModelTest : RobolectricTest() { coEvery { fhirEngine.get( questionnaireConfig1.resourceType!!, - questionnaireConfig1.resourceIdentifier!! + questionnaireConfig1.resourceIdentifier!!, ) } returns patient