diff --git a/.circleci/config.yml b/.circleci/config.yml
index 3e7d9b10cbbc2210e2db04ff498f4665902f7e5b..f5008b878a490f09bb33f14a0008f935fee63404 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -2,16 +2,23 @@ version: 2.1
 orbs:
   android: circleci/android@0.2.1
   sonarcloud: sonarsource/sonarcloud@1.0.2
+
+#######################
+# Commands section
+# For code reuse.
+#######################
 commands:
   install-ndk: android/install-ndk
   restore-android-build-cache: android/restore-build-cache
   save-android-build-cache: android/save-build-cache
   scan-sonar: sonarcloud/scan
+
   restore-gradle-cache:
     description: "Restore gradle caches"
     steps:
       - restore_cache:
           key: jars-{{ checksum "build.gradle" }}-{{ checksum  "Corona-Warn-App/build.gradle" }}-{{ checksum  "Server-Protocol-Buffer/build.gradle" }}
+
   save-gradle-cache:
     description: "Save gradle caches"
     steps:
@@ -19,17 +26,7 @@ commands:
           paths:
             - ~/.gradle
           key: jars-{{ checksum "build.gradle" }}-{{ checksum  "Corona-Warn-App/build.gradle" }}-{{ checksum  "Server-Protocol-Buffer/build.gradle" }}
-  require-version-bump:
-    description: "Require version bump for binary assembling"
-    steps:
-      - run:
-          name: "Check if assemble required"
-          command: |
-            last_commit=$(git log -1 --pretty=%B)
-            if [[ $last_commit != *"Version bump"* ]]; then
-              circleci-agent step halt
-              echo "Skipping job"
-            fi
+
   run-gradle-cmd:
     description: "Running gradle command with environment options"
     parameters:
@@ -41,10 +38,19 @@ commands:
     steps:
       - run:
           name: << parameters.desc >>
-          command: ./gradlew << parameters.cmd >>
+          command: >
+            ./gradlew -PdisablePreDex
+            << parameters.cmd >>
+          no_output_timeout: 30m
           environment:
-            JVM_OPTS: -Xmx2048m
-            GRADLE_OPTS: -Xmx1536m -XX:+HeapDumpOnOutOfMemoryError -Dorg.gradle.caching=true -Dorg.gradle.configureondemand=true -Dkotlin.compiler.execution.strategy=in-process -Dkotlin.incremental=false
+            JVM_OPTS: -Xmx4096m
+            GRADLE_OPTS: >
+              -Xmx1536m -XX:+HeapDumpOnOutOfMemoryError
+              -Dorg.gradle.caching=true
+              -Dorg.gradle.configureondemand=true
+              -Dkotlin.compiler.execution.strategy=in-process
+              -Dkotlin.incremental=false
+
   run-gradle-cmd-test-splitting:
     description: "Running gradle command with environment options and test splitting"
     parameters:
@@ -59,13 +65,135 @@ commands:
           command: circleci tests glob "**/test*/**/*.kt" | circleci tests split | xargs -n 1 echo
       - run:
           name: << parameters.desc >>
-          command: ./gradlew << parameters.cmd >> -i -PtestFilter="`circleci tests glob "**/test*/**/*.kt" | circleci tests split`"
+          command: >
+            ./gradlew -PdisablePreDex
+            << parameters.cmd >>
+            -i -PtestFilter="`circleci tests glob "**/test*/**/*.kt" | circleci tests split`"
           environment:
-            JVM_OPTS: -Xmx2048m
-            GRADLE_OPTS: -Xmx1536m -XX:+HeapDumpOnOutOfMemoryError -Dorg.gradle.caching=true -Dorg.gradle.configureondemand=true -Dkotlin.compiler.execution.strategy=in-process -Dkotlin.incremental=false
+            JVM_OPTS: -Xmx4096m
+            GRADLE_OPTS: >
+              -Xmx1536m -XX:+HeapDumpOnOutOfMemoryError
+              -Dorg.gradle.caching=true
+              -Dorg.gradle.configureondemand=true
+              -Dkotlin.compiler.execution.strategy=in-process
+              -Dkotlin.incremental=false
+
+  skip-for-external-pull-requests:
+    description: "Skip for external pull requests due to missing access to secrets."
+    steps:
+      - run:
+          name: Early return if this build is from a forked PR
+          command: |
+            if [ -n "$CIRCLE_PR_NUMBER" ]; then
+              echo "Nothing to do for forked PRs, so marking this step successful"
+              circleci step halt
+            fi
+
+  setup-android-macos:
+    description: "Setup Android environment on macOS executor"
+    steps:
+      - restore_cache:
+          key: android-sdk-v1-{{ arch }}-{{ checksum ".circleci/install-android-sdk.sh" }}
+      - run:
+          name: Set ANDROID_SDK_ROOT environment variable
+          command: echo 'export ANDROID_SDK_ROOT=$HOME/android-sdk'  >> $BASH_ENV
+      - run:
+          name: Install Android SDK
+          command: |
+            sh .circleci/install-android-sdk.sh
+            echo 'export PATH=$ANDROID_SDK_ROOT/cmdline-tools/latest/bin:$PATH'  >> $BASH_ENV
+            echo 'export PATH=$ANDROID_SDK_ROOT/cmdline-tools/latest:$PATH'  >> $BASH_ENV
+            echo 'export PATH=$ANDROID_SDK_ROOT/platform-tools:$PATH'  >> $BASH_ENV
+            echo 'export PATH=$ANDROID_SDK_ROOT/emulator:$PATH'  >> $BASH_ENV
+            echo 'export PATH=$ANDROID_SDK_ROOT/build-tools/29.0.3:$PATH'  >> $BASH_ENV
+            source $BASH_ENV
+            sdkmanager --list
+      - save_cache:
+          key: android-sdk-v1-{{ arch }}-{{ checksum ".circleci/install-android-sdk.sh" }}
+          paths:
+            - /Users/distiller/android-sdk
+
+  run-emulator-for-api:
+    parameters:
+      apilevel:
+        type: integer
+    description: "Setup and start emulator for API<< parameters.apilevel >>"
+    steps:
+      - run:
+          name: Create emulator AVD
+          command: >
+            echo "no" | avdmanager --verbose create avd --force
+            --name "emulator_API<< parameters.apilevel >>"
+            --package "system-images;android-<< parameters.apilevel >>;google_apis;x86_64"
+      - run:
+          name: Configure emulator settings
+          command: |
+            cd $HOME/.android/avd/emulator_API<< parameters.apilevel >>.avd
+            sed -i '' -e 's/hw.lcd.density=[0-9]*/hw.lcd.density=560/g' config.ini
+            sed -i '' -e 's/hw.lcd.height=[0-9]*/hw.lcd.height=2880/g' config.ini
+            sed -i '' -e 's/hw.lcd.width=[0-9]*/hw.lcd.width=1440/g' config.ini
+            sed -i '' -e 's/hw.ramSize=[0-9]*/hw.ramSize=1536/g' config.ini
+      - run:
+          name: Check host state
+          command: |
+            emulator -accel-check
+            emulator -version
+      - run:
+          name: Start emulator AVD
+          command: >
+            emulator @emulator_API<< parameters.apilevel >>
+            -no-window
+            -no-audio
+            -no-boot-anim
+            -memory 2048
+            -nojni
+          background: true
+          no_output_timeout: 60m
+      - run:
+          name: Wait for emulator
+          command: |
+            adb wait-for-device shell 'while [[ -z $(getprop dev.bootcomplete) ]]; do sleep 1; done;'
+            adb devices
+            sleep 5
+      - run:
+          name: Disable animations
+          command: |
+            adb shell settings put global window_animation_scale 0
+            adb shell settings put global transition_animation_scale 0
+            adb shell settings put global animator_duration_scale 0
+
+  kill-all-emulators:
+    description: "Kill all emulators"
+    steps:
+      - run:
+          name: Kill all emulators
+          command: |
+            adb devices | grep emulator | cut -f1 | while read line; do adb -s $line emu kill; done
+            sleep 2
+            adb kill-server
+            sleep 2
+
+  compress-path:
+    parameters:
+      input:
+        type: string
+      output:
+        type: string
+    description: "Compress << parameters.input >> to << parameters.output >>"
+    steps:
+      - run:
+          name: Compress files
+          command: >
+            zip -r
+            << parameters.output >>
+            << parameters.input >>
 
