From d0205cf47af1852bc5e4b1fcda97e1b382281860 Mon Sep 17 00:00:00 2001 From: chris-cwa <69595386+chris-cwa@users.noreply.github.com> Date: Tue, 20 Apr 2021 10:52:04 +0200 Subject: [PATCH] Cleaned PCR evaluation logic (EXPOSUREAPP-5991) (#2874) * simplified pcr evaluation * - unused device ui state * more simplifying * fixed tests Co-authored-by: Matthias Urhahn <matthias.urhahn@sap.com> Co-authored-by: Mohamed <mohamed.metwalli@sap.com> --- .../type/pcr/PCRCoronaTestExtensions.kt | 138 +++--------------- .../ui/main/home/HomeFragmentViewModel.kt | 1 - .../ui/view/TestResultSectionView.kt | 2 - .../rki/coronawarnapp/util/DeviceUIState.kt | 2 - .../util/NetworkRequestWrapper.kt | 30 ---- .../formatter/FormatterSubmissionHelper.kt | 8 +- .../FormatterSubmissionHelperTest.kt | 20 --- 7 files changed, 25 insertions(+), 176 deletions(-) delete mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/NetworkRequestWrapper.kt diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/pcr/PCRCoronaTestExtensions.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/pcr/PCRCoronaTestExtensions.kt index 5ce1c6582..c6d90c7d2 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/pcr/PCRCoronaTestExtensions.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/pcr/PCRCoronaTestExtensions.kt @@ -1,121 +1,29 @@ package de.rki.coronawarnapp.coronatest.type.pcr +import de.rki.coronawarnapp.coronatest.type.pcr.PCRCoronaTest.State.INVALID +import de.rki.coronawarnapp.coronatest.type.pcr.PCRCoronaTest.State.NEGATIVE +import de.rki.coronawarnapp.coronatest.type.pcr.PCRCoronaTest.State.PENDING +import de.rki.coronawarnapp.coronatest.type.pcr.PCRCoronaTest.State.POSITIVE +import de.rki.coronawarnapp.coronatest.type.pcr.PCRCoronaTest.State.REDEEMED +import de.rki.coronawarnapp.coronatest.type.pcr.SubmissionStatePCR.FetchingResult +import de.rki.coronawarnapp.coronatest.type.pcr.SubmissionStatePCR.NoTest +import de.rki.coronawarnapp.coronatest.type.pcr.SubmissionStatePCR.TestError +import de.rki.coronawarnapp.coronatest.type.pcr.SubmissionStatePCR.TestInvalid +import de.rki.coronawarnapp.coronatest.type.pcr.SubmissionStatePCR.TestNegative +import de.rki.coronawarnapp.coronatest.type.pcr.SubmissionStatePCR.TestPending +import de.rki.coronawarnapp.coronatest.type.pcr.SubmissionStatePCR.TestPositive +import de.rki.coronawarnapp.coronatest.type.pcr.SubmissionStatePCR.TestResultReady import de.rki.coronawarnapp.exception.http.CwaServerError -import de.rki.coronawarnapp.util.CWADebug -import de.rki.coronawarnapp.util.DeviceUIState -import de.rki.coronawarnapp.util.NetworkRequestWrapper -import de.rki.coronawarnapp.util.NetworkRequestWrapper.Companion.withSuccess -import timber.log.Timber -fun PCRCoronaTest?.toSubmissionState(): SubmissionStatePCR { - if (this == null) return SubmissionStatePCR.NoTest - - val uiState: DeviceUIState = when (state) { - PCRCoronaTest.State.PENDING -> DeviceUIState.PAIRED_NO_RESULT - PCRCoronaTest.State.INVALID -> DeviceUIState.PAIRED_ERROR - PCRCoronaTest.State.POSITIVE -> DeviceUIState.PAIRED_POSITIVE - PCRCoronaTest.State.NEGATIVE -> DeviceUIState.PAIRED_NEGATIVE - PCRCoronaTest.State.REDEEMED -> DeviceUIState.PAIRED_REDEEMED - } - - val networkWrapper = when { - isProcessing -> NetworkRequestWrapper.RequestStarted - lastError != null -> NetworkRequestWrapper.RequestFailed(lastError) - else -> NetworkRequestWrapper.RequestSuccessful(uiState) - } - - val eval = Evaluation( - deviceUiState = networkWrapper, - isDeviceRegistered = registrationToken != null, - hasTestResultBeenSeen = this.isViewed - ) - Timber.d("eval: %s", eval) - return when { - eval.isUnregistered() -> SubmissionStatePCR.NoTest - eval.isFetching() -> SubmissionStatePCR.FetchingResult - eval.isTestResultReady() -> SubmissionStatePCR.TestResultReady - eval.isResultPositive() -> SubmissionStatePCR.TestPositive - eval.isInvalid() -> SubmissionStatePCR.TestInvalid - eval.isError() -> SubmissionStatePCR.TestError - eval.isResultNegative() -> SubmissionStatePCR.TestNegative - eval.isSubmissionDone() -> SubmissionStatePCR.SubmissionDone(testRegisteredAt = registeredAt) - eval.isPending() -> SubmissionStatePCR.TestPending - else -> { - if (CWADebug.isDeviceForTestersBuild) throw IllegalStateException(eval.toString()) - else SubmissionStatePCR.TestPending - } +fun PCRCoronaTest?.toSubmissionState() = when { + this == null -> NoTest + isProcessing -> FetchingResult + lastError != null -> if (lastError is CwaServerError) TestPending else TestInvalid + else -> when (state) { + INVALID -> TestError + POSITIVE -> if (isViewed) TestPositive else TestResultReady + NEGATIVE -> TestNegative + REDEEMED -> TestInvalid + PENDING -> TestPending } } - -// TODO Refactor this to be easier to understand, probably remove the "withSuccess" logic. -private data class Evaluation( - val deviceUiState: NetworkRequestWrapper<DeviceUIState, Throwable>, - val isDeviceRegistered: Boolean, - val hasTestResultBeenSeen: Boolean -) { - - fun isUnregistered(): Boolean = !isDeviceRegistered - - fun isTestResultReady(): Boolean = deviceUiState.withSuccess(false) { - when (it) { - DeviceUIState.PAIRED_POSITIVE, - DeviceUIState.PAIRED_POSITIVE_TELETAN -> !hasTestResultBeenSeen - else -> false - } - } - - fun isFetching(): Boolean = - isDeviceRegistered && when (deviceUiState) { - is NetworkRequestWrapper.RequestFailed -> false - is NetworkRequestWrapper.RequestStarted -> true - is NetworkRequestWrapper.RequestIdle -> true - else -> false - } - - fun isResultPositive(): Boolean = - deviceUiState.withSuccess(false) { - when (it) { - DeviceUIState.PAIRED_POSITIVE, DeviceUIState.PAIRED_POSITIVE_TELETAN -> hasTestResultBeenSeen - else -> false - } - } - - fun isResultNegative(): Boolean = - deviceUiState.withSuccess(false) { - when (it) { - DeviceUIState.PAIRED_NEGATIVE -> true - else -> false - } - } - - fun isSubmissionDone(): Boolean = - when (deviceUiState) { - is NetworkRequestWrapper.RequestSuccessful -> deviceUiState.data == DeviceUIState.SUBMITTED_FINAL - else -> false - } - - fun isInvalid(): Boolean = - isDeviceRegistered && when (deviceUiState) { - is NetworkRequestWrapper.RequestFailed -> deviceUiState.error !is CwaServerError - is NetworkRequestWrapper.RequestSuccessful -> deviceUiState.data == DeviceUIState.PAIRED_REDEEMED - else -> false - } - - fun isError(): Boolean = - deviceUiState.withSuccess(false) { - when (it) { - DeviceUIState.PAIRED_ERROR -> true - else -> false - } - } - - fun isPending(): Boolean = - when (deviceUiState) { - is NetworkRequestWrapper.RequestFailed -> true - is NetworkRequestWrapper.RequestSuccessful -> { - deviceUiState.data == DeviceUIState.PAIRED_ERROR || - deviceUiState.data == DeviceUIState.PAIRED_NO_RESULT - } - else -> false - } -} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentViewModel.kt index 6a761f777..801b5d14d 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentViewModel.kt @@ -313,7 +313,6 @@ class HomeFragmentViewModel @AssistedInject constructor( test == null -> false test.lastError != null -> false test.testResult.toDeviceUIState() == DeviceUIState.PAIRED_POSITIVE -> true - test.testResult.toDeviceUIState() == DeviceUIState.PAIRED_POSITIVE_TELETAN -> true else -> false } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/view/TestResultSectionView.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/view/TestResultSectionView.kt index 11c140a9f..acdb4ca5d 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/view/TestResultSectionView.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/view/TestResultSectionView.kt @@ -60,7 +60,6 @@ constructor( private fun formatTestStatusIcon(coronaTest: CoronaTest?): Drawable? { val drawable = when (coronaTest?.testResult.toDeviceUIState()) { DeviceUIState.PAIRED_NO_RESULT -> R.drawable.ic_test_result_illustration_pending - DeviceUIState.PAIRED_POSITIVE_TELETAN, DeviceUIState.PAIRED_POSITIVE -> R.drawable.ic_test_result_illustration_positive DeviceUIState.PAIRED_NEGATIVE -> R.drawable.ic_test_result_illustration_negative DeviceUIState.PAIRED_ERROR, @@ -84,7 +83,6 @@ constructor( SpannableString(context.getString(R.string.test_result_card_status_invalid)) DeviceUIState.PAIRED_POSITIVE, - DeviceUIState.PAIRED_POSITIVE_TELETAN, DeviceUIState.PAIRED_NEGATIVE -> SpannableString(formatTestResult(context, uiState)) else -> SpannableString("") } 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 bc304ab27..8d4ecd55a 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 @@ -4,10 +4,8 @@ enum class DeviceUIState { UNPAIRED, PAIRED_NO_RESULT, PAIRED_POSITIVE, - 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/NetworkRequestWrapper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/NetworkRequestWrapper.kt deleted file mode 100644 index ddef4e314..000000000 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/NetworkRequestWrapper.kt +++ /dev/null @@ -1,30 +0,0 @@ -package de.rki.coronawarnapp.util - -sealed class NetworkRequestWrapper<out T : Any, out U : Any> { - object RequestIdle : NetworkRequestWrapper<Nothing, Nothing>() - object RequestStarted : NetworkRequestWrapper<Nothing, Nothing>() - data class RequestSuccessful<T : Any, U : Any>(val data: T) : NetworkRequestWrapper<T, U>() - data class RequestFailed<T : Any, U : Throwable>(val error: U) : NetworkRequestWrapper<T, U>() - - companion object { - fun <T : Any, U : Any, W> NetworkRequestWrapper<T, U>?.withSuccess(without: W, block: (data: T) -> W): W { - return if (this is RequestSuccessful) { - block(this.data) - } else { - without - } - } - - fun <T : Any, U : Any> NetworkRequestWrapper<T, U>?.withSuccess(block: (data: T) -> Unit) { - if (this is RequestSuccessful) { - block(this.data) - } - } - - fun <T : Any, U : Any> NetworkRequestWrapper<T, U>?.withFailure(block: (error: U) -> Unit) { - if (this is RequestFailed) { - block(this.error) - } - } - } -} 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 498386108..41caecdaa 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 @@ -67,15 +67,13 @@ fun formatSymptomBackgroundButtonStyleByState( fun formatTestResultStatusText(context: Context, uiState: DeviceUIState): String = when (uiState) { DeviceUIState.PAIRED_NEGATIVE -> R.string.test_result_card_status_negative - DeviceUIState.PAIRED_POSITIVE, - DeviceUIState.PAIRED_POSITIVE_TELETAN -> R.string.test_result_card_status_positive + DeviceUIState.PAIRED_POSITIVE -> R.string.test_result_card_status_positive else -> R.string.test_result_card_status_invalid }.let { context.getString(it) } fun formatTestResultStatusColor(context: Context, uiState: DeviceUIState): Int = when (uiState) { DeviceUIState.PAIRED_NEGATIVE -> R.color.colorTextSemanticGreen - DeviceUIState.PAIRED_POSITIVE, - DeviceUIState.PAIRED_POSITIVE_TELETAN -> R.color.colorTextSemanticRed + DeviceUIState.PAIRED_POSITIVE -> R.color.colorTextSemanticRed else -> R.color.colorTextSemanticRed }.let { context.getColorCompat(it) } @@ -105,7 +103,6 @@ fun formatTestResultCardContent( SpannableString(context.getString(R.string.test_result_card_status_invalid)) DeviceUIState.PAIRED_POSITIVE, - DeviceUIState.PAIRED_POSITIVE_TELETAN, DeviceUIState.PAIRED_NEGATIVE -> SpannableString(formatTestResult(context, uiState)) else -> SpannableString("") } @@ -113,7 +110,6 @@ fun formatTestResultCardContent( fun formatTestStatusIcon(context: Context, uiState: DeviceUIState): Drawable? = when (uiState) { DeviceUIState.PAIRED_NO_RESULT -> R.drawable.ic_test_result_illustration_pending - DeviceUIState.PAIRED_POSITIVE_TELETAN, DeviceUIState.PAIRED_POSITIVE -> R.drawable.ic_test_result_illustration_positive DeviceUIState.PAIRED_NEGATIVE -> R.drawable.ic_test_result_illustration_negative DeviceUIState.PAIRED_ERROR, diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/formatter/FormatterSubmissionHelperTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/formatter/FormatterSubmissionHelperTest.kt index 54d8d584e..14bb4ab06 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/formatter/FormatterSubmissionHelperTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/formatter/FormatterSubmissionHelperTest.kt @@ -138,18 +138,10 @@ class FormatterSubmissionHelperTest : BaseTest() { oUiState = DeviceUIState.PAIRED_POSITIVE, iResult = context.getString(R.string.test_result_card_status_positive) ) - formatTestResultStatusTextBase( - oUiState = DeviceUIState.PAIRED_POSITIVE_TELETAN, - iResult = context.getString(R.string.test_result_card_status_positive) - ) formatTestResultStatusTextBase( oUiState = DeviceUIState.SUBMITTED_FINAL, iResult = context.getString(R.string.test_result_card_status_invalid) ) - formatTestResultStatusTextBase( - oUiState = DeviceUIState.SUBMITTED_INITIAL, - iResult = context.getString(R.string.test_result_card_status_invalid) - ) formatTestResultStatusTextBase( oUiState = DeviceUIState.UNPAIRED, iResult = context.getString(R.string.test_result_card_status_invalid) @@ -174,18 +166,10 @@ class FormatterSubmissionHelperTest : BaseTest() { oUiState = DeviceUIState.PAIRED_POSITIVE, iResult = context.getColorCompat(R.color.colorTextSemanticRed) ) - formatTestResultStatusColorBase( - oUiState = DeviceUIState.PAIRED_POSITIVE_TELETAN, - iResult = context.getColorCompat(R.color.colorTextSemanticRed) - ) formatTestResultStatusColorBase( oUiState = DeviceUIState.SUBMITTED_FINAL, iResult = context.getColorCompat(R.color.colorTextSemanticRed) ) - formatTestResultStatusColorBase( - oUiState = DeviceUIState.SUBMITTED_INITIAL, - iResult = context.getColorCompat(R.color.colorTextSemanticRed) - ) formatTestResultStatusColorBase( oUiState = DeviceUIState.UNPAIRED, iResult = context.getColorCompat(R.color.colorTextSemanticRed) @@ -198,9 +182,7 @@ class FormatterSubmissionHelperTest : BaseTest() { formatTestStatusIconBase(oUiState = DeviceUIState.PAIRED_ERROR) formatTestStatusIconBase(oUiState = DeviceUIState.PAIRED_NO_RESULT) formatTestStatusIconBase(oUiState = DeviceUIState.PAIRED_POSITIVE) - formatTestStatusIconBase(oUiState = DeviceUIState.PAIRED_POSITIVE_TELETAN) formatTestStatusIconBase(oUiState = DeviceUIState.SUBMITTED_FINAL) - formatTestStatusIconBase(oUiState = DeviceUIState.SUBMITTED_INITIAL) formatTestStatusIconBase(oUiState = DeviceUIState.UNPAIRED) } @@ -210,9 +192,7 @@ class FormatterSubmissionHelperTest : BaseTest() { formatTestResultBase(oUiState = DeviceUIState.PAIRED_ERROR) formatTestResultBase(oUiState = DeviceUIState.PAIRED_NO_RESULT) formatTestResultBase(oUiState = DeviceUIState.PAIRED_POSITIVE) - formatTestResultBase(oUiState = DeviceUIState.PAIRED_POSITIVE_TELETAN) formatTestResultBase(oUiState = DeviceUIState.SUBMITTED_FINAL) - formatTestResultBase(oUiState = DeviceUIState.SUBMITTED_INITIAL) formatTestResultBase(oUiState = DeviceUIState.UNPAIRED) } } -- GitLab