mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-02 12:07:28 +00:00
ConfirmAccountProviderEvents -> ConfirmAccountProviderEvent
This commit is contained in:
+4
-4
@@ -8,11 +8,11 @@
|
||||
|
||||
package io.element.android.features.login.impl.screens.confirmaccountprovider
|
||||
|
||||
sealed interface ConfirmAccountProviderEvents {
|
||||
data class UserInputChanged(val accountProvider: String) : ConfirmAccountProviderEvents
|
||||
sealed interface ConfirmAccountProviderEvent {
|
||||
data class UserInputChanged(val accountProvider: String) : ConfirmAccountProviderEvent
|
||||
|
||||
// Carries the account provider to submit (the current field text, or the accepted autocomplete suggestion),
|
||||
// captured from the view at click time so it can't lag behind fast input (e.g. keyboard autofill).
|
||||
data class Continue(val accountProvider: String) : ConfirmAccountProviderEvents
|
||||
data object ClearError : ConfirmAccountProviderEvents
|
||||
data class Continue(val accountProvider: String) : ConfirmAccountProviderEvent
|
||||
data object ClearError : ConfirmAccountProviderEvent
|
||||
}
|
||||
+4
-4
@@ -110,14 +110,14 @@ class ConfirmAccountProviderPresenter(
|
||||
}
|
||||
}
|
||||
|
||||
fun handleEvent(event: ConfirmAccountProviderEvents) {
|
||||
fun handleEvent(event: ConfirmAccountProviderEvent) {
|
||||
when (event) {
|
||||
is ConfirmAccountProviderEvents.UserInputChanged -> {
|
||||
is ConfirmAccountProviderEvent.UserInputChanged -> {
|
||||
userInput = event.accountProvider
|
||||
}
|
||||
// Validate (and persist) the chosen account provider before proceeding. This also enforces the
|
||||
// account-provider access control, which the login submit does not run on its own.
|
||||
is ConfirmAccountProviderEvents.Continue -> {
|
||||
is ConfirmAccountProviderEvent.Continue -> {
|
||||
// Apply the accepted account provider (any accepted completion) back into the field so it
|
||||
// renders the full server rather than the typed prefix, and survives the OAuth round-trip.
|
||||
val accountProvider = event.accountProvider.trim()
|
||||
@@ -137,7 +137,7 @@ class ConfirmAccountProviderPresenter(
|
||||
ChangeServerEvent.ChangeServer(AccountProvider(url = accountProviderUrl))
|
||||
)
|
||||
}
|
||||
ConfirmAccountProviderEvents.ClearError -> {
|
||||
ConfirmAccountProviderEvent.ClearError -> {
|
||||
loginModeState.eventSink(LoginModeEvent.ClearError)
|
||||
changeServerState.eventSink(ChangeServerEvent.ClearError)
|
||||
}
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ data class ConfirmAccountProviderState(
|
||||
val isAccountCreation: Boolean,
|
||||
val loginModeState: LoginModeState,
|
||||
val changeServerState: ChangeServerState,
|
||||
val eventSink: (ConfirmAccountProviderEvents) -> Unit
|
||||
val eventSink: (ConfirmAccountProviderEvent) -> Unit
|
||||
) {
|
||||
val submitEnabled: Boolean
|
||||
get() = accountProviderInput.isNotBlank() &&
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ private fun aConfirmAccountProviderState(
|
||||
isAccountCreation: Boolean = false,
|
||||
loginModeState: LoginModeState = aLoginModeState(),
|
||||
changeServerState: ChangeServerState = aChangeServerState(),
|
||||
eventSink: (ConfirmAccountProviderEvents) -> Unit = {},
|
||||
eventSink: (ConfirmAccountProviderEvent) -> Unit = {},
|
||||
) = ConfirmAccountProviderState(
|
||||
accountProviderInput = accountProviderInput,
|
||||
accountProviderSuggestion = accountProviderSuggestion,
|
||||
|
||||
+5
-5
@@ -99,7 +99,7 @@ fun ConfirmAccountProviderView(
|
||||
// Dismiss the keyboard and release focus while the account provider is being validated.
|
||||
focusManager.clearFocus(force = true)
|
||||
// Submit the exact field text (plus any accepted suggestion).
|
||||
eventSink(ConfirmAccountProviderEvents.Continue(accountProviderToSubmit))
|
||||
eventSink(ConfirmAccountProviderEvent.Continue(accountProviderToSubmit))
|
||||
}
|
||||
|
||||
// Once a validation / login error has been dismissed, return focus and the keyboard to the field so
|
||||
@@ -151,7 +151,7 @@ fun ConfirmAccountProviderView(
|
||||
value = input,
|
||||
onValueChange = {
|
||||
input = it
|
||||
eventSink(ConfirmAccountProviderEvents.UserInputChanged(it))
|
||||
eventSink(ConfirmAccountProviderEvent.UserInputChanged(it))
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
@@ -181,7 +181,7 @@ fun ConfirmAccountProviderView(
|
||||
// showing, Done submits directly.
|
||||
val accepted = input + suggestionSuffix
|
||||
input = accepted
|
||||
eventSink(ConfirmAccountProviderEvents.UserInputChanged(accepted))
|
||||
eventSink(ConfirmAccountProviderEvent.UserInputChanged(accepted))
|
||||
focusManager.clearFocus(force = true)
|
||||
} else {
|
||||
submit()
|
||||
@@ -197,7 +197,7 @@ fun ConfirmAccountProviderView(
|
||||
role = Role.Button,
|
||||
) {
|
||||
input = ""
|
||||
eventSink(ConfirmAccountProviderEvents.UserInputChanged(""))
|
||||
eventSink(ConfirmAccountProviderEvent.UserInputChanged(""))
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
@@ -222,7 +222,7 @@ fun ConfirmAccountProviderView(
|
||||
|
||||
LoginModeView(
|
||||
loginMode = state.loginModeState.loginMode,
|
||||
onClearError = { eventSink(ConfirmAccountProviderEvents.ClearError) },
|
||||
onClearError = { eventSink(ConfirmAccountProviderEvent.ClearError) },
|
||||
onLearnMoreClick = onLearnMoreClick,
|
||||
onOAuthDetails = onOAuthDetails,
|
||||
onNeedLoginPassword = onNeedLoginPassword,
|
||||
|
||||
+28
-28
@@ -68,7 +68,7 @@ class ConfirmAccountProviderPresenterTest {
|
||||
)
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue(AuthenticationConfig.MATRIX_ORG_URL))
|
||||
initialState.eventSink.invoke(ConfirmAccountProviderEvent.Continue(AuthenticationConfig.MATRIX_ORG_URL))
|
||||
val successState = awaitLoginMode { it is AsyncData.Success }
|
||||
assertThat(successState.loginModeState.loginMode.dataOrNull()).isEqualTo(LoginMode.PasswordLogin)
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
@@ -87,7 +87,7 @@ class ConfirmAccountProviderPresenterTest {
|
||||
)
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue(AuthenticationConfig.MATRIX_ORG_URL))
|
||||
initialState.eventSink.invoke(ConfirmAccountProviderEvent.Continue(AuthenticationConfig.MATRIX_ORG_URL))
|
||||
val successState = awaitLoginMode { it is AsyncData.Success }
|
||||
assertThat(successState.loginModeState.loginMode.dataOrNull()).isInstanceOf(LoginMode.OAuth::class.java)
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
@@ -108,7 +108,7 @@ class ConfirmAccountProviderPresenterTest {
|
||||
)
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue(AuthenticationConfig.MATRIX_ORG_URL))
|
||||
initialState.eventSink.invoke(ConfirmAccountProviderEvent.Continue(AuthenticationConfig.MATRIX_ORG_URL))
|
||||
val successState = awaitLoginMode { it is AsyncData.Success }
|
||||
assertThat(successState.loginModeState.loginMode.dataOrNull()).isInstanceOf(LoginMode.OAuth::class.java)
|
||||
authenticationService.givenOAuthCancelError(AN_EXCEPTION)
|
||||
@@ -133,7 +133,7 @@ class ConfirmAccountProviderPresenterTest {
|
||||
)
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue(AuthenticationConfig.MATRIX_ORG_URL))
|
||||
initialState.eventSink.invoke(ConfirmAccountProviderEvent.Continue(AuthenticationConfig.MATRIX_ORG_URL))
|
||||
val successState = awaitLoginMode { it is AsyncData.Success }
|
||||
assertThat(successState.loginModeState.loginMode.dataOrNull()).isInstanceOf(LoginMode.OAuth::class.java)
|
||||
defaultOAuthActionFlow.post(OAuthAction.GoBack())
|
||||
@@ -157,7 +157,7 @@ class ConfirmAccountProviderPresenterTest {
|
||||
)
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue(AuthenticationConfig.MATRIX_ORG_URL))
|
||||
initialState.eventSink.invoke(ConfirmAccountProviderEvent.Continue(AuthenticationConfig.MATRIX_ORG_URL))
|
||||
awaitLoginMode { it is AsyncData.Loading }
|
||||
defaultOAuthActionFlow.post(OAuthAction.GoBack(toUnblock = true))
|
||||
val cancelFinalState = awaitLoginMode { it is AsyncData.Uninitialized }
|
||||
@@ -180,7 +180,7 @@ class ConfirmAccountProviderPresenterTest {
|
||||
)
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue(AuthenticationConfig.MATRIX_ORG_URL))
|
||||
initialState.eventSink.invoke(ConfirmAccountProviderEvent.Continue(AuthenticationConfig.MATRIX_ORG_URL))
|
||||
val successState = awaitLoginMode { it is AsyncData.Success }
|
||||
assertThat(successState.loginModeState.loginMode.dataOrNull()).isInstanceOf(LoginMode.OAuth::class.java)
|
||||
authenticationService.givenLoginError(AN_EXCEPTION)
|
||||
@@ -205,7 +205,7 @@ class ConfirmAccountProviderPresenterTest {
|
||||
)
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue(AuthenticationConfig.MATRIX_ORG_URL))
|
||||
initialState.eventSink.invoke(ConfirmAccountProviderEvent.Continue(AuthenticationConfig.MATRIX_ORG_URL))
|
||||
val successState = awaitLoginMode { it is AsyncData.Success }
|
||||
assertThat(successState.loginModeState.loginMode.dataOrNull()).isInstanceOf(LoginMode.OAuth::class.java)
|
||||
defaultOidcActionFlow.post(OAuthAction.Success("aUrl"))
|
||||
@@ -227,7 +227,7 @@ class ConfirmAccountProviderPresenterTest {
|
||||
)
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue(AuthenticationConfig.MATRIX_ORG_URL))
|
||||
initialState.eventSink.invoke(ConfirmAccountProviderEvent.Continue(AuthenticationConfig.MATRIX_ORG_URL))
|
||||
// The account provider validation fails, so the login is never attempted.
|
||||
val failureState = awaitState { it.changeServerState.changeServerAction is AsyncData.Failure }
|
||||
assertThat(failureState.loginModeState.loginMode).isEqualTo(AsyncData.Uninitialized)
|
||||
@@ -249,13 +249,13 @@ class ConfirmAccountProviderPresenterTest {
|
||||
val initialState = awaitItem()
|
||||
|
||||
// Submit will return an error while validating the account provider
|
||||
initialState.eventSink(ConfirmAccountProviderEvents.Continue(AuthenticationConfig.MATRIX_ORG_URL))
|
||||
initialState.eventSink(ConfirmAccountProviderEvent.Continue(AuthenticationConfig.MATRIX_ORG_URL))
|
||||
|
||||
// Check an error was returned
|
||||
val submittedState = awaitState { it.changeServerState.changeServerAction is AsyncData.Failure }
|
||||
|
||||
// Assert the error is then cleared
|
||||
submittedState.eventSink(ConfirmAccountProviderEvents.ClearError)
|
||||
submittedState.eventSink(ConfirmAccountProviderEvent.ClearError)
|
||||
val clearedState = awaitState { it.changeServerState.changeServerAction is AsyncData.Uninitialized }
|
||||
assertThat(clearedState.loginModeState.loginMode).isEqualTo(AsyncData.Uninitialized)
|
||||
}
|
||||
@@ -274,12 +274,12 @@ class ConfirmAccountProviderPresenterTest {
|
||||
)
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(ConfirmAccountProviderEvents.Continue(AuthenticationConfig.MATRIX_ORG_URL))
|
||||
initialState.eventSink(ConfirmAccountProviderEvent.Continue(AuthenticationConfig.MATRIX_ORG_URL))
|
||||
// Check an error was returned
|
||||
val submittedState = awaitLoginMode { it is AsyncData.Failure }
|
||||
assertThat(submittedState.loginModeState.loginMode.errorOrNull()).isInstanceOf(AccountCreationNotSupported::class.java)
|
||||
// Assert the error is then cleared
|
||||
submittedState.eventSink(ConfirmAccountProviderEvents.ClearError)
|
||||
submittedState.eventSink(ConfirmAccountProviderEvent.ClearError)
|
||||
val clearedState = awaitLoginMode { it is AsyncData.Uninitialized }
|
||||
assertThat(clearedState.loginModeState.loginMode).isEqualTo(AsyncData.Uninitialized)
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
@@ -299,7 +299,7 @@ class ConfirmAccountProviderPresenterTest {
|
||||
)
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(ConfirmAccountProviderEvents.Continue(AuthenticationConfig.MATRIX_ORG_URL))
|
||||
initialState.eventSink(ConfirmAccountProviderEvent.Continue(AuthenticationConfig.MATRIX_ORG_URL))
|
||||
val submittedState = awaitLoginMode { it is AsyncData.Success }
|
||||
assertThat(submittedState.loginModeState.loginMode.dataOrNull()).isInstanceOf(LoginMode.OAuth::class.java)
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
@@ -316,7 +316,7 @@ class ConfirmAccountProviderPresenterTest {
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.accountProviderSuggestion).isNull()
|
||||
initialState.eventSink(ConfirmAccountProviderEvents.UserInputChanged("random"))
|
||||
initialState.eventSink(ConfirmAccountProviderEvent.UserInputChanged("random"))
|
||||
val suggestionState = awaitState { it.accountProviderInput == "random" }
|
||||
// Completion is offered without the https:// scheme, even though history stores the full URL.
|
||||
assertThat(suggestionState.accountProviderSuggestion).isEqualTo("randomcommunity.org")
|
||||
@@ -340,9 +340,9 @@ class ConfirmAccountProviderPresenterTest {
|
||||
)
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(ConfirmAccountProviderEvents.UserInputChanged("random"))
|
||||
initialState.eventSink(ConfirmAccountProviderEvent.UserInputChanged("random"))
|
||||
val suggestionState = awaitState { it.accountProviderSuggestion != null }
|
||||
suggestionState.eventSink(ConfirmAccountProviderEvents.Continue("randomcommunity.org"))
|
||||
suggestionState.eventSink(ConfirmAccountProviderEvent.Continue("randomcommunity.org"))
|
||||
awaitLoginMode { it is AsyncData.Success }
|
||||
assertThat(submittedUrls.first()).isEqualTo("https://randomcommunity.org")
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
@@ -360,9 +360,9 @@ class ConfirmAccountProviderPresenterTest {
|
||||
)
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(ConfirmAccountProviderEvents.UserInputChanged("random"))
|
||||
initialState.eventSink(ConfirmAccountProviderEvent.UserInputChanged("random"))
|
||||
val suggestionState = awaitState { it.accountProviderSuggestion != null }
|
||||
suggestionState.eventSink(ConfirmAccountProviderEvents.Continue("randomcommunity.org"))
|
||||
suggestionState.eventSink(ConfirmAccountProviderEvent.Continue("randomcommunity.org"))
|
||||
// The field now renders the full accepted server rather than the typed prefix.
|
||||
val appliedState = awaitState { it.accountProviderInput == "randomcommunity.org" }
|
||||
assertThat(appliedState.accountProviderInput).isEqualTo("randomcommunity.org")
|
||||
@@ -381,7 +381,7 @@ class ConfirmAccountProviderPresenterTest {
|
||||
)
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(ConfirmAccountProviderEvents.UserInputChanged("ele"))
|
||||
initialState.eventSink(ConfirmAccountProviderEvent.UserInputChanged("ele"))
|
||||
val suggestionState = awaitState { it.accountProviderInput == "ele" }
|
||||
assertThat(suggestionState.accountProviderSuggestion).isEqualTo("element.io")
|
||||
}
|
||||
@@ -394,7 +394,7 @@ class ConfirmAccountProviderPresenterTest {
|
||||
)
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(ConfirmAccountProviderEvents.UserInputChanged("matr"))
|
||||
initialState.eventSink(ConfirmAccountProviderEvent.UserInputChanged("matr"))
|
||||
val suggestionState = awaitState { it.accountProviderInput == "matr" }
|
||||
assertThat(suggestionState.accountProviderSuggestion).isEqualTo("matrix.org")
|
||||
}
|
||||
@@ -409,9 +409,9 @@ class ConfirmAccountProviderPresenterTest {
|
||||
)
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(ConfirmAccountProviderEvents.UserInputChanged("https://mat"))
|
||||
initialState.eventSink(ConfirmAccountProviderEvent.UserInputChanged("https://mat"))
|
||||
assertThat(awaitState { it.accountProviderInput == "https://mat" }.accountProviderSuggestion).isNull()
|
||||
initialState.eventSink(ConfirmAccountProviderEvents.UserInputChanged("http://mat"))
|
||||
initialState.eventSink(ConfirmAccountProviderEvent.UserInputChanged("http://mat"))
|
||||
assertThat(awaitState { it.accountProviderInput == "http://mat" }.accountProviderSuggestion).isNull()
|
||||
}
|
||||
}
|
||||
@@ -430,7 +430,7 @@ class ConfirmAccountProviderPresenterTest {
|
||||
)
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(ConfirmAccountProviderEvents.Continue("matrix.org"))
|
||||
initialState.eventSink(ConfirmAccountProviderEvent.Continue("matrix.org"))
|
||||
awaitLoginMode { it is AsyncData.Success }
|
||||
assertThat(submittedUrls.first()).isEqualTo(AuthenticationConfig.MATRIX_ORG_URL)
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
@@ -453,7 +453,7 @@ class ConfirmAccountProviderPresenterTest {
|
||||
)
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(ConfirmAccountProviderEvents.Continue(AuthenticationConfig.MATRIX_ORG_URL))
|
||||
initialState.eventSink(ConfirmAccountProviderEvent.Continue(AuthenticationConfig.MATRIX_ORG_URL))
|
||||
awaitLoginMode { it is AsyncData.Success }
|
||||
assertThat(submittedUrls).containsExactly(AuthenticationConfig.MATRIX_ORG_URL)
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
@@ -472,7 +472,7 @@ class ConfirmAccountProviderPresenterTest {
|
||||
val presenter = createConfirmAccountProviderPresenter(matrixAuthenticationService = authenticationService)
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(ConfirmAccountProviderEvents.Continue("@alice:example.org"))
|
||||
initialState.eventSink(ConfirmAccountProviderEvent.Continue("@alice:example.org"))
|
||||
awaitLoginMode { it is AsyncData.Success }
|
||||
assertThat(submittedUrls.first()).isEqualTo("https://example.org")
|
||||
assertThat(authenticationService.getOAuthUrlLoginHint).isEqualTo("mxid:@alice:example.org")
|
||||
@@ -492,7 +492,7 @@ class ConfirmAccountProviderPresenterTest {
|
||||
val presenter = createConfirmAccountProviderPresenter(matrixAuthenticationService = authenticationService)
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(ConfirmAccountProviderEvents.Continue("@alice:example.org:8448"))
|
||||
initialState.eventSink(ConfirmAccountProviderEvent.Continue("@alice:example.org:8448"))
|
||||
awaitLoginMode { it is AsyncData.Success }
|
||||
assertThat(submittedUrls.first()).isEqualTo("https://example.org:8448")
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
@@ -507,7 +507,7 @@ class ConfirmAccountProviderPresenterTest {
|
||||
val presenter = createConfirmAccountProviderPresenter(matrixAuthenticationService = authenticationService)
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(ConfirmAccountProviderEvents.Continue("matrix.org"))
|
||||
initialState.eventSink(ConfirmAccountProviderEvent.Continue("matrix.org"))
|
||||
awaitLoginMode { it is AsyncData.Success }
|
||||
assertThat(authenticationService.getOAuthUrlLoginHint).isNull()
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
@@ -525,7 +525,7 @@ class ConfirmAccountProviderPresenterTest {
|
||||
)
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(ConfirmAccountProviderEvents.Continue("@alice:example.org"))
|
||||
initialState.eventSink(ConfirmAccountProviderEvent.Continue("@alice:example.org"))
|
||||
awaitLoginMode { it is AsyncData.Success }
|
||||
assertThat(authenticationService.getOAuthUrlLoginHint).isNull()
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
|
||||
Reference in New Issue
Block a user