+#######################
+# Jobs section
+# Tasks that get executed
+#######################
 jobs:
-  quick_build_device_release_no_tests:
+  detekt:
     executor: android/android
     resource_class: large
     working_directory: ~/project
@@ -73,7 +201,21 @@ jobs:
       - checkout
       - restore-gradle-cache
       - restore-android-build-cache
-      - require-version-bump
+      - run-gradle-cmd:
+          desc: Detekt check
+          cmd: ":Corona-Warn-App:detekt"
+      - store_artifacts:
+          path: Corona-Warn-App/build/reports
+          destination: reports
+
+  quick_build_device_release_no_tests:
+    executor: android/android
+    resource_class: xlarge
+    working_directory: ~/project
+    steps:
+      - checkout
+      - restore-gradle-cache
+      - restore-android-build-cache
       - run-gradle-cmd:
           desc: Quick Build
           cmd: "assembleDeviceRelease"
@@ -82,15 +224,15 @@ jobs:
       - store_artifacts:
           path: Corona-Warn-App/build/reports
           destination: reports
+
   quick_build_device_for_testers_release_no_tests:
     executor: android/android
-    resource_class: large
+    resource_class: xlarge
     working_directory: ~/project
     steps:
       - checkout
       - restore-gradle-cache
       - restore-android-build-cache
-      - require-version-bump
       - run-gradle-cmd:
           desc: Quick Build
           cmd: ":Corona-Warn-App:assembleDeviceForTestersRelease"
@@ -99,9 +241,10 @@ jobs:
       - store_artifacts:
           path: Corona-Warn-App/build/reports
           destination: reports
-  device_release_unit_tests:
+
+  unit_tests_device_release:
     executor: android/android
-    resource_class: large
+    resource_class: xlarge
     working_directory: ~/project
     parallelism: 3
     steps:
@@ -113,18 +256,22 @@ jobs:
           cmd: ":Corona-Warn-App:testDeviceReleaseUnitTest -i"
       - save-gradle-cache
       - save-android-build-cache
-      - store_artifacts:
-          path: Corona-Warn-App/build/reports
-          destination: reports
       - store_test_results:
           path: Corona-Warn-App/build/test-results
       - persist_to_workspace:
           root: /home/circleci
           paths:
             - ./project
-  device_for_testers_release_unit_tests:
+      - compress-path:
+          input: ./Corona-Warn-App/build/reports
+          output: /tmp/unit_tests_device_release.zip
+      - store_artifacts:
+          path: /tmp/unit_tests_device_release.zip
+          destination: zips/unit_tests_device_release.zip
+
+  unit_tests_device_for_testers_release:
     executor: android/android
-    resource_class: large
+    resource_class: xlarge
     working_directory: ~/project
     parallelism: 3
     steps:
@@ -136,14 +283,19 @@ jobs:
           cmd: ":Corona-Warn-App:testDeviceForTestersReleaseUnitTest"
       - save-gradle-cache
       - save-android-build-cache
-      - store_artifacts:
-          path: Corona-Warn-App/build/reports
-          destination: reports
       - store_test_results:
           path: Corona-Warn-App/build/test-results
+      - compress-path:
+          input: ./Corona-Warn-App/build/reports
+          output: /tmp/unit_tests_device_for_testers_release.zip
+      - store_artifacts:
+          path: /tmp/unit_tests_device_for_testers_release.zip
+          destination: zips/unit_tests_device_for_testers_release.zip
+
+
   lint_device_release_check:
     executor: android/android
