From 87cf73d0708be2050ee1ba341c130cf77c2eb36b Mon Sep 17 00:00:00 2001 From: Chilja Gossow <49635654+chiljamgossow@users.noreply.github.com> Date: Mon, 26 Apr 2021 18:54:38 +0200 Subject: [PATCH] Fix number of days with encounters calculation (EXPOSUREAPP-6703) (#2958) * change calculation * fix test fragment Co-authored-by: I502720 <axel.herbstreith@sap.com> --- ...iskLevelCalculationFragmentCWAViewModel.kt | 10 +- .../presencetracing/risk/PtRiskLevelResult.kt | 12 +- .../coronawarnapp/risk/CombinedEwPtRisk.kt | 10 +- .../coronawarnapp/risk/EwRiskLevelResult.kt | 18 ++- .../risk/RiskLevelResultExtensions.kt | 2 - .../risk/storage/BaseRiskLevelStorage.kt | 3 +- .../risk/storage/internal/RiskCombinator.kt | 2 - .../modules/ExposureRiskMetadataDonorTest.kt | 1 - .../risk/CombinedEwPtRiskTest.kt | 143 ++++++++++++++++++ .../risk/EwRiskLevelResultExtensionsTest.kt | 1 - .../risk/EwRiskLevelResultTest.kt | 67 ++++++-- .../risk/RiskLevelChangeDetectorTest.kt | 1 - .../storage/internal/RiskCombinatorTest.kt | 3 +- 13 files changed, 232 insertions(+), 41 deletions(-) create mode 100644 Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/CombinedEwPtRiskTest.kt diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/risklevel/ui/TestRiskLevelCalculationFragmentCWAViewModel.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/risklevel/ui/TestRiskLevelCalculationFragmentCWAViewModel.kt index d8968b77d..844ca50ad 100644 --- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/risklevel/ui/TestRiskLevelCalculationFragmentCWAViewModel.kt +++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/risklevel/ui/TestRiskLevelCalculationFragmentCWAViewModel.kt @@ -122,23 +122,25 @@ class TestRiskLevelCalculationFragmentCWAViewModel @AssistedInject constructor( riskLevel = latestCalc.riskState, riskLevelLastSuccessfulCalculated = latestSuccessfulCalc.riskState, matchedKeyCount = latestCalc.matchedKeyCount, - daysSinceLastExposure = latestCalc.daysWithEncounters, + noOfDaysWithExposures = if (latestCalc.riskState == RiskState.INCREASED_RISK) + latestCalc.ewAggregatedRiskResult?.numberOfDaysWithHighRisk ?: 0 + else latestCalc.ewAggregatedRiskResult?.numberOfDaysWithLowRisk ?: 0, lastKeySubmission = latestSubmission?.startedAt ) }.asLiveData() - private suspend fun createAdditionalRiskCalcInfo( + private fun createAdditionalRiskCalcInfo( lastTimeRiskLevelCalculation: Instant, riskLevel: RiskState, riskLevelLastSuccessfulCalculated: RiskState, matchedKeyCount: Int, - daysSinceLastExposure: Int, + noOfDaysWithExposures: Int, lastKeySubmission: Instant? ): String = StringBuilder() .appendLine("Risk Level: $riskLevel") .appendLine("Last successful Risk Level: $riskLevelLastSuccessfulCalculated") .appendLine("Matched key count: $matchedKeyCount") - .appendLine("Days since last Exposure: $daysSinceLastExposure days") + .appendLine("Days with exposures: $noOfDaysWithExposures days") .appendLine("Last key submission: $lastKeySubmission") .appendLine("Last time risk level calculation $lastTimeRiskLevelCalculation") .toString() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/PtRiskLevelResult.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/PtRiskLevelResult.kt index bc9bb6639..4cf28e6ec 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/PtRiskLevelResult.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/PtRiskLevelResult.kt @@ -21,12 +21,16 @@ data class PtRiskLevelResult( riskState != RiskState.CALCULATION_FAILED } - val numberOfDaysWithHighRisk: Int by lazy { - presenceTracingDayRisk?.count { it.riskState == RiskState.INCREASED_RISK } ?: 0 + val daysWithHighRisk: List<LocalDate> by lazy { + presenceTracingDayRisk?.filter { + it.riskState == RiskState.INCREASED_RISK + }?.map { it.localDateUtc } ?: emptyList() } - val numberOfDaysWithLowRisk: Int by lazy { - presenceTracingDayRisk?.count { it.riskState == RiskState.LOW_RISK } ?: 0 + val daysWithLowRisk: List<LocalDate> by lazy { + presenceTracingDayRisk?.filter { + it.riskState == RiskState.LOW_RISK + }?.map { it.localDateUtc } ?: emptyList() } val mostRecentDateWithHighRisk: LocalDate? by lazy { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/CombinedEwPtRisk.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/CombinedEwPtRisk.kt index 304aa75d3..cd5d3699d 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/CombinedEwPtRisk.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/CombinedEwPtRisk.kt @@ -31,12 +31,14 @@ data class CombinedEwPtRiskLevelResult( val daysWithEncounters: Int by lazy { when (riskState) { RiskState.INCREASED_RISK -> { - (ewRiskLevelResult.ewAggregatedRiskResult?.numberOfDaysWithHighRisk ?: 0) + - ptRiskLevelResult.numberOfDaysWithHighRisk + ewRiskLevelResult.daysWithHighRisk + .plus(ptRiskLevelResult.daysWithHighRisk) + .distinct().count() } RiskState.LOW_RISK -> { - (ewRiskLevelResult.ewAggregatedRiskResult?.numberOfDaysWithLowRisk ?: 0) + - ptRiskLevelResult.numberOfDaysWithLowRisk + ewRiskLevelResult.daysWithLowRisk + .plus(ptRiskLevelResult.daysWithLowRisk) + .distinct().count() } else -> 0 } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/EwRiskLevelResult.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/EwRiskLevelResult.kt index 952b994c4..daa440e5a 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/EwRiskLevelResult.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/EwRiskLevelResult.kt @@ -3,6 +3,7 @@ package de.rki.coronawarnapp.risk import com.google.android.gms.nearby.exposurenotification.ExposureWindow import de.rki.coronawarnapp.risk.result.EwAggregatedRiskResult import org.joda.time.Instant +import org.joda.time.LocalDate interface EwRiskLevelResult { val calculatedAt: Instant @@ -35,13 +36,6 @@ interface EwRiskLevelResult { ewAggregatedRiskResult?.totalMinimumDistinctEncountersWithLowRisk ?: 0 } - val daysWithEncounters: Int - get() = if (isIncreasedRisk) { - ewAggregatedRiskResult?.numberOfDaysWithHighRisk ?: 0 - } else { - ewAggregatedRiskResult?.numberOfDaysWithLowRisk ?: 0 - } - val lastRiskEncounterAt: Instant? get() = if (isIncreasedRisk) { ewAggregatedRiskResult?.mostRecentDateWithHighRisk @@ -49,6 +43,16 @@ interface EwRiskLevelResult { ewAggregatedRiskResult?.mostRecentDateWithLowRisk } + val daysWithHighRisk: List<LocalDate> + get() = ewAggregatedRiskResult?.exposureWindowDayRisks?.filter { + it.riskLevel.mapToRiskState() == RiskState.INCREASED_RISK + }?.map { it.localDateUtc } ?: emptyList() + + val daysWithLowRisk: List<LocalDate> + get() = ewAggregatedRiskResult?.exposureWindowDayRisks?.filter { + it.riskLevel.mapToRiskState() == RiskState.LOW_RISK + }?.map { it.localDateUtc } ?: emptyList() + enum class FailureReason(val failureCode: String) { UNKNOWN("unknown"), TRACING_OFF("tracingOff"), diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelResultExtensions.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelResultExtensions.kt index 1d0ea0988..73bafdb64 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelResultExtensions.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelResultExtensions.kt @@ -30,7 +30,6 @@ private object EwInitialLowRiskLevelResult : EwRiskLevelResult { override val ewAggregatedRiskResult: EwAggregatedRiskResult? = null override val exposureWindows: List<ExposureWindow>? = null override val matchedKeyCount: Int = 0 - override val daysWithEncounters: Int = 0 } private object EwUndeterminedRiskLevelResult : EwRiskLevelResult { @@ -40,5 +39,4 @@ private object EwUndeterminedRiskLevelResult : EwRiskLevelResult { override val ewAggregatedRiskResult: EwAggregatedRiskResult? = null override val exposureWindows: List<ExposureWindow>? = null override val matchedKeyCount: Int = 0 - override val daysWithEncounters: Int = 0 } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/storage/BaseRiskLevelStorage.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/storage/BaseRiskLevelStorage.kt index 800757c75..e7891623c 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/storage/BaseRiskLevelStorage.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/storage/BaseRiskLevelStorage.kt @@ -190,7 +190,8 @@ abstract class BaseRiskLevelStorage constructor( presenceTracingRiskRepository.allEntries() ) { ewRiskLevelResults, ptRiskLevelResults -> - val combinedResults = riskCombinator.combineEwPtRiskLevelResults(ptRiskLevelResults, ewRiskLevelResults) + val combinedResults = riskCombinator + .combineEwPtRiskLevelResults(ptRiskLevelResults, ewRiskLevelResults) .sortedByDescending { it.calculatedAt } LastCombinedRiskResults( diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/storage/internal/RiskCombinator.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/storage/internal/RiskCombinator.kt index 13aa62d91..4e33b2a24 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/storage/internal/RiskCombinator.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/storage/internal/RiskCombinator.kt @@ -27,7 +27,6 @@ class RiskCombinator @Inject constructor( override val ewAggregatedRiskResult: EwAggregatedRiskResult? = null override val exposureWindows: List<ExposureWindow>? = null override val matchedKeyCount: Int = 0 - override val daysWithEncounters: Int = 0 } private val initialPTRiskLevelResult: PtRiskLevelResult = PtRiskLevelResult( @@ -48,7 +47,6 @@ class RiskCombinator @Inject constructor( override val ewAggregatedRiskResult: EwAggregatedRiskResult? = null override val exposureWindows: List<ExposureWindow>? = null override val matchedKeyCount: Int = 0 - override val daysWithEncounters: Int = 0 } private val ptCurrentLowRiskLevelResult: PtRiskLevelResult diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/datadonation/analytics/modules/ExposureRiskMetadataDonorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/datadonation/analytics/modules/ExposureRiskMetadataDonorTest.kt index 6451d5f74..22d97cc86 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/datadonation/analytics/modules/ExposureRiskMetadataDonorTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/datadonation/analytics/modules/ExposureRiskMetadataDonorTest.kt @@ -50,7 +50,6 @@ class ExposureRiskMetadataDonorTest : BaseTest() { override val failureReason: EwRiskLevelResult.FailureReason? = failureReason override val exposureWindows: List<ExposureWindow>? = null override val matchedKeyCount: Int = 0 - override val daysWithEncounters: Int = 0 } private fun createInstance() = ExposureRiskMetadataDonor( diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/CombinedEwPtRiskTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/CombinedEwPtRiskTest.kt new file mode 100644 index 000000000..18ec9e4c2 --- /dev/null +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/CombinedEwPtRiskTest.kt @@ -0,0 +1,143 @@ +package de.rki.coronawarnapp.risk + +import com.google.android.gms.nearby.exposurenotification.ExposureWindow +import de.rki.coronawarnapp.presencetracing.risk.PtRiskLevelResult +import de.rki.coronawarnapp.presencetracing.risk.calculation.PresenceTracingDayRisk +import de.rki.coronawarnapp.risk.result.EwAggregatedRiskResult +import de.rki.coronawarnapp.risk.result.ExposureWindowDayRisk +import de.rki.coronawarnapp.server.protocols.internal.v2.RiskCalculationParametersOuterClass +import de.rki.coronawarnapp.util.TimeAndDateExtensions.toLocalDateUtc +import io.kotest.matchers.shouldBe +import io.mockk.MockKAnnotations +import io.mockk.every +import io.mockk.impl.annotations.MockK +import org.joda.time.Instant +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import testhelpers.BaseTest + +class CombinedEwPtRiskTest : BaseTest() { + + @MockK lateinit var ewAggregatedRiskResult: EwAggregatedRiskResult + + @BeforeEach + fun setup() { + MockKAnnotations.init(this) + } + + @Test + fun `counts high risk days correctly`() { + val ewDayRisk = ExposureWindowDayRisk( + dateMillisSinceEpoch = 1000, + riskLevel = RiskCalculationParametersOuterClass.NormalizedTimeToRiskLevelMapping.RiskLevel.HIGH, + minimumDistinctEncountersWithLowRisk = 0, + minimumDistinctEncountersWithHighRisk = 1 + ) + val ewDayRisk2 = ExposureWindowDayRisk( + dateMillisSinceEpoch = 1000 + MILLIS_DAY, + riskLevel = RiskCalculationParametersOuterClass.NormalizedTimeToRiskLevelMapping.RiskLevel.LOW, + minimumDistinctEncountersWithLowRisk = 1, + minimumDistinctEncountersWithHighRisk = 0 + ) + val ewDayRisk3 = ExposureWindowDayRisk( + dateMillisSinceEpoch = 1000 + 2 * MILLIS_DAY, + riskLevel = RiskCalculationParametersOuterClass.NormalizedTimeToRiskLevelMapping.RiskLevel.HIGH, + minimumDistinctEncountersWithLowRisk = 1, + minimumDistinctEncountersWithHighRisk = 2 + ) + every { ewAggregatedRiskResult.exposureWindowDayRisks } returns listOf(ewDayRisk, ewDayRisk2, ewDayRisk3) + + val ptDayRisk = PresenceTracingDayRisk( + riskState = RiskState.INCREASED_RISK, + localDateUtc = Instant.ofEpochMilli(1000).toLocalDateUtc() + ) + val ptDayRisk2 = PresenceTracingDayRisk( + riskState = RiskState.LOW_RISK, + localDateUtc = Instant.ofEpochMilli(1000 + MILLIS_DAY).toLocalDateUtc() + ) + val ptDayRisk3 = PresenceTracingDayRisk( + riskState = RiskState.INCREASED_RISK, + localDateUtc = Instant.ofEpochMilli(1000 + 2 * MILLIS_DAY).toLocalDateUtc() + ) + + every { ewAggregatedRiskResult.isIncreasedRisk() } returns true + + CombinedEwPtRiskLevelResult( + ptRiskLevelResult = createPtRiskLevelResult( + calculatedAt = Instant.ofEpochMilli(1000 + 2 * MILLIS_DAY), + riskState = RiskState.LOW_RISK, + presenceTracingDayRisk = listOf(ptDayRisk, ptDayRisk2, ptDayRisk3) + ), + ewRiskLevelResult = createEwRiskLevel( + calculatedAt = Instant.ofEpochMilli(1000 + 2 * MILLIS_DAY), + ewAggregatedRiskResult + ) + ).daysWithEncounters shouldBe 2 + } + + @Test + fun `counts low risk days correctly`() { + val ewDayRisk = ExposureWindowDayRisk( + dateMillisSinceEpoch = 1000, + riskLevel = RiskCalculationParametersOuterClass.NormalizedTimeToRiskLevelMapping.RiskLevel.LOW, + minimumDistinctEncountersWithLowRisk = 0, + minimumDistinctEncountersWithHighRisk = 1 + ) + val ewDayRisk2 = ExposureWindowDayRisk( + dateMillisSinceEpoch = 1000 + MILLIS_DAY, + riskLevel = RiskCalculationParametersOuterClass.NormalizedTimeToRiskLevelMapping.RiskLevel.LOW, + minimumDistinctEncountersWithLowRisk = 1, + minimumDistinctEncountersWithHighRisk = 0 + ) + + every { ewAggregatedRiskResult.exposureWindowDayRisks } returns listOf(ewDayRisk, ewDayRisk2) + + val ptDayRisk = PresenceTracingDayRisk( + riskState = RiskState.LOW_RISK, + localDateUtc = Instant.ofEpochMilli(1000).toLocalDateUtc() + ) + + val ptDayRisk3 = PresenceTracingDayRisk( + riskState = RiskState.LOW_RISK, + localDateUtc = Instant.ofEpochMilli(1000 + 2 * MILLIS_DAY).toLocalDateUtc() + ) + + every { ewAggregatedRiskResult.isLowRisk() } returns true + every { ewAggregatedRiskResult.isIncreasedRisk() } returns false + + CombinedEwPtRiskLevelResult( + ptRiskLevelResult = createPtRiskLevelResult( + calculatedAt = Instant.ofEpochMilli(1000 + 2 * MILLIS_DAY), + riskState = RiskState.LOW_RISK, + presenceTracingDayRisk = listOf(ptDayRisk, ptDayRisk3) + ), + ewRiskLevelResult = createEwRiskLevel( + calculatedAt = Instant.ofEpochMilli(1000 + 2 * MILLIS_DAY), + ewAggregatedRiskResult + ) + ).daysWithEncounters shouldBe 3 + } + + private fun createPtRiskLevelResult( + calculatedAt: Instant, + riskState: RiskState, + presenceTracingDayRisk: List<PresenceTracingDayRisk> + ): PtRiskLevelResult = PtRiskLevelResult( + calculatedAt = calculatedAt, + riskState = riskState, + presenceTracingDayRisk = presenceTracingDayRisk + ) + + private fun createEwRiskLevel( + calculatedAt: Instant, + ewAggregatedRiskResult: EwAggregatedRiskResult? + ): EwRiskLevelResult = object : EwRiskLevelResult { + override val calculatedAt = calculatedAt + override val ewAggregatedRiskResult: EwAggregatedRiskResult? = ewAggregatedRiskResult + override val failureReason: EwRiskLevelResult.FailureReason? = null + override val exposureWindows: List<ExposureWindow>? = null + override val matchedKeyCount: Int = 0 + } +} + +private const val MILLIS_DAY = (1000 * 60 * 60 * 24).toLong() diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/EwRiskLevelResultExtensionsTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/EwRiskLevelResultExtensionsTest.kt index 18acf7c63..24e88df60 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/EwRiskLevelResultExtensionsTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/EwRiskLevelResultExtensionsTest.kt @@ -21,7 +21,6 @@ class EwRiskLevelResultExtensionsTest : BaseTest() { get() = if (!hasResult) EwRiskLevelResult.FailureReason.UNKNOWN else null override val exposureWindows: List<ExposureWindow>? = null override val matchedKeyCount: Int = 0 - override val daysWithEncounters: Int = 0 } @Test diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/EwRiskLevelResultTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/EwRiskLevelResultTest.kt index c5b8c6c55..c2bb7d546 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/EwRiskLevelResultTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/EwRiskLevelResultTest.kt @@ -2,28 +2,29 @@ package de.rki.coronawarnapp.risk import com.google.android.gms.nearby.exposurenotification.ExposureWindow import de.rki.coronawarnapp.risk.result.EwAggregatedRiskResult +import de.rki.coronawarnapp.risk.result.ExposureWindowDayRisk +import de.rki.coronawarnapp.server.protocols.internal.v2.RiskCalculationParametersOuterClass.NormalizedTimeToRiskLevelMapping.RiskLevel import io.kotest.matchers.shouldBe +import io.mockk.MockKAnnotations +import io.mockk.every +import io.mockk.impl.annotations.MockK import io.mockk.mockk import org.joda.time.Instant -import org.junit.Test +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test import testhelpers.BaseTest class EwRiskLevelResultTest : BaseTest() { - private fun createRiskLevel( - ewAggregatedRiskResult: EwAggregatedRiskResult?, - failureReason: EwRiskLevelResult.FailureReason? - ): EwRiskLevelResult = object : EwRiskLevelResult { - override val calculatedAt: Instant = Instant.EPOCH - override val ewAggregatedRiskResult: EwAggregatedRiskResult? = ewAggregatedRiskResult - override val failureReason: EwRiskLevelResult.FailureReason? = failureReason - override val exposureWindows: List<ExposureWindow>? = null - override val matchedKeyCount: Int = 0 - override val daysWithEncounters: Int = 0 + @MockK lateinit var ewAggregatedRiskResult1: EwAggregatedRiskResult + + @BeforeEach + fun setup() { + MockKAnnotations.init(this) } @Test - fun testUnsuccessfulRistLevels() { + fun testUnsuccessfulRiskLevels() { createRiskLevel( ewAggregatedRiskResult = null, failureReason = EwRiskLevelResult.FailureReason.UNKNOWN @@ -34,4 +35,46 @@ class EwRiskLevelResultTest : BaseTest() { failureReason = null ).wasSuccessfullyCalculated shouldBe true } + + @Test + fun `counts days correctly`() { + val dayRisk = ExposureWindowDayRisk( + dateMillisSinceEpoch = 1000, + riskLevel = RiskLevel.HIGH, + minimumDistinctEncountersWithLowRisk = 0, + minimumDistinctEncountersWithHighRisk = 1 + ) + val dayRisk2 = ExposureWindowDayRisk( + dateMillisSinceEpoch = 1000 + MILLIS_DAY, + riskLevel = RiskLevel.LOW, + minimumDistinctEncountersWithLowRisk = 1, + minimumDistinctEncountersWithHighRisk = 0 + ) + val dayRisk3 = ExposureWindowDayRisk( + dateMillisSinceEpoch = 1000 + 2 * MILLIS_DAY, + riskLevel = RiskLevel.HIGH, + minimumDistinctEncountersWithLowRisk = 1, + minimumDistinctEncountersWithHighRisk = 2 + ) + every { ewAggregatedRiskResult1.exposureWindowDayRisks } returns listOf(dayRisk, dayRisk2, dayRisk3) + val riskLevel = createRiskLevel( + ewAggregatedRiskResult = ewAggregatedRiskResult1, + failureReason = null + ) + riskLevel.daysWithHighRisk.size shouldBe 2 + riskLevel.daysWithLowRisk.size shouldBe 1 + } + + private fun createRiskLevel( + ewAggregatedRiskResult: EwAggregatedRiskResult?, + failureReason: EwRiskLevelResult.FailureReason? + ): EwRiskLevelResult = object : EwRiskLevelResult { + override val calculatedAt: Instant = Instant.EPOCH + override val ewAggregatedRiskResult: EwAggregatedRiskResult? = ewAggregatedRiskResult + override val failureReason: EwRiskLevelResult.FailureReason? = failureReason + override val exposureWindows: List<ExposureWindow>? = null + override val matchedKeyCount: Int = 0 + } } + +private const val MILLIS_DAY = (1000 * 60 * 60 * 24).toLong() diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelChangeDetectorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelChangeDetectorTest.kt index a88a3a777..da0c655be 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelChangeDetectorTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelChangeDetectorTest.kt @@ -105,7 +105,6 @@ class RiskLevelChangeDetectorTest : BaseTest() { override val failureReason: EwRiskLevelResult.FailureReason? = null override val exposureWindows: List<ExposureWindow>? = null override val matchedKeyCount: Int = 0 - override val daysWithEncounters: Int = 0 } private fun createPtRiskLevel( diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/internal/RiskCombinatorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/internal/RiskCombinatorTest.kt index 3d23b8d37..13a444759 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/internal/RiskCombinatorTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/internal/RiskCombinatorTest.kt @@ -210,7 +210,7 @@ class RiskCombinatorTest : BaseTest() { } @Test - fun `max RiskState works`() { + fun `combine RiskState works`() { RiskCombinator.combine(INCREASED_RISK, INCREASED_RISK) shouldBe INCREASED_RISK RiskCombinator.combine(INCREASED_RISK, LOW_RISK) shouldBe INCREASED_RISK RiskCombinator.combine(INCREASED_RISK, CALCULATION_FAILED) shouldBe CALCULATION_FAILED @@ -232,5 +232,4 @@ private fun createEwRiskLevelResult( override val ewAggregatedRiskResult: EwAggregatedRiskResult? = null override val exposureWindows: List<ExposureWindow>? = null override val matchedKeyCount: Int = 0 - override val daysWithEncounters: Int = 0 } -- GitLab