diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/risklevel/ui/TestRiskLevelCalculationFragmentCWAViewModel.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/risklevel/ui/TestRiskLevelCalculationFragmentCWAViewModel.kt index bf2c2595ee3c4a8b93b4839dd963c189eef3f978..ca4ed7c6094acda5e0f635abeb35af7304ece19e 100644 --- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/risklevel/ui/TestRiskLevelCalculationFragmentCWAViewModel.kt +++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/risklevel/ui/TestRiskLevelCalculationFragmentCWAViewModel.kt @@ -13,8 +13,8 @@ import de.rki.coronawarnapp.diagnosiskeys.download.DownloadDiagnosisKeysTask import de.rki.coronawarnapp.diagnosiskeys.storage.KeyCacheRepository import de.rki.coronawarnapp.exception.ExceptionCategory import de.rki.coronawarnapp.exception.reporting.report -import de.rki.coronawarnapp.risk.RiskLevel import de.rki.coronawarnapp.risk.RiskLevelTask +import de.rki.coronawarnapp.risk.RiskState import de.rki.coronawarnapp.risk.TimeVariables import de.rki.coronawarnapp.risk.result.AggregatedRiskResult import de.rki.coronawarnapp.risk.storage.RiskLevelStorage @@ -158,8 +158,8 @@ class TestRiskLevelCalculationFragmentCWAViewModel @AssistedInject constructor( createAdditionalRiskCalcInfo( latestCalc.calculatedAt, - riskLevel = latestCalc.riskLevel, - riskLevelLastSuccessfulCalculated = latestSuccessfulCalc.riskLevel, + riskLevel = latestCalc.riskState, + riskLevelLastSuccessfulCalculated = latestSuccessfulCalc.riskState, matchedKeyCount = latestCalc.matchedKeyCount, daysSinceLastExposure = latestCalc.daysWithEncounters, lastTimeDiagnosisKeysFromServerFetch = lastTimeDiagnosisKeysFromServerFetch @@ -168,8 +168,8 @@ class TestRiskLevelCalculationFragmentCWAViewModel @AssistedInject constructor( private suspend fun createAdditionalRiskCalcInfo( lastTimeRiskLevelCalculation: Instant, - riskLevel: RiskLevel, - riskLevelLastSuccessfulCalculated: RiskLevel, + riskLevel: RiskState, + riskLevelLastSuccessfulCalculated: RiskState, matchedKeyCount: Int, daysSinceLastExposure: Int, lastTimeDiagnosisKeysFromServerFetch: Date? diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevel.kt deleted file mode 100644 index 6242e96052ac38cdfffccfddf9807a8c290ec3ea..0000000000000000000000000000000000000000 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevel.kt +++ /dev/null @@ -1,34 +0,0 @@ -package de.rki.coronawarnapp.risk - -enum class RiskLevel(val raw: Int) { - // mapped to: no calculation possible - // the ExposureNotification Framework or Bluetooth is not active - // This risk score level has the highest priority and can oversteer the other risk score levels. - NO_CALCULATION_POSSIBLE_TRACING_OFF(RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF), - - // mapped to: low risk - // the risk score is higher than the riskScoreMinimumThreshold and lower than the riskScoreLevelThreshold - // and the timeActivateTracing is higher than notEnoughDataTimeRange - LOW_LEVEL_RISK(RiskLevelConstants.LOW_LEVEL_RISK), - - // mapped to: increased risk - // the risk score is higher than the riskScoreLevelThreshold - // The notEnoughDataTimeRange must not be not considered. - INCREASED_RISK(RiskLevelConstants.INCREASED_RISK), - - // mapped to: unknown risk - outdated results - // This risk status is shown if timeSinceLastExposureCalculation > maxStaleExposureRiskRange - // and background jobs are enabled - UNKNOWN_RISK_OUTDATED_RESULTS(RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS), - - // mapped to: unknown risk - outdated results manual - // This risk status is shown if timeSinceLastExposureCalculation > maxStaleExposureRiskRange - // and background jobs are disabled - UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL(RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL), - - UNKNOWN_RISK_NO_INTERNET(RiskLevelConstants.UNKNOWN_RISK_NO_INTERNET), - - // mapped to no UI state - // this should never happen - UNDETERMINED(RiskLevelConstants.UNDETERMINED); -} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelChangeDetector.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelChangeDetector.kt index 0a08ba9ef3c5d9d59c444c1c737003bf248d4164..e2d403a1d01aa91a5dbc1866bbe85ebae24197c8 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelChangeDetector.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelChangeDetector.kt @@ -56,32 +56,30 @@ class RiskLevelChangeDetector @Inject constructor( } riskLevelSettings.lastChangeCheckedRiskLevelTimestamp = newResult.calculatedAt - val oldRiskLevel = oldResult.riskLevel - val newRiskLevel = newResult.riskLevel + val oldRiskState = oldResult.riskState + val newRiskState = newResult.riskState - Timber.d("last CalculatedS core is ${oldRiskLevel.raw} and Current Risk Level is ${newRiskLevel.raw}") + Timber.d("Last state was $oldRiskState and current state is $newRiskState") - if (hasHighLowLevelChanged(oldRiskLevel, newRiskLevel) && !LocalData.submissionWasSuccessful()) { + if (hasHighLowLevelChanged(oldRiskState, newRiskState) && !LocalData.submissionWasSuccessful()) { Timber.d("Notification Permission = ${notificationManagerCompat.areNotificationsEnabled()}") if (!foregroundState.isInForeground.first()) { NotificationHelper.sendNotification( content = context.getString(R.string.notification_body), - notificationId = NEW_MESSAGE_RISK_LEVEL_SCORE_NOTIFICATION_ID) + notificationId = NEW_MESSAGE_RISK_LEVEL_SCORE_NOTIFICATION_ID + ) } else { Timber.d("App is in foreground, not sending notifications") } - Timber.d("Risk level changed and notification sent. Current Risk level is $newRiskLevel") + Timber.d("Risk level changed and notification sent. Current Risk level is $newRiskState") } - if ( - oldRiskLevel.raw == RiskLevelConstants.INCREASED_RISK && - newRiskLevel.raw == RiskLevelConstants.LOW_LEVEL_RISK - ) { + if (oldRiskState == RiskState.INCREASED_RISK && newRiskState == RiskState.LOW_RISK) { LocalData.isUserToBeNotifiedOfLoweredRiskLevel = true - Timber.d("Risk level changed LocalData is updated. Current Risk level is $newRiskLevel") + Timber.d("Risk level changed LocalData is updated. Current Risk level is $newRiskState") } } @@ -94,10 +92,10 @@ class RiskLevelChangeDetector @Inject constructor( * @return */ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) - internal fun hasHighLowLevelChanged(previous: RiskLevel, current: RiskLevel) = + internal fun hasHighLowLevelChanged(previous: RiskState, current: RiskState) = previous.isIncreasedRisk != current.isIncreasedRisk - private val RiskLevel.isIncreasedRisk: Boolean - get() = this == RiskLevel.INCREASED_RISK + private val RiskState.isIncreasedRisk: Boolean + get() = this == RiskState.INCREASED_RISK } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelConstants.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelConstants.kt deleted file mode 100644 index cf4eb571e92828d03e680d55dc5e63eba5d71074..0000000000000000000000000000000000000000 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelConstants.kt +++ /dev/null @@ -1,11 +0,0 @@ -package de.rki.coronawarnapp.risk - -object RiskLevelConstants { - const val NO_CALCULATION_POSSIBLE_TRACING_OFF = 1 - const val LOW_LEVEL_RISK = 2 - const val INCREASED_RISK = 3 - const val UNKNOWN_RISK_OUTDATED_RESULTS = 4 - const val UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL = 5 - const val UNKNOWN_RISK_NO_INTERNET = 6 - const val UNDETERMINED = 9001 -} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelResult.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelResult.kt index 40f7d4905f857f7dc89d701865c5ebbf47a51bb2..00327c9e458452010032a38dbf3f8928f2989bf9 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelResult.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelResult.kt @@ -7,16 +7,11 @@ import org.joda.time.Instant interface RiskLevelResult { val calculatedAt: Instant - val riskLevel: RiskLevel + val riskState: RiskState get() = when { - aggregatedRiskResult?.isIncreasedRisk() == true -> RiskLevel.INCREASED_RISK - aggregatedRiskResult?.isLowRisk() == true -> RiskLevel.LOW_LEVEL_RISK - failureReason == FailureReason.OUTDATED_RESULTS -> RiskLevel.UNKNOWN_RISK_OUTDATED_RESULTS - failureReason == FailureReason.OUTDATED_RESULTS_MANUAL -> RiskLevel.UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL - failureReason == FailureReason.TRACING_OFF -> RiskLevel.NO_CALCULATION_POSSIBLE_TRACING_OFF - failureReason == FailureReason.NO_INTERNET -> RiskLevel.UNKNOWN_RISK_NO_INTERNET - failureReason == FailureReason.UNKNOWN -> RiskLevel.UNDETERMINED - else -> RiskLevel.UNDETERMINED + aggregatedRiskResult?.isIncreasedRisk() == true -> RiskState.INCREASED_RISK + aggregatedRiskResult?.isLowRisk() == true -> RiskState.LOW_RISK + else -> RiskState.CALCULATION_FAILED } val failureReason: FailureReason? @@ -61,13 +56,4 @@ interface RiskLevelResult { OUTDATED_RESULTS("outDatedResults"), OUTDATED_RESULTS_MANUAL("outDatedResults.manual") } - - companion object { - private val UNSUCCESSFUL_RISK_LEVELS = arrayOf( - RiskLevel.UNDETERMINED, - RiskLevel.NO_CALCULATION_POSSIBLE_TRACING_OFF, - RiskLevel.UNKNOWN_RISK_OUTDATED_RESULTS, - RiskLevel.UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL - ) - } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskState.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskState.kt new file mode 100644 index 0000000000000000000000000000000000000000..e71d6f7a47b0ebce7445f3615ba4d8777a60af21 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskState.kt @@ -0,0 +1,7 @@ +package de.rki.coronawarnapp.risk + +enum class RiskState { + LOW_RISK, + INCREASED_RISK, + CALCULATION_FAILED +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/TimeVariables.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/TimeVariables.kt index 274b0db8df8b25b9841982516e82a158dcf4ff8a..b1f46c2a894f9f7360bd2497a46fad1f5d581ef6 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/TimeVariables.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/TimeVariables.kt @@ -10,6 +10,7 @@ import de.rki.coronawarnapp.storage.tracing.TracingIntervalRepository import de.rki.coronawarnapp.util.CWADebug import de.rki.coronawarnapp.util.TimeAndDateExtensions.daysToMilliseconds import de.rki.coronawarnapp.util.TimeAndDateExtensions.roundUpMsToDays +import timber.log.Timber object TimeVariables { @@ -176,7 +177,13 @@ object TimeVariables { // because we delete periods that are past 14 days but tracingActiveMS counts from first // ever activation, there are edge cases where tracingActiveMS gets to be > 14 days - return (minOf(tracingActiveMS, retentionPeriodInMS) - inactiveTracingMS).roundUpMsToDays() + val activeTracingDays = (minOf(tracingActiveMS, retentionPeriodInMS) - inactiveTracingMS).roundUpMsToDays() + return if (activeTracingDays >= 0) { + activeTracingDays + } else { + Timber.w("Negative active tracing days: %d", activeTracingDays) + 0 + } } /**************************************************** diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/storage/legacy/RiskLevelResultMigrator.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/storage/legacy/RiskLevelResultMigrator.kt index 07e127e23d223d12201722c774e9bd4d9970fec7..0f60e67edfc2b0e1533ad3325acee636ef1aa86f 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/storage/legacy/RiskLevelResultMigrator.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/storage/legacy/RiskLevelResultMigrator.kt @@ -4,9 +4,8 @@ import android.content.SharedPreferences import androidx.annotation.VisibleForTesting import com.google.android.gms.nearby.exposurenotification.ExposureWindow import dagger.Lazy -import de.rki.coronawarnapp.risk.RiskLevel -import de.rki.coronawarnapp.risk.RiskLevelConstants import de.rki.coronawarnapp.risk.RiskLevelResult +import de.rki.coronawarnapp.risk.RiskState import de.rki.coronawarnapp.risk.result.AggregatedRiskResult import de.rki.coronawarnapp.storage.EncryptedPreferences import de.rki.coronawarnapp.util.TimeStamper @@ -34,12 +33,12 @@ class RiskLevelResultMigrator @Inject constructor( } } - private fun lastCalculatedRiskLevel(): RiskLevel? { + private fun lastCalculatedRiskLevel(): RiskState? { val rawRiskLevel = prefs.getInt("preference_risk_level_score", -1) return if (rawRiskLevel != -1) mapRiskLevelConstant(rawRiskLevel) else null } - private fun lastSuccessfullyCalculatedRiskLevel(): RiskLevel? { + private fun lastSuccessfullyCalculatedRiskLevel(): RiskState? { val rawRiskLevel = prefs.getInt("preference_risk_level_score_successful", -1) return if (rawRiskLevel != -1) mapRiskLevelConstant(rawRiskLevel) else null } @@ -49,14 +48,14 @@ class RiskLevelResultMigrator @Inject constructor( lastCalculatedRiskLevel()?.let { legacyResults.add( LegacyResult( - riskLevel = it, + riskState = it, calculatedAt = lastTimeRiskLevelCalculation() ?: timeStamper.nowUTC ) ) } lastSuccessfullyCalculatedRiskLevel()?.let { - legacyResults.add(LegacyResult(riskLevel = it, calculatedAt = timeStamper.nowUTC)) + legacyResults.add(LegacyResult(riskState = it, calculatedAt = timeStamper.nowUTC)) } legacyResults @@ -66,7 +65,7 @@ class RiskLevelResultMigrator @Inject constructor( } data class LegacyResult( - override val riskLevel: RiskLevel, + override val riskState: RiskState, override val calculatedAt: Instant ) : RiskLevelResult { override val failureReason: RiskLevelResult.FailureReason? = null @@ -77,18 +76,23 @@ class RiskLevelResultMigrator @Inject constructor( } companion object { + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) - internal fun mapRiskLevelConstant(value: Int): RiskLevel { - return when (value) { - RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF -> RiskLevel.NO_CALCULATION_POSSIBLE_TRACING_OFF - RiskLevelConstants.LOW_LEVEL_RISK -> RiskLevel.LOW_LEVEL_RISK - RiskLevelConstants.INCREASED_RISK -> RiskLevel.INCREASED_RISK - RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS -> RiskLevel.UNKNOWN_RISK_OUTDATED_RESULTS - RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL -> { - RiskLevel.UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL - } - else -> RiskLevel.UNDETERMINED - } + internal fun mapRiskLevelConstant(value: Int): RiskState = when (value) { + MigrationRiskLevelConstants.LOW_LEVEL_RISK -> RiskState.LOW_RISK + MigrationRiskLevelConstants.INCREASED_RISK -> RiskState.INCREASED_RISK + else -> RiskState.CALCULATION_FAILED } } } + +@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) +internal object MigrationRiskLevelConstants { + const val NO_CALCULATION_POSSIBLE_TRACING_OFF = 1 + const val LOW_LEVEL_RISK = 2 + const val INCREASED_RISK = 3 + const val UNKNOWN_RISK_OUTDATED_RESULTS = 4 + const val UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL = 5 + const val UNKNOWN_RISK_NO_INTERNET = 6 + const val UNDETERMINED = 9001 +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/card/TracingCardState.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/card/TracingCardState.kt index 46b9eb568486163f01096c11beb7c813b122f1c6..67003dd6b56f3eab95951567b92a56208bf4feac 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/card/TracingCardState.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/card/TracingCardState.kt @@ -5,7 +5,10 @@ import android.content.res.ColorStateList import android.graphics.drawable.Drawable import android.text.format.DateUtils import de.rki.coronawarnapp.R -import de.rki.coronawarnapp.risk.RiskLevelConstants +import de.rki.coronawarnapp.risk.RiskState +import de.rki.coronawarnapp.risk.RiskState.CALCULATION_FAILED +import de.rki.coronawarnapp.risk.RiskState.INCREASED_RISK +import de.rki.coronawarnapp.risk.RiskState.LOW_RISK import de.rki.coronawarnapp.risk.TimeVariables import de.rki.coronawarnapp.tracing.GeneralTracingStatus import de.rki.coronawarnapp.tracing.TracingProgress @@ -18,12 +21,12 @@ import java.util.Date @Suppress("TooManyFunctions") data class TracingCardState( override val tracingStatus: GeneralTracingStatus.Status, - override val riskLevelScore: Int, + override val riskState: RiskState, override val tracingProgress: TracingProgress, - val lastRiskLevelScoreCalculated: Int, + val lastSuccessfulRiskState: RiskState, val daysWithEncounters: Int, val lastEncounterAt: Instant?, - val activeTracingDaysInRetentionPeriod: Long, + val activeTracingDays: Long, val lastTimeDiagnosisKeysFetched: Date?, override val isManualKeyRetrievalEnabled: Boolean, override val showDetails: Boolean = false @@ -35,9 +38,8 @@ data class TracingCardState( * between colored / light / dark background */ fun getStableIconColor(c: Context): Int = when { - tracingStatus == GeneralTracingStatus.Status.TRACING_INACTIVE -> R.color.colorTextSemanticNeutral - riskLevelScore == RiskLevelConstants.INCREASED_RISK || - riskLevelScore == RiskLevelConstants.LOW_LEVEL_RISK -> R.color.colorStableLight + isTracingOff() -> R.color.colorTextSemanticNeutral + riskState == INCREASED_RISK || riskState == LOW_RISK -> R.color.colorStableLight else -> R.color.colorTextSemanticNeutral }.let { c.getColor(it) } @@ -46,18 +48,14 @@ data class TracingCardState( * for general information when no definite risk level * can be calculated */ - fun getRiskBody(c: Context): String { - return if (tracingStatus != GeneralTracingStatus.Status.TRACING_INACTIVE) { - when (riskLevelScore) { - RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS -> R.string.risk_card_outdated_risk_body - RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF -> R.string.risk_card_body_tracing_off - RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL -> R.string.risk_card_outdated_manual_risk_body - RiskLevelConstants.UNKNOWN_RISK_NO_INTERNET -> R.string.risk_card_check_failed_no_internet_body - else -> null - }?.let { c.getString(it) } ?: "" - } else { + fun getErrorStateBody(c: Context): String { + if (isTracingOff()) { return c.getString(R.string.risk_card_body_tracing_off) } + return when (riskState) { + CALCULATION_FAILED -> c.getString(R.string.risk_card_check_failed_no_internet_body) + else -> "" + } } /** @@ -65,71 +63,67 @@ data class TracingCardState( * only in the special case where tracing is turned off and * the persisted risk level is of importance */ - @Suppress("ComplexCondition") fun getSavedRiskBody(c: Context): String { - return if (tracingStatus != GeneralTracingStatus.Status.TRACING_INACTIVE) { - return if ( - riskLevelScore == RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF || - riskLevelScore == RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS || - riskLevelScore == RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL || - riskLevelScore == RiskLevelConstants.UNKNOWN_RISK_NO_INTERNET - ) { - when (lastRiskLevelScoreCalculated) { - RiskLevelConstants.LOW_LEVEL_RISK, - RiskLevelConstants.INCREASED_RISK -> { - val arg = formatRiskLevelHeadline(c, lastRiskLevelScoreCalculated) - c.getString(R.string.risk_card_no_calculation_possible_body_saved_risk) - .format(arg) - } - else -> "" - } - } else { - "" - } - } else { - val arg = formatRiskLevelHeadline(c, lastRiskLevelScoreCalculated) - c.getString(R.string.risk_card_no_calculation_possible_body_saved_risk) - .format(arg) + // Don't display last risk when tracing is disabled + if (isTracingOff()) { + val arg = c.getString(R.string.risk_card_no_calculation_possible_headline) + return c.getString(R.string.risk_card_no_calculation_possible_body_saved_risk).format(arg) } + + // Don't have any old risk state to display + if (lastSuccessfulRiskState == CALCULATION_FAILED) { + return "" + } + + // If we failed this time, we want to display the old risk + if (riskState == CALCULATION_FAILED) { + val arg = when (lastSuccessfulRiskState) { + INCREASED_RISK -> R.string.risk_card_increased_risk_headline + LOW_RISK -> R.string.risk_card_low_risk_headline + else -> null + }?.let { c.getString(it) } ?: "" + return c.getString(R.string.risk_card_no_calculation_possible_body_saved_risk).format(arg) + } + + // We are not in an error state + return "" } /** * Formats the risk card text display of infected contacts recognized */ - fun getRiskContactBody(c: Context): String { - val resources = c.resources - return when (riskLevelScore) { - RiskLevelConstants.INCREASED_RISK -> { - if (daysWithEncounters == 0) { - c.getString(R.string.risk_card_high_risk_no_encounters_body) - } else { - resources.getQuantityString( - R.plurals.risk_card_high_risk_encounter_days_body, - daysWithEncounters, - daysWithEncounters - ) - } - } - RiskLevelConstants.LOW_LEVEL_RISK -> { - if (daysWithEncounters == 0) { - c.getString(R.string.risk_card_low_risk_no_encounters_body) - } else { - resources.getQuantityString( - R.plurals.risk_card_low_risk_encounter_days_body, - daysWithEncounters, - daysWithEncounters - ) - } - } - else -> "" + fun getRiskContactBody(c: Context): String = when { + isTracingOff() -> { + "" + } + riskState == INCREASED_RISK && daysWithEncounters == 0 -> { + c.getString(R.string.risk_card_high_risk_no_encounters_body) + } + riskState == INCREASED_RISK -> { + c.resources.getQuantityString( + R.plurals.risk_card_high_risk_encounter_days_body, + daysWithEncounters, + daysWithEncounters + ) } + riskState == LOW_RISK && daysWithEncounters == 0 -> { + c.getString(R.string.risk_card_low_risk_no_encounters_body) + } + riskState == LOW_RISK -> { + c.resources.getQuantityString( + R.plurals.risk_card_low_risk_encounter_days_body, + daysWithEncounters, + daysWithEncounters + ) + } + else -> "" } /** * Formats the risk card icon display of infected contacts recognized */ fun getRiskContactIcon(c: Context): Drawable? = c.getDrawable( - if (riskLevelScore == RiskLevelConstants.INCREASED_RISK) { + if (riskState == INCREASED_RISK) { R.drawable.ic_risk_card_contact_increased } else { R.drawable.ic_risk_card_contact @@ -141,7 +135,7 @@ data class TracingCardState( * only in the special case of increased risk as a positive contact is a * prerequisite for increased risk */ - fun getRiskContactLast(c: Context): String = if (riskLevelScore == RiskLevelConstants.INCREASED_RISK) { + fun getRiskContactLast(c: Context): String = if (riskState == INCREASED_RISK) { val formattedDate = lastEncounterAt?.toLocalDate()?.toString(DateTimeFormat.mediumDate()) c.getString(R.string.risk_card_high_risk_most_recent_body, formattedDate) } else { @@ -152,34 +146,21 @@ data class TracingCardState( * Formats the risk card text display of tracing active duration in days depending on risk level * Special case for increased risk as it is then only displayed on risk detail view */ - fun getRiskActiveTracingDaysInRetentionPeriod(c: Context): String = when (riskLevelScore) { - RiskLevelConstants.INCREASED_RISK -> { - if (showDetails) { - if (activeTracingDaysInRetentionPeriod < TimeVariables.getDefaultRetentionPeriodInDays()) { - c.getString( - R.string.risk_card_body_saved_days - ) - .format(activeTracingDaysInRetentionPeriod) - } else { - c.getString( - R.string.risk_card_body_saved_days_full - ) - } - } else { - "" - } + fun getRiskActiveTracingDaysInRetentionPeriod(c: Context): String = when { + isTracingOff() -> "" + riskState == INCREASED_RISK && !showDetails -> "" + riskState == INCREASED_RISK && activeTracingDays < TimeVariables.getDefaultRetentionPeriodInDays() -> { + c.getString(R.string.risk_card_body_saved_days).format(activeTracingDays) + } + riskState == INCREASED_RISK && activeTracingDays >= TimeVariables.getDefaultRetentionPeriodInDays() -> { + c.getString(R.string.risk_card_body_saved_days_full) + } + riskState == LOW_RISK && activeTracingDays < TimeVariables.getDefaultRetentionPeriodInDays() -> { + c.getString(R.string.risk_card_body_saved_days).format(activeTracingDays) + } + riskState == LOW_RISK && activeTracingDays >= TimeVariables.getDefaultRetentionPeriodInDays() -> { + c.getString(R.string.risk_card_body_saved_days_full) } - RiskLevelConstants.LOW_LEVEL_RISK -> - if (activeTracingDaysInRetentionPeriod < TimeVariables.getDefaultRetentionPeriodInDays()) { - c.getString( - R.string.risk_card_body_saved_days - ) - .format(activeTracingDaysInRetentionPeriod) - } else { - c.getString( - R.string.risk_card_body_saved_days_full - ) - } else -> "" } @@ -199,7 +180,7 @@ data class TracingCardState( */ */ fun getTimeFetched(c: Context): String { - if (tracingStatus == GeneralTracingStatus.Status.TRACING_INACTIVE) { + if (isTracingOff()) { return if (lastTimeDiagnosisKeysFetched != null) { c.getString( R.string.risk_card_body_time_fetched, @@ -209,9 +190,8 @@ data class TracingCardState( c.getString(R.string.risk_card_body_not_yet_fetched) } } - return when (riskLevelScore) { - RiskLevelConstants.LOW_LEVEL_RISK, - RiskLevelConstants.INCREASED_RISK -> { + return when (riskState) { + LOW_RISK, INCREASED_RISK -> { if (lastTimeDiagnosisKeysFetched != null) { c.getString( R.string.risk_card_body_time_fetched, @@ -221,13 +201,9 @@ data class TracingCardState( c.getString(R.string.risk_card_body_not_yet_fetched) } } - RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF, - RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS, - RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL, - RiskLevelConstants.UNKNOWN_RISK_NO_INTERNET -> { - when (lastRiskLevelScoreCalculated) { - RiskLevelConstants.LOW_LEVEL_RISK, - RiskLevelConstants.INCREASED_RISK -> { + CALCULATION_FAILED -> { + when (lastSuccessfulRiskState) { + LOW_RISK, INCREASED_RISK -> { if (lastTimeDiagnosisKeysFetched != null) { c.getString( R.string.risk_card_body_time_fetched, @@ -240,7 +216,6 @@ data class TracingCardState( else -> "" } } - else -> "" } } @@ -250,43 +225,36 @@ data class TracingCardState( * between colored / light / dark background */ fun getStableDividerColor(c: Context): Int = c.getColor( - if (!isTracingOffRiskLevel()) R.color.colorStableHairlineLight else R.color.colorStableHairlineDark + if (isTracingOff() || riskState == CALCULATION_FAILED) { + R.color.colorStableHairlineDark + } else { + R.color.colorStableHairlineLight + } ) /** * Formats the risk card button display for enable tracing depending on risk level and current view */ - fun showTracingButton(): Boolean = isTracingOffRiskLevel() && !showDetails + fun showTracingButton(): Boolean = isTracingOff() && !showDetails /** * Formats the risk card button display for manual updates depending on risk level, * background task setting and current view */ fun showUpdateButton(): Boolean = - !isTracingOffRiskLevel() && - (isManualKeyRetrievalEnabled || riskLevelScore == RiskLevelConstants.UNKNOWN_RISK_NO_INTERNET) && + !isTracingOff() && + (isManualKeyRetrievalEnabled || riskState == CALCULATION_FAILED) && !showDetails - fun getRiskLevelHeadline(c: Context) = formatRiskLevelHeadline(c, riskLevelScore) - - fun formatRiskLevelHeadline(c: Context, riskLevelScore: Int): String { - return if (tracingStatus != GeneralTracingStatus.Status.TRACING_INACTIVE) { - when (riskLevelScore) { - RiskLevelConstants.INCREASED_RISK -> - R.string.risk_card_increased_risk_headline - RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS, - RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL -> - R.string.risk_card_outdated_risk_headline - RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF -> - R.string.risk_card_no_calculation_possible_headline - RiskLevelConstants.LOW_LEVEL_RISK -> - R.string.risk_card_low_risk_headline - RiskLevelConstants.UNKNOWN_RISK_NO_INTERNET -> R.string.risk_card_check_failed_no_internet_headline - else -> null - }?.let { c.getString(it) } ?: "" - } else { + fun getRiskLevelHeadline(c: Context): String { + if (isTracingOff()) { return c.getString(R.string.risk_card_no_calculation_possible_headline) } + return when (riskState) { + INCREASED_RISK -> R.string.risk_card_increased_risk_headline + LOW_RISK -> R.string.risk_card_low_risk_headline + CALCULATION_FAILED -> R.string.risk_card_check_failed_no_internet_headline + }.let { c.getString(it) } } fun getProgressCardHeadline(c: Context): String = when (tracingProgress) { @@ -304,27 +272,23 @@ data class TracingCardState( fun isTracingInProgress(): Boolean = tracingProgress != TracingProgress.Idle fun getRiskInfoContainerBackgroundTint(c: Context): ColorStateList { - return if (tracingStatus != GeneralTracingStatus.Status.TRACING_INACTIVE) { - when (riskLevelScore) { - RiskLevelConstants.INCREASED_RISK -> R.color.card_increased - RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS -> R.color.card_outdated - RiskLevelConstants.LOW_LEVEL_RISK -> R.color.card_low - else -> R.color.card_no_calculation - }.let { c.getColorStateList(it) } - } else { + if (isTracingOff()) { return c.getColorStateList(R.color.card_no_calculation) } + return when (riskState) { + INCREASED_RISK -> R.color.card_increased + LOW_RISK -> R.color.card_low + CALCULATION_FAILED -> R.color.card_no_calculation + }.let { c.getColorStateList(it) } } - fun getUpdateButtonColor(c: Context): Int = when (riskLevelScore) { - RiskLevelConstants.INCREASED_RISK, - RiskLevelConstants.LOW_LEVEL_RISK -> R.color.colorStableLight + fun getUpdateButtonColor(c: Context): Int = when (riskState) { + INCREASED_RISK, LOW_RISK -> R.color.colorStableLight else -> R.color.colorAccentTintButton }.let { c.getColor(it) } - fun getUpdateButtonTextColor(c: Context): Int = when (riskLevelScore) { - RiskLevelConstants.INCREASED_RISK, - RiskLevelConstants.LOW_LEVEL_RISK -> R.color.colorTextPrimary1Stable + fun getUpdateButtonTextColor(c: Context): Int = when (riskState) { + INCREASED_RISK, LOW_RISK -> R.color.colorTextPrimary1Stable else -> R.color.colorTextPrimary1InvertedStable }.let { c.getColor(it) } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/card/TracingCardStateProvider.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/card/TracingCardStateProvider.kt index f843a6970daef739f4bf47054c2b8c31f498ff53..1f8e51ee7dc53a2824e8f09ea6d83f56faa31ab6 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/card/TracingCardStateProvider.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/card/TracingCardStateProvider.kt @@ -1,8 +1,8 @@ package de.rki.coronawarnapp.ui.tracing.card import dagger.Reusable +import de.rki.coronawarnapp.risk.RiskState import de.rki.coronawarnapp.risk.storage.RiskLevelStorage -import de.rki.coronawarnapp.storage.SettingsRepository import de.rki.coronawarnapp.storage.TracingRepository import de.rki.coronawarnapp.tracing.GeneralTracingStatus import de.rki.coronawarnapp.ui.tracing.common.tryLatestResultsWithDefaults @@ -19,7 +19,6 @@ import javax.inject.Inject class TracingCardStateProvider @Inject constructor( tracingStatus: GeneralTracingStatus, backgroundModeStatus: BackgroundModeStatus, - settingsRepository: SettingsRepository, tracingRepository: TracingRepository, riskLevelStorage: RiskLevelStorage ) { @@ -50,18 +49,23 @@ class TracingCardStateProvider @Inject constructor( lastTimeDiagnosisKeysFetched, isBackgroundJobEnabled -> - val (latestCalc, latestSuccessfulCalc) = riskLevelResults.tryLatestResultsWithDefaults() + val ( + latestCalc, + latestSuccessfulCalc + ) = riskLevelResults.tryLatestResultsWithDefaults() + + val isRestartButtonEnabled = !isBackgroundJobEnabled || latestCalc.riskState == RiskState.CALCULATION_FAILED TracingCardState( tracingStatus = status, - riskLevelScore = latestCalc.riskLevel.raw, + riskState = latestCalc.riskState, tracingProgress = tracingProgress, - lastRiskLevelScoreCalculated = latestSuccessfulCalc.riskLevel.raw, + lastSuccessfulRiskState = latestSuccessfulCalc.riskState, lastTimeDiagnosisKeysFetched = lastTimeDiagnosisKeysFetched, daysWithEncounters = latestCalc.daysWithEncounters, lastEncounterAt = latestCalc.lastRiskEncounterAt, - activeTracingDaysInRetentionPeriod = activeTracingDaysInRetentionPeriod, - isManualKeyRetrievalEnabled = !isBackgroundJobEnabled + activeTracingDays = activeTracingDaysInRetentionPeriod, + isManualKeyRetrievalEnabled = isRestartButtonEnabled ) } .onStart { Timber.v("TracingCardState FLOW start") } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/common/BaseTracingState.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/common/BaseTracingState.kt index a87f4267c1c87cefd14a9171515e3b91d0165b8c..23cf72ada6439be8d7a0d11fbf91ef045cdb5cd9 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/common/BaseTracingState.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/common/BaseTracingState.kt @@ -2,13 +2,13 @@ package de.rki.coronawarnapp.ui.tracing.common import android.content.Context import de.rki.coronawarnapp.R -import de.rki.coronawarnapp.risk.RiskLevelConstants +import de.rki.coronawarnapp.risk.RiskState import de.rki.coronawarnapp.tracing.GeneralTracingStatus import de.rki.coronawarnapp.tracing.TracingProgress abstract class BaseTracingState { abstract val tracingStatus: GeneralTracingStatus.Status - abstract val riskLevelScore: Int + abstract val riskState: RiskState abstract val tracingProgress: TracingProgress abstract val showDetails: Boolean // Only true for riskdetailsfragment abstract val isManualKeyRetrievalEnabled: Boolean @@ -18,39 +18,28 @@ abstract class BaseTracingState { */ fun getRiskColor(c: Context): Int = when { tracingStatus == GeneralTracingStatus.Status.TRACING_INACTIVE -> R.color.colorSemanticUnknownRisk - riskLevelScore == RiskLevelConstants.INCREASED_RISK -> R.color.colorSemanticHighRisk - riskLevelScore == RiskLevelConstants.LOW_LEVEL_RISK -> R.color.colorSemanticLowRisk + riskState == RiskState.INCREASED_RISK -> R.color.colorSemanticHighRisk + riskState == RiskState.LOW_RISK -> R.color.colorSemanticLowRisk else -> R.color.colorSemanticUnknownRisk }.let { c.getColor(it) } - fun isTracingOffRiskLevel(): Boolean { - return if (tracingStatus != GeneralTracingStatus.Status.TRACING_INACTIVE) { - when (riskLevelScore) { - RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF, - RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS -> true - else -> false - } - } else { - return true - } - } + fun isTracingOff(): Boolean = tracingStatus == GeneralTracingStatus.Status.TRACING_INACTIVE fun getStableTextColor(c: Context): Int = when { - tracingStatus == GeneralTracingStatus.Status.TRACING_INACTIVE -> R.color.colorTextPrimary1 - riskLevelScore == RiskLevelConstants.INCREASED_RISK || - riskLevelScore == RiskLevelConstants.LOW_LEVEL_RISK -> R.color.colorTextPrimary1InvertedStable - else -> R.color.colorTextPrimary1 - }.let { c.getColor(it) } + tracingStatus == GeneralTracingStatus.Status.TRACING_INACTIVE -> R.color.colorTextPrimary1 + riskState == RiskState.INCREASED_RISK || + riskState == RiskState.LOW_RISK -> R.color.colorTextPrimary1InvertedStable + else -> R.color.colorTextPrimary1 + }.let { c.getColor(it) } /** * Change the manual update button text according to current timer */ - fun getUpdateButtonText(c: Context): String = if (riskLevelScore == RiskLevelConstants.UNKNOWN_RISK_NO_INTERNET) { + fun getUpdateButtonText(c: Context): String = if (riskState == RiskState.CALCULATION_FAILED) { c.getString(R.string.risk_card_check_failed_no_internet_restart_button) } else { c.getString(R.string.risk_card_button_update) } - fun isUpdateButtonEnabled(): Boolean = isManualKeyRetrievalEnabled || - riskLevelScore == RiskLevelConstants.UNKNOWN_RISK_NO_INTERNET + fun isUpdateButtonEnabled(): Boolean = isManualKeyRetrievalEnabled } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/common/RiskLevelExtensions.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/common/RiskLevelResultExtensions.kt similarity index 90% rename from Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/common/RiskLevelExtensions.kt rename to Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/common/RiskLevelResultExtensions.kt index a5c15ffa856cb8b0c59e0ae141c31b269d5881b1..4087bedf49fde363e3046d127193f4dc28e5adb6 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/common/RiskLevelExtensions.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/common/RiskLevelResultExtensions.kt @@ -1,8 +1,8 @@ package de.rki.coronawarnapp.ui.tracing.common import com.google.android.gms.nearby.exposurenotification.ExposureWindow -import de.rki.coronawarnapp.risk.RiskLevel import de.rki.coronawarnapp.risk.RiskLevelResult +import de.rki.coronawarnapp.risk.RiskState import de.rki.coronawarnapp.risk.result.AggregatedRiskResult import org.joda.time.Instant @@ -26,7 +26,7 @@ data class DisplayableRiskResults( private object InitialLowLevelRiskLevelResult : RiskLevelResult { override val calculatedAt: Instant = Instant.now() - override val riskLevel: RiskLevel = RiskLevel.LOW_LEVEL_RISK + override val riskState: RiskState = RiskState.LOW_RISK override val failureReason: RiskLevelResult.FailureReason? = null override val aggregatedRiskResult: AggregatedRiskResult? = null override val exposureWindows: List<ExposureWindow>? = null @@ -36,7 +36,7 @@ private object InitialLowLevelRiskLevelResult : RiskLevelResult { private object UndeterminedRiskLevelResult : RiskLevelResult { override val calculatedAt: Instant = Instant.EPOCH - override val riskLevel: RiskLevel = RiskLevel.UNDETERMINED + override val riskState: RiskState = RiskState.CALCULATION_FAILED override val failureReason: RiskLevelResult.FailureReason? = null override val aggregatedRiskResult: AggregatedRiskResult? = null override val exposureWindows: List<ExposureWindow>? = null diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/details/DefaultRiskDetailPresenter.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/details/DefaultRiskDetailPresenter.kt index 6ff94bb2b4bf27508702ed9dd645883557bdf72d..3369797d05cc72a0276af2cbec365985365b4e9f 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/details/DefaultRiskDetailPresenter.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/details/DefaultRiskDetailPresenter.kt @@ -1,15 +1,14 @@ package de.rki.coronawarnapp.ui.tracing.details import dagger.Reusable -import de.rki.coronawarnapp.risk.RiskLevelConstants +import de.rki.coronawarnapp.risk.RiskState import javax.inject.Inject @Reusable class DefaultRiskDetailPresenter @Inject constructor() { - fun isAdditionalInfoVisible(riskLevel: Int, matchedKeyCount: Int) = - riskLevel == RiskLevelConstants.LOW_LEVEL_RISK && matchedKeyCount > 0 + fun isAdditionalInfoVisible(riskState: RiskState, matchedKeyCount: Int) = + riskState == RiskState.LOW_RISK && matchedKeyCount > 0 - fun isInformationBodyNoticeVisible(riskLevel: Int) = - riskLevel != RiskLevelConstants.LOW_LEVEL_RISK + fun isInformationBodyNoticeVisible(riskState: RiskState) = riskState != RiskState.LOW_RISK } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/details/TracingDetailsState.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/details/TracingDetailsState.kt index 2cebeea8246629f8176c2e6b8a9e4dfec0d3375b..a20d89855a8f87d8d2f4722b392fb5c93e0abc2e 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/details/TracingDetailsState.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/details/TracingDetailsState.kt @@ -2,14 +2,17 @@ package de.rki.coronawarnapp.ui.tracing.details import android.content.Context import de.rki.coronawarnapp.R -import de.rki.coronawarnapp.risk.RiskLevelConstants +import de.rki.coronawarnapp.risk.RiskState +import de.rki.coronawarnapp.risk.RiskState.CALCULATION_FAILED +import de.rki.coronawarnapp.risk.RiskState.INCREASED_RISK +import de.rki.coronawarnapp.risk.RiskState.LOW_RISK import de.rki.coronawarnapp.tracing.GeneralTracingStatus import de.rki.coronawarnapp.tracing.TracingProgress import de.rki.coronawarnapp.ui.tracing.common.BaseTracingState data class TracingDetailsState( override val tracingStatus: GeneralTracingStatus.Status, - override val riskLevelScore: Int, + override val riskState: RiskState, override val tracingProgress: TracingProgress, val matchedKeyCount: Int, val activeTracingDaysInRetentionPeriod: Long, @@ -26,28 +29,26 @@ data class TracingDetailsState( * in all cases when risk level is not increased */ fun isBehaviorNormalVisible(): Boolean = - riskLevelScore != RiskLevelConstants.INCREASED_RISK + riskState != INCREASED_RISK /** * Format the risk details include display for suggested behavior depending on risk level * Only applied in special case for increased risk */ fun isBehaviorIncreasedRiskVisible(): Boolean = - riskLevelScore == RiskLevelConstants.INCREASED_RISK + riskState == INCREASED_RISK /** * Format the risk details period logged card display depending on risk level * applied in case of low and high risk levels */ - fun isBehaviorPeriodLoggedVisible(): Boolean = - riskLevelScore == RiskLevelConstants.INCREASED_RISK || riskLevelScore == RiskLevelConstants.LOW_LEVEL_RISK + fun isBehaviorPeriodLoggedVisible(): Boolean = riskState == INCREASED_RISK || riskState == LOW_RISK /** * Format the risk details include display for suggested behavior depending on risk level * Only applied in special case for low level risk */ - fun isBehaviorLowLevelRiskVisible(): Boolean = - riskLevelScore == RiskLevelConstants.LOW_LEVEL_RISK && matchedKeyCount > 0 + fun isBehaviorLowLevelRiskVisible(): Boolean = riskState == LOW_RISK && matchedKeyCount > 0 /** * Formats the risk details text display for each risk level @@ -56,48 +57,41 @@ data class TracingDetailsState( val resources = c.resources val days = daysSinceLastExposure val count = matchedKeyCount - return when (riskLevelScore) { - RiskLevelConstants.INCREASED_RISK -> - resources.getQuantityString( - R.plurals.risk_details_information_body_increased_risk, - days, - days - ) - RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS -> - c.getString(R.string.risk_details_information_body_outdated_risk) - RiskLevelConstants.LOW_LEVEL_RISK -> - c.getString( - if (count > 0) R.string.risk_details_information_body_low_risk_with_encounter - else R.string.risk_details_information_body_low_risk - ) - else -> "" + return when (riskState) { + INCREASED_RISK -> resources.getQuantityString( + R.plurals.risk_details_information_body_increased_risk, + days, + days + ) + CALCULATION_FAILED -> c.getString(R.string.risk_details_information_body_outdated_risk) + LOW_RISK -> c.getString( + if (count > 0) R.string.risk_details_information_body_low_risk_with_encounter + else R.string.risk_details_information_body_low_risk + ) } } /** * Formats the risk details text display for each risk level for the body notice */ - fun getRiskDetailsRiskLevelBodyNotice(c: Context): String = when (riskLevelScore) { - RiskLevelConstants.INCREASED_RISK -> R.string.risk_details_information_body_notice_increased + fun getRiskDetailsRiskLevelBodyNotice(c: Context): String = when (riskState) { + INCREASED_RISK -> R.string.risk_details_information_body_notice_increased else -> R.string.risk_details_information_body_notice }.let { c.getString(it) } - /** - * Formats the risk details button display for enable tracing depending on risk level - */ - fun areRiskDetailsButtonsVisible(): Boolean = - isRiskDetailsEnableTracingButtonVisible() || isRiskDetailsUpdateButtonVisible() + fun isRiskLevelButtonGroupVisible(): Boolean = isRiskDetailsEnableTracingButtonVisible() || + isRiskDetailsUpdateButtonVisible() /** * Formats the risk details button display for enable tracing depending on risk level */ - fun isRiskDetailsEnableTracingButtonVisible(): Boolean = isTracingOffRiskLevel() + fun isRiskDetailsEnableTracingButtonVisible(): Boolean = isTracingOff() /** * Formats the risk details button display for manual updates depending on risk level and * background task setting */ - fun isRiskDetailsUpdateButtonVisible(): Boolean = !isTracingOffRiskLevel() && isManualKeyRetrievalEnabled + fun isRiskDetailsUpdateButtonVisible(): Boolean = !isTracingOff() && isManualKeyRetrievalEnabled /** * Formats the risk logged period card text display of tracing active duration in days depending on risk level @@ -108,9 +102,8 @@ data class TracingDetailsState( ).format(activeTracingDaysInRetentionPeriod) fun getBehaviorIcon(context: Context) = when { - tracingStatus != GeneralTracingStatus.Status.TRACING_ACTIVE -> R.color.colorTextSemanticNeutral - riskLevelScore == RiskLevelConstants.INCREASED_RISK || - riskLevelScore == RiskLevelConstants.LOW_LEVEL_RISK -> R.color.colorStableLight + isTracingOff() -> R.color.colorTextSemanticNeutral + riskState == INCREASED_RISK || riskState == LOW_RISK -> R.color.colorStableLight else -> R.color.colorTextSemanticNeutral }.let { context.getColor(it) } @@ -121,9 +114,9 @@ data class TracingDetailsState( * @return */ fun getBehaviorIconBackground(context: Context) = when { - tracingStatus != GeneralTracingStatus.Status.TRACING_ACTIVE -> R.color.colorSurface2 - riskLevelScore == RiskLevelConstants.INCREASED_RISK -> R.color.colorSemanticHighRisk - riskLevelScore == RiskLevelConstants.LOW_LEVEL_RISK -> R.color.colorSemanticLowRisk + isTracingOff() -> R.color.colorSurface2 + riskState == INCREASED_RISK -> R.color.colorSemanticHighRisk + riskState == LOW_RISK -> R.color.colorSemanticLowRisk else -> R.color.colorSurface2 }.let { context.getColor(it) } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/details/TracingDetailsStateProvider.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/details/TracingDetailsStateProvider.kt index 2648093aee1fa1d6171ee4d2b691b0d03efdb9f0..ad2a48f630657c8fd63ced416f1fcefb2a6f4e47 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/details/TracingDetailsStateProvider.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/details/TracingDetailsStateProvider.kt @@ -1,6 +1,7 @@ package de.rki.coronawarnapp.ui.tracing.details import dagger.Reusable +import de.rki.coronawarnapp.risk.RiskState import de.rki.coronawarnapp.risk.storage.RiskLevelStorage import de.rki.coronawarnapp.storage.TracingRepository import de.rki.coronawarnapp.tracing.GeneralTracingStatus @@ -38,20 +39,22 @@ class TracingDetailsStateProvider @Inject constructor( val (latestCalc, latestSuccessfulCalc) = riskLevelResults.tryLatestResultsWithDefaults() val isAdditionalInformationVisible = riskDetailPresenter.isAdditionalInfoVisible( - latestCalc.riskLevel.raw, latestCalc.matchedKeyCount + latestCalc.riskState, latestCalc.matchedKeyCount ) val isInformationBodyNoticeVisible = riskDetailPresenter.isInformationBodyNoticeVisible( - latestCalc.riskLevel.raw + latestCalc.riskState ) + val isRestartButtonEnabled = !isBackgroundJobEnabled || latestCalc.riskState == RiskState.CALCULATION_FAILED + TracingDetailsState( tracingStatus = status, - riskLevelScore = latestCalc.riskLevel.raw, + riskState = latestCalc.riskState, tracingProgress = tracingProgress, matchedKeyCount = latestCalc.matchedKeyCount, daysSinceLastExposure = latestCalc.daysWithEncounters, activeTracingDaysInRetentionPeriod = activeTracingDaysInRetentionPeriod, - isManualKeyRetrievalEnabled = !isBackgroundJobEnabled, + isManualKeyRetrievalEnabled = isRestartButtonEnabled, isAdditionalInformationVisible = isAdditionalInformationVisible, isInformationBodyNoticeVisible = isInformationBodyNoticeVisible ) diff --git a/Corona-Warn-App/src/main/res/layout/fragment_risk_details.xml b/Corona-Warn-App/src/main/res/layout/fragment_risk_details.xml index b2248af9e91c92aa79909b8c7c3aa78d36bee227..a8c3cd2329d000e1b34429d732f4b9ded478baae 100644 --- a/Corona-Warn-App/src/main/res/layout/fragment_risk_details.xml +++ b/Corona-Warn-App/src/main/res/layout/fragment_risk_details.xml @@ -108,6 +108,7 @@ android:background="@drawable/rectangle" android:backgroundTint="@{tracingCard.getRiskInfoContainerBackgroundTint(context)}" android:backgroundTintMode="src_over" + android:elevation="@dimen/spacing_tiny" android:padding="@dimen/spacing_normal" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -309,7 +310,7 @@ android:paddingTop="@dimen/spacing_small" android:paddingEnd="@dimen/spacing_normal" android:paddingBottom="@dimen/spacing_small" - gone="@{!tracingDetails.areRiskDetailsButtonsVisible()}" + gone="@{!tracingDetails.isRiskLevelButtonGroupVisible()}" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"> diff --git a/Corona-Warn-App/src/main/res/layout/include_risk_card_content.xml b/Corona-Warn-App/src/main/res/layout/include_risk_card_content.xml index c8f610201bc23b5160be651c16edb83be3c782f9..5789d905d90bf2a3c5228c3f37acce081bc5dd46 100644 --- a/Corona-Warn-App/src/main/res/layout/include_risk_card_content.xml +++ b/Corona-Warn-App/src/main/res/layout/include_risk_card_content.xml @@ -35,7 +35,7 @@ android:layout_marginEnd="16dp" android:accessibilityHeading="true" android:text="@{tracingCard.getProgressCardHeadline(context)}" - android:textColor="@color/colorStableLight" + android:textColor="@{tracingCard.getStableTextColor(context)}" app:layout_constraintEnd_toStartOf="@+id/risk_card_progress_headline_icon" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" @@ -49,7 +49,7 @@ android:layout_height="@dimen/icon_size_risk_card" android:importantForAccessibility="no" android:src="@drawable/ic_forward" - android:tint="@color/colorStableLight" + android:tint="@{tracingCard.getStableIconColor(context)}" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -59,19 +59,20 @@ android:layout_width="36dp" android:layout_height="36dp" android:indeterminate="true" - app:layout_constraintBottom_toBottomOf="@+id/textView2" + android:indeterminateTint="@{tracingCard.getStableIconColor(context)}" + app:layout_constraintBottom_toBottomOf="@+id/risk_card_progress_body" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="@+id/textView2" /> + app:layout_constraintTop_toTopOf="@+id/risk_card_progress_body" /> <TextView - android:id="@+id/textView2" + android:id="@+id/risk_card_progress_body" style="@style/subtitle" android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" android:layout_marginStart="@dimen/spacing_small" android:layout_marginTop="24dp" android:text="@{tracingCard.getProgressCardBody(context)}" - android:textColor="@color/colorStableLight" + android:textColor="@{tracingCard.getStableTextColor(context)}" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/risk_card_progress_indicator" @@ -117,11 +118,11 @@ <TextView android:id="@+id/risk_card_body" style="@style/subtitle" - gone="@{tracingCard.getRiskBody(context).empty}" + gone="@{tracingCard.getErrorStateBody(context).empty}" android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" android:layout_marginTop="@dimen/spacing_normal" - android:text="@{tracingCard.getRiskBody(context)}" + android:text="@{tracingCard.getErrorStateBody(context)}" android:textColor="@{tracingCard.getStableTextColor(context)}" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -195,7 +196,7 @@ app:layout_constraintBottom_toBottomOf="@+id/risk_card_row_saved_days_body" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/risk_card_row_saved_days_body" - app:progress="@{tracingCard.activeTracingDaysInRetentionPeriod}" + app:progress="@{tracingCard.activeTracingDays}" app:progressColor="@color/colorStableLight" /> <TextView diff --git a/Corona-Warn-App/src/main/res/layout/include_submission_done_content.xml b/Corona-Warn-App/src/main/res/layout/include_submission_done_content.xml index 0b91a3732a6c9d7ac23aad831a166dedb0b9b175..dbe51a20c99baba7cf484a2041fe4681cf5d2c35 100644 --- a/Corona-Warn-App/src/main/res/layout/include_submission_done_content.xml +++ b/Corona-Warn-App/src/main/res/layout/include_submission_done_content.xml @@ -3,9 +3,6 @@ xmlns:app="http://schemas.android.com/apk/res-auto"> <data> - - <import type="de.rki.coronawarnapp.risk.RiskLevelConstants" /> - <variable name="illustrationDescription" type="String" /> diff --git a/Corona-Warn-App/src/main/res/layout/include_submission_status_card_positive.xml b/Corona-Warn-App/src/main/res/layout/include_submission_status_card_positive.xml index 6d30aae4a6c1045abd8778491687d7531ae2129f..e10fd40921c3cf0fb810bedd9bc9a85aa855cb5c 100644 --- a/Corona-Warn-App/src/main/res/layout/include_submission_status_card_positive.xml +++ b/Corona-Warn-App/src/main/res/layout/include_submission_status_card_positive.xml @@ -2,10 +2,6 @@ <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> - <data> - <import type="de.rki.coronawarnapp.risk.RiskLevelConstants" /> - </data> - <androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/submission_status_card_positive" style="@style/card" diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelChangeDetectorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelChangeDetectorTest.kt index 37e6cd26854d8b8f7130f7f94c74198c49ef6a4f..f8b9208074742faf6ea029954917c843f2c99424 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelChangeDetectorTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelChangeDetectorTest.kt @@ -3,9 +3,9 @@ package de.rki.coronawarnapp.risk import android.content.Context import androidx.core.app.NotificationManagerCompat import com.google.android.gms.nearby.exposurenotification.ExposureWindow -import de.rki.coronawarnapp.risk.RiskLevel.INCREASED_RISK -import de.rki.coronawarnapp.risk.RiskLevel.LOW_LEVEL_RISK -import de.rki.coronawarnapp.risk.RiskLevel.UNDETERMINED +import de.rki.coronawarnapp.risk.RiskState.CALCULATION_FAILED +import de.rki.coronawarnapp.risk.RiskState.INCREASED_RISK +import de.rki.coronawarnapp.risk.RiskState.LOW_RISK import de.rki.coronawarnapp.risk.result.AggregatedRiskResult import de.rki.coronawarnapp.risk.storage.RiskLevelStorage import de.rki.coronawarnapp.storage.LocalData @@ -59,10 +59,10 @@ class RiskLevelChangeDetectorTest : BaseTest() { } private fun createRiskLevel( - riskLevel: RiskLevel, + riskState: RiskState, calculatedAt: Instant = Instant.EPOCH ): RiskLevelResult = object : RiskLevelResult { - override val riskLevel: RiskLevel = riskLevel + override val riskState: RiskState = riskState override val calculatedAt: Instant = calculatedAt override val aggregatedRiskResult: AggregatedRiskResult? = null override val failureReason: RiskLevelResult.FailureReason? = null @@ -82,7 +82,7 @@ class RiskLevelChangeDetectorTest : BaseTest() { @Test fun `nothing happens if there is only one result yet`() { - every { riskLevelStorage.riskLevelResults } returns flowOf(listOf(createRiskLevel(LOW_LEVEL_RISK))) + every { riskLevelStorage.riskLevelResults } returns flowOf(listOf(createRiskLevel(LOW_RISK))) runBlockingTest { val instance = createInstance(scope = this) @@ -101,8 +101,8 @@ class RiskLevelChangeDetectorTest : BaseTest() { fun `no risklevel change, nothing should happen`() { every { riskLevelStorage.riskLevelResults } returns flowOf( listOf( - createRiskLevel(LOW_LEVEL_RISK), - createRiskLevel(LOW_LEVEL_RISK) + createRiskLevel(LOW_RISK), + createRiskLevel(LOW_RISK) ) ) @@ -123,7 +123,7 @@ class RiskLevelChangeDetectorTest : BaseTest() { fun `risklevel went from HIGH to LOW`() { every { riskLevelStorage.riskLevelResults } returns flowOf( listOf( - createRiskLevel(LOW_LEVEL_RISK, calculatedAt = Instant.EPOCH.plus(1)), + createRiskLevel(LOW_RISK, calculatedAt = Instant.EPOCH.plus(1)), createRiskLevel(INCREASED_RISK, calculatedAt = Instant.EPOCH) ) ) @@ -147,7 +147,7 @@ class RiskLevelChangeDetectorTest : BaseTest() { every { riskLevelStorage.riskLevelResults } returns flowOf( listOf( createRiskLevel(INCREASED_RISK, calculatedAt = Instant.EPOCH.plus(1)), - createRiskLevel(LOW_LEVEL_RISK, calculatedAt = Instant.EPOCH) + createRiskLevel(LOW_RISK, calculatedAt = Instant.EPOCH) ) ) @@ -169,7 +169,7 @@ class RiskLevelChangeDetectorTest : BaseTest() { every { riskLevelStorage.riskLevelResults } returns flowOf( listOf( createRiskLevel(INCREASED_RISK, calculatedAt = Instant.EPOCH.plus(1)), - createRiskLevel(LOW_LEVEL_RISK, calculatedAt = Instant.EPOCH) + createRiskLevel(LOW_RISK, calculatedAt = Instant.EPOCH) ) ) every { riskLevelSettings.lastChangeCheckedRiskLevelTimestamp } returns Instant.EPOCH.plus(1) @@ -189,12 +189,12 @@ class RiskLevelChangeDetectorTest : BaseTest() { @Test fun `evaluate risk level change detection function`() { - RiskLevelChangeDetector.hasHighLowLevelChanged(UNDETERMINED, UNDETERMINED) shouldBe false - RiskLevelChangeDetector.hasHighLowLevelChanged(LOW_LEVEL_RISK, LOW_LEVEL_RISK) shouldBe false + RiskLevelChangeDetector.hasHighLowLevelChanged(CALCULATION_FAILED, CALCULATION_FAILED) shouldBe false + RiskLevelChangeDetector.hasHighLowLevelChanged(LOW_RISK, LOW_RISK) shouldBe false RiskLevelChangeDetector.hasHighLowLevelChanged(INCREASED_RISK, INCREASED_RISK) shouldBe false - RiskLevelChangeDetector.hasHighLowLevelChanged(INCREASED_RISK, LOW_LEVEL_RISK) shouldBe true - RiskLevelChangeDetector.hasHighLowLevelChanged(LOW_LEVEL_RISK, INCREASED_RISK) shouldBe true - RiskLevelChangeDetector.hasHighLowLevelChanged(UNDETERMINED, INCREASED_RISK) shouldBe true - RiskLevelChangeDetector.hasHighLowLevelChanged(INCREASED_RISK, UNDETERMINED) shouldBe true + RiskLevelChangeDetector.hasHighLowLevelChanged(INCREASED_RISK, LOW_RISK) shouldBe true + RiskLevelChangeDetector.hasHighLowLevelChanged(LOW_RISK, INCREASED_RISK) shouldBe true + RiskLevelChangeDetector.hasHighLowLevelChanged(CALCULATION_FAILED, INCREASED_RISK) shouldBe true + RiskLevelChangeDetector.hasHighLowLevelChanged(INCREASED_RISK, CALCULATION_FAILED) shouldBe true } } diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelConstantsTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelConstantsTest.kt deleted file mode 100644 index 13099654b65191a0440e5d5f633e6ae6c70d262d..0000000000000000000000000000000000000000 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelConstantsTest.kt +++ /dev/null @@ -1,16 +0,0 @@ -package de.rki.coronawarnapp.risk - -import org.junit.Assert -import org.junit.Test - -class RiskLevelConstantsTest { - - @Test - fun allRiskLevelConstants() { - Assert.assertEquals(RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF, 1) - Assert.assertEquals(RiskLevelConstants.LOW_LEVEL_RISK, 2) - Assert.assertEquals(RiskLevelConstants.INCREASED_RISK, 3) - Assert.assertEquals(RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS, 4) - Assert.assertEquals(RiskLevelConstants.UNDETERMINED, 9001) - } -} diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelTest.kt deleted file mode 100644 index d57c2ac12afffa9da6cc47c721f52c5cfcb618f3..0000000000000000000000000000000000000000 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelTest.kt +++ /dev/null @@ -1,19 +0,0 @@ -package de.rki.coronawarnapp.risk - -import org.junit.Assert.assertEquals -import org.junit.Test - -class RiskLevelTest { - - @Test - fun testEnum() { - assertEquals( - RiskLevel.NO_CALCULATION_POSSIBLE_TRACING_OFF.raw, - RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF - ) - assertEquals(RiskLevel.LOW_LEVEL_RISK.raw, RiskLevelConstants.LOW_LEVEL_RISK) - assertEquals(RiskLevel.INCREASED_RISK.raw, RiskLevelConstants.INCREASED_RISK) - assertEquals(RiskLevel.UNKNOWN_RISK_OUTDATED_RESULTS.raw, RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS) - assertEquals(RiskLevel.UNDETERMINED.raw, RiskLevelConstants.UNDETERMINED) - } -} diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/internal/PersistedRiskResultDaoTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/internal/PersistedRiskResultDaoTest.kt index 682310435afa9b8ac41fc2d24aeb15d282a37812..51adcacd6ddef65210794636c93bcf0586a6648b 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/internal/PersistedRiskResultDaoTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/internal/PersistedRiskResultDaoTest.kt @@ -1,7 +1,7 @@ package de.rki.coronawarnapp.risk.storage.internal -import de.rki.coronawarnapp.risk.RiskLevel import de.rki.coronawarnapp.risk.RiskLevelResult +import de.rki.coronawarnapp.risk.RiskState import de.rki.coronawarnapp.risk.storage.RiskStorageTestData.testExposureWindow import de.rki.coronawarnapp.risk.storage.RiskStorageTestData.testExposureWindowDaoWrapper import de.rki.coronawarnapp.risk.storage.internal.riskresults.PersistedRiskLevelResultDao @@ -30,7 +30,7 @@ class PersistedRiskResultDaoTest : BaseTest() { numberOfDaysWithHighRisk = 81 ) ).toRiskResult(listOf(testExposureWindowDaoWrapper)).apply { - riskLevel shouldBe RiskLevel.LOW_LEVEL_RISK + riskState shouldBe RiskState.LOW_RISK calculatedAt.millis shouldBe 931161601L exposureWindows shouldBe listOf(testExposureWindow) failureReason shouldBe null @@ -65,7 +65,7 @@ class PersistedRiskResultDaoTest : BaseTest() { numberOfDaysWithHighRisk = 81 ) ).toRiskResult().apply { - riskLevel shouldBe RiskLevel.LOW_LEVEL_RISK + riskState shouldBe RiskState.LOW_RISK calculatedAt.millis shouldBe 931161601L exposureWindows shouldBe null failureReason shouldBe null @@ -92,7 +92,7 @@ class PersistedRiskResultDaoTest : BaseTest() { failureReason = RiskLevelResult.FailureReason.TRACING_OFF, aggregatedRiskResult = null ).toRiskResult().apply { - riskLevel shouldBe RiskLevel.NO_CALCULATION_POSSIBLE_TRACING_OFF + riskState shouldBe RiskState.CALCULATION_FAILED calculatedAt.millis shouldBe 931161601L exposureWindows shouldBe null failureReason shouldBe RiskLevelResult.FailureReason.TRACING_OFF diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/legacy/RiskLevelResultMigratorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/legacy/RiskLevelResultMigratorTest.kt index 955a8c9083e84f849f961ca8c5f20d007655f9e9..453bde1aa8e43131120df75ff2854a59eca99c08 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/legacy/RiskLevelResultMigratorTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/legacy/RiskLevelResultMigratorTest.kt @@ -1,8 +1,7 @@ package de.rki.coronawarnapp.risk.storage.legacy import androidx.core.content.edit -import de.rki.coronawarnapp.risk.RiskLevel -import de.rki.coronawarnapp.risk.RiskLevelConstants +import de.rki.coronawarnapp.risk.RiskState import de.rki.coronawarnapp.util.TimeStamper import io.kotest.matchers.shouldBe import io.mockk.MockKAnnotations @@ -41,18 +40,18 @@ class RiskLevelResultMigratorTest : BaseTest() { @Test fun `normal case with full values`() { mockPreferences.edit { - putInt("preference_risk_level_score", RiskLevel.INCREASED_RISK.raw) - putInt("preference_risk_level_score_successful", RiskLevel.LOW_LEVEL_RISK.raw) + putInt("preference_risk_level_score", MigrationRiskLevelConstants.INCREASED_RISK) + putInt("preference_risk_level_score_successful", MigrationRiskLevelConstants.LOW_LEVEL_RISK) putLong("preference_timestamp_risk_level_calculation", 1234567890L) } createInstance().apply { val legacyResults = getLegacyResults() legacyResults[0].apply { - riskLevel shouldBe RiskLevel.INCREASED_RISK + riskState shouldBe RiskState.INCREASED_RISK calculatedAt shouldBe Instant.ofEpochMilli(1234567890L) } legacyResults[1].apply { - riskLevel shouldBe RiskLevel.LOW_LEVEL_RISK + riskState shouldBe RiskState.LOW_RISK calculatedAt shouldBe Instant.EPOCH.plus(1337) } } @@ -67,17 +66,17 @@ class RiskLevelResultMigratorTest : BaseTest() { @Test fun `if no timestamp is available we use the current time`() { mockPreferences.edit { - putInt("preference_risk_level_score", RiskLevel.INCREASED_RISK.raw) - putInt("preference_risk_level_score_successful", RiskLevel.LOW_LEVEL_RISK.raw) + putInt("preference_risk_level_score", MigrationRiskLevelConstants.INCREASED_RISK) + putInt("preference_risk_level_score_successful", MigrationRiskLevelConstants.LOW_LEVEL_RISK) } createInstance().apply { val legacyResults = getLegacyResults() legacyResults[0].apply { - riskLevel shouldBe RiskLevel.INCREASED_RISK + riskState shouldBe RiskState.INCREASED_RISK calculatedAt shouldBe Instant.EPOCH.plus(1337) } legacyResults[1].apply { - riskLevel shouldBe RiskLevel.LOW_LEVEL_RISK + riskState shouldBe RiskState.LOW_RISK calculatedAt shouldBe Instant.EPOCH.plus(1337) } } @@ -86,13 +85,13 @@ class RiskLevelResultMigratorTest : BaseTest() { @Test fun `last successful is null`() { mockPreferences.edit { - putInt("preference_risk_level_score_successful", RiskLevel.INCREASED_RISK.raw) + putInt("preference_risk_level_score_successful", MigrationRiskLevelConstants.INCREASED_RISK) } createInstance().apply { val legacyResults = getLegacyResults() legacyResults.size shouldBe 1 legacyResults.first().apply { - riskLevel shouldBe RiskLevel.INCREASED_RISK + riskState shouldBe RiskState.INCREASED_RISK calculatedAt shouldBe Instant.EPOCH.plus(1337) } } @@ -101,14 +100,14 @@ class RiskLevelResultMigratorTest : BaseTest() { @Test fun `last successfully calculated is null`() { mockPreferences.edit { - putInt("preference_risk_level_score", RiskLevel.INCREASED_RISK.raw) + putInt("preference_risk_level_score", MigrationRiskLevelConstants.INCREASED_RISK) putLong("preference_timestamp_risk_level_calculation", 1234567890L) } createInstance().apply { val legacyResults = getLegacyResults() legacyResults.size shouldBe 1 legacyResults.first().apply { - riskLevel shouldBe RiskLevel.INCREASED_RISK + riskState shouldBe RiskState.INCREASED_RISK calculatedAt shouldBe Instant.ofEpochMilli(1234567890L) } } @@ -117,7 +116,7 @@ class RiskLevelResultMigratorTest : BaseTest() { @Test fun `exceptions are handled gracefully`() { mockPreferences.edit { - putInt("preference_risk_level_score", RiskLevel.INCREASED_RISK.raw) + putInt("preference_risk_level_score", MigrationRiskLevelConstants.INCREASED_RISK) } every { timeStamper.nowUTC } throws Exception("Surprise!") createInstance().getLegacyResults() shouldBe emptyList() @@ -126,20 +125,27 @@ class RiskLevelResultMigratorTest : BaseTest() { @Test fun `legacy risk level mapping`() { RiskLevelResultMigrator.mapRiskLevelConstant( - RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF - ) shouldBe RiskLevel.NO_CALCULATION_POSSIBLE_TRACING_OFF + MigrationRiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF + ) shouldBe RiskState.CALCULATION_FAILED - RiskLevelResultMigrator.mapRiskLevelConstant(RiskLevelConstants.LOW_LEVEL_RISK) shouldBe RiskLevel.LOW_LEVEL_RISK - RiskLevelResultMigrator.mapRiskLevelConstant(RiskLevelConstants.INCREASED_RISK) shouldBe RiskLevel.INCREASED_RISK + RiskLevelResultMigrator.mapRiskLevelConstant( + MigrationRiskLevelConstants.LOW_LEVEL_RISK + ) shouldBe RiskState.LOW_RISK + + RiskLevelResultMigrator.mapRiskLevelConstant( + MigrationRiskLevelConstants.INCREASED_RISK + ) shouldBe RiskState.INCREASED_RISK RiskLevelResultMigrator.mapRiskLevelConstant( - RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS - ) shouldBe RiskLevel.UNKNOWN_RISK_OUTDATED_RESULTS + MigrationRiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS + ) shouldBe RiskState.CALCULATION_FAILED RiskLevelResultMigrator.mapRiskLevelConstant( - RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL - ) shouldBe RiskLevel.UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL + MigrationRiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL + ) shouldBe RiskState.CALCULATION_FAILED - RiskLevelResultMigrator.mapRiskLevelConstant(RiskLevelConstants.UNDETERMINED) shouldBe RiskLevel.UNDETERMINED + RiskLevelResultMigrator.mapRiskLevelConstant( + MigrationRiskLevelConstants.UNDETERMINED + ) shouldBe RiskState.CALCULATION_FAILED } } diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/riskdetails/DefaultRiskDetailPresenterTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/riskdetails/DefaultRiskDetailPresenterTest.kt index ad879839c98c1a79e2561b45666b66e32db3c165..b8b06302d05a790816057cb5bf1e5878c27cbb32 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/riskdetails/DefaultRiskDetailPresenterTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/riskdetails/DefaultRiskDetailPresenterTest.kt @@ -1,8 +1,10 @@ package de.rki.coronawarnapp.ui.riskdetails -import de.rki.coronawarnapp.risk.RiskLevelConstants +import de.rki.coronawarnapp.risk.RiskState.CALCULATION_FAILED +import de.rki.coronawarnapp.risk.RiskState.INCREASED_RISK +import de.rki.coronawarnapp.risk.RiskState.LOW_RISK import de.rki.coronawarnapp.ui.tracing.details.DefaultRiskDetailPresenter -import org.junit.Assert +import io.kotest.matchers.shouldBe import org.junit.Test class DefaultRiskDetailPresenterTest { @@ -10,23 +12,19 @@ class DefaultRiskDetailPresenterTest { @Test fun test_isAdditionalInfoVisible() { DefaultRiskDetailPresenter().apply { - Assert.assertFalse(isAdditionalInfoVisible(RiskLevelConstants.LOW_LEVEL_RISK, 0)) - Assert.assertTrue(isAdditionalInfoVisible(RiskLevelConstants.LOW_LEVEL_RISK, 1)) - Assert.assertFalse(isAdditionalInfoVisible(RiskLevelConstants.INCREASED_RISK, 0)) - Assert.assertFalse(isAdditionalInfoVisible(RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS, 0)) - Assert.assertFalse(isAdditionalInfoVisible(RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF, 0)) - Assert.assertFalse(isAdditionalInfoVisible(RiskLevelConstants.UNDETERMINED, 0)) + isAdditionalInfoVisible(LOW_RISK, 0) shouldBe false + isAdditionalInfoVisible(LOW_RISK, 1) shouldBe true + isAdditionalInfoVisible(INCREASED_RISK, 0) shouldBe false + isAdditionalInfoVisible(CALCULATION_FAILED, 0) shouldBe false } } @Test fun test_isInformationBodyNoticeVisible() { DefaultRiskDetailPresenter().apply { - Assert.assertFalse(isInformationBodyNoticeVisible(RiskLevelConstants.LOW_LEVEL_RISK)) - Assert.assertTrue(isInformationBodyNoticeVisible(RiskLevelConstants.INCREASED_RISK)) - Assert.assertTrue(isInformationBodyNoticeVisible(RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS)) - Assert.assertTrue(isInformationBodyNoticeVisible(RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF)) - Assert.assertTrue(isInformationBodyNoticeVisible(RiskLevelConstants.UNDETERMINED)) + isInformationBodyNoticeVisible(LOW_RISK) shouldBe false + isInformationBodyNoticeVisible(INCREASED_RISK) shouldBe true + isInformationBodyNoticeVisible(CALCULATION_FAILED) shouldBe true } } } diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/tracing/card/TracingCardStateTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/tracing/card/TracingCardStateTest.kt index b283b8ab5a0741f86be02ef75923d49f7847f963..5702e64d16b383c946c1f139d6604aa8d9e753d2 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/tracing/card/TracingCardStateTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/tracing/card/TracingCardStateTest.kt @@ -2,13 +2,13 @@ package de.rki.coronawarnapp.ui.tracing.card import android.content.Context import de.rki.coronawarnapp.R -import de.rki.coronawarnapp.risk.RiskLevelConstants -import de.rki.coronawarnapp.risk.RiskLevelConstants.INCREASED_RISK -import de.rki.coronawarnapp.risk.RiskLevelConstants.LOW_LEVEL_RISK -import de.rki.coronawarnapp.risk.RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF -import de.rki.coronawarnapp.risk.RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS -import de.rki.coronawarnapp.tracing.GeneralTracingStatus +import de.rki.coronawarnapp.risk.RiskState +import de.rki.coronawarnapp.risk.RiskState.CALCULATION_FAILED +import de.rki.coronawarnapp.risk.RiskState.INCREASED_RISK +import de.rki.coronawarnapp.risk.RiskState.LOW_RISK +import de.rki.coronawarnapp.tracing.GeneralTracingStatus.Status import de.rki.coronawarnapp.tracing.TracingProgress +import de.rki.coronawarnapp.util.TimeAndDateExtensions.toLocalDate import io.kotest.matchers.shouldBe import io.mockk.MockKAnnotations import io.mockk.clearAllMocks @@ -17,6 +17,7 @@ import io.mockk.mockk import io.mockk.verify import io.mockk.verifySequence import org.joda.time.Instant +import org.joda.time.format.DateTimeFormat import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -38,10 +39,10 @@ class TracingCardStateTest : BaseTest() { } private fun createInstance( - tracingStatus: GeneralTracingStatus.Status = mockk(), - riskLevel: Int = 0, + tracingStatus: Status = mockk(), + riskState: RiskState = LOW_RISK, tracingProgress: TracingProgress = TracingProgress.Idle, - riskLevelLastSuccessfulCalculation: Int = 0, + lastSuccessfulRiskState: RiskState = LOW_RISK, daysWithEncounters: Int = 0, lastEncounterAt: Instant? = null, activeTracingDaysInRetentionPeriod: Long = 0, @@ -49,177 +50,99 @@ class TracingCardStateTest : BaseTest() { isBackgroundJobEnabled: Boolean = false ) = TracingCardState( tracingStatus = tracingStatus, - riskLevelScore = riskLevel, + riskState = riskState, tracingProgress = tracingProgress, - lastRiskLevelScoreCalculated = riskLevelLastSuccessfulCalculation, + lastSuccessfulRiskState = lastSuccessfulRiskState, daysWithEncounters = daysWithEncounters, lastEncounterAt = lastEncounterAt, - activeTracingDaysInRetentionPeriod = activeTracingDaysInRetentionPeriod, + activeTracingDays = activeTracingDaysInRetentionPeriod, lastTimeDiagnosisKeysFetched = lastTimeDiagnosisKeysFetched, isManualKeyRetrievalEnabled = !isBackgroundJobEnabled ) @Test fun `risklevel affects icon color`() { - createInstance(riskLevel = INCREASED_RISK).apply { + createInstance(riskState = INCREASED_RISK).apply { getStableIconColor(context) verify { context.getColor(R.color.colorStableLight) } } - createInstance(riskLevel = UNKNOWN_RISK_OUTDATED_RESULTS).apply { + createInstance(riskState = LOW_RISK).apply { getStableIconColor(context) - verify { context.getColor(R.color.colorTextSemanticNeutral) } + verify { context.getColor(R.color.colorStableLight) } } - createInstance(riskLevel = NO_CALCULATION_POSSIBLE_TRACING_OFF).apply { + createInstance(riskState = CALCULATION_FAILED).apply { getStableIconColor(context) verify { context.getColor(R.color.colorTextSemanticNeutral) } } - - createInstance(riskLevel = LOW_LEVEL_RISK).apply { - getStableIconColor(context) - verify { context.getColor(R.color.colorStableLight) } - } } @Test fun `risklevel affects riskcolors`() { - createInstance(riskLevel = INCREASED_RISK).apply { + createInstance(riskState = INCREASED_RISK).apply { getRiskInfoContainerBackgroundTint(context) verify { context.getColorStateList(R.color.card_increased) } } - createInstance(riskLevel = UNKNOWN_RISK_OUTDATED_RESULTS).apply { + createInstance(riskState = LOW_RISK).apply { getRiskInfoContainerBackgroundTint(context) - verify { context.getColorStateList(R.color.card_outdated) } + verify { context.getColorStateList(R.color.card_low) } } - createInstance(riskLevel = NO_CALCULATION_POSSIBLE_TRACING_OFF).apply { + createInstance(riskState = CALCULATION_FAILED).apply { getRiskInfoContainerBackgroundTint(context) verify { context.getColorStateList(R.color.card_no_calculation) } } - - createInstance(riskLevel = LOW_LEVEL_RISK).apply { - getRiskInfoContainerBackgroundTint(context) - verify { context.getColorStateList(R.color.card_low) } - } } @Test fun `risklevel affects risk body text`() { - createInstance(riskLevel = UNKNOWN_RISK_OUTDATED_RESULTS).apply { - getRiskBody(context) - verify { context.getString(R.string.risk_card_outdated_risk_body) } - } - - createInstance(riskLevel = NO_CALCULATION_POSSIBLE_TRACING_OFF).apply { - getRiskBody(context) - verify { context.getString(R.string.risk_card_body_tracing_off) } - } - - createInstance(riskLevel = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL).apply { - getRiskBody(context) - verify { context.getString(R.string.risk_card_outdated_manual_risk_body) } - } - } - - @Test - fun `risklevel affected by tracing status`() { - createInstance( - riskLevel = UNKNOWN_RISK_OUTDATED_RESULTS, - tracingStatus = GeneralTracingStatus.Status.TRACING_INACTIVE - ).apply { - getRiskBody(context) - verify { context.getString(R.string.risk_card_body_tracing_off) } + createInstance(riskState = INCREASED_RISK).apply { + getErrorStateBody(context) shouldBe "" } - createInstance( - riskLevel = NO_CALCULATION_POSSIBLE_TRACING_OFF, - tracingStatus = GeneralTracingStatus.Status.TRACING_INACTIVE - ).apply { - getRiskBody(context) - verify { context.getString(R.string.risk_card_body_tracing_off) } + createInstance(riskState = LOW_RISK).apply { + getErrorStateBody(context) shouldBe "" } - createInstance( - riskLevel = LOW_LEVEL_RISK, - tracingStatus = GeneralTracingStatus.Status.TRACING_INACTIVE - ).apply { - getRiskBody(context) - verify { context.getString(R.string.risk_card_body_tracing_off) } + createInstance(riskState = CALCULATION_FAILED).apply { + getErrorStateBody(context) + verify { context.getString(R.string.risk_card_check_failed_no_internet_body) } } createInstance( - riskLevel = INCREASED_RISK, - tracingStatus = GeneralTracingStatus.Status.TRACING_INACTIVE + riskState = CALCULATION_FAILED, + tracingStatus = Status.TRACING_INACTIVE ).apply { - getRiskBody(context) + getErrorStateBody(context) verify { context.getString(R.string.risk_card_body_tracing_off) } } } @Test fun `saved risk body is affected by risklevel`() { - createInstance( - riskLevel = INCREASED_RISK, - riskLevelLastSuccessfulCalculation = 0 - ).apply { - getSavedRiskBody(context) shouldBe "" - } - - createInstance( - riskLevel = UNKNOWN_RISK_OUTDATED_RESULTS, - riskLevelLastSuccessfulCalculation = 0 - ).apply { - getSavedRiskBody(context) shouldBe "" - } - - createInstance( - riskLevel = NO_CALCULATION_POSSIBLE_TRACING_OFF, - riskLevelLastSuccessfulCalculation = 0 - ).apply { - getSavedRiskBody(context) shouldBe "" - } - - createInstance( - riskLevel = LOW_LEVEL_RISK, - riskLevelLastSuccessfulCalculation = 0 - ).apply { + createInstance(riskState = CALCULATION_FAILED, lastSuccessfulRiskState = CALCULATION_FAILED).apply { getSavedRiskBody(context) shouldBe "" } - createInstance( - riskLevel = INCREASED_RISK, - riskLevelLastSuccessfulCalculation = INCREASED_RISK - ).apply { + createInstance(riskState = LOW_RISK, lastSuccessfulRiskState = CALCULATION_FAILED).apply { getSavedRiskBody(context) shouldBe "" } - createInstance( - riskLevel = INCREASED_RISK, - riskLevelLastSuccessfulCalculation = UNKNOWN_RISK_OUTDATED_RESULTS - ).apply { + createInstance(riskState = INCREASED_RISK, lastSuccessfulRiskState = INCREASED_RISK).apply { getSavedRiskBody(context) shouldBe "" } - createInstance( - riskLevel = INCREASED_RISK, - riskLevelLastSuccessfulCalculation = NO_CALCULATION_POSSIBLE_TRACING_OFF - ).apply { + createInstance(riskState = INCREASED_RISK, lastSuccessfulRiskState = CALCULATION_FAILED).apply { getSavedRiskBody(context) shouldBe "" } - createInstance( - riskLevel = INCREASED_RISK, - riskLevelLastSuccessfulCalculation = LOW_LEVEL_RISK - ).apply { + createInstance(riskState = INCREASED_RISK, lastSuccessfulRiskState = LOW_RISK).apply { getSavedRiskBody(context) shouldBe "" } - createInstance( - riskLevel = NO_CALCULATION_POSSIBLE_TRACING_OFF, - riskLevelLastSuccessfulCalculation = LOW_LEVEL_RISK - ).apply { + createInstance(riskState = CALCULATION_FAILED, lastSuccessfulRiskState = LOW_RISK).apply { getSavedRiskBody(context) verify { context @@ -228,10 +151,7 @@ class TracingCardStateTest : BaseTest() { } } - createInstance( - riskLevel = NO_CALCULATION_POSSIBLE_TRACING_OFF, - riskLevelLastSuccessfulCalculation = INCREASED_RISK - ).apply { + createInstance(riskState = CALCULATION_FAILED, lastSuccessfulRiskState = INCREASED_RISK).apply { getSavedRiskBody(context) verify { context @@ -240,10 +160,7 @@ class TracingCardStateTest : BaseTest() { } } - createInstance( - riskLevel = UNKNOWN_RISK_OUTDATED_RESULTS, - riskLevelLastSuccessfulCalculation = LOW_LEVEL_RISK - ).apply { + createInstance(riskState = CALCULATION_FAILED, lastSuccessfulRiskState = LOW_RISK).apply { getSavedRiskBody(context) verify { context @@ -251,69 +168,32 @@ class TracingCardStateTest : BaseTest() { .format(context.getString(R.string.risk_card_low_risk_headline)) } } - - createInstance( - riskLevel = UNKNOWN_RISK_OUTDATED_RESULTS, - riskLevelLastSuccessfulCalculation = INCREASED_RISK - ).apply { - getSavedRiskBody(context) - verify { - context - .getString(R.string.risk_card_no_calculation_possible_body_saved_risk) - .format(context.getString(R.string.risk_card_increased_risk_headline)) - } - } } @Test fun `risk contact body is affected by risklevel`() { - createInstance( - riskLevel = UNKNOWN_RISK_OUTDATED_RESULTS, - daysWithEncounters = 0 - ).apply { - getRiskContactBody(context) shouldBe "" - } - - createInstance( - riskLevel = NO_CALCULATION_POSSIBLE_TRACING_OFF, - daysWithEncounters = 0 - ).apply { + createInstance(riskState = CALCULATION_FAILED, daysWithEncounters = 0).apply { getRiskContactBody(context) shouldBe "" } - createInstance( - riskLevel = UNKNOWN_RISK_OUTDATED_RESULTS, - daysWithEncounters = 2 - ).apply { - getRiskContactBody(context) shouldBe "" - } - - createInstance( - riskLevel = NO_CALCULATION_POSSIBLE_TRACING_OFF, - daysWithEncounters = 2 - ).apply { + createInstance(riskState = CALCULATION_FAILED, daysWithEncounters = 2).apply { getRiskContactBody(context) shouldBe "" } } @Test fun `risk icon formatting`() { - createInstance(riskLevel = INCREASED_RISK).apply { + createInstance(riskState = INCREASED_RISK).apply { getRiskContactIcon(context) verify { context.getDrawable(R.drawable.ic_risk_card_contact_increased) } } - createInstance(riskLevel = UNKNOWN_RISK_OUTDATED_RESULTS).apply { - getRiskContactIcon(context) - verify { context.getDrawable(R.drawable.ic_risk_card_contact) } - } - - createInstance(riskLevel = NO_CALCULATION_POSSIBLE_TRACING_OFF).apply { + createInstance(riskState = LOW_RISK).apply { getRiskContactIcon(context) verify { context.getDrawable(R.drawable.ic_risk_card_contact) } } - createInstance(riskLevel = LOW_LEVEL_RISK).apply { + createInstance(riskState = CALCULATION_FAILED).apply { getRiskContactIcon(context) verify { context.getDrawable(R.drawable.ic_risk_card_contact) } } @@ -321,60 +201,41 @@ class TracingCardStateTest : BaseTest() { @Test fun `last risk contact text formatting`() { - createInstance( - riskLevel = UNKNOWN_RISK_OUTDATED_RESULTS - ).apply { - getRiskContactLast(context) shouldBe "" + createInstance(riskState = INCREASED_RISK, lastEncounterAt = Instant.EPOCH).apply { + getRiskContactLast(context) + verify { + context.getString( + R.string.risk_card_high_risk_most_recent_body, + Instant.EPOCH.toLocalDate().toString(DateTimeFormat.mediumDate()) + ) + } } - createInstance( - riskLevel = NO_CALCULATION_POSSIBLE_TRACING_OFF - ).apply { + createInstance(riskState = LOW_RISK).apply { getRiskContactLast(context) shouldBe "" } - createInstance( - riskLevel = LOW_LEVEL_RISK - ).apply { + createInstance(riskState = CALCULATION_FAILED).apply { getRiskContactLast(context) shouldBe "" } } @Test fun `text for active risktracing in retention period`() { - createInstance( - riskLevel = INCREASED_RISK, - activeTracingDaysInRetentionPeriod = 1 - ).apply { + createInstance(riskState = INCREASED_RISK, activeTracingDaysInRetentionPeriod = 1).apply { getRiskActiveTracingDaysInRetentionPeriod(context) shouldBe "" } - createInstance( - riskLevel = UNKNOWN_RISK_OUTDATED_RESULTS, - activeTracingDaysInRetentionPeriod = 1 - ).apply { + createInstance(riskState = CALCULATION_FAILED, activeTracingDaysInRetentionPeriod = 1).apply { getRiskActiveTracingDaysInRetentionPeriod(context) shouldBe "" } - createInstance( - riskLevel = NO_CALCULATION_POSSIBLE_TRACING_OFF, - activeTracingDaysInRetentionPeriod = 1 - ).apply { - getRiskActiveTracingDaysInRetentionPeriod(context) shouldBe "" - } - - createInstance( - riskLevel = LOW_LEVEL_RISK, - activeTracingDaysInRetentionPeriod = 1 - ).apply { + createInstance(riskState = LOW_RISK, activeTracingDaysInRetentionPeriod = 1).apply { getRiskActiveTracingDaysInRetentionPeriod(context) verify { context.getString(R.string.risk_card_body_saved_days).format(1) } } - createInstance( - riskLevel = LOW_LEVEL_RISK, - activeTracingDaysInRetentionPeriod = 2 - ).apply { + createInstance(riskState = LOW_RISK, activeTracingDaysInRetentionPeriod = 2).apply { getRiskActiveTracingDaysInRetentionPeriod(context) verify { context.getString(R.string.risk_card_body_saved_days).format(2) } } @@ -384,8 +245,8 @@ class TracingCardStateTest : BaseTest() { fun `text for last time diagnosis keys were fetched`() { val date = Date() createInstance( - riskLevel = INCREASED_RISK, - riskLevelLastSuccessfulCalculation = 2, + riskState = INCREASED_RISK, + lastSuccessfulRiskState = LOW_RISK, lastTimeDiagnosisKeysFetched = date ).apply { getTimeFetched(context) @@ -393,8 +254,8 @@ class TracingCardStateTest : BaseTest() { } createInstance( - riskLevel = UNKNOWN_RISK_OUTDATED_RESULTS, - riskLevelLastSuccessfulCalculation = 2, + riskState = CALCULATION_FAILED, + lastSuccessfulRiskState = LOW_RISK, lastTimeDiagnosisKeysFetched = date ).apply { getTimeFetched(context) @@ -402,8 +263,8 @@ class TracingCardStateTest : BaseTest() { } createInstance( - riskLevel = NO_CALCULATION_POSSIBLE_TRACING_OFF, - riskLevelLastSuccessfulCalculation = 2, + riskState = CALCULATION_FAILED, + lastSuccessfulRiskState = LOW_RISK, lastTimeDiagnosisKeysFetched = date ).apply { getTimeFetched(context) @@ -411,70 +272,38 @@ class TracingCardStateTest : BaseTest() { } createInstance( - riskLevel = LOW_LEVEL_RISK, - riskLevelLastSuccessfulCalculation = 2, + riskState = LOW_RISK, + lastSuccessfulRiskState = LOW_RISK, lastTimeDiagnosisKeysFetched = date ).apply { getTimeFetched(context) verify { context.getString(eq(R.string.risk_card_body_time_fetched), any()) } } - createInstance( - riskLevel = INCREASED_RISK, - lastTimeDiagnosisKeysFetched = date - ).apply { + createInstance(riskState = INCREASED_RISK, lastTimeDiagnosisKeysFetched = date).apply { getTimeFetched(context) verify { context.getString(eq(R.string.risk_card_body_time_fetched), any()) } } - createInstance( - riskLevel = UNKNOWN_RISK_OUTDATED_RESULTS, - lastTimeDiagnosisKeysFetched = date - ).apply { - getTimeFetched(context) shouldBe "" - } - - createInstance( - riskLevel = NO_CALCULATION_POSSIBLE_TRACING_OFF, - lastTimeDiagnosisKeysFetched = date - ).apply { + createInstance(riskState = CALCULATION_FAILED, lastTimeDiagnosisKeysFetched = date).apply { getTimeFetched(context) shouldBe "" } - createInstance( - riskLevel = LOW_LEVEL_RISK, - lastTimeDiagnosisKeysFetched = date - ).apply { + createInstance(riskState = LOW_RISK, lastTimeDiagnosisKeysFetched = date).apply { getTimeFetched(context) verify { context.getString(eq(R.string.risk_card_body_time_fetched), any()) } } - createInstance( - riskLevel = INCREASED_RISK, - lastTimeDiagnosisKeysFetched = null - ).apply { + createInstance(riskState = INCREASED_RISK, lastTimeDiagnosisKeysFetched = null).apply { getTimeFetched(context) verify { context.getString(R.string.risk_card_body_not_yet_fetched) } } - createInstance( - riskLevel = UNKNOWN_RISK_OUTDATED_RESULTS, - lastTimeDiagnosisKeysFetched = null - ).apply { - getTimeFetched(context) shouldBe "" - } - - createInstance( - riskLevel = NO_CALCULATION_POSSIBLE_TRACING_OFF, - lastTimeDiagnosisKeysFetched = null - ).apply { + createInstance(riskState = CALCULATION_FAILED, lastTimeDiagnosisKeysFetched = null).apply { getTimeFetched(context) shouldBe "" } - createInstance( - riskLevel = LOW_LEVEL_RISK, - lastTimeDiagnosisKeysFetched = null - ).apply { + createInstance(riskState = LOW_RISK, lastTimeDiagnosisKeysFetched = null).apply { getTimeFetched(context) verify { context.getString(R.string.risk_card_body_not_yet_fetched) } } @@ -482,123 +311,96 @@ class TracingCardStateTest : BaseTest() { @Test fun `task divider is formatted according to riskLevel`() { - createInstance(riskLevel = INCREASED_RISK).apply { + createInstance(riskState = INCREASED_RISK).apply { getStableDividerColor(context) verify { context.getColor(R.color.colorStableHairlineLight) } } - createInstance(riskLevel = UNKNOWN_RISK_OUTDATED_RESULTS).apply { + createInstance(riskState = INCREASED_RISK, tracingStatus = Status.TRACING_INACTIVE).apply { getStableDividerColor(context) verify { context.getColor(R.color.colorStableHairlineDark) } } - createInstance(riskLevel = NO_CALCULATION_POSSIBLE_TRACING_OFF).apply { + createInstance(riskState = LOW_RISK).apply { getStableDividerColor(context) - verify { context.getColor(R.color.colorStableHairlineDark) } + verify { context.getColor(R.color.colorStableHairlineLight) } } - createInstance(riskLevel = LOW_LEVEL_RISK).apply { + createInstance(riskState = CALCULATION_FAILED).apply { getStableDividerColor(context) - verify { context.getColor(R.color.colorStableHairlineLight) } + verify { context.getColor(R.color.colorStableHairlineDark) } } } @Test fun `tracing button visibility depends on risklevel`() { - createInstance(riskLevel = INCREASED_RISK).apply { + createInstance(riskState = INCREASED_RISK).apply { showTracingButton() shouldBe false } - createInstance(riskLevel = UNKNOWN_RISK_OUTDATED_RESULTS).apply { - showTracingButton() shouldBe true + createInstance(riskState = LOW_RISK).apply { + showTracingButton() shouldBe false } - createInstance(riskLevel = NO_CALCULATION_POSSIBLE_TRACING_OFF).apply { - showTracingButton() shouldBe true + createInstance(riskState = CALCULATION_FAILED).apply { + showTracingButton() shouldBe false } - createInstance(riskLevel = LOW_LEVEL_RISK).apply { - showTracingButton() shouldBe false + createInstance(riskState = CALCULATION_FAILED, tracingStatus = Status.TRACING_INACTIVE).apply { + showTracingButton() shouldBe true } } @Test fun `update button visibility`() { - createInstance( - riskLevel = INCREASED_RISK, - isBackgroundJobEnabled = false - ).apply { + createInstance(riskState = INCREASED_RISK, isBackgroundJobEnabled = false).apply { showUpdateButton() shouldBe true } - createInstance( - riskLevel = INCREASED_RISK, - isBackgroundJobEnabled = true - ).apply { - showUpdateButton() shouldBe false - } - - createInstance( - riskLevel = UNKNOWN_RISK_OUTDATED_RESULTS, - isBackgroundJobEnabled = false - ).apply { - showUpdateButton() shouldBe false - } - - createInstance( - riskLevel = UNKNOWN_RISK_OUTDATED_RESULTS, - isBackgroundJobEnabled = true - ).apply { + createInstance(riskState = INCREASED_RISK, isBackgroundJobEnabled = true).apply { showUpdateButton() shouldBe false } - createInstance( - riskLevel = NO_CALCULATION_POSSIBLE_TRACING_OFF, - isBackgroundJobEnabled = false - ).apply { - showUpdateButton() shouldBe false + createInstance(riskState = CALCULATION_FAILED, isBackgroundJobEnabled = false).apply { + showUpdateButton() shouldBe true } - createInstance( - riskLevel = NO_CALCULATION_POSSIBLE_TRACING_OFF, - isBackgroundJobEnabled = true - ).apply { - showUpdateButton() shouldBe false + createInstance(riskState = CALCULATION_FAILED, isBackgroundJobEnabled = true).apply { + showUpdateButton() shouldBe true } - createInstance( - riskLevel = LOW_LEVEL_RISK, - isBackgroundJobEnabled = false - ).apply { + createInstance(riskState = LOW_RISK, isBackgroundJobEnabled = false).apply { showUpdateButton() shouldBe true } - createInstance( - riskLevel = LOW_LEVEL_RISK, - isBackgroundJobEnabled = true - ).apply { + createInstance(riskState = LOW_RISK, isBackgroundJobEnabled = true).apply { showUpdateButton() shouldBe false } } @Test fun `risklevel headline is affected by score`() { - createInstance(riskLevel = INCREASED_RISK).apply { + createInstance(riskState = INCREASED_RISK).apply { getRiskLevelHeadline(context) verify { context.getString(R.string.risk_card_increased_risk_headline) } } - createInstance(riskLevel = UNKNOWN_RISK_OUTDATED_RESULTS).apply { + createInstance(riskState = CALCULATION_FAILED).apply { getRiskLevelHeadline(context) - verify { context.getString(R.string.risk_card_outdated_risk_headline) } + verify { context.getString(R.string.risk_card_check_failed_no_internet_headline) } + } + + createInstance(riskState = CALCULATION_FAILED, tracingStatus = Status.TRACING_INACTIVE).apply { + getRiskLevelHeadline(context) + verify { context.getString(R.string.risk_card_no_calculation_possible_headline) } } - createInstance(riskLevel = NO_CALCULATION_POSSIBLE_TRACING_OFF).apply { + createInstance(riskState = INCREASED_RISK, tracingStatus = Status.TRACING_INACTIVE).apply { getRiskLevelHeadline(context) verify { context.getString(R.string.risk_card_no_calculation_possible_headline) } } - createInstance(riskLevel = LOW_LEVEL_RISK).apply { + createInstance(riskState = LOW_RISK).apply { getRiskLevelHeadline(context) verify { context.getString(R.string.risk_card_low_risk_headline) } } diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/tracing/common/BaseTracingStateTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/tracing/common/BaseTracingStateTest.kt index 32c817a0dd9153ea212463c2e9e9ff99c828ca82..2f280ca94b56a7a1a4f7a637630ce0f6a111df09 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/tracing/common/BaseTracingStateTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/tracing/common/BaseTracingStateTest.kt @@ -2,8 +2,11 @@ package de.rki.coronawarnapp.ui.tracing.common import android.content.Context import de.rki.coronawarnapp.R -import de.rki.coronawarnapp.risk.RiskLevelConstants -import de.rki.coronawarnapp.tracing.GeneralTracingStatus +import de.rki.coronawarnapp.risk.RiskState +import de.rki.coronawarnapp.risk.RiskState.CALCULATION_FAILED +import de.rki.coronawarnapp.risk.RiskState.INCREASED_RISK +import de.rki.coronawarnapp.risk.RiskState.LOW_RISK +import de.rki.coronawarnapp.tracing.GeneralTracingStatus.Status import de.rki.coronawarnapp.tracing.TracingProgress import io.kotest.matchers.shouldBe import io.mockk.MockKAnnotations @@ -11,7 +14,6 @@ import io.mockk.clearAllMocks import io.mockk.impl.annotations.MockK import io.mockk.mockk import io.mockk.verify -import io.mockk.verifySequence import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -32,14 +34,14 @@ class BaseTracingStateTest : BaseTest() { } private fun createInstance( - tracingStatus: GeneralTracingStatus.Status = mockk(), - riskLevelScore: Int = 0, + tracingStatus: Status = mockk(), + riskState: RiskState = LOW_RISK, tracingProgress: TracingProgress = TracingProgress.Idle, isManualKeyRetrievalEnabled: Boolean = false, showDetails: Boolean = false ) = object : BaseTracingState() { - override val tracingStatus: GeneralTracingStatus.Status = tracingStatus - override val riskLevelScore: Int = riskLevelScore + override val tracingStatus: Status = tracingStatus + override val riskState: RiskState = riskState override val tracingProgress: TracingProgress = tracingProgress override val showDetails: Boolean = showDetails override val isManualKeyRetrievalEnabled: Boolean = isManualKeyRetrievalEnabled @@ -47,80 +49,61 @@ class BaseTracingStateTest : BaseTest() { @Test fun `risk color`() { - createInstance(riskLevelScore = RiskLevelConstants.INCREASED_RISK).apply { + createInstance(riskState = INCREASED_RISK).apply { getRiskColor(context) verify { context.getColor(R.color.colorSemanticHighRisk) } } - createInstance(riskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS).apply { + createInstance(riskState = LOW_RISK).apply { getRiskColor(context) - verify { context.getColor(R.color.colorSemanticUnknownRisk) } + verify { context.getColor(R.color.colorSemanticLowRisk) } } - createInstance(riskLevelScore = RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF).apply { + createInstance(riskState = CALCULATION_FAILED).apply { getRiskColor(context) verify { context.getColor(R.color.colorSemanticUnknownRisk) } } - createInstance(riskLevelScore = RiskLevelConstants.LOW_LEVEL_RISK).apply { - getRiskColor(context) - verify { context.getColor(R.color.colorSemanticLowRisk) } - } } @Test fun `risk tracing off level`() { - createInstance(riskLevelScore = RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF).apply { - isTracingOffRiskLevel() shouldBe true - } - createInstance(riskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS).apply { - isTracingOffRiskLevel() shouldBe true + createInstance(riskState = CALCULATION_FAILED, tracingStatus = Status.TRACING_INACTIVE).apply { + isTracingOff() shouldBe true } - createInstance(riskLevelScore = RiskLevelConstants.LOW_LEVEL_RISK).apply { - isTracingOffRiskLevel() shouldBe false + createInstance(riskState = CALCULATION_FAILED).apply { + isTracingOff() shouldBe false } - createInstance(riskLevelScore = RiskLevelConstants.INCREASED_RISK).apply { - isTracingOffRiskLevel() shouldBe false + createInstance(riskState = LOW_RISK).apply { + isTracingOff() shouldBe false } - createInstance(riskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL).apply { - isTracingOffRiskLevel() shouldBe false - } - createInstance(riskLevelScore = RiskLevelConstants.UNDETERMINED).apply { - isTracingOffRiskLevel() shouldBe false + createInstance(riskState = INCREASED_RISK).apply { + isTracingOff() shouldBe false } } @Test fun `text color`() { - createInstance(riskLevelScore = RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF).apply { - getStableTextColor(context) - } - createInstance(riskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS).apply { - getStableTextColor(context) - } - createInstance(riskLevelScore = RiskLevelConstants.LOW_LEVEL_RISK).apply { - getStableTextColor(context) - } - createInstance(riskLevelScore = RiskLevelConstants.INCREASED_RISK).apply { + + createInstance(riskState = CALCULATION_FAILED).apply { getStableTextColor(context) + verify { context.getColor(R.color.colorTextPrimary1) } } - createInstance(riskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL).apply { + createInstance(riskState = LOW_RISK).apply { getStableTextColor(context) + verify { context.getColor(R.color.colorTextPrimary1InvertedStable) } } - createInstance(riskLevelScore = RiskLevelConstants.UNDETERMINED).apply { + createInstance(riskState = INCREASED_RISK).apply { getStableTextColor(context) + verify { context.getColor(R.color.colorTextPrimary1InvertedStable) } } - verifySequence { - context.getColor(R.color.colorTextPrimary1) - context.getColor(R.color.colorTextPrimary1) - context.getColor(R.color.colorTextPrimary1InvertedStable) - context.getColor(R.color.colorTextPrimary1InvertedStable) - context.getColor(R.color.colorTextPrimary1) - context.getColor(R.color.colorTextPrimary1) + createInstance(riskState = INCREASED_RISK, tracingStatus = Status.TRACING_INACTIVE).apply { + getStableTextColor(context) + verify { context.getColor(R.color.colorTextPrimary1) } } } @Test fun `update button text`() { - createInstance(riskLevelScore = RiskLevelConstants.UNKNOWN_RISK_NO_INTERNET).apply { + createInstance(riskState = CALCULATION_FAILED).apply { getUpdateButtonText(context) verify { context.getString(R.string.risk_card_check_failed_no_internet_restart_button) } } diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/tracing/common/RiskLevelExtensionsTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/tracing/common/RiskLevelResultExtensionsTest.kt similarity index 70% rename from Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/tracing/common/RiskLevelExtensionsTest.kt rename to Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/tracing/common/RiskLevelResultExtensionsTest.kt index 89905fe02a99358bc640e16beb5b44adce05a13e..4ae361d55af51e0786196de156ab0f83c3a91c42 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/tracing/common/RiskLevelExtensionsTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/tracing/common/RiskLevelResultExtensionsTest.kt @@ -1,8 +1,8 @@ package de.rki.coronawarnapp.ui.tracing.common import com.google.android.gms.nearby.exposurenotification.ExposureWindow -import de.rki.coronawarnapp.risk.RiskLevel import de.rki.coronawarnapp.risk.RiskLevelResult +import de.rki.coronawarnapp.risk.RiskState import de.rki.coronawarnapp.risk.result.AggregatedRiskResult import io.kotest.matchers.longs.shouldBeInRange import io.kotest.matchers.shouldBe @@ -11,9 +11,9 @@ import org.joda.time.Instant import org.junit.jupiter.api.Test import testhelpers.BaseTest -class RiskLevelExtensionsTest : BaseTest() { +class RiskLevelResultExtensionsTest : BaseTest() { - private fun createRiskLevel( + private fun createRiskLevelResult( hasResult: Boolean, calculatedAt: Instant ): RiskLevelResult = object : RiskLevelResult { @@ -32,12 +32,12 @@ class RiskLevelExtensionsTest : BaseTest() { emptyResults.tryLatestResultsWithDefaults().apply { lastCalculated.apply { - riskLevel shouldBe RiskLevel.LOW_LEVEL_RISK + riskState shouldBe RiskState.LOW_RISK val now = Instant.now().millis calculatedAt.millis shouldBeInRange ((now - 60 * 1000L)..now + 60 * 1000L) } lastSuccessfullyCalculated.apply { - riskLevel shouldBe RiskLevel.UNDETERMINED + riskState shouldBe RiskState.CALCULATION_FAILED } } } @@ -45,8 +45,8 @@ class RiskLevelExtensionsTest : BaseTest() { @Test fun `getLastestAndLastSuccessful last calculation was successful`() { val results = listOf( - createRiskLevel(hasResult = true, calculatedAt = Instant.EPOCH), - createRiskLevel(hasResult = true, calculatedAt = Instant.EPOCH.plus(1)) + createRiskLevelResult(hasResult = true, calculatedAt = Instant.EPOCH), + createRiskLevelResult(hasResult = true, calculatedAt = Instant.EPOCH.plus(1)) ) results.tryLatestResultsWithDefaults().apply { @@ -58,9 +58,9 @@ class RiskLevelExtensionsTest : BaseTest() { @Test fun `getLastestAndLastSuccessful last calculation was not successful`() { val results = listOf( - createRiskLevel(hasResult = true, calculatedAt = Instant.EPOCH), - createRiskLevel(hasResult = true, calculatedAt = Instant.EPOCH.plus(1)), - createRiskLevel(hasResult = false, calculatedAt = Instant.EPOCH.plus(2)) + createRiskLevelResult(hasResult = true, calculatedAt = Instant.EPOCH), + createRiskLevelResult(hasResult = true, calculatedAt = Instant.EPOCH.plus(1)), + createRiskLevelResult(hasResult = false, calculatedAt = Instant.EPOCH.plus(2)) ) results.tryLatestResultsWithDefaults().apply { @@ -72,10 +72,10 @@ class RiskLevelExtensionsTest : BaseTest() { @Test fun `getLastestAndLastSuccessful no successful calculations yet`() { val results = listOf( - createRiskLevel(hasResult = false, calculatedAt = Instant.EPOCH.plus(10)), - createRiskLevel(hasResult = false, calculatedAt = Instant.EPOCH.plus(11)), - createRiskLevel(hasResult = false, calculatedAt = Instant.EPOCH.plus(12)), - createRiskLevel(hasResult = false, calculatedAt = Instant.EPOCH.plus(13)) + createRiskLevelResult(hasResult = false, calculatedAt = Instant.EPOCH.plus(10)), + createRiskLevelResult(hasResult = false, calculatedAt = Instant.EPOCH.plus(11)), + createRiskLevelResult(hasResult = false, calculatedAt = Instant.EPOCH.plus(12)), + createRiskLevelResult(hasResult = false, calculatedAt = Instant.EPOCH.plus(13)) ) results.tryLatestResultsWithDefaults().apply { diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/tracing/details/TracingDetailsStateTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/tracing/details/TracingDetailsStateTest.kt index dd225af90a792520020cafcb6a19b6e79162750f..432070fbfe7f712f3a1447e944673d01ae42ecc0 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/tracing/details/TracingDetailsStateTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/tracing/details/TracingDetailsStateTest.kt @@ -3,7 +3,10 @@ package de.rki.coronawarnapp.ui.tracing.details import android.content.Context import android.content.res.Resources import de.rki.coronawarnapp.R -import de.rki.coronawarnapp.risk.RiskLevelConstants +import de.rki.coronawarnapp.risk.RiskState +import de.rki.coronawarnapp.risk.RiskState.CALCULATION_FAILED +import de.rki.coronawarnapp.risk.RiskState.INCREASED_RISK +import de.rki.coronawarnapp.risk.RiskState.LOW_RISK import de.rki.coronawarnapp.tracing.GeneralTracingStatus import de.rki.coronawarnapp.tracing.TracingProgress import io.kotest.matchers.shouldBe @@ -37,7 +40,7 @@ class TracingDetailsStateTest : BaseTest() { private fun createInstance( tracingStatus: GeneralTracingStatus.Status = mockk(), - riskLevelScore: Int = 0, + riskState: RiskState, tracingProgress: TracingProgress = TracingProgress.Idle, matchedKeyCount: Int = 3, daysSinceLastExposure: Int = 2, @@ -47,7 +50,7 @@ class TracingDetailsStateTest : BaseTest() { isAdditionalInformationVisible: Boolean = false ) = TracingDetailsState( tracingStatus = tracingStatus, - riskLevelScore = riskLevelScore, + riskState = riskState, tracingProgress = tracingProgress, matchedKeyCount = matchedKeyCount, daysSinceLastExposure = daysSinceLastExposure, @@ -59,115 +62,70 @@ class TracingDetailsStateTest : BaseTest() { @Test fun `normal behavior visibility`() { - createInstance(riskLevelScore = RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF).apply { + createInstance(riskState = LOW_RISK).apply { isBehaviorNormalVisible() shouldBe true } - createInstance(riskLevelScore = RiskLevelConstants.LOW_LEVEL_RISK).apply { - isBehaviorNormalVisible() shouldBe true - } - createInstance(riskLevelScore = RiskLevelConstants.INCREASED_RISK).apply { + createInstance(riskState = INCREASED_RISK).apply { isBehaviorNormalVisible() shouldBe false } - createInstance(riskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS).apply { - isBehaviorNormalVisible() shouldBe true - } - createInstance(riskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL).apply { - isBehaviorNormalVisible() shouldBe true - } - createInstance(riskLevelScore = RiskLevelConstants.UNDETERMINED).apply { + createInstance(riskState = CALCULATION_FAILED).apply { isBehaviorNormalVisible() shouldBe true } } @Test fun `increased risk visibility`() { - createInstance(riskLevelScore = RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF).apply { + createInstance(riskState = LOW_RISK).apply { isBehaviorIncreasedRiskVisible() shouldBe false } - createInstance(riskLevelScore = RiskLevelConstants.LOW_LEVEL_RISK).apply { - isBehaviorIncreasedRiskVisible() shouldBe false - } - createInstance(riskLevelScore = RiskLevelConstants.INCREASED_RISK).apply { + createInstance(riskState = INCREASED_RISK).apply { isBehaviorIncreasedRiskVisible() shouldBe true } - createInstance(riskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS).apply { - isBehaviorIncreasedRiskVisible() shouldBe false - } - createInstance(riskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL).apply { - isBehaviorIncreasedRiskVisible() shouldBe false - } - createInstance(riskLevelScore = RiskLevelConstants.UNDETERMINED).apply { + createInstance(riskState = CALCULATION_FAILED).apply { isBehaviorIncreasedRiskVisible() shouldBe false } } @Test fun `logged period card visibility`() { - createInstance(riskLevelScore = RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF).apply { - isBehaviorPeriodLoggedVisible() shouldBe false - } - createInstance(riskLevelScore = RiskLevelConstants.LOW_LEVEL_RISK).apply { + createInstance(riskState = LOW_RISK).apply { isBehaviorPeriodLoggedVisible() shouldBe true } - createInstance(riskLevelScore = RiskLevelConstants.INCREASED_RISK).apply { + createInstance(riskState = INCREASED_RISK).apply { isBehaviorPeriodLoggedVisible() shouldBe true } - createInstance(riskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS).apply { - isBehaviorPeriodLoggedVisible() shouldBe false - } - createInstance(riskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL).apply { - isBehaviorPeriodLoggedVisible() shouldBe false - } - createInstance(riskLevelScore = RiskLevelConstants.UNDETERMINED).apply { + createInstance(riskState = CALCULATION_FAILED).apply { isBehaviorPeriodLoggedVisible() shouldBe false } } @Test fun `low level risk visibility`() { - createInstance(riskLevelScore = RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF).apply { - isBehaviorLowLevelRiskVisible() shouldBe false - } - createInstance(riskLevelScore = RiskLevelConstants.LOW_LEVEL_RISK, matchedKeyCount = 1).apply { + createInstance(riskState = LOW_RISK, matchedKeyCount = 1).apply { isBehaviorLowLevelRiskVisible() shouldBe true } - createInstance(riskLevelScore = RiskLevelConstants.LOW_LEVEL_RISK, matchedKeyCount = 0).apply { - isBehaviorLowLevelRiskVisible() shouldBe false - } - createInstance(riskLevelScore = RiskLevelConstants.INCREASED_RISK).apply { - isBehaviorLowLevelRiskVisible() shouldBe false - } - createInstance(riskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS).apply { + createInstance(riskState = LOW_RISK, matchedKeyCount = 0).apply { isBehaviorLowLevelRiskVisible() shouldBe false } - createInstance(riskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL).apply { + createInstance(riskState = INCREASED_RISK).apply { isBehaviorLowLevelRiskVisible() shouldBe false } - createInstance(riskLevelScore = RiskLevelConstants.UNDETERMINED).apply { + createInstance(riskState = CALCULATION_FAILED).apply { isBehaviorLowLevelRiskVisible() shouldBe false } } @Test fun `risk details body text`() { - createInstance(riskLevelScore = RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF).apply { - getRiskDetailsRiskLevelBody(context) shouldBe "" - } - createInstance( - riskLevelScore = RiskLevelConstants.LOW_LEVEL_RISK, - matchedKeyCount = 1 - ).apply { + createInstance(riskState = LOW_RISK, matchedKeyCount = 1).apply { getRiskDetailsRiskLevelBody(context) verify { context.getString(R.string.risk_details_information_body_low_risk_with_encounter) } } - createInstance( - riskLevelScore = RiskLevelConstants.LOW_LEVEL_RISK, - matchedKeyCount = 0 - ).apply { + createInstance(riskState = LOW_RISK, matchedKeyCount = 0).apply { getRiskDetailsRiskLevelBody(context) verify { context.getString(R.string.risk_details_information_body_low_risk) } } - createInstance(riskLevelScore = RiskLevelConstants.INCREASED_RISK).apply { + createInstance(riskState = INCREASED_RISK).apply { getRiskDetailsRiskLevelBody(context) verify { resources.getQuantityString( @@ -176,175 +134,78 @@ class TracingDetailsStateTest : BaseTest() { ) } } - createInstance(riskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS).apply { + createInstance(riskState = CALCULATION_FAILED).apply { getRiskDetailsRiskLevelBody(context) verify { context.getString(R.string.risk_details_information_body_outdated_risk) } } - createInstance(riskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL).apply { - getRiskDetailsRiskLevelBody(context) shouldBe "" - } - createInstance(riskLevelScore = RiskLevelConstants.UNDETERMINED).apply { - getRiskDetailsRiskLevelBody(context) shouldBe "" - } } @Test fun `riskdetails body notice`() { - createInstance(riskLevelScore = RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF).apply { - getRiskDetailsRiskLevelBodyNotice(context) - verify { context.getString(R.string.risk_details_information_body_notice) } - } - createInstance(riskLevelScore = RiskLevelConstants.LOW_LEVEL_RISK).apply { + createInstance(riskState = LOW_RISK).apply { getRiskDetailsRiskLevelBodyNotice(context) verify { context.getString(R.string.risk_details_information_body_notice) } } - createInstance(riskLevelScore = RiskLevelConstants.INCREASED_RISK).apply { + createInstance(riskState = INCREASED_RISK).apply { getRiskDetailsRiskLevelBodyNotice(context) verify { context.getString(R.string.risk_details_information_body_notice_increased) } } - createInstance(riskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS).apply { - getRiskDetailsRiskLevelBodyNotice(context) - verify { context.getString(R.string.risk_details_information_body_notice) } - } - createInstance(riskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL).apply { - getRiskDetailsRiskLevelBodyNotice(context) - verify { context.getString(R.string.risk_details_information_body_notice) } - } - createInstance(riskLevelScore = RiskLevelConstants.UNDETERMINED).apply { + createInstance(riskState = CALCULATION_FAILED).apply { getRiskDetailsRiskLevelBodyNotice(context) verify { context.getString(R.string.risk_details_information_body_notice) } } } @Test - fun `risk details buttons visibility`() { - createInstance( - riskLevelScore = RiskLevelConstants.INCREASED_RISK, - isBackgroundJobEnabled = true - ).apply { - areRiskDetailsButtonsVisible() shouldBe false - } - createInstance( - riskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS, - isBackgroundJobEnabled = true - ).apply { - areRiskDetailsButtonsVisible() shouldBe true - } - createInstance( - riskLevelScore = RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF, - isBackgroundJobEnabled = true - ).apply { - areRiskDetailsButtonsVisible() shouldBe true - } - createInstance( - riskLevelScore = RiskLevelConstants.LOW_LEVEL_RISK, - isBackgroundJobEnabled = true - ).apply { - areRiskDetailsButtonsVisible() shouldBe false - } - createInstance( - riskLevelScore = RiskLevelConstants.INCREASED_RISK, - isBackgroundJobEnabled = false - ).apply { - areRiskDetailsButtonsVisible() shouldBe true - } - createInstance( - riskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS, - isBackgroundJobEnabled = false - ).apply { - areRiskDetailsButtonsVisible() shouldBe true - } - createInstance( - riskLevelScore = RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF, - isBackgroundJobEnabled = false - ).apply { - areRiskDetailsButtonsVisible() shouldBe true - } - createInstance( - riskLevelScore = RiskLevelConstants.LOW_LEVEL_RISK, - isBackgroundJobEnabled = false - ).apply { - areRiskDetailsButtonsVisible() shouldBe true - } - } - - @Test - fun `enable tracing button visibility`() { - createInstance(riskLevelScore = RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF).apply { + fun `is tracing enable tracing button visible`() { + createInstance(riskState = LOW_RISK, tracingStatus = GeneralTracingStatus.Status.TRACING_INACTIVE).apply { isRiskDetailsEnableTracingButtonVisible() shouldBe true } - createInstance(riskLevelScore = RiskLevelConstants.LOW_LEVEL_RISK).apply { + createInstance(riskState = LOW_RISK).apply { isRiskDetailsEnableTracingButtonVisible() shouldBe false } - createInstance(riskLevelScore = RiskLevelConstants.INCREASED_RISK).apply { + createInstance(riskState = INCREASED_RISK).apply { isRiskDetailsEnableTracingButtonVisible() shouldBe false } - createInstance(riskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS).apply { - isRiskDetailsEnableTracingButtonVisible() shouldBe true - } - createInstance(riskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS_MANUAL).apply { - isRiskDetailsEnableTracingButtonVisible() shouldBe false - } - createInstance(riskLevelScore = RiskLevelConstants.UNDETERMINED).apply { + createInstance(riskState = CALCULATION_FAILED).apply { isRiskDetailsEnableTracingButtonVisible() shouldBe false } } @Test - fun `risk details update button visibility`() { + fun `manual update button visible`() { createInstance( - riskLevelScore = RiskLevelConstants.INCREASED_RISK, - isBackgroundJobEnabled = true + riskState = INCREASED_RISK, + isBackgroundJobEnabled = false, + tracingStatus = GeneralTracingStatus.Status.TRACING_INACTIVE ).apply { isRiskDetailsUpdateButtonVisible() shouldBe false } - createInstance( - riskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS, - isBackgroundJobEnabled = true - ).apply { + createInstance(riskState = INCREASED_RISK, isBackgroundJobEnabled = true).apply { isRiskDetailsUpdateButtonVisible() shouldBe false } - createInstance( - riskLevelScore = RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF, - isBackgroundJobEnabled = true - ).apply { - isRiskDetailsUpdateButtonVisible() shouldBe false + createInstance(riskState = INCREASED_RISK, isBackgroundJobEnabled = false).apply { + isRiskDetailsUpdateButtonVisible() shouldBe true } - createInstance( - riskLevelScore = RiskLevelConstants.LOW_LEVEL_RISK, - isBackgroundJobEnabled = true - ).apply { + + createInstance(riskState = LOW_RISK, isBackgroundJobEnabled = true).apply { isRiskDetailsUpdateButtonVisible() shouldBe false } - createInstance( - riskLevelScore = RiskLevelConstants.INCREASED_RISK, - isBackgroundJobEnabled = false - ).apply { + createInstance(riskState = LOW_RISK, isBackgroundJobEnabled = false).apply { isRiskDetailsUpdateButtonVisible() shouldBe true } - createInstance( - riskLevelScore = RiskLevelConstants.UNKNOWN_RISK_OUTDATED_RESULTS, - isBackgroundJobEnabled = false - ).apply { - isRiskDetailsUpdateButtonVisible() shouldBe false - } - createInstance( - riskLevelScore = RiskLevelConstants.NO_CALCULATION_POSSIBLE_TRACING_OFF, - isBackgroundJobEnabled = false - ).apply { + + createInstance(riskState = CALCULATION_FAILED, isBackgroundJobEnabled = true).apply { isRiskDetailsUpdateButtonVisible() shouldBe false } - createInstance( - riskLevelScore = RiskLevelConstants.LOW_LEVEL_RISK, - isBackgroundJobEnabled = false - ).apply { + createInstance(riskState = CALCULATION_FAILED, isBackgroundJobEnabled = false).apply { isRiskDetailsUpdateButtonVisible() shouldBe true } } @Test fun `format active tracing days in retention`() { - createInstance().apply { + createInstance(riskState = LOW_RISK).apply { getRiskActiveTracingDaysInRetentionPeriodLogged(context) verify { context.getString(R.string.risk_details_information_body_period_logged_assessment) } }