-    resource_class: large
+    resource_class: xlarge
     working_directory: ~/project
     steps:
       - checkout
@@ -155,23 +307,10 @@ jobs:
       - store_artifacts:
           path: Corona-Warn-App/build/reports
           destination: reports
-  ktlint_device_release_check:
-    executor: android/android
-    resource_class: medium
-    working_directory: ~/project
-    steps:
-      - checkout
-      - restore-gradle-cache
-      - restore-android-build-cache
-      - run-gradle-cmd:
-          desc: Ktlint check deviceRelease
-          cmd: ":Corona-Warn-App:ktlintDeviceReleaseCheck"
-      - store_artifacts:
-          path: Corona-Warn-App/build/reports
-          destination: reports
+
   lint_device_for_testers_release_check:
     executor: android/android
-    resource_class: large
+    resource_class: xlarge
     working_directory: ~/project
     steps:
       - checkout
@@ -183,7 +322,8 @@ jobs:
       - store_artifacts:
           path: Corona-Warn-App/build/reports
           destination: reports
-  ktlint_device_for_testers_release_check:
+
+  ktlint_device_release_check:
     executor: android/android
     resource_class: medium
     working_directory: ~/project
@@ -192,12 +332,13 @@ jobs:
       - restore-gradle-cache
       - restore-android-build-cache
       - run-gradle-cmd:
-          desc: Ktlint check deviceForTestersRelease
-          cmd: ":Corona-Warn-App:ktlintDeviceForTestersReleaseCheck"
+          desc: Ktlint check deviceRelease
+          cmd: ":Corona-Warn-App:ktlintDeviceReleaseCheck"
       - store_artifacts:
           path: Corona-Warn-App/build/reports
           destination: reports
-  detekt:
+
+  ktlint_device_for_testers_release_check:
     executor: android/android
     resource_class: medium
     working_directory: ~/project
@@ -206,16 +347,18 @@ jobs:
       - restore-gradle-cache
       - restore-android-build-cache
       - run-gradle-cmd:
-          desc: Detekt check
-          cmd: ":Corona-Warn-App:detekt"
+          desc: Ktlint check deviceForTestersRelease
+          cmd: ":Corona-Warn-App:ktlintDeviceForTestersReleaseCheck"
       - store_artifacts:
           path: Corona-Warn-App/build/reports
           destination: reports
+
   run_sonar:
     executor: android/android
-    resource_class: large
+    resource_class: xlarge
     working_directory: ~/project
     steps:
+      - skip-for-external-pull-requests
       - attach_workspace:
           at: /home/circleci
       - restore-gradle-cache
@@ -224,9 +367,10 @@ jobs:
           desc: JaCoCo report
           cmd: ":Corona-Warn-App:jacocoTestReportDeviceRelease -i"
       - scan-sonar
+
   quick_build_device_for_testers_signed:
     executor: android/android
-    resource_class: large
+    resource_class: xlarge
     working_directory: ~/project
     steps:
       - checkout
@@ -276,22 +420,101 @@ jobs:
             curl --location --request POST $tsystems_upload_url \
             --header "Authorization: Bearer $tsystems_upload_bearer" \
             --form "file=@${fileName}" \
