From 04a579c17c2e863141caf87138ffd64999d54887 Mon Sep 17 00:00:00 2001
From: Kolya Opahle <k.opahle@sap.com>
Date: Fri, 7 Aug 2020 16:25:06 +0200
Subject: [PATCH] Added support for new TestResult and DeviceUIState based on
 EXPOSUREAPP-1743 (#989)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* Added support for new TestResult and DeviceUIState based on EXPOSUREAPP-1743

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* Removed empty strings from other translations and added English

Co-authored-by: Jakob Möller <jakob.moeller@sap.com>
---
 .../storage/SubmissionRepository.kt           |  1 +
 .../SubmissionTestResultFragment.kt           | 19 ++++++++++++++
 .../rki/coronawarnapp/util/DeviceUIState.kt   |  1 +
 .../formatter/FormatterSubmissionHelper.kt    | 25 +++++++++++++------
 .../util/formatter/TestResult.kt              |  3 ++-
 .../src/main/res/values-de/strings.xml        |  7 ++++++
 .../src/main/res/values/strings.xml           |  7 ++++++
 7 files changed, 54 insertions(+), 9 deletions(-)

diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SubmissionRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SubmissionRepository.kt
index a81018bd0..3190d0e48 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SubmissionRepository.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SubmissionRepository.kt
@@ -58,6 +58,7 @@ object SubmissionRepository {
                 TestResult.POSITIVE -> DeviceUIState.PAIRED_POSITIVE
                 TestResult.PENDING -> DeviceUIState.PAIRED_NO_RESULT
                 TestResult.INVALID -> DeviceUIState.PAIRED_ERROR
+                TestResult.REDEEMED -> DeviceUIState.PAIRED_REDEEMED
             }
         } catch (err: NoRegistrationTokenSetException) {
             return DeviceUIState.UNPAIRED
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultFragment.kt
index 41c8ace27..03aecc8b2 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultFragment.kt
@@ -9,6 +9,7 @@ import android.view.accessibility.AccessibilityEvent
 import androidx.activity.OnBackPressedCallback
 import androidx.fragment.app.Fragment
 import androidx.fragment.app.activityViewModels
+import androidx.lifecycle.Observer
 import androidx.navigation.fragment.findNavController
 import de.rki.coronawarnapp.R
 import de.rki.coronawarnapp.databinding.FragmentSubmissionTestResultBinding
@@ -18,6 +19,7 @@ import de.rki.coronawarnapp.exception.http.CwaWebException
 import de.rki.coronawarnapp.ui.doNavigate
 import de.rki.coronawarnapp.ui.viewmodel.SubmissionViewModel
 import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel
+import de.rki.coronawarnapp.util.DeviceUIState
 import de.rki.coronawarnapp.util.DialogHelper
 import de.rki.coronawarnapp.util.observeEvent
 
@@ -115,6 +117,23 @@ class SubmissionTestResultFragment : Fragment() {
         submissionViewModel.uiStateError.observeEvent(viewLifecycleOwner) {
             DialogHelper.showDialog(buildErrorDialog(it))
         }
+
+        submissionViewModel.deviceUiState.observe(viewLifecycleOwner, Observer { uiState ->
+            if (uiState == DeviceUIState.PAIRED_REDEEMED) {
+                showRedeemedTokenWarningDialog()
+            }
+        })
+    }
+
+    private fun showRedeemedTokenWarningDialog() {
+        val dialog = DialogHelper.DialogInstance(
+            requireActivity(),
+            R.string.submission_error_dialog_web_tan_redeemed_title,
+            R.string.submission_error_dialog_web_tan_redeemed_body,
+            R.string.submission_error_dialog_web_tan_redeemed_button_positive
+        )
+
+        DialogHelper.showDialog(dialog)
     }
 
     override fun onResume() {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DeviceUIState.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DeviceUIState.kt
index 6049195d4..bc304ab27 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DeviceUIState.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DeviceUIState.kt
@@ -7,6 +7,7 @@ enum class DeviceUIState {
     PAIRED_POSITIVE_TELETAN,
     PAIRED_NEGATIVE,
     PAIRED_ERROR,
+    PAIRED_REDEEMED,
     SUBMITTED_INITIAL,
     SUBMITTED_FINAL
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterSubmissionHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterSubmissionHelper.kt
index 5d93578b1..fb6de1ec9 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterSubmissionHelper.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterSubmissionHelper.kt
@@ -64,7 +64,8 @@ fun formatTestResultCardContent(uiState: DeviceUIState?): Spannable {
     return when (uiState) {
         DeviceUIState.PAIRED_NO_RESULT ->
             SpannableString(appContext.getString(R.string.test_result_card_status_pending))
-        DeviceUIState.PAIRED_ERROR ->
+        DeviceUIState.PAIRED_ERROR,
+        DeviceUIState.PAIRED_REDEEMED ->
             SpannableString(appContext.getString(R.string.test_result_card_status_invalid))
 
         DeviceUIState.PAIRED_POSITIVE,
@@ -81,7 +82,8 @@ fun formatTestStatusIcon(uiState: DeviceUIState?): Drawable? {
         DeviceUIState.PAIRED_POSITIVE_TELETAN,
         DeviceUIState.PAIRED_POSITIVE -> appContext.getDrawable(R.drawable.ic_test_result_illustration_positive)
         DeviceUIState.PAIRED_NEGATIVE -> appContext.getDrawable(R.drawable.ic_test_result_illustration_negative)
-        DeviceUIState.PAIRED_ERROR -> appContext.getDrawable(R.drawable.ic_test_result_illustration_invalid)
+        DeviceUIState.PAIRED_ERROR,
+        DeviceUIState.PAIRED_REDEEMED -> appContext.getDrawable(R.drawable.ic_test_result_illustration_invalid)
         else -> appContext.getDrawable(R.drawable.ic_test_result_illustration_invalid)
     }
 }
@@ -102,13 +104,14 @@ fun formatTestResultPositiveStepsVisible(uiState: DeviceUIState?): Int =
     formatVisibility(uiState == DeviceUIState.PAIRED_POSITIVE || uiState == DeviceUIState.PAIRED_POSITIVE_TELETAN)
 
 fun formatTestResultInvalidStepsVisible(uiState: DeviceUIState?): Int =
-    formatVisibility(uiState == DeviceUIState.PAIRED_ERROR)
+    formatVisibility(uiState == DeviceUIState.PAIRED_ERROR || uiState == DeviceUIState.PAIRED_REDEEMED)
 
 fun formatSubmissionStatusCardSubtitleColor(uiState: DeviceUIState?): Int {
     val appContext = CoronaWarnApplication.getAppContext()
     return when (uiState) {
         DeviceUIState.PAIRED_NEGATIVE -> appContext.getColor(R.color.colorTextSemanticGreen)
-        DeviceUIState.PAIRED_ERROR -> appContext.getColor(R.color.colorTextSemanticNeutral)
+        DeviceUIState.PAIRED_ERROR,
+        DeviceUIState.PAIRED_REDEEMED -> appContext.getColor(R.color.colorTextSemanticNeutral)
         else -> appContext.getColor(R.color.colorTextPrimary1)
     }
 }
@@ -117,7 +120,8 @@ fun formatSubmissionStatusCardSubtitleText(uiState: DeviceUIState?): String {
     val appContext = CoronaWarnApplication.getAppContext()
     return when (uiState) {
         DeviceUIState.PAIRED_NEGATIVE -> appContext.getString(R.string.submission_status_card_subtitle_negative)
-        DeviceUIState.PAIRED_ERROR -> appContext.getString(R.string.submission_status_card_subtitle_invalid)
+        DeviceUIState.PAIRED_ERROR,
+        DeviceUIState.PAIRED_REDEEMED -> appContext.getString(R.string.submission_status_card_subtitle_invalid)
         else -> ""
     }
 }
@@ -126,6 +130,7 @@ fun formatSubmissionStatusCardContentTitleText(uiState: DeviceUIState?): String
     val appContext = CoronaWarnApplication.getAppContext()
     return when (uiState) {
         DeviceUIState.PAIRED_ERROR,
+        DeviceUIState.PAIRED_REDEEMED,
         DeviceUIState.PAIRED_NEGATIVE -> appContext.getString(R.string.submission_status_card_title_available)
         DeviceUIState.PAIRED_NO_RESULT -> appContext.getString(R.string.submission_status_card_title_pending)
         else -> appContext.getString(R.string.submission_status_card_title_pending)
@@ -135,7 +140,8 @@ fun formatSubmissionStatusCardContentTitleText(uiState: DeviceUIState?): String
 fun formatSubmissionStatusCardContentBodyText(uiState: DeviceUIState?): String {
     val appContext = CoronaWarnApplication.getAppContext()
     return when (uiState) {
-        DeviceUIState.PAIRED_ERROR -> appContext.getString(R.string.submission_status_card_body_invalid)
+        DeviceUIState.PAIRED_ERROR,
+        DeviceUIState.PAIRED_REDEEMED -> appContext.getString(R.string.submission_status_card_body_invalid)
         DeviceUIState.PAIRED_NEGATIVE -> appContext.getString(R.string.submission_status_card_body_negative)
         DeviceUIState.PAIRED_NO_RESULT -> appContext.getString(R.string.submission_status_card_body_pending)
         else -> appContext.getString(R.string.submission_status_card_body_pending)
@@ -145,6 +151,7 @@ fun formatSubmissionStatusCardContentBodyText(uiState: DeviceUIState?): String {
 fun formatSubmissionStatusCardContentStatusTextVisible(uiState: DeviceUIState?): Int {
     return when (uiState) {
         DeviceUIState.PAIRED_NEGATIVE,
+        DeviceUIState.PAIRED_REDEEMED,
         DeviceUIState.PAIRED_ERROR -> View.VISIBLE
         else -> View.GONE
     }
@@ -157,7 +164,8 @@ fun formatSubmissionStatusCardContentIcon(uiState: DeviceUIState?): Drawable? {
         DeviceUIState.PAIRED_POSITIVE,
         DeviceUIState.PAIRED_POSITIVE_TELETAN -> appContext.getDrawable(R.drawable.ic_main_illustration_pending)
         DeviceUIState.PAIRED_NEGATIVE -> appContext.getDrawable(R.drawable.ic_main_illustration_negative)
-        DeviceUIState.PAIRED_ERROR -> appContext.getDrawable(R.drawable.ic_main_illustration_invalid)
+        DeviceUIState.PAIRED_ERROR,
+        DeviceUIState.PAIRED_REDEEMED -> appContext.getDrawable(R.drawable.ic_main_illustration_invalid)
         else -> appContext.getDrawable(R.drawable.ic_main_illustration_invalid)
     }
 }
@@ -180,7 +188,8 @@ fun formatSubmissionStatusCardContentVisible(
 ): Int = formatVisibility(
     deviceUiState == DeviceUIState.PAIRED_ERROR ||
             deviceUiState == DeviceUIState.PAIRED_NEGATIVE ||
-            deviceUiState == DeviceUIState.PAIRED_NO_RESULT
+            deviceUiState == DeviceUIState.PAIRED_NO_RESULT ||
+            deviceUiState == DeviceUIState.PAIRED_REDEEMED
 )
 
 fun formatShowSubmissionStatusPositiveCard(deviceUiState: DeviceUIState?): Int =
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/TestResult.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/TestResult.kt
index 31ec1a64d..c0cacc40a 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/TestResult.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/TestResult.kt
@@ -5,7 +5,8 @@ enum class TestResult(val value: Int) {
     PENDING(0),
     NEGATIVE(1),
     POSITIVE(2),
-    INVALID(3);
+    INVALID(3),
+    REDEEMED(4);
 
     companion object {
         fun fromInt(value: Int) = values().first { it.value == value }
diff --git a/Corona-Warn-App/src/main/res/values-de/strings.xml b/Corona-Warn-App/src/main/res/values-de/strings.xml
index 599eb7de3..227eb515b 100644
--- a/Corona-Warn-App/src/main/res/values-de/strings.xml
+++ b/Corona-Warn-App/src/main/res/values-de/strings.xml
@@ -726,6 +726,13 @@
     <!-- XBUT: Positive button for submission tan invalid -->
     <string name="submission_error_dialog_web_tan_invalid_button_positive">"Zurück"</string>
 
+    <!-- XHED: Dialog title for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_title">"Test fehlerhaft"</string>
+    <!-- XMSG: Dialog body for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_body">"Es gab ein Problem bei der Auswertung Ihres Tests. Ihr QR Code ist bereits abgelaufen."</string>
+    <!-- XBUT: Positive button for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_button_positive">"OK"</string>
+
     <!-- Permission Rationale Dialog -->
     <!-- XHED: Dialog headline QR Scan permission rationale  -->
     <string name="submission_qr_code_scan_permission_rationale_dialog_headline">"Kamera-Zugriff benötigt"</string>
diff --git a/Corona-Warn-App/src/main/res/values/strings.xml b/Corona-Warn-App/src/main/res/values/strings.xml
index 82541082b..60485feb0 100644
--- a/Corona-Warn-App/src/main/res/values/strings.xml
+++ b/Corona-Warn-App/src/main/res/values/strings.xml
@@ -728,6 +728,13 @@
     <!-- XBUT: Positive button for submission tan invalid -->
     <string name="submission_error_dialog_web_tan_invalid_button_positive">"Back"</string>
 
+    <!-- XHED: Dialog title for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_title">"Test has errors"</string>
+    <!-- XMSG: Dialog body for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_body">"There was a problem evaluating your test. Your QR Code has already expired."</string>
+    <!-- XBUT: Positive button for submission tan redeemed -->
+    <string name="submission_error_dialog_web_tan_redeemed_button_positive">"OK"</string>
+
     <!-- Permission Rationale Dialog -->
     <!-- XHED: Dialog headline QR Scan permission rationale  -->
     <string name="submission_qr_code_scan_permission_rationale_dialog_headline">"Camera authorization required"</string>
-- 
GitLab