From a30ac447c3af6d840ad6047e2ed4565be4a5b39e Mon Sep 17 00:00:00 2001
From: Matthias Urhahn <matthias.urhahn@sap.com>
Date: Tue, 4 May 2021 12:58:13 +0200
Subject: [PATCH] Remove internet condition for EW risk level calculation task.
 (#3064)

We don't need internet for the risk calculation and using parameters from a cached config will be sufficient.

Co-authored-by: Kolya Opahle <k.opahle@sap.com>
---
 .../rki/coronawarnapp/risk/RiskLevelTask.kt   |  12 ---
 .../coronawarnapp/risk/RiskLevelTaskTest.kt   | 100 ++++++------------
 2 files changed, 35 insertions(+), 77 deletions(-)

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 eaf28fd1f..cab719c6c 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
@@ -1,6 +1,5 @@
 package de.rki.coronawarnapp.risk
 
-import android.content.Context
 import com.google.android.gms.nearby.exposurenotification.ExposureWindow
 import de.rki.coronawarnapp.appconfig.AppConfigProvider
 import de.rki.coronawarnapp.appconfig.ConfigData
@@ -20,10 +19,8 @@ import de.rki.coronawarnapp.task.Task
 import de.rki.coronawarnapp.task.TaskCancellationException
 import de.rki.coronawarnapp.task.TaskFactory
 import de.rki.coronawarnapp.task.common.DefaultProgress
-import de.rki.coronawarnapp.util.ConnectivityHelper.isNetworkEnabled
 import de.rki.coronawarnapp.util.TimeStamper
 import de.rki.coronawarnapp.util.device.BackgroundModeStatus
-import de.rki.coronawarnapp.util.di.AppContext
 import kotlinx.coroutines.channels.ConflatedBroadcastChannel
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.asFlow
@@ -37,7 +34,6 @@ import javax.inject.Provider
 @Suppress("ReturnCount", "LongParameterList")
 class RiskLevelTask @Inject constructor(
     private val riskLevels: RiskLevels,
-    @AppContext private val context: Context,
     private val enfClient: ENFClient,
     private val timeStamper: TimeStamper,
     private val backgroundModeStatus: BackgroundModeStatus,
@@ -101,14 +97,6 @@ class RiskLevelTask @Inject constructor(
             )
         }
 
-        if (!isNetworkEnabled(context)) {
-            Timber.i("Risk not calculated, internet unavailable.")
-            return EwRiskLevelTaskResult(
-                calculatedAt = nowUTC,
-                failureReason = FailureReason.NO_INTERNET
-            )
-        }
-
         if (!enfClient.isTracingEnabled.first()) {
             Timber.i("Risk not calculated, tracing is disabled.")
             return EwRiskLevelTaskResult(
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 0c6f3fce2..7f3f3be61 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
@@ -1,10 +1,5 @@
 package de.rki.coronawarnapp.risk
 
-import android.content.Context
-import android.net.ConnectivityManager
-import android.net.Network
-import android.net.NetworkCapabilities
-import android.net.NetworkInfo
 import de.rki.coronawarnapp.appconfig.AppConfigProvider
 import de.rki.coronawarnapp.appconfig.ConfigData
 import de.rki.coronawarnapp.coronatest.CoronaTestRepository
@@ -43,7 +38,6 @@ import testhelpers.BaseTest
 
 class RiskLevelTaskTest : BaseTest() {
     @MockK lateinit var riskLevels: RiskLevels
-    @MockK lateinit var context: Context
     @MockK lateinit var enfClient: ENFClient
     @MockK lateinit var timeStamper: TimeStamper
     @MockK lateinit var backgroundModeStatus: BackgroundModeStatus
@@ -66,42 +60,54 @@ class RiskLevelTaskTest : BaseTest() {
         )
     )
 
+    private val testTimeNow = Instant.parse("2020-12-28")
+    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)
+        }
+    }
+
     @BeforeEach
     fun setup() {
         MockKAnnotations.init(this)
 
         mockkObject(TimeVariables)
 
+        // Mocks setup a happy path, i.e. successful calculation
+
+        every { timeStamper.nowUTC } returns testTimeNow
+
         every { coronaTestRepository.coronaTests } returns coronaTests
-        every { configData.isDeviceTimeCorrect } returns true
         every { backgroundModeStatus.isAutoModeEnabled } returns flowOf(true)
         coEvery { appConfigProvider.getAppConfig() } returns configData
-        every { configData.identifier } returns "config-identifier"
 
-        every { context.getSystemService(Context.CONNECTIVITY_SERVICE) } returns mockk<ConnectivityManager>().apply {
-            every { activeNetwork } returns mockk<Network>().apply {
-                every { getNetworkCapabilities(any()) } returns mockk<NetworkCapabilities>().apply {
-                    every { hasCapability(any()) } returns true
-                }
-            }
-            every { activeNetworkInfo } returns mockk<NetworkInfo>().apply {
-                every { isConnected } returns true
-            }
+        configData.apply {
+            every { identifier } returns "config-identifier"
+            every { isDeviceTimeCorrect } returns true
         }
 
-        every { enfClient.isTracingEnabled } returns flowOf(true)
-        every { timeStamper.nowUTC } returns Instant.EPOCH
-
         every { riskLevelSettings.lastUsedConfigIdentifier = any() } just Runs
 
-        coEvery { keyCacheRepository.getAllCachedKeys() } returns emptyList()
-
         coEvery { riskLevelStorage.storeResult(any()) } just Runs
+
+        coEvery { keyCacheRepository.getAllCachedKeys() } returns listOf(testCachedKey)
+        enfClient.apply {
+            every { isTracingEnabled } returns flowOf(true)
+            coEvery { exposureWindows() } returns listOf()
+        }
+
+        riskLevels.apply {
+            every { calculateRisk(any(), any()) } returns null
+            every { aggregateResults(any(), any()) } returns testAggregatedResult
+        }
+        coEvery { analyticsExposureWindowCollector.reportRiskResultsPerWindow(any()) } just Runs
     }
 
     private fun createTask() = RiskLevelTask(
         riskLevels = riskLevels,
-        context = context,
         enfClient = enfClient,
         timeStamper = timeStamper,
         backgroundModeStatus = backgroundModeStatus,
@@ -129,36 +135,17 @@ class RiskLevelTaskTest : BaseTest() {
         every { configData.localOffset } returns Duration.standardHours(5)
 
         createTask().run(arguments) shouldBe EwRiskLevelTaskResult(
-            calculatedAt = Instant.EPOCH,
+            calculatedAt = testTimeNow,
             failureReason = EwRiskLevelResult.FailureReason.INCORRECT_DEVICE_TIME
         )
     }
 
-    @Test
-    fun `risk calculation is skipped if internet is unavailable`() = runBlockingTest {
-        every { context.getSystemService(Context.CONNECTIVITY_SERVICE) } returns mockk<ConnectivityManager>().apply {
-            every { activeNetwork } returns mockk<Network>().apply {
-                every { getNetworkCapabilities(any()) } returns mockk<NetworkCapabilities>().apply {
-                    every { hasCapability(any()) } returns false
-                }
-            }
-            every { activeNetworkInfo } returns mockk<NetworkInfo>().apply {
-                every { isConnected } returns false
-            }
-        }
-
-        createTask().run(arguments) shouldBe EwRiskLevelTaskResult(
-            calculatedAt = Instant.EPOCH,
-            failureReason = EwRiskLevelResult.FailureReason.NO_INTERNET
-        )
-    }
-
     @Test
     fun `risk calculation is skipped if tracing is disabled`() = runBlockingTest {
         every { enfClient.isTracingEnabled } returns flowOf(false)
 
         createTask().run(arguments) shouldBe EwRiskLevelTaskResult(
-            calculatedAt = Instant.EPOCH,
+            calculatedAt = testTimeNow,
             failureReason = EwRiskLevelResult.FailureReason.TRACING_OFF
         )
     }
@@ -168,7 +155,7 @@ class RiskLevelTaskTest : BaseTest() {
         coEvery { keyCacheRepository.getAllCachedKeys() } returns listOf()
         every { backgroundModeStatus.isAutoModeEnabled } returns flowOf(true)
         createTask().run(arguments) shouldBe EwRiskLevelTaskResult(
-            calculatedAt = Instant.EPOCH,
+            calculatedAt = testTimeNow,
             failureReason = EwRiskLevelResult.FailureReason.OUTDATED_RESULTS
         )
     }
@@ -178,7 +165,7 @@ class RiskLevelTaskTest : BaseTest() {
         coEvery { keyCacheRepository.getAllCachedKeys() } returns listOf()
         every { backgroundModeStatus.isAutoModeEnabled } returns flowOf(false)
         createTask().run(arguments) shouldBe EwRiskLevelTaskResult(
-            calculatedAt = Instant.EPOCH,
+            calculatedAt = testTimeNow,
             failureReason = EwRiskLevelResult.FailureReason.OUTDATED_RESULTS_MANUAL
         )
     }
@@ -283,27 +270,10 @@ class RiskLevelTaskTest : BaseTest() {
 
     @Test
     fun `risk calculation returns aggregated risk result`() = runBlockingTest {
-        val cachedKey = mockk<CachedKey>().apply {
-            every { info } returns mockk<CachedKeyInfo>().apply {
-                every { toDateTime() } returns DateTime.parse("2020-12-28").minusDays(1)
-            }
-        }
-        val now = Instant.parse("2020-12-28")
-        val aggregatedRiskResult = mockk<EwAggregatedRiskResult>().apply {
-            every { isIncreasedRisk() } returns true
-        }
-
-        coEvery { keyCacheRepository.getAllCachedKeys() } returns listOf(cachedKey)
-        coEvery { enfClient.exposureWindows() } returns listOf()
-        every { riskLevels.calculateRisk(any(), any()) } returns null
-        every { riskLevels.aggregateResults(any(), any()) } returns aggregatedRiskResult
-        every { timeStamper.nowUTC } returns now
-        coEvery { analyticsExposureWindowCollector.reportRiskResultsPerWindow(any()) } just Runs
-
         createTask().run(arguments) shouldBe EwRiskLevelTaskResult(
-            calculatedAt = now,
+            calculatedAt = testTimeNow,
             failureReason = null,
-            ewAggregatedRiskResult = aggregatedRiskResult,
+            ewAggregatedRiskResult = testAggregatedResult,
             listOf()
         )
     }
-- 
GitLab