+
+  instrumentation_tests_device:
+    macos:
+      xcode: "12.3.0"
+    resource_class: large
+    steps:
+      - checkout
+      - setup-android-macos
+      - run-gradle-cmd:
+          desc: Build Apks for instrumentation test
+          cmd: >
+            :Corona-Warn-App:assembleDeviceDebug
+            :Corona-Warn-App:assembleDeviceDebugAndroidTest
+      - run-emulator-for-api:
+          apilevel: 29
+      - run-gradle-cmd:
+          desc: Run instrumentation tests on device
+          cmd: >
+            :Corona-Warn-App:connectedDeviceDebugAndroidTest
+            --info --continue
+            -Pandroid.testInstrumentationRunnerArguments.notAnnotation=testhelpers.Screenshot
+            -Pandroid.testInstrumentationRunnerArguments.clearPackageData=true
+      - kill-all-emulators
+      - store_test_results:
+          path: Corona-Warn-App/build/outputs/androidTest-results
+      - compress-path:
+          input: ./Corona-Warn-App/build/reports
+          output: /tmp/instrumentation_tests_device.zip
+      - store_artifacts:
+          path: /tmp/instrumentation_tests_device.zip
+          destination: zips/instrumentation_tests_device.zip
+
+  device_screenshots:
+    macos:
+      xcode: "12.3.0"
+    resource_class: large
+    steps:
+      - checkout
+      - restore_cache:
+          key: gem-cache-v1-{{ arch }}-{{ checksum "Gemfile.lock" }}
+      - run: bundle check || bundle install --path vendor/bundle
+      - save_cache:
+          key: gem-cache-v1-{{ arch }}-{{ checksum "Gemfile.lock" }}
+          paths:
+            - vendor/bundle
+      - setup-android-macos
+      - run-gradle-cmd:
+          desc: Build APKs for screenshots
+          cmd: >
+            :Corona-Warn-App:assembleDebug
+            :Corona-Warn-App:assembleAndroidTest
+      - run-emulator-for-api:
+          apilevel: 29
+      - run:
+          name: Run fastlane screengrab
+          command: |
+            for i in {1..5}; do bundle exec fastlane screengrab && break || sleep 15; done
+          no_output_timeout: 30m
+      - kill-all-emulators
+      - store_artifacts:
+          path: fastlane/metadata/android
+          destination: screenshots
+      - compress-path:
+          input: ./fastlane/metadata/android
+          output: /tmp/device_screenshots.zip
+      - store_artifacts:
+          path: /tmp/device_screenshots.zip
+          destination: zips/device_screenshots.zip
+
+#######################
+# Workflow section
+# Job execution orders
+#######################
 workflows:
   version: 2
-  quick_build:
+  check_buildtype_device:
     jobs:
-      - quick_build_device_release_no_tests
-      - quick_build_device_for_testers_release_no_tests
-      - device_release_unit_tests
-      - device_for_testers_release_unit_tests
+      - detekt
       - lint_device_release_check
-      - lint_device_for_testers_release_check
       - ktlint_device_release_check
-      - ktlint_device_for_testers_release_check
-      - detekt
+      - quick_build_device_release_no_tests
+      - unit_tests_device_release
       - run_sonar:
           requires:
-            - device_release_unit_tests
+            - unit_tests_device_release
+      - instrumentation_tests_device
+
+  check_buildtype_device_for_testers:
+    jobs:
+      - detekt
+      - lint_device_for_testers_release_check
+      - ktlint_device_for_testers_release_check
+      - quick_build_device_for_testers_release_no_tests
+      - unit_tests_device_for_testers_release
+
   signed_build:
     jobs:
       - quick_build_device_for_testers_signed:
@@ -301,3 +524,6 @@ workflows:
                 - /^v.*/
             branches:
               ignore: /.*/
