Merge pull request #5692 from element-hq/feature/bma/loginFlow
Improve account provider selection during the login flow
This commit is contained in:
commit
77bc9b811a
36 changed files with 366 additions and 254 deletions
|
|
@ -60,11 +60,12 @@ class ChangeServerPresenter(
|
|||
title = data.title,
|
||||
accountProviderUrl = data.url,
|
||||
)
|
||||
authenticationService.setHomeserver(data.url).map {
|
||||
authenticationService.getHomeserverDetails().value!!
|
||||
// Valid, remember user choice
|
||||
accountProviderDataSource.userSelection(data)
|
||||
}.getOrThrow()
|
||||
val details = authenticationService.setHomeserver(data.url).getOrThrow()
|
||||
if (!details.isSupported) {
|
||||
throw ChangeServerError.UnsupportedServer
|
||||
}
|
||||
// Homeserver is valid, remember user choice
|
||||
accountProviderDataSource.userSelection(data)
|
||||
}.runCatchingUpdatingState(changeServerAction, errorTransform = ChangeServerError::from)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,13 +10,12 @@ package io.element.android.features.login.impl.changeserver
|
|||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.features.login.impl.error.ChangeServerError
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
open class ChangeServerStateProvider : PreviewParameterProvider<ChangeServerState> {
|
||||
override val values: Sequence<ChangeServerState>
|
||||
get() = sequenceOf(
|
||||
aChangeServerState(),
|
||||
aChangeServerState(changeServerAction = AsyncData.Failure(ChangeServerError.Error(CommonStrings.error_unknown))),
|
||||
aChangeServerState(changeServerAction = AsyncData.Failure(ChangeServerError.Error(null))),
|
||||
aChangeServerState(changeServerAction = AsyncData.Failure(ChangeServerError.SlidingSyncAlert)),
|
||||
aChangeServerState(
|
||||
changeServerAction = AsyncData.Failure(
|
||||
|
|
@ -34,6 +33,11 @@ open class ChangeServerStateProvider : PreviewParameterProvider<ChangeServerStat
|
|||
),
|
||||
)
|
||||
),
|
||||
aChangeServerState(
|
||||
changeServerAction = AsyncData.Failure(
|
||||
ChangeServerError.UnsupportedServer
|
||||
)
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
|
|||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.theme.LocalBuildMeta
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
@Composable
|
||||
fun ChangeServerView(
|
||||
|
|
@ -39,10 +40,26 @@ fun ChangeServerView(
|
|||
when (state.changeServerAction) {
|
||||
is AsyncData.Failure -> {
|
||||
when (val error = state.changeServerAction.error as? ChangeServerError) {
|
||||
ChangeServerError.InvalidServer ->
|
||||
ErrorDialog(
|
||||
modifier = modifier,
|
||||
content = stringResource(R.string.screen_change_server_error_invalid_homeserver),
|
||||
onSubmit = {
|
||||
eventSink.invoke(ChangeServerEvents.ClearError)
|
||||
}
|
||||
)
|
||||
ChangeServerError.UnsupportedServer ->
|
||||
ErrorDialog(
|
||||
modifier = modifier,
|
||||
content = stringResource(R.string.screen_login_error_unsupported_authentication),
|
||||
onSubmit = {
|
||||
eventSink.invoke(ChangeServerEvents.ClearError)
|
||||
}
|
||||
)
|
||||
is ChangeServerError.Error -> {
|
||||
ErrorDialog(
|
||||
modifier = modifier,
|
||||
content = error.message(),
|
||||
content = error.messageStr ?: stringResource(CommonStrings.error_unknown),
|
||||
onSubmit = {
|
||||
eventSink.invoke(ChangeServerEvents.ClearError)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,24 +7,13 @@
|
|||
|
||||
package io.element.android.features.login.impl.error
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.ReadOnlyComposable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import io.element.android.features.login.impl.R
|
||||
import io.element.android.features.login.impl.changeserver.AccountProviderAccessException
|
||||
import io.element.android.libraries.matrix.api.auth.AuthenticationException
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
sealed class ChangeServerError : Exception() {
|
||||
data class Error(
|
||||
@StringRes val messageId: Int? = null,
|
||||
val messageStr: String? = null,
|
||||
) : ChangeServerError() {
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
fun message(): String = messageStr ?: stringResource(messageId ?: CommonStrings.error_unknown)
|
||||
}
|
||||
) : ChangeServerError()
|
||||
|
||||
data class NeedElementPro(
|
||||
val unauthorisedAccountProviderTitle: String,
|
||||
|
|
@ -37,11 +26,23 @@ sealed class ChangeServerError : Exception() {
|
|||
) : ChangeServerError()
|
||||
|
||||
data object SlidingSyncAlert : ChangeServerError()
|
||||
data object InvalidServer : ChangeServerError()
|
||||
data object UnsupportedServer : ChangeServerError()
|
||||
|
||||
companion object {
|
||||
fun from(error: Throwable): ChangeServerError = when (error) {
|
||||
is AuthenticationException.SlidingSyncVersion -> SlidingSyncAlert
|
||||
is AuthenticationException.Oidc -> Error(messageStr = error.message)
|
||||
is ChangeServerError -> error
|
||||
is AuthenticationException -> {
|
||||
when (error) {
|
||||
is AuthenticationException.SlidingSyncVersion -> SlidingSyncAlert
|
||||
is AuthenticationException.InvalidServerName,
|
||||
is AuthenticationException.ServerUnreachable -> InvalidServer
|
||||
// AccountAlreadyLoggedIn error should not happen at this point
|
||||
is AuthenticationException.AccountAlreadyLoggedIn -> Error(messageStr = error.message)
|
||||
is AuthenticationException.Generic -> Error(messageStr = error.message)
|
||||
is AuthenticationException.Oidc -> Error(messageStr = error.message)
|
||||
}
|
||||
}
|
||||
is AccountProviderAccessException.NeedElementProException -> NeedElementPro(
|
||||
unauthorisedAccountProviderTitle = error.unauthorisedAccountProviderTitle,
|
||||
applicationId = error.applicationId,
|
||||
|
|
@ -50,7 +51,7 @@ sealed class ChangeServerError : Exception() {
|
|||
unauthorisedAccountProviderTitle = error.unauthorisedAccountProviderTitle,
|
||||
authorisedAccountProviderTitles = error.authorisedAccountProviderTitles,
|
||||
)
|
||||
else -> Error(messageId = R.string.screen_change_server_error_invalid_homeserver)
|
||||
else -> Error(messageStr = error.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,14 +8,11 @@
|
|||
package io.element.android.features.login.impl.error
|
||||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.features.login.impl.R
|
||||
|
||||
class ChangeServerErrorProvider : PreviewParameterProvider<ChangeServerError> {
|
||||
override val values: Sequence<ChangeServerError>
|
||||
get() = sequenceOf(
|
||||
ChangeServerError.Error(
|
||||
messageId = R.string.screen_change_server_error_invalid_homeserver,
|
||||
),
|
||||
ChangeServerError.InvalidServer,
|
||||
ChangeServerError.Error(
|
||||
messageStr = "An error description",
|
||||
),
|
||||
|
|
@ -28,5 +25,6 @@ class ChangeServerErrorProvider : PreviewParameterProvider<ChangeServerError> {
|
|||
authorisedAccountProviderTitles = listOf("provider.org", "provider.io"),
|
||||
),
|
||||
ChangeServerError.SlidingSyncAlert,
|
||||
ChangeServerError.UnsupportedServer,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,8 +65,7 @@ class LoginHelper(
|
|||
loginHint: String?,
|
||||
) = coroutineScope.launch {
|
||||
suspend {
|
||||
authenticationService.setHomeserver(homeserverUrl).map {
|
||||
val matrixHomeServerDetails = authenticationService.getHomeserverDetails().value!!
|
||||
authenticationService.setHomeserver(homeserverUrl).map { matrixHomeServerDetails ->
|
||||
if (matrixHomeServerDetails.supportsOidcLogin) {
|
||||
// Retrieve the details right now
|
||||
val oidcPrompt = if (isAccountCreation) OidcPrompt.Create else OidcPrompt.Login
|
||||
|
|
|
|||
|
|
@ -41,9 +41,20 @@ fun LoginModeView(
|
|||
when (val error = loginMode.error) {
|
||||
is ChangeServerError -> {
|
||||
when (error) {
|
||||
ChangeServerError.InvalidServer ->
|
||||
ErrorDialog(
|
||||
content = stringResource(R.string.screen_change_server_error_invalid_homeserver),
|
||||
onSubmit = onClearError,
|
||||
)
|
||||
is ChangeServerError.UnsupportedServer -> {
|
||||
ErrorDialog(
|
||||
content = stringResource(R.string.screen_login_error_unsupported_authentication),
|
||||
onSubmit = onClearError,
|
||||
)
|
||||
}
|
||||
is ChangeServerError.Error -> {
|
||||
ErrorDialog(
|
||||
content = error.message(),
|
||||
content = error.messageStr ?: stringResource(CommonStrings.error_unknown),
|
||||
onSubmit = onClearError,
|
||||
)
|
||||
}
|
||||
|
|
@ -91,7 +102,7 @@ fun LoginModeView(
|
|||
}
|
||||
is AuthenticationException.AccountAlreadyLoggedIn -> {
|
||||
ErrorDialog(
|
||||
content = stringResource(CommonStrings.error_account_already_logged_in, error.message.orEmpty()),
|
||||
content = stringResource(CommonStrings.error_account_already_logged_in, error.userId),
|
||||
onSubmit = onClearError,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,9 +52,10 @@ class HomeserverResolver(
|
|||
}
|
||||
}
|
||||
}
|
||||
// If list is empty, and the user has entered an URL, do not block the user.
|
||||
if (currentList.isEmpty() && trimmedUserInput.isValidUrl()) {
|
||||
emit(listOf(HomeserverData(homeserverUrl = trimmedUserInput)))
|
||||
// If list is empty, and candidateBase is a valid an URL, do not block the user.
|
||||
// A unsupported homeserver / homeserver not found error will be displayed if the user continues
|
||||
if (currentList.isEmpty() && candidateBase.isValidUrl()) {
|
||||
emit(listOf(HomeserverData(homeserverUrl = candidateBase)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,5 +43,5 @@ fun aHomeserverDataList(): List<HomeserverData> {
|
|||
fun aHomeserverData(
|
||||
homeserverUrl: String = AuthenticationConfig.MATRIX_ORG_URL,
|
||||
): HomeserverData {
|
||||
return HomeserverData(homeserverUrl = homeserverUrl,)
|
||||
return HomeserverData(homeserverUrl = homeserverUrl)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,9 +18,10 @@ import io.element.android.features.wellknown.test.FakeWellknownRetriever
|
|||
import io.element.android.features.wellknown.test.anElementWellKnown
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.core.uri.ensureProtocol
|
||||
import io.element.android.libraries.matrix.test.A_HOMESERVER
|
||||
import io.element.android.libraries.matrix.test.AN_EXCEPTION
|
||||
import io.element.android.libraries.matrix.test.A_HOMESERVER_URL
|
||||
import io.element.android.libraries.matrix.test.auth.FakeMatrixAuthenticationService
|
||||
import io.element.android.libraries.matrix.test.auth.aMatrixHomeServerDetails
|
||||
import io.element.android.libraries.wellknown.api.ElementWellKnown
|
||||
import io.element.android.libraries.wellknown.api.WellknownRetriever
|
||||
import io.element.android.libraries.wellknown.api.WellknownRetrieverResult
|
||||
|
|
@ -46,7 +47,11 @@ class ChangeServerPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `present - change server ok`() = runTest {
|
||||
val authenticationService = FakeMatrixAuthenticationService()
|
||||
val authenticationService = FakeMatrixAuthenticationService(
|
||||
setHomeserverResult = {
|
||||
Result.success(aMatrixHomeServerDetails(supportsOidcLogin = true))
|
||||
},
|
||||
)
|
||||
createPresenter(
|
||||
authenticationService = authenticationService,
|
||||
enterpriseService = FakeEnterpriseService(
|
||||
|
|
@ -55,7 +60,6 @@ class ChangeServerPresenterTest {
|
|||
).test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.changeServerAction).isEqualTo(AsyncData.Uninitialized)
|
||||
authenticationService.givenHomeserver(A_HOMESERVER)
|
||||
initialState.eventSink.invoke(ChangeServerEvents.ChangeServer(AccountProvider(url = A_HOMESERVER_URL)))
|
||||
val loadingState = awaitItem()
|
||||
assertThat(loadingState.changeServerAction).isInstanceOf(AsyncData.Loading::class.java)
|
||||
|
|
@ -66,10 +70,16 @@ class ChangeServerPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `present - change server error`() = runTest {
|
||||
val authenticationService = FakeMatrixAuthenticationService(
|
||||
setHomeserverResult = {
|
||||
Result.failure(AN_EXCEPTION)
|
||||
},
|
||||
)
|
||||
createPresenter(
|
||||
enterpriseService = FakeEnterpriseService(
|
||||
isAllowedToConnectToHomeserverResult = { true },
|
||||
),
|
||||
authenticationService = authenticationService,
|
||||
).test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.changeServerAction).isEqualTo(AsyncData.Uninitialized)
|
||||
|
|
@ -85,6 +95,32 @@ class ChangeServerPresenterTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - change server unsupported server`() = runTest {
|
||||
val authenticationService = FakeMatrixAuthenticationService(
|
||||
setHomeserverResult = {
|
||||
Result.success(aMatrixHomeServerDetails())
|
||||
},
|
||||
)
|
||||
createPresenter(
|
||||
enterpriseService = FakeEnterpriseService(
|
||||
isAllowedToConnectToHomeserverResult = { true },
|
||||
),
|
||||
authenticationService = authenticationService,
|
||||
).test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.changeServerAction).isEqualTo(AsyncData.Uninitialized)
|
||||
initialState.eventSink.invoke(ChangeServerEvents.ChangeServer(AccountProvider(url = A_HOMESERVER_URL)))
|
||||
val loadingState = awaitItem()
|
||||
assertThat(loadingState.changeServerAction).isInstanceOf(AsyncData.Loading::class.java)
|
||||
val failureState = awaitItem()
|
||||
assertThat(failureState.changeServerAction).isInstanceOf(AsyncData.Failure::class.java)
|
||||
assertThat(failureState.changeServerAction.errorOrNull()).isEqualTo(
|
||||
ChangeServerError.UnsupportedServer
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - change server not allowed error`() = runTest {
|
||||
val isAllowedToConnectToHomeserverResult = lambdaRecorder<String, Boolean> { false }
|
||||
|
|
|
|||
|
|
@ -7,9 +7,6 @@
|
|||
|
||||
package io.element.android.features.login.impl.screens.changeaccountprovider
|
||||
|
||||
import app.cash.molecule.RecompositionMode
|
||||
import app.cash.molecule.moleculeFlow
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.features.enterprise.api.EnterpriseService
|
||||
import io.element.android.features.enterprise.test.FakeEnterpriseService
|
||||
|
|
@ -18,6 +15,7 @@ import io.element.android.features.login.impl.changeserver.aChangeServerState
|
|||
import io.element.android.libraries.matrix.test.AN_ACCOUNT_PROVIDER
|
||||
import io.element.android.libraries.matrix.test.AN_ACCOUNT_PROVIDER_2
|
||||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import io.element.android.tests.testutils.test
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
|
@ -34,9 +32,7 @@ class ChangeAccountProviderPresenterTest {
|
|||
defaultHomeserverListResult = { emptyList() }
|
||||
),
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.accountProviders).isEqualTo(
|
||||
listOf(
|
||||
|
|
@ -63,9 +59,7 @@ class ChangeAccountProviderPresenterTest {
|
|||
}
|
||||
),
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.accountProviders).isEqualTo(
|
||||
listOf(
|
||||
|
|
@ -99,9 +93,7 @@ class ChangeAccountProviderPresenterTest {
|
|||
}
|
||||
),
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.accountProviders).isEqualTo(
|
||||
listOf(
|
||||
|
|
|
|||
|
|
@ -95,7 +95,11 @@ class ChooseAccountProviderPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `present - select account provider and continue - error then clear error`() = runTest {
|
||||
val authenticationService = FakeMatrixAuthenticationService()
|
||||
val authenticationService = FakeMatrixAuthenticationService(
|
||||
setHomeserverResult = {
|
||||
Result.failure(AN_EXCEPTION)
|
||||
},
|
||||
)
|
||||
val presenter = createPresenter(
|
||||
enterpriseService = FakeEnterpriseService(
|
||||
defaultHomeserverListResult = { listOf(ACCOUNT_PROVIDER_FROM_CONFIG_1, ACCOUNT_PROVIDER_FROM_CONFIG_2) },
|
||||
|
|
@ -111,7 +115,6 @@ class ChooseAccountProviderPresenterTest {
|
|||
}
|
||||
awaitItem().also {
|
||||
assertThat(it.selectedAccountProvider).isEqualTo(accountProvider1)
|
||||
authenticationService.givenChangeServerError(AN_EXCEPTION)
|
||||
it.eventSink(ChooseAccountProviderEvents.Continue)
|
||||
skipItems(1) // Loading
|
||||
|
||||
|
|
|
|||
|
|
@ -7,9 +7,6 @@
|
|||
|
||||
package io.element.android.features.login.impl.screens.confirmaccountprovider
|
||||
|
||||
import app.cash.molecule.RecompositionMode
|
||||
import app.cash.molecule.moleculeFlow
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.appconfig.AuthenticationConfig
|
||||
import io.element.android.features.enterprise.test.FakeEnterpriseService
|
||||
|
|
@ -22,13 +19,13 @@ import io.element.android.features.login.impl.web.WebClientUrlForAuthenticationR
|
|||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
|
||||
import io.element.android.libraries.matrix.test.AN_EXCEPTION
|
||||
import io.element.android.libraries.matrix.test.A_HOMESERVER
|
||||
import io.element.android.libraries.matrix.test.A_HOMESERVER_OIDC
|
||||
import io.element.android.libraries.matrix.test.auth.FakeMatrixAuthenticationService
|
||||
import io.element.android.libraries.matrix.test.auth.aMatrixHomeServerDetails
|
||||
import io.element.android.libraries.oidc.api.OidcAction
|
||||
import io.element.android.libraries.oidc.api.OidcActionFlow
|
||||
import io.element.android.libraries.oidc.test.customtab.FakeOidcActionFlow
|
||||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import io.element.android.tests.testutils.test
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
|
@ -40,9 +37,7 @@ class ConfirmAccountProviderPresenterTest {
|
|||
@Test
|
||||
fun `present - initial test`() = runTest {
|
||||
val presenter = createConfirmAccountProviderPresenter()
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.isAccountCreation).isFalse()
|
||||
assertThat(initialState.submitEnabled).isTrue()
|
||||
|
|
@ -53,14 +48,15 @@ class ConfirmAccountProviderPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `present - continue password login`() = runTest {
|
||||
val authenticationService = FakeMatrixAuthenticationService()
|
||||
val authenticationService = FakeMatrixAuthenticationService(
|
||||
setHomeserverResult = {
|
||||
Result.success(aMatrixHomeServerDetails(supportsPasswordLogin = true))
|
||||
},
|
||||
)
|
||||
val presenter = createConfirmAccountProviderPresenter(
|
||||
matrixAuthenticationService = authenticationService,
|
||||
)
|
||||
authenticationService.givenHomeserver(A_HOMESERVER)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue)
|
||||
val loadingState = awaitItem()
|
||||
|
|
@ -75,14 +71,15 @@ class ConfirmAccountProviderPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `present - continue oidc`() = runTest {
|
||||
val authenticationService = FakeMatrixAuthenticationService()
|
||||
val authenticationService = FakeMatrixAuthenticationService(
|
||||
setHomeserverResult = {
|
||||
Result.success(aMatrixHomeServerDetails(supportsOidcLogin = true))
|
||||
},
|
||||
)
|
||||
val presenter = createConfirmAccountProviderPresenter(
|
||||
matrixAuthenticationService = authenticationService,
|
||||
)
|
||||
authenticationService.givenHomeserver(A_HOMESERVER_OIDC)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue)
|
||||
val loadingState = awaitItem()
|
||||
|
|
@ -97,16 +94,17 @@ class ConfirmAccountProviderPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `present - oidc - cancel with failure`() = runTest {
|
||||
val authenticationService = FakeMatrixAuthenticationService()
|
||||
val authenticationService = FakeMatrixAuthenticationService(
|
||||
setHomeserverResult = {
|
||||
Result.success(aMatrixHomeServerDetails(supportsOidcLogin = true))
|
||||
},
|
||||
)
|
||||
val defaultOidcActionFlow = FakeOidcActionFlow()
|
||||
val presenter = createConfirmAccountProviderPresenter(
|
||||
matrixAuthenticationService = authenticationService,
|
||||
defaultOidcActionFlow = defaultOidcActionFlow,
|
||||
)
|
||||
authenticationService.givenHomeserver(A_HOMESERVER_OIDC)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue)
|
||||
val loadingState = awaitItem()
|
||||
|
|
@ -125,16 +123,17 @@ class ConfirmAccountProviderPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `present - oidc - cancel with success`() = runTest {
|
||||
val authenticationService = FakeMatrixAuthenticationService()
|
||||
val authenticationService = FakeMatrixAuthenticationService(
|
||||
setHomeserverResult = {
|
||||
Result.success(aMatrixHomeServerDetails(supportsOidcLogin = true))
|
||||
},
|
||||
)
|
||||
val defaultOidcActionFlow = FakeOidcActionFlow()
|
||||
val presenter = createConfirmAccountProviderPresenter(
|
||||
matrixAuthenticationService = authenticationService,
|
||||
defaultOidcActionFlow = defaultOidcActionFlow,
|
||||
)
|
||||
authenticationService.givenHomeserver(A_HOMESERVER_OIDC)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue)
|
||||
val loadingState = awaitItem()
|
||||
|
|
@ -152,16 +151,17 @@ class ConfirmAccountProviderPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `present - oidc - cancel to unblock`() = runTest {
|
||||
val authenticationService = FakeMatrixAuthenticationService()
|
||||
val authenticationService = FakeMatrixAuthenticationService(
|
||||
setHomeserverResult = {
|
||||
Result.success(aMatrixHomeServerDetails(supportsOidcLogin = true))
|
||||
},
|
||||
)
|
||||
val defaultOidcActionFlow = FakeOidcActionFlow()
|
||||
val presenter = createConfirmAccountProviderPresenter(
|
||||
matrixAuthenticationService = authenticationService,
|
||||
defaultOidcActionFlow = defaultOidcActionFlow,
|
||||
)
|
||||
authenticationService.givenHomeserver(A_HOMESERVER_OIDC)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue)
|
||||
val loadingState = awaitItem()
|
||||
|
|
@ -175,16 +175,17 @@ class ConfirmAccountProviderPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `present - oidc - success with failure`() = runTest {
|
||||
val authenticationService = FakeMatrixAuthenticationService()
|
||||
val authenticationService = FakeMatrixAuthenticationService(
|
||||
setHomeserverResult = {
|
||||
Result.success(aMatrixHomeServerDetails(supportsOidcLogin = true))
|
||||
},
|
||||
)
|
||||
val defaultOidcActionFlow = FakeOidcActionFlow()
|
||||
val presenter = createConfirmAccountProviderPresenter(
|
||||
matrixAuthenticationService = authenticationService,
|
||||
defaultOidcActionFlow = defaultOidcActionFlow,
|
||||
)
|
||||
authenticationService.givenHomeserver(A_HOMESERVER_OIDC)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue)
|
||||
val loadingState = awaitItem()
|
||||
|
|
@ -205,16 +206,17 @@ class ConfirmAccountProviderPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `present - oidc - success with success`() = runTest {
|
||||
val authenticationService = FakeMatrixAuthenticationService()
|
||||
val authenticationService = FakeMatrixAuthenticationService(
|
||||
setHomeserverResult = {
|
||||
Result.success(aMatrixHomeServerDetails(supportsOidcLogin = true))
|
||||
},
|
||||
)
|
||||
val defaultOidcActionFlow = FakeOidcActionFlow()
|
||||
val presenter = createConfirmAccountProviderPresenter(
|
||||
matrixAuthenticationService = authenticationService,
|
||||
defaultOidcActionFlow = defaultOidcActionFlow,
|
||||
)
|
||||
authenticationService.givenHomeserver(A_HOMESERVER_OIDC)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue)
|
||||
val loadingState = awaitItem()
|
||||
|
|
@ -232,15 +234,16 @@ class ConfirmAccountProviderPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `present - submit fails`() = runTest {
|
||||
val authenticationService = FakeMatrixAuthenticationService()
|
||||
val authenticationService = FakeMatrixAuthenticationService(
|
||||
setHomeserverResult = {
|
||||
Result.failure(AN_EXCEPTION)
|
||||
},
|
||||
)
|
||||
val presenter = createConfirmAccountProviderPresenter(
|
||||
matrixAuthenticationService = authenticationService,
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
authenticationService.givenChangeServerError(RuntimeException())
|
||||
initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue)
|
||||
skipItems(1) // Loading
|
||||
val failureState = awaitItem()
|
||||
|
|
@ -251,17 +254,18 @@ class ConfirmAccountProviderPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `present - clear error`() = runTest {
|
||||
val authenticationService = FakeMatrixAuthenticationService()
|
||||
val authenticationService = FakeMatrixAuthenticationService(
|
||||
setHomeserverResult = {
|
||||
Result.failure(AN_EXCEPTION)
|
||||
},
|
||||
)
|
||||
val presenter = createConfirmAccountProviderPresenter(
|
||||
matrixAuthenticationService = authenticationService,
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
|
||||
// Submit will return an error
|
||||
authenticationService.givenChangeServerError(AN_EXCEPTION)
|
||||
initialState.eventSink(ConfirmAccountProviderEvents.Continue)
|
||||
|
||||
skipItems(1) // Loading
|
||||
|
|
@ -279,8 +283,11 @@ class ConfirmAccountProviderPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `present - confirm account creation without oidc and without url generates an error`() = runTest {
|
||||
val authenticationService = FakeMatrixAuthenticationService()
|
||||
authenticationService.givenHomeserver(A_HOMESERVER)
|
||||
val authenticationService = FakeMatrixAuthenticationService(
|
||||
setHomeserverResult = {
|
||||
Result.success(aMatrixHomeServerDetails())
|
||||
},
|
||||
)
|
||||
val presenter = createConfirmAccountProviderPresenter(
|
||||
params = ConfirmAccountProviderPresenter.Params(isAccountCreation = true),
|
||||
matrixAuthenticationService = authenticationService,
|
||||
|
|
@ -288,9 +295,7 @@ class ConfirmAccountProviderPresenterTest {
|
|||
throw AccountCreationNotSupported()
|
||||
},
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(ConfirmAccountProviderEvents.Continue)
|
||||
skipItems(1) // Loading
|
||||
|
|
@ -306,15 +311,16 @@ class ConfirmAccountProviderPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `present - confirm account creation with oidc is successful`() = runTest {
|
||||
val authenticationService = FakeMatrixAuthenticationService()
|
||||
authenticationService.givenHomeserver(A_HOMESERVER_OIDC)
|
||||
val authenticationService = FakeMatrixAuthenticationService(
|
||||
setHomeserverResult = {
|
||||
Result.success(aMatrixHomeServerDetails(supportsOidcLogin = true))
|
||||
},
|
||||
)
|
||||
val presenter = createConfirmAccountProviderPresenter(
|
||||
params = ConfirmAccountProviderPresenter.Params(isAccountCreation = true),
|
||||
matrixAuthenticationService = authenticationService,
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(ConfirmAccountProviderEvents.Continue)
|
||||
skipItems(1) // Loading
|
||||
|
|
@ -327,16 +333,17 @@ class ConfirmAccountProviderPresenterTest {
|
|||
@Test
|
||||
fun `present - confirm account creation with oidc and url continues with oidc`() = runTest {
|
||||
val aUrl = "aUrl"
|
||||
val authenticationService = FakeMatrixAuthenticationService()
|
||||
authenticationService.givenHomeserver(A_HOMESERVER_OIDC)
|
||||
val authenticationService = FakeMatrixAuthenticationService(
|
||||
setHomeserverResult = {
|
||||
Result.success(aMatrixHomeServerDetails(supportsOidcLogin = true))
|
||||
},
|
||||
)
|
||||
val presenter = createConfirmAccountProviderPresenter(
|
||||
params = ConfirmAccountProviderPresenter.Params(isAccountCreation = true),
|
||||
matrixAuthenticationService = authenticationService,
|
||||
webClientUrlForAuthenticationRetriever = FakeWebClientUrlForAuthenticationRetriever { aUrl },
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(ConfirmAccountProviderEvents.Continue)
|
||||
skipItems(1) // Loading
|
||||
|
|
@ -349,16 +356,17 @@ class ConfirmAccountProviderPresenterTest {
|
|||
@Test
|
||||
fun `present - confirm account creation without oidc and with url continuing with url`() = runTest {
|
||||
val aUrl = "aUrl"
|
||||
val authenticationService = FakeMatrixAuthenticationService()
|
||||
authenticationService.givenHomeserver(A_HOMESERVER)
|
||||
val authenticationService = FakeMatrixAuthenticationService(
|
||||
setHomeserverResult = {
|
||||
Result.success(aMatrixHomeServerDetails())
|
||||
},
|
||||
)
|
||||
val presenter = createConfirmAccountProviderPresenter(
|
||||
params = ConfirmAccountProviderPresenter.Params(isAccountCreation = true),
|
||||
matrixAuthenticationService = authenticationService,
|
||||
webClientUrlForAuthenticationRetriever = FakeWebClientUrlForAuthenticationRetriever { aUrl },
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(ConfirmAccountProviderEvents.Continue)
|
||||
skipItems(1) // Loading
|
||||
|
|
|
|||
|
|
@ -7,9 +7,6 @@
|
|||
|
||||
package io.element.android.features.login.impl.screens.createaccount
|
||||
|
||||
import app.cash.molecule.RecompositionMode
|
||||
import app.cash.molecule.moleculeFlow
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.core.meta.BuildMeta
|
||||
|
|
@ -26,6 +23,7 @@ import io.element.android.libraries.matrix.test.verification.FakeSessionVerifica
|
|||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||
import io.element.android.tests.testutils.lambda.value
|
||||
import io.element.android.tests.testutils.test
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
|
@ -37,9 +35,7 @@ class CreateAccountPresenterTest {
|
|||
@Test
|
||||
fun `present - initial state`() = runTest {
|
||||
val presenter = createPresenter()
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.url).isEqualTo("aUrl")
|
||||
assertThat(initialState.pageProgress).isEqualTo(0)
|
||||
|
|
@ -51,9 +47,7 @@ class CreateAccountPresenterTest {
|
|||
@Test
|
||||
fun `present - set up progress update the state`() = runTest {
|
||||
val presenter = createPresenter()
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(CreateAccountEvents.SetPageProgress(33))
|
||||
assertThat(awaitItem().pageProgress).isEqualTo(33)
|
||||
|
|
@ -65,9 +59,7 @@ class CreateAccountPresenterTest {
|
|||
val presenter = createPresenter(
|
||||
messageParser = FakeMessageParser { error("An error") }
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(CreateAccountEvents.OnMessageReceived(""))
|
||||
assertThat(awaitItem().createAction).isInstanceOf(AsyncAction.Failure::class.java)
|
||||
|
|
@ -77,9 +69,7 @@ class CreateAccountPresenterTest {
|
|||
@Test
|
||||
fun `present - receiving a message containing isTrusted is ignored`() = runTest {
|
||||
val presenter = createPresenter()
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(CreateAccountEvents.OnMessageReceived("isTrusted"))
|
||||
}
|
||||
|
|
@ -98,9 +88,7 @@ class CreateAccountPresenterTest {
|
|||
messageParser = FakeMessageParser(lambda),
|
||||
clientProvider = clientProvider,
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(CreateAccountEvents.OnMessageReceived("aMessage"))
|
||||
assertThat(awaitItem().createAction.isLoading()).isTrue()
|
||||
|
|
@ -118,9 +106,7 @@ class CreateAccountPresenterTest {
|
|||
),
|
||||
messageParser = FakeMessageParser { anExternalSession() }
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(CreateAccountEvents.OnMessageReceived(""))
|
||||
assertThat(awaitItem().createAction.isLoading()).isTrue()
|
||||
|
|
|
|||
|
|
@ -14,11 +14,11 @@ import io.element.android.features.login.impl.accountprovider.AccountProviderDat
|
|||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.matrix.api.core.SessionId
|
||||
import io.element.android.libraries.matrix.test.AN_EXCEPTION
|
||||
import io.element.android.libraries.matrix.test.A_HOMESERVER
|
||||
import io.element.android.libraries.matrix.test.A_PASSWORD
|
||||
import io.element.android.libraries.matrix.test.A_SESSION_ID
|
||||
import io.element.android.libraries.matrix.test.A_USER_NAME
|
||||
import io.element.android.libraries.matrix.test.auth.FakeMatrixAuthenticationService
|
||||
import io.element.android.libraries.matrix.test.auth.aMatrixHomeServerDetails
|
||||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import io.element.android.tests.testutils.test
|
||||
import kotlinx.coroutines.test.runTest
|
||||
|
|
@ -42,8 +42,11 @@ class LoginPasswordPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `present - enter login and password`() = runTest {
|
||||
val authenticationService = FakeMatrixAuthenticationService()
|
||||
authenticationService.givenHomeserver(A_HOMESERVER)
|
||||
val authenticationService = FakeMatrixAuthenticationService(
|
||||
setHomeserverResult = {
|
||||
Result.success(aMatrixHomeServerDetails())
|
||||
},
|
||||
)
|
||||
createLoginPasswordPresenter(
|
||||
authenticationService = authenticationService,
|
||||
).test {
|
||||
|
|
@ -61,8 +64,11 @@ class LoginPasswordPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `present - submit`() = runTest {
|
||||
val authenticationService = FakeMatrixAuthenticationService()
|
||||
authenticationService.givenHomeserver(A_HOMESERVER)
|
||||
val authenticationService = FakeMatrixAuthenticationService(
|
||||
setHomeserverResult = {
|
||||
Result.success(aMatrixHomeServerDetails())
|
||||
},
|
||||
)
|
||||
createLoginPasswordPresenter(
|
||||
authenticationService = authenticationService,
|
||||
).test {
|
||||
|
|
@ -81,8 +87,11 @@ class LoginPasswordPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `present - submit with error`() = runTest {
|
||||
val authenticationService = FakeMatrixAuthenticationService()
|
||||
authenticationService.givenHomeserver(A_HOMESERVER)
|
||||
val authenticationService = FakeMatrixAuthenticationService(
|
||||
setHomeserverResult = {
|
||||
Result.success(aMatrixHomeServerDetails())
|
||||
},
|
||||
)
|
||||
createLoginPasswordPresenter(
|
||||
authenticationService = authenticationService,
|
||||
).test {
|
||||
|
|
@ -102,8 +111,11 @@ class LoginPasswordPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `present - clear error`() = runTest {
|
||||
val authenticationService = FakeMatrixAuthenticationService()
|
||||
authenticationService.givenHomeserver(A_HOMESERVER)
|
||||
val authenticationService = FakeMatrixAuthenticationService(
|
||||
setHomeserverResult = {
|
||||
Result.success(aMatrixHomeServerDetails())
|
||||
},
|
||||
)
|
||||
createLoginPasswordPresenter(
|
||||
authenticationService = authenticationService,
|
||||
).test {
|
||||
|
|
|
|||
|
|
@ -214,7 +214,11 @@ class OnBoardingPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `present - default account provider - login and clear error`() = runTest {
|
||||
val authenticationService = FakeMatrixAuthenticationService()
|
||||
val authenticationService = FakeMatrixAuthenticationService(
|
||||
setHomeserverResult = {
|
||||
Result.failure(AN_EXCEPTION)
|
||||
},
|
||||
)
|
||||
val presenter = createPresenter(
|
||||
params = OnBoardingNode.Params(
|
||||
accountProvider = A_HOMESERVER_URL,
|
||||
|
|
@ -231,7 +235,6 @@ class OnBoardingPresenterTest {
|
|||
skipItems(3)
|
||||
awaitItem().also {
|
||||
assertThat(it.defaultAccountProvider).isEqualTo(A_HOMESERVER_URL)
|
||||
authenticationService.givenChangeServerError(AN_EXCEPTION)
|
||||
it.eventSink(OnBoardingEvents.OnSignIn(A_HOMESERVER_URL))
|
||||
skipItems(1) // Loading
|
||||
|
||||
|
|
|
|||
|
|
@ -7,14 +7,12 @@
|
|||
|
||||
package io.element.android.features.login.impl.screens.qrcode.intro
|
||||
|
||||
import app.cash.molecule.RecompositionMode
|
||||
import app.cash.molecule.moleculeFlow
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.libraries.core.meta.BuildMeta
|
||||
import io.element.android.libraries.matrix.test.core.aBuildMeta
|
||||
import io.element.android.libraries.permissions.test.FakePermissionsPresenter
|
||||
import io.element.android.libraries.permissions.test.FakePermissionsPresenterFactory
|
||||
import io.element.android.tests.testutils.test
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
||||
|
|
@ -22,9 +20,7 @@ class QrCodeIntroPresenterTest {
|
|||
@Test
|
||||
fun `present - initial state`() = runTest {
|
||||
val presenter = createQrCodeIntroPresenter()
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
awaitItem().run {
|
||||
assertThat(appName).isEqualTo("AppName")
|
||||
assertThat(desktopAppName).isEqualTo("DesktopAppName")
|
||||
|
|
@ -39,9 +35,7 @@ class QrCodeIntroPresenterTest {
|
|||
val permissionsPresenter = FakePermissionsPresenter().apply { setPermissionGranted() }
|
||||
val permissionsPresenterFactory = FakePermissionsPresenterFactory(permissionsPresenter)
|
||||
val presenter = createQrCodeIntroPresenter(permissionsPresenterFactory = permissionsPresenterFactory)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
awaitItem().eventSink(QrCodeIntroEvents.Continue)
|
||||
assertThat(awaitItem().canContinue).isTrue()
|
||||
}
|
||||
|
|
@ -52,9 +46,7 @@ class QrCodeIntroPresenterTest {
|
|||
val permissionsPresenter = FakePermissionsPresenter()
|
||||
val permissionsPresenterFactory = FakePermissionsPresenterFactory(permissionsPresenter)
|
||||
val presenter = createQrCodeIntroPresenter(permissionsPresenterFactory = permissionsPresenterFactory)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
awaitItem().eventSink(QrCodeIntroEvents.Continue)
|
||||
assertThat(awaitItem().cameraPermissionState.showDialog).isTrue()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,9 +7,6 @@
|
|||
|
||||
package io.element.android.features.login.impl.screens.qrcode.scan
|
||||
|
||||
import app.cash.molecule.RecompositionMode
|
||||
import app.cash.molecule.moleculeFlow
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.features.enterprise.api.EnterpriseService
|
||||
import io.element.android.features.enterprise.test.FakeEnterpriseService
|
||||
|
|
@ -34,9 +31,7 @@ class QrCodeScanPresenterTest {
|
|||
@Test
|
||||
fun `present - initial state`() = runTest {
|
||||
val presenter = createQrCodeScanPresenter()
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
awaitItem().run {
|
||||
assertThat(isScanning).isTrue()
|
||||
assertThat(authenticationAction.isUninitialized()).isTrue()
|
||||
|
|
@ -114,9 +109,7 @@ class QrCodeScanPresenterTest {
|
|||
parseQrCodeLoginDataResult = { Result.failure(Exception("Failed to parse QR code")) }
|
||||
)
|
||||
val presenter = createQrCodeScanPresenter(qrCodeLoginDataFactory = qrCodeLoginDataFactory)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(QrCodeScanEvents.QrCodeScanned(byteArrayOf()))
|
||||
assertThat(awaitItem().isScanning).isFalse()
|
||||
|
|
@ -140,9 +133,7 @@ class QrCodeScanPresenterTest {
|
|||
}
|
||||
qrCodeLoginManager.resetAction = resetAction
|
||||
val presenter = createQrCodeScanPresenter(qrCodeLoginDataFactory = qrCodeLoginDataFactory, qrCodeLoginManager = qrCodeLoginManager)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
// Skip initial item
|
||||
skipItems(1)
|
||||
|
||||
|
|
|
|||
|
|
@ -7,9 +7,6 @@
|
|||
|
||||
package io.element.android.features.login.impl.screens.searchaccountprovider
|
||||
|
||||
import app.cash.molecule.RecompositionMode
|
||||
import app.cash.molecule.moleculeFlow
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.features.login.impl.changeserver.aChangeServerState
|
||||
import io.element.android.features.login.impl.resolver.HomeserverResolver
|
||||
|
|
@ -18,6 +15,7 @@ import io.element.android.libraries.matrix.test.auth.FakeHomeServerLoginCompatib
|
|||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||
import io.element.android.tests.testutils.lambda.value
|
||||
import io.element.android.tests.testutils.test
|
||||
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
|
|
@ -34,9 +32,7 @@ class SearchAccountProviderPresenterTest {
|
|||
homeserverResolver = HomeserverResolver(testCoroutineDispatchers(), fakeLoginCompatibilityChecker),
|
||||
changeServerPresenter = { aChangeServerState() }
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.userInput).isEmpty()
|
||||
assertThat(initialState.userInputResult).isEqualTo(AsyncData.Uninitialized)
|
||||
|
|
@ -50,9 +46,7 @@ class SearchAccountProviderPresenterTest {
|
|||
homeserverResolver = HomeserverResolver(testCoroutineDispatchers(), fakeLoginCompatibilityChecker),
|
||||
changeServerPresenter = { aChangeServerState() }
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(SearchAccountProviderEvents.UserInput("https://test.org"))
|
||||
val withInputState = awaitItem()
|
||||
|
|
@ -76,16 +70,20 @@ class SearchAccountProviderPresenterTest {
|
|||
homeserverResolver = HomeserverResolver(testCoroutineDispatchers(), fakeWellknownRetriever),
|
||||
changeServerPresenter = { aChangeServerState() }
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(SearchAccountProviderEvents.UserInput("test"))
|
||||
val withInputState = awaitItem()
|
||||
assertThat(withInputState.userInput).isEqualTo("test")
|
||||
assertThat(initialState.userInputResult).isEqualTo(AsyncData.Uninitialized)
|
||||
assertThat(awaitItem().userInputResult).isInstanceOf(AsyncData.Loading::class.java)
|
||||
assertThat(awaitItem().userInputResult).isEqualTo(AsyncData.Uninitialized)
|
||||
assertThat(awaitItem().userInputResult).isEqualTo(
|
||||
AsyncData.Success(
|
||||
listOf(
|
||||
aHomeserverData(homeserverUrl = "https://test"),
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -105,9 +103,7 @@ class SearchAccountProviderPresenterTest {
|
|||
homeserverResolver = HomeserverResolver(testCoroutineDispatchers(), fakeLoginCompatibilityChecker),
|
||||
changeServerPresenter = { aChangeServerState() }
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(SearchAccountProviderEvents.UserInput("test"))
|
||||
val withInputState = awaitItem()
|
||||
|
|
@ -147,9 +143,7 @@ class SearchAccountProviderPresenterTest {
|
|||
homeserverResolver = HomeserverResolver(testCoroutineDispatchers(), fakeLoginCompatibilityChecker),
|
||||
changeServerPresenter = { aChangeServerState() }
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(SearchAccountProviderEvents.UserInput("test"))
|
||||
val withInputState = awaitItem()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue