From 8857ab08a57ff01b918b7e21238a7be50db374e2 Mon Sep 17 00:00:00 2001
From: chris-cwa <69595386+chris-cwa@users.noreply.github.com>
Date: Mon, 7 Sep 2020 11:35:57 +0200
Subject: [PATCH] Improve Explanation for "Risikobegegnung mit niedrigem
 Risiko" (EXPOSUREAPP-1971) (#1112)

---
 .../riskdetails/DefaultRiskDetailPresenter.kt |  12 ++
 .../ui/riskdetails/RiskDetailPresenter.kt     |   8 +
 .../ui/viewmodel/TracingViewModel.kt          |  52 ++++++
 .../util/formatter/FormatterRiskHelper.kt     |  10 +-
 .../main/res/layout/fragment_risk_details.xml |  19 +-
 ...nclude_risk_details_low_risk_encounter.xml |  62 +++++++
 .../DefaultRiskDetailPresenterTest.kt         |  34 ++++
 .../util/formatter/FormatterRiskHelperTest.kt | 164 ++++++++++--------
 8 files changed, 282 insertions(+), 79 deletions(-)
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/DefaultRiskDetailPresenter.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/RiskDetailPresenter.kt
 create mode 100644 Corona-Warn-App/src/main/res/layout/include_risk_details_low_risk_encounter.xml
 create mode 100644 Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/riskdetails/DefaultRiskDetailPresenterTest.kt

diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/DefaultRiskDetailPresenter.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/DefaultRiskDetailPresenter.kt
new file mode 100644
index 000000000..e577f7ce8
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/DefaultRiskDetailPresenter.kt
@@ -0,0 +1,12 @@
+package de.rki.coronawarnapp.ui.riskdetails
+
+import de.rki.coronawarnapp.risk.RiskLevelConstants
+
+class DefaultRiskDetailPresenter : RiskDetailPresenter {
+
+    override fun isAdditionalInfoVisible(riskLevel: Int, matchedKeyCount: Int) =
+        riskLevel == RiskLevelConstants.LOW_LEVEL_RISK && matchedKeyCount > 0
+
+    override fun isInformationBodyNoticeVisible(riskLevel: Int, matchedKeyCount: Int) =
+        !(riskLevel == RiskLevelConstants.LOW_LEVEL_RISK && matchedKeyCount > 0)
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/RiskDetailPresenter.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/RiskDetailPresenter.kt
new file mode 100644
index 000000000..0186d75f0
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/RiskDetailPresenter.kt
@@ -0,0 +1,8 @@
+package de.rki.coronawarnapp.ui.riskdetails
+
+interface RiskDetailPresenter {
+
+    fun isAdditionalInfoVisible(riskLevel: Int, matchedKeyCount: Int): Boolean
+
+    fun isInformationBodyNoticeVisible(riskLevel: Int, matchedKeyCount: Int): Boolean
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/TracingViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/TracingViewModel.kt
index 8d3b8e0c5..2d94bf11d 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/TracingViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/TracingViewModel.kt
@@ -1,12 +1,15 @@
 package de.rki.coronawarnapp.ui.viewmodel
 
+import android.view.View
 import androidx.lifecycle.LiveData
+import androidx.lifecycle.MediatorLiveData
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
 import de.rki.coronawarnapp.CoronaWarnApplication
 import de.rki.coronawarnapp.exception.ExceptionCategory.INTERNAL
 import de.rki.coronawarnapp.exception.TransactionException
 import de.rki.coronawarnapp.exception.reporting.report
+import de.rki.coronawarnapp.risk.RiskLevelConstants
 import de.rki.coronawarnapp.storage.ExposureSummaryRepository
 import de.rki.coronawarnapp.storage.LocalData
 import de.rki.coronawarnapp.storage.RiskLevelRepository
@@ -14,6 +17,7 @@ import de.rki.coronawarnapp.storage.TracingRepository
 import de.rki.coronawarnapp.timer.TimerHelper
 import de.rki.coronawarnapp.transaction.RetrieveDiagnosisKeysTransaction
 import de.rki.coronawarnapp.transaction.RiskLevelTransaction
+import de.rki.coronawarnapp.ui.riskdetails.DefaultRiskDetailPresenter
 import de.rki.coronawarnapp.util.ConnectivityHelper
 import kotlinx.coroutines.launch
 import org.joda.time.DateTime
@@ -37,6 +41,8 @@ class TracingViewModel : ViewModel() {
         val TAG: String? = TracingViewModel::class.simpleName
     }
 
+    private val riskDetailPresenter = DefaultRiskDetailPresenter()
+
     // Values from RiskLevelRepository
     val riskLevel: LiveData<Int> = RiskLevelRepository.riskLevelScore
     val riskLevelScoreLastSuccessfulCalculated =
@@ -53,6 +59,52 @@ class TracingViewModel : ViewModel() {
     val activeTracingDaysInRetentionPeriod = TracingRepository.activeTracingDaysInRetentionPeriod
     var isRefreshing: LiveData<Boolean> = TracingRepository.isRefreshing
 
+    val additionalInformationVisibility = MediatorLiveData<Int>()
+    val informationBodyNoticeVisibility = MediatorLiveData<Int>()
+
+    init {
+        additionalInformationVisibility.addSource(riskLevel) {
+            additionalInformationVisibility.value =
+                if (riskDetailPresenter.isAdditionalInfoVisible(it, matchedKeyCount.value ?: -1))
+                    View.VISIBLE
+                else
+                    View.GONE
+        }
+        additionalInformationVisibility.addSource(matchedKeyCount) {
+            additionalInformationVisibility.value =
+                if (riskDetailPresenter.isAdditionalInfoVisible(
+                        riskLevel.value ?: RiskLevelConstants.UNKNOWN_RISK_INITIAL,
+                        it ?: 0
+                    )
+                )
+                    View.VISIBLE
+                else
+                    View.GONE
+        }
+        informationBodyNoticeVisibility.addSource(riskLevel) {
+            informationBodyNoticeVisibility.value =
+                if (riskDetailPresenter.isInformationBodyNoticeVisible(
+                        it,
+                        matchedKeyCount.value ?: -1
+                    )
+                )
+                    View.VISIBLE
+                else
+                    View.GONE
+        }
+        informationBodyNoticeVisibility.addSource(matchedKeyCount) {
+            informationBodyNoticeVisibility.value =
+                if (riskDetailPresenter.isInformationBodyNoticeVisible(
+                        riskLevel.value ?: RiskLevelConstants.UNKNOWN_RISK_INITIAL,
+                        it ?: 0
+                    )
+                )
+                    View.VISIBLE
+                else
+                    View.GONE
+        }
+    }
+
     /**
      * Launches the RetrieveDiagnosisKeysTransaction and RiskLevelTransaction in the viewModel scope
      *
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterRiskHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterRiskHelper.kt
index 85c5cf343..5c5fe1ffb 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterRiskHelper.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterRiskHelper.kt
@@ -363,12 +363,14 @@ fun formatNextUpdateContentDescription(
  *
  * @param riskLevelScore
  * @param daysSinceLastExposure
+ * @param matchedKeysCount
  * @return
  */
-fun formatRiskDetailsRiskLevelBody(riskLevelScore: Int?, daysSinceLastExposure: Int?): String {
+fun formatRiskDetailsRiskLevelBody(riskLevelScore: Int?, daysSinceLastExposure: Int?, matchedKeysCount: Int?): String {
     val appContext = CoronaWarnApplication.getAppContext()
     val resources = appContext.resources
     val days = daysSinceLastExposure ?: 0
+    val count = matchedKeysCount ?: 0
     return when (riskLevelScore) {
         RiskLevelConstants.INCREASED_RISK ->
             resources.getQuantityString(
@@ -379,7 +381,11 @@ fun formatRiskDetailsRiskLevelBody(riskLevelScore: Int?, daysSinceLastExposure:
         RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS ->
             appContext.getString(R.string.risk_details_information_body_outdated_risk)
         RiskLevelConstants.LOW_LEVEL_RISK ->
-            appContext.getString(R.string.risk_details_information_body_low_risk)
+            appContext.getString(
+                if (count > 0)
+                    R.string.risk_details_information_body_low_risk_with_encounter
+                else
+                    R.string.risk_details_information_body_low_risk)
         RiskLevelConstants.UNKNOWN_RISK_INITIAL ->
             appContext.getString(R.string.risk_details_information_body_unknown_risk)
         else -> ""
diff --git a/Corona-Warn-App/src/main/res/layout/fragment_risk_details.xml b/Corona-Warn-App/src/main/res/layout/fragment_risk_details.xml
index 3496a3d73..e538e5b2b 100644
--- a/Corona-Warn-App/src/main/res/layout/fragment_risk_details.xml
+++ b/Corona-Warn-App/src/main/res/layout/fragment_risk_details.xml
@@ -117,6 +117,18 @@
                     app:showDetails="@{true}"
                     app:tracingViewModel="@{tracingViewModel}" />
 
+                <include
+                    android:id="@+id/risk_details_additional_information"
+                    layout="@layout/include_risk_details_low_risk_encounter"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:focusable="false"
+                    app:layout_constraintEnd_toEndOf="parent"
+                    app:layout_constraintStart_toStartOf="parent"
+                    app:layout_constraintTop_toBottomOf="@id/risk_details_risk_card"
+                    app:settingsViewModel="@{settingsViewModel}"
+                    app:tracingViewModel="@{tracingViewModel}" />
+
                 <TextView
                     android:id="@+id/risk_details_behavior_headline"
                     style="@style/headline5"
@@ -129,7 +141,7 @@
                     app:layout_constraintEnd_toStartOf="@+id/guideline_end"
                     app:layout_constraintHorizontal_bias="0.0"
                     app:layout_constraintStart_toStartOf="@+id/guideline_start"
-                    app:layout_constraintTop_toBottomOf="@+id/risk_details_risk_card" />
+                    app:layout_constraintTop_toBottomOf="@+id/risk_details_additional_information" />
 
                 <TextView
                     android:id="@+id/risk_details_behavior_subtitle"
@@ -232,8 +244,8 @@
                         android:layout_width="match_parent"
                         android:layout_height="wrap_content"
                         android:layout_marginTop="@dimen/spacing_normal"
-                        android:text="@{FormatterRiskHelper.formatRiskDetailsRiskLevelBody(tracingViewModel.riskLevel, tracingViewModel.daysSinceLastExposure)}"
-                        android:visibility="@{FormatterHelper.formatVisibilityText(FormatterRiskHelper.formatRiskDetailsRiskLevelBody(tracingViewModel.riskLevel, tracingViewModel.daysSinceLastExposure))}"
+                        android:text="@{FormatterRiskHelper.formatRiskDetailsRiskLevelBody(tracingViewModel.riskLevel, tracingViewModel.daysSinceLastExposure, tracingViewModel.matchedKeyCount)}"
+                        android:visibility="@{FormatterHelper.formatVisibilityText(FormatterRiskHelper.formatRiskDetailsRiskLevelBody(tracingViewModel.riskLevel, tracingViewModel.daysSinceLastExposure, tracingViewModel.matchedKeyCount))}"
                         android:focusable="true"
                         app:layout_constraintEnd_toEndOf="parent"
                         app:layout_constraintStart_toStartOf="parent"
@@ -246,6 +258,7 @@
                         android:layout_height="wrap_content"
                         android:layout_marginTop="@dimen/spacing_normal"
                         android:text="@{FormatterRiskHelper.formatRiskDetailsRiskLevelBodyNotice(tracingViewModel.riskLevel)}"
+                        android:visibility="@{tracingViewModel.informationBodyNoticeVisibility}"
                         android:focusable="true"
                         app:layout_constraintEnd_toEndOf="parent"
                         app:layout_constraintStart_toStartOf="parent"
diff --git a/Corona-Warn-App/src/main/res/layout/include_risk_details_low_risk_encounter.xml b/Corona-Warn-App/src/main/res/layout/include_risk_details_low_risk_encounter.xml
new file mode 100644
index 000000000..ad8aedeb3
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/layout/include_risk_details_low_risk_encounter.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <data>
+
+        <variable
+            name="tracingViewModel"
+            type="de.rki.coronawarnapp.ui.viewmodel.TracingViewModel" />
+
+        <variable
+            name="settingsViewModel"
+            type="de.rki.coronawarnapp.ui.viewmodel.SettingsViewModel" />
+    </data>
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="@{tracingViewModel.additionalInformationVisibility}">
+
+        <TextView
+            android:id="@+id/risk_details_additional_information_headline"
+            style="@style/headline5"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="28dp"
+            android:accessibilityHeading="true"
+            android:focusable="true"
+            android:text="@string/risk_details_additional_info_title"
+            android:layout_marginHorizontal="@dimen/spacing_normal"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+        <TextView
+            android:id="@+id/risk_details_additional_information_subtitle"
+            style="@style/body2"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="@dimen/spacing_tiny"
+            android:focusable="true"
+            android:text="@string/risk_details_additional_info_subtitle"
+            android:layout_marginHorizontal="@dimen/spacing_normal"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/risk_details_additional_information_headline" />
+
+        <TextView
+            android:id="@+id/risk_details_additional_information_body"
+            style="@style/body1"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="@dimen/spacing_normal"
+            android:text="@string/risk_details_additional_info_text"
+            android:focusable="true"
+            android:layout_marginHorizontal="@dimen/spacing_normal"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/risk_details_additional_information_subtitle" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</layout>
\ No newline at end of file
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/riskdetails/DefaultRiskDetailPresenterTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/riskdetails/DefaultRiskDetailPresenterTest.kt
new file mode 100644
index 000000000..445d0dce5
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/riskdetails/DefaultRiskDetailPresenterTest.kt
@@ -0,0 +1,34 @@
+package de.rki.coronawarnapp.ui.riskdetails
+
+import de.rki.coronawarnapp.risk.RiskLevelConstants
+import org.junit.Assert
+import org.junit.Test
+
+class DefaultRiskDetailPresenterTest {
+
+    @Test
+    fun test_isAdditionalInfoVisible() {
+        DefaultRiskDetailPresenter().apply {
+            Assert.assertFalse(isAdditionalInfoVisible(RiskLevelConstants.LOW_LEVEL_RISK, 0))
+            Assert.assertTrue(isAdditionalInfoVisible(RiskLevelConstants.LOW_LEVEL_RISK, 1))
+            Assert.assertFalse(isAdditionalInfoVisible(RiskLevelConstants.UNKNOWN_RISK_INITIAL, 0))
+            Assert.assertFalse(isAdditionalInfoVisible(RiskLevelConstants.INCREASED_RISK, 0))
+            Assert.assertFalse(isAdditionalInfoVisible(RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS, 0))
+            Assert.assertFalse(isAdditionalInfoVisible(RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF, 0))
+            Assert.assertFalse(isAdditionalInfoVisible(RiskLevelConstants.UNDETERMINED, 0))
+        }
+    }
+
+    @Test
+    fun test_isInformationBodyNoticeVisible() {
+        DefaultRiskDetailPresenter().apply {
+            Assert.assertTrue(isInformationBodyNoticeVisible(RiskLevelConstants.LOW_LEVEL_RISK, 0))
+            Assert.assertFalse(isInformationBodyNoticeVisible(RiskLevelConstants.LOW_LEVEL_RISK, 1))
+            Assert.assertTrue(isInformationBodyNoticeVisible(RiskLevelConstants.UNKNOWN_RISK_INITIAL, 0))
+            Assert.assertTrue(isInformationBodyNoticeVisible(RiskLevelConstants.INCREASED_RISK, 0))
+            Assert.assertTrue(isInformationBodyNoticeVisible(RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS, 0))
+            Assert.assertTrue(isInformationBodyNoticeVisible(RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF, 0))
+            Assert.assertTrue(isInformationBodyNoticeVisible(RiskLevelConstants.UNDETERMINED, 0))
+        }
+    }
+}
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/formatter/FormatterRiskHelperTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/formatter/FormatterRiskHelperTest.kt
index 0c5ec3a06..3240d2c3e 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/formatter/FormatterRiskHelperTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/formatter/FormatterRiskHelperTest.kt
@@ -93,17 +93,19 @@ class FormatterRiskHelperTest {
         )
     }
 
-//    private fun formatRiskContactBase(iRiskLevelScore: Int?, iMatchedKeysCount: Int?, sValue: String) {
-//        every { context.getString(R.string.risk_card_body_contact) } returns R.string.risk_card_body_contact.toString()
-//
-//        val result = formatRiskContact(riskLevelScore = iRiskLevelScore, matchedKeysCount = iMatchedKeysCount)
-//        assertThat(
-//            result, `is`(sValue)
-//        )
-//    }
+    private fun formatRiskContactBase(iRiskLevelScore: Int?, iMatchedKeysCount: Int?, sValue: String) {
+        every { context.getString(R.string.risk_card_body_contact) } returns R.string.risk_card_body_contact.toString()
+        every { context.getString(R.string.risk_card_body_contact_low_risk) } returns R.string.risk_card_body_contact_low_risk.toString()
+
+        val result = formatRiskContact(riskLevelScore = iRiskLevelScore, matchedKeysCount = iMatchedKeysCount)
+        assertThat(
+            result, `is`(sValue)
+        )
+    }
 
     private fun formatRiskContactLastBase(iRiskLevelScore: Int?, iDaysSinceLastExposure: Int?, sValue: String) {
         every { context.getString(R.string.risk_card_body_contact) } returns R.string.risk_card_body_contact.toString()
+        every { context.getString(R.string.risk_card_body_contact_low_risk) } returns R.string.risk_card_body_contact_low_risk.toString()
 
         val result =
             formatRiskContactLast(riskLevelScore = iRiskLevelScore, daysSinceLastExposure = iDaysSinceLastExposure)
@@ -192,6 +194,7 @@ class FormatterRiskHelperTest {
     private fun formatRiskDetailsRiskLevelBodyBase(
         iRiskLevelScore: Int?,
         iDaysSinceLastExposure: Int?,
+        iMatchedKeysCount: Int?,
         sValue: String
     ) {
         every { context.getString(R.string.risk_details_information_body_outdated_risk) } returns R.string.risk_details_information_body_outdated_risk.toString()
@@ -200,7 +203,8 @@ class FormatterRiskHelperTest {
 
         val result = formatRiskDetailsRiskLevelBody(
             riskLevelScore = iRiskLevelScore,
-            daysSinceLastExposure = iDaysSinceLastExposure
+            daysSinceLastExposure = iDaysSinceLastExposure,
+            matchedKeysCount = iMatchedKeysCount
         )
         assertThat(
             result, `is`(sValue)
@@ -577,70 +581,70 @@ class FormatterRiskHelperTest {
 
     @Test
     fun formatRiskContact() {
-//        formatRiskContactBase(iRiskLevelScore = null, iMatchedKeysCount = null, sValue = "")
-//        formatRiskContactBase(iRiskLevelScore = null, iMatchedKeysCount = 0, sValue = "")
-//
-//        formatRiskContactBase(
-//            iRiskLevelScore = RiskLevelConstants.INCREASED_RISK,
-//            iMatchedKeysCount = 0,
-//            sValue = context.getString(R.string.risk_card_body_contact)
-//        )
-//        formatRiskContactBase(
-//            iRiskLevelScore = RiskLevelConstants.INCREASED_RISK,
-//            iMatchedKeysCount = 2,
-//            sValue = context.resources.getQuantityString(
-//                R.plurals.risk_card_body_contact_value,
-//                2,
-//                2
-//            )
-//        )
-//
-//        formatRiskContactBase(
-//            iRiskLevelScore = RiskLevelConstants.LOW_LEVEL_RISK,
-//            iMatchedKeysCount = 0,
-//            sValue = context.getString(R.string.risk_card_body_contact)
-//        )
-//        formatRiskContactBase(
-//            iRiskLevelScore = RiskLevelConstants.LOW_LEVEL_RISK,
-//            iMatchedKeysCount = 2,
-//            sValue = context.resources.getQuantityString(
-//                R.plurals.risk_card_body_contact_value,
-//                2,
-//                2
-//            )
-//        )
-//
-//        formatRiskContactBase(
-//            iRiskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS,
-//            iMatchedKeysCount = 0,
-//            sValue = ""
-//        )
-//        formatRiskContactBase(
-//            iRiskLevelScore = RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF,
-//            iMatchedKeysCount = 0,
-//            sValue = ""
-//        )
-//        formatRiskContactBase(
-//            iRiskLevelScore = RiskLevelConstants.UNKNOWN_RISK_INITIAL,
-//            iMatchedKeysCount = 0,
-//            sValue = ""
-//        )
-//
-//        formatRiskContactBase(
-//            iRiskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS,
-//            iMatchedKeysCount = 2,
-//            sValue = ""
-//        )
-//        formatRiskContactBase(
-//            iRiskLevelScore = RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF,
-//            iMatchedKeysCount = 2,
-//            sValue = ""
-//        )
-//        formatRiskContactBase(
-//            iRiskLevelScore = RiskLevelConstants.UNKNOWN_RISK_INITIAL,
-//            iMatchedKeysCount = 2,
-//            sValue = ""
-//        )
+        formatRiskContactBase(iRiskLevelScore = null, iMatchedKeysCount = null, sValue = "")
+        formatRiskContactBase(iRiskLevelScore = null, iMatchedKeysCount = 0, sValue = "")
+
+        formatRiskContactBase(
+            iRiskLevelScore = RiskLevelConstants.INCREASED_RISK,
+            iMatchedKeysCount = 0,
+            sValue = context.getString(R.string.risk_card_body_contact)
+        )
+        formatRiskContactBase(
+            iRiskLevelScore = RiskLevelConstants.INCREASED_RISK,
+            iMatchedKeysCount = 2,
+            sValue = context.resources.getQuantityString(
+                R.plurals.risk_card_body_contact_value,
+                2,
+                2
+            )
+        )
+
+        formatRiskContactBase(
+            iRiskLevelScore = RiskLevelConstants.LOW_LEVEL_RISK,
+            iMatchedKeysCount = 0,
+            sValue = context.getString(R.string.risk_card_body_contact_low_risk)
+        )
+        formatRiskContactBase(
+            iRiskLevelScore = RiskLevelConstants.LOW_LEVEL_RISK,
+            iMatchedKeysCount = 2,
+            sValue = context.resources.getQuantityString(
+                R.plurals.risk_card_body_contact_value,
+                2,
+                2
+            )
+        )
+
+        formatRiskContactBase(
+            iRiskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS,
+            iMatchedKeysCount = 0,
+            sValue = ""
+        )
+        formatRiskContactBase(
+            iRiskLevelScore = RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF,
+            iMatchedKeysCount = 0,
+            sValue = ""
+        )
+        formatRiskContactBase(
+            iRiskLevelScore = RiskLevelConstants.UNKNOWN_RISK_INITIAL,
+            iMatchedKeysCount = 0,
+            sValue = ""
+        )
+
+        formatRiskContactBase(
+            iRiskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS,
+            iMatchedKeysCount = 2,
+            sValue = ""
+        )
+        formatRiskContactBase(
+            iRiskLevelScore = RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF,
+            iMatchedKeysCount = 2,
+            sValue = ""
+        )
+        formatRiskContactBase(
+            iRiskLevelScore = RiskLevelConstants.UNKNOWN_RISK_INITIAL,
+            iMatchedKeysCount = 2,
+            sValue = ""
+        )
     }
 
     @Test
@@ -1054,11 +1058,13 @@ class FormatterRiskHelperTest {
         formatRiskDetailsRiskLevelBodyBase(
             iRiskLevelScore = null,
             iDaysSinceLastExposure = 0,
+            iMatchedKeysCount = 0,
             sValue = ""
         )
         formatRiskDetailsRiskLevelBodyBase(
             iRiskLevelScore = RiskLevelConstants.INCREASED_RISK,
             iDaysSinceLastExposure = 1,
+            iMatchedKeysCount = 0,
             sValue = resources.getQuantityString(
                 R.plurals.risk_details_information_body_increased_risk,
                 1,
@@ -1068,28 +1074,34 @@ class FormatterRiskHelperTest {
         formatRiskDetailsRiskLevelBodyBase(
             iRiskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS,
             iDaysSinceLastExposure = 1,
+            iMatchedKeysCount = 0,
             sValue = context.getString(R.string.risk_details_information_body_outdated_risk)
         )
         formatRiskDetailsRiskLevelBodyBase(
             iRiskLevelScore = RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF,
             iDaysSinceLastExposure = 1,
+            iMatchedKeysCount = 0,
             sValue = ""
         )
         formatRiskDetailsRiskLevelBodyBase(
             iRiskLevelScore = RiskLevelConstants.LOW_LEVEL_RISK,
             iDaysSinceLastExposure = 1,
+            iMatchedKeysCount = 0,
             sValue = context.getString(R.string.risk_details_information_body_low_risk)
         )
         formatRiskDetailsRiskLevelBodyBase(
             iRiskLevelScore = RiskLevelConstants.UNKNOWN_RISK_INITIAL,
             iDaysSinceLastExposure = 1,
+            iMatchedKeysCount = 0,
             sValue = context.getString(R.string.risk_details_information_body_unknown_risk)
         )
 
-        formatRiskDetailsRiskLevelBodyBase(iRiskLevelScore = null, iDaysSinceLastExposure = null, sValue = "")
+        formatRiskDetailsRiskLevelBodyBase(iRiskLevelScore = null, iDaysSinceLastExposure = null,
+            iMatchedKeysCount = 0, sValue = "")
         formatRiskDetailsRiskLevelBodyBase(
             iRiskLevelScore = RiskLevelConstants.INCREASED_RISK,
             iDaysSinceLastExposure = null,
+            iMatchedKeysCount = 0,
             sValue = resources.getQuantityString(
                 R.plurals.risk_details_information_body_increased_risk,
                 0,
@@ -1099,21 +1111,25 @@ class FormatterRiskHelperTest {
         formatRiskDetailsRiskLevelBodyBase(
             iRiskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS,
             iDaysSinceLastExposure = null,
+            iMatchedKeysCount = 0,
             sValue = context.getString(R.string.risk_details_information_body_outdated_risk)
         )
         formatRiskDetailsRiskLevelBodyBase(
             iRiskLevelScore = RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF,
             iDaysSinceLastExposure = null,
+            iMatchedKeysCount = 0,
             sValue = ""
         )
         formatRiskDetailsRiskLevelBodyBase(
             iRiskLevelScore = RiskLevelConstants.LOW_LEVEL_RISK,
             iDaysSinceLastExposure = null,
+            iMatchedKeysCount = 0,
             sValue = context.getString(R.string.risk_details_information_body_low_risk)
         )
         formatRiskDetailsRiskLevelBodyBase(
             iRiskLevelScore = RiskLevelConstants.UNKNOWN_RISK_INITIAL,
             iDaysSinceLastExposure = null,
+            iMatchedKeysCount = 0,
             sValue = context.getString(R.string.risk_details_information_body_unknown_risk)
         )
     }
-- 
GitLab