+      - device_screenshots:
+          requires:
+            - quick_build_device_for_testers_signed
\ No newline at end of file
diff --git a/.circleci/install-android-sdk.sh b/.circleci/install-android-sdk.sh
new file mode 100644
index 0000000000000000000000000000000000000000..fc79de5a31dc8b7add7729e6ee24dd44a0328b4e
--- /dev/null
+++ b/.circleci/install-android-sdk.sh
@@ -0,0 +1,29 @@
+if [ -d $ANDROID_SDK_ROOT ]
+then
+    echo "Directory $ANDROID_SDK_ROOT already exists so we're skipping the install. If you'd like to install fresh tools, edit this script to invalidate the CI cache..."
+    exit 0
+fi
+
+mkdir -p $ANDROID_SDK_ROOT
+cd $ANDROID_SDK_ROOT
+curl https://dl.google.com/android/repository/commandlinetools-mac-6858069_latest.zip -o cmdline-tools.zip
+
+unzip cmdline-tools.zip -d $ANDROID_SDK_ROOT/cmdline-tools
+mv $ANDROID_SDK_ROOT/cmdline-tools/cmdline-tools $ANDROID_SDK_ROOT/cmdline-tools/latest
+
+mkdir -p "$ANDROID_SDK_ROOT/licenses"
+
+echo "24333f8a63b6825ea9c5514f83c2829b004d1fee" > "$ANDROID_SDK_ROOT/licenses/android-sdk-license"
+echo "84831b9409646a918e30573bab4c9c91346d8abd" > "$ANDROID_SDK_ROOT/licenses/android-sdk-preview-license"
+echo "d975f751698a77b662f1254ddbeed3901e976f5a" > "$ANDROID_SDK_ROOT/licenses/intel-android-extra-license"
+
+SDKMANAGER=$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager
+
+$SDKMANAGER "platform-tools"
+$SDKMANAGER "platforms;android-29"
+$SDKMANAGER "build-tools;29.0.3"
+$SDKMANAGER "ndk-bundle"
+$SDKMANAGER "system-images;android-29;google_apis;x86_64"
+$SDKMANAGER "emulator"
+
+echo "y" | sudo $SDKMANAGER --install "ndk;21.2.6472646" --sdk_root=${ANDROID_SDK_ROOT}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 71358b8a592ff73b6228ba865bc47a4f2a729215..0eb1ef447ed64c495b50fd45a097b692724f0d92 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,4 +12,5 @@
 /test_environments.json
 *.jks
 /keystore.properties
