From 98da5decced1854a10f265bbe281b2f9cb693e92 Mon Sep 17 00:00:00 2001 From: Matthias Urhahn <matthias.urhahn@sap.com> Date: Wed, 26 May 2021 16:47:01 +0200 Subject: [PATCH] Adjust reference time for deadman notification (EXPOSUREAPP-7386) (#3269) * Use last successful diagnosis key download as time reference for the deadman notification. * Use last successful diagnosis key download as time reference for the deadman notification. * Reuse mocking function. Co-authored-by: harambasicluka <64483219+harambasicluka@users.noreply.github.com> Co-authored-by: Alex Paulescu <alex.paulescu@gmail.com> --- .../DeadmanNotificationTimeCalculation.kt | 18 ++-- .../download/DayPackageSyncTool.kt | 3 +- .../download/HourPackageSyncTool.kt | 3 +- .../diagnosiskeys/storage/CachedKeyInfo.kt | 11 +-- .../rki/coronawarnapp/risk/RiskLevelTask.kt | 5 +- .../DeadmanNotificationTimeCalculationTest.kt | 89 +++++++++++++------ .../download/CommonSyncToolTest.kt | 63 ++++++++----- .../download/DayPackageSyncToolTest.kt | 16 +--- .../download/HourPackageSyncToolTest.kt | 22 +---- .../coronawarnapp/risk/RiskLevelTaskTest.kt | 39 +++----- 10 files changed, 145 insertions(+), 124 deletions(-) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/deadman/DeadmanNotificationTimeCalculation.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/deadman/DeadmanNotificationTimeCalculation.kt index a78205544..de21b1095 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/deadman/DeadmanNotificationTimeCalculation.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/deadman/DeadmanNotificationTimeCalculation.kt @@ -1,7 +1,8 @@ package de.rki.coronawarnapp.deadman import dagger.Reusable -import de.rki.coronawarnapp.nearby.ENFClient +import de.rki.coronawarnapp.diagnosiskeys.storage.KeyCacheRepository +import de.rki.coronawarnapp.diagnosiskeys.storage.pkgDateTime import de.rki.coronawarnapp.util.TimeStamper import kotlinx.coroutines.flow.first import org.joda.time.DateTimeConstants @@ -12,8 +13,8 @@ import javax.inject.Inject @Reusable class DeadmanNotificationTimeCalculation @Inject constructor( - val timeStamper: TimeStamper, - val enfClient: ENFClient + private val timeStamper: TimeStamper, + private val keyCacheRepository: KeyCacheRepository, ) { /** @@ -29,10 +30,15 @@ class DeadmanNotificationTimeCalculation @Inject constructor( * If last success date time is null (eg: on application first start) - return [DEADMAN_NOTIFICATION_DELAY] */ suspend fun getDelay(): Long { - val lastSuccess = enfClient.lastSuccessfulTrackedExposureDetection().first()?.finishedAt - Timber.d("enfClient.lastSuccessfulTrackedExposureDetection: $lastSuccess") + val lastSuccess = keyCacheRepository.allCachedKeys() + .first() + .filter { it.info.isDownloadComplete } + .maxByOrNull { it.info.pkgDateTime } + ?.info + + Timber.d("Last successful diagnosis key package download: $lastSuccess") return if (lastSuccess != null) { - getHoursDiff(lastSuccess).toLong() + getHoursDiff(lastSuccess.pkgDateTime.toInstant()).toLong() } else { (DEADMAN_NOTIFICATION_DELAY * DateTimeConstants.MINUTES_PER_HOUR).toLong() } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/DayPackageSyncTool.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/DayPackageSyncTool.kt index 7598c00a6..6744d5a6a 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/DayPackageSyncTool.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/DayPackageSyncTool.kt @@ -9,6 +9,7 @@ import de.rki.coronawarnapp.diagnosiskeys.server.LocationCode import de.rki.coronawarnapp.diagnosiskeys.storage.CachedKey import de.rki.coronawarnapp.diagnosiskeys.storage.CachedKeyInfo.Type import de.rki.coronawarnapp.diagnosiskeys.storage.KeyCacheRepository +import de.rki.coronawarnapp.diagnosiskeys.storage.pkgDateTime import de.rki.coronawarnapp.exception.http.CwaUnknownHostException import de.rki.coronawarnapp.storage.DeviceStorage import de.rki.coronawarnapp.util.TimeAndDateExtensions.toLocalDateUtc @@ -81,7 +82,7 @@ class DayPackageSyncTool @Inject constructor( @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) internal fun expectNewDayPackages(cachedDays: List<CachedKey>): Boolean { val yesterday = timeStamper.nowUTC.toLocalDateUtc().minusDays(1) - val newestDay = cachedDays.map { it.info.toDateTime() }.maxOrNull()?.toLocalDate() + val newestDay = cachedDays.map { it.info.pkgDateTime }.maxOrNull()?.toLocalDate() return yesterday != newestDay } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/HourPackageSyncTool.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/HourPackageSyncTool.kt index caa3143bc..6a2c01262 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/HourPackageSyncTool.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/HourPackageSyncTool.kt @@ -9,6 +9,7 @@ import de.rki.coronawarnapp.diagnosiskeys.server.LocationCode import de.rki.coronawarnapp.diagnosiskeys.storage.CachedKey import de.rki.coronawarnapp.diagnosiskeys.storage.CachedKeyInfo.Type import de.rki.coronawarnapp.diagnosiskeys.storage.KeyCacheRepository +import de.rki.coronawarnapp.diagnosiskeys.storage.pkgDateTime import de.rki.coronawarnapp.exception.http.CwaServerError import de.rki.coronawarnapp.exception.http.CwaUnknownHostException import de.rki.coronawarnapp.exception.http.NetworkConnectTimeoutException @@ -126,7 +127,7 @@ class HourPackageSyncTool @Inject constructor( @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) internal fun expectNewHourPackages(cachedHours: List<CachedKey>, now: Instant): Boolean { val today = now.toDateTime(DateTimeZone.UTC) - val newestHour = cachedHours.map { it.info.toDateTime() }.maxOrNull() + val newestHour = cachedHours.map { it.info.pkgDateTime }.maxOrNull() return today.minusHours(1).hourOfDay != newestHour?.hourOfDay || today.toLocalDate() != newestHour.toLocalDate() } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/storage/CachedKeyInfo.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/storage/CachedKeyInfo.kt index ada80369a..b7d7f3954 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/storage/CachedKeyInfo.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/storage/CachedKeyInfo.kt @@ -50,11 +50,6 @@ data class CachedKeyInfo( isDownloadComplete = true ) - fun toDateTime(): DateTime = when (type) { - Type.LOCATION_DAY -> day.toDateTimeAtStartOfDay(DateTimeZone.UTC) - Type.LOCATION_HOUR -> day.toDateTime(hour, DateTimeZone.UTC) - } - companion object { fun calcluateId( location: LocationCode, @@ -89,3 +84,9 @@ data class CachedKeyInfo( @ColumnInfo(name = "completed") val isDownloadComplete: Boolean ) } + +val CachedKeyInfo.pkgDateTime: DateTime + get() = when (type) { + CachedKeyInfo.Type.LOCATION_DAY -> day.toDateTimeAtStartOfDay(DateTimeZone.UTC) + CachedKeyInfo.Type.LOCATION_HOUR -> day.toDateTime(hour, DateTimeZone.UTC) + } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelTask.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelTask.kt index cab719c6c..ea42e6f17 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelTask.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelTask.kt @@ -7,6 +7,7 @@ import de.rki.coronawarnapp.appconfig.ExposureWindowRiskCalculationConfig import de.rki.coronawarnapp.coronatest.CoronaTestRepository import de.rki.coronawarnapp.datadonation.analytics.modules.exposurewindows.AnalyticsExposureWindowCollector import de.rki.coronawarnapp.diagnosiskeys.storage.KeyCacheRepository +import de.rki.coronawarnapp.diagnosiskeys.storage.pkgDateTime import de.rki.coronawarnapp.exception.ExceptionCategory import de.rki.coronawarnapp.exception.reporting.report import de.rki.coronawarnapp.nearby.ENFClient @@ -124,14 +125,14 @@ class RiskLevelTask @Inject constructor( Timber.tag(TAG).d("Evaluating areKeyPkgsOutDated(nowUTC=%s)", nowUTC) val latestDownload = keyCacheRepository.getAllCachedKeys().maxByOrNull { - it.info.toDateTime() + it.info.pkgDateTime } if (latestDownload == null) { Timber.w("areKeyPkgsOutDated(): No downloads available, why is the RiskLevelTask running? Aborting!") return true } - val downloadAge = Duration(latestDownload.info.toDateTime(), nowUTC).also { + val downloadAge = Duration(latestDownload.info.pkgDateTime, nowUTC).also { Timber.d("areKeyPkgsOutDated(): Age is %dh for latest key package: %s", it.standardHours, latestDownload) } diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/deadman/DeadmanNotificationTimeCalculationTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/deadman/DeadmanNotificationTimeCalculationTest.kt index f83e96389..ef310d304 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/deadman/DeadmanNotificationTimeCalculationTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/deadman/DeadmanNotificationTimeCalculationTest.kt @@ -1,16 +1,21 @@ package de.rki.coronawarnapp.deadman -import de.rki.coronawarnapp.nearby.ENFClient -import de.rki.coronawarnapp.nearby.modules.detectiontracker.TrackedExposureDetection +import de.rki.coronawarnapp.diagnosiskeys.download.createMockCachedKeyInfo +import de.rki.coronawarnapp.diagnosiskeys.storage.CachedKey +import de.rki.coronawarnapp.diagnosiskeys.storage.KeyCacheRepository import de.rki.coronawarnapp.util.TimeStamper import io.kotest.matchers.shouldBe import io.mockk.MockKAnnotations +import io.mockk.coEvery +import io.mockk.coVerify import io.mockk.every import io.mockk.impl.annotations.MockK -import io.mockk.verify -import kotlinx.coroutines.flow.flowOf +import io.mockk.mockk +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.runBlockingTest import org.joda.time.Instant +import org.joda.time.LocalDate +import org.joda.time.LocalTime import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import testhelpers.BaseTest @@ -18,79 +23,109 @@ import testhelpers.BaseTest class DeadmanNotificationTimeCalculationTest : BaseTest() { @MockK lateinit var timeStamper: TimeStamper - @MockK lateinit var enfClient: ENFClient - @MockK lateinit var mockExposureDetection: TrackedExposureDetection + @MockK lateinit var keyCacheRepository: KeyCacheRepository + + private val allCachedKeysFlow = MutableStateFlow(emptyList<CachedKey>()) @BeforeEach fun setup() { MockKAnnotations.init(this) - every { timeStamper.nowUTC } returns Instant.parse("2020-08-01T23:00:00.000Z") - every { enfClient.lastSuccessfulTrackedExposureDetection() } returns flowOf(mockExposureDetection) + every { timeStamper.nowUTC } returns Instant.parse("2020-08-01T23:00:00") + coEvery { keyCacheRepository.allCachedKeys() } returns allCachedKeysFlow } private fun createTimeCalculator() = DeadmanNotificationTimeCalculation( timeStamper = timeStamper, - enfClient = enfClient + keyCacheRepository = keyCacheRepository ) + private fun mockCachedKey( + keyDay: LocalDate, + keyHour: LocalTime? = null, + isComplete: Boolean = true, + ): CachedKey = mockk<CachedKey>().apply { + every { info } returns createMockCachedKeyInfo( + dayIdentifier = keyDay, + hourIdentifier = keyHour, + isComplete = isComplete, + ) + } + @Test fun `12 hours difference`() { - every { timeStamper.nowUTC } returns Instant.parse("2020-08-28T14:00:00.000Z") + every { timeStamper.nowUTC } returns Instant.parse("2020-08-28T14:00:00") - createTimeCalculator().getHoursDiff(Instant.parse("2020-08-27T14:00:00.000Z")) shouldBe 720 + createTimeCalculator().getHoursDiff(Instant.parse("2020-08-27T14:00:00")) shouldBe 720 } @Test fun `negative time difference`() { - every { timeStamper.nowUTC } returns Instant.parse("2020-08-30T14:00:00.000Z") + every { timeStamper.nowUTC } returns Instant.parse("2020-08-30T14:00:00") - createTimeCalculator().getHoursDiff(Instant.parse("2020-08-27T14:00:00.000Z")) shouldBe -2160 + createTimeCalculator().getHoursDiff(Instant.parse("2020-08-27T14:00:00")) shouldBe -2160 } @Test fun `success in future case`() { - every { timeStamper.nowUTC } returns Instant.parse("2020-08-27T14:00:00.000Z") + every { timeStamper.nowUTC } returns Instant.parse("2020-08-27T14:00:00") - createTimeCalculator().getHoursDiff(Instant.parse("2020-08-27T15:00:00.000Z")) shouldBe 2220 + createTimeCalculator().getHoursDiff(Instant.parse("2020-08-27T15:00:00")) shouldBe 2220 } @Test fun `12 hours delay`() = runBlockingTest { every { timeStamper.nowUTC } returns Instant.parse("2020-08-28T14:00:00.000Z") - every { mockExposureDetection.finishedAt } returns Instant.parse("2020-08-27T14:00:00.000Z") + allCachedKeysFlow.value = listOf( + mockCachedKey(keyDay = LocalDate.parse("2020-08-27"), keyHour = LocalTime.parse("14:00:00")) + ) createTimeCalculator().getDelay() shouldBe 720 - verify(exactly = 1) { enfClient.lastSuccessfulTrackedExposureDetection() } + coVerify(exactly = 1) { keyCacheRepository.allCachedKeys() } + } + + @Test + fun `12 hours delay - only completed results count`() = runBlockingTest { + every { timeStamper.nowUTC } returns Instant.parse("2020-08-28T14:00:00.000Z") + allCachedKeysFlow.value = listOf( + mockCachedKey(keyDay = LocalDate.parse("2020-08-27"), keyHour = LocalTime.parse("14:00:00")), + mockCachedKey( + keyDay = LocalDate.parse("2020-08-27"), + keyHour = LocalTime.parse("16:00:00"), + isComplete = false + ) + ) + + createTimeCalculator().getDelay() shouldBe 720 + + coVerify(exactly = 1) { keyCacheRepository.allCachedKeys() } } @Test fun `negative delay`() = runBlockingTest { every { timeStamper.nowUTC } returns Instant.parse("2020-08-30T14:00:00.000Z") - every { mockExposureDetection.finishedAt } returns Instant.parse("2020-08-27T14:00:00.000Z") + allCachedKeysFlow.value = listOf( + mockCachedKey(keyDay = LocalDate.parse("2020-08-27"), keyHour = LocalTime.parse("14:00:00")), + ) createTimeCalculator().getDelay() shouldBe -2160 - - verify(exactly = 1) { enfClient.lastSuccessfulTrackedExposureDetection() } } @Test fun `success in future delay`() = runBlockingTest { every { timeStamper.nowUTC } returns Instant.parse("2020-08-27T14:00:00.000Z") - every { mockExposureDetection.finishedAt } returns Instant.parse("2020-08-27T15:00:00.000Z") + allCachedKeysFlow.value = listOf( + mockCachedKey(keyDay = LocalDate.parse("2020-08-27"), keyHour = LocalTime.parse("15:00:00")), + ) createTimeCalculator().getDelay() shouldBe 2220 - - verify(exactly = 1) { enfClient.lastSuccessfulTrackedExposureDetection() } } @Test fun `initial delay - no successful calculations yet`() = runBlockingTest { - every { timeStamper.nowUTC } returns Instant.parse("2020-08-27T14:00:00.000Z") - every { enfClient.lastSuccessfulTrackedExposureDetection() } returns flowOf(null) + every { timeStamper.nowUTC } returns Instant.parse("2020-08-27T14:00:00") + allCachedKeysFlow.value = emptyList() createTimeCalculator().getDelay() shouldBe 2160 - - verify(exactly = 1) { enfClient.lastSuccessfulTrackedExposureDetection() } } } diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/CommonSyncToolTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/CommonSyncToolTest.kt index 29b079f8e..ff29aad05 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/CommonSyncToolTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/CommonSyncToolTest.kt @@ -38,9 +38,6 @@ abstract class CommonSyncToolTest : BaseIOTest() { private val testDir = File(IO_TEST_BASEDIR, this::class.simpleName!!) - internal val String.loc get() = LocationCode(this) - internal val String.day get() = LocalDate.parse(this) - internal val String.hour get() = LocalTime.parse(this) val keyRepoData = mutableMapOf<String, CachedKey>() @BeforeEach @@ -130,28 +127,12 @@ abstract class CommonSyncToolTest : BaseIOTest() { hourIdentifier: LocalTime?, isComplete: Boolean = true ): CachedKey { - var keyInfo = CachedKeyInfo( - type = when (hourIdentifier) { - null -> CachedKeyInfo.Type.LOCATION_DAY - else -> CachedKeyInfo.Type.LOCATION_HOUR - }, + val keyInfo = createMockCachedKeyInfo( location = location, - day = dayIdentifier, - hour = hourIdentifier, - createdAt = when (hourIdentifier) { - null -> dayIdentifier.toLocalDateTime(LocalTime.MIDNIGHT).toDateTime(DateTimeZone.UTC).toInstant() - else -> dayIdentifier.toLocalDateTime(hourIdentifier).toDateTime(DateTimeZone.UTC).toInstant() - } + dayIdentifier = dayIdentifier, + hourIdentifier = hourIdentifier, + isComplete = isComplete ) - if (isComplete) { - keyInfo = keyInfo.copy( - etag = when (hourIdentifier) { - null -> "$location-$dayIdentifier" - else -> "$location-$dayIdentifier-$hourIdentifier" - }, - isDownloadComplete = true - ) - } Timber.i("mockKeyCacheCreateEntry(...): %s", keyInfo) val file = File(testDir, keyInfo.id) file.createNewFile() @@ -160,3 +141,39 @@ abstract class CommonSyncToolTest : BaseIOTest() { } } } + +internal val String.loc get() = LocationCode(this) +internal val String.day get() = LocalDate.parse(this) +internal val String.hour get() = LocalTime.parse(this) + +fun createMockCachedKeyInfo( + dayIdentifier: LocalDate, + hourIdentifier: LocalTime?, + isComplete: Boolean, + location: LocationCode = "EUR".loc, +): CachedKeyInfo { + var keyInfo = CachedKeyInfo( + type = when (hourIdentifier) { + null -> CachedKeyInfo.Type.LOCATION_DAY + else -> CachedKeyInfo.Type.LOCATION_HOUR + }, + location = location, + day = dayIdentifier, + hour = hourIdentifier, + createdAt = when (hourIdentifier) { + null -> dayIdentifier.toLocalDateTime(LocalTime.MIDNIGHT).toDateTime(DateTimeZone.UTC).toInstant() + else -> dayIdentifier.toLocalDateTime(hourIdentifier).toDateTime(DateTimeZone.UTC).toInstant() + } + ) + if (isComplete) { + keyInfo = keyInfo.copy( + etag = when (hourIdentifier) { + null -> "$location-$dayIdentifier" + else -> "$location-$dayIdentifier-$hourIdentifier" + }, + isDownloadComplete = true + ) + } + Timber.i("createMockCachedKeyInfo(...): %s", keyInfo) + return keyInfo +} diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/DayPackageSyncToolTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/DayPackageSyncToolTest.kt index 17c498967..2b9a8f4ce 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/DayPackageSyncToolTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/DayPackageSyncToolTest.kt @@ -1,17 +1,13 @@ package de.rki.coronawarnapp.diagnosiskeys.download import de.rki.coronawarnapp.appconfig.mapping.RevokedKeyPackage -import de.rki.coronawarnapp.diagnosiskeys.storage.CachedKey -import de.rki.coronawarnapp.diagnosiskeys.storage.CachedKeyInfo import de.rki.coronawarnapp.diagnosiskeys.storage.CachedKeyInfo.Type import io.kotest.matchers.shouldBe import io.mockk.coEvery import io.mockk.coVerify import io.mockk.coVerifySequence import io.mockk.every -import io.mockk.mockk import kotlinx.coroutines.test.runBlockingTest -import org.joda.time.DateTimeZone import org.joda.time.Instant import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach @@ -98,16 +94,8 @@ class DayPackageSyncToolTest : CommonSyncToolTest() { @Test fun `EXPECT_NEW_DAY_PACKAGES evaluation`() = runBlockingTest { - val cachedKey1 = mockk<CachedKey>().apply { - every { info } returns mockk<CachedKeyInfo>().apply { - every { toDateTime() } returns Instant.parse("2020-10-30T01:02:03.000Z").toDateTime(DateTimeZone.UTC) - } - } - val cachedKey2 = mockk<CachedKey>().apply { - every { info } returns mockk<CachedKeyInfo>().apply { - every { toDateTime() } returns Instant.parse("2020-10-31T01:02:03.000Z").toDateTime(DateTimeZone.UTC) - } - } + val cachedKey1 = mockCachedDay("EUR".loc, "2020-10-30".day) + val cachedKey2 = mockCachedDay("EUR".loc, "2020-10-31".day) val instance = createInstance() diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/HourPackageSyncToolTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/HourPackageSyncToolTest.kt index 0a58b9578..1f5590a38 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/HourPackageSyncToolTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/HourPackageSyncToolTest.kt @@ -1,8 +1,6 @@ package de.rki.coronawarnapp.diagnosiskeys.download import de.rki.coronawarnapp.appconfig.mapping.RevokedKeyPackage -import de.rki.coronawarnapp.diagnosiskeys.storage.CachedKey -import de.rki.coronawarnapp.diagnosiskeys.storage.CachedKeyInfo import de.rki.coronawarnapp.diagnosiskeys.storage.CachedKeyInfo.Type import de.rki.coronawarnapp.exception.http.NetworkConnectTimeoutException import io.kotest.matchers.shouldBe @@ -10,9 +8,7 @@ import io.mockk.coEvery import io.mockk.coVerify import io.mockk.coVerifySequence import io.mockk.every -import io.mockk.mockk import kotlinx.coroutines.test.runBlockingTest -import org.joda.time.DateTimeZone import org.joda.time.Instant import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach @@ -184,16 +180,8 @@ class HourPackageSyncToolTest : CommonSyncToolTest() { @Test fun `EXPECT_NEW_HOUR_PACKAGES evaluation`() = runBlockingTest { - val cachedKey1 = mockk<CachedKey>().apply { - every { info } returns mockk<CachedKeyInfo>().apply { - every { toDateTime() } returns Instant.parse("2020-01-01T00:00:03.000Z").toDateTime(DateTimeZone.UTC) - } - } - val cachedKey2 = mockk<CachedKey>().apply { - every { info } returns mockk<CachedKeyInfo>().apply { - every { toDateTime() } returns Instant.parse("2020-01-01T01:00:03.000Z").toDateTime(DateTimeZone.UTC) - } - } + val cachedKey1 = mockCachedHour("EUR".loc, "2020-01-01".day, "00:00".hour) + val cachedKey2 = mockCachedHour("EUR".loc, "2020-01-01".day, "01:00".hour) val instance = createInstance() @@ -207,11 +195,7 @@ class HourPackageSyncToolTest : CommonSyncToolTest() { @Test fun `EXPECT_NEW_HOUR_PACKAGES does not get confused by same hour on next day`() = runBlockingTest { - val cachedKey1 = mockk<CachedKey>().apply { - every { info } returns mockk<CachedKeyInfo>().apply { - every { toDateTime() } returns Instant.parse("2020-01-01T00:00:03.000Z").toDateTime(DateTimeZone.UTC) - } - } + val cachedKey1 = mockCachedHour("EUR".loc, "2020-01-01".day, "00:00".hour) val instance = createInstance() diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelTaskTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelTaskTest.kt index 7f3f3be61..728fc06a9 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelTaskTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelTaskTest.kt @@ -5,8 +5,8 @@ import de.rki.coronawarnapp.appconfig.ConfigData import de.rki.coronawarnapp.coronatest.CoronaTestRepository import de.rki.coronawarnapp.coronatest.type.CoronaTest import de.rki.coronawarnapp.datadonation.analytics.modules.exposurewindows.AnalyticsExposureWindowCollector +import de.rki.coronawarnapp.diagnosiskeys.download.createMockCachedKeyInfo import de.rki.coronawarnapp.diagnosiskeys.storage.CachedKey -import de.rki.coronawarnapp.diagnosiskeys.storage.CachedKeyInfo import de.rki.coronawarnapp.diagnosiskeys.storage.KeyCacheRepository import de.rki.coronawarnapp.nearby.ENFClient import de.rki.coronawarnapp.risk.result.EwAggregatedRiskResult @@ -64,11 +64,7 @@ class RiskLevelTaskTest : BaseTest() { private val testAggregatedResult = mockk<EwAggregatedRiskResult>().apply { every { isIncreasedRisk() } returns true } - private val testCachedKey = mockk<CachedKey>().apply { - every { info } returns mockk<CachedKeyInfo>().apply { - every { toDateTime() } returns testTimeNow.toDateTime().minusDays(1) - } - } + private val testCachedKey = mockCachedKey(testTimeNow.toDateTime().minusDays(1)) @BeforeEach fun setup() { @@ -119,6 +115,13 @@ class RiskLevelTaskTest : BaseTest() { analyticsExposureWindowCollector = analyticsExposureWindowCollector, ) + private fun mockCachedKey( + dateTime: DateTime, + isComplete: Boolean = true, + ): CachedKey = mockk<CachedKey>().apply { + every { info } returns createMockCachedKeyInfo(dateTime.toLocalDate(), dateTime.toLocalTime(), isComplete) + } + @Test fun `last used config ID is set after calculation`() = runBlockingTest { every { configData.isDeviceTimeCorrect } returns true @@ -172,11 +175,7 @@ class RiskLevelTaskTest : BaseTest() { @Test fun `risk calculation is skipped if results are outdated while in background mode`() = runBlockingTest { - val cachedKey = mockk<CachedKey>().apply { - every { info } returns mockk<CachedKeyInfo>().apply { - every { toDateTime() } returns DateTime.parse("2020-12-28").minusDays(3) - } - } + val cachedKey = mockCachedKey(DateTime.parse("2020-12-28").minusDays(3)) val now = Instant.parse("2020-12-28") coEvery { keyCacheRepository.getAllCachedKeys() } returns listOf(cachedKey) @@ -191,11 +190,7 @@ class RiskLevelTaskTest : BaseTest() { @Test fun `risk calculation is skipped if results are outdated while no background mode`() = runBlockingTest { - val cachedKey = mockk<CachedKey>().apply { - every { info } returns mockk<CachedKeyInfo>().apply { - every { toDateTime() } returns DateTime.parse("2020-12-28").minusDays(3) - } - } + val cachedKey = mockCachedKey(DateTime.parse("2020-12-28").minusDays(3)) val now = Instant.parse("2020-12-28") coEvery { keyCacheRepository.getAllCachedKeys() } returns listOf(cachedKey) @@ -210,11 +205,7 @@ class RiskLevelTaskTest : BaseTest() { @Test fun `risk calculation is skipped if positive test is registered and viewed`() = runBlockingTest { - val cachedKey = mockk<CachedKey>().apply { - every { info } returns mockk<CachedKeyInfo>().apply { - every { toDateTime() } returns DateTime.parse("2020-12-28").minusDays(1) - } - } + val cachedKey = mockCachedKey(DateTime.parse("2020-12-28").minusDays(1)) val now = Instant.parse("2020-12-28") coEvery { keyCacheRepository.getAllCachedKeys() } returns listOf(cachedKey) @@ -236,11 +227,7 @@ class RiskLevelTaskTest : BaseTest() { @Test fun `risk calculation is not skipped if positive test is registered and not viewed`() = runBlockingTest { - val cachedKey = mockk<CachedKey>().apply { - every { info } returns mockk<CachedKeyInfo>().apply { - every { toDateTime() } returns DateTime.parse("2020-12-28").minusDays(1) - } - } + val cachedKey = mockCachedKey(DateTime.parse("2020-12-28").minusDays(1)) val now = Instant.parse("2020-12-28") val aggregatedRiskResult = mockk<EwAggregatedRiskResult>().apply { every { isIncreasedRisk() } returns true -- GitLab