diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/appconfig/mapping/ExposureWindowRiskCalculationConfigMapper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/appconfig/mapping/ExposureWindowRiskCalculationConfigMapper.kt index 03ab772373f8841087ab2d1ab32662dc2ab0a015..dc447aff6d40db685a0c460a9a763396ff227b14 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/appconfig/mapping/ExposureWindowRiskCalculationConfigMapper.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/appconfig/mapping/ExposureWindowRiskCalculationConfigMapper.kt @@ -6,6 +6,7 @@ import de.rki.coronawarnapp.appconfig.ExposureWindowRiskCalculationConfig import de.rki.coronawarnapp.appconfig.internal.ApplicationConfigurationInvalidException import de.rki.coronawarnapp.server.protocols.internal.v2.AppConfigAndroid import de.rki.coronawarnapp.server.protocols.internal.v2.RiskCalculationParametersOuterClass +import timber.log.Timber import javax.inject.Inject @Reusable @@ -27,6 +28,14 @@ class ExposureWindowRiskCalculationConfigMapper @Inject constructor() : val riskCalculationParameters = rawConfig.riskCalculationParameters + if (riskCalculationParameters.transmissionRiskValueMappingList.isEmpty()) { + val msg = "Transmission Risk Value Mapping List is empty which indicates an outdated app config" + Timber.w(msg) + throw ApplicationConfigurationInvalidException( + message = msg + ) + } + return ExposureWindowRiskCalculationContainer( minutesAtAttenuationFilters = riskCalculationParameters.minutesAtAttenuationFiltersList, minutesAtAttenuationWeights = riskCalculationParameters.minutesAtAttenuationWeightsList, @@ -55,9 +64,12 @@ class ExposureWindowRiskCalculationConfigMapper @Inject constructor() : } data class ExposureWindowRiskCalculationContainer( - override val minutesAtAttenuationFilters: List<RiskCalculationParametersOuterClass.MinutesAtAttenuationFilter>, - override val minutesAtAttenuationWeights: List<RiskCalculationParametersOuterClass.MinutesAtAttenuationWeight>, - override val transmissionRiskLevelEncoding: RiskCalculationParametersOuterClass.TransmissionRiskLevelEncoding, + override val minutesAtAttenuationFilters: + List<RiskCalculationParametersOuterClass.MinutesAtAttenuationFilter>, + override val minutesAtAttenuationWeights: + List<RiskCalculationParametersOuterClass.MinutesAtAttenuationWeight>, + override val transmissionRiskLevelEncoding: + RiskCalculationParametersOuterClass.TransmissionRiskLevelEncoding, override val transmissionRiskLevelFilters: List<RiskCalculationParametersOuterClass.TrlFilter>, override val normalizedTimePerExposureWindowToRiskLevelMapping: diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/appconfig/mapping/ExposureWindowRiskCalculationConfigMapperTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/appconfig/mapping/ExposureWindowRiskCalculationConfigMapperTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..9871f1d918016f13d7a55d64c08e3a138ff1c98e --- /dev/null +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/appconfig/mapping/ExposureWindowRiskCalculationConfigMapperTest.kt @@ -0,0 +1,95 @@ +package de.rki.coronawarnapp.appconfig.mapping + +import de.rki.coronawarnapp.appconfig.internal.ApplicationConfigurationInvalidException +import de.rki.coronawarnapp.server.protocols.internal.v2.AppConfigAndroid +import de.rki.coronawarnapp.server.protocols.internal.v2.RiskCalculationParametersOuterClass +import io.kotest.assertions.throwables.shouldThrow +import io.kotest.matchers.shouldBe +import io.kotest.matchers.string.shouldContain +import org.junit.jupiter.api.Test +import testhelpers.BaseTest + +class ExposureWindowRiskCalculationConfigMapperTest : BaseTest() { + + private fun createInstance() = ExposureWindowRiskCalculationConfigMapper() + private val defaultRiskParams = RiskCalculationParametersOuterClass.RiskCalculationParameters.getDefaultInstance() + private val defaultKeysMapping = AppConfigAndroid.DiagnosisKeysDataMapping.getDefaultInstance() + + private val transmissionRiskValueMapping = + RiskCalculationParametersOuterClass.TransmissionRiskValueMapping.newBuilder() + .setTransmissionRiskLevel(3) + .setTransmissionRiskValue(0.6) + private val riskParams = RiskCalculationParametersOuterClass.RiskCalculationParameters.newBuilder() + .addTransmissionRiskValueMapping(transmissionRiskValueMapping) + + @Test + fun `throws when riskCalculationParameters are missing`() { + val rawConfig = AppConfigAndroid.ApplicationConfigurationAndroid.newBuilder() + .build() + + rawConfig.run { + hasRiskCalculationParameters() shouldBe false + hasDiagnosisKeysDataMapping() shouldBe false + } + + val error = shouldThrow<ApplicationConfigurationInvalidException> { + createInstance().map(rawConfig) + } + error.message shouldContain "Risk Calculation Parameters" + } + + @Test + fun `throws when diagnosisKeysDataMapping is missing`() { + val rawConfig = AppConfigAndroid.ApplicationConfigurationAndroid.newBuilder() + .setRiskCalculationParameters(defaultRiskParams) + .build() + + rawConfig.run { + hasRiskCalculationParameters() shouldBe true + hasDiagnosisKeysDataMapping() shouldBe false + } + + val error = shouldThrow<ApplicationConfigurationInvalidException> { + createInstance().map(rawConfig) + } + error.message shouldContain "Diagnosis Keys Data Mapping" + } + + @Test + fun `throws when transmissionRiskValueMappingList is empty`() { + val rawConfig = AppConfigAndroid.ApplicationConfigurationAndroid.newBuilder() + .setRiskCalculationParameters(defaultRiskParams) + .setDiagnosisKeysDataMapping(defaultKeysMapping) + .build() + + rawConfig.run { + hasRiskCalculationParameters() shouldBe true + hasDiagnosisKeysDataMapping() shouldBe true + riskCalculationParameters.transmissionRiskValueMappingList.isEmpty() shouldBe true + } + + val error = shouldThrow<ApplicationConfigurationInvalidException> { + createInstance().map(rawConfig) + } + error.message shouldContain "Transmission Risk Value Mapping List" + } + + @Test + fun `Mapping of transmissionRiskValueMappingList is correct`() { + val rawConfig = AppConfigAndroid.ApplicationConfigurationAndroid.newBuilder() + .setRiskCalculationParameters(riskParams) + .setDiagnosisKeysDataMapping(defaultKeysMapping) + .build() + + rawConfig.run { + hasRiskCalculationParameters() shouldBe true + hasDiagnosisKeysDataMapping() shouldBe true + riskCalculationParameters.transmissionRiskValueMappingCount shouldBe 1 + + riskCalculationParameters.transmissionRiskValueMappingList.first().run { + transmissionRiskLevel shouldBe 3 + transmissionRiskValue shouldBe 0.6 + } + } + } +}