diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewEvents.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewEvents.kt index 01de7c073a..ea6981a2b5 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewEvents.kt @@ -47,10 +47,11 @@ sealed class OnboardingViewEvents : VectorViewEvents { object OnHomeserverEdited : OnboardingViewEvents() data class OnSignModeSelected(val signMode: SignMode) : OnboardingViewEvents() object OnForgetPasswordClicked : OnboardingViewEvents() - data class OnResetPasswordSendThreePidDone(val email: String) : OnboardingViewEvents() - object OnResetPasswordMailConfirmationSuccess : OnboardingViewEvents() + + data class OnResetPasswordEmailConfirmationSent(val email: String) : OnboardingViewEvents() + object OpenResetPasswordComplete : OnboardingViewEvents() object OnResetPasswordBreakerConfirmed : OnboardingViewEvents() - object OnResetPasswordMailConfirmationSuccessDone : OnboardingViewEvents() + object OnResetPasswordComplete : OnboardingViewEvents() data class OnSendEmailSuccess(val email: String) : OnboardingViewEvents() data class OnSendMsisdnSuccess(val msisdn: String) : OnboardingViewEvents() diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index 650b308937..b5f5682be1 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -443,7 +443,7 @@ class OnboardingViewModel @AssistedInject constructor( private fun handleResetPassword(action: OnboardingAction.ResetPassword) { startResetPasswordFlow(action.email) { setState { copy(isLoading = false, resetState = createResetState(action, selectedHomeserver)) } - _viewEvents.post(OnboardingViewEvents.OnResetPasswordSendThreePidDone(action.email)) + _viewEvents.post(OnboardingViewEvents.OnResetPasswordEmailConfirmationSent(action.email)) } } @@ -506,7 +506,11 @@ class OnboardingViewModel @AssistedInject constructor( runCatching { loginWizard.resetPasswordMailConfirmed(newPassword, logoutAllDevices = logoutAllDevices) }.fold( onSuccess = { setState { copy(isLoading = false, resetState = ResetState()) } - _viewEvents.post(OnboardingViewEvents.OnResetPasswordMailConfirmationSuccess) + val nextEvent = when { + vectorFeatures.isOnboardingCombinedLoginEnabled() -> OnboardingViewEvents.OnResetPasswordComplete + else -> OnboardingViewEvents.OpenResetPasswordComplete + } + _viewEvents.post(nextEvent) }, onFailure = { setState { copy(isLoading = false) } diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordSuccessFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordSuccessFragment.kt index adc6e1b214..956566a587 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordSuccessFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordSuccessFragment.kt @@ -41,7 +41,7 @@ class FtueAuthResetPasswordSuccessFragment @Inject constructor() : AbstractFtueA } private fun submit() { - viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnResetPasswordMailConfirmationSuccessDone)) + viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnResetPasswordComplete)) } override fun resetViewModel() { diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt index 80375ec6c5..fa7de37650 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt @@ -29,7 +29,6 @@ import androidx.fragment.app.FragmentTransaction import com.airbnb.mvrx.withState import com.google.android.material.dialog.MaterialAlertDialogBuilder import im.vector.app.R -import im.vector.app.core.extensions.POP_BACK_STACK_EXCLUSIVE import im.vector.app.core.extensions.addFragment import im.vector.app.core.extensions.addFragmentToBackstack import im.vector.app.core.extensions.popBackstack @@ -166,7 +165,7 @@ class FtueAuthVariant( vectorFeatures.isOnboardingCombinedLoginEnabled() -> addLoginStageFragmentToBackstack(FtueAuthResetPasswordEmailEntryFragment::class.java) else -> addLoginStageFragmentToBackstack(FtueAuthResetPasswordFragment::class.java) } - is OnboardingViewEvents.OnResetPasswordSendThreePidDone -> { + is OnboardingViewEvents.OnResetPasswordEmailConfirmationSent -> { supportFragmentManager.popBackStack(FRAGMENT_LOGIN_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE) when { vectorFeatures.isOnboardingCombinedLoginEnabled() -> addLoginStageFragmentToBackstack( @@ -187,12 +186,11 @@ class FtueAuthVariant( option = commonOption ) } - is OnboardingViewEvents.OnResetPasswordMailConfirmationSuccess -> { + is OnboardingViewEvents.OpenResetPasswordComplete -> { supportFragmentManager.popBackStack(FRAGMENT_LOGIN_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE) addLoginStageFragmentToBackstack(FtueAuthResetPasswordSuccessFragment::class.java) } - is OnboardingViewEvents.OnResetPasswordMailConfirmationSuccessDone -> { - // Go back to the login fragment + OnboardingViewEvents.OnResetPasswordComplete -> { supportFragmentManager.popBackStack(FRAGMENT_LOGIN_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE) } is OnboardingViewEvents.OnSendEmailSuccess -> { 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 b0d539bdcc..c730c9b045 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 @@ -478,7 +478,7 @@ class OnboardingViewModelTest { } @Test - fun `given can successfully reset password, when resetting password, then emits reset done event`() = runTest { + fun `given can successfully start password reset, when resetting password, then emits confirmation email sent`() = runTest { viewModelWith(initialState.copy(selectedHomeserver = SELECTED_HOMESERVER_STATE_SUPPORTED_LOGOUT_DEVICES)) val test = viewModel.test() fakeLoginWizard.givenResetPasswordSuccess(AN_EMAIL) @@ -495,12 +495,12 @@ class OnboardingViewModelTest { copy(isLoading = false, resetState = resetState) } ) - .assertEvents(OnboardingViewEvents.OnResetPasswordSendThreePidDone(AN_EMAIL)) + .assertEvents(OnboardingViewEvents.OnResetPasswordEmailConfirmationSent(AN_EMAIL)) .finish() } @Test - fun `given reset state, when resending reset password email, then emits reset success`() = runTest { + fun `given reset state, when resending reset password email, then triggers reset password and emits nothing`() = runTest { viewModelWith(initialState.copy(resetState = ResetState(AN_EMAIL, A_PASSWORD))) val test = viewModel.test() fakeLoginWizard.givenResetPasswordSuccess(AN_EMAIL) @@ -516,12 +516,14 @@ class OnboardingViewModelTest { ) .assertNoEvents() .finish() + fakeLoginWizard.verifyResetPassword(AN_EMAIL) } @Test - fun `given can successfully confirm reset password, when confirm reset password, then emits reset success`() = runTest { + fun `given can successfully confirm reset password, when confirm reset password, then opens reset password complete`() = runTest { viewModelWith(initialState.copy(resetState = ResetState(AN_EMAIL, A_PASSWORD))) val test = viewModel.test() + fakeVectorFeatures.givenCombinedLoginDisabled() fakeLoginWizard.givenConfirmResetPasswordSuccess(A_PASSWORD) fakeAuthenticationService.givenLoginWizard(fakeLoginWizard) @@ -533,10 +535,31 @@ class OnboardingViewModelTest { { copy(isLoading = true) }, { copy(isLoading = false, resetState = ResetState()) } ) - .assertEvents(OnboardingViewEvents.OnResetPasswordMailConfirmationSuccess) + .assertEvents(OnboardingViewEvents.OpenResetPasswordComplete) .finish() } + @Test + fun `given can successfully confirm reset password, when confirm reset password, then emits reset password complete`() = runTest { + viewModelWith(initialState.copy(resetState = ResetState(AN_EMAIL, A_PASSWORD))) + val test = viewModel.test() + fakeVectorFeatures.givenCombinedLoginEnabled() + fakeLoginWizard.givenConfirmResetPasswordSuccess(A_PASSWORD) + fakeAuthenticationService.givenLoginWizard(fakeLoginWizard) + + viewModel.handle(OnboardingAction.ResetPasswordMailConfirmed) + + test + .assertStatesChanges( + initialState, + { copy(isLoading = true) }, + { copy(isLoading = false, resetState = ResetState()) } + ) + .assertEvents(OnboardingViewEvents.OnResetPasswordComplete) + .finish() + } + + private fun viewModelWith(state: OnboardingViewState) { OnboardingViewModel( state, diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeLoginWizard.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeLoginWizard.kt index 38bb75087c..07577ed61c 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeLoginWizard.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeLoginWizard.kt @@ -17,6 +17,7 @@ package im.vector.app.test.fakes import io.mockk.coJustRun +import io.mockk.coVerify import io.mockk.mockk import org.matrix.android.sdk.api.auth.login.LoginWizard @@ -29,4 +30,8 @@ class FakeLoginWizard : LoginWizard by mockk() { fun givenConfirmResetPasswordSuccess(password: String) { coJustRun { resetPasswordMailConfirmed(password) } } + + fun verifyResetPassword(email: String) { + coVerify { resetPassword(email) } + } } diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeVectorFeatures.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeVectorFeatures.kt index e227a1a686..0b150ae9d0 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeVectorFeatures.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeVectorFeatures.kt @@ -27,7 +27,11 @@ class FakeVectorFeatures : VectorFeatures by spyk() { every { isOnboardingPersonalizeEnabled() } returns true } - fun givenCombinedRegisterEnabled() { - every { isOnboardingCombinedRegisterEnabled() } returns true + fun givenCombinedLoginEnabled() { + every { isOnboardingCombinedLoginEnabled() } returns true + } + + fun givenCombinedLoginDisabled() { + every { isOnboardingCombinedLoginEnabled() } returns false } }