diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/TestCertificateProcessor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateProcessor.kt
similarity index 78%
rename from Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/TestCertificateProcessor.kt
rename to Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateProcessor.kt
index fe9960c7c71e9a6add4e4d39857a47097bba1a8d..4dda48e8e6b93dd9313c5e394af85843f63a1868 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/TestCertificateProcessor.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateProcessor.kt
@@ -1,14 +1,17 @@
-package de.rki.coronawarnapp.covidcertificate.test.core.storage
+package de.rki.coronawarnapp.covidcertificate.test.core
 
 import dagger.Reusable
 import de.rki.coronawarnapp.appconfig.AppConfigProvider
-import de.rki.coronawarnapp.coronatest.type.CoronaTest
 import de.rki.coronawarnapp.covidcertificate.common.certificate.DccQrCodeExtractor
 import de.rki.coronawarnapp.covidcertificate.common.exception.InvalidHealthCertificateException
 import de.rki.coronawarnapp.covidcertificate.common.exception.InvalidTestCertificateException
 import de.rki.coronawarnapp.covidcertificate.common.exception.TestCertificateServerException
+import de.rki.coronawarnapp.covidcertificate.common.exception.TestCertificateServerException.ErrorCode
 import de.rki.coronawarnapp.covidcertificate.test.core.server.TestCertificateComponents
 import de.rki.coronawarnapp.covidcertificate.test.core.server.TestCertificateServer
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.types.PCRCertificateData
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.types.RACertificateData
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.types.RetrievedTestCertificate
 import de.rki.coronawarnapp.util.TimeStamper
 import de.rki.coronawarnapp.util.encryption.rsa.RSACryptography
 import de.rki.coronawarnapp.util.encryption.rsa.RSAKeyPairGenerator
