Skip to content

Commit

Permalink
Support Stringtype, Integertype as answer option type when item type …
Browse files Browse the repository at this point in the history
…is choice. (#1399)

* Support stringtype, Integertype as answeroption type.

* Remove commented code.

* Address review comments.

* Update changes in when clause.

* Address review comments.

Co-authored-by: Santosh Pingle <spingle@google.com>
  • Loading branch information
santosh-pingle and Santosh Pingle authored Jul 1, 2022
1 parent be98cd5 commit 63fc76f
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,34 @@ package com.google.android.fhir.datacapture

import com.google.android.fhir.getLocalizedText
import org.hl7.fhir.r4.model.BooleanType
import org.hl7.fhir.r4.model.Coding
import org.hl7.fhir.r4.model.DateType
import org.hl7.fhir.r4.model.IntegerType
import org.hl7.fhir.r4.model.Questionnaire
import org.hl7.fhir.r4.model.StringType
import org.hl7.fhir.r4.model.TimeType

internal const val EXTENSION_OPTION_EXCLUSIVE_URL =
"http://hl7.org/fhir/StructureDefinition/questionnaire-optionExclusive"

val Questionnaire.QuestionnaireItemAnswerOptionComponent.displayString: String
/**
* Text value for answer option [Questionnaire.QuestionnaireItemAnswerOptionComponent] if answer
* option is [IntegerType] or [StringType] or [Coding] type.
*/
internal val Questionnaire.QuestionnaireItemAnswerOptionComponent.displayString: String
get() {
if (!hasValueCoding()) {
throw IllegalArgumentException("Answer option does not having coding.")
}
val display = valueCoding.displayElement.getLocalizedText() ?: valueCoding.display
return if (display.isNullOrEmpty()) {
valueCoding.code
} else {
display
return when (value) {
is IntegerType, is DateType, is TimeType -> value.primitiveValue()
is StringType -> (value as StringType).getLocalizedText() ?: value.toString()
is Coding -> {
val display = valueCoding.displayElement.getLocalizedText() ?: valueCoding.display
if (display.isNullOrEmpty()) {
valueCoding.code
} else {
display
}
}
else -> throw IllegalArgumentException("$value is not supported.")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ internal class QuestionnaireItemAdapter(
}
}

if (questionnaireItemViewItem.answerOption.isNotEmpty()) {
return getChoiceViewHolderType(questionnaireItemViewItem).value
}

return when (val type = questionnaireItem.type) {
QuestionnaireItemType.GROUP -> QuestionnaireItemViewHolderType.GROUP
QuestionnaireItemType.BOOLEAN -> QuestionnaireItemViewHolderType.BOOLEAN_TYPE_PICKER
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import androidx.constraintlayout.widget.ConstraintLayout
import com.google.android.fhir.datacapture.ChoiceOrientationTypes
import com.google.android.fhir.datacapture.R
import com.google.android.fhir.datacapture.choiceOrientation
import com.google.android.fhir.datacapture.displayString
import com.google.android.fhir.datacapture.optionExclusive
import com.google.android.fhir.datacapture.validation.ValidationResult
import com.google.android.fhir.datacapture.validation.getSingleStringValidationMessage
Expand Down Expand Up @@ -101,7 +102,7 @@ internal object QuestionnaireItemCheckBoxGroupViewHolderFactory :
val checkbox =
checkboxLayout.findViewById<CheckBox>(R.id.check_box).apply {
id = viewId
text = answerOption.valueCoding.display
text = answerOption.displayString
isChecked = questionnaireItemViewItem.isAnswerOptionSelected(answerOption)
layoutParams =
ViewGroup.LayoutParams(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ internal object QuestionnaireItemDropDownViewHolderFactory :
} else {
questionnaireItemViewItem.singleAnswerOrNull =
QuestionnaireResponse.QuestionnaireResponseItemAnswerComponent()
.setValue(questionnaireItemViewItem.answerOption[position - 1].valueCoding)
.setValue(questionnaireItemViewItem.answerOption[position - 1].value)
}
onAnswerChanged(autoCompleteTextView.context)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ import kotlin.test.assertFailsWith
import kotlinx.coroutines.runBlocking
import org.hl7.fhir.r4.model.BooleanType
import org.hl7.fhir.r4.model.Coding
import org.hl7.fhir.r4.model.DateType
import org.hl7.fhir.r4.model.Extension
import org.hl7.fhir.r4.model.IntegerType
import org.hl7.fhir.r4.model.Questionnaire
import org.hl7.fhir.r4.model.StringType
import org.hl7.fhir.r4.model.TimeType
import org.hl7.fhir.r4.utils.ToolingExtensions
import org.junit.Test
import org.junit.runner.RunWith
Expand Down Expand Up @@ -60,6 +63,23 @@ class MoreAnswerOptionsTest {
assertFailsWith<IllegalArgumentException> { answerOption.displayString }
}

@Test
fun getDisplayString_integerType_shouldReturnIntegerValue() {
val answerOption =
Questionnaire.QuestionnaireItemAnswerOptionComponent().setValue(IntegerType().setValue(1))

assertThat(answerOption.displayString).isEqualTo("1")
}

@Test
fun getDisplayString_stringType_shouldReturnStringValue() {
val answerOption =
Questionnaire.QuestionnaireItemAnswerOptionComponent()
.setValue(StringType().setValue("string type value"))

assertThat(answerOption.displayString).isEqualTo("string type value")
}

@Test
fun getDisplayString_validExtension_shouldReturnLocalizedText() {
val answerOption =
Expand Down Expand Up @@ -105,6 +125,42 @@ class MoreAnswerOptionsTest {
assertThat(answerOption.displayString).isEqualTo("Test Code")
}

@Test
fun getDisplayString_stringType_validTranslationExtension_shouldReturnLocalizedText() {
val answerOption =
Questionnaire.QuestionnaireItemAnswerOptionComponent().apply {
value =
StringType().apply {
value = "string value"
addExtension(
Extension(ToolingExtensions.EXT_TRANSLATION).apply {
addExtension(Extension("lang", StringType("vi-VN")))
addExtension(Extension("content", StringType("Thí nghiệm")))
}
)
}
}
Locale.setDefault(Locale.forLanguageTag("vi-VN"))

assertThat(answerOption.displayString).isEqualTo("Thí nghiệm")
}

@Test
fun getDisplayString_timeType_shouldReturnTimeValue() {
val answerOption =
Questionnaire.QuestionnaireItemAnswerOptionComponent().setValue(TimeType("16:25:00"))

assertThat(answerOption.displayString).isEqualTo("16:25:00")
}

@Test
fun getDisplayString_dateType_shouldReturnDateValue() {
val answerOption =
Questionnaire.QuestionnaireItemAnswerOptionComponent().setValue(DateType("2022-06-23"))

assertThat(answerOption.displayString).isEqualTo("2022-06-23")
}

@Test
fun optionExclusiveExtension_valueTrue_returnsTrue() = runBlocking {
val answerOptionTest = Coding("test", "option", "1")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@ import com.google.android.fhir.datacapture.views.QuestionnaireItemViewItem
import com.google.common.truth.Truth.assertThat
import org.hl7.fhir.r4.model.CodeableConcept
import org.hl7.fhir.r4.model.Coding
import org.hl7.fhir.r4.model.DateType
import org.hl7.fhir.r4.model.Extension
import org.hl7.fhir.r4.model.IntegerType
import org.hl7.fhir.r4.model.Questionnaire
import org.hl7.fhir.r4.model.QuestionnaireResponse
import org.hl7.fhir.r4.model.StringType
import org.junit.Assert.assertThrows
import org.junit.Test
import org.junit.runner.RunWith
Expand Down Expand Up @@ -88,6 +91,28 @@ class QuestionnaireItemAdapterTest {
.isEqualTo(QuestionnaireItemViewHolderType.DATE_PICKER.value)
}

@Test
fun getItemViewType_dateItemType_answerOption_shouldReturnDropDownViewHolderType() {
val questionnaireItemAdapter = QuestionnaireItemAdapter()
val questionnaireItemComponent =
Questionnaire.QuestionnaireItemComponent().apply {
type = Questionnaire.QuestionnaireItemType.DATE
answerOption =
listOf(Questionnaire.QuestionnaireItemAnswerOptionComponent(DateType("2022-06-22")))
}
questionnaireItemAdapter.submitList(
listOf(
QuestionnaireItemViewItem(
questionnaireItemComponent,
QuestionnaireResponse.QuestionnaireResponseItemComponent()
) {}
)
)

assertThat(questionnaireItemAdapter.getItemViewType(0))
.isEqualTo(QuestionnaireItemViewHolderType.RADIO_GROUP.value)
}

@Test
fun getItemViewType_dateTimeItemType_shouldReturnDateTimePickerViewHolderType() {
val questionnaireItemAdapter = QuestionnaireItemAdapter()
Expand Down Expand Up @@ -152,6 +177,28 @@ class QuestionnaireItemAdapterTest {
.isEqualTo(QuestionnaireItemViewHolderType.PHONE_NUMBER.value)
}

@Test
fun getItemViewType_stringItemType_answerOption_shouldReturnDropDownViewHolderType() {
val questionnaireItemAdapter = QuestionnaireItemAdapter()
val questionnaireItemComponent =
Questionnaire.QuestionnaireItemComponent().apply {
type = Questionnaire.QuestionnaireItemType.STRING
answerOption =
listOf(Questionnaire.QuestionnaireItemAnswerOptionComponent(StringType("option-1")))
}
questionnaireItemAdapter.submitList(
listOf(
QuestionnaireItemViewItem(
questionnaireItemComponent,
QuestionnaireResponse.QuestionnaireResponseItemComponent()
) {}
)
)

assertThat(questionnaireItemAdapter.getItemViewType(0))
.isEqualTo(QuestionnaireItemViewHolderType.RADIO_GROUP.value)
}

@Test
fun getItemViewType_textItemType_shouldReturnEditTextViewHolderType() {
val questionnaireItemAdapter = QuestionnaireItemAdapter()
Expand Down Expand Up @@ -218,6 +265,28 @@ class QuestionnaireItemAdapterTest {
.isEqualTo(QuestionnaireItemViewHolderType.SLIDER.value)
}

@Test
fun getItemViewType_integerItemType_answerOption_shouldReturnDropDownViewHolderType() {
val questionnaireItemAdapter = QuestionnaireItemAdapter()
val questionnaireItemComponent =
Questionnaire.QuestionnaireItemComponent().apply {
type = Questionnaire.QuestionnaireItemType.INTEGER
answerOption =
listOf(Questionnaire.QuestionnaireItemAnswerOptionComponent(IntegerType("1")))
}
questionnaireItemAdapter.submitList(
listOf(
QuestionnaireItemViewItem(
questionnaireItemComponent,
QuestionnaireResponse.QuestionnaireResponseItemComponent()
) {}
)
)

assertThat(questionnaireItemAdapter.getItemViewType(0))
.isEqualTo(QuestionnaireItemViewHolderType.RADIO_GROUP.value)
}

@Test
fun getItemViewType_decimalItemType_shouldReturnEditTextDecimalViewHolderType() {
val questionnaireItemAdapter = QuestionnaireItemAdapter()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,9 @@ import com.google.android.fhir.datacapture.R
import com.google.android.fhir.datacapture.displayString
import com.google.android.material.textfield.TextInputLayout
import com.google.common.truth.Truth.assertThat
import kotlin.test.assertFailsWith
import org.hl7.fhir.r4.model.Coding
import org.hl7.fhir.r4.model.Questionnaire
import org.hl7.fhir.r4.model.QuestionnaireResponse
import org.hl7.fhir.r4.model.StringType
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
Expand Down Expand Up @@ -163,27 +161,6 @@ class QuestionnaireItemDropDownViewHolderFactoryTest {
.isEqualTo(answerOption.displayString)
}

@Test
fun shouldThrowErrorForAnswerOptionWithoutCoding() {
val answerOption =
Questionnaire.QuestionnaireItemAnswerOptionComponent().apply { value = StringType("test") }

assertFailsWith<IllegalArgumentException> {
viewHolder.bind(
QuestionnaireItemViewItem(
Questionnaire.QuestionnaireItemComponent().apply { addAnswerOption(answerOption) },
QuestionnaireResponse.QuestionnaireResponseItemComponent().apply {
addAnswer(
QuestionnaireResponse.QuestionnaireResponseItemAnswerComponent().apply {
value = answerOption.value
}
)
}
) {}
)
}
}

@Test
fun displayValidationResult_error_shouldShowErrorMessage() {
viewHolder.bind(
Expand Down

0 comments on commit 63fc76f

Please sign in to comment.