From 6337ca600818f6da756f08afff8a73bfd2e0a6f6 Mon Sep 17 00:00:00 2001
From: Lukas Lechner <lukas.lechner@sap.com>
Date: Mon, 26 Apr 2021 09:31:17 +0200
Subject: [PATCH] PPA should only collect data for PCA tests (EXPOSUREAPP-6598)
 (#2935)

* Not collect PPA submission data for RAT tests

* Improve LogMessage in SubmissionTask.kt

* Align SubmissionTestResultConsentGivenViewModel.kt regarding PPA

* Align SubmissionTestResultNoConsentViewModel.kt regarding PPA

* Align SubmissionResultPositiveOtherWarningNoConsentViewModel.kt regarding PPA

* Fix some test function names

* Align PPA for SubmissionTestResultAvailableViewModel.kt

* Add testType Navigation Argument to SubmissionResultReadyFragment.kt, SubmissionSymptomCalendarFragment.kt and SubmissionSymptomIntroductionFragment.kt

* Align PPA for SubmissionSymptomIntroductionViewModel.kt

* Align PPA for SubmissionSymptomCalendarViewModel.kt

* Fix SubmissionTaskTest.kt

* Fix InstrumentationTests

* Add call to reportAdvancedConsentGiven
---
 .../SubmissionSymptomCalendarFragmentTest.kt  | 10 ++-
 .../SubmissionSymptomIntroFragmentTest.kt     | 25 +++++--
 .../submission/task/SubmissionTask.kt         | 12 ++--
 .../consent/CheckInsConsentFragment.kt        |  4 +-
 .../scan/SubmissionQRCodeScanViewModel.kt     |  8 ++-
 .../SubmissionTestResultAvailableViewModel.kt |  7 +-
 .../SubmissionResultReadyFragment.kt          |  6 +-
 .../SubmissionSymptomCalendarFragment.kt      |  2 +-
 .../SubmissionSymptomCalendarViewModel.kt     | 21 ++++--
 .../SubmissionSymptomIntroductionFragment.kt  | 16 ++++-
 .../SubmissionSymptomIntroductionViewModel.kt | 19 +++--
 ...ubmissionTestResultConsentGivenFragment.kt |  4 +-
 ...bmissionTestResultConsentGivenViewModel.kt | 10 +--
 .../SubmissionTestResultNoConsentViewModel.kt |  5 +-
 ...tPositiveOtherWarningNoConsentViewModel.kt |  9 ++-
 .../src/main/res/navigation/nav_graph.xml     |  9 +++
 .../submission/task/SubmissionTaskTest.kt     | 43 +++++++++++-
 .../scan/SubmissionQRCodeScanViewModelTest.kt | 34 ++++++++-
 .../SubmissionSymptomCalendarViewModelTest.kt | 69 ++++++++++++++++++-
 ...missionSymptomIntroductionViewModelTest.kt | 29 +++++++-
 ...missionTestResultAvailableViewModelTest.kt | 26 +++++++
 ...sionTestResultConsentGivenViewModelTest.kt | 16 +++++
 ...missionTestResultNoConsentViewModelTest.kt | 46 +++++++++++++
 ...itiveOtherWarningNoConsentViewModelTest.kt | 18 +++++
 24 files changed, 404 insertions(+), 44 deletions(-)
 create mode 100644 Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultNoConsentViewModelTest.kt

diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionSymptomCalendarFragmentTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionSymptomCalendarFragmentTest.kt
index aa15d484e..f80a5891d 100644
--- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionSymptomCalendarFragmentTest.kt
+++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionSymptomCalendarFragmentTest.kt
@@ -8,6 +8,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
 import dagger.Module
 import dagger.android.ContributesAndroidInjector
 import de.rki.coronawarnapp.R
+import de.rki.coronawarnapp.coronatest.type.CoronaTest
 import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector
 import de.rki.coronawarnapp.submission.SubmissionRepository
 import de.rki.coronawarnapp.submission.Symptoms
@@ -54,6 +55,7 @@ class SubmissionSymptomCalendarFragmentTest : BaseUITest() {
         viewModel = spyk(
             SubmissionSymptomCalendarViewModel(
                 Symptoms.Indication.POSITIVE,
+                CoronaTest.Type.PCR,
                 TestDispatcherProvider(),
                 submissionRepository,
                 autoSubmission,
@@ -65,7 +67,10 @@ class SubmissionSymptomCalendarFragmentTest : BaseUITest() {
         }
         setupMockViewModel(
             object : SubmissionSymptomCalendarViewModel.Factory {
-                override fun create(symptomIndication: Symptoms.Indication): SubmissionSymptomCalendarViewModel = viewModel
+                override fun create(
+                    symptomIndication: Symptoms.Indication,
+                    testType: CoronaTest.Type
+                ): SubmissionSymptomCalendarViewModel = viewModel
             }
         )
     }
@@ -80,7 +85,8 @@ class SubmissionSymptomCalendarFragmentTest : BaseUITest() {
     fun capture_fragment() {
         captureScreenshot<SubmissionSymptomCalendarFragment>(
             fragmentArgs = SubmissionSymptomCalendarFragmentArgs(
-                Symptoms.Indication.POSITIVE
+                Symptoms.Indication.POSITIVE,
+                CoronaTest.Type.PCR
             ).toBundle()
         )
 
diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionSymptomIntroFragmentTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionSymptomIntroFragmentTest.kt
index b1bf713e0..eea3e2c46 100644
--- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionSymptomIntroFragmentTest.kt
+++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionSymptomIntroFragmentTest.kt
@@ -9,11 +9,13 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
 import dagger.Module
 import dagger.android.ContributesAndroidInjector
 import de.rki.coronawarnapp.R
+import de.rki.coronawarnapp.coronatest.type.CoronaTest
 import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector
 import de.rki.coronawarnapp.submission.SubmissionRepository
 import de.rki.coronawarnapp.submission.Symptoms
 import de.rki.coronawarnapp.submission.auto.AutoSubmission
 import de.rki.coronawarnapp.ui.submission.symptoms.introduction.SubmissionSymptomIntroductionFragment
+import de.rki.coronawarnapp.ui.submission.symptoms.introduction.SubmissionSymptomIntroductionFragmentArgs
 import de.rki.coronawarnapp.ui.submission.symptoms.introduction.SubmissionSymptomIntroductionViewModel
 import io.mockk.MockKAnnotations
 import io.mockk.every
@@ -58,7 +60,8 @@ class SubmissionSymptomIntroFragmentTest : BaseUITest() {
                 TestDispatcherProvider(),
                 submissionRepository,
                 autoSubmission,
-                analyticsKeySubmissionCollector
+                analyticsKeySubmissionCollector,
+                CoronaTest.Type.PCR
             )
         )
         with(viewModel) {
@@ -66,7 +69,7 @@ class SubmissionSymptomIntroFragmentTest : BaseUITest() {
         }
         setupMockViewModel(
             object : SubmissionSymptomIntroductionViewModel.Factory {
-                override fun create(): SubmissionSymptomIntroductionViewModel = viewModel
+                override fun create(testType: CoronaTest.Type): SubmissionSymptomIntroductionViewModel = viewModel
             }
         )
     }
@@ -78,12 +81,20 @@ class SubmissionSymptomIntroFragmentTest : BaseUITest() {
 
     @Test
     fun launch_fragment() {
-        launchFragment2<SubmissionSymptomIntroductionFragment>()
+        launchFragment2<SubmissionSymptomIntroductionFragment>(
+            fragmentArgs = SubmissionSymptomIntroductionFragmentArgs(
+                CoronaTest.Type.PCR
+            ).toBundle()
+        )
     }
 
     @Test
     fun testSymptomNextClicked() {
-        launchFragmentInContainer2<SubmissionSymptomIntroductionFragment>()
+        launchFragmentInContainer2<SubmissionSymptomIntroductionFragment>(
+            fragmentArgs = SubmissionSymptomIntroductionFragmentArgs(
+                CoronaTest.Type.PCR
+            ).toBundle()
+        )
         onView(withId(R.id.symptom_button_next))
             .perform(click())
     }
@@ -91,7 +102,11 @@ class SubmissionSymptomIntroFragmentTest : BaseUITest() {
     @Test
     @Screenshot
     fun capture_fragment() {
-        captureScreenshot<SubmissionSymptomIntroductionFragment>()
+        captureScreenshot<SubmissionSymptomIntroductionFragment>(
+            fragmentArgs = SubmissionSymptomIntroductionFragmentArgs(
+                CoronaTest.Type.PCR
+            ).toBundle()
+        )
         onView(withId(R.id.target_button_verify))
             .perform(scrollTo())
         takeScreenshot<SubmissionSymptomIntroductionFragment>("2")
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/task/SubmissionTask.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/task/SubmissionTask.kt
index d95c9e4ad..aacefbebc 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/task/SubmissionTask.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/task/SubmissionTask.kt
@@ -6,6 +6,7 @@ import de.rki.coronawarnapp.bugreporting.reportProblem
 import de.rki.coronawarnapp.coronatest.CoronaTestRepository
 import de.rki.coronawarnapp.coronatest.notification.ShareTestResultNotificationService
 import de.rki.coronawarnapp.coronatest.type.CoronaTest
+import de.rki.coronawarnapp.coronatest.type.CoronaTest.Type.PCR
 import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector
 import de.rki.coronawarnapp.notification.PCRTestResultAvailableNotificationService
 import de.rki.coronawarnapp.playbook.Playbook
@@ -138,7 +139,7 @@ class SubmissionTask @Inject constructor(
         val keys: List<TemporaryExposureKey> = try {
             tekHistoryStorage.tekData.first().flatMap { it.keys }
         } catch (e: NoSuchElementException) {
-            Timber.tag(TAG).e(e, "No TEKs available, aborting.")
+            Timber.tag(TAG).e(e, "tekHistoryStorage access failed, aborting.")
             autoSubmission.updateMode(AutoSubmission.Mode.DISABLED)
             throw e
         }
@@ -172,8 +173,11 @@ class SubmissionTask @Inject constructor(
         Timber.tag(TAG).d("Submitting %s", submissionData)
         playbook.submit(submissionData)
 
-        analyticsKeySubmissionCollector.reportSubmitted()
-        if (inBackground) analyticsKeySubmissionCollector.reportSubmittedInBackground()
+        // PPA will only be used for PCR tests for now
+        if (coronaTest.type == PCR) {
+            analyticsKeySubmissionCollector.reportSubmitted()
+            if (inBackground) analyticsKeySubmissionCollector.reportSubmittedInBackground()
+        }
 
         Timber.tag(TAG).d("Submission successful, deleting submission data.")
         tekHistoryStorage.clear()
@@ -264,6 +268,6 @@ class SubmissionTask @Inject constructor(
 }
 
 private fun CoronaTest.Type.toSubmissionType() = when (this) {
-    CoronaTest.Type.PCR -> SubmissionType.SUBMISSION_TYPE_PCR_TEST
+    PCR -> SubmissionType.SUBMISSION_TYPE_PCR_TEST
     CoronaTest.Type.RAPID_ANTIGEN -> SubmissionType.SUBMISSION_TYPE_RAPID_TEST
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/attendee/checkins/consent/CheckInsConsentFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/attendee/checkins/consent/CheckInsConsentFragment.kt
index c11dbe490..8b014f565 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/attendee/checkins/consent/CheckInsConsentFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/attendee/checkins/consent/CheckInsConsentFragment.kt
@@ -69,7 +69,9 @@ class CheckInsConsentFragment : Fragment(R.layout.check_ins_consent_fragment), A
                     CheckInsConsentFragmentDirections.actionCheckInsConsentFragmentToMainFragment()
                 )
                 CheckInsConsentNavigation.ToSubmissionResultReadyFragment -> doNavigate(
-                    CheckInsConsentFragmentDirections.actionCheckInsConsentFragmentToSubmissionResultReadyFragment()
+                    CheckInsConsentFragmentDirections.actionCheckInsConsentFragmentToSubmissionResultReadyFragment(
+                        navArgs.testType
+                    )
                 )
                 CheckInsConsentNavigation.ToSubmissionTestResultConsentGivenFragment -> doNavigate(
                     CheckInsConsentFragmentDirections
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 d07af3d2d..b49dad702 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
@@ -6,6 +6,8 @@ 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
+import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector
 import de.rki.coronawarnapp.submission.SubmissionRepository
 import de.rki.coronawarnapp.ui.submission.qrcode.QrCodeRegistrationStateProcessor
 import de.rki.coronawarnapp.ui.submission.viewmodel.SubmissionNavigationEvents
@@ -23,7 +25,8 @@ class SubmissionQRCodeScanViewModel @AssistedInject constructor(
     private val qrCodeRegistrationStateProcessor: QrCodeRegistrationStateProcessor,
     @Assisted private val isConsentGiven: Boolean,
     private val submissionRepository: SubmissionRepository,
-    private val qrCodeValidator: CoronaTestQrCodeValidator
+    private val qrCodeValidator: CoronaTestQrCodeValidator,
+    private val analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector
 ) : CWAViewModel(dispatcherProvider = dispatcherProvider) {
     val routeToScreen = SingleLiveEvent<SubmissionNavigationEvents>()
     val showRedeemedTokenWarning = qrCodeRegistrationStateProcessor.showRedeemedTokenWarning
@@ -53,6 +56,9 @@ class SubmissionQRCodeScanViewModel @AssistedInject constructor(
                     )
                 )
             } else {
+                if (isConsentGiven && coronaTestQRCode.type == CoronaTest.Type.PCR) {
+                    analyticsKeySubmissionCollector.reportAdvancedConsentGiven()
+                }
                 qrCodeRegistrationStateProcessor.startQrCodeRegistration(coronaTestQRCode, isConsentGiven)
             }
         } catch (err: InvalidQRCodeException) {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/resultavailable/SubmissionTestResultAvailableViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/resultavailable/SubmissionTestResultAvailableViewModel.kt
index e5bc9c334..ea82510a5 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/resultavailable/SubmissionTestResultAvailableViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/resultavailable/SubmissionTestResultAvailableViewModel.kt
@@ -9,6 +9,7 @@ import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import de.rki.coronawarnapp.coronatest.type.CoronaTest
+import de.rki.coronawarnapp.coronatest.type.CoronaTest.Type.PCR
 import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector
 import de.rki.coronawarnapp.exception.ExceptionCategory
 import de.rki.coronawarnapp.exception.reporting.report
@@ -98,7 +99,7 @@ class SubmissionTestResultAvailableViewModel @AssistedInject constructor(
     )
 
     init {
-        submissionRepository.refreshTest(type = CoronaTest.Type.PCR)
+        submissionRepository.refreshTest(type = PCR)
     }
 
     fun goBack() {
@@ -130,7 +131,9 @@ class SubmissionTestResultAvailableViewModel @AssistedInject constructor(
                 tekHistoryUpdater.updateTEKHistoryOrRequestPermission()
             } else {
                 Timber.tag(TAG).d("routeToScreen:SubmissionTestResultNoConsentFragment")
-                analyticsKeySubmissionCollector.reportConsentWithdrawn()
+                if (testType == PCR) {
+                    analyticsKeySubmissionCollector.reportConsentWithdrawn()
+                }
                 showKeysRetrievalProgress.postValue(false)
                 routeToScreen.postValue(
                     SubmissionTestResultAvailableFragmentDirections
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/resultready/SubmissionResultReadyFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/resultready/SubmissionResultReadyFragment.kt
index 92f10cc9a..a97360430 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/resultready/SubmissionResultReadyFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/resultready/SubmissionResultReadyFragment.kt
@@ -5,8 +5,10 @@ import android.view.View
 import android.view.accessibility.AccessibilityEvent
 import androidx.activity.OnBackPressedCallback
 import androidx.fragment.app.Fragment
+import androidx.navigation.fragment.navArgs
 import de.rki.coronawarnapp.R
 import de.rki.coronawarnapp.databinding.FragmentSubmissionResultReadyBinding
+import de.rki.coronawarnapp.ui.presencetracing.attendee.checkins.consent.CheckInsConsentFragmentArgs
 import de.rki.coronawarnapp.ui.submission.SubmissionBlockingDialog
 import de.rki.coronawarnapp.ui.submission.SubmissionCancelDialog
 import de.rki.coronawarnapp.ui.submission.viewmodel.SubmissionNavigationEvents
@@ -27,6 +29,8 @@ class SubmissionResultReadyFragment : Fragment(R.layout.fragment_submission_resu
     private val viewModel: SubmissionResultReadyViewModel by cwaViewModels { viewModelFactory }
     private val binding: FragmentSubmissionResultReadyBinding by viewBindingLazy()
 
+    private val navArgs by navArgs<CheckInsConsentFragmentArgs>()
+
     private lateinit var uploadDialog: SubmissionBlockingDialog
 
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -50,7 +54,7 @@ class SubmissionResultReadyFragment : Fragment(R.layout.fragment_submission_resu
 
                 is SubmissionNavigationEvents.NavigateToSymptomIntroduction -> doNavigate(
                     SubmissionResultReadyFragmentDirections
-                        .actionSubmissionResultReadyFragmentToSubmissionSymptomIntroductionFragment()
+                        .actionSubmissionResultReadyFragmentToSubmissionSymptomIntroductionFragment(navArgs.testType)
                 )
             }
         }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/symptoms/calendar/SubmissionSymptomCalendarFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/symptoms/calendar/SubmissionSymptomCalendarFragment.kt
index 44e574a02..5c2bac135 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/symptoms/calendar/SubmissionSymptomCalendarFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/symptoms/calendar/SubmissionSymptomCalendarFragment.kt
@@ -32,7 +32,7 @@ class SubmissionSymptomCalendarFragment :
         factoryProducer = { viewModelFactory },
         constructorCall = { factory, _ ->
             factory as SubmissionSymptomCalendarViewModel.Factory
-            factory.create(navArgs.symptomIndication)
+            factory.create(navArgs.symptomIndication, navArgs.testType)
         }
     )
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/symptoms/calendar/SubmissionSymptomCalendarViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/symptoms/calendar/SubmissionSymptomCalendarViewModel.kt
index 249f7e24e..935aec884 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/symptoms/calendar/SubmissionSymptomCalendarViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/symptoms/calendar/SubmissionSymptomCalendarViewModel.kt
@@ -8,6 +8,8 @@ import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import de.rki.coronawarnapp.bugreporting.reportProblem
+import de.rki.coronawarnapp.coronatest.type.CoronaTest.Type
+import de.rki.coronawarnapp.coronatest.type.CoronaTest.Type.PCR
 import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector
 import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.Screen
 import de.rki.coronawarnapp.submission.SubmissionRepository
@@ -23,6 +25,7 @@ import timber.log.Timber
 
 class SubmissionSymptomCalendarViewModel @AssistedInject constructor(
     @Assisted val symptomIndication: Symptoms.Indication,
+    @Assisted val testType: Type,
     dispatcherProvider: DispatcherProvider,
     private val submissionRepository: SubmissionRepository,
     private val autoSubmission: AutoSubmission,
@@ -87,12 +90,20 @@ class SubmissionSymptomCalendarViewModel @AssistedInject constructor(
                 startOfSymptoms = symptomStartInternal.value
             ).also { Timber.tag(TAG).v("Symptoms updated to %s", it) }
         }
-        performSubmission { analyticsKeySubmissionCollector.reportSubmittedAfterSymptomFlow() }
+        performSubmission {
+            if (testType == PCR) {
+                analyticsKeySubmissionCollector.reportSubmittedAfterSymptomFlow()
+            }
+        }
     }
 
     fun onCancelConfirmed() {
         Timber.d("onCancelConfirmed() clicked on calendar screen.")
-        performSubmission { analyticsKeySubmissionCollector.reportSubmittedAfterCancel() }
+        performSubmission {
+            if (testType == PCR) {
+                analyticsKeySubmissionCollector.reportSubmittedAfterCancel()
+            }
+        }
     }
 
     private fun performSubmission(onSubmitted: () -> Unit) {
@@ -114,14 +125,16 @@ class SubmissionSymptomCalendarViewModel @AssistedInject constructor(
 
     fun onNewUserActivity() {
         Timber.d("onNewUserActivity()")
-        analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.SYMPTOM_ONSET)
+        if (testType == PCR) {
+            analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.SYMPTOM_ONSET)
+        }
         autoSubmission.updateLastSubmissionUserActivity()
     }
 
     @AssistedFactory
     interface Factory : CWAViewModelFactory<SubmissionSymptomCalendarViewModel> {
 
-        fun create(symptomIndication: Symptoms.Indication): SubmissionSymptomCalendarViewModel
+        fun create(symptomIndication: Symptoms.Indication, testType: Type): SubmissionSymptomCalendarViewModel
     }
 
     companion object {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/symptoms/introduction/SubmissionSymptomIntroductionFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/symptoms/introduction/SubmissionSymptomIntroductionFragment.kt
index 40d9e4eba..0a60e95c2 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/symptoms/introduction/SubmissionSymptomIntroductionFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/symptoms/introduction/SubmissionSymptomIntroductionFragment.kt
@@ -5,9 +5,11 @@ import android.os.Bundle
 import android.view.View
 import android.widget.Button
 import androidx.fragment.app.Fragment
+import androidx.navigation.fragment.navArgs
 import de.rki.coronawarnapp.R
 import de.rki.coronawarnapp.databinding.FragmentSubmissionSymptomIntroBinding
 import de.rki.coronawarnapp.submission.Symptoms
+import de.rki.coronawarnapp.ui.presencetracing.attendee.checkins.consent.CheckInsConsentFragmentArgs
 import de.rki.coronawarnapp.ui.submission.SubmissionBlockingDialog
 import de.rki.coronawarnapp.ui.submission.SubmissionCancelDialog
 import de.rki.coronawarnapp.util.di.AutoInject
@@ -17,7 +19,7 @@ import de.rki.coronawarnapp.util.ui.doNavigate
 import de.rki.coronawarnapp.util.ui.observe2
 import de.rki.coronawarnapp.util.ui.viewBindingLazy
 import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider
-import de.rki.coronawarnapp.util.viewmodel.cwaViewModels
+import de.rki.coronawarnapp.util.viewmodel.cwaViewModelsAssisted
 import javax.inject.Inject
 
 /**
@@ -28,10 +30,18 @@ class SubmissionSymptomIntroductionFragment :
     Fragment(R.layout.fragment_submission_symptom_intro),
     AutoInject {
 
-    @Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory
-    private val viewModel: SubmissionSymptomIntroductionViewModel by cwaViewModels { viewModelFactory }
+    private val navArgs by navArgs<CheckInsConsentFragmentArgs>()
 
+    @Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory
+    private val viewModel: SubmissionSymptomIntroductionViewModel by cwaViewModelsAssisted(
+        factoryProducer = { viewModelFactory },
+        constructorCall = { factory, _ ->
+            factory as SubmissionSymptomIntroductionViewModel.Factory
+            factory.create(navArgs.testType)
+        }
+    )
     private val binding: FragmentSubmissionSymptomIntroBinding by viewBindingLazy()
+
     private lateinit var uploadDialog: SubmissionBlockingDialog
 
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/symptoms/introduction/SubmissionSymptomIntroductionViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/symptoms/introduction/SubmissionSymptomIntroductionViewModel.kt
index 6628ddc87..307fc779e 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/symptoms/introduction/SubmissionSymptomIntroductionViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/symptoms/introduction/SubmissionSymptomIntroductionViewModel.kt
@@ -4,8 +4,11 @@ import androidx.lifecycle.LiveData
 import androidx.lifecycle.MediatorLiveData
 import androidx.lifecycle.asLiveData
 import androidx.navigation.NavDirections
+import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
+import de.rki.coronawarnapp.coronatest.type.CoronaTest.Type
+import de.rki.coronawarnapp.coronatest.type.CoronaTest.Type.PCR
 import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector
 import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.Screen
 import de.rki.coronawarnapp.submission.SubmissionRepository
@@ -14,7 +17,7 @@ import de.rki.coronawarnapp.submission.auto.AutoSubmission
 import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
 import de.rki.coronawarnapp.util.ui.SingleLiveEvent
 import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
-import de.rki.coronawarnapp.util.viewmodel.SimpleCWAViewModelFactory
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
 import kotlinx.coroutines.flow.MutableStateFlow
 import timber.log.Timber
 
@@ -22,7 +25,8 @@ class SubmissionSymptomIntroductionViewModel @AssistedInject constructor(
     dispatcherProvider: DispatcherProvider,
     private val submissionRepository: SubmissionRepository,
     private val autoSubmission: AutoSubmission,
-    private val analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector
+    private val analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector,
+    @Assisted private val testType: Type
 ) : CWAViewModel(dispatcherProvider = dispatcherProvider) {
 
     private val symptomIndicationInternal = MutableStateFlow<Symptoms.Indication?>(null)
@@ -50,7 +54,8 @@ class SubmissionSymptomIntroductionViewModel @AssistedInject constructor(
                     navigation.postValue(
                         SubmissionSymptomIntroductionFragmentDirections
                             .actionSubmissionSymptomIntroductionFragmentToSubmissionSymptomCalendarFragment(
-                                symptomIndication = Symptoms.Indication.POSITIVE
+                                symptomIndication = Symptoms.Indication.POSITIVE,
+                                testType = testType
                             )
                     )
                 }
@@ -121,10 +126,14 @@ class SubmissionSymptomIntroductionViewModel @AssistedInject constructor(
 
     fun onNewUserActivity() {
         Timber.d("onNewUserActivity()")
-        analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.SYMPTOMS)
+        if (testType == PCR) {
+            analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.SYMPTOMS)
+        }
         autoSubmission.updateLastSubmissionUserActivity()
     }
 
     @AssistedFactory
-    interface Factory : SimpleCWAViewModelFactory<SubmissionSymptomIntroductionViewModel>
+    interface Factory : CWAViewModelFactory<SubmissionSymptomIntroductionViewModel> {
+        fun create(testType: Type): SubmissionSymptomIntroductionViewModel
+    }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultConsentGivenFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultConsentGivenFragment.kt
index 07b6e9f66..30208766c 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultConsentGivenFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultConsentGivenFragment.kt
@@ -69,7 +69,9 @@ class SubmissionTestResultConsentGivenFragment :
                 is SubmissionNavigationEvents.NavigateToSymptomIntroduction ->
                     doNavigate(
                         SubmissionTestResultConsentGivenFragmentDirections
-                            .actionSubmissionTestResultConsentGivenFragmentToSubmissionSymptomIntroductionFragment()
+                            .actionSubmissionTestResultConsentGivenFragmentToSubmissionSymptomIntroductionFragment(
+                                navArgs.testType
+                            )
                     )
                 is SubmissionNavigationEvents.NavigateToMainActivity ->
                     doNavigate(
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultConsentGivenViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultConsentGivenViewModel.kt
index c2c4f6b45..5033e1905 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultConsentGivenViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultConsentGivenViewModel.kt
@@ -5,7 +5,7 @@ import androidx.lifecycle.asLiveData
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
-import de.rki.coronawarnapp.coronatest.type.CoronaTest
+import de.rki.coronawarnapp.coronatest.type.CoronaTest.Type
 import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector
 import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.Screen
 import de.rki.coronawarnapp.notification.PCRTestResultAvailableNotificationService
@@ -27,7 +27,7 @@ class SubmissionTestResultConsentGivenViewModel @AssistedInject constructor(
     private val autoSubmission: AutoSubmission,
     private val testResultAvailableNotificationService: PCRTestResultAvailableNotificationService,
     private val analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector,
-    @Assisted private val testType: CoronaTest.Type,
+    @Assisted private val testType: Type,
     dispatcherProvider: DispatcherProvider
 ) : CWAViewModel(dispatcherProvider = dispatcherProvider) {
 
@@ -77,12 +77,14 @@ class SubmissionTestResultConsentGivenViewModel @AssistedInject constructor(
 
     fun onNewUserActivity() {
         Timber.d("onNewUserActivity()")
-        analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.TEST_RESULT)
+        if (testType == Type.PCR) {
+            analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.TEST_RESULT)
+        }
         autoSubmission.updateLastSubmissionUserActivity()
     }
 
     @AssistedFactory
     interface Factory : CWAViewModelFactory<SubmissionTestResultConsentGivenViewModel> {
-        fun create(testType: CoronaTest.Type): SubmissionTestResultConsentGivenViewModel
+        fun create(testType: Type): SubmissionTestResultConsentGivenViewModel
     }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultNoConsentViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultNoConsentViewModel.kt
index 9868f82df..69a3092f8 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultNoConsentViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultNoConsentViewModel.kt
@@ -6,6 +6,7 @@ import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import de.rki.coronawarnapp.coronatest.type.CoronaTest
+import de.rki.coronawarnapp.coronatest.type.CoronaTest.Type.PCR
 import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector
 import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.Screen
 import de.rki.coronawarnapp.notification.PCRTestResultAvailableNotificationService
@@ -36,7 +37,9 @@ class SubmissionTestResultNoConsentViewModel @AssistedInject constructor(
 
     fun onTestOpened() = launch {
         Timber.v("onTestOpened()")
-        analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.TEST_RESULT)
+        if (testType == PCR) {
+            analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.TEST_RESULT)
+        }
         submissionRepository.setViewedTestResult(type = testType)
         testResultAvailableNotificationService.cancelTestResultAvailableNotification()
     }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/warnothers/SubmissionResultPositiveOtherWarningNoConsentViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/warnothers/SubmissionResultPositiveOtherWarningNoConsentViewModel.kt
index 28f1e8a8c..14ac3802e 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/warnothers/SubmissionResultPositiveOtherWarningNoConsentViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/warnothers/SubmissionResultPositiveOtherWarningNoConsentViewModel.kt
@@ -9,6 +9,7 @@ import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import de.rki.coronawarnapp.coronatest.type.CoronaTest
+import de.rki.coronawarnapp.coronatest.type.CoronaTest.Type.PCR
 import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector
 import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.Screen
 import de.rki.coronawarnapp.exception.ExceptionCategory
@@ -70,7 +71,9 @@ class SubmissionResultPositiveOtherWarningNoConsentViewModel @AssistedInject con
                     autoSubmission.updateMode(AutoSubmission.Mode.MONITOR)
                     Timber.tag(TAG).d("Navigate to SubmissionResultReadyFragment")
                     SubmissionResultPositiveOtherWarningNoConsentFragmentDirections
-                        .actionSubmissionResultPositiveOtherWarningNoConsentFragmentToSubmissionResultReadyFragment()
+                        .actionSubmissionResultPositiveOtherWarningNoConsentFragmentToSubmissionResultReadyFragment(
+                            testType
+                        )
                 }
                 routeToScreen.postValue(navDirections)
             }
@@ -138,7 +141,9 @@ class SubmissionResultPositiveOtherWarningNoConsentViewModel @AssistedInject con
     }
 
     fun onResume() {
-        analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.WARN_OTHERS)
+        if (testType == PCR) {
+            analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.WARN_OTHERS)
+        }
     }
 
     @AssistedFactory
diff --git a/Corona-Warn-App/src/main/res/navigation/nav_graph.xml b/Corona-Warn-App/src/main/res/navigation/nav_graph.xml
index 44c7f7131..b25a75044 100644
--- a/Corona-Warn-App/src/main/res/navigation/nav_graph.xml
+++ b/Corona-Warn-App/src/main/res/navigation/nav_graph.xml
@@ -401,6 +401,9 @@
         android:name="de.rki.coronawarnapp.ui.submission.resultready.SubmissionResultReadyFragment"
         android:label="SubmissionResultReadyFragment"
         tools:layout="@layout/fragment_submission_result_ready">
+        <argument
+            android:name="testType"
+            app:argType="de.rki.coronawarnapp.coronatest.type.CoronaTest$Type" />
         <action
             android:id="@+id/action_submissionResultReadyFragment_to_mainFragment"
             app:destination="@id/mainFragment"
@@ -422,6 +425,9 @@
         android:id="@+id/submissionSymptomIntroductionFragment"
         android:name="de.rki.coronawarnapp.ui.submission.symptoms.introduction.SubmissionSymptomIntroductionFragment"
         android:label="SubmissionSymptomIntroductionFragment">
+        <argument
+            android:name="testType"
+            app:argType="de.rki.coronawarnapp.coronatest.type.CoronaTest$Type" />
         <action
             android:id="@+id/action_submissionSymptomIntroductionFragment_to_submissionSymptomCalendarFragment"
             app:destination="@id/submissionSymptomCalendarFragment" />
@@ -438,6 +444,9 @@
         <argument
             android:name="symptomIndication"
             app:argType="de.rki.coronawarnapp.submission.Symptoms$Indication" />
+        <argument
+            android:name="testType"
+            app:argType="de.rki.coronawarnapp.coronatest.type.CoronaTest$Type" />
         <action
             android:id="@+id/action_submissionCalendarFragment_to_submissionSymptomIntroductionFragment"
             app:destination="@id/submissionSymptomIntroductionFragment" />
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/submission/task/SubmissionTaskTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/submission/task/SubmissionTaskTest.kt
index 81300aaa5..f58738ff6 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/submission/task/SubmissionTaskTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/submission/task/SubmissionTaskTest.kt
@@ -6,6 +6,8 @@ import de.rki.coronawarnapp.appconfig.ConfigData
 import de.rki.coronawarnapp.coronatest.CoronaTestRepository
 import de.rki.coronawarnapp.coronatest.notification.ShareTestResultNotificationService
 import de.rki.coronawarnapp.coronatest.type.CoronaTest
+import de.rki.coronawarnapp.coronatest.type.CoronaTest.Type.PCR
+import de.rki.coronawarnapp.coronatest.type.CoronaTest.Type.RAPID_ANTIGEN
 import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector
 import de.rki.coronawarnapp.notification.PCRTestResultAvailableNotificationService
 import de.rki.coronawarnapp.playbook.Playbook
@@ -223,9 +225,6 @@ class SubmissionTaskTest : BaseTest() {
                 )
             )
 
-            analyticsKeySubmissionCollector.reportSubmitted()
-            analyticsKeySubmissionCollector.reportSubmittedInBackground()
-
             tekHistoryStorage.clear()
             submissionSettings.symptoms
             settingSymptomsPreference.update(match { it.invoke(mockk()) == null })
@@ -393,4 +392,42 @@ class SubmissionTaskTest : BaseTest() {
         }
         verify { autoSubmission.updateMode(AutoSubmission.Mode.DISABLED) }
     }
+
+    @Test
+    fun `PPA is collected for PCR tests`() = runBlockingTest {
+        coronaTestsFlow.value = setOf(
+            mockk<CoronaTest>().apply {
+                every { type } returns PCR
+                every { isAdvancedConsentGiven } returns true
+                every { isSubmissionAllowed } returns true
+                every { isSubmitted } returns false
+                every { registrationToken } returns "regtoken"
+                every { identifier } returns "coronatest-identifier"
+            }
+        )
+
+        createTask().run(SubmissionTask.Arguments(checkUserActivity = true))
+
+        verify(exactly = 1) { analyticsKeySubmissionCollector.reportSubmitted() }
+        verify(exactly = 1) { analyticsKeySubmissionCollector.reportSubmittedInBackground() }
+    }
+
+    @Test
+    fun `PPA is NOT collected for RAT tests`() = runBlockingTest {
+        coronaTestsFlow.value = setOf(
+            mockk<CoronaTest>().apply {
+                every { type } returns RAPID_ANTIGEN
+                every { isAdvancedConsentGiven } returns true
+                every { isSubmissionAllowed } returns true
+                every { isSubmitted } returns false
+                every { registrationToken } returns "regtoken"
+                every { identifier } returns "coronatest-identifier"
+            }
+        )
+
+        createTask().run(SubmissionTask.Arguments(checkUserActivity = true))
+
+        verify(exactly = 0) { analyticsKeySubmissionCollector.reportSubmitted() }
+        verify(exactly = 0) { analyticsKeySubmissionCollector.reportSubmittedInBackground() }
+    }
 }
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 0f81834e2..bd8f052d2 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
@@ -6,6 +6,7 @@ import de.rki.coronawarnapp.coronatest.qrcode.CoronaTestQRCode
 import de.rki.coronawarnapp.coronatest.qrcode.CoronaTestQrCodeValidator
 import de.rki.coronawarnapp.coronatest.qrcode.InvalidQRCodeException
 import de.rki.coronawarnapp.coronatest.type.CoronaTest
+import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector
 import de.rki.coronawarnapp.submission.SubmissionRepository
 import de.rki.coronawarnapp.ui.submission.ApiRequestState
 import de.rki.coronawarnapp.ui.submission.qrcode.QrCodeRegistrationStateProcessor
@@ -14,11 +15,14 @@ import de.rki.coronawarnapp.util.permission.CameraSettings
 import de.rki.coronawarnapp.util.ui.SingleLiveEvent
 import io.kotest.matchers.shouldBe
 import io.mockk.MockKAnnotations
+import io.mockk.Runs
 import io.mockk.coEvery
 import io.mockk.every
 import io.mockk.impl.annotations.MockK
+import io.mockk.just
 import io.mockk.verify
 import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.test.runBlockingTest
 import org.junit.jupiter.api.BeforeEach
 import org.junit.jupiter.api.Test
 import org.junit.jupiter.api.extension.ExtendWith
@@ -34,6 +38,7 @@ class SubmissionQRCodeScanViewModelTest : BaseTest() {
     @MockK lateinit var cameraSettings: CameraSettings
     @MockK lateinit var qrCodeValidator: CoronaTestQrCodeValidator
     @MockK lateinit var qrCodeRegistrationStateProcessor: QrCodeRegistrationStateProcessor
+    @MockK lateinit var analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector
 
     private val coronaTestFlow = MutableStateFlow<CoronaTest?>(
         null
@@ -57,7 +62,8 @@ class SubmissionQRCodeScanViewModelTest : BaseTest() {
         qrCodeRegistrationStateProcessor,
         isConsentGiven = true,
         submissionRepository,
-        qrCodeValidator
+        qrCodeValidator,
+        analyticsKeySubmissionCollector
     )
 
     @Test
@@ -100,4 +106,30 @@ class SubmissionQRCodeScanViewModelTest : BaseTest() {
 
         verify { cameraSettings.isCameraDeniedPermanently }
     }
+
+    @Test
+    fun `startQrCodeRegistration() should call analyticsKeySubmissionCollector for PCR tests`() = runBlockingTest {
+        val coronaTestQRCode = CoronaTestQRCode.PCR(qrCodeGUID = "123456-12345678-1234-4DA7-B166-B86D85475064")
+
+        every { qrCodeValidator.validate(any()) } returns coronaTestQRCode
+        every { analyticsKeySubmissionCollector.reportAdvancedConsentGiven() } just Runs
+        coEvery { qrCodeRegistrationStateProcessor.startQrCodeRegistration(any(), any()) } just Runs
+
+        createViewModel().startQrCodeRegistration(rawResult = "", isConsentGiven = true)
+
+        verify(exactly = 1) { analyticsKeySubmissionCollector.reportAdvancedConsentGiven() }
+    }
+
+    @Test
+    fun `startQrCodeRegistration() should NOT call analyticsKeySubmissionCollector for RAT tests`() = runBlockingTest {
+        val coronaTestQRCode = CoronaTestQRCode.PCR(qrCodeGUID = "123456-12345678-1234-4DA7-B166-B86D85475064")
+
+        every { qrCodeValidator.validate(any()) } returns coronaTestQRCode
+        every { analyticsKeySubmissionCollector.reportAdvancedConsentGiven() } just Runs
+        coEvery { qrCodeRegistrationStateProcessor.startQrCodeRegistration(any(), any()) } just Runs
+
+        createViewModel().startQrCodeRegistration(rawResult = "", isConsentGiven = true)
+
+        verify(exactly = 1) { analyticsKeySubmissionCollector.reportAdvancedConsentGiven() }
+    }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/symptoms/calendar/SubmissionSymptomCalendarViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/symptoms/calendar/SubmissionSymptomCalendarViewModelTest.kt
index 835ce668d..c50aaff09 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/symptoms/calendar/SubmissionSymptomCalendarViewModelTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/symptoms/calendar/SubmissionSymptomCalendarViewModelTest.kt
@@ -1,6 +1,10 @@
 package de.rki.coronawarnapp.ui.submission.symptoms.calendar
 
+import de.rki.coronawarnapp.coronatest.type.CoronaTest
+import de.rki.coronawarnapp.coronatest.type.CoronaTest.Type.PCR
+import de.rki.coronawarnapp.coronatest.type.CoronaTest.Type.RAPID_ANTIGEN
 import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector
+import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.Screen
 import de.rki.coronawarnapp.submission.SubmissionRepository
 import de.rki.coronawarnapp.submission.Symptoms
 import de.rki.coronawarnapp.submission.auto.AutoSubmission
@@ -16,6 +20,7 @@ import io.mockk.just
 import io.mockk.verify
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.runBlockingTest
 import org.joda.time.LocalDate
 import org.junit.jupiter.api.BeforeEach
 import org.junit.jupiter.api.Test
@@ -31,6 +36,7 @@ class SubmissionSymptomCalendarViewModelTest : BaseTest() {
     @MockK lateinit var submissionRepository: SubmissionRepository
     @MockK lateinit var autoSubmission: AutoSubmission
     @MockK lateinit var analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector
+    @MockK lateinit var testType: CoronaTest.Type
     private lateinit var currentSymptoms: FlowPreference<Symptoms?>
 
     @BeforeEach
@@ -51,7 +57,8 @@ class SubmissionSymptomCalendarViewModelTest : BaseTest() {
             dispatcherProvider = TestDispatcherProvider(),
             submissionRepository = submissionRepository,
             autoSubmission = autoSubmission,
-            analyticsKeySubmissionCollector = analyticsKeySubmissionCollector
+            analyticsKeySubmissionCollector = analyticsKeySubmissionCollector,
+            testType = testType
         )
 
     @Test
@@ -111,4 +118,64 @@ class SubmissionSymptomCalendarViewModelTest : BaseTest() {
             showUploadDialog.value shouldBe false
         }
     }
+
+    @Test
+    fun `onNewUserActivity() should call analyticsKeySubmissionCollector for PCR tests`() {
+        testType = PCR
+
+        createViewModel().onNewUserActivity()
+
+        verify(exactly = 1) { analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.SYMPTOM_ONSET) }
+    }
+
+    @Test
+    fun `onNewUserActivity() should NOT call analyticsKeySubmissionCollector for RAT tests`() {
+        testType = RAPID_ANTIGEN
+
+        createViewModel().onNewUserActivity()
+
+        verify(exactly = 0) { analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.SYMPTOM_ONSET) }
+    }
+
+    @Test
+    fun `onCancelConfirmed() should call analyticsKeySubmissionCollector for PCR tests`() {
+        testType = PCR
+
+        createViewModel().onCancelConfirmed()
+
+        verify(exactly = 1) { analyticsKeySubmissionCollector.reportSubmittedAfterCancel() }
+    }
+
+    @Test
+    fun `onCancelConfirmed() should NOT call analyticsKeySubmissionCollector for RAT tests`() {
+        testType = RAPID_ANTIGEN
+
+        createViewModel().onCancelConfirmed()
+
+        verify(exactly = 0) { analyticsKeySubmissionCollector.reportSubmittedAfterCancel() }
+    }
+
+    @Test
+    fun `onDone() should call analyticsKeySubmissionCollector for PCR tests`() = runBlockingTest {
+        testType = PCR
+
+        createViewModel().apply {
+            onLastSevenDaysStart()
+            onDone()
+        }
+
+        verify(exactly = 1) { analyticsKeySubmissionCollector.reportSubmittedAfterSymptomFlow() }
+    }
+
+    @Test
+    fun `onDone() should NOT call analyticsKeySubmissionCollector for RAT tests`() {
+        testType = RAPID_ANTIGEN
+
+        createViewModel().apply {
+            onLastSevenDaysStart()
+            onDone()
+        }
+
+        verify(exactly = 0) { analyticsKeySubmissionCollector.reportSubmittedAfterSymptomFlow() }
+    }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/symptoms/introduction/SubmissionSymptomIntroductionViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/symptoms/introduction/SubmissionSymptomIntroductionViewModelTest.kt
index 250cb3f5c..9416e0123 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/symptoms/introduction/SubmissionSymptomIntroductionViewModelTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/symptoms/introduction/SubmissionSymptomIntroductionViewModelTest.kt
@@ -1,6 +1,10 @@
 package de.rki.coronawarnapp.ui.submission.symptoms.introduction
 
+import de.rki.coronawarnapp.coronatest.type.CoronaTest
+import de.rki.coronawarnapp.coronatest.type.CoronaTest.Type.PCR
+import de.rki.coronawarnapp.coronatest.type.CoronaTest.Type.RAPID_ANTIGEN
 import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector
+import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.Screen
 import de.rki.coronawarnapp.submission.SubmissionRepository
 import de.rki.coronawarnapp.submission.Symptoms
 import de.rki.coronawarnapp.submission.auto.AutoSubmission
@@ -30,6 +34,7 @@ class SubmissionSymptomIntroductionViewModelTest : BaseTest() {
     @MockK lateinit var submissionRepository: SubmissionRepository
     @MockK lateinit var autoSubmission: AutoSubmission
     @MockK lateinit var analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector
+    @MockK lateinit var testType: CoronaTest.Type
     private val currentSymptoms = mockFlowPreference<Symptoms?>(null)
 
     @BeforeEach
@@ -45,7 +50,8 @@ class SubmissionSymptomIntroductionViewModelTest : BaseTest() {
         dispatcherProvider = TestDispatcherProvider(),
         submissionRepository = submissionRepository,
         autoSubmission = autoSubmission,
-        analyticsKeySubmissionCollector = analyticsKeySubmissionCollector
+        analyticsKeySubmissionCollector = analyticsKeySubmissionCollector,
+        testType = testType
     )
 
     @Test
@@ -55,7 +61,8 @@ class SubmissionSymptomIntroductionViewModelTest : BaseTest() {
             onNextClicked()
             navigation.value shouldBe SubmissionSymptomIntroductionFragmentDirections
                 .actionSubmissionSymptomIntroductionFragmentToSubmissionSymptomCalendarFragment(
-                    symptomIndication = Symptoms.Indication.POSITIVE
+                    symptomIndication = Symptoms.Indication.POSITIVE,
+                    testType = testType
                 )
         }
 
@@ -121,4 +128,22 @@ class SubmissionSymptomIntroductionViewModelTest : BaseTest() {
             showUploadDialog.value shouldBe false
         }
     }
+
+    @Test
+    fun `onNewUserActivity() should call analyticsKeySubmissionCollector for PCR tests`() {
+        testType = PCR
+
+        createViewModel().onNewUserActivity()
+
+        verify(exactly = 1) { analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.SYMPTOMS) }
+    }
+
+    @Test
+    fun `onNewUserActivity() should NOT call analyticsKeySubmissionCollector for RAT tests`() {
+        testType = RAPID_ANTIGEN
+
+        createViewModel().onNewUserActivity()
+
+        verify(exactly = 0) { analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.SYMPTOMS) }
+    }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/testavailable/SubmissionTestResultAvailableViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/testavailable/SubmissionTestResultAvailableViewModelTest.kt
index 00fae3d0b..fad77e251 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/testavailable/SubmissionTestResultAvailableViewModelTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/testavailable/SubmissionTestResultAvailableViewModelTest.kt
@@ -2,6 +2,8 @@ package de.rki.coronawarnapp.ui.submission.testavailable
 
 import de.rki.coronawarnapp.coronatest.CoronaTestRepository
 import de.rki.coronawarnapp.coronatest.type.CoronaTest
+import de.rki.coronawarnapp.coronatest.type.CoronaTest.Type.PCR
+import de.rki.coronawarnapp.coronatest.type.CoronaTest.Type.RAPID_ANTIGEN
 import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector
 import de.rki.coronawarnapp.presencetracing.checkins.CheckInRepository
 import de.rki.coronawarnapp.submission.SubmissionRepository
@@ -129,4 +131,28 @@ class SubmissionTestResultAvailableViewModelTest : BaseTest() {
         viewModel.routeToScreen.value shouldBe SubmissionTestResultAvailableFragmentDirections
             .actionSubmissionTestResultAvailableFragmentToSubmissionTestResultNoConsentFragment(testType)
     }
+
+    @Test
+    fun `proceed() should call analyticsKeySubmissionCollector for PCR tests`() {
+        testType = PCR
+        coronaTestFlow.value = mockk<CoronaTest>().apply {
+            every { isAdvancedConsentGiven } returns false
+        }
+
+        createViewModel().proceed()
+
+        verify(exactly = 1) { analyticsKeySubmissionCollector.reportConsentWithdrawn() }
+    }
+
+    @Test
+    fun `proceed() should NOT call analyticsKeySubmissionCollector for RAT tests`() {
+        testType = RAPID_ANTIGEN
+        coronaTestFlow.value = mockk<CoronaTest>().apply {
+            every { isAdvancedConsentGiven } returns false
+        }
+
+        createViewModel().proceed()
+
+        verify(exactly = 0) { analyticsKeySubmissionCollector.reportConsentWithdrawn() }
+    }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/testresult/SubmissionTestResultConsentGivenViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/testresult/SubmissionTestResultConsentGivenViewModelTest.kt
index 31e401a51..f504e2a83 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/testresult/SubmissionTestResultConsentGivenViewModelTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/testresult/SubmissionTestResultConsentGivenViewModelTest.kt
@@ -2,6 +2,7 @@ package de.rki.coronawarnapp.ui.submission.testresult
 
 import de.rki.coronawarnapp.coronatest.type.CoronaTest
 import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector
+import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.Screen
 import de.rki.coronawarnapp.notification.PCRTestResultAvailableNotificationService
 import de.rki.coronawarnapp.submission.SubmissionRepository
 import de.rki.coronawarnapp.submission.auto.AutoSubmission
@@ -10,6 +11,7 @@ import de.rki.coronawarnapp.ui.submission.viewmodel.SubmissionNavigationEvents
 import io.kotest.matchers.shouldBe
 import io.mockk.MockKAnnotations
 import io.mockk.impl.annotations.MockK
+import io.mockk.verify
 import org.junit.jupiter.api.BeforeEach
 import org.junit.jupiter.api.Test
 import org.junit.jupiter.api.extension.ExtendWith
@@ -53,4 +55,18 @@ class SubmissionTestResultConsentGivenViewModelTest : BaseTest() {
         viewModel.onCancelConfirmed()
         viewModel.routeToScreen.value shouldBe SubmissionNavigationEvents.NavigateToMainActivity
     }
+
+    @Test
+    fun `onNewUserActivity should call analyticsSubmissionCollector for PCR tests`() {
+        testType = CoronaTest.Type.PCR
+        createViewModel().onNewUserActivity()
+        verify(exactly = 1) { analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.TEST_RESULT) }
+    }
+
+    @Test
+    fun `onNewUserActivity should NOT call analyticsSubmissionCollector for RAT tests`() {
+        testType = CoronaTest.Type.RAPID_ANTIGEN
+        createViewModel().onNewUserActivity()
+        verify(exactly = 0) { analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.TEST_RESULT) }
+    }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultNoConsentViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultNoConsentViewModelTest.kt
new file mode 100644
index 000000000..cd5efd3f5
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultNoConsentViewModelTest.kt
@@ -0,0 +1,46 @@
+package de.rki.coronawarnapp.ui.submission.testresult.positive
+
+import de.rki.coronawarnapp.coronatest.type.CoronaTest.Type
+import de.rki.coronawarnapp.coronatest.type.CoronaTest.Type.PCR
+import de.rki.coronawarnapp.coronatest.type.CoronaTest.Type.RAPID_ANTIGEN
+import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector
+import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.Screen
+import de.rki.coronawarnapp.notification.PCRTestResultAvailableNotificationService
+import de.rki.coronawarnapp.submission.SubmissionRepository
+import io.mockk.MockKAnnotations
+import io.mockk.impl.annotations.MockK
+import io.mockk.verify
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import testhelpers.BaseTest
+
+internal class SubmissionTestResultNoConsentViewModelTest : BaseTest() {
+
+    @MockK lateinit var submissionRepository: SubmissionRepository
+    @MockK lateinit var testResultAvailableNotificationService: PCRTestResultAvailableNotificationService
+    @MockK lateinit var analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector
+
+    @BeforeEach
+    fun setUp() {
+        MockKAnnotations.init(this, relaxed = true)
+    }
+
+    private fun createInstance(testType: Type) = SubmissionTestResultNoConsentViewModel(
+        submissionRepository,
+        testResultAvailableNotificationService,
+        analyticsKeySubmissionCollector,
+        testType
+    )
+
+    @Test
+    fun `onTestOpened() should call analyticsKeySubmissionCollector for PCR tests`() {
+        createInstance(PCR).onTestOpened()
+        verify(exactly = 1) { analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.TEST_RESULT) }
+    }
+
+    @Test
+    fun `onTestOpened() should NOT call analyticsKeySubmissionCollector for RAT tests`() {
+        createInstance(RAPID_ANTIGEN).onTestOpened()
+        verify(exactly = 0) { analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.TEST_RESULT) }
+    }
+}
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/warnothers/SubmissionResultPositiveOtherWarningNoConsentViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/warnothers/SubmissionResultPositiveOtherWarningNoConsentViewModelTest.kt
index a189fc595..3e16e9385 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/warnothers/SubmissionResultPositiveOtherWarningNoConsentViewModelTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/warnothers/SubmissionResultPositiveOtherWarningNoConsentViewModelTest.kt
@@ -1,7 +1,10 @@
 package de.rki.coronawarnapp.ui.submission.warnothers
 
 import de.rki.coronawarnapp.coronatest.type.CoronaTest
+import de.rki.coronawarnapp.coronatest.type.CoronaTest.Type.PCR
+import de.rki.coronawarnapp.coronatest.type.CoronaTest.Type.RAPID_ANTIGEN
 import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector
+import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.Screen
 import de.rki.coronawarnapp.nearby.ENFClient
 import de.rki.coronawarnapp.presencetracing.checkins.CheckInRepository
 import de.rki.coronawarnapp.storage.interoperability.InteroperabilityRepository
@@ -59,6 +62,7 @@ class SubmissionResultPositiveOtherWarningNoConsentViewModelTest : BaseTest() {
         }
 
         every { enfClient.isTracingEnabled } returns flowOf(true)
+        every { analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.WARN_OTHERS) } just Runs
     }
 
     private fun createViewModel() = SubmissionResultPositiveOtherWarningNoConsentViewModel(
@@ -86,4 +90,18 @@ class SubmissionResultPositiveOtherWarningNoConsentViewModelTest : BaseTest() {
         verify { submissionRepository.giveConsentToSubmission(any()) }
         verify { tekHistoryUpdater.updateTEKHistoryOrRequestPermission() }
     }
+
+    @Test
+    fun `onResume() should call analyticsKeySubmissionCollector for PCR tests`() {
+        testType = PCR
+        createViewModel().onResume()
+        verify(exactly = 1) { analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.WARN_OTHERS) }
+    }
+
+    @Test
+    fun `onResume() should NOT call analyticsKeySubmissionCollector for RAT tests`() {
+        testType = RAPID_ANTIGEN
+        createViewModel().onResume()
+        verify(exactly = 0) { analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.WARN_OTHERS) }
+    }
 }
-- 
GitLab