diff --git a/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt b/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt index 62a38146fc..1ba6c90369 100644 --- a/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt +++ b/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt @@ -20,6 +20,7 @@ import android.net.Uri import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Loading import com.airbnb.mvrx.Success +import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.test.MvRxTestRule import im.vector.app.features.DefaultVectorOverrides import im.vector.app.features.login.ReAuthHelper @@ -29,20 +30,27 @@ import im.vector.app.test.fakes.FakeAuthenticationService import im.vector.app.test.fakes.FakeContext import im.vector.app.test.fakes.FakeHomeServerConnectionConfigFactory import im.vector.app.test.fakes.FakeHomeServerHistoryService +import im.vector.app.test.fakes.FakeRegistrationWizard import im.vector.app.test.fakes.FakeSession import im.vector.app.test.fakes.FakeStringProvider import im.vector.app.test.fakes.FakeUri import im.vector.app.test.fakes.FakeUriFilenameResolver import im.vector.app.test.fakes.FakeVectorFeatures +import im.vector.app.test.fakes.FakeVectorOverrides import im.vector.app.test.test import kotlinx.coroutines.test.runBlockingTest import org.junit.Before import org.junit.Rule import org.junit.Test +import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities private const val A_DISPLAY_NAME = "a display name" private const val A_PICTURE_FILENAME = "a-picture.png" private val AN_ERROR = RuntimeException("an error!") +private val AN_UNSUPPORTED_PERSONALISATION_STATE = PersonalizationState( + supportsChangingDisplayName = false, + supportsChangingProfilePicture = false +) class OnboardingViewModelTest { @@ -55,6 +63,7 @@ class OnboardingViewModelTest { private val fakeSession = FakeSession() private val fakeUriFilenameResolver = FakeUriFilenameResolver() private val fakeActiveSessionHolder = FakeActiveSessionHolder(fakeSession) + private val fakeAuthenticationService = FakeAuthenticationService() lateinit var viewModel: OnboardingViewModel @@ -74,6 +83,33 @@ class OnboardingViewModelTest { .finish() } + @Test + fun `given homeserver does not support personalisation when registering account then updates state and emits account created event`() = runBlockingTest { + fakeSession.fakeHomeServerCapabilitiesService.givenCapabilities(HomeServerCapabilities(canChangeDisplayName = false, canChangeAvatar = false)) + givenSuccessfullyCreatesAccount() + val test = viewModel.test(this) + + viewModel.handle(OnboardingAction.RegisterDummy) + + test + .assertStates( + initialState, + initialState.copy(asyncRegistration = Loading()), + initialState.copy( + asyncLoginAction = Success(Unit), + asyncRegistration = Loading(), + personalizationState = AN_UNSUPPORTED_PERSONALISATION_STATE + ), + initialState.copy( + asyncLoginAction = Success(Unit), + asyncRegistration = Uninitialized, + personalizationState = AN_UNSUPPORTED_PERSONALISATION_STATE + ) + ) + .assertEvents(OnboardingViewEvents.OnAccountCreated) + .finish() + } + @Test fun `when handling display name update then updates upstream user display name`() = runBlockingTest { val test = viewModel.test(this) @@ -184,13 +220,14 @@ class OnboardingViewModelTest { return OnboardingViewModel( state, fakeContext.instance, - FakeAuthenticationService(), + fakeAuthenticationService, fakeActiveSessionHolder.instance, FakeHomeServerConnectionConfigFactory().instance, ReAuthHelper(), FakeStringProvider().instance, FakeHomeServerHistoryService(), FakeVectorFeatures(), + FakeVectorOverrides(), FakeAnalyticsTracker(), fakeUriFilenameResolver.instance, DefaultVectorOverrides() @@ -214,4 +251,12 @@ class OnboardingViewModelTest { state.copy(asyncProfilePicture = Loading()), state.copy(asyncProfilePicture = Fail(cause)) ) + + private fun givenSuccessfullyCreatesAccount() { + fakeActiveSessionHolder.expectSetsActiveSession(fakeSession) + val registrationWizard = FakeRegistrationWizard().also { it.givenSuccessfulDummy(fakeSession) } + fakeAuthenticationService.givenRegistrationWizard(registrationWizard) + fakeAuthenticationService.expectReset() + fakeSession.expectStartsSyncing() + } } diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeActiveSessionHolder.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeActiveSessionHolder.kt index 4b2264752a..d0825a0043 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeActiveSessionHolder.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeActiveSessionHolder.kt @@ -18,7 +18,9 @@ package im.vector.app.test.fakes import im.vector.app.core.di.ActiveSessionHolder import io.mockk.every +import io.mockk.justRun import io.mockk.mockk +import org.matrix.android.sdk.api.session.Session class FakeActiveSessionHolder( private val fakeSession: FakeSession = FakeSession() @@ -26,4 +28,8 @@ class FakeActiveSessionHolder( val instance = mockk { every { getActiveSession() } returns fakeSession } + + fun expectSetsActiveSession(session: Session) { + justRun { instance.setActiveSession(session) } + } } diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeAuthenticationService.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeAuthenticationService.kt index 9cdd7c9136..fc796b60d1 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeAuthenticationService.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeAuthenticationService.kt @@ -16,7 +16,19 @@ package im.vector.app.test.fakes +import io.mockk.coJustRun +import io.mockk.every +import io.mockk.justRun import io.mockk.mockk import org.matrix.android.sdk.api.auth.AuthenticationService +import org.matrix.android.sdk.api.auth.registration.RegistrationWizard -class FakeAuthenticationService : AuthenticationService by mockk() +class FakeAuthenticationService : AuthenticationService by mockk() { + fun givenRegistrationWizard(registrationWizard: RegistrationWizard) { + every { getRegistrationWizard() } returns registrationWizard + } + + fun expectReset() { + coJustRun { reset() } + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeHomeServerCapabilitiesService.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeHomeServerCapabilitiesService.kt new file mode 100644 index 0000000000..006789f62b --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeHomeServerCapabilitiesService.kt @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 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 im.vector.app.test.fakes + +import io.mockk.every +import io.mockk.mockk +import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities +import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService + +class FakeHomeServerCapabilitiesService : HomeServerCapabilitiesService by mockk() { + + fun givenCapabilities(homeServerCapabilities: HomeServerCapabilities) { + every { getHomeServerCapabilities() } returns homeServerCapabilities + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeRegistrationWizard.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeRegistrationWizard.kt new file mode 100644 index 0000000000..6ae394eea1 --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeRegistrationWizard.kt @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 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 im.vector.app.test.fakes + +import io.mockk.coEvery +import io.mockk.mockk +import org.matrix.android.sdk.api.auth.registration.RegistrationResult +import org.matrix.android.sdk.api.auth.registration.RegistrationWizard +import org.matrix.android.sdk.api.session.Session + +class FakeRegistrationWizard : RegistrationWizard by mockk() { + + fun givenSuccessfulDummy(session: Session) { + coEvery { dummy() } returns RegistrationResult.Success(session) + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeSession.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeSession.kt index 952a75cbeb..1fff67e982 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeSession.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeSession.kt @@ -17,10 +17,13 @@ package im.vector.app.test.fakes import android.net.Uri +import im.vector.app.core.extensions.configureAndStart +import im.vector.app.core.extensions.startSyncing import im.vector.app.core.extensions.vectorStore import im.vector.app.features.session.VectorSessionStore import im.vector.app.test.testCoroutineDispatchers import io.mockk.coEvery +import io.mockk.coJustRun import io.mockk.mockk import io.mockk.mockkStatic import org.matrix.android.sdk.api.session.Session @@ -28,6 +31,7 @@ import org.matrix.android.sdk.api.session.Session class FakeSession( val fakeCryptoService: FakeCryptoService = FakeCryptoService(), val fakeProfileService: FakeProfileService = FakeProfileService(), + val fakeHomeServerCapabilitiesService: FakeHomeServerCapabilitiesService = FakeHomeServerCapabilitiesService(), val fakeSharedSecretStorageService: FakeSharedSecretStorageService = FakeSharedSecretStorageService() ) : Session by mockk(relaxed = true) { @@ -42,6 +46,7 @@ class FakeSession( override val coroutineDispatchers = testCoroutineDispatchers override suspend fun setDisplayName(userId: String, newDisplayName: String) = fakeProfileService.setDisplayName(userId, newDisplayName) override suspend fun updateAvatar(userId: String, newAvatarUri: Uri, fileName: String) = fakeProfileService.updateAvatar(userId, newAvatarUri, fileName) + override fun getHomeServerCapabilities() = fakeHomeServerCapabilitiesService.getHomeServerCapabilities() fun givenVectorStore(vectorSessionStore: VectorSessionStore) { coEvery { @@ -50,4 +55,11 @@ class FakeSession( vectorSessionStore } } + + fun expectStartsSyncing() { + coJustRun { + this@FakeSession.configureAndStart(any(), startSyncing = true) + this@FakeSession.startSyncing(any()) + } + } } diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeVectorOverrides.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeVectorOverrides.kt new file mode 100644 index 0000000000..b47d887b8d --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeVectorOverrides.kt @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022 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 im.vector.app.test.fakes + +import im.vector.app.features.DefaultVectorOverrides +import im.vector.app.features.VectorOverrides +import io.mockk.mockk + +class FakeVectorOverrides : VectorOverrides by DefaultVectorOverrides()