From 9dda84558fbfa69481c89d3b119cf0dd968edd5a Mon Sep 17 00:00:00 2001 From: chungwwei Date: Tue, 31 Dec 2024 21:06:38 -0500 Subject: [PATCH 1/8] Include min and max values in the validation message in a number question if the values are in the extension --- .../EditTextIntegerViewHolderFactory.kt | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/EditTextIntegerViewHolderFactory.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/EditTextIntegerViewHolderFactory.kt index f619802494..bcdbf4090d 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/EditTextIntegerViewHolderFactory.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/EditTextIntegerViewHolderFactory.kt @@ -24,6 +24,8 @@ import android.text.InputType import androidx.annotation.RequiresApi import com.google.android.fhir.datacapture.R import com.google.android.fhir.datacapture.extensions.getValidationErrorMessage +import com.google.android.fhir.datacapture.validation.MAX_VALUE_EXTENSION_URL +import com.google.android.fhir.datacapture.validation.MIN_VALUE_EXTENSION_URL import com.google.android.fhir.datacapture.views.QuestionnaireViewItem import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputLayout @@ -38,6 +40,22 @@ internal object EditTextIntegerViewHolderFactory : QuestionnaireItemEditTextViewHolderDelegate( InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_SIGNED, ) { + + private val minValue: Int by lazy { + getExtensionValueOrDefault(MIN_VALUE_EXTENSION_URL, Int.MIN_VALUE) + } + + private val maxValue: Int by lazy { + getExtensionValueOrDefault(MAX_VALUE_EXTENSION_URL, Int.MAX_VALUE) + } + + private fun getExtensionValueOrDefault(url: String, defaultValue: Int): Int { + return questionnaireViewItem.questionnaireItem.extension + .find { it.url == url } + ?.let { (it.value as? IntegerType)?.value } + ?: defaultValue + } + override suspend fun handleInput( editable: Editable, questionnaireViewItem: QuestionnaireViewItem, @@ -95,8 +113,8 @@ internal object EditTextIntegerViewHolderFactory : textInputLayout.error = textInputLayout.context.getString( R.string.integer_format_validation_error_msg, - formatInteger(Int.MIN_VALUE), - formatInteger(Int.MAX_VALUE), + formatInteger(minValue), + formatInteger(maxValue), ) } } From 9bf3bb7fe8c5cd4ea23980afe0e7f262e3518147 Mon Sep 17 00:00:00 2001 From: chungwwei Date: Thu, 9 Jan 2025 05:00:03 -0500 Subject: [PATCH 2/8] Use the min and max values in questionnaireItem --- .../EditTextIntegerViewHolderFactory.kt | 27 +++++++------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/EditTextIntegerViewHolderFactory.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/EditTextIntegerViewHolderFactory.kt index bcdbf4090d..34c5e2401f 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/EditTextIntegerViewHolderFactory.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/EditTextIntegerViewHolderFactory.kt @@ -1,5 +1,5 @@ /* - * Copyright 2022-2024 Google LLC + * Copyright 2022-2025 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,8 +24,8 @@ import android.text.InputType import androidx.annotation.RequiresApi import com.google.android.fhir.datacapture.R import com.google.android.fhir.datacapture.extensions.getValidationErrorMessage -import com.google.android.fhir.datacapture.validation.MAX_VALUE_EXTENSION_URL -import com.google.android.fhir.datacapture.validation.MIN_VALUE_EXTENSION_URL +import com.google.android.fhir.datacapture.extensions.maxValue +import com.google.android.fhir.datacapture.extensions.minValue import com.google.android.fhir.datacapture.views.QuestionnaireViewItem import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputLayout @@ -41,21 +41,6 @@ internal object EditTextIntegerViewHolderFactory : InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_SIGNED, ) { - private val minValue: Int by lazy { - getExtensionValueOrDefault(MIN_VALUE_EXTENSION_URL, Int.MIN_VALUE) - } - - private val maxValue: Int by lazy { - getExtensionValueOrDefault(MAX_VALUE_EXTENSION_URL, Int.MAX_VALUE) - } - - private fun getExtensionValueOrDefault(url: String, defaultValue: Int): Int { - return questionnaireViewItem.questionnaireItem.extension - .find { it.url == url } - ?.let { (it.value as? IntegerType)?.value } - ?: defaultValue - } - override suspend fun handleInput( editable: Editable, questionnaireViewItem: QuestionnaireViewItem, @@ -108,6 +93,12 @@ internal object EditTextIntegerViewHolderFactory : questionnaireViewItem, questionnaireViewItem.validationResult, ) + + val minValue = + (questionnaireViewItem.questionnaireItem.minValue as? IntegerType)?.value ?: Int.MIN_VALUE + val maxValue = + (questionnaireViewItem.questionnaireItem.maxValue as? IntegerType)?.value ?: Int.MAX_VALUE + // Update error message if draft answer present if (questionnaireViewItem.draftAnswer != null) { textInputLayout.error = From d3292f21ae83157ea41529f35f01df43b3fe163e Mon Sep 17 00:00:00 2001 From: chungwwei Date: Thu, 9 Jan 2025 05:21:03 -0500 Subject: [PATCH 3/8] Use the fields in questionnaireViewItem and remove imports --- .../views/factories/EditTextIntegerViewHolderFactory.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/EditTextIntegerViewHolderFactory.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/EditTextIntegerViewHolderFactory.kt index 34c5e2401f..f073bb2696 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/EditTextIntegerViewHolderFactory.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/EditTextIntegerViewHolderFactory.kt @@ -24,8 +24,6 @@ import android.text.InputType import androidx.annotation.RequiresApi import com.google.android.fhir.datacapture.R import com.google.android.fhir.datacapture.extensions.getValidationErrorMessage -import com.google.android.fhir.datacapture.extensions.maxValue -import com.google.android.fhir.datacapture.extensions.minValue import com.google.android.fhir.datacapture.views.QuestionnaireViewItem import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputLayout @@ -95,9 +93,9 @@ internal object EditTextIntegerViewHolderFactory : ) val minValue = - (questionnaireViewItem.questionnaireItem.minValue as? IntegerType)?.value ?: Int.MIN_VALUE + (questionnaireViewItem.minAnswerValue as? IntegerType)?.value ?: Int.MIN_VALUE val maxValue = - (questionnaireViewItem.questionnaireItem.maxValue as? IntegerType)?.value ?: Int.MAX_VALUE + (questionnaireViewItem.maxAnswerValue as? IntegerType)?.value ?: Int.MAX_VALUE // Update error message if draft answer present if (questionnaireViewItem.draftAnswer != null) { From f0fde4b8499c867c1a0e1ff1f69ef7678342cfcc Mon Sep 17 00:00:00 2001 From: chungwwei Date: Thu, 16 Jan 2025 08:26:08 -0500 Subject: [PATCH 4/8] Throw IllegalArgumentException when minValue is larger than maxValue --- .../factories/EditTextIntegerViewHolderFactory.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/EditTextIntegerViewHolderFactory.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/EditTextIntegerViewHolderFactory.kt index f073bb2696..1811d39667 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/EditTextIntegerViewHolderFactory.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/EditTextIntegerViewHolderFactory.kt @@ -39,6 +39,17 @@ internal object EditTextIntegerViewHolderFactory : InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_SIGNED, ) { + override fun bind(questionnaireViewItem: QuestionnaireViewItem) { + super.bind(questionnaireViewItem) + + val minValue = (questionnaireViewItem.minAnswerValue as? IntegerType)?.value + val maxValue = (questionnaireViewItem.maxAnswerValue as? IntegerType)?.value + + if (minValue != null && maxValue != null && minValue > maxValue) { + throw IllegalArgumentException("minValue cannot be greater than maxValue") + } + } + override suspend fun handleInput( editable: Editable, questionnaireViewItem: QuestionnaireViewItem, From 45d4416d4be32d9c7df6225af2d177017196caaf Mon Sep 17 00:00:00 2001 From: chungwwei Date: Thu, 6 Feb 2025 18:09:48 -0500 Subject: [PATCH 5/8] Hoist check to viewmodel --- .../datacapture/QuestionnaireViewModel.kt | 29 ++++++++++++++++++- .../EditTextIntegerViewHolderFactory.kt | 12 -------- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/QuestionnaireViewModel.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/QuestionnaireViewModel.kt index ecc019b0a8..734de3b202 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/QuestionnaireViewModel.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/QuestionnaireViewModel.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Google LLC + * Copyright 2023-2025 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ import androidx.lifecycle.viewModelScope import ca.uhn.fhir.context.FhirContext import ca.uhn.fhir.context.FhirVersionEnum import ca.uhn.fhir.parser.IParser +import com.google.android.fhir.compareTo import com.google.android.fhir.datacapture.enablement.EnablementEvaluator import com.google.android.fhir.datacapture.expressions.EnabledAnswerOptionsEvaluator import com.google.android.fhir.datacapture.extensions.EntryMode @@ -77,12 +78,16 @@ import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.withIndex import kotlinx.coroutines.launch import org.hl7.fhir.r4.model.DateTimeType +import org.hl7.fhir.r4.model.DateType +import org.hl7.fhir.r4.model.DecimalType +import org.hl7.fhir.r4.model.IntegerType import org.hl7.fhir.r4.model.Questionnaire import org.hl7.fhir.r4.model.Questionnaire.QuestionnaireItemComponent import org.hl7.fhir.r4.model.QuestionnaireResponse import org.hl7.fhir.r4.model.QuestionnaireResponse.QuestionnaireResponseItemAnswerComponent import org.hl7.fhir.r4.model.QuestionnaireResponse.QuestionnaireResponseItemComponent import org.hl7.fhir.r4.model.Resource +import org.hl7.fhir.r4.model.Type import timber.log.Timber internal class QuestionnaireViewModel(application: Application, state: SavedStateHandle) : @@ -204,7 +209,9 @@ internal class QuestionnaireViewModel(application: Application, state: SavedStat item: QuestionnaireItemComponent, questionnaireItemToParentMap: ItemToParentMap, ) { + CheckMinAndMaxExtensionValues(item.minValue, item.maxValue) for (child in item.item) { + CheckMinAndMaxExtensionValues(child.minValue, child.maxValue) questionnaireItemToParentMap[child] = item buildParentList(child, questionnaireItemToParentMap) } @@ -485,6 +492,10 @@ internal class QuestionnaireViewModel(application: Application, state: SavedStat } } + // fun validateMinvalueExtensionAndMaxValueExtension() { + // questionnaire. + // } + /** Clears all the answers from the questionnaire response by iterating through each item. */ fun clearAllAnswers() { questionnaireResponse.allItems.forEach { it.answer = emptyList() } @@ -1141,6 +1152,22 @@ internal class QuestionnaireViewModel(application: Application, state: SavedStat block() } } + + private fun CheckMinAndMaxExtensionValues(minValue: Type?, maxValue: Type?) { + if (minValue == null || maxValue == null) { + return + } + if ( + (minValue is IntegerType && maxValue is IntegerType) || + (minValue is DecimalType && maxValue is DecimalType) || + (minValue is DateType && maxValue is DateType) || + (minValue is DateTimeType && maxValue is DateTimeType) + ) { + if (minValue > maxValue) { + throw IllegalArgumentException("minValue cannot be greater than maxValue") + } + } + } } typealias ItemToParentMap = MutableMap diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/EditTextIntegerViewHolderFactory.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/EditTextIntegerViewHolderFactory.kt index 1811d39667..6d0bcf9c52 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/EditTextIntegerViewHolderFactory.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/EditTextIntegerViewHolderFactory.kt @@ -39,17 +39,6 @@ internal object EditTextIntegerViewHolderFactory : InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_SIGNED, ) { - override fun bind(questionnaireViewItem: QuestionnaireViewItem) { - super.bind(questionnaireViewItem) - - val minValue = (questionnaireViewItem.minAnswerValue as? IntegerType)?.value - val maxValue = (questionnaireViewItem.maxAnswerValue as? IntegerType)?.value - - if (minValue != null && maxValue != null && minValue > maxValue) { - throw IllegalArgumentException("minValue cannot be greater than maxValue") - } - } - override suspend fun handleInput( editable: Editable, questionnaireViewItem: QuestionnaireViewItem, @@ -102,7 +91,6 @@ internal object EditTextIntegerViewHolderFactory : questionnaireViewItem, questionnaireViewItem.validationResult, ) - val minValue = (questionnaireViewItem.minAnswerValue as? IntegerType)?.value ?: Int.MIN_VALUE val maxValue = From 33232fbde46724cff1ad7696b76d2f7164a4b23f Mon Sep 17 00:00:00 2001 From: chungwwei Date: Thu, 6 Feb 2025 18:12:07 -0500 Subject: [PATCH 6/8] Remove comments --- .../google/android/fhir/datacapture/QuestionnaireViewModel.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/QuestionnaireViewModel.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/QuestionnaireViewModel.kt index 734de3b202..4b390b548a 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/QuestionnaireViewModel.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/QuestionnaireViewModel.kt @@ -492,9 +492,6 @@ internal class QuestionnaireViewModel(application: Application, state: SavedStat } } - // fun validateMinvalueExtensionAndMaxValueExtension() { - // questionnaire. - // } /** Clears all the answers from the questionnaire response by iterating through each item. */ fun clearAllAnswers() { From 38e0b030e00a6586e47132c5eb744b9484beaf2d Mon Sep 17 00:00:00 2001 From: chungwwei Date: Fri, 7 Feb 2025 00:56:51 -0500 Subject: [PATCH 7/8] Add tests and remove checks at individual widgets --- .../datacapture/QuestionnaireViewModel.kt | 8 +- .../factories/DatePickerViewHolderFactory.kt | 6 +- .../factories/SliderViewHolderFactory.kt | 5 +- .../datacapture/QuestionnaireViewModelTest.kt | 92 ++++++++++++++++++- .../factories/SliderViewHolderFactoryTest.kt | 26 +----- 5 files changed, 97 insertions(+), 40 deletions(-) diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/QuestionnaireViewModel.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/QuestionnaireViewModel.kt index 4b390b548a..d04d590f09 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/QuestionnaireViewModel.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/QuestionnaireViewModel.kt @@ -209,14 +209,13 @@ internal class QuestionnaireViewModel(application: Application, state: SavedStat item: QuestionnaireItemComponent, questionnaireItemToParentMap: ItemToParentMap, ) { - CheckMinAndMaxExtensionValues(item.minValue, item.maxValue) + checkMinAndMaxExtensionValues(item.minValue, item.maxValue) for (child in item.item) { - CheckMinAndMaxExtensionValues(child.minValue, child.maxValue) + checkMinAndMaxExtensionValues(child.minValue, child.maxValue) questionnaireItemToParentMap[child] = item buildParentList(child, questionnaireItemToParentMap) } } - questionnaireItemParentMap = buildMap { for (item in questionnaire.item) { buildParentList(item, this) @@ -492,7 +491,6 @@ internal class QuestionnaireViewModel(application: Application, state: SavedStat } } - /** Clears all the answers from the questionnaire response by iterating through each item. */ fun clearAllAnswers() { questionnaireResponse.allItems.forEach { it.answer = emptyList() } @@ -1150,7 +1148,7 @@ internal class QuestionnaireViewModel(application: Application, state: SavedStat } } - private fun CheckMinAndMaxExtensionValues(minValue: Type?, maxValue: Type?) { + private fun checkMinAndMaxExtensionValues(minValue: Type?, maxValue: Type?) { if (minValue == null || maxValue == null) { return } diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/DatePickerViewHolderFactory.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/DatePickerViewHolderFactory.kt index 8d65eddea2..aff706052b 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/DatePickerViewHolderFactory.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/DatePickerViewHolderFactory.kt @@ -1,5 +1,5 @@ /* - * Copyright 2022-2024 Google LLC + * Copyright 2022-2025 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -169,10 +169,6 @@ internal object DatePickerViewHolderFactory : val min = (questionnaireViewItem.minAnswerValue as? DateType)?.value?.time val max = (questionnaireViewItem.maxAnswerValue as? DateType)?.value?.time - if (min != null && max != null && min > max) { - throw IllegalArgumentException("minValue cannot be greater than maxValue") - } - val listValidators = ArrayList() min?.let { listValidators.add(DateValidatorPointForward.from(it)) } max?.let { listValidators.add(DateValidatorPointBackward.before(it)) } diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/SliderViewHolderFactory.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/SliderViewHolderFactory.kt index eaec4454e4..a101250cf5 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/SliderViewHolderFactory.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/SliderViewHolderFactory.kt @@ -1,5 +1,5 @@ /* - * Copyright 2022-2024 Google LLC + * Copyright 2022-2025 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,9 +58,6 @@ internal object SliderViewHolderFactory : QuestionnaireItemViewHolderFactory(R.l val answer = questionnaireViewItem.answers.singleOrNull() val minValue = getMinValue(questionnaireViewItem.minAnswerValue) val maxValue = getMaxValue(questionnaireViewItem.maxAnswerValue) - if (minValue >= maxValue) { - throw IllegalStateException("minValue $minValue must be smaller than maxValue $maxValue") - } with(slider) { clearOnChangeListeners() diff --git a/datacapture/src/test/java/com/google/android/fhir/datacapture/QuestionnaireViewModelTest.kt b/datacapture/src/test/java/com/google/android/fhir/datacapture/QuestionnaireViewModelTest.kt index 659429a95a..b53308e1f6 100644 --- a/datacapture/src/test/java/com/google/android/fhir/datacapture/QuestionnaireViewModelTest.kt +++ b/datacapture/src/test/java/com/google/android/fhir/datacapture/QuestionnaireViewModelTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Google LLC + * Copyright 2023-2025 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -86,7 +86,9 @@ import org.hl7.fhir.r4.model.BooleanType import org.hl7.fhir.r4.model.CodeType import org.hl7.fhir.r4.model.CodeableConcept import org.hl7.fhir.r4.model.Coding +import org.hl7.fhir.r4.model.DateTimeType import org.hl7.fhir.r4.model.DateType +import org.hl7.fhir.r4.model.DecimalType import org.hl7.fhir.r4.model.Enumerations import org.hl7.fhir.r4.model.Expression import org.hl7.fhir.r4.model.Extension @@ -228,6 +230,94 @@ class QuestionnaireViewModelTest { } } + @Test + fun `should throw exception if minValue is greater than maxValue for integer type`() { + val questionnaire = + Questionnaire().apply { + addItem().apply { + type = Questionnaire.QuestionnaireItemType.INTEGER + addExtension().apply { + url = MIN_VALUE_EXTENSION_URL + setValue(IntegerType(10)) + } + addExtension().apply { + url = MAX_VALUE_EXTENSION_URL + setValue(IntegerType(1)) + } + } + } + val errorMessage = + assertFailsWith { createQuestionnaireViewModel(questionnaire) } + .localizedMessage + assertThat(errorMessage).isEqualTo("minValue cannot be greater than maxValue") + } + + @Test + fun `should throw exception if minValue is greater than maxValue for decimal type`() { + val questionnaire = + Questionnaire().apply { + addItem().apply { + type = Questionnaire.QuestionnaireItemType.INTEGER + addExtension().apply { + url = MIN_VALUE_EXTENSION_URL + setValue(DecimalType(10.0)) + } + addExtension().apply { + url = MAX_VALUE_EXTENSION_URL + setValue(DecimalType(1.5)) + } + } + } + val errorMessage = + assertFailsWith { createQuestionnaireViewModel(questionnaire) } + .localizedMessage + assertThat(errorMessage).isEqualTo("minValue cannot be greater than maxValue") + } + + @Test + fun `should throw exception if minValue is greater than maxValue for datetime type`() { + val questionnaire = + Questionnaire().apply { + addItem().apply { + type = Questionnaire.QuestionnaireItemType.DATETIME + addExtension().apply { + url = MIN_VALUE_EXTENSION_URL + setValue(DateTimeType("2020-01-01T00:00:00Z")) + } + addExtension().apply { + url = MAX_VALUE_EXTENSION_URL + setValue(DateTimeType("2019-01-01T00:00:00Z")) + } + } + } + val errorMessage = + assertFailsWith { createQuestionnaireViewModel(questionnaire) } + .localizedMessage + assertThat(errorMessage).isEqualTo("minValue cannot be greater than maxValue") + } + + @Test + fun `should throw exception if minValue is greater than maxValue for date type`() { + val questionnaire = + Questionnaire().apply { + addItem().apply { + type = Questionnaire.QuestionnaireItemType.DATE + addExtension().apply { + url = MIN_VALUE_EXTENSION_URL + setValue(DateType("2020-01-01")) + } + addExtension().apply { + url = MAX_VALUE_EXTENSION_URL + setValue(DateType("2019-01-01")) + } + } + } + val errorMessage = + assertFailsWith { createQuestionnaireViewModel(questionnaire) } + .localizedMessage + assertThat(errorMessage).isEqualTo("minValue cannot be greater than maxValue") + } + @Test fun `should copy nested questions if no response is provided`() { val questionnaire = diff --git a/datacapture/src/test/java/com/google/android/fhir/datacapture/views/factories/SliderViewHolderFactoryTest.kt b/datacapture/src/test/java/com/google/android/fhir/datacapture/views/factories/SliderViewHolderFactoryTest.kt index 33195746bf..f2c5073ebc 100644 --- a/datacapture/src/test/java/com/google/android/fhir/datacapture/views/factories/SliderViewHolderFactoryTest.kt +++ b/datacapture/src/test/java/com/google/android/fhir/datacapture/views/factories/SliderViewHolderFactoryTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Google LLC + * Copyright 2023-2025 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +31,6 @@ import com.google.android.fhir.datacapture.views.QuestionTextConfiguration import com.google.android.fhir.datacapture.views.QuestionnaireViewItem import com.google.android.material.slider.Slider import com.google.common.truth.Truth.assertThat -import kotlin.test.assertFailsWith import org.hl7.fhir.r4.model.CodeableConcept import org.hl7.fhir.r4.model.Coding import org.hl7.fhir.r4.model.Extension @@ -185,29 +184,6 @@ class SliderViewHolderFactoryTest { assertThat(viewHolder.itemView.findViewById(R.id.slider).valueFrom).isEqualTo(0.0F) } - @Test - fun `throws exception if minValue is greater than maxvalue`() { - assertFailsWith { - viewHolder.bind( - QuestionnaireViewItem( - Questionnaire.QuestionnaireItemComponent().apply { - addExtension().apply { - url = "http://hl7.org/fhir/StructureDefinition/minValue" - setValue(IntegerType("100")) - } - addExtension().apply { - url = "http://hl7.org/fhir/StructureDefinition/maxValue" - setValue(IntegerType("50")) - } - }, - QuestionnaireResponse.QuestionnaireResponseItemComponent(), - validationResult = NotValidated, - answersChangedCallback = { _, _, _, _ -> }, - ), - ) - } - } - @Test fun shouldSetQuestionnaireResponseSliderAnswer() { var answerHolder: List? = null From 9f545cc40a7eb9780e19b6671fbd123a596101b9 Mon Sep 17 00:00:00 2001 From: chungwwei Date: Fri, 7 Feb 2025 02:06:54 -0500 Subject: [PATCH 8/8] Remove redundant call --- .../google/android/fhir/datacapture/QuestionnaireViewModel.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/QuestionnaireViewModel.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/QuestionnaireViewModel.kt index d04d590f09..878e6aa0e7 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/QuestionnaireViewModel.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/QuestionnaireViewModel.kt @@ -211,7 +211,6 @@ internal class QuestionnaireViewModel(application: Application, state: SavedStat ) { checkMinAndMaxExtensionValues(item.minValue, item.maxValue) for (child in item.item) { - checkMinAndMaxExtensionValues(child.minValue, child.maxValue) questionnaireItemToParentMap[child] = item buildParentList(child, questionnaireItemToParentMap) }