diff --git a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/DefaultFtueStateTests.kt b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/DefaultFtueStateTests.kt index cfd489ea2a..908683227f 100644 --- a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/DefaultFtueStateTests.kt +++ b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/DefaultFtueStateTests.kt @@ -18,9 +18,14 @@ package io.element.android.features.ftue.impl import com.google.common.truth.Truth.assertThat import io.element.android.features.analytics.test.FakeAnalyticsService +import io.element.android.features.ftue.impl.migration.InMemoryMigrationScreenStore +import io.element.android.features.ftue.impl.migration.MigrationScreenStore import io.element.android.features.ftue.impl.state.DefaultFtueState import io.element.android.features.ftue.impl.state.FtueStep import io.element.android.features.ftue.impl.welcome.state.FakeWelcomeState +import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.test.A_SESSION_ID +import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.services.analytics.api.AnalyticsService import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob @@ -45,12 +50,14 @@ class DefaultFtueStateTests { fun `given all checks being true, should display flow is false`() = runTest { val welcomeState = FakeWelcomeState() val analyticsService = FakeAnalyticsService() + val migrationScreenStore = InMemoryMigrationScreenStore() val coroutineScope = CoroutineScope(coroutineContext + SupervisorJob()) - val state = createState(coroutineScope, welcomeState, analyticsService) + val state = createState(coroutineScope, welcomeState, analyticsService, migrationScreenStore) welcomeState.setWelcomeScreenShown() analyticsService.setDidAskUserConsent() + migrationScreenStore.setMigrationScreenShown(A_SESSION_ID) state.updateState() assertThat(state.shouldDisplayFlow.value).isFalse() @@ -63,16 +70,21 @@ class DefaultFtueStateTests { fun `traverse flow`() = runTest { val welcomeState = FakeWelcomeState() val analyticsService = FakeAnalyticsService() + val migrationScreenStore = InMemoryMigrationScreenStore() val coroutineScope = CoroutineScope(coroutineContext + SupervisorJob()) - val state = createState(coroutineScope, welcomeState, analyticsService) + val state = createState(coroutineScope, welcomeState, analyticsService, migrationScreenStore) val steps = mutableListOf() - // First step, welcome screen + // First step, migration screen + steps.add(state.getNextStep(steps.lastOrNull())) + migrationScreenStore.setMigrationScreenShown(A_SESSION_ID) + + // Second step, welcome screen steps.add(state.getNextStep(steps.lastOrNull())) welcomeState.setWelcomeScreenShown() - // Second step, analytics opt in + // Third step, analytics opt in steps.add(state.getNextStep(steps.lastOrNull())) analyticsService.setDidAskUserConsent() @@ -80,6 +92,7 @@ class DefaultFtueStateTests { steps.add(state.getNextStep(steps.lastOrNull())) assertThat(steps).containsExactly( + FtueStep.MigrationScreen, FtueStep.WelcomeScreen, FtueStep.AnalyticsOptIn, null, // Final state @@ -93,7 +106,16 @@ class DefaultFtueStateTests { fun `if a check for a step is true, start from the next one`() = runTest { val coroutineScope = CoroutineScope(coroutineContext + SupervisorJob()) val analyticsService = FakeAnalyticsService() - val state = createState(coroutineScope = coroutineScope, analyticsService = analyticsService) + val migrationScreenStore = InMemoryMigrationScreenStore() + + val state = createState( + coroutineScope = coroutineScope, + analyticsService = analyticsService, + migrationScreenStore = migrationScreenStore, + ) + + migrationScreenStore.setMigrationScreenShown(A_SESSION_ID) + assertThat(state.getNextStep()).isEqualTo(FtueStep.WelcomeScreen) state.setWelcomeScreenShown() assertThat(state.getNextStep()).isEqualTo(FtueStep.AnalyticsOptIn) @@ -108,7 +130,14 @@ class DefaultFtueStateTests { private fun createState( coroutineScope: CoroutineScope, welcomeState: FakeWelcomeState = FakeWelcomeState(), - analyticsService: AnalyticsService = FakeAnalyticsService() - ) = DefaultFtueState(coroutineScope, analyticsService, welcomeState) - + analyticsService: AnalyticsService = FakeAnalyticsService(), + migrationScreenStore: MigrationScreenStore = InMemoryMigrationScreenStore(), + matrixClient: MatrixClient = FakeMatrixClient(), + ) = DefaultFtueState( + coroutineScope = coroutineScope, + analyticsService = analyticsService, + welcomeScreenState = welcomeState, + migrationScreenStore = migrationScreenStore, + matrixClient = matrixClient, + ) } diff --git a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/migration/InMemoryMigrationScreenStore.kt b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/migration/InMemoryMigrationScreenStore.kt new file mode 100644 index 0000000000..a77a4d001a --- /dev/null +++ b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/migration/InMemoryMigrationScreenStore.kt @@ -0,0 +1,36 @@ +/* + * 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.ftue.impl.migration + +import io.element.android.libraries.matrix.api.core.SessionId + +class InMemoryMigrationScreenStore : MigrationScreenStore { + private val store = mutableMapOf() + + override fun isMigrationScreenNeeded(sessionId: SessionId): Boolean { + // If store does not have key return true, else return the opposite of the value + return store[sessionId]?.not() ?: true + } + + override fun setMigrationScreenShown(sessionId: SessionId) { + store[sessionId] = true + } + + override fun reset() { + store.clear() + } +}