diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentTest.kt index 4dc5e974943a1f3b8b2744823285e49af166a10a..982637a9df449e0ff8eb24b91c2f48343b721ece 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentTest.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentTest.kt @@ -31,6 +31,7 @@ import de.rki.coronawarnapp.ui.main.home.items.FAQCard import de.rki.coronawarnapp.ui.main.home.items.HomeItem import de.rki.coronawarnapp.ui.presencetracing.organizer.TraceLocationOrganizerSettings import de.rki.coronawarnapp.ui.statistics.Statistics +import de.rki.coronawarnapp.util.TimeStamper import de.rki.coronawarnapp.util.encryptionmigration.EncryptionErrorResetTool import de.rki.coronawarnapp.util.shortcuts.AppShortcutsHelper import de.rki.coronawarnapp.util.ui.SingleLiveEvent @@ -73,6 +74,7 @@ class HomeFragmentTest : BaseUITest() { @MockK lateinit var appShortcutsHelper: AppShortcutsHelper @MockK lateinit var tracingSettings: TracingSettings @MockK lateinit var traceLocationOrganizerSettings: TraceLocationOrganizerSettings + @MockK lateinit var timeStamper: TimeStamper private lateinit var homeFragmentViewModel: HomeFragmentViewModel @@ -274,7 +276,8 @@ class HomeFragmentTest : BaseUITest() { deadmanNotificationScheduler = deadmanNotificationScheduler, appShortcutsHelper = appShortcutsHelper, tracingSettings = tracingSettings, - traceLocationOrganizerSettings = traceLocationOrganizerSettings + traceLocationOrganizerSettings = traceLocationOrganizerSettings, + timeStamper = timeStamper ) ) diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/hometestcards/ui/HomeTestCardsFragmentViewModel.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/hometestcards/ui/HomeTestCardsFragmentViewModel.kt index 2def4a1e835ee1167eea8a8eb61272f82a1c2e91..d4676cb5a038497c7547067f24d91da65ae576b9 100644 --- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/hometestcards/ui/HomeTestCardsFragmentViewModel.kt +++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/hometestcards/ui/HomeTestCardsFragmentViewModel.kt @@ -50,7 +50,7 @@ class HomeTestCardsFragmentViewModel @AssistedInject constructor( RapidTestPendingCard.Item(SubmissionStateRAT.TestPending) {}, RapidTestReadyCard.Item(SubmissionStateRAT.TestResultReady) {}, RapidTestInvalidCard.Item(SubmissionStateRAT.TestInvalid) {}, - RapidTestOutdatedCard.Item(SubmissionStateRAT.TestInvalid) {}, + RapidTestOutdatedCard.Item(SubmissionStateRAT.TestOutdated) {}, RapidTestErrorCard.Item(SubmissionStateRAT.TestError) {}, RapidTestNegativeCard.Item(SubmissionStateRAT.TestNegative(Instant.now())) {}, RapidTestPositiveCard.Item(SubmissionStateRAT.TestPositive(Instant.now())) {}, diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/appconfig/CoronaTestConfig.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/appconfig/CoronaTestConfig.kt index acba0188803f585aeab3c6de7da3dbc8425b2f81..54c0ff93229178b39104338d8f5dacbf94f78c24 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/appconfig/CoronaTestConfig.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/appconfig/CoronaTestConfig.kt @@ -9,10 +9,10 @@ interface CoronaTestConfig { } data class CoronaRapidAntigenTestParametersContainer( - val hoursToDeemTestOutdated: Int = DEFAULT_HOURS + val hoursToDeemTestOutdated: Long = DEFAULT_HOURS ) { companion object { - const val DEFAULT_HOURS = 48 + const val DEFAULT_HOURS: Long = 48 } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/appconfig/mapping/CoronaTestConfigMapper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/appconfig/mapping/CoronaTestConfigMapper.kt index 09fbb9068256a59f2068c8f27df844df27ea609f..d7025379b976024313e0e1ab2f116b830cef5991 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/appconfig/mapping/CoronaTestConfigMapper.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/appconfig/mapping/CoronaTestConfigMapper.kt @@ -25,7 +25,7 @@ class CoronaTestConfigMapper @Inject constructor() : CoronaTestConfig.Mapper { private fun ApplicationConfigurationAndroid.mapCoronaTestParameters(): CoronaTestConfig { val coronaRapidAntigenTestParameters = if (coronaTestParameters.hasCoronaRapidAntigenTestParameters()) { CoronaRapidAntigenTestParametersContainer( - coronaTestParameters.coronaRapidAntigenTestParameters.hoursToDeemTestOutdated + coronaTestParameters.coronaRapidAntigenTestParameters.hoursToDeemTestOutdated.toLong() ) } else { Timber.d("coronaRapidAntigenTestParameters is missing") diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RACoronaTest.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RACoronaTest.kt index a8f6b3f5d69b43eab99c8870439332fa32972990..8bb272b108fc3fa5ab88699f8ae3fb2d4c3d534a 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RACoronaTest.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RACoronaTest.kt @@ -1,6 +1,7 @@ package de.rki.coronawarnapp.coronatest.type.rapidantigen import com.google.gson.annotations.SerializedName +import de.rki.coronawarnapp.appconfig.CoronaTestConfig import de.rki.coronawarnapp.coronatest.server.CoronaTestResult import de.rki.coronawarnapp.coronatest.server.CoronaTestResult.PCR_OR_RAT_PENDING import de.rki.coronawarnapp.coronatest.server.CoronaTestResult.RAT_INVALID @@ -64,14 +65,23 @@ data class RACoronaTest( override val type: CoronaTest.Type get() = CoronaTest.Type.RAPID_ANTIGEN - fun getState(nowUTC: Instant) = when (testResult) { - PCR_OR_RAT_PENDING -> State.PENDING - RAT_NEGATIVE -> State.NEGATIVE - RAT_POSITIVE -> State.POSITIVE - RAT_INVALID -> State.INVALID - RAT_REDEEMED -> State.REDEEMED - else -> throw IllegalArgumentException("Invalid RAT test state $testResult") - } + private fun isOutdated(nowUTC: Instant, testConfig: CoronaTestConfig) = + testedAt.plus(testConfig.coronaRapidAntigenTestParameters.hoursToDeemTestOutdated).isBefore(nowUTC) + + fun getState(nowUTC: Instant, testConfig: CoronaTestConfig) = + if (testResult == RAT_NEGATIVE && isOutdated(nowUTC, testConfig)) { + State.OUTDATED + } else { + when (testResult) { + PCR_OR_RAT_PENDING, + RAT_PENDING -> State.PENDING + RAT_NEGATIVE -> State.NEGATIVE + RAT_POSITIVE -> State.POSITIVE + RAT_INVALID -> State.INVALID + RAT_REDEEMED -> State.REDEEMED + else -> throw IllegalArgumentException("Invalid RAT test state $testResult") + } + } override val isPositive: Boolean get() = testResult == RAT_POSITIVE diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RapidAntigenCoronaTestExtensions.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RapidAntigenCoronaTestExtensions.kt index e11e53071d35d16b9de90e79122d566464b5cd75..598d434590a5f7523820adcc5273c33aaf1a32e2 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RapidAntigenCoronaTestExtensions.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RapidAntigenCoronaTestExtensions.kt @@ -1,5 +1,6 @@ package de.rki.coronawarnapp.coronatest.type.rapidantigen +import de.rki.coronawarnapp.appconfig.CoronaTestConfig import de.rki.coronawarnapp.coronatest.type.rapidantigen.RACoronaTest.State.INVALID import de.rki.coronawarnapp.coronatest.type.rapidantigen.RACoronaTest.State.NEGATIVE import de.rki.coronawarnapp.coronatest.type.rapidantigen.RACoronaTest.State.OUTDATED @@ -11,17 +12,18 @@ import de.rki.coronawarnapp.coronatest.type.rapidantigen.SubmissionStateRAT.NoTe import de.rki.coronawarnapp.coronatest.type.rapidantigen.SubmissionStateRAT.TestError import de.rki.coronawarnapp.coronatest.type.rapidantigen.SubmissionStateRAT.TestInvalid import de.rki.coronawarnapp.coronatest.type.rapidantigen.SubmissionStateRAT.TestNegative +import de.rki.coronawarnapp.coronatest.type.rapidantigen.SubmissionStateRAT.TestOutdated import de.rki.coronawarnapp.coronatest.type.rapidantigen.SubmissionStateRAT.TestPending import de.rki.coronawarnapp.coronatest.type.rapidantigen.SubmissionStateRAT.TestPositive import de.rki.coronawarnapp.coronatest.type.rapidantigen.SubmissionStateRAT.TestResultReady import de.rki.coronawarnapp.exception.http.CwaServerError import org.joda.time.Instant -fun RACoronaTest?.toSubmissionState(nowUTC: Instant = Instant.now()) = when { +fun RACoronaTest?.toSubmissionState(nowUTC: Instant = Instant.now(), coronaTestConfig: CoronaTestConfig) = when { this == null -> NoTest isProcessing -> FetchingResult lastError != null -> if (lastError is CwaServerError) TestPending else TestInvalid - else -> when (getState(nowUTC)) { + else -> when (getState(nowUTC, coronaTestConfig)) { INVALID -> TestError POSITIVE -> { if (isViewed) TestPositive(testRegisteredAt = registeredAt) @@ -30,7 +32,6 @@ fun RACoronaTest?.toSubmissionState(nowUTC: Instant = Instant.now()) = when { NEGATIVE -> TestNegative(testRegisteredAt = registeredAt) REDEEMED -> TestInvalid PENDING -> TestPending - // TODO: Should be updated once the logic for OUTDATED tests is in - OUTDATED -> TestNegative(testRegisteredAt = registeredAt) + OUTDATED -> TestOutdated } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/SubmissionStateRAT.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/SubmissionStateRAT.kt index 8069a5d4d963f954333d0b22034c1204cacf5f68..0cc3508b6bf15d41c4414e6423cfc77e7a6e9419 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/SubmissionStateRAT.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/SubmissionStateRAT.kt @@ -25,6 +25,8 @@ sealed class SubmissionStateRAT { object TestPending : SubmissionStateRAT() + object TestOutdated : SubmissionStateRAT() + data class SubmissionDone( override val testRegisteredAt: Instant ) : SubmissionStateRAT(), CommonSubmissionStates.SubmissionDone diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/ui/homecards/RapidTestOutdatedCard.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/ui/homecards/RapidTestOutdatedCard.kt index a35e11d70cfcd86a2560bf5b5cb0b996179f3279..649a9a9b09fab6fd31e663caf00f910f219b86c8 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/ui/homecards/RapidTestOutdatedCard.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/ui/homecards/RapidTestOutdatedCard.kt @@ -29,7 +29,7 @@ class RapidTestOutdatedCard( } data class Item( - val state: SubmissionStateRAT.TestInvalid, + val state: SubmissionStateRAT.TestOutdated, val hideTest: (Item) -> Unit ) : TestResultItem.RA, HasPayloadDiffer { override fun diffPayload(old: Any, new: Any): Any? = if (old::class == new::class) new else null diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentViewModel.kt index 8516f8c8664fbd597c33d532eb4efab04fd4ffb7..0c5b76df726c81881920476a80750d497162e4bb 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/home/HomeFragmentViewModel.kt @@ -6,6 +6,7 @@ import androidx.navigation.NavDirections import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import de.rki.coronawarnapp.appconfig.AppConfigProvider +import de.rki.coronawarnapp.appconfig.CoronaTestConfig import de.rki.coronawarnapp.coronatest.CoronaTestRepository import de.rki.coronawarnapp.coronatest.latestPCRT import de.rki.coronawarnapp.coronatest.latestRAT @@ -34,6 +35,7 @@ import de.rki.coronawarnapp.submission.ui.homecards.PcrTestSubmissionDoneCard import de.rki.coronawarnapp.submission.ui.homecards.RapidTestErrorCard import de.rki.coronawarnapp.submission.ui.homecards.RapidTestInvalidCard import de.rki.coronawarnapp.submission.ui.homecards.RapidTestNegativeCard +import de.rki.coronawarnapp.submission.ui.homecards.RapidTestOutdatedCard import de.rki.coronawarnapp.submission.ui.homecards.RapidTestPendingCard import de.rki.coronawarnapp.submission.ui.homecards.RapidTestPositiveCard import de.rki.coronawarnapp.submission.ui.homecards.RapidTestReadyCard @@ -61,6 +63,7 @@ import de.rki.coronawarnapp.ui.main.home.items.FAQCard import de.rki.coronawarnapp.ui.main.home.items.HomeItem import de.rki.coronawarnapp.ui.main.home.items.ReenableRiskCard import de.rki.coronawarnapp.ui.presencetracing.organizer.TraceLocationOrganizerSettings +import de.rki.coronawarnapp.util.TimeStamper import de.rki.coronawarnapp.util.coroutine.DispatcherProvider import de.rki.coronawarnapp.util.encryptionmigration.EncryptionErrorResetTool import de.rki.coronawarnapp.util.shortcuts.AppShortcutsHelper @@ -82,12 +85,13 @@ class HomeFragmentViewModel @AssistedInject constructor( private val tracingRepository: TracingRepository, private val submissionRepository: SubmissionRepository, private val cwaSettings: CWASettings, - appConfigProvider: AppConfigProvider, + private val appConfigProvider: AppConfigProvider, statisticsProvider: StatisticsProvider, private val deadmanNotificationScheduler: DeadmanNotificationScheduler, private val appShortcutsHelper: AppShortcutsHelper, private val tracingSettings: TracingSettings, - private val traceLocationOrganizerSettings: TraceLocationOrganizerSettings + private val traceLocationOrganizerSettings: TraceLocationOrganizerSettings, + private val timeStamper: TimeStamper ) : CWAViewModel(dispatcherProvider = dispatcherProvider) { private val tracingStateProvider by lazy { tracingStateProviderFactory.create(isDetailsMode = false) } @@ -208,57 +212,66 @@ class HomeFragmentViewModel @AssistedInject constructor( is SubmissionStatePCR.SubmissionDone -> PcrTestSubmissionDoneCard.Item(state) } - private fun RACoronaTest?.toTestCardItem() = when (val state = this.toSubmissionState()) { - is SubmissionStateRAT.NoTest -> TestUnregisteredCard.Item(state) { - routeToScreen.postValue(HomeFragmentDirections.actionMainFragmentToSubmissionDispatcher()) - } - is SubmissionStateRAT.FetchingResult -> TestFetchingCard.Item(state) - is SubmissionStateRAT.TestResultReady -> RapidTestReadyCard.Item(state) { - routeToScreen.postValue( - HomeFragmentDirections - .actionMainFragmentToSubmissionTestResultAvailableFragment(CoronaTest.Type.RAPID_ANTIGEN) - ) - } - is SubmissionStateRAT.TestPositive -> RapidTestPositiveCard.Item(state) { - routeToScreen.postValue( - HomeFragmentDirections - .actionMainFragmentToSubmissionResultPositiveOtherWarningNoConsentFragment( - CoronaTest.Type.RAPID_ANTIGEN - ) - ) - } - is SubmissionStateRAT.TestNegative -> RapidTestNegativeCard.Item(state) { - routeToScreen.postValue( - HomeFragmentDirections - .actionMainFragmentToSubmissionNegativeAntigenTestResultFragment() - ) - } - is SubmissionStateRAT.TestInvalid -> RapidTestInvalidCard.Item(state) { - popupEvents.postValue(HomeFragmentEvents.ShowDeleteTestDialog) - } - is SubmissionStateRAT.TestError -> RapidTestErrorCard.Item(state) { - routeToScreen.postValue( - HomeFragmentDirections - .actionMainFragmentToSubmissionTestResultPendingFragment(testType = CoronaTest.Type.RAPID_ANTIGEN) - ) - } - is SubmissionStateRAT.TestPending -> RapidTestPendingCard.Item(state) { - routeToScreen.postValue( - HomeFragmentDirections - .actionMainFragmentToSubmissionTestResultPendingFragment(testType = CoronaTest.Type.RAPID_ANTIGEN) - ) + private fun RACoronaTest?.toTestCardItem(coronaTestConfig: CoronaTestConfig) = + when (val state = this.toSubmissionState(timeStamper.nowUTC, coronaTestConfig)) { + is SubmissionStateRAT.NoTest -> TestUnregisteredCard.Item(state) { + routeToScreen.postValue(HomeFragmentDirections.actionMainFragmentToSubmissionDispatcher()) + } + is SubmissionStateRAT.FetchingResult -> TestFetchingCard.Item(state) + is SubmissionStateRAT.TestResultReady -> RapidTestReadyCard.Item(state) { + routeToScreen.postValue( + HomeFragmentDirections + .actionMainFragmentToSubmissionTestResultAvailableFragment(CoronaTest.Type.RAPID_ANTIGEN) + ) + } + is SubmissionStateRAT.TestPositive -> RapidTestPositiveCard.Item(state) { + routeToScreen.postValue( + HomeFragmentDirections + .actionMainFragmentToSubmissionResultPositiveOtherWarningNoConsentFragment( + CoronaTest.Type.RAPID_ANTIGEN + ) + ) + } + is SubmissionStateRAT.TestNegative -> RapidTestNegativeCard.Item(state) { + routeToScreen.postValue( + HomeFragmentDirections + .actionMainFragmentToSubmissionNegativeAntigenTestResultFragment() + ) + } + is SubmissionStateRAT.TestInvalid -> RapidTestInvalidCard.Item(state) { + popupEvents.postValue(HomeFragmentEvents.ShowDeleteTestDialog) + } + is SubmissionStateRAT.TestError -> RapidTestErrorCard.Item(state) { + routeToScreen.postValue( + HomeFragmentDirections + .actionMainFragmentToSubmissionTestResultPendingFragment( + testType = CoronaTest.Type.RAPID_ANTIGEN + ) + ) + } + is SubmissionStateRAT.TestPending -> RapidTestPendingCard.Item(state) { + routeToScreen.postValue( + HomeFragmentDirections + .actionMainFragmentToSubmissionTestResultPendingFragment( + testType = CoronaTest.Type.RAPID_ANTIGEN + ) + ) + } + is SubmissionStateRAT.TestOutdated -> RapidTestOutdatedCard.Item(state) { + submissionRepository.removeTestFromDevice(type = CoronaTest.Type.RAPID_ANTIGEN) + } + is SubmissionStateRAT.SubmissionDone -> RapidTestSubmissionDoneCard.Item(state) } - is SubmissionStateRAT.SubmissionDone -> RapidTestSubmissionDoneCard.Item(state) - } val homeItems: LiveData<List<HomeItem>> = combine( tracingCardItems, coronaTestRepository.latestPCRT, coronaTestRepository.latestRAT, - statisticsProvider.current.distinctUntilChanged() - ) { tracingItem, testPCR, testRAT, statsData -> + statisticsProvider.current.distinctUntilChanged(), + appConfigProvider.currentConfig.map { it.coronaTestParameters }.distinctUntilChanged() + ) { tracingItem, testPCR, testRAT, statsData, coronaTestParameters -> val statePCR = testPCR.toSubmissionState() - val stateRAT = testRAT.toSubmissionState() + val stateRAT = testRAT.toSubmissionState(timeStamper.nowUTC, coronaTestParameters) val bothTestStates = setOf(statePCR, stateRAT) mutableListOf<HomeItem>().apply { when { @@ -277,14 +290,14 @@ class HomeFragmentViewModel @AssistedInject constructor( if (stateRAT == SubmissionStateRAT.NoTest) { add(testPCR.toTestCardItem()) } else { - add(testRAT.toTestCardItem()) + add(testRAT.toTestCardItem(coronaTestParameters)) add(testPCR.toTestCardItem()) } } else -> { add(testPCR.toTestCardItem()) if (stateRAT != SubmissionStateRAT.NoTest) { - add(testRAT.toTestCardItem()) + add(testRAT.toTestCardItem(coronaTestParameters)) add( TestUnregisteredCard.Item(SubmissionStatePCR.NoTest) { routeToScreen.postValue( @@ -292,7 +305,7 @@ class HomeFragmentViewModel @AssistedInject constructor( ) } ) - } else add(testRAT.toTestCardItem()) + } else add(testRAT.toTestCardItem(coronaTestParameters)) } } diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/appconfig/mapping/CoronaTestParametersDistinctTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/appconfig/mapping/CoronaTestParametersDistinctTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..1f71e9b78d2c72f0df2989e4a752b29bfdc5147e --- /dev/null +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/appconfig/mapping/CoronaTestParametersDistinctTest.kt @@ -0,0 +1,25 @@ +package de.rki.coronawarnapp.appconfig.mapping + +import de.rki.coronawarnapp.appconfig.CoronaRapidAntigenTestParametersContainer +import io.kotest.matchers.shouldBe +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.drop +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.test.runBlockingTest +import org.junit.Test +import testhelpers.BaseTest + +class CoronaTestParametersDistinctTest : BaseTest() { + + @Test + fun `can we use distinctUntilChanged on CoronaTestParameters`() = runBlockingTest { + val flow = flow { + emit(CoronaRapidAntigenTestParametersContainer(48)) + emit(CoronaRapidAntigenTestParametersContainer(48)) + emit(CoronaRapidAntigenTestParametersContainer(12)) + } + + flow.distinctUntilChanged().drop(1).first().hoursToDeemTestOutdated shouldBe 12 + } +} diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RapidAntigenCoronaTestExtensionsTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RapidAntigenCoronaTestExtensionsTest.kt index 48486b70cbcda1ec67315615d65c64bccc53fa88..ed1be6eb11aa6fa1b747bb51267f0a19f80c3a67 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RapidAntigenCoronaTestExtensionsTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/type/rapidantigen/RapidAntigenCoronaTestExtensionsTest.kt @@ -1,15 +1,32 @@ package de.rki.coronawarnapp.coronatest.type.rapidantigen +import de.rki.coronawarnapp.appconfig.CoronaTestConfig +import de.rki.coronawarnapp.util.TimeStamper import io.kotest.matchers.shouldBe +import io.mockk.MockKAnnotations +import io.mockk.every +import io.mockk.impl.annotations.MockK import kotlinx.coroutines.test.runBlockingTest +import org.joda.time.Instant +import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import testhelpers.BaseTest class RapidAntigenCoronaTestExtensionsTest : BaseTest() { + @MockK lateinit var coronaTestConfig: CoronaTestConfig + @MockK lateinit var timeStamper: TimeStamper + + @BeforeEach + fun setup() { + MockKAnnotations.init(this) + + every { timeStamper.nowUTC } returns Instant.ofEpochMilli(1010010101) + every { coronaTestConfig.coronaRapidAntigenTestParameters.hoursToDeemTestOutdated } returns 48 + } @Test fun `state determination, unregistered test`() = runBlockingTest { val test: RACoronaTest? = null - test.toSubmissionState() shouldBe SubmissionStateRAT.NoTest + test.toSubmissionState(timeStamper.nowUTC, coronaTestConfig) shouldBe SubmissionStateRAT.NoTest } } diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/main/home/HomeFragmentViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/main/home/HomeFragmentViewModelTest.kt index 43dc0a8ba7f789d898f1d03bc73bfb4d0f632097..5c027f688621adacfe73f360942ff6ae511c0823 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/main/home/HomeFragmentViewModelTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/main/home/HomeFragmentViewModelTest.kt @@ -18,6 +18,7 @@ import de.rki.coronawarnapp.tracing.ui.statusbar.TracingHeaderState import de.rki.coronawarnapp.ui.main.home.HomeFragmentEvents import de.rki.coronawarnapp.ui.main.home.HomeFragmentViewModel import de.rki.coronawarnapp.ui.presencetracing.organizer.TraceLocationOrganizerSettings +import de.rki.coronawarnapp.util.TimeStamper import de.rki.coronawarnapp.util.encryptionmigration.EncryptionErrorResetTool import de.rki.coronawarnapp.util.shortcuts.AppShortcutsHelper import io.kotest.matchers.shouldBe @@ -31,6 +32,7 @@ import io.mockk.mockkObject import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOf +import org.joda.time.Instant import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -59,6 +61,7 @@ class HomeFragmentViewModelTest : BaseTest() { @MockK lateinit var appShortcutsHelper: AppShortcutsHelper @MockK lateinit var tracingSettings: TracingSettings @MockK lateinit var traceLocationOrganizerSettings: TraceLocationOrganizerSettings + @MockK lateinit var timeStamper: TimeStamper @BeforeEach fun setup() { @@ -73,6 +76,8 @@ class HomeFragmentViewModelTest : BaseTest() { coEvery { appConfigProvider.currentConfig } returns emptyFlow() coEvery { statisticsProvider.current } returns emptyFlow() + + every { timeStamper.nowUTC } returns Instant.ofEpochMilli(100101010) } private fun createInstance(): HomeFragmentViewModel = HomeFragmentViewModel( @@ -89,7 +94,8 @@ class HomeFragmentViewModelTest : BaseTest() { deadmanNotificationScheduler = deadmanNotificationScheduler, appShortcutsHelper = appShortcutsHelper, tracingSettings = tracingSettings, - traceLocationOrganizerSettings = traceLocationOrganizerSettings + traceLocationOrganizerSettings = traceLocationOrganizerSettings, + timeStamper = timeStamper ) @Test