+.local/*
 fastlane/metadata
diff --git a/Corona-Warn-App/build.gradle b/Corona-Warn-App/build.gradle
index 81c5fa348604877b1342e01047824d5587104f79..199d127a55d9684d74d99e7d1f167b47699fbf6d 100644
--- a/Corona-Warn-App/build.gradle
+++ b/Corona-Warn-App/build.gradle
@@ -196,6 +196,12 @@ android {
             includeAndroidResources = true
             returnDefaultValues = true
         }
+
+        // Using orchestration toegether with mockk on x86 (32bit) emulator images crashes
+        // Leaving this in here as reminder
+        // https://github.com/android/android-test/issues/352
+        // https://github.com/mockk/mockk/issues/466
+        // execution 'ANDROIDX_TEST_ORCHESTRATOR'
     }
 
     kapt {
@@ -317,9 +323,11 @@ dependencies {
     implementation "com.google.dagger:dagger-android:$dagger_version"
     implementation "com.google.dagger:dagger-android-support:$dagger_version"
     kapt "com.google.dagger:dagger-compiler:$dagger_version"
-    kapt "com.google.dagger:dagger-android-processor:$dagger_version"
     kaptTest "com.google.dagger:dagger-compiler:$dagger_version"
     kaptAndroidTest "com.google.dagger:dagger-compiler:$dagger_version"
+    kapt "com.google.dagger:dagger-android-processor:$dagger_version"
+    kaptTest "com.google.dagger:dagger-android-processor:$dagger_version"
+    kaptAndroidTest "com.google.dagger:dagger-android-processor:$dagger_version"
 
     def assisted_injection_version = "0.6.0"
     compileOnly "com.squareup.inject:assisted-inject-annotations-dagger2:$assisted_injection_version"
diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/contactdiary/DiaryData.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/contactdiary/DiaryData.kt
index 767da20af5015aaaa451a2c27e9fda0033fe4c7a..910abff2693ecc7e8a709d9b9d2fe60101b09484 100644
--- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/contactdiary/DiaryData.kt
+++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/contactdiary/DiaryData.kt
@@ -14,22 +14,26 @@ object DiaryData {
     val LIST_ITEMS = listOf(
         ListItem.Data(
             R.drawable.ic_contact_diary_person_item,
-            "Max Mustermann"
+            "Max Mustermann",
+            ListItem.Type.PERSON
         ),
 
         ListItem.Data(
             R.drawable.ic_contact_diary_person_item,
-            "Erika Mustermann"
+            "Erika Mustermann",
+            ListItem.Type.PERSON
         ),
 
         ListItem.Data(
             R.drawable.ic_contact_diary_location,
-            "Fitnessstudio"
+            "Fitnessstudio",
+            ListItem.Type.LOCATION
         ),
 
         ListItem.Data(
             R.drawable.ic_contact_diary_location,
-            "Supermarket"
+            "Supermarket",
+            ListItem.Type.LOCATION
         )
     )
 
diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/util/security/DBPasswordTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/util/security/DBPasswordTest.kt
index 7d63879062b7de71dfc19b743aca4c3be1ceba73..0858f69d10ab54a797c310fd2871e79ac5f1f671 100644
--- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/util/security/DBPasswordTest.kt
+++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/util/security/DBPasswordTest.kt
@@ -2,13 +2,26 @@ package de.rki.coronawarnapp.util.security
 
 import android.content.Context
 import androidx.test.core.app.ApplicationProvider
+import de.rki.coronawarnapp.diagnosiskeys.storage.KeyCacheRepository
 import de.rki.coronawarnapp.storage.AppDatabase
 import de.rki.coronawarnapp.storage.tracing.TracingIntervalEntity
+import de.rki.coronawarnapp.storage.tracing.TracingIntervalRepository
+import de.rki.coronawarnapp.util.di.AppInjector
+import de.rki.coronawarnapp.util.di.ApplicationComponent
 import io.kotest.matchers.shouldBe
+import io.mockk.MockKAnnotations
+import io.mockk.Runs
+import io.mockk.clearAllMocks
+import io.mockk.coEvery
+import io.mockk.every
+import io.mockk.impl.annotations.MockK
+import io.mockk.just
+import io.mockk.mockkObject
 import kotlinx.coroutines.runBlocking
 import net.sqlcipher.database.SQLiteException
 import org.hamcrest.Matchers.equalTo
 import org.hamcrest.Matchers.not
+import org.junit.After
 import org.junit.Assert.assertThat
 import org.junit.Assert.assertTrue
 import org.junit.Before
@@ -19,6 +32,11 @@ import org.junit.runners.JUnit4
 @RunWith(JUnit4::class)
 class DBPasswordTest {
 
+    @MockK lateinit var applicationComponent: ApplicationComponent
+    @MockK lateinit var encryptedSharedPreferencesFactory: EncryptedPreferencesFactory
+    @MockK lateinit var errorResetTool: EncryptionErrorResetTool
+    @MockK lateinit var keyCacheRepository: KeyCacheRepository
+
     private val appContext: Context
         get() = ApplicationProvider.getApplicationContext()
 
@@ -27,10 +45,29 @@ class DBPasswordTest {
 
     @Before
     fun setUp() {
+        MockKAnnotations.init(this)
+        mockkObject(AppInjector)
+        every { AppInjector.component } returns applicationComponent
+
+        encryptedSharedPreferencesFactory = EncryptedPreferencesFactory(appContext)
+        every { applicationComponent.encryptedPreferencesFactory } returns encryptedSharedPreferencesFactory
+        every { applicationComponent.errorResetTool } returns errorResetTool
+        every { applicationComponent.keyCacheRepository } returns keyCacheRepository.apply {
+            coEvery { keyCacheRepository.clear() } just Runs
+        }
+
+        mockkObject(TracingIntervalRepository)
+        every { TracingIntervalRepository.resetInstance() } just Runs
+
         clearSharedPreferences()
         AppDatabase.reset(appContext)
     }
 
+    @After
+    fun teardown() {
+        clearAllMocks()
+    }
+
     @Test
     fun generatesPassphraseInCorrectLength() {
         val passphrase = SecurityHelper.getDBPassword()