diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/BugReportingSharedModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/BugReportingSharedModule.kt
index a090b59fadb6860df156d971cc1056565ec12163..638bc4082866a671d4fa8b1222f3da2111faf573 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/BugReportingSharedModule.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/BugReportingSharedModule.kt
@@ -5,12 +5,17 @@ import dagger.Provides
 import dagger.Reusable
 import dagger.multibindings.IntoSet
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor
-import de.rki.coronawarnapp.bugreporting.censors.DiaryEncounterCensor
-import de.rki.coronawarnapp.bugreporting.censors.DiaryLocationCensor
-import de.rki.coronawarnapp.bugreporting.censors.DiaryPersonCensor
-import de.rki.coronawarnapp.bugreporting.censors.DiaryVisitCensor
-import de.rki.coronawarnapp.bugreporting.censors.QRCodeCensor
-import de.rki.coronawarnapp.bugreporting.censors.RegistrationTokenCensor
+import de.rki.coronawarnapp.bugreporting.censors.contactdiary.DiaryEncounterCensor
+import de.rki.coronawarnapp.bugreporting.censors.contactdiary.DiaryLocationCensor
+import de.rki.coronawarnapp.bugreporting.censors.contactdiary.DiaryPersonCensor
+import de.rki.coronawarnapp.bugreporting.censors.contactdiary.DiaryVisitCensor
+import de.rki.coronawarnapp.bugreporting.censors.presencetracing.CheckInsCensor
+import de.rki.coronawarnapp.bugreporting.censors.presencetracing.TraceLocationCensor
+import de.rki.coronawarnapp.bugreporting.censors.submission.CoronaTestCensor
+import de.rki.coronawarnapp.bugreporting.censors.submission.PcrQrCodeCensor
+import de.rki.coronawarnapp.bugreporting.censors.submission.RACoronaTestCensor
+import de.rki.coronawarnapp.bugreporting.censors.submission.RatProfileCensor
+import de.rki.coronawarnapp.bugreporting.censors.submission.RatQrCodeCensor
 import de.rki.coronawarnapp.bugreporting.debuglog.internal.DebugLoggerScope
 import de.rki.coronawarnapp.bugreporting.debuglog.internal.DebuggerScope
 import de.rki.coronawarnapp.bugreporting.debuglog.upload.server.LogUploadApiV1
