diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/contactdiary/DiaryData.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/contactdiary/DiaryData.kt
index 55b95459ee73e9658f413de65d6ebbf0c1b5f1bd..d46a8e8d690bca0a26585b0e89132d0eae563f26 100644
--- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/contactdiary/DiaryData.kt
+++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/contactdiary/DiaryData.kt
@@ -60,15 +60,19 @@ object DiaryData {
     )
 
     val HIGH_RISK = ListItem.Risk(
-        R.string.contact_diary_risk_body,
-        R.string.contact_diary_high_risk_title,
-        R.drawable.ic_high_risk_alert
+        title = R.string.contact_diary_high_risk_title,
+        body = R.string.contact_diary_risk_body,
+        bodyExtended = R.string.contact_diary_risk_body_extended,
+        drawableId = R.drawable.ic_high_risk_alert
     )
 
+    val HIGH_RISK_DUE_LOW_RISK_ENCOUNTERS = HIGH_RISK.copy(body = R.string.contact_diary_risk_body_high_risk_due_to_low_risk_encounters)
+
     val LOW_RISK = ListItem.Risk(
-        R.string.contact_diary_risk_body,
-        R.string.contact_diary_low_risk_title,
-        R.drawable.ic_low_risk_alert
+        title = R.string.contact_diary_low_risk_title,
+        body = R.string.contact_diary_risk_body,
+        bodyExtended = R.string.contact_diary_risk_body_extended,
+        drawableId = R.drawable.ic_low_risk_alert
     )
 
     val LOCATIONS: List<DiaryLocationListItem> = listOf(
diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/main/MainActivityTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/main/MainActivityTest.kt
index 6f2fb1680365478578ca595b9369fdaaea5ddd71..0ef69d98c02304ce2c1000ea334206153f87d7b8 100644
--- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/main/MainActivityTest.kt
+++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/main/MainActivityTest.kt
@@ -323,10 +323,14 @@ class MainActivityTest : BaseUITest() {
         MutableLiveData(
             (0 until ContactDiaryOverviewViewModel.DAY_COUNT)
                 .map { LocalDate.now().minusDays(it) }
-                .map {
-                    ListItem(it).apply {
+                .mapIndexed { index, localDate ->
+                    ListItem(localDate).apply {
                         data.addAll(DiaryData.DATA_ITEMS)
-                        risk = if (it.dayOfYear % 2 == 0) DiaryData.HIGH_RISK else DiaryData.LOW_RISK
+                        risk = when (index % 3) {
+                            0 -> DiaryData.HIGH_RISK
+                            1 -> DiaryData.HIGH_RISK_DUE_LOW_RISK_ENCOUNTERS
+                            else -> DiaryData.LOW_RISK
+                        }
                     }
                 }
         )
diff --git a/Corona-Warn-App/src/deviceForTesters/assets/exposure-windows-increased-risk-due-to-low-risk-encounter-random.json b/Corona-Warn-App/src/deviceForTesters/assets/exposure-windows-increased-risk-due-to-low-risk-encounter-random.json
new file mode 100644
index 0000000000000000000000000000000000000000..0f3fcf61f725b4520c036609eeee1b7746b4d6e7
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/assets/exposure-windows-increased-risk-due-to-low-risk-encounter-random.json
@@ -0,0 +1,110 @@
+[
+  {
+    "ageInDays": 1,
+    "reportType": 3,
+    "infectiousness": 1,
+    "calibrationConfidence": 0,
+    "scanInstances": [
+      {
+        "minAttenuation": 30,
+        "typicalAttenuation": 25,
+        "secondsSinceLastScan": 300
+      },
+      {
+        "minAttenuation": 30,
+        "typicalAttenuation": 25,
+        "secondsSinceLastScan": 300
+      }
+    ]
+  },
+  {
+    "ageInDays": 1,
+    "reportType": 3,
+    "infectiousness": 1,
+    "calibrationConfidence": 0,
+    "scanInstances": [
+      {
+        "minAttenuation": 30,
+        "typicalAttenuation": 26,
+        "secondsSinceLastScan": 300
+      },
+      {
+        "minAttenuation": 30,
+        "typicalAttenuation": 26,
+        "secondsSinceLastScan": 300
+      }
+    ]
+  },
+  {
+    "ageInDays": 1,
+    "reportType": 3,
+    "infectiousness": 1,
+    "calibrationConfidence": 0,
+    "scanInstances": [
+      {
+        "minAttenuation": 30,
+        "typicalAttenuation": 27,
+        "secondsSinceLastScan": 300
+      },
+      {
+        "minAttenuation": 30,
+        "typicalAttenuation": 27,
+        "secondsSinceLastScan": 300
+      }
+    ]
+  },
+  {
+    "ageInDays": 2,
+    "reportType": 3,
+    "infectiousness": 1,
+    "calibrationConfidence": 0,
+    "scanInstances": [
+      {
+        "minAttenuation": 30,
+        "typicalAttenuation": 25,
+        "secondsSinceLastScan": 300
+      },
+      {
+        "minAttenuation": 30,
+        "typicalAttenuation": 25,
+        "secondsSinceLastScan": 300
+      }
+    ]
+  },
+  {
+    "ageInDays": 2,
+    "reportType": 3,
+    "infectiousness": 1,
+    "calibrationConfidence": 0,
+    "scanInstances": [
+      {
+        "minAttenuation": 30,
+        "typicalAttenuation": 26,
+        "secondsSinceLastScan": 300
+      },
+      {
+        "minAttenuation": 30,
+        "typicalAttenuation": 26,
+        "secondsSinceLastScan": 300
+      }
+    ]
+  },
+  {
+    "ageInDays": 2,
+    "reportType": 3,
+    "infectiousness": 1,
+    "calibrationConfidence": 0,
+    "scanInstances": [
+      {
+        "minAttenuation": 30,
+        "typicalAttenuation": 27,
+        "secondsSinceLastScan": 300
+      },
+      {
+        "minAttenuation": 30,
+        "typicalAttenuation": 27,
+        "secondsSinceLastScan": 300
+      }
+    ]
+  }
+]
\ No newline at end of file
diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/nearby/modules/exposurewindow/FakeExposureWindowProvider.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/nearby/modules/exposurewindow/FakeExposureWindowProvider.kt
index ce213e8e03432873ea37ac457889cc65c92da657..12f7ef5474446268b0f44e7df6f3dae5f6a32551 100644
--- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/nearby/modules/exposurewindow/FakeExposureWindowProvider.kt
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/nearby/modules/exposurewindow/FakeExposureWindowProvider.kt
@@ -24,6 +24,7 @@ class FakeExposureWindowProvider @Inject constructor(
     fun getExposureWindows(testSettings: FakeExposureWindowTypes): List<ExposureWindow> {
         val jsonInput = when (testSettings) {
             FakeExposureWindowTypes.INCREASED_RISK_DEFAULT -> "exposure-windows-increased-risk-random.json"
+            FakeExposureWindowTypes.INCREASED_RISK_DUE_LOW_RISK_ENCOUNTER_DEFAULT -> "exposure-windows-increased-risk-due-to-low-risk-encounter-random.json"
             FakeExposureWindowTypes.LOW_RISK_DEFAULT -> "exposure-windows-lowrisk-random.json"
             else -> throw NotImplementedError()
         }.let { context.assets.open(it) }.readBytes().toString(Charsets.UTF_8)
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModel.kt
index f2c304ca1f3daa15c2c6b0c0bf004a4fa9677fc3..bf01a2f7b9daa8131a46256a34de11fd8ba342a4 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModel.kt
@@ -85,29 +85,33 @@ class ContactDiaryOverviewViewModel @AssistedInject constructor(
                         data.addLocationVisitsForDate(locationVisitList, date)
                         risk = riskLevelPerDateList
                             .firstOrNull { riskLevelPerDate -> riskLevelPerDate.day == it }
-                            ?.toRisk(data.isEmpty())
+                            ?.toRisk(data.isNotEmpty())
                     }
             }
     }
 
-    private fun AggregatedRiskPerDateResult.toRisk(noLocationOrPerson: Boolean): ListItem.Risk {
+    private fun AggregatedRiskPerDateResult.toRisk(locationOrPerson: Boolean): ListItem.Risk {
         @StringRes val title: Int
+        @StringRes var body: Int = R.string.contact_diary_risk_body
         @DrawableRes val drawableId: Int
 
-        @StringRes val body: Int = when (noLocationOrPerson) {
-            true -> R.string.contact_diary_risk_body
-            false -> R.string.contact_diary_risk_body_extended
+        @StringRes val bodyExtend: Int? = when (locationOrPerson) {
+            true -> R.string.contact_diary_risk_body_extended
+            false -> null
         }
 
         if (this.riskLevel == RiskCalculationParametersOuterClass.NormalizedTimeToRiskLevelMapping.RiskLevel.HIGH) {
             title = R.string.contact_diary_high_risk_title
             drawableId = R.drawable.ic_high_risk_alert
+            if (minimumDistinctEncountersWithHighRisk == 0) {
+                body = R.string.contact_diary_risk_body_high_risk_due_to_low_risk_encounters
+            }
         } else {
             title = R.string.contact_diary_low_risk_title
             drawableId = R.drawable.ic_low_risk_alert
         }
 
-        return ListItem.Risk(title, body, drawableId)
+        return ListItem.Risk(title, body, bodyExtend, drawableId)
     }
 
     private fun MutableList<ListItem.Data>.addPersonEncountersForDate(
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ContactDiaryOverviewAdapter.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ContactDiaryOverviewAdapter.kt
index f8b2782ec0aabe398370eaa1ecc65f03ac572190..e58c708ef1b935e6a1a3e0f091cedec570a230cf 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ContactDiaryOverviewAdapter.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ContactDiaryOverviewAdapter.kt
@@ -57,8 +57,15 @@ class ContactDiaryOverviewAdapter(
                     item.risk?.let {
                         this.contactDiaryOverviewRiskItem.isGone = false
                         this.contactDiaryOverviewItemRiskTitle.text = context.getString(it.title)
-                        this.contactDiaryOverviewItemRiskBody.text = context.getString(it.body)
                         this.contactDiaryOverviewRiskItemImage.setImageResource(it.drawableId)
+
+                        val sb = StringBuilder().append(context.getString(it.body))
+
+                        it.bodyExtended?.let { extend ->
+                            sb.appendLine().append(context.getString(extend))
+                        }
+
+                        this.contactDiaryOverviewItemRiskBody.text = sb
                     } ?: run { this.contactDiaryOverviewRiskItem.isGone = true }
                 }
             }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ListItem.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ListItem.kt
index 525d988f570055861e91369b66af1d1258063993..f155c87bccc2d84c968fdc4f45504ef4e4e3060c 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ListItem.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ListItem.kt
@@ -23,6 +23,7 @@ data class ListItem(
     data class Risk(
         @StringRes val title: Int,
         @StringRes val body: Int,
+        @StringRes val bodyExtended: Int? = null,
         @DrawableRes val drawableId: Int
     )
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/TestSettings.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/TestSettings.kt
index c0099d3a3f1550da855c969ff4c5e8ce6b0a289e..330028b103a14b22ba997670bb6a439c2fc85db9 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/TestSettings.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/TestSettings.kt
@@ -47,6 +47,9 @@ class TestSettings @Inject constructor(
         @SerializedName("INCREASED_RISK_DEFAULT")
         INCREASED_RISK_DEFAULT,
 
+        @SerializedName("INCREASED_RISK_DUE_LOW_RISK_ENCOUNTER_DEFAULT")
+        INCREASED_RISK_DUE_LOW_RISK_ENCOUNTER_DEFAULT,
+
         @SerializedName("LOW_RISK_DEFAULT")
         LOW_RISK_DEFAULT
     }
diff --git a/Corona-Warn-App/src/main/res/values-de/contact_diary_strings.xml b/Corona-Warn-App/src/main/res/values-de/contact_diary_strings.xml
index 2bf855a09b9124fc7a354ccbe4f0528bca6edf11..72abf54c41ffaef59f4815031746ad4b7ac6217e 100644
--- a/Corona-Warn-App/src/main/res/values-de/contact_diary_strings.xml
+++ b/Corona-Warn-App/src/main/res/values-de/contact_diary_strings.xml
@@ -73,8 +73,10 @@
     <string name="contact_diary_low_risk_title">"Niedriges Risiko"</string>
     <!-- XTXT: Body for contact diary overview screen risk information -->
     <string name="contact_diary_risk_body">"aufgrund der von der App ausgewerteten Begegnungen."</string>
+    <!-- XTXT: Body for contact diary overview screen risk information when high risk due to low risk encounters-->
+    <string name="contact_diary_risk_body_high_risk_due_to_low_risk_encounters">"aufgrund von mehreren Begegnungen mit niedrigem Risiko."</string>
     <!-- XTXT: Extended Body for contact diary overview screen risk information -->
-    <string name="contact_diary_risk_body_extended">"aufgrund der von der App ausgewerteten Begegnungen. Diese müssen nicht in Zusammenhang mit den von Ihnen erfassten Personen und Orten stehen."</string>
+    <string name="contact_diary_risk_body_extended">"Diese müssen nicht in Zusammenhang mit den von Ihnen erfassten Personen und Orten stehen."</string>
 
 
     <!-- XTXT: content description of contact journal image on home screen -->
diff --git a/Corona-Warn-App/src/main/res/values/contact_diary_strings.xml b/Corona-Warn-App/src/main/res/values/contact_diary_strings.xml
index b9c30d5c6f88ffd376e71d628ed4a36df1405e99..1db1884f3cd01ac69d8cc85dd4609bfcda3d59b3 100644
--- a/Corona-Warn-App/src/main/res/values/contact_diary_strings.xml
+++ b/Corona-Warn-App/src/main/res/values/contact_diary_strings.xml
@@ -73,8 +73,10 @@
     <string name="contact_diary_low_risk_title">"Low Risk"</string>
     <!-- XTXT: Body for contact diary overview screen risk information -->
     <string name="contact_diary_risk_body">"based on the encounters evaluated by the app."</string>
+    <!-- XTXT: Body for contact diary overview screen risk information when high risk due to low risk encounters-->
+    <string name="contact_diary_risk_body_high_risk_due_to_low_risk_encounters">"based on several encounters with low risk."</string>
     <!-- XTXT: Extended Body for contact diary overview screen risk information -->
-    <string name="contact_diary_risk_body_extended">"based on the encounters evaluated by the app. They are not necessarily related to the people and places you have recorded."</string>
+    <string name="contact_diary_risk_body_extended">"They are not necessarily related to the people and places you have recorded."</string>
 
 
     <!-- XTXT: content description of contact journal image on home screen -->
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModelTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..9de044a53bccdd9bd70e39e2dd9d60c66b6f2c62
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModelTest.kt
@@ -0,0 +1,296 @@
+package de.rki.coronawarnapp.contactdiary.ui.overview
+
+import de.rki.coronawarnapp.R
+import de.rki.coronawarnapp.contactdiary.model.DefaultContactDiaryLocation
+import de.rki.coronawarnapp.contactdiary.model.DefaultContactDiaryLocationVisit
+import de.rki.coronawarnapp.contactdiary.model.DefaultContactDiaryPerson
+import de.rki.coronawarnapp.contactdiary.model.DefaultContactDiaryPersonEncounter
+import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository
+import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.ListItem
+import de.rki.coronawarnapp.risk.result.AggregatedRiskPerDateResult
+import de.rki.coronawarnapp.risk.storage.RiskLevelStorage
+import de.rki.coronawarnapp.server.protocols.internal.v2.RiskCalculationParametersOuterClass
+import de.rki.coronawarnapp.task.TaskController
+import io.kotest.matchers.should
+import io.kotest.matchers.shouldBe
+import io.kotest.matchers.types.beInstanceOf
+import io.mockk.MockKAnnotations
+import io.mockk.every
+import io.mockk.impl.annotations.MockK
+import io.mockk.just
+import io.mockk.runs
+import io.mockk.verify
+import kotlinx.coroutines.flow.flowOf
+import org.joda.time.DateTimeZone
+import org.joda.time.LocalDate
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.extension.ExtendWith
+import testhelpers.TestDispatcherProvider
+import testhelpers.extensions.InstantExecutorExtension
+import testhelpers.extensions.getOrAwaitValue
+
+@ExtendWith(InstantExecutorExtension::class)
+open class ContactDiaryOverviewViewModelTest {
+
+    @MockK lateinit var taskController: TaskController
+    @MockK lateinit var contactDiaryRepository: ContactDiaryRepository
+    @MockK lateinit var riskLevelStorage: RiskLevelStorage
+    private val testDispatcherProvider = TestDispatcherProvider()
+    private val date = LocalDate.now()
+    private val dateMillis = date.toDateTimeAtStartOfDay(DateTimeZone.UTC).millis
+
+    @BeforeEach
+    fun refresh() {
+        MockKAnnotations.init(this)
+
+        every { taskController.submit(any()) } just runs
+        every { contactDiaryRepository.locationVisits } returns flowOf(emptyList())
+        every { contactDiaryRepository.personEncounters } returns flowOf(emptyList())
+        every { riskLevelStorage.aggregatedRiskPerDateResults } returns flowOf(emptyList())
+    }
+
+    private val person = DefaultContactDiaryPerson(123, "Romeo")
+    private val location = DefaultContactDiaryLocation(124, "Rewe")
+    private val personEncounter = DefaultContactDiaryPersonEncounter(125, date, person)
+    private val locationVisit = DefaultContactDiaryLocationVisit(126, date, location)
+
+    private val aggregatedRiskPerDateResultLowRisk = AggregatedRiskPerDateResult(
+        dateMillisSinceEpoch = dateMillis,
+        riskLevel = RiskCalculationParametersOuterClass.NormalizedTimeToRiskLevelMapping.RiskLevel.LOW,
+        minimumDistinctEncountersWithLowRisk = 1,
+        minimumDistinctEncountersWithHighRisk = 0
+    )
+
+    private val aggregatedRiskPerDateResultLowRiskDueToHighRiskEncounter = AggregatedRiskPerDateResult(
+        dateMillisSinceEpoch = dateMillis,
+        riskLevel = RiskCalculationParametersOuterClass.NormalizedTimeToRiskLevelMapping.RiskLevel.HIGH,
+        minimumDistinctEncountersWithLowRisk = 0,
+        minimumDistinctEncountersWithHighRisk = 1
+    )
+
+    private val aggregatedRiskPerDateResultLowRiskDueToLowRiskEncounter = AggregatedRiskPerDateResult(
+        dateMillisSinceEpoch = dateMillis,
+        riskLevel = RiskCalculationParametersOuterClass.NormalizedTimeToRiskLevelMapping.RiskLevel.HIGH,
+        minimumDistinctEncountersWithLowRisk = 10,
+        minimumDistinctEncountersWithHighRisk = 0
+    )
+
+    fun createInstance(): ContactDiaryOverviewViewModel = ContactDiaryOverviewViewModel(
+        taskController = taskController,
+        dispatcherProvider = testDispatcherProvider,
+        contactDiaryRepository = contactDiaryRepository,
+        riskLevelStorage = riskLevelStorage
+    )
+
+    @Test
+    fun `submit clean task on init`() {
+        createInstance()
+
+        verify(exactly = 1) { taskController.submit(any()) }
+    }
+
+    @Test
+    fun `overview list lists all days as expected`() {
+        with(createInstance().listItems.getOrAwaitValue()) {
+            size shouldBe ContactDiaryOverviewViewModel.DAY_COUNT
+
+            var days = 0
+            forEach { it.date shouldBe date.minusDays(days++) }
+        }
+    }
+
+    @Test
+    fun `navigate back to main activity`() {
+        with(createInstance()) {
+            onBackButtonPress()
+            routeToScreen.getOrAwaitValue() shouldBe ContactDiaryOverviewNavigationEvents.NavigateToMainActivity
+        }
+    }
+
+    @Test
+    fun `navigate to day fragment with correct day`() {
+        val listItem = ListItem(date)
+
+        with(createInstance()) {
+            onItemPress(listItem)
+            val navigationEvent = routeToScreen.getOrAwaitValue()
+            navigationEvent should beInstanceOf(ContactDiaryOverviewNavigationEvents.NavigateToContactDiaryDayFragment::class)
+            navigationEvent as ContactDiaryOverviewNavigationEvents.NavigateToContactDiaryDayFragment
+            navigationEvent.localDateString shouldBe ContactDiaryOverviewNavigationEvents.NavigateToContactDiaryDayFragment(
+                listItem.date
+            ).localDateString
+        }
+    }
+
+    @Test
+    fun `low risk with person and location`() {
+        every { contactDiaryRepository.personEncounters } returns flowOf(listOf(personEncounter))
+        every { contactDiaryRepository.locationVisits } returns flowOf(listOf(locationVisit))
+        every { riskLevelStorage.aggregatedRiskPerDateResults } returns flowOf(listOf(aggregatedRiskPerDateResultLowRisk))
+
+        with(createInstance().listItems.getOrAwaitValue().first { it.date == date }) {
+            data.validate(
+                hasPerson = true,
+                hasLocation = true
+            )
+
+            risk!!.validate(
+                highRisk = false,
+                dueToLowEncounters = false,
+                hasPersonOrLocation = true
+            )
+        }
+    }
+
+    @Test
+    fun `low risk without person or location`() {
+        every { riskLevelStorage.aggregatedRiskPerDateResults } returns flowOf(listOf(aggregatedRiskPerDateResultLowRisk))
+
+        with(createInstance().listItems.getOrAwaitValue().first { it.date == date }) {
+            data.validate(
+                hasPerson = false,
+                hasLocation = false
+            )
+
+            risk!!.validate(
+                highRisk = false,
+                dueToLowEncounters = false,
+                hasPersonOrLocation = false
+            )
+        }
+    }
+
+    @Test
+    fun `high risk due to high risk encounter with person and location`() {
+        every { contactDiaryRepository.personEncounters } returns flowOf(listOf(personEncounter))
+        every { contactDiaryRepository.locationVisits } returns flowOf(listOf(locationVisit))
+        every { riskLevelStorage.aggregatedRiskPerDateResults } returns flowOf(
+            listOf(
+                aggregatedRiskPerDateResultLowRiskDueToHighRiskEncounter
+            )
+        )
+
+        with(createInstance().listItems.getOrAwaitValue().first { it.date == date }) {
+            data.validate(
+                hasPerson = true,
+                hasLocation = true
+            )
+
+            risk!!.validate(
+                highRisk = true,
+                dueToLowEncounters = false,
+                hasPersonOrLocation = true
+            )
+        }
+    }
+
+    @Test
+    fun `high risk due to high risk encounter without person or location`() {
+        every { riskLevelStorage.aggregatedRiskPerDateResults } returns flowOf(
+            listOf(
+                aggregatedRiskPerDateResultLowRiskDueToHighRiskEncounter
+            )
+        )
+
+        with(createInstance().listItems.getOrAwaitValue().first { it.date == date }) {
+            data.validate(
+                hasPerson = false,
+                hasLocation = false
+            )
+
+            risk!!.validate(
+                highRisk = true,
+                dueToLowEncounters = false,
+                hasPersonOrLocation = false
+            )
+        }
+    }
+
+    @Test
+    fun `high risk due to low risk encounter with person and location`() {
+        every { contactDiaryRepository.personEncounters } returns flowOf(listOf(personEncounter))
+        every { contactDiaryRepository.locationVisits } returns flowOf(listOf(locationVisit))
+        every { riskLevelStorage.aggregatedRiskPerDateResults } returns flowOf(
+            listOf(
+                aggregatedRiskPerDateResultLowRiskDueToLowRiskEncounter
+            )
+        )
+
+        with(createInstance().listItems.getOrAwaitValue().first { it.date == date }) {
+            data.validate(
+                hasPerson = true,
+                hasLocation = true
+            )
+
+            risk!!.validate(
+                highRisk = true,
+                dueToLowEncounters = true,
+                hasPersonOrLocation = true
+            )
+        }
+    }
+
+    @Test
+    fun `high risk due to low risk encounter without person or location`() {
+        every { riskLevelStorage.aggregatedRiskPerDateResults } returns flowOf(
+            listOf(
+                aggregatedRiskPerDateResultLowRiskDueToLowRiskEncounter
+            )
+        )
+
+        with(createInstance().listItems.getOrAwaitValue().first { it.date == date }) {
+            data.validate(
+                hasPerson = false,
+                hasLocation = false
+            )
+
+            risk!!.validate(
+                highRisk = true,
+                dueToLowEncounters = true,
+                hasPersonOrLocation = false
+            )
+        }
+    }
+
+    private fun List<ListItem.Data>.validate(hasPerson: Boolean, hasLocation: Boolean) {
+        var count = 0
+        if (hasPerson) count++
+        if (hasLocation) count++
+
+        size shouldBe count
+        forEach {
+            when (it.type) {
+                ListItem.Type.PERSON -> {
+                    it.drawableId shouldBe R.drawable.ic_contact_diary_person_item
+                }
+                ListItem.Type.LOCATION -> {
+                    it.drawableId shouldBe R.drawable.ic_contact_diary_location_item
+                }
+            }
+        }
+    }
+
+    private fun ListItem.Risk.validate(highRisk: Boolean, dueToLowEncounters: Boolean, hasPersonOrLocation: Boolean) {
+        when (highRisk) {
+            true -> {
+                title shouldBe R.string.contact_diary_high_risk_title
+                drawableId shouldBe R.drawable.ic_high_risk_alert
+                body shouldBe when (dueToLowEncounters) {
+                    true -> R.string.contact_diary_risk_body_high_risk_due_to_low_risk_encounters
+                    false -> R.string.contact_diary_risk_body
+                }
+            }
+            false -> {
+                title shouldBe R.string.contact_diary_low_risk_title
+                body shouldBe R.string.contact_diary_risk_body
+                drawableId shouldBe R.drawable.ic_low_risk_alert
+            }
+        }
+
+        bodyExtended shouldBe when (hasPersonOrLocation) {
+            true -> R.string.contact_diary_risk_body_extended
+            false -> null
+        }
+    }
+}