From 101ed1f272e3dd466445666f44b795f1dd47d539 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 8 Feb 2023 15:23:47 +0100 Subject: [PATCH] Add test for `CrashDetectionPresenter` --- .../crash/ui/CrashDetectionPresenterTest.kt | 89 +++++++++++++++++++ .../rageshake/crash/ui/FakeCrashDataStore.kt | 48 ++++++++++ 2 files changed, 137 insertions(+) create mode 100644 features/rageshake/src/test/kotlin/io/element/android/features/rageshake/crash/ui/CrashDetectionPresenterTest.kt create mode 100644 features/rageshake/src/test/kotlin/io/element/android/features/rageshake/crash/ui/FakeCrashDataStore.kt diff --git a/features/rageshake/src/test/kotlin/io/element/android/features/rageshake/crash/ui/CrashDetectionPresenterTest.kt b/features/rageshake/src/test/kotlin/io/element/android/features/rageshake/crash/ui/CrashDetectionPresenterTest.kt new file mode 100644 index 0000000000..16a03eca86 --- /dev/null +++ b/features/rageshake/src/test/kotlin/io/element/android/features/rageshake/crash/ui/CrashDetectionPresenterTest.kt @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:OptIn(ExperimentalCoroutinesApi::class) + +package io.element.android.features.rageshake.crash.ui + +import app.cash.molecule.RecompositionClock +import app.cash.molecule.moleculeFlow +import app.cash.turbine.test +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runTest +import org.junit.Test + +class CrashDetectionPresenterTest { + @Test + fun `present - initial state no crash`() = runTest { + val presenter = CrashDetectionPresenter( + FakeCrashDataStore() + ) + moleculeFlow(RecompositionClock.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + assertThat(initialState.crashDetected).isFalse() + } + } + + @Test + fun `present - initial state crash`() = runTest { + val presenter = CrashDetectionPresenter( + FakeCrashDataStore(appHasCrashed = true) + ) + moleculeFlow(RecompositionClock.Immediate) { + presenter.present() + }.test { + skipItems(1) + val initialState = awaitItem() + assertThat(initialState.crashDetected).isTrue() + + } + } + + @Test + fun `present - reset app has crashed`() = runTest { + val presenter = CrashDetectionPresenter( + FakeCrashDataStore(appHasCrashed = true) + ) + moleculeFlow(RecompositionClock.Immediate) { + presenter.present() + }.test { + skipItems(1) + val initialState = awaitItem() + assertThat(initialState.crashDetected).isTrue() + initialState.eventSink.invoke(CrashDetectionEvents.ResetAppHasCrashed) + assertThat(awaitItem().crashDetected).isFalse() + } + } + + @Test + fun `present - reset all crash data`() = runTest { + val presenter = CrashDetectionPresenter( + FakeCrashDataStore(appHasCrashed = true, crashData = A_CRASH_DATA) + ) + moleculeFlow(RecompositionClock.Immediate) { + presenter.present() + }.test { + skipItems(1) + val initialState = awaitItem() + assertThat(initialState.crashDetected).isTrue() + initialState.eventSink.invoke(CrashDetectionEvents.ResetAllCrashData) + assertThat(awaitItem().crashDetected).isFalse() + } + } +} diff --git a/features/rageshake/src/test/kotlin/io/element/android/features/rageshake/crash/ui/FakeCrashDataStore.kt b/features/rageshake/src/test/kotlin/io/element/android/features/rageshake/crash/ui/FakeCrashDataStore.kt new file mode 100644 index 0000000000..a757931d53 --- /dev/null +++ b/features/rageshake/src/test/kotlin/io/element/android/features/rageshake/crash/ui/FakeCrashDataStore.kt @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.rageshake.crash.ui + +import io.element.android.features.rageshake.crash.CrashDataStore +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow + +const val A_CRASH_DATA = "Some crash data" + +class FakeCrashDataStore( + crashData: String = "", + appHasCrashed: Boolean = false, +) : CrashDataStore { + private val appHasCrashedFlow = MutableStateFlow(appHasCrashed) + private val crashDataFlow = MutableStateFlow(crashData) + + override fun setCrashData(crashData: String) { + crashDataFlow.value = crashData + } + + override suspend fun resetAppHasCrashed() { + appHasCrashedFlow.value = false + } + + override fun appHasCrashed(): Flow = appHasCrashedFlow + + override fun crashInfo(): Flow = crashDataFlow + + override suspend fun reset() { + appHasCrashedFlow.value = false + crashDataFlow.value = "" + } +}