@@ -34,10 +37,15 @@ class TestCertificateProcessor @Inject constructor(
      * the test certificate components should be available, via [obtainCertificate].
      */
     internal suspend fun registerPublicKey(
-        data: StoredTestCertificateData
-    ): StoredTestCertificateData {
+        data: RetrievedTestCertificate
+    ): RetrievedTestCertificate {
         Timber.tag(TAG).d("registerPublicKey(cert=%s)", data)
 
+        if (data is PCRCertificateData && data.labId.isNullOrBlank()) {
+            Timber.tag(TAG).e("PCR certificate is missing valid labId: %s", data)
+            throw TestCertificateServerException(ErrorCode.DCC_NOT_SUPPORTED_BY_LAB)
+        }
+
         if (data.publicKeyRegisteredAt != null) {
             Timber.tag(TAG).d("Public key is already registered for %s", data)
             return data
@@ -57,13 +65,13 @@ class TestCertificateProcessor @Inject constructor(
 
         val nowUTC = timeStamper.nowUTC
 
-        return when (data.type) {
-            CoronaTest.Type.PCR -> (data as PCRCertificateData).copy(
+        return when (data) {
+            is PCRCertificateData -> data.copy(
                 publicKeyRegisteredAt = nowUTC,
                 rsaPublicKey = rsaKeyPair.publicKey,
                 rsaPrivateKey = rsaKeyPair.privateKey,
             )
-            CoronaTest.Type.RAPID_ANTIGEN -> (data as RACertificateData).copy(
+            is RACertificateData -> data.copy(
                 publicKeyRegisteredAt = nowUTC,
                 rsaPublicKey = rsaKeyPair.publicKey,
                 rsaPrivateKey = rsaKeyPair.privateKey,
@@ -79,10 +87,15 @@ class TestCertificateProcessor @Inject constructor(
      * The server does not immediately return the test certificate components after registering the public key.
      */
     internal suspend fun obtainCertificate(
-        data: StoredTestCertificateData
-    ): StoredTestCertificateData {
+        data: RetrievedTestCertificate
+    ): RetrievedTestCertificate {
         Timber.tag(TAG).d("requestCertificate(cert=%s)", data)
 
+        if (data is PCRCertificateData && data.labId.isNullOrBlank()) {
+            Timber.tag(TAG).e("PCR certificate is missing valid labId: %s", data)
+            throw TestCertificateServerException(ErrorCode.DCC_NOT_SUPPORTED_BY_LAB)
+        }
+
         if (data.publicKeyRegisteredAt == null) {
             throw IllegalStateException("Public key is not registered yet.")
         }
@@ -111,7 +124,7 @@ class TestCertificateProcessor @Inject constructor(
         val components = try {
             executeRequest()
         } catch (e: TestCertificateServerException) {
-            if (e.errorCode == TestCertificateServerException.ErrorCode.DCC_COMP_202) {
+            if (e.errorCode == ErrorCode.DCC_COMP_202) {
                 delay(certConfig.waitForRetry.millis)
                 executeRequest()
             } else {
@@ -138,12 +151,12 @@ class TestCertificateProcessor @Inject constructor(
 
         val nowUtc = timeStamper.nowUTC
 
-        return when (data.type) {
-            CoronaTest.Type.PCR -> (data as PCRCertificateData).copy(
+        return when (data) {
+            is PCRCertificateData -> data.copy(
                 testCertificateQrCode = extractedData.qrCode,
                 certificateReceivedAt = nowUtc,
             )
-            CoronaTest.Type.RAPID_ANTIGEN -> (data as RACertificateData).copy(
+            is RACertificateData -> data.copy(
                 testCertificateQrCode = extractedData.qrCode,
                 certificateReceivedAt = nowUtc,
             )
@@ -151,13 +164,13 @@ class TestCertificateProcessor @Inject constructor(
     }
 
     internal suspend fun updateSeenByUser(
-        data: StoredTestCertificateData,
+        data: RetrievedTestCertificate,
         seenByUser: Boolean,
-    ): StoredTestCertificateData {
+    ): RetrievedTestCertificate {
         Timber.tag(TAG).d("updateSeenByUser(data=%s, seenByUser=%b)", data, seenByUser)
-        return when (data.type) {
-            CoronaTest.Type.PCR -> (data as PCRCertificateData).copy(certificateSeenByUser = seenByUser)
-            CoronaTest.Type.RAPID_ANTIGEN -> (data as RACertificateData).copy(certificateSeenByUser = seenByUser)
+        return when (data) {
+            is PCRCertificateData -> data.copy(certificateSeenByUser = seenByUser)
+            is RACertificateData -> data.copy(certificateSeenByUser = seenByUser)
         }
     }
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateRepository.kt
index cfa190d28b98f8aff99cdf49834ad108c9f76993..9b4b4ad40386e7a1546c15e762e3da625d589bee 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateRepository.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateRepository.kt
@@ -3,15 +3,18 @@ package de.rki.coronawarnapp.covidcertificate.test.core
 import de.rki.coronawarnapp.bugreporting.reportProblem
 import de.rki.coronawarnapp.coronatest.type.CoronaTest
 import de.rki.coronawarnapp.covidcertificate.common.certificate.DccQrCodeExtractor
-import de.rki.coronawarnapp.covidcertificate.common.exception.TestCertificateServerException
-import de.rki.coronawarnapp.covidcertificate.common.exception.TestCertificateServerException.ErrorCode.DCC_NOT_SUPPORTED_BY_LAB
-import de.rki.coronawarnapp.covidcertificate.test.core.storage.PCRCertificateData
-import de.rki.coronawarnapp.covidcertificate.test.core.storage.RACertificateData
+import de.rki.coronawarnapp.covidcertificate.common.exception.InvalidHealthCertificateException
+import de.rki.coronawarnapp.covidcertificate.common.exception.InvalidTestCertificateException
+import de.rki.coronawarnapp.covidcertificate.test.core.qrcode.TestCertificateQRCode
 import de.rki.coronawarnapp.covidcertificate.test.core.storage.TestCertificateContainer
 import de.rki.coronawarnapp.covidcertificate.test.core.storage.TestCertificateIdentifier
-import de.rki.coronawarnapp.covidcertificate.test.core.storage.TestCertificateProcessor
 import de.rki.coronawarnapp.covidcertificate.test.core.storage.TestCertificateStorage
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.types.GenericTestCertificateData
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.types.PCRCertificateData
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.types.RACertificateData
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.types.RetrievedTestCertificate
 import de.rki.coronawarnapp.covidcertificate.valueset.ValueSetsRepository
+import de.rki.coronawarnapp.util.TimeStamper
 import de.rki.coronawarnapp.util.coroutine.AppScope
 import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
 import de.rki.coronawarnapp.util.flow.HotDataFlow
@@ -39,6 +42,7 @@ class TestCertificateRepository @Inject constructor(
     private val storage: TestCertificateStorage,
     private val qrCodeExtractor: DccQrCodeExtractor,
     private val processor: TestCertificateProcessor,
+    private val timeStamper: TimeStamper,
     valueSetsRepository: ValueSetsRepository,
 ) {
 
@@ -98,9 +102,15 @@ class TestCertificateRepository @Inject constructor(
         Timber.tag(TAG).d("requestCertificate(test.identifier=%s)", test.identifier)
 
         val newData = internalData.updateBlocking {
-            if (values.any { it.registrationToken == test.registrationToken }) {
+
+            val matchesExisting = values
+                .map { it.data }
+                .filterIsInstance<RetrievedTestCertificate>()
+                .any { it.registrationToken == test.registrationToken }
+
+            if (matchesExisting) {
                 Timber.tag(TAG).e("Certificate entry already exists for %s", test.identifier)
-                throw IllegalArgumentException("A certificate was already created for this ${test.identifier}")
+                throw InvalidTestCertificateException(InvalidHealthCertificateException.ErrorCode.ALREADY_REGISTERED)
             }
             if (!test.isDccSupportedByPoc) {
                 throw IllegalArgumentException("DCC is not supported by PoC for this test: ${test.identifier}")
@@ -133,7 +143,42 @@ class TestCertificateRepository @Inject constructor(
             mutate { this[container.identifier] = container }
         }
 
-        return newData.values.single { it.registrationToken == test.registrationToken }
+        return newData.values.single {
+            it.data is RetrievedTestCertificate && it.data.registrationToken == test.registrationToken
+        }
+    }
+
+    suspend fun registerTestCertificate(
+        qrCode: TestCertificateQRCode
+    ): TestCertificateContainer {
+        Timber.tag(TAG).v("registerTestCertificate(qrCode=%s)", qrCode)
+
+        val updatedData = internalData.updateBlocking {
+
+            if (values.any { it.certificateId == qrCode.uniqueCertificateIdentifier }) {
+                Timber.tag(TAG).e("Certificate entry already exists for %s", qrCode)
+                throw InvalidTestCertificateException(InvalidHealthCertificateException.ErrorCode.ALREADY_REGISTERED)
+            }
+
+            val nowUtc = timeStamper.nowUTC
+
+            val data = GenericTestCertificateData(
+                identifier = UUID.randomUUID().toString(),
+                registeredAt = nowUtc,
+                certificateReceivedAt = nowUtc,
+                testCertificateQrCode = qrCode.qrCode
+            )
+            val container = TestCertificateContainer(
+                data = data,
+                qrCodeExtractor = qrCodeExtractor,
+            )
+            Timber.tag(TAG).d("Adding test certificate entry: %s", container)
+            mutate { this[container.identifier] = container }
+        }
+
+        // We just registered it, it MUST be available.
+        return updatedData.values
+            .single { it.certificateId == qrCode.uniqueCertificateIdentifier }
     }
 
     /**
@@ -156,7 +201,6 @@ class TestCertificateRepository @Inject constructor(
      *
      * [refresh] itself will NOT throw an exception.
      */
-    // TODO Will be addressed in 2.5?
     @Suppress("ComplexMethod")
     suspend fun refresh(identifier: TestCertificateIdentifier? = null): Set<RefreshResult> {
         Timber.tag(TAG).d("refresh(identifier=%s)", identifier)
@@ -168,6 +212,7 @@ class TestCertificateRepository @Inject constructor(
         internalData.updateBlocking {
             val toRefresh = values
                 .filter { it.identifier == identifier || identifier == null } // Targets of our refresh
+                .filter { it.data is RetrievedTestCertificate } // Can only update retrieved certificates
                 .filter { !it.isUpdatingData && it.isCertificateRetrievalPending } // Those that need refreshing
 
             mutate {
@@ -178,43 +223,15 @@ class TestCertificateRepository @Inject constructor(
             }
         }
 
-        // Not sure i really like this
-        internalData.updateBlocking {
-            Timber.tag(TAG).d("Checking for invalid lab id.")
-
-            val refreshedCerts = values
-                .filter { workedOnIds.contains(it.identifier) } // Refresh targets
-                .filter { it.labId == null && it.data is PCRCertificateData } // Targets of this step
-                .map { cert ->
-                    Timber.tag(TAG).d("%s is missing a lab id returning exception", cert)
-                    RefreshResult(
-                        cert,
-                        TestCertificateServerException(
-                            DCC_NOT_SUPPORTED_BY_LAB
-                        )
-                    )
-                }
-
-            refreshedCerts.forEach {
-                refreshCallResults[it.certificateContainer.identifier] = it
-            }
-
-            mutate {
-                refreshedCerts
-                    .filter { it.error == null }
-                    .map { it.certificateContainer }
-                    .forEach { this[it.identifier] = it }
-            }
-        }
-
         internalData.updateBlocking {
             Timber.tag(TAG).d("Checking for unregistered public keys.")
 
             val refreshedCerts = values
                 .filter { workedOnIds.contains(it.identifier) } // Refresh targets
-                .filter { !it.isPublicKeyRegistered } // Targets of this step
-                .filter { it.labId != null || it.data !is PCRCertificateData }
-                .map { cert ->
+                .mapNotNull { cert ->
+                    if (cert.data !is RetrievedTestCertificate) return@mapNotNull null
+                    if (cert.data.isPublicKeyRegistered) return@mapNotNull null
+
                     withContext(dispatcherProvider.IO) {
                         try {
                             val updatedData = processor.registerPublicKey(cert.data)
@@ -243,9 +260,12 @@ class TestCertificateRepository @Inject constructor(
 
             val refreshedCerts = values
                 .filter { workedOnIds.contains(it.identifier) } // Refresh targets
-                .filter { it.isPublicKeyRegistered && it.isCertificateRetrievalPending } // Targets of this step
-                .filter { it.labId != null || it.data !is PCRCertificateData }
-                .map { cert ->
+                .mapNotNull { cert ->
+                    if (cert.data !is RetrievedTestCertificate) return@mapNotNull null
+
+                    if (!cert.data.isPublicKeyRegistered) return@mapNotNull null
+                    if (!cert.isCertificateRetrievalPending) return@mapNotNull null
+
                     withContext(dispatcherProvider.IO) {
                         try {
                             val updatedData = processor.obtainCertificate(cert.data)
@@ -270,12 +290,10 @@ class TestCertificateRepository @Inject constructor(
         }
 
         internalData.updateBlocking {
-            val certs = values.filter { workedOnIds.contains(it.identifier) }
-
             mutate {
-                certs.forEach {
-                    this[it.identifier] = it.copy(isUpdatingData = false)
-                }
+                values
+                    .filter { workedOnIds.contains(it.identifier) }
+                    .forEach { this[it.identifier] = it.copy(isUpdatingData = false) }
             }
         }
 
@@ -314,6 +332,11 @@ class TestCertificateRepository @Inject constructor(
                 return@updateBlocking this
             }
 
+            if (current.data !is RetrievedTestCertificate) {
+                Timber.tag(TAG).w("%s is not a retrieved certificate, so it was immediately available.", identifier)
+                return@updateBlocking this
+            }
+
             val updated = current.copy(
                 data = processor.updateSeenByUser(current.data, true)
             )
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateWrapper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateWrapper.kt
index 0df7c8164ead0b32c0651a94157746965feeeab7..698531b2fbe984f50967f6272f10587e91d175d0 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateWrapper.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateWrapper.kt
@@ -3,25 +3,26 @@ package de.rki.coronawarnapp.covidcertificate.test.core
 import de.rki.coronawarnapp.covidcertificate.test.core.storage.TestCertificateContainer
 import de.rki.coronawarnapp.covidcertificate.test.core.storage.TestCertificateIdentifier
 import de.rki.coronawarnapp.covidcertificate.valueset.valuesets.TestCertificateValueSets
+import org.joda.time.Instant
 
 data class TestCertificateWrapper(
     private val valueSets: TestCertificateValueSets,
     private val container: TestCertificateContainer
 ) {
 
-    val identifier: TestCertificateIdentifier = container.identifier
+    val identifier: TestCertificateIdentifier get() = container.identifier
 
-    val isCertificateRetrievalPending = container.isCertificateRetrievalPending
+    val isCertificateRetrievalPending: Boolean get() = container.isCertificateRetrievalPending
 
-    val isUpdatingData = container.isUpdatingData
+    val isUpdatingData: Boolean get() = container.isUpdatingData
 
-    val registeredAt = container.registeredAt
+    val registeredAt: Instant get() = container.registeredAt
 
-    val seenByUser = container.certificateSeenByUser
+    val seenByUser: Boolean get() = container.certificateSeenByUser
+
+    val registrationToken: String? get() = container.registrationToken
 
     val testCertificate: TestCertificate? by lazy {
         container.toTestCertificate(valueSets)
     }
-
-    val registrationToken = container.registrationToken
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/StoredTestCertificateData.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/StoredTestCertificateData.kt
deleted file mode 100644
index 9ce2281d176f35a686386dcea9203446f856edea..0000000000000000000000000000000000000000
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/StoredTestCertificateData.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-package de.rki.coronawarnapp.covidcertificate.test.core.storage
-
-import de.rki.coronawarnapp.coronatest.type.CoronaTest
-import de.rki.coronawarnapp.coronatest.type.RegistrationToken
-import de.rki.coronawarnapp.util.encryption.rsa.RSAKey
-import okio.ByteString
-import org.joda.time.Instant
-
-interface StoredTestCertificateData {
-    val identifier: TestCertificateIdentifier
-    val registrationToken: RegistrationToken
-    val type: CoronaTest.Type
-    val registeredAt: Instant
-    val publicKeyRegisteredAt: Instant?
-    val rsaPublicKey: RSAKey.Public?
-    val rsaPrivateKey: RSAKey.Private?
-    val certificateReceivedAt: Instant?
-    val encryptedDataEncryptionkey: ByteString?
-    val encryptedDccCose: ByteString?
-    val testCertificateQrCode: String?
-    val labId: String?
-    val certificateSeenByUser: Boolean
-}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/TestCertificateContainer.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/TestCertificateContainer.kt
index 3afa51c3c70cc98bc6a327a32c2dd0ac067469e4..ea176ee6de746207ded7ba152a4ee31a3dc26a98 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/TestCertificateContainer.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/TestCertificateContainer.kt
@@ -6,16 +6,19 @@ import de.rki.coronawarnapp.covidcertificate.common.certificate.DccV1Parser
 import de.rki.coronawarnapp.covidcertificate.common.qrcode.QrCodeString
 import de.rki.coronawarnapp.covidcertificate.test.core.TestCertificate
 import de.rki.coronawarnapp.covidcertificate.test.core.qrcode.TestCertificateQRCode
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.types.BaseTestCertificateData
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.types.GenericTestCertificateData
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.types.RetrievedTestCertificate
 import de.rki.coronawarnapp.covidcertificate.valueset.valuesets.TestCertificateValueSets
 import org.joda.time.Instant
 import org.joda.time.LocalDate
 import java.util.Locale
 
 data class TestCertificateContainer(
-    internal val data: StoredTestCertificateData,
-    private val qrCodeExtractor: DccQrCodeExtractor,
+    internal val data: BaseTestCertificateData,
+    internal val qrCodeExtractor: DccQrCodeExtractor,
     val isUpdatingData: Boolean = false,
-) : StoredTestCertificateData by data {
+) {
 
     @delegate:Transient
     private val testCertificateQRCode: TestCertificateQRCode by lazy {
@@ -27,8 +30,23 @@ data class TestCertificateContainer(
         }
     }
 
-    val isPublicKeyRegistered: Boolean
-        get() = data.publicKeyRegisteredAt != null
+    val registrationToken: String?
+        get() = when (data) {
+            is RetrievedTestCertificate -> data.registrationToken
+            is GenericTestCertificateData -> null // Has none
+        }
+
+    val certificateSeenByUser: Boolean
+        get() = when (data) {
+            is RetrievedTestCertificate -> data.certificateSeenByUser
+            is GenericTestCertificateData -> true // Immediately available
+        }
+
+    val identifier: TestCertificateIdentifier
+        get() = data.identifier
+
+    val registeredAt: Instant
+        get() = data.registeredAt
 
     val isCertificateRetrievalPending: Boolean
         get() = data.certificateReceivedAt == null
@@ -40,7 +58,7 @@ data class TestCertificateContainer(
         }
 
     fun toTestCertificate(
-        valueSet: TestCertificateValueSets?,
+        valueSet: TestCertificateValueSets? = null,
         userLocale: Locale = Locale.getDefault(),
     ): TestCertificate? {
         if (isCertificateRetrievalPending) return null
@@ -80,15 +98,6 @@ data class TestCertificateContainer(
             override val testCenter: String?
                 get() = testCertificate.testCenter
 
-            override val isUpdatingData: Boolean
-                get() = this@TestCertificateContainer.isUpdatingData
-
-            override val registeredAt: Instant
-                get() = this@TestCertificateContainer.registeredAt
-
-            override val isCertificateRetrievalPending: Boolean
-                get() = this@TestCertificateContainer.isCertificateRetrievalPending
-
             override val certificateIssuer: String
                 get() = header.issuer
             override val certificateCountry: String
@@ -106,6 +115,15 @@ data class TestCertificateContainer(
 
             override val qrCode: QrCodeString
                 get() = data.testCertificateQrCode!!
+
+            override val isUpdatingData: Boolean
+                get() = this@TestCertificateContainer.isUpdatingData
+
+            override val registeredAt: Instant
+                get() = data.registeredAt
+
+            override val isCertificateRetrievalPending: Boolean
+                get() = this@TestCertificateContainer.isCertificateRetrievalPending
         }
     }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/TestCertificateStorage.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/TestCertificateStorage.kt
index 087486024444e89c955a9d87d4ba1b3ed5123e0c..01ddef7c27d8398d8e2b2958934b492a3882b1e2 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/TestCertificateStorage.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/TestCertificateStorage.kt
@@ -1,12 +1,15 @@
 package de.rki.coronawarnapp.covidcertificate.test.core.storage
 
 import android.content.Context
+import android.content.SharedPreferences
 import androidx.core.content.edit
 import com.google.gson.Gson
 import com.google.gson.reflect.TypeToken
 import de.rki.coronawarnapp.coronatest.server.CoronaTestResult
-import de.rki.coronawarnapp.coronatest.type.CoronaTest
-import de.rki.coronawarnapp.covidcertificate.vaccination.core.repository.storage.ContainerPostProcessor
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.types.BaseTestCertificateData
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.types.GenericTestCertificateData
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.types.PCRCertificateData
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.types.RACertificateData
 import de.rki.coronawarnapp.util.di.AppContext
 import de.rki.coronawarnapp.util.serialization.BaseGson
 import timber.log.Timber
@@ -17,7 +20,6 @@ import javax.inject.Singleton
 class TestCertificateStorage @Inject constructor(
     @AppContext val context: Context,
     @BaseGson val baseGson: Gson,
-    private val containerPostProcessor: ContainerPostProcessor,
 ) {
 
     private val prefs by lazy {
@@ -27,73 +29,73 @@ class TestCertificateStorage @Inject constructor(
     private val gson by lazy {
         baseGson.newBuilder().apply {
             registerTypeAdapter(CoronaTestResult::class.java, CoronaTestResult.GsonAdapter())
-            registerTypeAdapterFactory(containerPostProcessor)
         }.create()
     }
 
-    private val typeTokenPCR by lazy {
-        object : TypeToken<Set<PCRCertificateData>>() {}.type
+    private val typeTokenPCR: TypeToken<Set<PCRCertificateData>> by lazy {
+        object : TypeToken<Set<PCRCertificateData>>() {}
     }
-
-    private val typeTokenRA by lazy {
-        object : TypeToken<Set<RACertificateData>>() {}.type
+    private val typeTokenRA: TypeToken<Set<RACertificateData>> by lazy {
+        object : TypeToken<Set<RACertificateData>>() {}
+    }
+    private val typeTokenGeneric: TypeToken<Set<GenericTestCertificateData>> by lazy {
+        object : TypeToken<Set<GenericTestCertificateData>>() {}
     }
 
-    var testCertificates: Collection<StoredTestCertificateData>
+    var testCertificates: Collection<BaseTestCertificateData>
         get() {
             Timber.tag(TAG).d("load()")
 
-            val pcrCertContainers: Set<PCRCertificateData> = run {
-                val raw = prefs.getString(PKEY_DATA_PCR, null) ?: return@run emptySet()
-                gson.fromJson<Set<PCRCertificateData>>(raw, typeTokenPCR).onEach {
-                    Timber.tag(TAG).v("PCR loaded: %s", it)
-                    requireNotNull(it.identifier)
-                    requireNotNull(it.type) { "PCR type should not be null, GSON footgun." }
-                }
-            }
-
-            val raCerts: Set<RACertificateData> = run {
-                val raw = prefs.getString(PKEY_DATA_RA, null) ?: return@run emptySet()
-                gson.fromJson<Set<RACertificateData>>(raw, typeTokenRA).onEach {
-                    Timber.tag(TAG).v("RA loaded: %s", it)
-                    requireNotNull(it.identifier)
-                    requireNotNull(it.type) { "RA type should not be null, GSON footgun." }
-                }
-            }
+            val pcrCertContainers: Set<PCRCertificateData> = prefs.loadCerts(typeTokenPCR, PKEY_DATA_PCR)
+            val raCerts: Set<RACertificateData> = prefs.loadCerts(typeTokenRA, PKEY_DATA_RA)
+            val scannedCerts: Set<GenericTestCertificateData> = prefs.loadCerts(typeTokenGeneric, PKEY_DATA_SCANNED)
 
-            return (pcrCertContainers + raCerts).also {
+            return (pcrCertContainers + raCerts + scannedCerts).also {
                 Timber.tag(TAG).v("Loaded %d certificates.", it.size)
             }
         }
         set(value) {
             Timber.tag(TAG).d("save(testCertificates=%s)", value)
             prefs.edit {
-                value.filter { it.type == CoronaTest.Type.PCR }.run {
-                    if (isNotEmpty()) {
-                        val raw = gson.toJson(this, typeTokenPCR)
-                        Timber.tag(TAG).v("PCR storing: %s", raw)
-                        putString(PKEY_DATA_PCR, raw)
-                    } else {
-                        Timber.tag(TAG).v("No PCR certificates available, clearing.")
-                        remove(PKEY_DATA_PCR)
-                    }
-                }
-                value.filter { it.type == CoronaTest.Type.RAPID_ANTIGEN }.run {
-                    if (isNotEmpty()) {
-                        val raw = gson.toJson(this, typeTokenRA)
-                        Timber.tag(TAG).v("RA storing: %s", raw)
-                        putString(PKEY_DATA_RA, raw)
-                    } else {
-                        Timber.tag(TAG).v("No RA certificates available, clearing.")
-                        remove(PKEY_DATA_RA)
-                    }
-                }
+
+                storeCerts(value.filterIsInstance<PCRCertificateData>(), typeTokenPCR, PKEY_DATA_PCR)
+                storeCerts(value.filterIsInstance<RACertificateData>(), typeTokenRA, PKEY_DATA_RA)
+                storeCerts(value.filterIsInstance<GenericTestCertificateData>(), typeTokenGeneric, PKEY_DATA_SCANNED)
             }
         }
 
+    private fun <T : BaseTestCertificateData> SharedPreferences.Editor.storeCerts(
+        certs: Collection<BaseTestCertificateData>,
+        typeToken: TypeToken<Set<T>>,
+        storageKey: String
+    ) {
+        val type = typeToken.type
+        if (certs.isNotEmpty()) {
+            val raw = gson.toJson(certs, type)
+            Timber.tag(TAG).v("Storing scanned certs ($type): %s", raw)
+            putString(storageKey, raw)
+        } else {
+            Timber.tag(TAG).v("No stored certificates ($type) available, clearing.")
+            remove(storageKey)
+        }
+    }
+
+    private fun <T : BaseTestCertificateData> SharedPreferences.loadCerts(
+        typeToken: TypeToken<Set<T>>,
+        storageKey: String
+    ): Set<T> {
+        val type = typeToken.type
+        val raw = prefs.getString(storageKey, null) ?: return emptySet()
+        return gson.fromJson<Set<T>>(raw, type).onEach {
+            Timber.tag(TAG).v("Certificates ($type) loaded: %s", it)
+            requireNotNull(it.identifier)
+        }
+    }
+
     companion object {
         private const val TAG = "TestCertificateStorage"
         private const val PKEY_DATA_RA = "testcertificate.data.ra"
         private const val PKEY_DATA_PCR = "testcertificate.data.pcr"
+        private const val PKEY_DATA_SCANNED = "testcertificate.data.scanned"
     }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/types/BaseTestCertificateData.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/types/BaseTestCertificateData.kt
new file mode 100644
index 0000000000000000000000000000000000000000..9c43db6d2f8c465ca660f43b0f07f24ae0550efa
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/types/BaseTestCertificateData.kt
@@ -0,0 +1,14 @@
+package de.rki.coronawarnapp.covidcertificate.test.core.storage.types
+
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.TestCertificateIdentifier
+import org.joda.time.Instant
+
+/**
+ * Common data for test certificates, idepdent of whether they were retrieved or scanned.
+ */
+sealed class BaseTestCertificateData {
+    abstract val identifier: TestCertificateIdentifier
+    abstract val registeredAt: Instant
+    abstract val certificateReceivedAt: Instant?
+    abstract val testCertificateQrCode: String?
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/types/GenericTestCertificateData.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/types/GenericTestCertificateData.kt
new file mode 100644
index 0000000000000000000000000000000000000000..c441d4a1471a2c5aa1fc607e41810a17b069df40
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/types/GenericTestCertificateData.kt
@@ -0,0 +1,30 @@
+package de.rki.coronawarnapp.covidcertificate.test.core.storage.types
+
+import com.google.gson.annotations.SerializedName
+import org.joda.time.Instant
+
+/**
+ * A generic data class used to store data for scanned qrcodes.
+ * May be cloned if we need to support different types of test certificates in the future.
+ */
+data class GenericTestCertificateData(
+    @SerializedName("identifier")
+    override val identifier: String,
+
+    @SerializedName("registeredAt")
+    override val registeredAt: Instant,
+
+    @SerializedName("certificateReceivedAt")
+    override val certificateReceivedAt: Instant? = null,
+
+    @SerializedName("testCertificateQrCode")
+    override val testCertificateQrCode: String? = null,
+) : ScannedTestCertificate() {
+
+    // Otherwise GSON unsafes reflection to create this class, and sets the LAZY to null
+    @Suppress("unused")
+    constructor() : this(
+        identifier = "",
+        registeredAt = Instant.EPOCH
+    )
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/PCRCertificateData.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/types/PCRCertificateData.kt
similarity index 87%
rename from Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/PCRCertificateData.kt
rename to Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/types/PCRCertificateData.kt
index d53a1d54b8bd82a026349e87f191443e7564fb4f..a3e3d056ba50ce9f3da43148eb13e33ea6d729c0 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/PCRCertificateData.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/types/PCRCertificateData.kt
@@ -1,7 +1,6 @@
-package de.rki.coronawarnapp.covidcertificate.test.core.storage
+package de.rki.coronawarnapp.covidcertificate.test.core.storage.types
 
 import com.google.gson.annotations.SerializedName
-import de.rki.coronawarnapp.coronatest.type.CoronaTest
 import de.rki.coronawarnapp.coronatest.type.RegistrationToken
 import de.rki.coronawarnapp.util.encryption.rsa.RSAKey
 import okio.ByteString
@@ -43,7 +42,7 @@ data class PCRCertificateData internal constructor(
 
     @SerializedName("certificateSeenByUser")
     override val certificateSeenByUser: Boolean = false,
-) : StoredTestCertificateData {
+) : RetrievedTestCertificate() {
 
     // Otherwise GSON unsafes reflection to create this class, and sets the LAZY to null
     @Suppress("unused")
@@ -52,7 +51,4 @@ data class PCRCertificateData internal constructor(
         registrationToken = "",
         registeredAt = Instant.EPOCH
     )
-
-    override val type: CoronaTest.Type
-        get() = CoronaTest.Type.PCR
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/RACertificateData.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/types/RACertificateData.kt
similarity index 87%
rename from Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/RACertificateData.kt
rename to Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/types/RACertificateData.kt
index fe10fabb6604501b72a8f73f6482095e834db3dc..051ae776d646fef2dd58a64846b7e21ef505637b 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/RACertificateData.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/types/RACertificateData.kt
@@ -1,7 +1,6 @@
-package de.rki.coronawarnapp.covidcertificate.test.core.storage
+package de.rki.coronawarnapp.covidcertificate.test.core.storage.types
 
 import com.google.gson.annotations.SerializedName
-import de.rki.coronawarnapp.coronatest.type.CoronaTest
 import de.rki.coronawarnapp.coronatest.type.RegistrationToken
 import de.rki.coronawarnapp.util.encryption.rsa.RSAKey
 import okio.ByteString
@@ -43,7 +42,7 @@ data class RACertificateData(
 
     @SerializedName("certificateSeenByUser")
     override val certificateSeenByUser: Boolean = false,
-) : StoredTestCertificateData {
+) : RetrievedTestCertificate() {
 
     // Otherwise GSON unsafes reflection to create this class, and sets the LAZY to null
     @Suppress("unused")
@@ -52,7 +51,4 @@ data class RACertificateData(
         registrationToken = "",
         registeredAt = Instant.EPOCH
     )
-
-    override val type: CoronaTest.Type
-        get() = CoronaTest.Type.RAPID_ANTIGEN
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/types/RetrievedTestCertificate.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/types/RetrievedTestCertificate.kt
new file mode 100644
index 0000000000000000000000000000000000000000..614e452e3b7441353ebf158e02c3cf1216f39212
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/types/RetrievedTestCertificate.kt
@@ -0,0 +1,28 @@
+package de.rki.coronawarnapp.covidcertificate.test.core.storage.types
+
+import de.rki.coronawarnapp.coronatest.type.RegistrationToken
+import de.rki.coronawarnapp.util.encryption.rsa.RSAKey
+import okio.ByteString
+import org.joda.time.Instant
+
+/**
+ * A test certificate that is, or will be, retrieved by the CWA.
+ * Either a [RACertificateData] or [PCRCertificateData]
+ */
+sealed class RetrievedTestCertificate : BaseTestCertificateData() {
+
+    abstract val registrationToken: RegistrationToken
+
+    abstract val publicKeyRegisteredAt: Instant?
+    abstract val rsaPublicKey: RSAKey.Public?
+    abstract val rsaPrivateKey: RSAKey.Private?
+
+    abstract val encryptedDataEncryptionkey: ByteString?
+    abstract val encryptedDccCose: ByteString?
+
+    abstract val labId: String?
+    abstract val certificateSeenByUser: Boolean
+
+    val isPublicKeyRegistered: Boolean
+        get() = publicKeyRegisteredAt != null
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/types/ScannedTestCertificate.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/types/ScannedTestCertificate.kt
new file mode 100644
index 0000000000000000000000000000000000000000..49a28c8cc3cd76f0495099834907f81236caa0e4
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/types/ScannedTestCertificate.kt
@@ -0,0 +1,6 @@
+package de.rki.coronawarnapp.covidcertificate.test.core.storage.types
+
+/**
+ * A scanned test certificate, e.g. from a qr code.
+ */
+sealed class ScannedTestCertificate : BaseTestCertificateData()
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/CoronaTestTestComponent.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/CoronaTestTestComponent.kt
index 79a1f43020fdb4839313f36afdc00e775afe2925..edea3c746e741a86d7be55b50b3f5aa58e33cdda 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/CoronaTestTestComponent.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/CoronaTestTestComponent.kt
@@ -3,7 +3,8 @@ package de.rki.coronawarnapp.coronatest
 import dagger.Component
 import dagger.Module
 import de.rki.coronawarnapp.coronatest.type.TestCertificateContainerTest
-import de.rki.coronawarnapp.covidcertificate.test.storage.TestCertificateStorageTest
+import de.rki.coronawarnapp.covidcertificate.test.core.TestCertificateRepositoryTest
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.TestCertificateStorageTest
 import de.rki.coronawarnapp.util.serialization.SerializationModule
 import javax.inject.Singleton
 
@@ -18,6 +19,7 @@ interface CoronaTestTestComponent {
 
     fun inject(testClass: TestCertificateStorageTest)
     fun inject(testClass: TestCertificateContainerTest)
+    fun inject(testClass: TestCertificateRepositoryTest)
 
     @Component.Factory
     interface Factory {
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/TestCertificateContainerTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/TestCertificateContainerTest.kt
index 18fd7a8ed99aab9ea3405f50ac03730c32754dd5..6ebeb375d6b2d018cdcd7dbbb404db77ae6d9cac 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/TestCertificateContainerTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/TestCertificateContainerTest.kt
@@ -23,7 +23,6 @@ class TestCertificateContainerTest : BaseTest() {
     @Test
     fun `ui facing test certificate creation and fallbacks`() {
         certificateTestData.personATest2CertContainer.apply {
-            isPublicKeyRegistered shouldBe true
             isCertificateRetrievalPending shouldBe false
             certificateId shouldBe "URN:UVCI:V1:DE:7WR8CE12Y8O2AN4NK320TPNKB1"
             data.testCertificateQrCode shouldBe certificateTestData.personATest2CertQRCodeString
@@ -35,7 +34,6 @@ class TestCertificateContainerTest : BaseTest() {
     @Test
     fun `pending check and nullability`() {
         certificateTestData.personATest3CertNokeyContainer.apply {
-            isPublicKeyRegistered shouldBe false
             isCertificateRetrievalPending shouldBe true
             certificateId shouldBe null
             data.testCertificateQrCode shouldBe null
@@ -44,7 +42,6 @@ class TestCertificateContainerTest : BaseTest() {
         }
 
         certificateTestData.personATest4CertPendingContainer.apply {
-            isPublicKeyRegistered shouldBe true
             isCertificateRetrievalPending shouldBe true
             certificateId shouldBe null
             data.testCertificateQrCode shouldBe null
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/TestCertificateRepositoryTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/TestCertificateRepositoryTest.kt
deleted file mode 100644
index c170f486908b41df490f43cfc5071b1848f5acf2..0000000000000000000000000000000000000000
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/TestCertificateRepositoryTest.kt
+++ /dev/null
@@ -1,79 +0,0 @@
-package de.rki.coronawarnapp.covidcertificate.test
-
-import de.rki.coronawarnapp.appconfig.CovidCertificateConfig
-import de.rki.coronawarnapp.covidcertificate.common.certificate.DccQrCodeExtractor
-import de.rki.coronawarnapp.covidcertificate.common.qrcode.DccQrCode
-import de.rki.coronawarnapp.covidcertificate.test.core.TestCertificateRepository
-import de.rki.coronawarnapp.covidcertificate.test.core.storage.PCRCertificateData
-import de.rki.coronawarnapp.covidcertificate.test.core.storage.StoredTestCertificateData
-import de.rki.coronawarnapp.covidcertificate.test.core.storage.TestCertificateProcessor
-import de.rki.coronawarnapp.covidcertificate.test.core.storage.TestCertificateStorage
-import de.rki.coronawarnapp.covidcertificate.valueset.ValueSetsRepository
-import io.mockk.MockKAnnotations
-import io.mockk.coEvery
-import io.mockk.every
-import io.mockk.impl.annotations.MockK
-import io.mockk.mockk
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.emptyFlow
-import org.joda.time.Duration
-import org.joda.time.Instant
-import org.junit.jupiter.api.BeforeEach
-import testhelpers.BaseTest
-import testhelpers.TestDispatcherProvider
-
-class TestCertificateRepositoryTest : BaseTest() {
-
-    @MockK lateinit var storage: TestCertificateStorage
-    @MockK lateinit var qrCodeExtractor: DccQrCodeExtractor
-    @MockK lateinit var covidTestCertificateConfig: CovidCertificateConfig.TestCertificate
-    @MockK lateinit var valueSetsRepository: ValueSetsRepository
-    @MockK lateinit var testCertificateProcessor: TestCertificateProcessor
-
-    private val testCertificateNew = PCRCertificateData(
-        identifier = "identifier1",
-        registrationToken = "regtoken1",
-        registeredAt = Instant.EPOCH,
-    )
-
-    private val testCertificateWithPubKey = testCertificateNew.copy(
-        publicKeyRegisteredAt = Instant.EPOCH,
-        rsaPublicKey = mockk(),
-        rsaPrivateKey = mockk(),
-    )
-
-    private var storageSet = mutableSetOf<StoredTestCertificateData>()
-
-    @BeforeEach
-    fun setup() {
-        MockKAnnotations.init(this)
-
-        covidTestCertificateConfig.apply {
-            every { waitForRetry } returns Duration.standardSeconds(10)
-            every { waitAfterPublicKeyRegistration } returns Duration.standardSeconds(10)
-        }
-
-        storage.apply {
-            every { storage.testCertificates = any() } answers {
-                storageSet.clear()
-                storageSet.addAll(arg(0))
-            }
-            every { storage.testCertificates } answers { storageSet }
-        }
-
-        coEvery { qrCodeExtractor.extract(any()) } returns mockk<DccQrCode>().apply {
-            every { qrCode } returns "qrCode"
-            every { data } returns mockk()
-        }
-        every { valueSetsRepository.latestTestCertificateValueSets } returns emptyFlow()
-    }
-
-    private fun createInstance(scope: CoroutineScope) = TestCertificateRepository(
-        appScope = scope,
-        dispatcherProvider = TestDispatcherProvider(),
-        storage = storage,
-        qrCodeExtractor = qrCodeExtractor,
-        valueSetsRepository = valueSetsRepository,
-        processor = testCertificateProcessor,
-    )
-}
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/TestCertificateTestData.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/TestCertificateTestData.kt
index ae152c4d202eedd243eb3a5e4974d22bc76147da..c6e1265c938e89c6140f74301393e3c54c708243 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/TestCertificateTestData.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/TestCertificateTestData.kt
@@ -1,9 +1,11 @@
 package de.rki.coronawarnapp.covidcertificate.test
 
 import de.rki.coronawarnapp.covidcertificate.common.certificate.DccQrCodeExtractor
-import de.rki.coronawarnapp.covidcertificate.test.core.storage.PCRCertificateData
-import de.rki.coronawarnapp.covidcertificate.test.core.storage.RACertificateData
+import de.rki.coronawarnapp.covidcertificate.test.core.qrcode.TestCertificateQRCode
 import de.rki.coronawarnapp.covidcertificate.test.core.storage.TestCertificateContainer
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.types.GenericTestCertificateData
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.types.PCRCertificateData
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.types.RACertificateData
 import de.rki.coronawarnapp.util.encryption.rsa.RSAKey
 import okio.ByteString.Companion.decodeBase64
 import org.joda.time.Instant
@@ -17,6 +19,8 @@ class TestCertificateTestData @Inject constructor(
     val personATest1CertQRCodeString =
         "HC1:6BFQ$9FY7$\$Q00019C-5HQ57WDQTLUMS256TUMP49JLZCX/N4VB14NRINX6J7+KF\$UB.N83CMMPVNPAHJ035FT88%AJ1R*UOGR3ZWLC24+F7DO276HB.O*BEVJODVSKNOP0T4\$FZ.R/03N6QK3A05EQVBONNHSJ9WJT+B15H NBEZ3VI8-V77AFL4NY9V*JM *KOPC2H8PR5OG9:VIG$969FJRV28N9PORZJQ43EOIHIJ+83XDDRB201N.L58EB7 8GS8. 9GPNGHFV/6\$I3R3R4930TC/ZGZESM929.D59GO13E\$H7LMUGS18ABF6YD955C C6VPNMZU+3FJR1RVLBZDR2F*8A4MKWIH+/JPU1*H6E2CTHGYHPPU6U*FYFJ6RJO*I8P1T59S:V3V1SA86L8Y8A5XB*10112G8GHK77CBOK9QEI960TTNC.I3A4P8BM6DO:MI/98PC/ZP2:JW3JB.J:R2.5GX0J$1J.OOCYSS8A*DS\$AFVJR9RT-L6N%PS%CV%B8KL0%EL SXLBSA6 %M6JEN+E0Q8A:RAGW16KGUA627-Y2:EDH\$VFVT:29FWUTJSANSYCV4PSKNP\$ZV-8T27SV4CC3CJIV20TKBS22O$/MT/V*0Q0IUE0DBPT+UP03IR1CRFOP3"
 
+    val personATest1CertQRCode = qrCodeExtractor.extract(personATest1CertQRCodeString) as TestCertificateQRCode
+
     val personATest1StoredData = run {
         val publicKey = RSAKey.Public(
             "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA2+WCCvy0SNqZMy/V1FYYMkBTGp/5BQt/NxUW1nIkj84u6duqNNQh4GjugoDc8epyl/yi3D61Jt7qArwk+eTcnW4/jEOexT5pCabRKrFm6IMndSefYrP3CeaD86ZU47uhnRuCG3TcPhIqUN2E37EbOsI9Z59JXc5tmmB71CxTF0bjE0PNLgbTU2snnsO6+oz/JLo7D2nw6E9yxSJ8JBjM5j+FC4sYLuO2nYi/BzAGZL/wsKrajg2hjA3f8r1cgst8HdzAJjMUG90pb3UG2K2KVRScbvF8pvRrzLCvJ/gqAGDXX/M00jr407vU8V4O2A9YdSavaC02iRFTNail65cbOW96p3ptjeejofj8l5PO5eBYWERla8NrlD9EcW93+aSmswn4w9iSSq+j38GMyhYulLcOlhKTeWumc5goDjcHyri48Ki70ddGzrxFxggaC/FqlCG85A6/43fVaWH/Wi2uPDPzaRGNQzXRy4LCuE/dvUzp8TlkpcT0QFy/Q4Ke0u1dAgMBAAE\u003d".decodeBase64()!!
@@ -66,6 +70,12 @@ class TestCertificateTestData @Inject constructor(
         )
     }
 
+    val personATest2CertScannedStoredData = GenericTestCertificateData(
+        identifier = "identifier2",
+        registeredAt = Instant.ofEpochMilli(12345),
+        testCertificateQrCode = personATest2CertQRCodeString
+    )
+
     val personATest2CertContainer = TestCertificateContainer(
         data = personATest2CertStoredData,
         qrCodeExtractor = qrCodeExtractor,
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/execution/TestCertificateProcessorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateProcessorTest.kt
similarity index 61%
rename from Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/execution/TestCertificateProcessorTest.kt
rename to Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateProcessorTest.kt
index 83d374bb7d6b89d32d0fe3e7b5770e2ee41bb735..dc8e11f65a00b4d4c2a3135a2ddd25937d293dc6 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/execution/TestCertificateProcessorTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateProcessorTest.kt
@@ -1,18 +1,21 @@
-package de.rki.coronawarnapp.covidcertificate.test.execution
+package de.rki.coronawarnapp.covidcertificate.test.core
 
 import de.rki.coronawarnapp.appconfig.AppConfigProvider
 import de.rki.coronawarnapp.appconfig.ConfigData
 import de.rki.coronawarnapp.appconfig.CovidCertificateConfig
 import de.rki.coronawarnapp.covidcertificate.common.certificate.DccQrCodeExtractor
+import de.rki.coronawarnapp.covidcertificate.common.exception.TestCertificateServerException
 import de.rki.coronawarnapp.covidcertificate.test.core.qrcode.TestCertificateQRCode
 import de.rki.coronawarnapp.covidcertificate.test.core.server.TestCertificateComponents
 import de.rki.coronawarnapp.covidcertificate.test.core.server.TestCertificateServer
-import de.rki.coronawarnapp.covidcertificate.test.core.storage.PCRCertificateData
-import de.rki.coronawarnapp.covidcertificate.test.core.storage.StoredTestCertificateData
-import de.rki.coronawarnapp.covidcertificate.test.core.storage.TestCertificateProcessor
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.types.PCRCertificateData
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.types.RACertificateData
 import de.rki.coronawarnapp.util.TimeStamper
 import de.rki.coronawarnapp.util.encryption.rsa.RSACryptography
 import de.rki.coronawarnapp.util.encryption.rsa.RSAKeyPairGenerator
+import io.kotest.assertions.throwables.shouldThrow
+import io.kotest.matchers.shouldBe
+import io.mockk.Called
 import io.mockk.MockKAnnotations
 import io.mockk.Runs
 import io.mockk.coEvery
@@ -40,13 +43,27 @@ class TestCertificateProcessorTest : BaseTest() {
     @MockK lateinit var appConfigData: ConfigData
     @MockK lateinit var covidTestCertificateConfig: CovidCertificateConfig.TestCertificate
 
-    private val testCertificateNew = PCRCertificateData(
+    private val pcrCertificateData = PCRCertificateData(
         identifier = "identifier1",
         registrationToken = "regtoken1",
         registeredAt = Instant.EPOCH,
+        labId = "labId"
     )
 
-    private val testCertificateWithPubKey = testCertificateNew.copy(
+    private val pcrCertificateDataWithPubKey = pcrCertificateData.copy(
+        publicKeyRegisteredAt = Instant.EPOCH,
+        rsaPublicKey = mockk(),
+        rsaPrivateKey = mockk(),
+    )
+
+    private val raCertificateData = RACertificateData(
+        identifier = "identifier2",
+        registrationToken = "regtoken2",
+        registeredAt = Instant.EPOCH,
+        labId = null
+    )
+
+    private val raCertificateDataWithPubKey = raCertificateData.copy(
         publicKeyRegisteredAt = Instant.EPOCH,
         rsaPublicKey = mockk(),
         rsaPrivateKey = mockk(),
@@ -57,8 +74,6 @@ class TestCertificateProcessorTest : BaseTest() {
         every { encryptedCoseTestCertificateBase64 } returns ""
     }
 
-    private var storageSet = mutableSetOf<StoredTestCertificateData>()
-
     @BeforeEach
     fun setup() {
         MockKAnnotations.init(this)
@@ -105,21 +120,54 @@ class TestCertificateProcessorTest : BaseTest() {
     @Test
     fun `public key registration`() = runBlockingTest2(ignoreActive = true) {
         val instance = createInstance()
-        instance.registerPublicKey(testCertificateNew)
+        instance.registerPublicKey(pcrCertificateData)
 
         coVerify {
-            certificateServer.registerPublicKeyForTest(testCertificateNew.registrationToken, any())
+            certificateServer.registerPublicKeyForTest(pcrCertificateData.registrationToken, any())
+        }
+    }
+
+    @Test
+    fun `public key registration - requires valid labId only if PCR`() = runBlockingTest2(ignoreActive = true) {
+        val instance = createInstance()
+        shouldThrow<TestCertificateServerException> {
+            instance.registerPublicKey(pcrCertificateData.copy(labId = null))
+        }.errorCode shouldBe TestCertificateServerException.ErrorCode.DCC_NOT_SUPPORTED_BY_LAB
+
+        coVerify { certificateServer wasNot Called }
+
+        instance.registerPublicKey(raCertificateData)
+
+        coVerify(exactly = 1) {
+            certificateServer.registerPublicKeyForTest(any(), any())
         }
     }
 
     @Test
     fun `obtain certificate components`() = runBlockingTest2(ignoreActive = true) {
         val instance = createInstance()
-        instance.obtainCertificate(testCertificateWithPubKey)
+        instance.obtainCertificate(pcrCertificateDataWithPubKey)
 
         coVerify {
             covidTestCertificateConfig.waitAfterPublicKeyRegistration
-            certificateServer.requestCertificateForTest(testCertificateNew.registrationToken)
+            certificateServer.requestCertificateForTest(pcrCertificateData.registrationToken)
+        }
+    }
+
+    @Test
+    fun `obtain certificate components - requires valid labId only if PCR`() = runBlockingTest2(ignoreActive = true) {
+        val instance = createInstance()
+
+        shouldThrow<TestCertificateServerException> {
+            instance.obtainCertificate(pcrCertificateDataWithPubKey.copy(labId = null))
+        }.errorCode shouldBe TestCertificateServerException.ErrorCode.DCC_NOT_SUPPORTED_BY_LAB
+
+        coVerify { certificateServer wasNot Called }
+
+        instance.obtainCertificate(raCertificateDataWithPubKey)
+
+        coVerify(exactly = 1) {
+            certificateServer.requestCertificateForTest(any())
         }
     }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateRepositoryTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateRepositoryTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..e353f62e5b08e48ce0f7ac0aa6ceb19818466573
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/core/TestCertificateRepositoryTest.kt
@@ -0,0 +1,165 @@
+package de.rki.coronawarnapp.covidcertificate.test.core
+
+import de.rki.coronawarnapp.appconfig.CovidCertificateConfig
+import de.rki.coronawarnapp.coronatest.DaggerCoronaTestTestComponent
+import de.rki.coronawarnapp.coronatest.type.CoronaTest
+import de.rki.coronawarnapp.covidcertificate.common.certificate.DccQrCodeExtractor
+import de.rki.coronawarnapp.covidcertificate.common.exception.InvalidHealthCertificateException.ErrorCode
+import de.rki.coronawarnapp.covidcertificate.common.exception.InvalidTestCertificateException
+import de.rki.coronawarnapp.covidcertificate.test.TestCertificateTestData
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.TestCertificateStorage
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.types.BaseTestCertificateData
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.types.GenericTestCertificateData
+import de.rki.coronawarnapp.covidcertificate.test.core.storage.types.PCRCertificateData
+import de.rki.coronawarnapp.covidcertificate.valueset.ValueSetsRepository
+import de.rki.coronawarnapp.util.TimeStamper
+import io.kotest.assertions.throwables.shouldThrow
+import io.kotest.matchers.shouldBe
+import io.mockk.MockKAnnotations
+import io.mockk.coEvery
+import io.mockk.every
+import io.mockk.impl.annotations.MockK
+import io.mockk.mockk
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.emptyFlow
+import org.joda.time.Duration
+import org.joda.time.Instant
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import testhelpers.BaseTest
+import testhelpers.TestDispatcherProvider
+import testhelpers.coroutines.runBlockingTest2
+import javax.inject.Inject
+
+class TestCertificateRepositoryTest : BaseTest() {
+
+    @MockK lateinit var storage: TestCertificateStorage
+    @MockK lateinit var qrCodeExtractor: DccQrCodeExtractor
+    @MockK lateinit var covidTestCertificateConfig: CovidCertificateConfig.TestCertificate
+    @MockK lateinit var valueSetsRepository: ValueSetsRepository
+    @MockK lateinit var testCertificateProcessor: TestCertificateProcessor
+    @MockK lateinit var timeStamper: TimeStamper
+
+    @Inject lateinit var testData: TestCertificateTestData
+
+    private val testCertificateNew = PCRCertificateData(
+        identifier = "identifier1",
+        registrationToken = "regtoken1",
+        registeredAt = Instant.EPOCH,
+    )
+
+    private val testCertificateWithPubKey = testCertificateNew.copy(
+        publicKeyRegisteredAt = Instant.EPOCH,
+        rsaPublicKey = mockk(),
+        rsaPrivateKey = mockk(),
+    )
+
+    private var storageSet = mutableSetOf<BaseTestCertificateData>()
+
+    @BeforeEach
+    fun setup() {
+        MockKAnnotations.init(this)
+
+        DaggerCoronaTestTestComponent.factory().create().inject(this)
+
+        covidTestCertificateConfig.apply {
+            every { waitForRetry } returns Duration.standardSeconds(10)
+            every { waitAfterPublicKeyRegistration } returns Duration.standardSeconds(10)
+        }
+
+        storage.apply {
+            every { storage.testCertificates = any() } answers {
+                storageSet.clear()
+                storageSet.addAll(arg(0))
+            }
+            every { storage.testCertificates } answers { storageSet }
+        }
+
+        qrCodeExtractor.apply {
+            coEvery { extract(any(), any()) } returns testData.personATest1CertQRCode
+            coEvery { extract(testData.personATest1CertQRCodeString) } returns testData.personATest1CertQRCode
+        }
+
+        every { valueSetsRepository.latestTestCertificateValueSets } returns emptyFlow()
+
+        every { timeStamper.nowUTC } returns Instant.ofEpochSecond(12345678)
+    }
+
+    private fun createInstance(scope: CoroutineScope) = TestCertificateRepository(
+        appScope = scope,
+        dispatcherProvider = TestDispatcherProvider(),
+        storage = storage,
+        qrCodeExtractor = qrCodeExtractor,
+        valueSetsRepository = valueSetsRepository,
+        timeStamper = timeStamper,
+        processor = testCertificateProcessor,
+    )
+
+    @Test
+    fun `register via corona test`() = runBlockingTest2(ignoreActive = true) {
+        val instance = createInstance(scope = this)
+
+        instance.requestCertificate(
+            test = mockk<CoronaTest>().apply {
+                every { identifier } returns "test-identifier"
+                every { isDccSupportedByPoc } returns true
+                every { isDccConsentGiven } returns true
+                every { type } returns CoronaTest.Type.PCR
+                every { registeredAt } returns Instant.ofEpochSecond(4555)
+                every { registrationToken } returns "token"
+                every { labId } returns "best-lab"
+            }
+        ).apply {
+            this.qrCodeExtractor shouldBe qrCodeExtractor
+
+            certificateId shouldBe null
+            data.testCertificateQrCode shouldBe null
+
+            isCertificateRetrievalPending shouldBe true
+            isUpdatingData shouldBe false
+        }
+
+        storageSet.single().apply {
+            this as PCRCertificateData
+
+            testCertificateQrCode shouldBe null
+
+            identifier.isNotEmpty() shouldBe true
+
+            registeredAt shouldBe Instant.ofEpochSecond(4555)
+            certificateReceivedAt shouldBe null
+            registrationToken shouldBe "token"
+        }
+    }
+
+    @Test
+    fun `register via qrcode`() = runBlockingTest2(ignoreActive = true) {
+        val instance = createInstance(scope = this)
+
+        instance.registerTestCertificate(
+            qrCode = testData.personATest1CertQRCode
+        ).apply {
+            this.qrCodeExtractor shouldBe qrCodeExtractor
+
+            data.testCertificateQrCode shouldBe testData.personATest1CertQRCodeString
+            certificateId shouldBe testData.personATest1CertQRCode.uniqueCertificateIdentifier
+
+            isCertificateRetrievalPending shouldBe false
+            isUpdatingData shouldBe false
+        }
+
+        storageSet.single().apply {
+            this as GenericTestCertificateData
+            testCertificateQrCode shouldBe testData.personATest1CertQRCodeString
+            identifier.isNotEmpty() shouldBe true
+            registeredAt shouldBe timeStamper.nowUTC
+            certificateReceivedAt shouldBe timeStamper.nowUTC
+        }
+
+        shouldThrow<InvalidTestCertificateException> {
+            instance.registerTestCertificate(
+                qrCode = testData.personATest1CertQRCode
+            )
+        }.errorCode shouldBe ErrorCode.ALREADY_REGISTERED
+    }
+}
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/execution/TestCertificateRetrievalSchedulerTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/core/execution/TestCertificateRetrievalSchedulerTest.kt
similarity index 97%
rename from Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/execution/TestCertificateRetrievalSchedulerTest.kt
rename to Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/core/execution/TestCertificateRetrievalSchedulerTest.kt
index 68a4a2c129670109c315f44f7b05f3cb00608fc9..1f64039d68f6aa23f7c670347ad139da173350e0 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/execution/TestCertificateRetrievalSchedulerTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/core/execution/TestCertificateRetrievalSchedulerTest.kt
@@ -1,4 +1,4 @@
-package de.rki.coronawarnapp.covidcertificate.test.execution
+package de.rki.coronawarnapp.covidcertificate.test.core.execution
 
 import androidx.work.OneTimeWorkRequest
 import androidx.work.WorkInfo
@@ -7,7 +7,6 @@ import de.rki.coronawarnapp.coronatest.CoronaTestRepository
 import de.rki.coronawarnapp.coronatest.type.CoronaTest
 import de.rki.coronawarnapp.covidcertificate.test.core.TestCertificateRepository
 import de.rki.coronawarnapp.covidcertificate.test.core.TestCertificateWrapper
-import de.rki.coronawarnapp.covidcertificate.test.core.execution.TestCertificateRetrievalScheduler
 import de.rki.coronawarnapp.util.device.ForegroundState
 import io.mockk.MockKAnnotations
 import io.mockk.Runs
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/execution/TestCertificateRetrievalWorkerTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/core/execution/TestCertificateRetrievalWorkerTest.kt
similarity index 93%
rename from Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/execution/TestCertificateRetrievalWorkerTest.kt
rename to Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/core/execution/TestCertificateRetrievalWorkerTest.kt
index 951f57f800909902c26c814688f6068773ebb106..90ca54289489ae2144489478083c772435e67a2a 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/execution/TestCertificateRetrievalWorkerTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/core/execution/TestCertificateRetrievalWorkerTest.kt
@@ -1,11 +1,10 @@
-package de.rki.coronawarnapp.covidcertificate.test.execution
+package de.rki.coronawarnapp.covidcertificate.test.core.execution
 
 import android.content.Context
 import androidx.work.ListenableWorker
 import androidx.work.WorkRequest
 import androidx.work.WorkerParameters
 import de.rki.coronawarnapp.covidcertificate.test.core.TestCertificateRepository
-import de.rki.coronawarnapp.covidcertificate.test.core.execution.TestCertificateRetrievalWorker
 import io.kotest.matchers.shouldBe
 import io.mockk.MockKAnnotations
 import io.mockk.coEvery
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/storage/PCRTestCertificateTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/PCRTestCertificateTest.kt
similarity index 52%
rename from Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/storage/PCRTestCertificateTest.kt
rename to Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/PCRTestCertificateTest.kt
index 317137016813ca25fd6d83b32efd42f416b53c29..37ce8f4016a605f31a982782f8731252aacfd0d4 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/storage/PCRTestCertificateTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/PCRTestCertificateTest.kt
@@ -1,4 +1,4 @@
-package de.rki.coronawarnapp.covidcertificate.test.storage
+package de.rki.coronawarnapp.covidcertificate.test.core.storage
 
 import testhelpers.BaseTest
 
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/storage/RATestCertificateTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/RATestCertificateTest.kt
similarity index 52%
rename from Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/storage/RATestCertificateTest.kt
rename to Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/RATestCertificateTest.kt
index 31fa7193a03a8ff9acb0772fd9c3862220491d1e..75ab9381609c6a7866398e51e4034beb3723dd36 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/storage/RATestCertificateTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/RATestCertificateTest.kt
@@ -1,4 +1,4 @@
-package de.rki.coronawarnapp.covidcertificate.test.storage
+package de.rki.coronawarnapp.covidcertificate.test.core.storage
 
 import testhelpers.BaseTest
 
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/storage/TestCertificateStorageTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/TestCertificateStorageTest.kt
similarity index 92%
rename from Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/storage/TestCertificateStorageTest.kt
rename to Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/TestCertificateStorageTest.kt
index 983f9549a849c04cde7d0ee2b517b9557f1a0070..93c4dbc01f5c89743ec0ac528e387fda0f0d4d5a 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/storage/TestCertificateStorageTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/covidcertificate/test/core/storage/TestCertificateStorageTest.kt
@@ -1,10 +1,9 @@
-package de.rki.coronawarnapp.covidcertificate.test.storage
+package de.rki.coronawarnapp.covidcertificate.test.core.storage
 
 import android.content.Context
 import androidx.core.content.edit
 import de.rki.coronawarnapp.coronatest.DaggerCoronaTestTestComponent
 import de.rki.coronawarnapp.covidcertificate.test.TestCertificateTestData
-import de.rki.coronawarnapp.covidcertificate.test.core.storage.TestCertificateStorage
 import de.rki.coronawarnapp.covidcertificate.vaccination.core.repository.storage.ContainerPostProcessor
 import de.rki.coronawarnapp.util.serialization.SerializationModule
 import io.kotest.matchers.shouldBe
@@ -40,8 +39,7 @@ class TestCertificateStorageTest : BaseTest() {
 
     private fun createInstance() = TestCertificateStorage(
         context = context,
-        baseGson = SerializationModule().baseGson(),
-        containerPostProcessor = postProcessor,
+        baseGson = SerializationModule().baseGson()
     )
 
     @Test
@@ -55,6 +53,7 @@ class TestCertificateStorageTest : BaseTest() {
             putString("dontdeleteme", "test")
             putString("testcertificate.data.ra", "test")
             putString("testcertificate.data.pcr", "test")
+            putString("testcertificate.data.scanned", "test")
         }
         createInstance().testCertificates = emptySet()
 
@@ -65,7 +64,8 @@ class TestCertificateStorageTest : BaseTest() {
     fun `store two containers, one for each type`() {
         createInstance().testCertificates = setOf(
             certificateTestData.personATest1StoredData,
-            certificateTestData.personATest2CertStoredData
+            certificateTestData.personATest2CertStoredData,
+            certificateTestData.personATest2CertScannedStoredData,
         )
 
         (mockPreferences.dataMapPeek["testcertificate.data.pcr"] as String).toComparableJsonPretty() shouldBe """
@@ -102,9 +102,20 @@ class TestCertificateStorageTest : BaseTest() {
             ]
         """.toComparableJsonPretty()
 
+        (mockPreferences.dataMapPeek["testcertificate.data.scanned"] as String).toComparableJsonPretty() shouldBe """
+            [
+              {
+                "identifier": "identifier2",
+                "registeredAt": 12345,
+                "testCertificateQrCode": "${certificateTestData.personATest2CertQRCodeString}"
+              }
+            ]
+        """.toComparableJsonPretty()
+
         createInstance().testCertificates shouldBe setOf(
             certificateTestData.personATest1StoredData,
-            certificateTestData.personATest2CertStoredData
+            certificateTestData.personATest2CertStoredData,
+            certificateTestData.personATest2CertScannedStoredData,
         )
     }
 }