From 2cc5437499635e5faff14755e142c40b5c9333d4 Mon Sep 17 00:00:00 2001
From: Lukas Lechner <lukas.lechner@sap.com>
Date: Tue, 25 May 2021 14:09:33 +0200
Subject: [PATCH] Contact Diary data is written in clear text into error log on
 data deletion (EXPOSUREAPP-7408) (#3261)

* Censor people even after they got deleted in the contact diary

* Censor people encounters even after they got deleted in the contact diary

* Fix thread-safety

* Censor contact diary locations even when they got deleted previously

* Censor contact diary visits even when they got deleted previously

* Fix lint

* Censor checkIns even if they already got deleted

* Censor TraceLocations even if they already got deleted

* Censor RACoronaTests even if they already got deleted

* Adjust RatProfileCensorTest.kt

* Improve Thread-Safety of some censors

* Refactor CoronaTestCensor.kt

* Fix lint

* Fix DiaryEncounterCensor.kt

* Fix CheckInsCensorTest

* Fix CensorInjectionTest.kt

* Add mutex lock

Co-authored-by: harambasicluka <64483219+harambasicluka@users.noreply.github.com>
---
 .../contactdiary/DiaryEncounterCensor.kt      | 31 +++++++------
 .../contactdiary/DiaryLocationCensor.kt       | 30 ++++++------
 .../censors/contactdiary/DiaryPersonCensor.kt | 31 +++++++------
 .../censors/contactdiary/DiaryVisitCensor.kt  | 35 ++++++++------
 .../censors/presencetracing/CheckInsCensor.kt | 33 ++++++-------
 .../presencetracing/TraceLocationCensor.kt    | 33 ++++++-------
 .../censors/submission/CoronaTestCensor.kt    | 27 +++++------
 .../censors/submission/RACoronaTestCensor.kt  | 44 +++++++++---------
 .../censors/CensorInjectionTest.kt            | 21 +++++++--
 .../censors/CheckInsCensorTest.kt             | 42 +++++++++++++++--
 .../censors/DiaryEncounterCensorTest.kt       | 26 ++++++++++-
 .../censors/DiaryLocationCensorTest.kt        | 25 +++++++++-
 .../censors/DiaryPersonCensorTest.kt          | 26 ++++++++++-
 .../censors/DiaryVisitCensorTest.kt           | 24 +++++++++-
 .../censors/RACoronaTestCensorTest.kt         | 30 +++++++++---
 .../censors/TraceLocationCensorTest.kt        | 46 +++++++++++++++++--
 .../submission/RatProfileCensorTest.kt        | 13 +++++-
 17 files changed, 366 insertions(+), 151 deletions(-)

diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryEncounterCensor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryEncounterCensor.kt
index 0814fd1f7..63c6cfc42 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryEncounterCensor.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryEncounterCensor.kt
@@ -8,12 +8,13 @@ import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.plus
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.toNullIfUnmodified
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidComment
 import de.rki.coronawarnapp.bugreporting.debuglog.internal.DebuggerScope
+import de.rki.coronawarnapp.contactdiary.model.ContactDiaryPersonEncounter
 import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.filterNotNull
-import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.sync.Mutex
+import kotlinx.coroutines.sync.withLock
 import javax.inject.Inject
 
 @Reusable
@@ -22,20 +23,22 @@ class DiaryEncounterCensor @Inject constructor(
     diary: ContactDiaryRepository
 ) : BugCensor {
 
-    private val encounters by lazy {
-        diary.personEncounters.stateIn(
-            scope = debugScope,
-            started = SharingStarted.Lazily,
-            initialValue = null
-        ).filterNotNull()
+    // We keep a history of all encounters so that we can censor them even after they got deleted
+    private val encounterHistory = mutableSetOf<ContactDiaryPersonEncounter>()
+
+    val mutex = Mutex()
+
+    init {
+        diary.personEncounters
+            .onEach { mutex.withLock { encounterHistory.addAll(it) } }
+            .launchIn(debugScope)
     }
 
-    override suspend fun checkLog(message: String): CensoredString? {
-        val encountersNow = encounters.first().filter { !it.circumstances.isNullOrBlank() }
+    override suspend fun checkLog(message: String): CensoredString? = mutex.withLock {
 
-        if (encountersNow.isEmpty()) return null
+        if (encounterHistory.isEmpty()) return null
 
-        val newMessage = encountersNow.fold(CensoredString(message)) { orig, encounter ->
+        val newMessage = encounterHistory.fold(CensoredString(message)) { orig, encounter ->
             var wip = orig
 
             withValidComment(encounter.circumstances) {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryLocationCensor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryLocationCensor.kt
index 1ee602135..e1439a50c 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryLocationCensor.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryLocationCensor.kt
@@ -10,12 +10,13 @@ import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidEm
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidName
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidPhoneNumber
 import de.rki.coronawarnapp.bugreporting.debuglog.internal.DebuggerScope
+import de.rki.coronawarnapp.contactdiary.model.ContactDiaryLocation
 import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.filterNotNull
-import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.sync.Mutex
+import kotlinx.coroutines.sync.withLock
 import javax.inject.Inject
 
 @Reusable
@@ -24,20 +25,21 @@ class DiaryLocationCensor @Inject constructor(
     diary: ContactDiaryRepository
 ) : BugCensor {
 
-    private val locations by lazy {
-        diary.locations.stateIn(
-            scope = debugScope,
-            started = SharingStarted.Lazily,
-            initialValue = null
-        ).filterNotNull()
+    private val mutex = Mutex()
+
+    private var locationHistory = mutableSetOf<ContactDiaryLocation>()
+
+    init {
+        diary.locations
+            .onEach { mutex.withLock { locationHistory.addAll(it) } }
+            .launchIn(debugScope)
     }
 
-    override suspend fun checkLog(message: String): CensoredString? {
-        val locationsNow = locations.first()
+    override suspend fun checkLog(message: String): CensoredString? = mutex.withLock {
 
-        if (locationsNow.isEmpty()) return null
+        if (locationHistory.isEmpty()) return null
 
-        val newMessage = locationsNow.fold(CensoredString(message)) { orig, location ->
+        val newMessage = locationHistory.fold(CensoredString(message)) { orig, location ->
             var wip = orig
 
             withValidName(location.locationName) {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryPersonCensor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryPersonCensor.kt
index d525cde21..52f542fc4 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryPersonCensor.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryPersonCensor.kt
@@ -10,12 +10,13 @@ import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidEm
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidName
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidPhoneNumber
 import de.rki.coronawarnapp.bugreporting.debuglog.internal.DebuggerScope
+import de.rki.coronawarnapp.contactdiary.model.ContactDiaryPerson
 import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.filterNotNull
-import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.sync.Mutex
+import kotlinx.coroutines.sync.withLock
 import javax.inject.Inject
 
 @Reusable
@@ -24,20 +25,22 @@ class DiaryPersonCensor @Inject constructor(
     diary: ContactDiaryRepository
 ) : BugCensor {
 
-    private val persons by lazy {
-        diary.people.stateIn(
-            scope = debugScope,
-            started = SharingStarted.Lazily,
-            initialValue = null
-        ).filterNotNull()
+    private val mutex = Mutex()
+
+    // We keep a history of all persons so that we can censor them even after they got deleted
+    private val personHistory = mutableSetOf<ContactDiaryPerson>()
+
+    init {
+        diary.people
+            .onEach { mutex.withLock { personHistory.addAll(it) } }
+            .launchIn(debugScope)
     }
 
-    override suspend fun checkLog(message: String): CensoredString? {
-        val personsNow = persons.first()
+    override suspend fun checkLog(message: String): CensoredString? = mutex.withLock {
 
-        if (personsNow.isEmpty()) return null
+        if (personHistory.isEmpty()) return null
 
-        val newMessage = personsNow.fold(CensoredString(message)) { orig, person ->
+        val newMessage = personHistory.fold(CensoredString(message)) { orig, person ->
             var wip = orig
 
             withValidName(person.fullName) {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryVisitCensor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryVisitCensor.kt
index 61398937d..f08bfc69d 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryVisitCensor.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryVisitCensor.kt
@@ -7,12 +7,13 @@ import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.censor
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.plus
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.toNullIfUnmodified
 import de.rki.coronawarnapp.bugreporting.debuglog.internal.DebuggerScope
+import de.rki.coronawarnapp.contactdiary.model.ContactDiaryLocationVisit
 import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.filterNotNull
-import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.sync.Mutex
+import kotlinx.coroutines.sync.withLock
 import javax.inject.Inject
 
 @Reusable
@@ -21,20 +22,26 @@ class DiaryVisitCensor @Inject constructor(
     diary: ContactDiaryRepository
 ) : BugCensor {
 
-    private val visits by lazy {
-        diary.locationVisits.stateIn(
-            scope = debugScope,
-            started = SharingStarted.Lazily,
-            initialValue = null
-        ).filterNotNull()
+    private val mutex = Mutex()
+
+    private val visitsHistory = mutableSetOf<ContactDiaryLocationVisit>()
+
+    init {
+        diary.locationVisits
+            .onEach { locationVisitList ->
+                val visitsWithCircumstances = locationVisitList.filterNot { it.circumstances.isNullOrBlank() }
+                mutex.withLock {
+                    visitsHistory.addAll(visitsWithCircumstances)
+                }
+            }
+            .launchIn(debugScope)
     }
 
-    override suspend fun checkLog(message: String): CensoredString? {
-        val visitsNow = visits.first().filter { !it.circumstances.isNullOrBlank() }
+    override suspend fun checkLog(message: String): CensoredString? = mutex.withLock {
 
-        if (visitsNow.isEmpty()) return null
+        if (visitsHistory.isEmpty()) return null
 
-        val newMessage = visitsNow.fold(CensoredString(message)) { orig, visit ->
+        val newMessage = visitsHistory.fold(CensoredString(message)) { orig, visit ->
             var wip = orig
 
             BugCensor.withValidComment(visit.circumstances) {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/presencetracing/CheckInsCensor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/presencetracing/CheckInsCensor.kt
index 018f5208b..7cbede14a 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/presencetracing/CheckInsCensor.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/presencetracing/CheckInsCensor.kt
@@ -9,35 +9,36 @@ import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.toNullIfUnm
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidAddress
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidDescription
 import de.rki.coronawarnapp.bugreporting.debuglog.internal.DebuggerScope
+import de.rki.coronawarnapp.presencetracing.checkins.CheckIn
 import de.rki.coronawarnapp.presencetracing.checkins.CheckInRepository
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.filterNotNull
-import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.sync.Mutex
+import kotlinx.coroutines.sync.withLock
 import javax.inject.Inject
 
 @Reusable
 class CheckInsCensor @Inject constructor(
     @DebuggerScope debugScope: CoroutineScope,
-    private val checkInRepository: CheckInRepository
+    checkInRepository: CheckInRepository
 ) : BugCensor {
 
-    private val checkInsFlow by lazy {
-        checkInRepository.allCheckIns.stateIn(
-            scope = debugScope,
-            started = SharingStarted.Lazily,
-            initialValue = null
-        ).filterNotNull()
-    }
+    private val mutex = Mutex()
+
+    private val checkInsHistory = mutableSetOf<CheckIn>()
 
-    override suspend fun checkLog(message: String): CensoredString? {
+    init {
+        checkInRepository.allCheckIns
+            .onEach { mutex.withLock { checkInsHistory.addAll(it) } }
+            .launchIn(debugScope)
+    }
 
-        val checkIns = checkInsFlow.first()
+    override suspend fun checkLog(message: String): CensoredString? = mutex.withLock {
 
-        if (checkIns.isEmpty()) return null
+        if (checkInsHistory.isEmpty()) return null
 
-        val newLogMsg = checkIns.fold(CensoredString(message)) { initial, checkIn ->
+        val newLogMsg = checkInsHistory.fold(CensoredString(message)) { initial, checkIn ->
 
             var acc = initial
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/presencetracing/TraceLocationCensor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/presencetracing/TraceLocationCensor.kt
index 5f702727e..cae77e407 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/presencetracing/TraceLocationCensor.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/presencetracing/TraceLocationCensor.kt
@@ -9,19 +9,20 @@ import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.toNullIfUnm
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidAddress
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidDescription
 import de.rki.coronawarnapp.bugreporting.debuglog.internal.DebuggerScope
+import de.rki.coronawarnapp.presencetracing.checkins.qrcode.TraceLocation
 import de.rki.coronawarnapp.presencetracing.locations.TraceLocationUserInput
 import de.rki.coronawarnapp.presencetracing.storage.repo.TraceLocationRepository
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.filterNotNull
-import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.sync.Mutex
+import kotlinx.coroutines.sync.withLock
 import javax.inject.Inject
 
 /**
  * Censors Trace Location Data
  *
- * The information about which data to censor comes from two places
+ * The information about what data to censor comes from two places
  * - traceLocationRepository, for traceLocations that are already stored
  * - dataToCensor, which is set before a traceLocation is created; this is needed in cases when the app crashes between
  * data input and storing
@@ -29,22 +30,22 @@ import javax.inject.Inject
 @Reusable
 class TraceLocationCensor @Inject constructor(
     @DebuggerScope debugScope: CoroutineScope,
-    private val traceLocationRepository: TraceLocationRepository
+    traceLocationRepository: TraceLocationRepository
 ) : BugCensor {
 
-    private val traceLocationsFlow by lazy {
-        traceLocationRepository.allTraceLocations.stateIn(
-            scope = debugScope,
-            started = SharingStarted.Lazily,
-            initialValue = null
-        ).filterNotNull()
-    }
+    private val mutex = Mutex()
+
+    private val traceLocationHistory = mutableSetOf<TraceLocation>()
 
-    override suspend fun checkLog(message: String): CensoredString? {
+    init {
+        traceLocationRepository.allTraceLocations
+            .onEach { mutex.withLock { traceLocationHistory.addAll(it) } }
+            .launchIn(debugScope)
+    }
 
-        val traceLocations = traceLocationsFlow.first()
+    override suspend fun checkLog(message: String): CensoredString? = mutex.withLock {
 
-        var newLogMsg = traceLocations.fold(CensoredString(message)) { initial, traceLocation ->
+        var newLogMsg = traceLocationHistory.fold(CensoredString(message)) { initial, traceLocation ->
             var acc = initial
 
             acc += acc.censor(traceLocation.type.name, "TraceLocation#${traceLocation.id}/Type")
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/submission/CoronaTestCensor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/submission/CoronaTestCensor.kt
index ccac2fe3d..ea9d31a4f 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/submission/CoronaTestCensor.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/submission/CoronaTestCensor.kt
@@ -9,11 +9,9 @@ import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.toNullIfUnm
 import de.rki.coronawarnapp.bugreporting.debuglog.internal.DebuggerScope
 import de.rki.coronawarnapp.coronatest.CoronaTestRepository
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.filterNotNull
-import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.sync.Mutex
 import kotlinx.coroutines.sync.withLock
 import javax.inject.Inject
@@ -21,7 +19,7 @@ import javax.inject.Inject
 @Reusable
 class CoronaTestCensor @Inject constructor(
     @DebuggerScope debugScope: CoroutineScope,
-    private val coronaTestRepository: CoronaTestRepository,
+    coronaTestRepository: CoronaTestRepository,
 ) : BugCensor {
 
     private val mutex = Mutex()
@@ -30,20 +28,19 @@ class CoronaTestCensor @Inject constructor(
     private val tokenHistory = mutableSetOf<String>()
     private val identifierHistory = mutableSetOf<String>()
 
-    private val coronaTestFlow by lazy {
-        coronaTestRepository.coronaTests.stateIn(
-            scope = debugScope,
-            started = SharingStarted.Lazily,
-            initialValue = null
-        ).filterNotNull().onEach { tests ->
-            // The Registration Token is received after registration of PCR and RAT tests. It is required to poll the test result.
-            tokenHistory.addAll(tests.map { it.registrationToken })
-            identifierHistory.addAll(tests.map { it.identifier })
-        }
+    init {
+        coronaTestRepository.coronaTests
+            .filterNotNull()
+            .onEach { tests ->
+                mutex.withLock {
+                    // The Registration Token is received after registration of PCR and RAT tests. It is required to poll the test result.
+                    tokenHistory.addAll(tests.map { it.registrationToken })
+                    identifierHistory.addAll(tests.map { it.identifier })
+                }
+            }.launchIn(debugScope)
     }
 
     override suspend fun checkLog(message: String): CensoredString? = mutex.withLock {
-        coronaTestFlow.first()
 
         var newMessage = CensoredString(message)
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/submission/RACoronaTestCensor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/submission/RACoronaTestCensor.kt
index fff347294..b2eff3186 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/submission/RACoronaTestCensor.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/submission/RACoronaTestCensor.kt
@@ -10,48 +10,50 @@ import de.rki.coronawarnapp.bugreporting.debuglog.internal.DebuggerScope
 import de.rki.coronawarnapp.coronatest.CoronaTestRepository
 import de.rki.coronawarnapp.coronatest.type.rapidantigen.RACoronaTest
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.filterNotNull
-import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.sync.Mutex
+import kotlinx.coroutines.sync.withLock
 import org.joda.time.format.DateTimeFormat
 import javax.inject.Inject
 
 class RACoronaTestCensor @Inject constructor(
     @DebuggerScope debugScope: CoroutineScope,
-    private val coronaTestRepository: CoronaTestRepository
+    coronaTestRepository: CoronaTestRepository
 ) : BugCensor {
 
+    private val mutex = Mutex()
+
     private val dayOfBirthFormatter = DateTimeFormat.forPattern("yyyy-MM-dd")
 
-    private val coronaTestFlow by lazy {
-        coronaTestRepository.coronaTests.stateIn(
-            scope = debugScope,
-            started = SharingStarted.Lazily,
-            initialValue = null
-        ).filterNotNull()
-    }
+    // We keep a history of rat corona test so that we are able to censor even after they got deleted
+    private val ratCoronaTestHistory = mutableSetOf<RACoronaTest>()
 
-    override suspend fun checkLog(message: String): CensoredString? {
+    init {
+        coronaTestRepository
+            .coronaTests
+            .map { it.filterIsInstance<RACoronaTest>() }
+            .onEach { mutex.withLock { ratCoronaTestHistory.addAll(it) } }
+            .launchIn(debugScope)
+    }
 
-        val raCoronaTestFlow = coronaTestFlow.map { tests -> tests.filterIsInstance<RACoronaTest>() }.first()
-        val raCoronaTest = raCoronaTestFlow.firstOrNull() ?: return null
+    override suspend fun checkLog(message: String): CensoredString? = mutex.withLock {
 
         var newMessage = CensoredString(message)
 
-        with(raCoronaTest) {
-            withValidName(firstName) { firstName ->
+        ratCoronaTestHistory.forEach { ratCoronaTest ->
+            withValidName(ratCoronaTest.firstName) { firstName ->
                 newMessage += newMessage.censor(firstName, "RATest/FirstName")
             }
 
-            withValidName(lastName) { lastName ->
+            withValidName(ratCoronaTest.lastName) { lastName ->
                 newMessage += newMessage.censor(lastName, "RATest/LastName")
             }
 
-            val dateOfBirthString = dateOfBirth?.toString(dayOfBirthFormatter) ?: return@with
-
-            newMessage += newMessage.censor(dateOfBirthString, "RATest/DateOfBirth")
+            ratCoronaTest.dateOfBirth?.toString(dayOfBirthFormatter)?.let { dateOfBirthString ->
+                newMessage += newMessage.censor(dateOfBirthString, "RATest/DateOfBirth")
+            }
         }
 
         return newMessage.toNullIfUnmodified()
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/CensorInjectionTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/CensorInjectionTest.kt
index cf4989e79..915ca4bb0 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/CensorInjectionTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/CensorInjectionTest.kt
@@ -13,7 +13,9 @@ import de.rki.coronawarnapp.submission.SubmissionSettings
 import io.github.classgraph.ClassGraph
 import io.kotest.matchers.collections.shouldContainAll
 import io.kotest.matchers.shouldBe
+import io.mockk.every
 import io.mockk.mockk
+import kotlinx.coroutines.flow.flowOf
 import org.junit.jupiter.api.Test
 import testhelpers.BaseTest
 import timber.log.Timber
@@ -67,7 +69,12 @@ class MockProvider {
 
     @Singleton
     @Provides
-    fun diary(): ContactDiaryRepository = mockk()
+    fun diary(): ContactDiaryRepository = mockk() {
+        every { people } returns flowOf(emptyList())
+        every { personEncounters } returns flowOf(emptyList())
+        every { locations } returns flowOf(emptyList())
+        every { locationVisits } returns flowOf(emptyList())
+    }
 
     @Singleton
     @Provides
@@ -75,15 +82,21 @@ class MockProvider {
 
     @Singleton
     @Provides
-    fun coronaTestRepository(): CoronaTestRepository = mockk()
+    fun coronaTestRepository(): CoronaTestRepository = mockk() {
+        every { coronaTests } returns flowOf(emptySet())
+    }
 
     @Singleton
     @Provides
-    fun checkInRepository(): CheckInRepository = mockk()
+    fun checkInRepository(): CheckInRepository = mockk() {
+        every { allCheckIns } returns flowOf(emptyList())
+    }
 
     @Singleton
     @Provides
-    fun traceLocationRepository(): TraceLocationRepository = mockk()
+    fun traceLocationRepository(): TraceLocationRepository = mockk() {
+        every { allTraceLocations } returns flowOf(emptyList())
+    }
 
     @Singleton
     @Provides
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/CheckInsCensorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/CheckInsCensorTest.kt
index 9965c6215..b49f0ac8a 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/CheckInsCensorTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/CheckInsCensorTest.kt
@@ -11,6 +11,7 @@ import io.mockk.mockk
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.runBlockingTest
 import org.junit.jupiter.api.BeforeEach
 import org.junit.jupiter.api.Test
 import testhelpers.BaseTest
@@ -40,7 +41,7 @@ internal class CheckInsCensorTest : BaseTest() {
     }
 
     @Test
-    fun `checkLog() should return LogLine with censored check-in information`() = runBlocking {
+    fun `checkLog() should return LogLine with censored check-in information`() = runBlockingTest {
         every { checkInsRepo.allCheckIns } returns flowOf(
             listOf(
                 mockCheckIn(
@@ -68,9 +69,44 @@ internal class CheckInsCensorTest : BaseTest() {
             Let's go to CheckIn#1/Description in CheckIn#1/Address.
             Who needs the CheckIn#2/Description in CheckIn#2/Address? I doooo!
         """.trimIndent()
+    }
 
-        // censoring should still work after user deletes his check-ins
-        every { checkInsRepo.allCheckIns } returns flowOf(emptyList())
+    @Test
+    fun `censoring should still work after user deletes his check-ins`() = runBlockingTest {
+        every { checkInsRepo.allCheckIns } returns flowOf(
+            listOf(
+                mockCheckIn(
+                    checkInId = 1,
+                    checkInDescription = "Moe's Tavern",
+                    checkInAddress = "Near 742 Evergreen Terrace, 12345 Springfield"
+                ),
+                mockCheckIn(
+                    checkInId = 2,
+                    checkInDescription = "Kwik-E-Mart",
+                    checkInAddress = "Some Street, 12345 Springfield"
+                )
+            ),
+            listOf(
+                mockCheckIn(
+                    checkInId = 1,
+                    checkInDescription = "Moe's Tavern",
+                    checkInAddress = "Near 742 Evergreen Terrace, 12345 Springfield"
+                ),
+                            /* deleted: mockCheckIn(
+                    checkInId = 2,
+                    checkInDescription = "Kwik-E-Mart",
+                    checkInAddress = "Some Street, 12345 Springfield"
+                )*/
+            )
+        )
+
+        val censor = createInstance(this)
+
+        val logLineToCensor =
+            """
+            Let's go to Moe's Tavern in Near 742 Evergreen Terrace, 12345 Springfield.
+            Who needs the Kwik-E-Mart in Some Street, 12345 Springfield? I doooo!
+            """.trimIndent()
 
         censor.checkLog(logLineToCensor)!!.string shouldBe """
             Let's go to CheckIn#1/Description in CheckIn#1/Address.
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/DiaryEncounterCensorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/DiaryEncounterCensorTest.kt
index 5f7b72554..75740a998 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/DiaryEncounterCensorTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/DiaryEncounterCensorTest.kt
@@ -63,9 +63,31 @@ class DiaryEncounterCensorTest : BaseTest() {
             two persons Encounter#3/Circumstances,
             everyone disliked that.
             """.trimIndent()
+    }
+
+    @Test
+    fun `censoring should still work after encounters are deleted`() = runBlockingTest {
+        every { diaryRepo.personEncounters } returns flowOf(
+            listOf(
+                mockEncounter(1, _circumstances = ""),
+                mockEncounter(2, _circumstances = "A rainy day"),
+                mockEncounter(3, "Spilled coffee on each others laptops")
+            ),
+            listOf(
+                mockEncounter(1, _circumstances = ""),
+                // "a rainy day" was deleted
+                mockEncounter(3, "Spilled coffee on each others laptops")
+            )
+        )
+
+        val instance = createInstance(this)
+        val censorMe =
+            """
+            On A rainy day,
+            two persons Spilled coffee on each others laptops,
+            everyone disliked that.
+            """.trimIndent()
 
-        // censoring should still work after encounters are deleted
-        every { diaryRepo.personEncounters } returns flowOf(emptyList())
         instance.checkLog(censorMe)!!.string shouldBe
             """
             On Encounter#2/Circumstances,
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/DiaryLocationCensorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/DiaryLocationCensorTest.kt
index c708da370..fbc4cd1af 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/DiaryLocationCensorTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/DiaryLocationCensorTest.kt
@@ -65,9 +65,30 @@ class DiaryLocationCensorTest : BaseTest() {
             Both agreed that their emails (Location#1/EMail|Location#3/EMail) are awesome,
             and that Location#2/Name doesn't exist as it has neither phonenumber (null) nor email (null).
             """.trimIndent()
+    }
 
-        // censoring should still work after locations are deleted
-        every { diaryRepo.locations } returns flowOf(emptyList())
+    @Test
+    fun `censoring should still work after locations are deleted`() = runBlockingTest {
+        every { diaryRepo.locations } returns flowOf(
+            listOf(
+                mockLocation(1, "Munich", phone = "+49 089 3333", mail = "bürgermeister@münchen.de"),
+                mockLocation(2, "Bielefeld", phone = null, mail = null),
+                mockLocation(3, "Aachen", phone = "+49 0241 9999", mail = "karl@aachen.de")
+            ),
+            listOf(
+                mockLocation(1, "Munich", phone = "+49 089 3333", mail = "bürgermeister@münchen.de"),
+                // Bielefeld was deleted
+                mockLocation(3, "Aachen", phone = "+49 0241 9999", mail = "karl@aachen.de")
+            )
+        )
+
+        val instance = createInstance(this)
+        val censorMe =
+            """
+            Bürgermeister of Munich (+49 089 3333) and Karl of Aachen [+49 0241 9999] called each other.
+            Both agreed that their emails (bürgermeister@münchen.de|karl@aachen.de) are awesome,
+            and that Bielefeld doesn't exist as it has neither phonenumber (null) nor email (null).
+            """.trimIndent()
         instance.checkLog(censorMe)!!.string shouldBe
             """
             Bürgermeister of Location#1/Name (Location#1/PhoneNumber) and Karl of Location#3/Name [Location#3/PhoneNumber] called each other.
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/DiaryPersonCensorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/DiaryPersonCensorTest.kt
index 240c80f3c..1d8ccac54 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/DiaryPersonCensorTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/DiaryPersonCensorTest.kt
@@ -66,9 +66,31 @@ class DiaryPersonCensorTest : BaseTest() {
             but Person#3/Name thought he had enough has had enough for today.
             A quick mail to Person#1/EMail confirmed this.
             """.trimIndent()
+    }
+
+    @Test
+    fun `censoring should still work after people are deleted`() = runBlockingTest {
+        every { diaryRepo.people } returns flowOf(
+            listOf(
+                mockPerson(1, "Luka", phone = "+49 1234 7777", mail = "luka@sap.com"),
+                mockPerson(2, "Ralf", phone = null, mail = null),
+                mockPerson(3, "Matthias", phone = null, mail = "matthias@sap.com")
+            ),
+            listOf(
+                mockPerson(1, "Luka", phone = "+49 1234 7777", mail = "luka@sap.com"),
+                mockPerson(2, "Ralf", phone = null, mail = null),
+                // Matthias was deleted
+            )
+        )
+
+        val instance = createInstance(this)
+        val censorMe =
+            """
+            Ralf requested more coffee from +49 1234 7777,
+            but Matthias thought he had enough has had enough for today.
+            A quick mail to luka@sap.com confirmed this.
+            """.trimIndent()
 
-        // censoring should still work after people are deleted
-        every { diaryRepo.people } returns flowOf(emptyList())
         instance.checkLog(censorMe)!!.string shouldBe
             """
             Person#2/Name requested more coffee from Person#1/PhoneNumber,
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/DiaryVisitCensorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/DiaryVisitCensorTest.kt
index cdd31e2a5..3f554b853 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/DiaryVisitCensorTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/DiaryVisitCensorTest.kt
@@ -61,9 +61,29 @@ class DiaryVisitCensorTest : BaseTest() {
             I got my Visit#2/Circumstances,
             only to find out the supermarket was Visit#3/Circumstances.
             """.trimIndent()
+    }
 
-        // censoring should still work even after visits are deleted
-        every { diaryRepo.locationVisits } returns flowOf(emptyList())
+    @Test
+    fun `censor should still work even after visits are deleted`() = runBlockingTest {
+        every { diaryRepo.locationVisits } returns flowOf(
+            listOf(
+                mockVisit(1, _circumstances = "Döner that was too spicy"),
+                mockVisit(2, _circumstances = "beard shaved without mask"),
+                mockVisit(3, _circumstances = "out of toiletpaper")
+            ),
+            listOf(
+                mockVisit(1, _circumstances = "Döner that was too spicy"),
+                // mockVisit(2, _circumstances = "beard shaved without mask"), => deleted
+                mockVisit(3, _circumstances = "out of toiletpaper")
+            )
+        )
+        val instance = createInstance(this)
+        val censorMe =
+            """
+            After having a Döner that was too spicy,
+            I got my beard shaved without mask,
+            only to find out the supermarket was out of toiletpaper.
+            """.trimIndent()
         instance.checkLog(censorMe)!!.string shouldBe
             """
             After having a Visit#1/Circumstances,
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/RACoronaTestCensorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/RACoronaTestCensorTest.kt
index 3a4e06d93..fa2b323d3 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/RACoronaTestCensorTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/RACoronaTestCensorTest.kt
@@ -11,6 +11,7 @@ import io.mockk.mockk
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.runBlockingTest
 import org.joda.time.LocalDate
 import org.junit.jupiter.api.BeforeEach
 import org.junit.jupiter.api.Test
@@ -31,7 +32,7 @@ internal class RACoronaTestCensorTest : BaseTest() {
     )
 
     @Test
-    fun `checkLog() should return censored LogLine`() = runBlocking {
+    fun `checkLog() should return censored LogLine`() = runBlockingTest {
         every { coronaTestRepository.coronaTests } returns flowOf(
             setOf(
                 mockk<RACoronaTest>().apply {
@@ -53,9 +54,28 @@ internal class RACoronaTestCensorTest : BaseTest() {
             """
             Hello! My name is RATest/FirstName. My friends call me Mister RATest/LastName and I was born on RATest/DateOfBirth.
             """.trimIndent()
+    }
 
-        // censoring should still work when test gets deleted
-        every { coronaTestRepository.coronaTests } returns flowOf(emptySet())
+    @Test
+    fun `censoring should still work when test gets deleted`() = runBlockingTest {
+        every { coronaTestRepository.coronaTests } returns flowOf(
+            setOf(
+                mockk<RACoronaTest>().apply {
+                    every { firstName } returns "John"
+                    every { lastName } returns "Doe"
+                    every { dateOfBirth } returns LocalDate.parse("2020-01-01")
+                }
+            ),
+            // Test got deleted
+            emptySet()
+        )
+
+        val censor = createInstance(this)
+
+        val logLineToCensor =
+            """
+            Hello! My name is John. My friends call me Mister Doe and I was born on 2020-01-01.
+            """.trimIndent()
 
         censor.checkLog(logLineToCensor)!!.string shouldBe
             """
@@ -91,8 +111,4 @@ internal class RACoronaTestCensorTest : BaseTest() {
         val logLine = "Lorem ipsum"
         censor.checkLog(logLine) shouldBe null
     }
-
-    @Test
-    fun `censoring should still work when test gets deleted`() {
-    }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/TraceLocationCensorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/TraceLocationCensorTest.kt
index 92bd63b96..cb123802a 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/TraceLocationCensorTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/TraceLocationCensorTest.kt
@@ -51,7 +51,7 @@ internal class TraceLocationCensorTest : BaseTest() {
     }
 
     @Test
-    fun `checkLog() should return LogLine with censored trace location information from repository`() = runBlocking {
+    fun `checkLog() should return LogLine with censored trace location information from repository`() = runBlockingTest {
         every { traceLocationRepo.allTraceLocations } returns flowOf(
             listOf(
                 mockTraceLocation(
@@ -82,9 +82,49 @@ internal class TraceLocationCensorTest : BaseTest() {
             The type is TraceLocation#2/Type. Yesterday we went to the TraceLocation#2/Description. The spectacle took place in TraceLocation#2/Address. 
             Afterwards we had some food in TraceLocation#1/Description in TraceLocation#1/Address. It a nice TraceLocation#1/Type.
             """.trimIndent()
+    }
 
-        // censoring should still work after the user deletes his trace locations
-        every { traceLocationRepo.allTraceLocations } returns flowOf(emptyList())
+    @Test
+    fun `censoring should still work after the user deletes his trace locations`() = runBlockingTest {
+
+        every { traceLocationRepo.allTraceLocations } returns flowOf(
+            listOf(
+                mockTraceLocation(
+                    traceLocationId = 1,
+                    traceLocationType = TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_PERMANENT_FOOD_SERVICE,
+                    traceLocationDescription = "Sushi Place",
+                    traceLocationAddress = "Sushi Street 123, 12345 Fish Town"
+                ),
+                mockTraceLocation(
+                    traceLocationId = 2,
+                    traceLocationType = TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_TEMPORARY_CULTURAL_EVENT,
+                    traceLocationDescription = "Rick Astley Concert",
+                    traceLocationAddress = "Never gonna give you up street 1, 12345 RickRoll City"
+                )
+            ),
+            listOf(
+                mockTraceLocation(
+                    traceLocationId = 1,
+                    traceLocationType = TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_PERMANENT_FOOD_SERVICE,
+                    traceLocationDescription = "Sushi Place",
+                    traceLocationAddress = "Sushi Street 123, 12345 Fish Town"
+                ),
+                /* deleted: mockTraceLocation(
+                    traceLocationId = 2,
+                    traceLocationType = TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_TEMPORARY_CULTURAL_EVENT,
+                    traceLocationDescription = "Rick Astley Concert",
+                    traceLocationAddress = "Never gonna give you up street 1, 12345 RickRoll City"
+                )*/
+            )
+        )
+
+        val censor = createInstance(this)
+
+        val logLineToCensor =
+            """
+            The type is LOCATION_TYPE_TEMPORARY_CULTURAL_EVENT. Yesterday we went to the Rick Astley Concert. The spectacle took place in Never gonna give you up street 1, 12345 RickRoll City. 
+            Afterwards we had some food in Sushi Place in Sushi Street 123, 12345 Fish Town. It a nice LOCATION_TYPE_PERMANENT_FOOD_SERVICE.
+            """.trimIndent()
 
         censor.checkLog(logLineToCensor)!!.string shouldBe
             """
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/submission/RatProfileCensorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/submission/RatProfileCensorTest.kt
index 2134750ac..9954cd867 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/submission/RatProfileCensorTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/submission/RatProfileCensorTest.kt
@@ -8,6 +8,7 @@ import io.mockk.every
 import io.mockk.impl.annotations.MockK
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.runBlockingTest
 import org.joda.time.format.DateTimeFormat
 import org.junit.jupiter.api.BeforeEach
 import org.junit.jupiter.api.Test
@@ -61,9 +62,17 @@ internal class RatProfileCensorTest : BaseTest() {
         censor.checkLog(logLine)!!.string shouldBe
             "Mister RAT-Profile/FirstName who is also known as RAT-Profile/LastName and is born on RAT-Profile/DateOfBirth lives in RAT-Profile/Street, " +
             "RAT-Profile/Zip-Code in the beautiful city of RAT-Profile/City. You can reach him by phone: RAT-Profile/Phone or email: RAT-Profile/eMail"
+    }
 
-        // censoring should still work after the user deletes his profile
-        every { ratProfileSettings.profile.flow } returns flowOf(null)
+    @Test
+    fun `censoring should still work after the user deletes his profile`() = runBlockingTest {
+        every { ratProfileSettings.profile.flow } returns flowOf(profile, null)
+
+        val censor = createInstance()
+
+        val logLine =
+            "Mister First name who is also known as Last name and is born on 1950-08-01 lives in Main street, " +
+                "12132 in the beautiful city of London. You can reach him by phone: 111111111 or email: email@example.com"
 
         censor.checkLog(logLine)!!.string shouldBe
             "Mister RAT-Profile/FirstName who is also known as RAT-Profile/LastName and is born on RAT-Profile/DateOfBirth lives in RAT-Profile/Street, " +
-- 
GitLab