@@ -71,11 +76,19 @@ class BugReportingSharedModule {
 
     @Provides
     @IntoSet
-    fun registrationTokenCensor(censor: RegistrationTokenCensor): BugCensor = censor
+    fun registrationTokenCensor(censor: CoronaTestCensor): BugCensor = censor
 
     @Provides
     @IntoSet
-    fun qrCodeCensor(censor: QRCodeCensor): BugCensor = censor
+    fun pcrQrCodeCensor(censor: PcrQrCodeCensor): BugCensor = censor
+
+    @Provides
+    @IntoSet
+    fun ratQrCodeCensor(censor: RatQrCodeCensor): BugCensor = censor
+
+    @Provides
+    @IntoSet
+    fun raCoronaTestCensor(censor: RACoronaTestCensor): BugCensor = censor
 
     @Provides
     @IntoSet
@@ -92,4 +105,16 @@ class BugReportingSharedModule {
     @Provides
     @IntoSet
     fun diaryVisitCensor(censor: DiaryVisitCensor): BugCensor = censor
+
+    @Provides
+    @IntoSet
+    fun checkInsCensor(censor: CheckInsCensor): BugCensor = censor
+
+    @Provides
+    @IntoSet
+    fun traceLocationsCensor(censor: TraceLocationCensor): BugCensor = censor
+
+    @Provides
+    @IntoSet
+    fun ratProfileCensor(censor: RatProfileCensor): BugCensor = censor
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/BugCensor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/BugCensor.kt
index 8be45d08b70e1fcf0dec7a11becd81b00a5cafaa..48c13a4a73e9de887be0621f210e447c91dd8759 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/BugCensor.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/BugCensor.kt
@@ -38,6 +38,34 @@ interface BugCensor {
             return true
         }
 
+        fun withValidDescription(description: String?, action: (String) -> Unit): Boolean {
+            if (description.isNullOrBlank()) return false
+            if (description.length < 5) return false
+            action(description)
+            return true
+        }
+
+        fun withValidAddress(address: String?, action: (String) -> Unit): Boolean {
+            if (address.isNullOrBlank()) return false
+            if (address.length < 4) return false
+            action(address)
+            return true
+        }
+
+        fun withValidCity(city: String?, action: (String) -> Unit): Boolean {
+            if (city.isNullOrBlank()) return false
+            if (city.length < 3) return false
+            action(city)
+            return true
+        }
+
+        fun withValidZipCode(zipCode: String?, action: (String) -> Unit): Boolean {
+            if (zipCode.isNullOrBlank()) return false
+            if (zipCode.length < 5) return false
+            action(zipCode)
+            return true
+        }
+
         fun LogLine.toNewLogLineIfDifferent(newMessage: String): LogLine? {
             return if (newMessage != message) copy(message = newMessage) else null
         }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/DiaryEncounterCensor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryEncounterCensor.kt
similarity index 92%
rename from Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/DiaryEncounterCensor.kt
rename to Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryEncounterCensor.kt
index b8d3934117675dc62e9e8d29f607b42fcb172f36..9c75a723f8df9d5ff4cc8caa8c6efd13e75ecb3b 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/DiaryEncounterCensor.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryEncounterCensor.kt
@@ -1,6 +1,7 @@
-package de.rki.coronawarnapp.bugreporting.censors
+package de.rki.coronawarnapp.bugreporting.censors.contactdiary
 
 import dagger.Reusable
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.toNewLogLineIfDifferent
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidComment
 import de.rki.coronawarnapp.bugreporting.debuglog.LogLine
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/DiaryLocationCensor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryLocationCensor.kt
similarity index 94%
rename from Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/DiaryLocationCensor.kt
rename to Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryLocationCensor.kt
index 24bf031cf63dff35797f0a0049b3fd133ce2ca8a..70628444cbaa4ed279be2e03adc54bb37bbc6c1e 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/DiaryLocationCensor.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryLocationCensor.kt
@@ -1,6 +1,7 @@
-package de.rki.coronawarnapp.bugreporting.censors
+package de.rki.coronawarnapp.bugreporting.censors.contactdiary
 
 import dagger.Reusable
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.toNewLogLineIfDifferent
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidEmail
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidName
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/DiaryPersonCensor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryPersonCensor.kt
similarity index 94%
rename from Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/DiaryPersonCensor.kt
rename to Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryPersonCensor.kt
index 42341a8b5fd687da53a5e63ed7e93ab99477f28c..a8a0056d95bc5027c1f79e3d4d3e0451cd0b41a7 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/DiaryPersonCensor.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryPersonCensor.kt
@@ -1,6 +1,7 @@
-package de.rki.coronawarnapp.bugreporting.censors
+package de.rki.coronawarnapp.bugreporting.censors.contactdiary
 
 import dagger.Reusable
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.toNewLogLineIfDifferent
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidEmail
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidName
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/DiaryVisitCensor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryVisitCensor.kt
similarity index 92%
rename from Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/DiaryVisitCensor.kt
rename to Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryVisitCensor.kt
index ff0c63cf1100805d6a36e6ce74efff917445e4cc..f060c0fd2d49e2e415664e3dac90ad56937bbef5 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/DiaryVisitCensor.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/contactdiary/DiaryVisitCensor.kt
@@ -1,6 +1,7 @@
-package de.rki.coronawarnapp.bugreporting.censors
+package de.rki.coronawarnapp.bugreporting.censors.contactdiary
 
 import dagger.Reusable
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.toNewLogLineIfDifferent
 import de.rki.coronawarnapp.bugreporting.debuglog.LogLine
 import de.rki.coronawarnapp.bugreporting.debuglog.internal.DebuggerScope
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
new file mode 100644
index 0000000000000000000000000000000000000000..a5f10d81cb24ca19dbf32068e6e878b557ac84e0
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/presencetracing/CheckInsCensor.kt
@@ -0,0 +1,55 @@
+package de.rki.coronawarnapp.bugreporting.censors.presencetracing
+
+import dagger.Reusable
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.toNewLogLineIfDifferent
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidAddress
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidDescription
+import de.rki.coronawarnapp.bugreporting.debuglog.LogLine
+import de.rki.coronawarnapp.bugreporting.debuglog.internal.DebuggerScope
+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 javax.inject.Inject
+
+@Reusable
+class CheckInsCensor @Inject constructor(
+    @DebuggerScope debugScope: CoroutineScope,
+    private val checkInRepository: CheckInRepository
+) : BugCensor {
+
+    private val checkInsFlow by lazy {
+        checkInRepository.allCheckIns.stateIn(
+            scope = debugScope,
+            started = SharingStarted.Lazily,
+            initialValue = null
+        ).filterNotNull()
+    }
+
+    override suspend fun checkLog(entry: LogLine): LogLine? {
+
+        val checkIns = checkInsFlow.first()
+
+        if (checkIns.isEmpty()) return null
+
+        val newLogMsg = checkIns.fold(entry.message) { initial, checkIn ->
+
+            var acc = initial
+
+            withValidDescription(checkIn.description) { description ->
+                acc = acc.replace(description, "CheckIn#${checkIn.id}/Description")
+            }
+
+            withValidAddress(checkIn.address) { address ->
+                acc = acc.replace(address, "CheckIn#${checkIn.id}/Address")
+            }
+
+            acc
+        }
+
+        return entry.toNewLogLineIfDifferent(newLogMsg)
+    }
+}
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
new file mode 100644
index 0000000000000000000000000000000000000000..6d3f60ffb8bf2bc8dc61612b9722a9fc67fac64b
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/presencetracing/TraceLocationCensor.kt
@@ -0,0 +1,80 @@
+package de.rki.coronawarnapp.bugreporting.censors.presencetracing
+
+import dagger.Reusable
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.toNewLogLineIfDifferent
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidAddress
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidDescription
+import de.rki.coronawarnapp.bugreporting.debuglog.LogLine
+import de.rki.coronawarnapp.bugreporting.debuglog.internal.DebuggerScope
+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 javax.inject.Inject
+
+/**
+ * Censors Trace Location Data
+ *
+ * The information about which 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
+ */
+@Reusable
+class TraceLocationCensor @Inject constructor(
+    @DebuggerScope debugScope: CoroutineScope,
+    private val traceLocationRepository: TraceLocationRepository
+) : BugCensor {
+
+    private val traceLocationsFlow by lazy {
+        traceLocationRepository.allTraceLocations.stateIn(
+            scope = debugScope,
+            started = SharingStarted.Lazily,
+            initialValue = null
+        ).filterNotNull()
+    }
+
+    override suspend fun checkLog(entry: LogLine): LogLine? {
+
+        val traceLocations = traceLocationsFlow.first()
+
+        var newLogMsg = traceLocations.fold(entry.message) { initial, traceLocation ->
+            var acc = initial
+
+            acc = acc.replace(traceLocation.type.name, "TraceLocation#${traceLocation.id}/Type")
+
+            withValidDescription(traceLocation.description) { description ->
+                acc = acc.replace(description, "TraceLocation#${traceLocation.id}/Description")
+            }
+
+            withValidAddress(traceLocation.address) { address ->
+                acc = acc.replace(address, "TraceLocation#${traceLocation.id}/Address")
+            }
+
+            acc
+        }
+
+        val inputDataToCensor = dataToCensor
+        if (inputDataToCensor != null) {
+            newLogMsg = newLogMsg.replace(inputDataToCensor.type.name, "TraceLocationUserInput#Type")
+
+            withValidDescription(inputDataToCensor.description) {
+                newLogMsg = newLogMsg.replace(inputDataToCensor.description, "TraceLocationUserInput#Description")
+            }
+
+            withValidAddress(inputDataToCensor.address) {
+                newLogMsg = newLogMsg.replace(inputDataToCensor.address, "TraceLocationUserInput#Address")
+            }
+        }
+
+        return entry.toNewLogLineIfDifferent(newLogMsg)
+    }
+
+    companion object {
+        var dataToCensor: TraceLocationUserInput? = null
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/RegistrationTokenCensor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/submission/CoronaTestCensor.kt
similarity index 56%
rename from Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/RegistrationTokenCensor.kt
rename to Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/submission/CoronaTestCensor.kt
index c8769d23087ff67a5d92401421161273d206e739..df934b7e678642cc9e1eff255b67473bfe70af25 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/RegistrationTokenCensor.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/submission/CoronaTestCensor.kt
@@ -1,6 +1,7 @@
-package de.rki.coronawarnapp.bugreporting.censors
+package de.rki.coronawarnapp.bugreporting.censors.submission
 
 import dagger.Reusable
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.toNewLogLineIfDifferent
 import de.rki.coronawarnapp.bugreporting.debuglog.LogLine
 import de.rki.coronawarnapp.coronatest.CoronaTestRepository
@@ -9,17 +10,25 @@ import kotlinx.coroutines.flow.first
 import javax.inject.Inject
 
 @Reusable
-class RegistrationTokenCensor @Inject constructor(
+class CoronaTestCensor @Inject constructor(
     private val coronaTestRepository: CoronaTestRepository,
 ) : BugCensor {
+
+    // Keep a history to have references even after the user deletes a test
+    private val tokenHistory = mutableSetOf<String>()
+    private val identifierHistory = mutableSetOf<String>()
+
     override suspend fun checkLog(entry: LogLine): LogLine? {
+
+        // The Registration Token is received after registration of PCR and RAT tests. It is required to poll the test result.
         val tokens = coronaTestRepository.coronaTests.first().map { it.registrationToken }
+        tokenHistory.addAll(tokens)
 
-        if (tokens.isEmpty()) return null
+        val identifiers = coronaTestRepository.coronaTests.first().map { it.identifier }
+        identifierHistory.addAll(identifiers)
 
         var newMessage = entry.message
-
-        for (token in tokens) {
+        for (token in tokenHistory) {
             if (!entry.message.contains(token)) continue
 
             newMessage = if (CWADebug.isDeviceForTestersBuild) {
@@ -29,6 +38,12 @@ class RegistrationTokenCensor @Inject constructor(
             }
         }
 
+        identifierHistory
+            .filter { entry.message.contains(it) }
+            .forEach {
+                newMessage = newMessage.replace(it, "${it.take(11)}CoronaTest/Identifier")
+            }
+
         return entry.toNewLogLineIfDifferent(newMessage)
     }
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/QRCodeCensor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/submission/PcrQrCodeCensor.kt
similarity index 83%
rename from Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/QRCodeCensor.kt
rename to Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/submission/PcrQrCodeCensor.kt
index b85888d1d02ba6fb39e379e7740c1fb68aefe39a..3880817e6806f408469f061cf7b2a2f682aab1c0 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/QRCodeCensor.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/submission/PcrQrCodeCensor.kt
@@ -1,13 +1,14 @@
-package de.rki.coronawarnapp.bugreporting.censors
+package de.rki.coronawarnapp.bugreporting.censors.submission
 
 import dagger.Reusable
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.toNewLogLineIfDifferent
 import de.rki.coronawarnapp.bugreporting.debuglog.LogLine
 import de.rki.coronawarnapp.util.CWADebug
 import javax.inject.Inject
 
 @Reusable
-class QRCodeCensor @Inject constructor() : BugCensor {
+class PcrQrCodeCensor @Inject constructor() : BugCensor {
 
     override suspend fun checkLog(entry: LogLine): LogLine? {
 
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
new file mode 100644
index 0000000000000000000000000000000000000000..38c06dca4ae6ed269f293e30b47948baeae28467
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/submission/RACoronaTestCensor.kt
@@ -0,0 +1,57 @@
+package de.rki.coronawarnapp.bugreporting.censors.submission
+
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.toNewLogLineIfDifferent
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidName
+import de.rki.coronawarnapp.bugreporting.debuglog.LogLine
+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.map
+import kotlinx.coroutines.flow.stateIn
+import org.joda.time.format.DateTimeFormat
+import javax.inject.Inject
+
+class RACoronaTestCensor @Inject constructor(
+    @DebuggerScope debugScope: CoroutineScope,
+    private val coronaTestRepository: CoronaTestRepository
+) : BugCensor {
+
+    private val dayOfBirthFormatter = DateTimeFormat.forPattern("yyyy-MM-dd")
+
+    private val coronaTestFlow by lazy {
+        coronaTestRepository.coronaTests.stateIn(
+            scope = debugScope,
+            started = SharingStarted.Lazily,
+            initialValue = null
+        ).filterNotNull()
+    }
+
+    override suspend fun checkLog(entry: LogLine): LogLine? {
+
+        val raCoronaTestFlow = coronaTestFlow.map { tests -> tests.filterIsInstance<RACoronaTest>() }.first()
+        val raCoronaTest = raCoronaTestFlow.firstOrNull() ?: return null
+
+        var newMessage = entry.message
+
+        with(raCoronaTest) {
+            withValidName(firstName) { firstName ->
+                newMessage = newMessage.replace(firstName, "RATest/FirstName")
+            }
+
+            withValidName(lastName) { lastName ->
+                newMessage = newMessage.replace(lastName, "RATest/LastName")
+            }
+
+            val dateOfBirthString = dateOfBirth?.toString(dayOfBirthFormatter) ?: return@with
+
+            newMessage = newMessage.replace(dateOfBirthString, "RATest/DateOfBirth")
+        }
+
+        return entry.toNewLogLineIfDifferent(newMessage)
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/submission/RatProfileCensor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/submission/RatProfileCensor.kt
new file mode 100644
index 0000000000000000000000000000000000000000..fa1e919bbeeccadfded6038b795001cee462cf34
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/submission/RatProfileCensor.kt
@@ -0,0 +1,74 @@
+package de.rki.coronawarnapp.bugreporting.censors.submission
+
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.toNewLogLineIfDifferent
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidAddress
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidCity
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidName
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidPhoneNumber
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidZipCode
+import de.rki.coronawarnapp.bugreporting.debuglog.LogLine
+import de.rki.coronawarnapp.coronatest.antigen.profile.RATProfile
+import de.rki.coronawarnapp.coronatest.antigen.profile.RATProfileSettings
+import kotlinx.coroutines.flow.first
+import org.joda.time.format.DateTimeFormat
+import javax.inject.Inject
+
+class RatProfileCensor @Inject constructor(
+    private val ratProfileSettings: RATProfileSettings
+) : BugCensor {
+
+    private val dayOfBirthFormatter = DateTimeFormat.forPattern("yyyy-MM-dd")
+    private val ratProfileHistory = mutableSetOf<RATProfile>()
+
+    override suspend fun checkLog(entry: LogLine): LogLine? {
+        val ratProfile = ratProfileSettings.profile.flow.first()
+
+        // store the profile in a property so we still have a reference after it was deleted by the user
+        if (ratProfile != null) {
+            ratProfileHistory.add(ratProfile)
+        }
+
+        var newMessage = entry.message
+
+        ratProfileHistory.forEach { profile ->
+            with(profile) {
+                withValidName(firstName) { firstName ->
+                    newMessage = newMessage.replace(firstName, "RAT-Profile/FirstName")
+                }
+
+                withValidName(lastName) { lastName ->
+                    newMessage = newMessage.replace(lastName, "RAT-Profile/LastName")
+                }
+
+                val dateOfBirthString = birthDate?.toString(dayOfBirthFormatter)
+
+                if (dateOfBirthString != null) {
+                    newMessage = newMessage.replace(dateOfBirthString, "RAT-Profile/DateOfBirth")
+                }
+
+                withValidAddress(street) { street ->
+                    newMessage = newMessage.replace(street, "RAT-Profile/Street")
+                }
+
+                withValidCity(city) { city ->
+                    newMessage = newMessage.replace(city, "RAT-Profile/City")
+                }
+
+                withValidZipCode(zipCode) { zipCode ->
+                    newMessage = newMessage.replace(zipCode, "RAT-Profile/Zip-Code")
+                }
+
+                withValidPhoneNumber(phone) { phone ->
+                    newMessage = newMessage.replace(phone, "RAT-Profile/Phone")
+                }
+
+                withValidPhoneNumber(email) { phone ->
+                    newMessage = newMessage.replace(phone, "RAT-Profile/eMail")
+                }
+            }
+        }
+
+        return entry.toNewLogLineIfDifferent(newMessage)
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/submission/RatQrCodeCensor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/submission/RatQrCodeCensor.kt
new file mode 100644
index 0000000000000000000000000000000000000000..8fe3c62f3d18c6b0c0600fe71f000c0f8090b831
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/censors/submission/RatQrCodeCensor.kt
@@ -0,0 +1,63 @@
+package de.rki.coronawarnapp.bugreporting.censors.submission
+
+import dagger.Reusable
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.toNewLogLineIfDifferent
+import de.rki.coronawarnapp.bugreporting.censors.BugCensor.Companion.withValidName
+import de.rki.coronawarnapp.bugreporting.debuglog.LogLine
+import de.rki.coronawarnapp.coronatest.qrcode.RapidAntigenHash
+import de.rki.coronawarnapp.util.CWADebug
+import org.joda.time.LocalDate
+import org.joda.time.format.DateTimeFormat
+import javax.inject.Inject
+
+@Reusable
+class RatQrCodeCensor @Inject constructor() : BugCensor {
+
+    private val dayOfBirthFormatter = DateTimeFormat.forPattern("yyyy-MM-dd")
+
+    override suspend fun checkLog(entry: LogLine): LogLine? {
+
+        val dataToCensor = dataToCensor ?: return null
+
+        var newMessage = entry.message
+
+        with(dataToCensor) {
+            newMessage = newMessage.replace(rawString, "RatQrCode/ScannedRawString")
+
+            newMessage = if (CWADebug.isDeviceForTestersBuild) {
+                newMessage.replace(hash, PLACEHOLDER + hash.takeLast(28))
+            } else {
+                newMessage.replace(hash, PLACEHOLDER + hash.takeLast(4))
+            }
+
+            withValidName(firstName) { firstName ->
+                newMessage = newMessage.replace(firstName, "RATest/FirstName")
+            }
+
+            withValidName(lastName) { lastName ->
+                newMessage = newMessage.replace(lastName, "RATest/LastName")
+            }
+
+            val dateOfBirthString = dateOfBirth?.toString(dayOfBirthFormatter) ?: return@with
+
+            newMessage = newMessage.replace(dateOfBirthString, "RATest/DateOfBirth")
+        }
+
+        return entry.toNewLogLineIfDifferent(newMessage)
+    }
+
+    companion object {
+        var dataToCensor: CensorData? = null
+
+        private const val PLACEHOLDER = "SHA256HASH-ENDING-WITH-"
+    }
+
+    data class CensorData(
+        val rawString: String,
+        val hash: RapidAntigenHash,
+        val firstName: String?,
+        val lastName: String?,
+        val dateOfBirth: LocalDate?
+    )
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/qrcode/PcrQrCodeExtractor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/qrcode/PcrQrCodeExtractor.kt
index 53d57593af693c5fa6cde7db77d4266f26edda1a..49633e3decd06846753a897897b235a16409cbdd 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/qrcode/PcrQrCodeExtractor.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/qrcode/PcrQrCodeExtractor.kt
@@ -1,5 +1,6 @@
 package de.rki.coronawarnapp.coronatest.qrcode
 
+import de.rki.coronawarnapp.bugreporting.censors.submission.PcrQrCodeCensor
 import java.util.regex.Pattern
 import javax.inject.Inject
 
@@ -8,9 +9,9 @@ class PcrQrCodeExtractor @Inject constructor() : QrCodeExtractor<CoronaTestQRCod
     override fun canHandle(rawString: String): Boolean = rawString.startsWith(prefix, ignoreCase = true)
 
     override fun extract(rawString: String): CoronaTestQRCode.PCR {
-        return CoronaTestQRCode.PCR(
-            extractGUID(rawString)
-        )
+        val guid = extractGUID(rawString)
+        PcrQrCodeCensor.lastGUID = guid
+        return CoronaTestQRCode.PCR(guid)
     }
 
     private fun extractGUID(rawString: String): CoronaTestGUID {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/qrcode/RapidAntigenQrCodeExtractor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/qrcode/RapidAntigenQrCodeExtractor.kt
index c1a95544ce0b759c88f7dc2f792d35c17cbcd194..c5881f97364a97bd6c5f8c795b3b1df7c1c72df0 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/qrcode/RapidAntigenQrCodeExtractor.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/qrcode/RapidAntigenQrCodeExtractor.kt
@@ -3,6 +3,7 @@ package de.rki.coronawarnapp.coronatest.qrcode
 import com.google.common.io.BaseEncoding
 import com.google.gson.Gson
 import com.google.gson.annotations.SerializedName
+import de.rki.coronawarnapp.bugreporting.censors.submission.RatQrCodeCensor
 import de.rki.coronawarnapp.util.HashExtensions.toSHA256
 import de.rki.coronawarnapp.util.hashing.isSha256Hash
 import de.rki.coronawarnapp.util.serialization.fromJson
@@ -22,6 +23,14 @@ class RapidAntigenQrCodeExtractor @Inject constructor() : QrCodeExtractor<Corona
         Timber.v("extract(rawString=%s)", rawString)
         val payload = CleanPayload(extractData(rawString))
 
+        RatQrCodeCensor.dataToCensor = RatQrCodeCensor.CensorData(
+            rawString = rawString,
+            hash = payload.hash,
+            firstName = payload.firstName,
+            lastName = payload.lastName,
+            dateOfBirth = payload.dateOfBirth
+        )
+
         payload.requireValidData()
 
         return CoronaTestQRCode.RapidAntigen(
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/organizer/create/TraceLocationCreateViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/organizer/create/TraceLocationCreateViewModel.kt
index 29976a36cb93c1afb1b495e72df06335aca4aab1..a753ca9424cfd7cc3e55a74b383adc8f5776627c 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/organizer/create/TraceLocationCreateViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/organizer/create/TraceLocationCreateViewModel.kt
@@ -8,6 +8,7 @@ import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import de.rki.coronawarnapp.R
+import de.rki.coronawarnapp.bugreporting.censors.presencetracing.TraceLocationCensor
 import de.rki.coronawarnapp.contactdiary.util.CWADateTimeFormatPatternFactory.shortDatePattern
 import de.rki.coronawarnapp.presencetracing.checkins.qrcode.TraceLocation
 import de.rki.coronawarnapp.presencetracing.locations.TraceLocationCreator
@@ -68,6 +69,8 @@ class TraceLocationCreateViewModel @AssistedInject constructor(
             defaultCheckInLengthInMinutes = checkInLength.standardMinutes.toInt()
         )
 
+        TraceLocationCensor.dataToCensor = userInput
+
         launch {
             try {
                 val traceLocation = traceLocationCreator.createTraceLocation(userInput)
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/qrcode/consent/SubmissionConsentViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/qrcode/consent/SubmissionConsentViewModel.kt
index 69b7c6e662c9b7a071f9c2735f2ab6809f753455..f6876b62aeebd0f5662569e1a26073a0fd7e8e66 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/qrcode/consent/SubmissionConsentViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/qrcode/consent/SubmissionConsentViewModel.kt
@@ -4,7 +4,6 @@ import androidx.lifecycle.asLiveData
 import com.google.android.gms.common.api.ApiException
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
-import de.rki.coronawarnapp.bugreporting.censors.QRCodeCensor
 import de.rki.coronawarnapp.coronatest.qrcode.CoronaTestQrCodeValidator
 import de.rki.coronawarnapp.coronatest.qrcode.InvalidQRCodeException
 import de.rki.coronawarnapp.nearby.modules.tekhistory.TEKHistoryProvider
@@ -79,8 +78,6 @@ class SubmissionConsentViewModel @AssistedInject constructor(
     private suspend fun validateAndRegister(qrCodeString: String) {
         try {
             val coronaTestQRCode = qrCodeValidator.validate(qrCodeString)
-            // TODO this needs to be adapted to work for different types
-            QRCodeCensor.lastGUID = coronaTestQRCode.registrationIdentifier
             qrCodeValidationState.postValue(QrCodeRegistrationStateProcessor.ValidationState.SUCCESS)
             val coronaTest = submissionRepository.testForType(coronaTestQRCode.type).first()
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/qrcode/scan/SubmissionQRCodeScanViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/qrcode/scan/SubmissionQRCodeScanViewModel.kt
index b49dad70291cd84b7433f48fac0d66a8bcc99720..4222a676fd91f1b08fe2e5dd4987fd02629c090f 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/qrcode/scan/SubmissionQRCodeScanViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/qrcode/scan/SubmissionQRCodeScanViewModel.kt
@@ -3,7 +3,6 @@ package de.rki.coronawarnapp.ui.submission.qrcode.scan
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
-import de.rki.coronawarnapp.bugreporting.censors.QRCodeCensor
 import de.rki.coronawarnapp.coronatest.qrcode.CoronaTestQrCodeValidator
 import de.rki.coronawarnapp.coronatest.qrcode.InvalidQRCodeException
 import de.rki.coronawarnapp.coronatest.type.CoronaTest
@@ -43,8 +42,6 @@ class SubmissionQRCodeScanViewModel @AssistedInject constructor(
     suspend fun startQrCodeRegistration(rawResult: String, isConsentGiven: Boolean) {
         try {
             val coronaTestQRCode = qrCodeValidator.validate(rawResult)
-            // TODO this needs to be adapted to work for different types
-            QRCodeCensor.lastGUID = coronaTestQRCode.registrationIdentifier
             qrCodeValidationState.postValue(QrCodeRegistrationStateProcessor.ValidationState.SUCCESS)
             val coronaTest = submissionRepository.testForType(coronaTestQRCode.type).first()
 
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/BugCensorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/BugCensorTest.kt
index c0680a991b0dae9908b46274bac5b5bbd4988276..988042877fb6032ffa037c2ee5957c30ec905798 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/BugCensorTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/BugCensorTest.kt
@@ -54,6 +54,51 @@ class BugCensorTest : BaseTest() {
         BugCensor.withValidComment("abc") {} shouldBe true
     }
 
+    @Test
+    fun `description censoring validity`() {
+        BugCensor.withValidDescription(null) {} shouldBe false
+        BugCensor.withValidDescription("   ") {} shouldBe false
+        BugCensor.withValidDescription("        ") {} shouldBe false
+        BugCensor.withValidDescription("a") {} shouldBe false
+        BugCensor.withValidDescription("ab") {} shouldBe false
+        BugCensor.withValidDescription("abc") {} shouldBe false
+        BugCensor.withValidDescription("abcd") {} shouldBe false
+        BugCensor.withValidDescription("abcde") {} shouldBe true
+    }
+
+    @Test
+    fun `address censoring validity`() {
+        BugCensor.withValidAddress(null) {} shouldBe false
+        BugCensor.withValidAddress("   ") {} shouldBe false
+        BugCensor.withValidAddress("        ") {} shouldBe false
+        BugCensor.withValidAddress("a") {} shouldBe false
+        BugCensor.withValidAddress("ab") {} shouldBe false
+        BugCensor.withValidAddress("abc") {} shouldBe false
+        BugCensor.withValidAddress("abcd") {} shouldBe true
+    }
+
+    @Test
+    fun `city censoring validity`() {
+        BugCensor.withValidCity(null) {} shouldBe false
+        BugCensor.withValidCity("   ") {} shouldBe false
+        BugCensor.withValidCity("        ") {} shouldBe false
+        BugCensor.withValidCity("a") {} shouldBe false
+        BugCensor.withValidCity("ab") {} shouldBe false
+        BugCensor.withValidCity("abc") {} shouldBe true
+    }
+
+    @Test
+    fun `zip-code censoring validity`() {
+        BugCensor.withValidZipCode(null) {} shouldBe false
+        BugCensor.withValidZipCode("   ") {} shouldBe false
+        BugCensor.withValidZipCode("        ") {} shouldBe false
+        BugCensor.withValidZipCode("1") {} shouldBe false
+        BugCensor.withValidZipCode("12") {} shouldBe false
+        BugCensor.withValidZipCode("123") {} shouldBe false
+        BugCensor.withValidZipCode("1234") {} shouldBe false
+        BugCensor.withValidZipCode("12345") {} shouldBe true
+    }
+
     @Test
     fun `loglines are only copied if the message is different`() {
         val logLine = LogLine(
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 e6c3aa4a1df8bf4db40f25f4eb488cf3ce9150df..cf4989e79c22668f3f03905bd2d0845dd589b5f8 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
@@ -6,6 +6,9 @@ import dagger.Provides
 import de.rki.coronawarnapp.bugreporting.BugReportingSharedModule
 import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository
 import de.rki.coronawarnapp.coronatest.CoronaTestRepository
+import de.rki.coronawarnapp.coronatest.antigen.profile.RATProfileSettings
+import de.rki.coronawarnapp.presencetracing.checkins.CheckInRepository
+import de.rki.coronawarnapp.presencetracing.storage.repo.TraceLocationRepository
 import de.rki.coronawarnapp.submission.SubmissionSettings
 import io.github.classgraph.ClassGraph
 import io.kotest.matchers.collections.shouldContainAll
@@ -73,4 +76,16 @@ class MockProvider {
     @Singleton
     @Provides
     fun coronaTestRepository(): CoronaTestRepository = mockk()
+
+    @Singleton
+    @Provides
+    fun checkInRepository(): CheckInRepository = mockk()
+
+    @Singleton
+    @Provides
+    fun traceLocationRepository(): TraceLocationRepository = mockk()
+
+    @Singleton
+    @Provides
+    fun ratProfileSettings(): RATProfileSettings = mockk()
 }
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
new file mode 100644
index 0000000000000000000000000000000000000000..818cdbb8e7e03ed2b86cb1cfce7ea7c8e59a0245
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/CheckInsCensorTest.kt
@@ -0,0 +1,139 @@
+package de.rki.coronawarnapp.bugreporting.censors
+
+import de.rki.coronawarnapp.bugreporting.censors.presencetracing.CheckInsCensor
+import de.rki.coronawarnapp.bugreporting.debuglog.LogLine
+import de.rki.coronawarnapp.presencetracing.checkins.CheckIn
+import de.rki.coronawarnapp.presencetracing.checkins.CheckInRepository
+import io.kotest.matchers.shouldBe
+import io.mockk.MockKAnnotations
+import io.mockk.every
+import io.mockk.impl.annotations.MockK
+import io.mockk.mockk
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.runBlocking
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import testhelpers.BaseTest
+
+internal class CheckInsCensorTest : BaseTest() {
+
+    @MockK lateinit var checkInsRepo: CheckInRepository
+
+    @BeforeEach
+    fun setUp() {
+        MockKAnnotations.init(this)
+    }
+
+    private fun createInstance(scope: CoroutineScope) = CheckInsCensor(
+        debugScope = scope,
+        checkInRepository = checkInsRepo
+    )
+
+    private fun mockCheckIn(
+        checkInId: Long,
+        checkInDescription: String,
+        checkInAddress: String
+    ) = mockk<CheckIn>().apply {
+        every { id } returns checkInId
+        every { description } returns checkInDescription
+        every { address } returns checkInAddress
+    }
+
+    @Test
+    fun `checkLog() should return LogLine with censored check-in information`() = runBlocking {
+        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"
+                )
+            )
+        )
+
+        val censor = createInstance(this)
+
+        val logLineToCensor = LogLine(
+            timestamp = 1,
+            priority = 3,
+            message =
+                """
+                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(),
+            tag = "I am tag",
+            throwable = null
+        )
+
+        censor.checkLog(logLineToCensor) shouldBe logLineToCensor.copy(
+            message =
+                """
+                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())
+
+        censor.checkLog(logLineToCensor) shouldBe logLineToCensor.copy(
+            message =
+                """
+                Let's go to CheckIn#1/Description in CheckIn#1/Address.
+                Who needs the CheckIn#2/Description in CheckIn#2/Address? I doooo!
+                """.trimIndent()
+        )
+    }
+
+    @Test
+    fun `checkLog() should return null if no check-ins are stored`() = runBlocking {
+        every { checkInsRepo.allCheckIns } returns flowOf(emptyList())
+
+        val censor = createInstance(this)
+        val logLine = LogLine(
+            timestamp = 1,
+            priority = 3,
+            message = "Some log message that shouldn't be censored.",
+            tag = "I'm a tag",
+            throwable = null
+        )
+
+        censor.checkLog(logLine) shouldBe null
+    }
+
+    @Test
+    fun `checkLog() should return null if LogLine doesn't need to be censored`() = runBlocking {
+
+        every { checkInsRepo.allCheckIns } returns flowOf(
+            listOf(
+                mockCheckIn(
+                    checkInId = 1,
+                    checkInDescription = "Description 1",
+                    checkInAddress = "Address 1"
+                ),
+                mockCheckIn(
+                    checkInId = 2,
+                    checkInDescription = "Description 2",
+                    checkInAddress = "Address 2"
+                )
+            )
+        )
+
+        val censor = createInstance(this)
+        val logLine = LogLine(
+            timestamp = 1,
+            priority = 3,
+            message = "Some log message that shouldn't be censored.",
+            tag = "I'm a tag",
+            throwable = null
+        )
+
+        censor.checkLog(logLine) shouldBe null
+    }
+}
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/RegistrationTokenCensorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/CoronaTestCensorTest.kt
similarity index 54%
rename from Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/RegistrationTokenCensorTest.kt
rename to Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/CoronaTestCensorTest.kt
index b3fde2e4884541ee4687eaa2afd73854c3e0d2bb..0b88f1988898763b4688396469c4dccad04c8b47 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/RegistrationTokenCensorTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/CoronaTestCensorTest.kt
@@ -1,8 +1,11 @@
 package de.rki.coronawarnapp.bugreporting.censors
 
+import de.rki.coronawarnapp.bugreporting.censors.submission.CoronaTestCensor
 import de.rki.coronawarnapp.bugreporting.debuglog.LogLine
 import de.rki.coronawarnapp.coronatest.CoronaTestRepository
 import de.rki.coronawarnapp.coronatest.type.CoronaTest
+import de.rki.coronawarnapp.coronatest.type.pcr.PCRCoronaTest
+import de.rki.coronawarnapp.coronatest.type.rapidantigen.RACoronaTest
 import de.rki.coronawarnapp.util.CWADebug
 import io.kotest.matchers.shouldBe
 import io.mockk.MockKAnnotations
@@ -17,15 +20,22 @@ import org.junit.jupiter.api.BeforeEach
 import org.junit.jupiter.api.Test
 import testhelpers.BaseTest
 
-class RegistrationTokenCensorTest : BaseTest() {
+class CoronaTestCensorTest : BaseTest() {
     @MockK lateinit var coronaTestRepository: CoronaTestRepository
 
     private val testToken = "63b4d3ff-e0de-4bd4-90c1-17c2bb683a2f"
+    private val pcrIdentifier = "qrcode-pcr-someIdentifier"
+    private val ratIdentifier = "qrcode-rat-someIdentifier"
 
     private val coronaTests: MutableStateFlow<Set<CoronaTest>> = MutableStateFlow(
         setOf(
-            mockk<CoronaTest>().apply {
+            mockk<PCRCoronaTest>().apply {
                 every { registrationToken } returns testToken
+                every { identifier } returns pcrIdentifier
+            },
+            mockk<RACoronaTest>().apply {
+                every { registrationToken } returns testToken
+                every { identifier } returns ratIdentifier
             }
         )
     )
@@ -40,7 +50,7 @@ class RegistrationTokenCensorTest : BaseTest() {
         every { coronaTestRepository.coronaTests } returns coronaTests
     }
 
-    private fun createInstance() = RegistrationTokenCensor(
+    private fun createInstance() = CoronaTestCensor(
         coronaTestRepository = coronaTestRepository
     )
 
@@ -50,31 +60,31 @@ class RegistrationTokenCensorTest : BaseTest() {
         val filterMe = LogLine(
             timestamp = 1,
             priority = 3,
-            message = "I'm a shy registration token: $testToken",
+            message = "I'm a shy registration token: $testToken and we are extrovert $pcrIdentifier and $ratIdentifier",
             tag = "I'm a tag",
             throwable = null
         )
         instance.checkLog(filterMe) shouldBe filterMe.copy(
-            message = "I'm a shy registration token: ########-####-####-####-########3a2f"
+            message = "I'm a shy registration token: ########-####-####-####-########3a2f and we are extrovert qrcode-pcr-CoronaTest/Identifier and qrcode-rat-CoronaTest/Identifier"
         )
 
         every { CWADebug.isDeviceForTestersBuild } returns true
         instance.checkLog(filterMe) shouldBe filterMe.copy(
-            message = "I'm a shy registration token: ########-e0de-4bd4-90c1-17c2bb683a2f"
+            message = "I'm a shy registration token: ########-e0de-4bd4-90c1-17c2bb683a2f and we are extrovert qrcode-pcr-CoronaTest/Identifier and qrcode-rat-CoronaTest/Identifier"
         )
 
         verify { coronaTestRepository.coronaTests }
     }
 
     @Test
-    fun `censoring returns null if there is no token`() = runBlockingTest {
+    fun `censoring returns null if there is no corona test stored`() = runBlockingTest {
         coronaTests.value = emptySet()
 
         val instance = createInstance()
         val filterMeNot = LogLine(
             timestamp = 1,
             priority = 3,
-            message = "I'm a shy registration token: $testToken",
+            message = "I'm a shy registration token: $testToken and we are extrovert $pcrIdentifier and $ratIdentifier",
             tag = "I'm a tag",
             throwable = null
         )
@@ -93,4 +103,29 @@ class RegistrationTokenCensorTest : BaseTest() {
         )
         instance.checkLog(filterMeNot) shouldBe null
     }
+
+    @Test
+    fun `censoring still works after test was deleted`() = runBlockingTest {
+
+        val censor = createInstance()
+
+        val filterMe = LogLine(
+            timestamp = 1,
+            priority = 3,
+            message = "I'm a shy registration token: $testToken and we are extrovert $pcrIdentifier and $ratIdentifier",
+            tag = "I'm a tag",
+            throwable = null
+        )
+
+        censor.checkLog(filterMe) shouldBe filterMe.copy(
+            message = "I'm a shy registration token: ########-####-####-####-########3a2f and we are extrovert qrcode-pcr-CoronaTest/Identifier and qrcode-rat-CoronaTest/Identifier"
+        )
+
+        // delete all tests
+        coronaTests.value = emptySet()
+
+        censor.checkLog(filterMe) shouldBe filterMe.copy(
+            message = "I'm a shy registration token: ########-####-####-####-########3a2f and we are extrovert qrcode-pcr-CoronaTest/Identifier and qrcode-rat-CoronaTest/Identifier"
+        )
+    }
 }
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 a00968c428c93e723309761c38e08af1634ce905..fead49fe948f4b9fc1d76262ba6fe22651ba2830 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
@@ -1,5 +1,6 @@
 package de.rki.coronawarnapp.bugreporting.censors
 
+import de.rki.coronawarnapp.bugreporting.censors.contactdiary.DiaryEncounterCensor
 import de.rki.coronawarnapp.bugreporting.debuglog.LogLine
 import de.rki.coronawarnapp.contactdiary.model.ContactDiaryPersonEncounter
 import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository
@@ -71,6 +72,17 @@ class DiaryEncounterCensorTest : BaseTest() {
                     everyone disliked that.
                 """.trimIndent()
         )
+
+        // censoring should still work after encounters are deleted
+        every { diaryRepo.personEncounters } returns flowOf(emptyList())
+        instance.checkLog(censorMe) shouldBe censorMe.copy(
+            message =
+                """
+                    On Encounter#2/Circumstances,
+                    two persons Encounter#3/Circumstances,
+                    everyone disliked that.
+                """.trimIndent()
+        )
     }
 
     @Test
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 0c80fee73ed0eb5e43ee044c80a43214c73047d2..191afcd5dcace16a5dce810c8aeeb8b6a9d2cbf4 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
@@ -1,5 +1,6 @@
 package de.rki.coronawarnapp.bugreporting.censors
 
+import de.rki.coronawarnapp.bugreporting.censors.contactdiary.DiaryLocationCensor
 import de.rki.coronawarnapp.bugreporting.debuglog.LogLine
 import de.rki.coronawarnapp.contactdiary.model.ContactDiaryLocation
 import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository
@@ -73,6 +74,17 @@ class DiaryLocationCensorTest : BaseTest() {
                 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())
+        instance.checkLog(censorMe) shouldBe censorMe.copy(
+            message =
+                """
+                Bürgermeister of Location#1/Name (Location#1/PhoneNumber) and Karl of Location#3/Name [Location#3/PhoneNumber] called each other.
+                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()
+        )
     }
 
     @Test
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 e4e5e38c294d6f3b384f6a8e7191f725a29ed441..1025df09c8876fd49a7e11f73c47603a77cb265f 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
@@ -1,5 +1,6 @@
 package de.rki.coronawarnapp.bugreporting.censors
 
+import de.rki.coronawarnapp.bugreporting.censors.contactdiary.DiaryPersonCensor
 import de.rki.coronawarnapp.bugreporting.debuglog.LogLine
 import de.rki.coronawarnapp.contactdiary.model.ContactDiaryPerson
 import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository
@@ -74,6 +75,17 @@ class DiaryPersonCensorTest : BaseTest() {
                 A quick mail to Person#1/EMail confirmed this.
                 """.trimIndent()
         )
+
+        // censoring should still work after people are deleted
+        every { diaryRepo.people } returns flowOf(emptyList())
+        instance.checkLog(censorMe) shouldBe censorMe.copy(
+            message =
+                """
+                Person#2/Name requested more coffee from Person#1/PhoneNumber,
+                but Person#3/Name thought he had enough has had enough for today.
+                A quick mail to Person#1/EMail confirmed this.
+                """.trimIndent()
+        )
     }
 
     @Test
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 cb9405722fde29918cb4d4a03fff8413fd518bea..5c8a0ed5155bd74d96a1f685b60fbc362ab68ccb 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
@@ -1,5 +1,6 @@
 package de.rki.coronawarnapp.bugreporting.censors
 
+import de.rki.coronawarnapp.bugreporting.censors.contactdiary.DiaryVisitCensor
 import de.rki.coronawarnapp.bugreporting.debuglog.LogLine
 import de.rki.coronawarnapp.contactdiary.model.ContactDiaryLocationVisit
 import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository
@@ -69,6 +70,17 @@ class DiaryVisitCensorTest : BaseTest() {
                 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())
+        instance.checkLog(censorMe) shouldBe censorMe.copy(
+            message =
+                """
+                After having a Visit#1/Circumstances,
+                I got my Visit#2/Circumstances,
+                only to find out the supermarket was Visit#3/Circumstances.
+                """.trimIndent()
+        )
     }
 
     @Test
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/QRCodeCensorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/PcrQrCodeCensorTest.kt
similarity index 86%
rename from Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/QRCodeCensorTest.kt
rename to Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/PcrQrCodeCensorTest.kt
index 62bf33f114bc5d0051b5d9fa0fafa92264c01417..d89f76791836507ba93d111cbf1d10fb776b7743 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/QRCodeCensorTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/PcrQrCodeCensorTest.kt
@@ -1,5 +1,6 @@
 package de.rki.coronawarnapp.bugreporting.censors
 
+import de.rki.coronawarnapp.bugreporting.censors.submission.PcrQrCodeCensor
 import de.rki.coronawarnapp.bugreporting.debuglog.LogLine
 import de.rki.coronawarnapp.util.CWADebug
 import io.kotest.matchers.shouldBe
@@ -12,7 +13,7 @@ import org.junit.jupiter.api.BeforeEach
 import org.junit.jupiter.api.Test
 import testhelpers.BaseTest
 
-class QRCodeCensorTest : BaseTest() {
+class PcrQrCodeCensorTest : BaseTest() {
 
     private val testGUID = "63b4d3ff-e0de-4bd4-90c1-17c2bb683a2f"
 
@@ -26,14 +27,14 @@ class QRCodeCensorTest : BaseTest() {
 
     @AfterEach
     fun teardown() {
-        QRCodeCensor.lastGUID = null
+        PcrQrCodeCensor.lastGUID = null
     }
 
-    private fun createInstance() = QRCodeCensor()
+    private fun createInstance() = PcrQrCodeCensor()
 
     @Test
     fun `censoring replaces the logline message`() = runBlockingTest {
-        QRCodeCensor.lastGUID = testGUID
+        PcrQrCodeCensor.lastGUID = testGUID
         val instance = createInstance()
         val censored = LogLine(
             timestamp = 1,
@@ -54,7 +55,7 @@ class QRCodeCensorTest : BaseTest() {
 
     @Test
     fun `censoring returns null if there is no match`() = runBlockingTest {
-        QRCodeCensor.lastGUID = testGUID.replace("f", "a")
+        PcrQrCodeCensor.lastGUID = testGUID.replace("f", "a")
         val instance = createInstance()
         val notCensored = LogLine(
             timestamp = 1,
@@ -68,7 +69,7 @@ class QRCodeCensorTest : BaseTest() {
 
     @Test
     fun `censoring aborts if no qrcode was set`() = runBlockingTest {
-        QRCodeCensor.lastGUID = null
+        PcrQrCodeCensor.lastGUID = null
         val instance = createInstance()
         val notCensored = LogLine(
             timestamp = 1,
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
new file mode 100644
index 0000000000000000000000000000000000000000..74c66acfadeafe2a4252b0a94df2457ebd7806bc
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/RACoronaTestCensorTest.kt
@@ -0,0 +1,121 @@
+package de.rki.coronawarnapp.bugreporting.censors
+
+import de.rki.coronawarnapp.bugreporting.censors.submission.RACoronaTestCensor
+import de.rki.coronawarnapp.bugreporting.debuglog.LogLine
+import de.rki.coronawarnapp.coronatest.CoronaTestRepository
+import de.rki.coronawarnapp.coronatest.type.rapidantigen.RACoronaTest
+import io.kotest.matchers.shouldBe
+import io.mockk.MockKAnnotations
+import io.mockk.every
+import io.mockk.impl.annotations.MockK
+import io.mockk.mockk
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.runBlocking
+import org.joda.time.LocalDate
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import testhelpers.BaseTest
+
+internal class RACoronaTestCensorTest : BaseTest() {
+
+    @MockK lateinit var coronaTestRepository: CoronaTestRepository
+
+    @BeforeEach
+    fun setUp() {
+        MockKAnnotations.init(this)
+    }
+
+    private fun createInstance(scope: CoroutineScope) = RACoronaTestCensor(
+        debugScope = scope,
+        coronaTestRepository = coronaTestRepository
+    )
+
+    @Test
+    fun `checkLog() should return censored LogLine`() = runBlocking {
+        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")
+                }
+            )
+        )
+
+        val censor = createInstance(this)
+
+        val logLineToCensor = LogLine(
+            timestamp = 1,
+            priority = 3,
+            message =
+                """
+                Hello! My name is John. My friends call me Mister Doe and I was born on 2020-01-01.
+                """.trimIndent(),
+            tag = "I am tag",
+            throwable = null
+        )
+
+        censor.checkLog(logLineToCensor) shouldBe logLineToCensor.copy(
+            message =
+                """
+                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())
+
+        censor.checkLog(logLineToCensor) shouldBe logLineToCensor.copy(
+            message =
+                """
+                Hello! My name is RATest/FirstName. My friends call me Mister RATest/LastName and I was born on RATest/DateOfBirth.
+                """.trimIndent()
+        )
+    }
+
+    @Test
+    fun `checkLog() should return return null if no corona tests are stored`() = runBlocking {
+        every { coronaTestRepository.coronaTests } returns flowOf(emptySet())
+
+        val censor = createInstance(this)
+
+        val logLine = LogLine(
+            timestamp = 1,
+            priority = 3,
+            message = "Lorem ipsum",
+            tag = "I'm a tag",
+            throwable = null
+        )
+
+        censor.checkLog(logLine) shouldBe null
+    }
+
+    @Test
+    fun `checkLog() should return null if LogLine doesn't need to be censored`() = runBlocking {
+        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")
+                }
+            )
+        )
+
+        val censor = createInstance(this)
+
+        val logLine = LogLine(
+            timestamp = 1,
+            priority = 3,
+            message = "Lorem ipsum",
+            tag = "I'm a tag",
+            throwable = null
+        )
+        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/RatQrCodeCensorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/RatQrCodeCensorTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..83b890cd184c083563c5b1c517362e2cd3768d68
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/RatQrCodeCensorTest.kt
@@ -0,0 +1,103 @@
+package de.rki.coronawarnapp.bugreporting.censors
+
+import de.rki.coronawarnapp.bugreporting.censors.submission.RatQrCodeCensor
+import de.rki.coronawarnapp.bugreporting.debuglog.LogLine
+import de.rki.coronawarnapp.util.CWADebug
+import io.kotest.matchers.shouldBe
+import io.mockk.MockKAnnotations
+import io.mockk.every
+import io.mockk.mockkObject
+import kotlinx.coroutines.test.runBlockingTest
+import org.joda.time.LocalDate
+import org.junit.jupiter.api.AfterEach
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+
+internal class RatQrCodeCensorTest {
+
+    private val testHash = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
+    private val testRawString = "testRawString"
+
+    @BeforeEach
+    fun setUp() {
+        MockKAnnotations.init(this)
+
+        mockkObject(CWADebug)
+        every { CWADebug.isDeviceForTestersBuild } returns false
+    }
+
+    @AfterEach
+    fun teardown() {
+        RatQrCodeCensor.dataToCensor = null
+    }
+
+    private fun createInstance() = RatQrCodeCensor()
+
+    @Test
+    fun `checkLog() should return censored LogLine`() = runBlockingTest {
+        RatQrCodeCensor.dataToCensor = RatQrCodeCensor.CensorData(
+            rawString = testRawString,
+            hash = testHash,
+            firstName = "Milhouse",
+            lastName = "Van Houten",
+            dateOfBirth = LocalDate.parse("1980-07-01")
+        )
+
+        val censor = createInstance()
+
+        val logLineToCensor = LogLine(
+            timestamp = 1,
+            priority = 3,
+            message = "Here comes the hash: $testHash of the rat test of Milhouse Van Houten. He was born on 1980-07-01",
+            tag = "I am tag",
+            throwable = null
+        )
+
+        censor.checkLog(logLineToCensor) shouldBe logLineToCensor.copy(
+            message = "Here comes the hash: SHA256HASH-ENDING-WITH-15ad of the rat test of RATest/FirstName RATest/LastName. He was born on RATest/DateOfBirth"
+        )
+
+        every { CWADebug.isDeviceForTestersBuild } returns true
+        censor.checkLog(logLineToCensor) shouldBe logLineToCensor.copy(
+            message = "Here comes the hash: SHA256HASH-ENDING-WITH-61a396177a9cb410ff61f20015ad of the rat test of RATest/FirstName RATest/LastName. He was born on RATest/DateOfBirth"
+        )
+    }
+
+    @Test
+    fun `checkLog() should return null if no data to censor was set`() = runBlockingTest {
+        val censor = createInstance()
+
+        val logLineNotToCensor = LogLine(
+            timestamp = 1,
+            priority = 3,
+            message = "Here comes the hash: $testHash",
+            tag = "I am tag",
+            throwable = null
+        )
+
+        censor.checkLog(logLineNotToCensor) shouldBe null
+    }
+
+    @Test
+    fun `checkLog() should return null if nothing should be censored`() = runBlockingTest {
+        RatQrCodeCensor.dataToCensor = RatQrCodeCensor.CensorData(
+            rawString = testRawString,
+            hash = testHash.replace("8", "9"),
+            firstName = null,
+            lastName = null,
+            dateOfBirth = null
+        )
+
+        val censor = createInstance()
+
+        val logLineNotToCensor = LogLine(
+            timestamp = 1,
+            priority = 3,
+            message = "Here comes the hash: $testHash",
+            tag = "I am tag",
+            throwable = null
+        )
+
+        censor.checkLog(logLineNotToCensor) shouldBe null
+    }
+}
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
new file mode 100644
index 0000000000000000000000000000000000000000..c7f6d6b7f41e7d877a2a0842a8051153fc765a8c
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/TraceLocationCensorTest.kt
@@ -0,0 +1,189 @@
+package de.rki.coronawarnapp.bugreporting.censors
+
+import de.rki.coronawarnapp.bugreporting.censors.presencetracing.TraceLocationCensor
+import de.rki.coronawarnapp.bugreporting.debuglog.LogLine
+import de.rki.coronawarnapp.presencetracing.checkins.qrcode.TraceLocation
+import de.rki.coronawarnapp.presencetracing.locations.TraceLocationUserInput
+import de.rki.coronawarnapp.presencetracing.storage.repo.TraceLocationRepository
+import de.rki.coronawarnapp.server.protocols.internal.pt.TraceLocationOuterClass
+import io.kotest.matchers.shouldBe
+import io.mockk.MockKAnnotations
+import io.mockk.every
+import io.mockk.impl.annotations.MockK
+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.AfterEach
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import testhelpers.BaseTest
+
+internal class TraceLocationCensorTest : BaseTest() {
+
+    @MockK lateinit var traceLocationRepo: TraceLocationRepository
+
+    @BeforeEach
+    fun setup() {
+        MockKAnnotations.init(this)
+    }
+
+    @AfterEach
+    fun teardown() {
+        TraceLocationCensor.dataToCensor = null
+    }
+
+    private fun createInstance(scope: CoroutineScope) = TraceLocationCensor(
+        debugScope = scope,
+        traceLocationRepository = traceLocationRepo
+    )
+
+    private fun mockTraceLocation(
+        traceLocationId: Long,
+        traceLocationType: TraceLocationOuterClass.TraceLocationType,
+        traceLocationDescription: String,
+        traceLocationAddress: String,
+    ) = mockk<TraceLocation>().apply {
+        every { id } returns traceLocationId
+        every { type } returns traceLocationType
+        every { description } returns traceLocationDescription
+        every { address } returns traceLocationAddress
+    }
+
+    @Test
+    fun `checkLog() should return LogLine with censored trace location information from repository`() = runBlocking {
+        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"
+                )
+            )
+        )
+
+        val censor = createInstance(this)
+
+        val logLineToCensor = LogLine(
+            timestamp = 1,
+            priority = 3,
+            message =
+                """
+                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(),
+            tag = "I am tag",
+            throwable = null
+        )
+
+        censor.checkLog(logLineToCensor) shouldBe logLineToCensor.copy(
+            message =
+                """
+                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())
+
+        censor.checkLog(logLineToCensor) shouldBe logLineToCensor.copy(
+            message =
+                """
+                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()
+        )
+    }
+
+    @Test
+    fun `checkLog() should return LogLine with censored trace location information from companion object`() =
+        runBlocking {
+            every { traceLocationRepo.allTraceLocations } returns flowOf(emptyList())
+            TraceLocationCensor.dataToCensor = TraceLocationUserInput(
+                type = TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_TEMPORARY_PRIVATE_EVENT,
+                description = "Top Secret Private Event",
+                address = "top secret address",
+                startDate = null,
+                endDate = null,
+                defaultCheckInLengthInMinutes = 180
+            )
+
+            val censor = createInstance(this)
+
+            val logLineToCensor = LogLine(
+                timestamp = 1,
+                priority = 3,
+                message =
+                    """
+                The user just created a new traceLocation with Top Secret Private Event as the description and
+                top secret address as the address. The type is LOCATION_TYPE_TEMPORARY_PRIVATE_EVENT. 
+                    """.trimIndent(),
+                tag = "I am tag",
+                throwable = null
+            )
+
+            censor.checkLog(logLineToCensor) shouldBe logLineToCensor.copy(
+                message =
+                    """
+                The user just created a new traceLocation with TraceLocationUserInput#Description as the description and
+                TraceLocationUserInput#Address as the address. The type is TraceLocationUserInput#Type. 
+                    """.trimIndent()
+            )
+        }
+
+    @Test
+    fun `checkLog() should return null if no trace locations are stored`() = runBlockingTest {
+        every { traceLocationRepo.allTraceLocations } returns flowOf(emptyList())
+
+        val censor = createInstance(this)
+        val logLine = LogLine(
+            timestamp = 1,
+            priority = 3,
+            message = "Lorem ipsum",
+            tag = "I'm a tag",
+            throwable = null
+        )
+        censor.checkLog(logLine) shouldBe null
+    }
+
+    @Test
+    fun `checkLog() should return null if LogLine doesn't need to be censored`() = runBlockingTest {
+
+        every { traceLocationRepo.allTraceLocations } returns flowOf(
+            listOf(
+                mockTraceLocation(
+                    traceLocationId = 1,
+                    traceLocationType = TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_TEMPORARY_CULTURAL_EVENT,
+                    traceLocationDescription = "Description 1",
+                    traceLocationAddress = "Address 1"
+                ),
+                mockTraceLocation(
+                    traceLocationId = 2,
+                    traceLocationType = TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_TEMPORARY_CULTURAL_EVENT,
+                    traceLocationDescription = "Description 2",
+                    traceLocationAddress = "Address 2"
+                )
+            )
+        )
+
+        val censor = createInstance(this)
+        val logLine = LogLine(
+            timestamp = 1,
+            priority = 3,
+            message = "Lorem ipsum",
+            tag = "I'm a tag",
+            throwable = null
+        )
+
+        censor.checkLog(logLine) shouldBe null
+    }
+}
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
new file mode 100644
index 0000000000000000000000000000000000000000..f3c887739c3fc236ec281c5a69b8db69bf5f06a8
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/censors/submission/RatProfileCensorTest.kt
@@ -0,0 +1,106 @@
+package de.rki.coronawarnapp.bugreporting.censors.submission
+
+import de.rki.coronawarnapp.bugreporting.debuglog.LogLine
+import de.rki.coronawarnapp.coronatest.antigen.profile.RATProfile
+import de.rki.coronawarnapp.coronatest.antigen.profile.RATProfileSettings
+import io.kotest.matchers.shouldBe
+import io.mockk.MockKAnnotations
+import io.mockk.every
+import io.mockk.impl.annotations.MockK
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.runBlocking
+import org.joda.time.format.DateTimeFormat
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import testhelpers.BaseTest
+
+internal class RatProfileCensorTest : BaseTest() {
+
+    @MockK lateinit var ratProfileSettings: RATProfileSettings
+
+    @BeforeEach
+    fun setUp() {
+        MockKAnnotations.init(this)
+    }
+
+    private fun createInstance(scope: CoroutineScope) = RatProfileCensor(
+        ratProfileSettings = ratProfileSettings
+    )
+
+    @Test
+    fun `checkLog() should return null if no RAT profile is stored`() = runBlocking {
+        every { ratProfileSettings.profile.flow } returns flowOf(null)
+
+        val censor = createInstance(this)
+
+        val logLine = LogLine(
+            timestamp = 1,
+            priority = 3,
+            message = "Lorem ipsum",
+            tag = "I'm a tag",
+            throwable = null
+        )
+
+        censor.checkLog(logLine) shouldBe null
+    }
+
+    @Test
+    fun `checkLog() should return null if LogLine doesn't need to be censored`() = runBlocking {
+        every { ratProfileSettings.profile.flow } returns flowOf(profile)
+
+        val censor = createInstance(this)
+
+        val logLine = LogLine(
+            timestamp = 1,
+            priority = 3,
+            message = "Lorem ipsum",
+            tag = "I'm a tag",
+            throwable = null
+        )
+
+        censor.checkLog(logLine) shouldBe null
+    }
+
+    @Test
+    fun `checkLog() should return censored LogLine`() = runBlocking {
+        every { ratProfileSettings.profile.flow } returns flowOf(profile)
+
+        val censor = createInstance(this)
+
+        val logLine = LogLine(
+            timestamp = 1,
+            priority = 3,
+            message = "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",
+            tag = "I'm a tag",
+            throwable = null
+        )
+
+        censor.checkLog(logLine) shouldBe logLine.copy(
+            message = "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)
+
+        censor.checkLog(logLine) shouldBe logLine.copy(
+            message = "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"
+        )
+    }
+
+    private val formatter = DateTimeFormat.forPattern("yyyy-MM-dd")
+
+    private val profile = RATProfile(
+        firstName = "First name",
+        lastName = "Last name",
+        birthDate = formatter.parseLocalDate("1950-08-01"),
+        street = "Main street",
+        zipCode = "12132",
+        city = "London",
+        phone = "111111111",
+        email = "email@example.com"
+    )
+}
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/debuglog/DebugLoggerTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/debuglog/DebugLoggerTest.kt
index ace9d7c0a8bf6eacb9e3f12d265f0f0a157d593a..029f51ee528a097dd1be66fd1158be739dfd4588 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/debuglog/DebugLoggerTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/debuglog/DebugLoggerTest.kt
@@ -2,7 +2,7 @@ package de.rki.coronawarnapp.bugreporting.debuglog
 
 import android.app.Application
 import dagger.Lazy
-import de.rki.coronawarnapp.bugreporting.censors.RegistrationTokenCensor
+import de.rki.coronawarnapp.bugreporting.censors.submission.CoronaTestCensor
 import de.rki.coronawarnapp.bugreporting.debuglog.internal.DebugLogTree
 import de.rki.coronawarnapp.util.CWADebug
 import de.rki.coronawarnapp.util.di.ApplicationComponent
@@ -29,7 +29,7 @@ class DebugLoggerTest : BaseIOTest() {
 
     @MockK lateinit var application: Application
     @MockK lateinit var component: ApplicationComponent
-    @MockK lateinit var registrationTokenCensor: RegistrationTokenCensor
+    @MockK lateinit var coronaTestCensor: CoronaTestCensor
 
     private val testDir = File(IO_TEST_BASEDIR, this::class.simpleName!!)
     private val cacheDir = File(testDir, "cache")
@@ -49,10 +49,10 @@ class DebugLoggerTest : BaseIOTest() {
         every { application.cacheDir } returns cacheDir
         every { component.inject(any<DebugLogger>()) } answers {
             val logger = arg<DebugLogger>(0)
-            logger.bugCensors = Lazy { setOf(registrationTokenCensor) }
+            logger.bugCensors = Lazy { setOf(coronaTestCensor) }
         }
 
-        coEvery { registrationTokenCensor.checkLog(any()) } returns null
+        coEvery { coronaTestCensor.checkLog(any()) } returns null
     }
 
     @AfterEach
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/qrcode/scan/SubmissionQRCodeScanViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/qrcode/scan/SubmissionQRCodeScanViewModelTest.kt
index bd8f052d20fbc544f19b3ef378a2567a6c378c9e..846984526b98bb72db9be53e8dbd89d777a543b7 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/qrcode/scan/SubmissionQRCodeScanViewModelTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/qrcode/scan/SubmissionQRCodeScanViewModelTest.kt
@@ -1,7 +1,6 @@
 package de.rki.coronawarnapp.ui.submission.qrcode.scan
 
 import androidx.lifecycle.MutableLiveData
-import de.rki.coronawarnapp.bugreporting.censors.QRCodeCensor
 import de.rki.coronawarnapp.coronatest.qrcode.CoronaTestQRCode
 import de.rki.coronawarnapp.coronatest.qrcode.CoronaTestQrCodeValidator
 import de.rki.coronawarnapp.coronatest.qrcode.InvalidQRCodeException
@@ -87,12 +86,9 @@ class SubmissionQRCodeScanViewModelTest : BaseTest() {
 
         viewModel.qrCodeValidationState.value shouldBe ValidationState.STARTED
 
-        QRCodeCensor.lastGUID = null
-
         viewModel.onQrCodeAvailable(validQrCode)
         viewModel.qrCodeValidationState.observeForever {}
         viewModel.qrCodeValidationState.value shouldBe ValidationState.SUCCESS
-        QRCodeCensor.lastGUID = guid
 
         // invalid guid
         viewModel.onQrCodeAvailable(invalidQrCode)