Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add maxSize extension support #1688

Merged
merged 17 commits into from
Jan 10, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ import com.google.android.fhir.datacapture.common.datatype.asStringValue
import com.google.android.fhir.datacapture.utilities.evaluateToDisplay
import com.google.android.fhir.getLocalizedText
import com.google.android.fhir.logicalId
import java.math.BigDecimal
import org.hl7.fhir.r4.model.Base
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.DecimalType
import org.hl7.fhir.r4.model.Expression
import org.hl7.fhir.r4.model.IntegerType
import org.hl7.fhir.r4.model.Questionnaire
Expand Down Expand Up @@ -175,6 +177,30 @@ internal val Questionnaire.QuestionnaireItemComponent.choiceOrientation: ChoiceO
return ChoiceOrientationTypes.values().firstOrNull { it.extensionCode == code }
}

internal const val EXTENSION_MAX_SIZE = "https://hl7.org/fhir/StructureDefinition/maxSize"

private val SIZE_UNIT_DIVIDER = BigDecimal(1024)
FikriMilano marked this conversation as resolved.
Show resolved Hide resolved

/** Maximum size an attachment can be. Unit in Bytes. */
internal val Questionnaire.QuestionnaireItemComponent.maxSizeInB: BigDecimal?
get() {
return (extension.firstOrNull { it.url == EXTENSION_MAX_SIZE }?.valueAsPrimitive
as DecimalType?)
?.value
}

/** Maximum size an attachment can be. Unit in Kibibytes. */
FikriMilano marked this conversation as resolved.
Show resolved Hide resolved
internal val Questionnaire.QuestionnaireItemComponent.maxSizeInKiB: BigDecimal?
FikriMilano marked this conversation as resolved.
Show resolved Hide resolved
FikriMilano marked this conversation as resolved.
Show resolved Hide resolved
get() {
return maxSizeInB?.div(SIZE_UNIT_DIVIDER)
FikriMilano marked this conversation as resolved.
Show resolved Hide resolved
}

/** Maximum size an attachment can be. Unit in Mebibytes. */
FikriMilano marked this conversation as resolved.
Show resolved Hide resolved
internal val Questionnaire.QuestionnaireItemComponent.maxSizeInMiB: BigDecimal?
FikriMilano marked this conversation as resolved.
Show resolved Hide resolved
get() {
return maxSizeInKiB?.div(SIZE_UNIT_DIVIDER)
}

/** UI controls relevant to rendering questionnaire items. */
internal enum class DisplayItemControlType(val extensionCode: String) {
FLYOVER("flyover"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,25 @@ package com.google.android.fhir.datacapture

import android.os.Build
import com.google.android.fhir.datacapture.mapping.ITEM_INITIAL_EXPRESSION_URL
import com.google.android.fhir.datacapture.validation.NotValidated
import com.google.android.fhir.datacapture.views.QuestionnaireItemViewItem
import com.google.common.truth.Truth.assertThat
import java.math.BigDecimal
import java.util.Locale
import org.hl7.fhir.r4.model.Attachment
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.DecimalType
FikriMilano marked this conversation as resolved.
Show resolved Hide resolved
import org.hl7.fhir.r4.model.Enumeration
import org.hl7.fhir.r4.model.Expression
import org.hl7.fhir.r4.model.Extension
import org.hl7.fhir.r4.model.IntegerType
import org.hl7.fhir.r4.model.Patient
import org.hl7.fhir.r4.model.Quantity
import org.hl7.fhir.r4.model.Questionnaire
import org.hl7.fhir.r4.model.QuestionnaireResponse
import org.hl7.fhir.r4.model.StringType
import org.hl7.fhir.r4.utils.ToolingExtensions
import org.junit.Assert.assertThrows
Expand Down Expand Up @@ -462,6 +467,64 @@ class MoreQuestionnaireItemComponentsTest {
assertThat(questionnaire.choiceOrientation).isNull()
}

@Test
fun maxSize_shouldReturnBytes() {
FikriMilano marked this conversation as resolved.
Show resolved Hide resolved
val questionnaire =
FikriMilano marked this conversation as resolved.
Show resolved Hide resolved
Questionnaire.QuestionnaireItemComponent().apply {
addExtension(EXTENSION_MAX_SIZE, DecimalType(5242880))
}
assertThat(questionnaire.maxSizeInB).isEqualTo(BigDecimal(5242880))
}

@Test
fun maxSize_shouldReturnKibibytes() {
val questionnaire =
Questionnaire.QuestionnaireItemComponent().apply {
addExtension(EXTENSION_MAX_SIZE, DecimalType(5242880))
}
assertThat(questionnaire.maxSizeInKiB).isEqualTo(BigDecimal(5120))
}

@Test
fun maxSize_shouldReturnMebibytes() {
val questionnaire =
Questionnaire.QuestionnaireItemComponent().apply {
addExtension(EXTENSION_MAX_SIZE, DecimalType(5242880))
}
assertThat(questionnaire.maxSizeInMiB).isEqualTo(BigDecimal(5))
}

@Test
fun maxSize_whenAnswerSizeIsAboveLimit_shouldBeKnown() {
FikriMilano marked this conversation as resolved.
Show resolved Hide resolved
var answers = listOf<QuestionnaireResponse.QuestionnaireResponseItemAnswerComponent>()
val questionnaireItemViewItem =
QuestionnaireItemViewItem(
questionnaireItem =
Questionnaire.QuestionnaireItemComponent().apply {
linkId = "attachment-1"
addExtension(EXTENSION_MAX_SIZE, DecimalType(0))
},
questionnaireResponseItem = QuestionnaireResponse.QuestionnaireResponseItemComponent(),
validationResult = NotValidated,
answersChangedCallback = { _, _, result -> answers = result },
)
.apply {
setAnswer(
QuestionnaireResponse.QuestionnaireResponseItemAnswerComponent()
.setValue(Attachment().apply { size = 5242880 })
)
}

assertThat(answers.first().valueAttachment.size)
.isGreaterThan(questionnaireItemViewItem.questionnaireItem.maxSizeInB?.toInt())
}

@Test
fun maxSize_missingExtension_shouldReturnNull() {
FikriMilano marked this conversation as resolved.
Show resolved Hide resolved
val questionnaire = Questionnaire.QuestionnaireItemComponent()
assertThat(questionnaire.maxSizeInB).isNull()
}

@Test
fun localizedTextSpanned_noText_shouldReturnNull() {
assertThat(Questionnaire.QuestionnaireItemComponent().localizedTextSpanned).isNull()
Expand Down