Rename Async to AsyncData

This commit is contained in:
Benoit Marty 2024-01-04 16:30:56 +01:00
parent 3b2882ce2f
commit 7b2341aec7
139 changed files with 745 additions and 745 deletions

View file

@ -24,7 +24,7 @@ import androidx.compose.runtime.rememberCoroutineScope
import io.element.android.features.login.impl.accountprovider.AccountProvider
import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource
import io.element.android.features.login.impl.error.ChangeServerError
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.architecture.runCatchingUpdatingState
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
@ -41,14 +41,14 @@ class ChangeServerPresenter @Inject constructor(
override fun present(): ChangeServerState {
val localCoroutineScope = rememberCoroutineScope()
val changeServerAction: MutableState<Async<Unit>> = remember {
mutableStateOf(Async.Uninitialized)
val changeServerAction: MutableState<AsyncData<Unit>> = remember {
mutableStateOf(AsyncData.Uninitialized)
}
fun handleEvents(event: ChangeServerEvents) {
when (event) {
is ChangeServerEvents.ChangeServer -> localCoroutineScope.changeServer(event.accountProvider, changeServerAction)
ChangeServerEvents.ClearError -> changeServerAction.value = Async.Uninitialized
ChangeServerEvents.ClearError -> changeServerAction.value = AsyncData.Uninitialized
}
}
@ -60,7 +60,7 @@ class ChangeServerPresenter @Inject constructor(
private fun CoroutineScope.changeServer(
data: AccountProvider,
changeServerAction: MutableState<Async<Unit>>,
changeServerAction: MutableState<AsyncData<Unit>>,
) = launch {
suspend {
authenticationService.setHomeserver(data.url).map {

View file

@ -16,9 +16,9 @@
package io.element.android.features.login.impl.changeserver
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
data class ChangeServerState(
val changeServerAction: Async<Unit>,
val changeServerAction: AsyncData<Unit>,
val eventSink: (ChangeServerEvents) -> Unit
)

View file

@ -17,7 +17,7 @@
package io.element.android.features.login.impl.changeserver
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
open class ChangeServerStateProvider : PreviewParameterProvider<ChangeServerState> {
override val values: Sequence<ChangeServerState>
@ -27,6 +27,6 @@ open class ChangeServerStateProvider : PreviewParameterProvider<ChangeServerStat
}
fun aChangeServerState() = ChangeServerState(
changeServerAction = Async.Uninitialized,
changeServerAction = AsyncData.Uninitialized,
eventSink = {}
)

View file

@ -22,7 +22,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.PreviewParameter
import io.element.android.features.login.impl.dialogs.SlidingSyncNotSupportedDialog
import io.element.android.features.login.impl.error.ChangeServerError
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.designsystem.components.ProgressDialog
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
import io.element.android.libraries.designsystem.preview.ElementPreview
@ -37,7 +37,7 @@ fun ChangeServerView(
) {
val eventSink = state.eventSink
when (state.changeServerAction) {
is Async.Failure -> {
is AsyncData.Failure -> {
when (val error = state.changeServerAction.error) {
is ChangeServerError.Error -> {
ErrorDialog(
@ -60,11 +60,11 @@ fun ChangeServerView(
}
}
}
is Async.Loading -> ProgressDialog()
is Async.Success -> LaunchedEffect(state.changeServerAction) {
is AsyncData.Loading -> ProgressDialog()
is AsyncData.Success -> LaunchedEffect(state.changeServerAction) {
onDone()
}
Async.Uninitialized -> Unit
AsyncData.Uninitialized -> Unit
}
}

View file

@ -26,7 +26,7 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import io.element.android.features.login.api.oidc.OidcAction
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
import io.element.android.libraries.matrix.api.auth.OidcDetails
@ -44,33 +44,33 @@ class OidcPresenter @AssistedInject constructor(
@Composable
override fun present(): OidcState {
var requestState: Async<Unit> by remember {
mutableStateOf(Async.Uninitialized)
var requestState: AsyncData<Unit> by remember {
mutableStateOf(AsyncData.Uninitialized)
}
val localCoroutineScope = rememberCoroutineScope()
fun handleCancel() {
requestState = Async.Loading()
requestState = AsyncData.Loading()
localCoroutineScope.launch {
authenticationService.cancelOidcLogin()
.fold(
onSuccess = {
// Then go back
requestState = Async.Success(Unit)
requestState = AsyncData.Success(Unit)
},
onFailure = {
requestState = Async.Failure(it)
requestState = AsyncData.Failure(it)
}
)
}
}
fun handleSuccess(url: String) {
requestState = Async.Loading()
requestState = AsyncData.Loading()
localCoroutineScope.launch {
authenticationService.loginWithOidc(url)
.onFailure {
requestState = Async.Failure(it)
requestState = AsyncData.Failure(it)
}
// On success, the node tree will be updated, there is nothing to do
}
@ -87,7 +87,7 @@ class OidcPresenter @AssistedInject constructor(
when (event) {
OidcEvents.Cancel -> handleCancel()
is OidcEvents.OidcActionEvent -> handleAction(event.oidcAction)
OidcEvents.ClearError -> requestState = Async.Uninitialized
OidcEvents.ClearError -> requestState = AsyncData.Uninitialized
}
}

View file

@ -16,11 +16,11 @@
package io.element.android.features.login.impl.oidc.webview
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.matrix.api.auth.OidcDetails
data class OidcState(
val oidcDetails: OidcDetails,
val requestState: Async<Unit>,
val requestState: AsyncData<Unit>,
val eventSink: (OidcEvents) -> Unit
)

View file

@ -17,20 +17,20 @@
package io.element.android.features.login.impl.oidc.webview
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.matrix.api.auth.OidcDetails
open class OidcStateProvider : PreviewParameterProvider<OidcState> {
override val values: Sequence<OidcState>
get() = sequenceOf(
aOidcState(),
aOidcState().copy(requestState = Async.Loading()),
aOidcState().copy(requestState = AsyncData.Loading()),
)
}
fun aOidcState() = OidcState(
oidcDetails = aOidcDetails(),
requestState = Async.Uninitialized,
requestState = AsyncData.Uninitialized,
eventSink = {}
)

View file

@ -32,7 +32,7 @@ import io.element.android.features.login.impl.DefaultLoginUserStory
import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource
import io.element.android.features.login.impl.error.ChangeServerError
import io.element.android.features.login.impl.oidc.customtab.DefaultOidcActionFlow
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.architecture.runCatchingUpdatingState
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
@ -61,8 +61,8 @@ class ConfirmAccountProviderPresenter @AssistedInject constructor(
val accountProvider by accountProviderDataSource.flow().collectAsState()
val localCoroutineScope = rememberCoroutineScope()
val loginFlowAction: MutableState<Async<LoginFlow>> = remember {
mutableStateOf(Async.Uninitialized)
val loginFlowAction: MutableState<AsyncData<LoginFlow>> = remember {
mutableStateOf(AsyncData.Uninitialized)
}
LaunchedEffect(Unit) {
@ -78,7 +78,7 @@ class ConfirmAccountProviderPresenter @AssistedInject constructor(
ConfirmAccountProviderEvents.Continue -> {
localCoroutineScope.submit(accountProvider.url, loginFlowAction)
}
ConfirmAccountProviderEvents.ClearError -> loginFlowAction.value = Async.Uninitialized
ConfirmAccountProviderEvents.ClearError -> loginFlowAction.value = AsyncData.Uninitialized
}
}
@ -92,7 +92,7 @@ class ConfirmAccountProviderPresenter @AssistedInject constructor(
private fun CoroutineScope.submit(
homeserverUrl: String,
loginFlowAction: MutableState<Async<LoginFlow>>,
loginFlowAction: MutableState<AsyncData<LoginFlow>>,
) = launch {
suspend {
authenticationService.setHomeserver(homeserverUrl).map {
@ -111,17 +111,17 @@ class ConfirmAccountProviderPresenter @AssistedInject constructor(
private suspend fun onOidcAction(
oidcAction: OidcAction,
loginFlowAction: MutableState<Async<LoginFlow>>,
loginFlowAction: MutableState<AsyncData<LoginFlow>>,
) {
loginFlowAction.value = Async.Loading()
loginFlowAction.value = AsyncData.Loading()
when (oidcAction) {
OidcAction.GoBack -> {
authenticationService.cancelOidcLogin()
.onSuccess {
loginFlowAction.value = Async.Uninitialized
loginFlowAction.value = AsyncData.Uninitialized
}
.onFailure { failure ->
loginFlowAction.value = Async.Failure(failure)
loginFlowAction.value = AsyncData.Failure(failure)
}
}
is OidcAction.Success -> {
@ -130,7 +130,7 @@ class ConfirmAccountProviderPresenter @AssistedInject constructor(
defaultLoginUserStory.setLoginFlowIsDone(true)
}
.onFailure { failure ->
loginFlowAction.value = Async.Failure(failure)
loginFlowAction.value = AsyncData.Failure(failure)
}
}
}

View file

@ -17,17 +17,17 @@
package io.element.android.features.login.impl.screens.confirmaccountprovider
import io.element.android.features.login.impl.accountprovider.AccountProvider
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.matrix.api.auth.OidcDetails
// Do not use default value, so no member get forgotten in the presenters.
data class ConfirmAccountProviderState(
val accountProvider: AccountProvider,
val isAccountCreation: Boolean,
val loginFlow: Async<LoginFlow>,
val loginFlow: AsyncData<LoginFlow>,
val eventSink: (ConfirmAccountProviderEvents) -> Unit
) {
val submitEnabled: Boolean get() = accountProvider.url.isNotEmpty() && (loginFlow is Async.Uninitialized || loginFlow is Async.Loading)
val submitEnabled: Boolean get() = accountProvider.url.isNotEmpty() && (loginFlow is AsyncData.Uninitialized || loginFlow is AsyncData.Loading)
}
sealed interface LoginFlow {

View file

@ -18,7 +18,7 @@ package io.element.android.features.login.impl.screens.confirmaccountprovider
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.login.impl.accountprovider.anAccountProvider
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
open class ConfirmAccountProviderStateProvider : PreviewParameterProvider<ConfirmAccountProviderState> {
override val values: Sequence<ConfirmAccountProviderState>
@ -31,6 +31,6 @@ open class ConfirmAccountProviderStateProvider : PreviewParameterProvider<Confir
fun aConfirmAccountProviderState() = ConfirmAccountProviderState(
accountProvider = anAccountProvider(),
isAccountCreation = false,
loginFlow = Async.Uninitialized,
loginFlow = AsyncData.Uninitialized,
eventSink = {}
)

View file

@ -31,7 +31,7 @@ import androidx.compose.ui.unit.dp
import io.element.android.features.login.impl.R
import io.element.android.features.login.impl.dialogs.SlidingSyncNotSupportedDialog
import io.element.android.features.login.impl.error.ChangeServerError
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule
import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule
import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage
@ -56,7 +56,7 @@ fun ConfirmAccountProviderView(
) {
val isLoading by remember(state.loginFlow) {
derivedStateOf {
state.loginFlow is Async.Loading
state.loginFlow is AsyncData.Loading
}
}
val eventSink = state.eventSink
@ -107,7 +107,7 @@ fun ConfirmAccountProviderView(
}
) {
when (state.loginFlow) {
is Async.Failure -> {
is AsyncData.Failure -> {
when (val error = state.loginFlow.error) {
is ChangeServerError.Error -> {
ErrorDialog(
@ -127,14 +127,14 @@ fun ConfirmAccountProviderView(
}
}
}
is Async.Loading -> Unit // The Continue button shows the loading state
is Async.Success -> {
is AsyncData.Loading -> Unit // The Continue button shows the loading state
is AsyncData.Success -> {
when (val loginFlowState = state.loginFlow.data) {
is LoginFlow.OidcFlow -> onOidcDetails(loginFlowState.oidcDetails)
LoginFlow.PasswordLogin -> onLoginPasswordNeeded()
}
}
Async.Uninitialized -> Unit
AsyncData.Uninitialized -> Unit
}
}
}

View file

@ -26,7 +26,7 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import io.element.android.features.login.impl.DefaultLoginUserStory
import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
import io.element.android.libraries.matrix.api.core.SessionId
@ -43,8 +43,8 @@ class LoginPasswordPresenter @Inject constructor(
@Composable
override fun present(): LoginPasswordState {
val localCoroutineScope = rememberCoroutineScope()
val loginAction: MutableState<Async<SessionId>> = remember {
mutableStateOf(Async.Uninitialized)
val loginAction: MutableState<AsyncData<SessionId>> = remember {
mutableStateOf(AsyncData.Uninitialized)
}
val formState = rememberSaveable {
@ -63,7 +63,7 @@ class LoginPasswordPresenter @Inject constructor(
LoginPasswordEvents.Submit -> {
localCoroutineScope.submit(formState.value, loginAction)
}
LoginPasswordEvents.ClearError -> loginAction.value = Async.Uninitialized
LoginPasswordEvents.ClearError -> loginAction.value = AsyncData.Uninitialized
}
}
@ -75,16 +75,16 @@ class LoginPasswordPresenter @Inject constructor(
)
}
private fun CoroutineScope.submit(formState: LoginFormState, loggedInState: MutableState<Async<SessionId>>) = launch {
loggedInState.value = Async.Loading()
private fun CoroutineScope.submit(formState: LoginFormState, loggedInState: MutableState<AsyncData<SessionId>>) = launch {
loggedInState.value = AsyncData.Loading()
authenticationService.login(formState.login.trim(), formState.password)
.onSuccess { sessionId ->
// We will not navigate to the WaitList screen, so the login user story is done
defaultLoginUserStory.setLoginFlowIsDone(true)
loggedInState.value = Async.Success(sessionId)
loggedInState.value = AsyncData.Success(sessionId)
}
.onFailure { failure ->
loggedInState.value = Async.Failure(failure)
loggedInState.value = AsyncData.Failure(failure)
}
}

View file

@ -18,18 +18,18 @@ package io.element.android.features.login.impl.screens.loginpassword
import android.os.Parcelable
import io.element.android.features.login.impl.accountprovider.AccountProvider
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.matrix.api.core.SessionId
import kotlinx.parcelize.Parcelize
data class LoginPasswordState(
val accountProvider: AccountProvider,
val formState: LoginFormState,
val loginAction: Async<SessionId>,
val loginAction: AsyncData<SessionId>,
val eventSink: (LoginPasswordEvents) -> Unit
) {
val submitEnabled: Boolean
get() = loginAction !is Async.Failure &&
get() = loginAction !is AsyncData.Failure &&
formState.login.isNotEmpty() &&
formState.password.isNotEmpty()
}

View file

@ -18,22 +18,22 @@ package io.element.android.features.login.impl.screens.loginpassword
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.login.impl.accountprovider.anAccountProvider
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
open class LoginPasswordStateProvider : PreviewParameterProvider<LoginPasswordState> {
override val values: Sequence<LoginPasswordState>
get() = sequenceOf(
aLoginPasswordState(),
// Loading
aLoginPasswordState().copy(loginAction = Async.Loading()),
aLoginPasswordState().copy(loginAction = AsyncData.Loading()),
// Error
aLoginPasswordState().copy(loginAction = Async.Failure(Exception("An error occurred"))),
aLoginPasswordState().copy(loginAction = AsyncData.Failure(Exception("An error occurred"))),
)
}
fun aLoginPasswordState() = LoginPasswordState(
accountProvider = anAccountProvider(),
formState = LoginFormState.Default,
loginAction = Async.Uninitialized,
loginAction = AsyncData.Uninitialized,
eventSink = {}
)

View file

@ -54,7 +54,7 @@ import io.element.android.compound.tokens.generated.CompoundIcons
import io.element.android.features.login.impl.R
import io.element.android.features.login.impl.error.isWaitListError
import io.element.android.features.login.impl.error.loginError
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule
import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
@ -84,7 +84,7 @@ fun LoginPasswordView(
) {
val isLoading by remember(state.loginAction) {
derivedStateOf {
state.loginAction is Async.Loading
state.loginAction is AsyncData.Loading
}
}
val focusManager = LocalFocusManager.current
@ -148,7 +148,7 @@ fun LoginPasswordView(
)
Spacer(modifier = Modifier.height(60.dp))
if (state.loginAction is Async.Failure) {
if (state.loginAction is AsyncData.Failure) {
when {
state.loginAction.error.isWaitListError() -> {
onWaitListError(state.formState)
@ -224,7 +224,7 @@ private fun LoginForm(
)
var passwordVisible by remember { mutableStateOf(false) }
if (state.loginAction is Async.Loading) {
if (state.loginAction is AsyncData.Loading) {
// Ensure password is hidden when user submits the form
passwordVisible = false
}

View file

@ -27,7 +27,7 @@ import androidx.compose.runtime.setValue
import io.element.android.features.login.impl.changeserver.ChangeServerPresenter
import io.element.android.features.login.impl.resolver.HomeserverData
import io.element.android.features.login.impl.resolver.HomeserverResolver
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.architecture.Presenter
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
@ -46,8 +46,8 @@ class SearchAccountProviderPresenter @Inject constructor(
}
val changeServerState = changeServerPresenter.present()
val data: MutableState<Async<List<HomeserverData>>> = remember {
mutableStateOf(Async.Uninitialized)
val data: MutableState<AsyncData<List<HomeserverData>>> = remember {
mutableStateOf(AsyncData.Uninitialized)
}
LaunchedEffect(userInput) {
@ -70,16 +70,16 @@ class SearchAccountProviderPresenter @Inject constructor(
)
}
private fun CoroutineScope.onUserInput(userInput: String, data: MutableState<Async<List<HomeserverData>>>) = launch {
data.value = Async.Uninitialized
private fun CoroutineScope.onUserInput(userInput: String, data: MutableState<AsyncData<List<HomeserverData>>>) = launch {
data.value = AsyncData.Uninitialized
// Debounce
delay(300)
data.value = Async.Loading()
data.value = AsyncData.Loading()
homeserverResolver.resolve(userInput).collect {
data.value = Async.Success(it)
data.value = AsyncData.Success(it)
}
if (data.value !is Async.Success) {
data.value = Async.Uninitialized
if (data.value !is AsyncData.Success) {
data.value = AsyncData.Uninitialized
}
}
}

View file

@ -18,12 +18,12 @@ package io.element.android.features.login.impl.screens.searchaccountprovider
import io.element.android.features.login.impl.changeserver.ChangeServerState
import io.element.android.features.login.impl.resolver.HomeserverData
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
// Do not use default value, so no member get forgotten in the presenters.
data class SearchAccountProviderState(
val userInput: String,
val userInputResult: Async<List<HomeserverData>>,
val userInputResult: AsyncData<List<HomeserverData>>,
val changeServerState: ChangeServerState,
val eventSink: (SearchAccountProviderEvents) -> Unit
)

View file

@ -20,20 +20,20 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.appconfig.AuthenticationConfig
import io.element.android.features.login.impl.changeserver.aChangeServerState
import io.element.android.features.login.impl.resolver.HomeserverData
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
open class SearchAccountProviderStateProvider : PreviewParameterProvider<SearchAccountProviderState> {
override val values: Sequence<SearchAccountProviderState>
get() = sequenceOf(
aSearchAccountProviderState(),
aSearchAccountProviderState(userInputResult = Async.Success(aHomeserverDataList())),
aSearchAccountProviderState(userInputResult = AsyncData.Success(aHomeserverDataList())),
// Add other state here
)
}
fun aSearchAccountProviderState(
userInput: String = "",
userInputResult: Async<List<HomeserverData>> = Async.Uninitialized,
userInputResult: AsyncData<List<HomeserverData>> = AsyncData.Uninitialized,
) = SearchAccountProviderState(
userInput = userInput,
userInputResult = userInputResult,

View file

@ -55,7 +55,7 @@ import io.element.android.features.login.impl.accountprovider.AccountProviderVie
import io.element.android.features.login.impl.changeserver.ChangeServerEvents
import io.element.android.features.login.impl.changeserver.ChangeServerView
import io.element.android.features.login.impl.resolver.HomeserverData
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule
import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.components.form.textFieldState
@ -152,10 +152,10 @@ fun SearchAccountProviderView(
}
when (state.userInputResult) {
is Async.Failure -> {
is AsyncData.Failure -> {
// Ignore errors (let the user type more chars)
}
is Async.Loading -> {
is AsyncData.Loading -> {
item {
Box(
modifier = Modifier
@ -167,7 +167,7 @@ fun SearchAccountProviderView(
}
}
}
is Async.Success -> {
is AsyncData.Success -> {
items(state.userInputResult.data) { homeserverData ->
val item = homeserverData.toAccountProvider()
AccountProviderView(
@ -178,7 +178,7 @@ fun SearchAccountProviderView(
)
}
}
Async.Uninitialized -> Unit
AsyncData.Uninitialized -> Unit
}
item {
Spacer(Modifier.height(32.dp))

View file

@ -27,7 +27,7 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import io.element.android.features.login.impl.DefaultLoginUserStory
import io.element.android.features.login.impl.screens.loginpassword.LoginFormState
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
@ -55,8 +55,8 @@ class WaitListPresenter @AssistedInject constructor(
authenticationService.getHomeserverDetails().value?.url ?: "server"
}
val loginAction: MutableState<Async<SessionId>> = remember {
mutableStateOf(Async.Uninitialized)
val loginAction: MutableState<AsyncData<SessionId>> = remember {
mutableStateOf(AsyncData.Uninitialized)
}
val attemptNumber = remember { mutableIntStateOf(0) }
@ -70,7 +70,7 @@ class WaitListPresenter @AssistedInject constructor(
coroutineScope.loginAttempt(formState, loginAction)
}
}
WaitListEvents.ClearError -> loginAction.value = Async.Uninitialized
WaitListEvents.ClearError -> loginAction.value = AsyncData.Uninitialized
WaitListEvents.Continue -> defaultLoginUserStory.setLoginFlowIsDone(true)
}
}
@ -83,15 +83,15 @@ class WaitListPresenter @AssistedInject constructor(
)
}
private fun CoroutineScope.loginAttempt(formState: LoginFormState, loggedInState: MutableState<Async<SessionId>>) = launch {
private fun CoroutineScope.loginAttempt(formState: LoginFormState, loggedInState: MutableState<AsyncData<SessionId>>) = launch {
Timber.w("Attempt to login...")
loggedInState.value = Async.Loading()
loggedInState.value = AsyncData.Loading()
authenticationService.login(formState.login.trim(), formState.password)
.onSuccess { sessionId ->
loggedInState.value = Async.Success(sessionId)
loggedInState.value = AsyncData.Success(sessionId)
}
.onFailure { failure ->
loggedInState.value = Async.Failure(failure)
loggedInState.value = AsyncData.Failure(failure)
}
}
}

View file

@ -16,13 +16,13 @@
package io.element.android.features.login.impl.screens.waitlistscreen
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.matrix.api.core.SessionId
// Do not use default value, so no member get forgotten in the presenters.
data class WaitListState(
val appName: String,
val serverName: String,
val loginAction: Async<SessionId>,
val loginAction: AsyncData<SessionId>,
val eventSink: (WaitListEvents) -> Unit
)

View file

@ -17,17 +17,17 @@
package io.element.android.features.login.impl.screens.waitlistscreen
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.matrix.api.core.SessionId
open class WaitListStateProvider : PreviewParameterProvider<WaitListState> {
override val values: Sequence<WaitListState>
get() = sequenceOf(
aWaitListState(loginAction = Async.Uninitialized),
aWaitListState(loginAction = Async.Loading()),
aWaitListState(loginAction = Async.Failure(Throwable("error"))),
aWaitListState(loginAction = Async.Failure(Throwable(message = "IO_ELEMENT_X_WAIT_LIST"))),
aWaitListState(loginAction = Async.Success(SessionId("@alice:element.io"))),
aWaitListState(loginAction = AsyncData.Uninitialized),
aWaitListState(loginAction = AsyncData.Loading()),
aWaitListState(loginAction = AsyncData.Failure(Throwable("error"))),
aWaitListState(loginAction = AsyncData.Failure(Throwable(message = "IO_ELEMENT_X_WAIT_LIST"))),
aWaitListState(loginAction = AsyncData.Success(SessionId("@alice:element.io"))),
// Add other state here
)
}
@ -35,7 +35,7 @@ open class WaitListStateProvider : PreviewParameterProvider<WaitListState> {
fun aWaitListState(
appName: String = "Element X",
serverName: String = "server.org",
loginAction: Async<SessionId> = Async.Uninitialized,
loginAction: AsyncData<SessionId> = AsyncData.Uninitialized,
) = WaitListState(
appName = appName,
serverName = serverName,

View file

@ -33,7 +33,7 @@ import androidx.lifecycle.Lifecycle
import io.element.android.features.login.impl.R
import io.element.android.features.login.impl.error.isWaitListError
import io.element.android.features.login.impl.error.loginError
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.designsystem.atomic.pages.SunsetPage
import io.element.android.libraries.designsystem.components.dialogs.RetryDialog
import io.element.android.libraries.designsystem.preview.ElementPreview
@ -89,12 +89,12 @@ private fun WaitListContent(
) {
val title = stringResource(
when (state.loginAction) {
is Async.Success -> R.string.screen_waitlist_title_success
is AsyncData.Success -> R.string.screen_waitlist_title_success
else -> R.string.screen_waitlist_title
}
)
val subtitle = when (state.loginAction) {
is Async.Success -> stringResource(
is AsyncData.Success -> stringResource(
id = R.string.screen_waitlist_message_success,
state.appName,
)
@ -122,7 +122,7 @@ private fun OverallContent(
modifier: Modifier = Modifier,
) {
Box(modifier = modifier.fillMaxSize()) {
if (state.loginAction !is Async.Success) {
if (state.loginAction !is AsyncData.Success) {
CompositionLocalProvider(LocalContentColor provides Color.Black) {
TextButton(
text = stringResource(CommonStrings.action_cancel),
@ -130,7 +130,7 @@ private fun OverallContent(
)
}
}
if (state.loginAction is Async.Success) {
if (state.loginAction is AsyncData.Success) {
Button(
text = stringResource(id = CommonStrings.action_continue),
onClick = { state.eventSink.invoke(WaitListEvents.Continue) },

View file

@ -22,7 +22,7 @@ import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import io.element.android.features.login.impl.accountprovider.AccountProvider
import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.matrix.test.A_HOMESERVER
import io.element.android.libraries.matrix.test.A_HOMESERVER_URL
import io.element.android.libraries.matrix.test.auth.FakeAuthenticationService
@ -46,7 +46,7 @@ class ChangeServerPresenterTest {
presenter.present()
}.test {
val initialState = awaitItem()
assertThat(initialState.changeServerAction).isEqualTo(Async.Uninitialized)
assertThat(initialState.changeServerAction).isEqualTo(AsyncData.Uninitialized)
}
}
@ -61,13 +61,13 @@ class ChangeServerPresenterTest {
presenter.present()
}.test {
val initialState = awaitItem()
assertThat(initialState.changeServerAction).isEqualTo(Async.Uninitialized)
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(Async.Loading::class.java)
assertThat(loadingState.changeServerAction).isInstanceOf(AsyncData.Loading::class.java)
val successState = awaitItem()
assertThat(successState.changeServerAction).isEqualTo(Async.Success(Unit))
assertThat(successState.changeServerAction).isEqualTo(AsyncData.Success(Unit))
}
}
@ -82,16 +82,16 @@ class ChangeServerPresenterTest {
presenter.present()
}.test {
val initialState = awaitItem()
assertThat(initialState.changeServerAction).isEqualTo(Async.Uninitialized)
assertThat(initialState.changeServerAction).isEqualTo(AsyncData.Uninitialized)
initialState.eventSink.invoke(ChangeServerEvents.ChangeServer(AccountProvider(url = A_HOMESERVER_URL)))
val loadingState = awaitItem()
assertThat(loadingState.changeServerAction).isInstanceOf(Async.Loading::class.java)
assertThat(loadingState.changeServerAction).isInstanceOf(AsyncData.Loading::class.java)
val failureState = awaitItem()
assertThat(failureState.changeServerAction).isInstanceOf(Async.Failure::class.java)
assertThat(failureState.changeServerAction).isInstanceOf(AsyncData.Failure::class.java)
// Clear error
failureState.eventSink.invoke(ChangeServerEvents.ClearError)
val finalState = awaitItem()
assertThat(finalState.changeServerAction).isEqualTo(Async.Uninitialized)
assertThat(finalState.changeServerAction).isEqualTo(AsyncData.Uninitialized)
}
}
}

View file

@ -23,7 +23,7 @@ import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import io.element.android.features.login.api.oidc.OidcAction
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.matrix.test.A_THROWABLE
import io.element.android.libraries.matrix.test.auth.A_OIDC_DATA
import io.element.android.libraries.matrix.test.auth.FakeAuthenticationService
@ -49,7 +49,7 @@ class OidcPresenterTest {
}.test {
val initialState = awaitItem()
assertThat(initialState.oidcDetails).isEqualTo(A_OIDC_DATA)
assertThat(initialState.requestState).isEqualTo(Async.Uninitialized)
assertThat(initialState.requestState).isEqualTo(AsyncData.Uninitialized)
}
}
@ -65,9 +65,9 @@ class OidcPresenterTest {
val initialState = awaitItem()
initialState.eventSink.invoke(OidcEvents.Cancel)
val loadingState = awaitItem()
assertThat(loadingState.requestState).isEqualTo(Async.Loading<Unit>())
assertThat(loadingState.requestState).isEqualTo(AsyncData.Loading<Unit>())
val finalState = awaitItem()
assertThat(finalState.requestState).isEqualTo(Async.Success(Unit))
assertThat(finalState.requestState).isEqualTo(AsyncData.Success(Unit))
}
}
@ -85,9 +85,9 @@ class OidcPresenterTest {
val initialState = awaitItem()
initialState.eventSink.invoke(OidcEvents.Cancel)
val loadingState = awaitItem()
assertThat(loadingState.requestState).isEqualTo(Async.Loading<Unit>())
assertThat(loadingState.requestState).isEqualTo(AsyncData.Loading<Unit>())
val finalState = awaitItem()
assertThat(finalState.requestState).isEqualTo(Async.Failure<Unit>(A_THROWABLE))
assertThat(finalState.requestState).isEqualTo(AsyncData.Failure<Unit>(A_THROWABLE))
// Note: in real life I do not think this can happen, and the app should not block the user.
}
}
@ -104,9 +104,9 @@ class OidcPresenterTest {
val initialState = awaitItem()
initialState.eventSink.invoke(OidcEvents.OidcActionEvent(OidcAction.GoBack))
val loadingState = awaitItem()
assertThat(loadingState.requestState).isEqualTo(Async.Loading<Unit>())
assertThat(loadingState.requestState).isEqualTo(AsyncData.Loading<Unit>())
val finalState = awaitItem()
assertThat(finalState.requestState).isEqualTo(Async.Success(Unit))
assertThat(finalState.requestState).isEqualTo(AsyncData.Success(Unit))
}
}
@ -122,7 +122,7 @@ class OidcPresenterTest {
val initialState = awaitItem()
initialState.eventSink.invoke(OidcEvents.OidcActionEvent(OidcAction.Success("A_URL")))
val loadingState = awaitItem()
assertThat(loadingState.requestState).isEqualTo(Async.Loading<Unit>())
assertThat(loadingState.requestState).isEqualTo(AsyncData.Loading<Unit>())
// In this case, no success, the session is created and the node get destroyed.
}
}
@ -141,12 +141,12 @@ class OidcPresenterTest {
val initialState = awaitItem()
initialState.eventSink.invoke(OidcEvents.OidcActionEvent(OidcAction.Success("A_URL")))
val loadingState = awaitItem()
assertThat(loadingState.requestState).isEqualTo(Async.Loading<Unit>())
assertThat(loadingState.requestState).isEqualTo(AsyncData.Loading<Unit>())
val errorState = awaitItem()
assertThat(errorState.requestState).isEqualTo(Async.Failure<Unit>(A_THROWABLE))
assertThat(errorState.requestState).isEqualTo(AsyncData.Failure<Unit>(A_THROWABLE))
errorState.eventSink.invoke(OidcEvents.ClearError)
val finalState = awaitItem()
assertThat(finalState.requestState).isEqualTo(Async.Uninitialized)
assertThat(finalState.requestState).isEqualTo(AsyncData.Uninitialized)
}
}
}

View file

@ -25,7 +25,7 @@ import io.element.android.features.login.impl.DefaultLoginUserStory
import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource
import io.element.android.features.login.impl.oidc.customtab.DefaultOidcActionFlow
import io.element.android.features.login.impl.util.defaultAccountProvider
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
import io.element.android.libraries.matrix.test.A_HOMESERVER
import io.element.android.libraries.matrix.test.A_HOMESERVER_OIDC
@ -52,7 +52,7 @@ class ConfirmAccountProviderPresenterTest {
assertThat(initialState.isAccountCreation).isFalse()
assertThat(initialState.submitEnabled).isTrue()
assertThat(initialState.accountProvider).isEqualTo(defaultAccountProvider)
assertThat(initialState.loginFlow).isEqualTo(Async.Uninitialized)
assertThat(initialState.loginFlow).isEqualTo(AsyncData.Uninitialized)
}
}
@ -70,10 +70,10 @@ class ConfirmAccountProviderPresenterTest {
initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue)
val loadingState = awaitItem()
assertThat(loadingState.submitEnabled).isTrue()
assertThat(loadingState.loginFlow).isInstanceOf(Async.Loading::class.java)
assertThat(loadingState.loginFlow).isInstanceOf(AsyncData.Loading::class.java)
val successState = awaitItem()
assertThat(successState.submitEnabled).isFalse()
assertThat(successState.loginFlow).isInstanceOf(Async.Success::class.java)
assertThat(successState.loginFlow).isInstanceOf(AsyncData.Success::class.java)
assertThat(successState.loginFlow.dataOrNull()).isEqualTo(LoginFlow.PasswordLogin)
}
}
@ -92,10 +92,10 @@ class ConfirmAccountProviderPresenterTest {
initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue)
val loadingState = awaitItem()
assertThat(loadingState.submitEnabled).isTrue()
assertThat(loadingState.loginFlow).isInstanceOf(Async.Loading::class.java)
assertThat(loadingState.loginFlow).isInstanceOf(AsyncData.Loading::class.java)
val successState = awaitItem()
assertThat(successState.submitEnabled).isFalse()
assertThat(successState.loginFlow).isInstanceOf(Async.Success::class.java)
assertThat(successState.loginFlow).isInstanceOf(AsyncData.Success::class.java)
assertThat(successState.loginFlow.dataOrNull()).isInstanceOf(LoginFlow.OidcFlow::class.java)
}
}
@ -116,15 +116,15 @@ class ConfirmAccountProviderPresenterTest {
initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue)
val loadingState = awaitItem()
assertThat(loadingState.submitEnabled).isTrue()
assertThat(loadingState.loginFlow).isInstanceOf(Async.Loading::class.java)
assertThat(loadingState.loginFlow).isInstanceOf(AsyncData.Loading::class.java)
val successState = awaitItem()
assertThat(successState.submitEnabled).isFalse()
assertThat(successState.loginFlow).isInstanceOf(Async.Success::class.java)
assertThat(successState.loginFlow).isInstanceOf(AsyncData.Success::class.java)
assertThat(successState.loginFlow.dataOrNull()).isInstanceOf(LoginFlow.OidcFlow::class.java)
authenticationService.givenOidcCancelError(A_THROWABLE)
defaultOidcActionFlow.post(OidcAction.GoBack)
val cancelFailureState = awaitItem()
assertThat(cancelFailureState.loginFlow).isInstanceOf(Async.Failure::class.java)
assertThat(cancelFailureState.loginFlow).isInstanceOf(AsyncData.Failure::class.java)
}
}
@ -144,14 +144,14 @@ class ConfirmAccountProviderPresenterTest {
initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue)
val loadingState = awaitItem()
assertThat(loadingState.submitEnabled).isTrue()
assertThat(loadingState.loginFlow).isInstanceOf(Async.Loading::class.java)
assertThat(loadingState.loginFlow).isInstanceOf(AsyncData.Loading::class.java)
val successState = awaitItem()
assertThat(successState.submitEnabled).isFalse()
assertThat(successState.loginFlow).isInstanceOf(Async.Success::class.java)
assertThat(successState.loginFlow).isInstanceOf(AsyncData.Success::class.java)
assertThat(successState.loginFlow.dataOrNull()).isInstanceOf(LoginFlow.OidcFlow::class.java)
defaultOidcActionFlow.post(OidcAction.GoBack)
val cancelFinalState = awaitItem()
assertThat(cancelFinalState.loginFlow).isInstanceOf(Async.Uninitialized::class.java)
assertThat(cancelFinalState.loginFlow).isInstanceOf(AsyncData.Uninitialized::class.java)
}
}
@ -171,17 +171,17 @@ class ConfirmAccountProviderPresenterTest {
initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue)
val loadingState = awaitItem()
assertThat(loadingState.submitEnabled).isTrue()
assertThat(loadingState.loginFlow).isInstanceOf(Async.Loading::class.java)
assertThat(loadingState.loginFlow).isInstanceOf(AsyncData.Loading::class.java)
val successState = awaitItem()
assertThat(successState.submitEnabled).isFalse()
assertThat(successState.loginFlow).isInstanceOf(Async.Success::class.java)
assertThat(successState.loginFlow).isInstanceOf(AsyncData.Success::class.java)
assertThat(successState.loginFlow.dataOrNull()).isInstanceOf(LoginFlow.OidcFlow::class.java)
authenticationService.givenLoginError(A_THROWABLE)
defaultOidcActionFlow.post(OidcAction.Success("aUrl"))
val cancelLoadingState = awaitItem()
assertThat(cancelLoadingState.loginFlow).isInstanceOf(Async.Loading::class.java)
assertThat(cancelLoadingState.loginFlow).isInstanceOf(AsyncData.Loading::class.java)
val cancelFailureState = awaitItem()
assertThat(cancelFailureState.loginFlow).isInstanceOf(Async.Failure::class.java)
assertThat(cancelFailureState.loginFlow).isInstanceOf(AsyncData.Failure::class.java)
}
}
@ -205,15 +205,15 @@ class ConfirmAccountProviderPresenterTest {
initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue)
val loadingState = awaitItem()
assertThat(loadingState.submitEnabled).isTrue()
assertThat(loadingState.loginFlow).isInstanceOf(Async.Loading::class.java)
assertThat(loadingState.loginFlow).isInstanceOf(AsyncData.Loading::class.java)
val successState = awaitItem()
assertThat(successState.submitEnabled).isFalse()
assertThat(successState.loginFlow).isInstanceOf(Async.Success::class.java)
assertThat(successState.loginFlow).isInstanceOf(AsyncData.Success::class.java)
assertThat(successState.loginFlow.dataOrNull()).isInstanceOf(LoginFlow.OidcFlow::class.java)
assertThat(defaultLoginUserStory.loginFlowIsDone.value).isFalse()
defaultOidcActionFlow.post(OidcAction.Success("aUrl"))
val successSuccessState = awaitItem()
assertThat(successSuccessState.loginFlow).isInstanceOf(Async.Loading::class.java)
assertThat(successSuccessState.loginFlow).isInstanceOf(AsyncData.Loading::class.java)
waitForPredicate { defaultLoginUserStory.loginFlowIsDone.value }
}
}
@ -233,7 +233,7 @@ class ConfirmAccountProviderPresenterTest {
skipItems(1) // Loading
val failureState = awaitItem()
assertThat(failureState.submitEnabled).isFalse()
assertThat(failureState.loginFlow).isInstanceOf(Async.Failure::class.java)
assertThat(failureState.loginFlow).isInstanceOf(AsyncData.Failure::class.java)
}
}
@ -256,12 +256,12 @@ class ConfirmAccountProviderPresenterTest {
// Check an error was returned
val submittedState = awaitItem()
assertThat(submittedState.loginFlow).isInstanceOf(Async.Failure::class.java)
assertThat(submittedState.loginFlow).isInstanceOf(AsyncData.Failure::class.java)
// Assert the error is then cleared
submittedState.eventSink(ConfirmAccountProviderEvents.ClearError)
val clearedState = awaitItem()
assertThat(clearedState.loginFlow).isEqualTo(Async.Uninitialized)
assertThat(clearedState.loginFlow).isEqualTo(AsyncData.Uninitialized)
}
}

View file

@ -23,7 +23,7 @@ import com.google.common.truth.Truth.assertThat
import io.element.android.features.login.impl.DefaultLoginUserStory
import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource
import io.element.android.features.login.impl.util.defaultAccountProvider
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.test.A_HOMESERVER
import io.element.android.libraries.matrix.test.A_PASSWORD
@ -57,7 +57,7 @@ class LoginPasswordPresenterTest {
val initialState = awaitItem()
assertThat(initialState.accountProvider).isEqualTo(defaultAccountProvider)
assertThat(initialState.formState).isEqualTo(LoginFormState.Default)
assertThat(initialState.loginAction).isEqualTo(Async.Uninitialized)
assertThat(initialState.loginAction).isEqualTo(AsyncData.Uninitialized)
assertThat(initialState.submitEnabled).isFalse()
}
}
@ -110,9 +110,9 @@ class LoginPasswordPresenterTest {
val loginAndPasswordState = awaitItem()
loginAndPasswordState.eventSink.invoke(LoginPasswordEvents.Submit)
val submitState = awaitItem()
assertThat(submitState.loginAction).isInstanceOf(Async.Loading::class.java)
assertThat(submitState.loginAction).isInstanceOf(AsyncData.Loading::class.java)
val loggedInState = awaitItem()
assertThat(loggedInState.loginAction).isEqualTo(Async.Success(A_SESSION_ID))
assertThat(loggedInState.loginAction).isEqualTo(AsyncData.Success(A_SESSION_ID))
assertThat(loginUserStory.loginFlowIsDone.value).isTrue()
}
}
@ -139,9 +139,9 @@ class LoginPasswordPresenterTest {
authenticationService.givenLoginError(A_THROWABLE)
loginAndPasswordState.eventSink.invoke(LoginPasswordEvents.Submit)
val submitState = awaitItem()
assertThat(submitState.loginAction).isInstanceOf(Async.Loading::class.java)
assertThat(submitState.loginAction).isInstanceOf(AsyncData.Loading::class.java)
val loggedInState = awaitItem()
assertThat(loggedInState.loginAction).isEqualTo(Async.Failure<SessionId>(A_THROWABLE))
assertThat(loggedInState.loginAction).isEqualTo(AsyncData.Failure<SessionId>(A_THROWABLE))
}
}
@ -167,14 +167,14 @@ class LoginPasswordPresenterTest {
authenticationService.givenLoginError(A_THROWABLE)
loginAndPasswordState.eventSink.invoke(LoginPasswordEvents.Submit)
val submitState = awaitItem()
assertThat(submitState.loginAction).isInstanceOf(Async.Loading::class.java)
assertThat(submitState.loginAction).isInstanceOf(AsyncData.Loading::class.java)
val loggedInState = awaitItem()
// Check an error was returned
assertThat(loggedInState.loginAction).isEqualTo(Async.Failure<SessionId>(A_THROWABLE))
assertThat(loggedInState.loginAction).isEqualTo(AsyncData.Failure<SessionId>(A_THROWABLE))
// Assert the error is then cleared
loggedInState.eventSink(LoginPasswordEvents.ClearError)
val clearedState = awaitItem()
assertThat(clearedState.loginAction).isEqualTo(Async.Uninitialized)
assertThat(clearedState.loginAction).isEqualTo(AsyncData.Uninitialized)
}
}
}

View file

@ -27,7 +27,7 @@ import io.element.android.features.login.impl.resolver.network.FakeWellknownRequ
import io.element.android.features.login.impl.resolver.network.WellKnown
import io.element.android.features.login.impl.resolver.network.WellKnownBaseConfig
import io.element.android.features.login.impl.resolver.network.WellKnownSlidingSyncConfig
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.matrix.test.A_HOMESERVER_URL
import io.element.android.libraries.matrix.test.auth.FakeAuthenticationService
import io.element.android.tests.testutils.WarmUpRule
@ -57,7 +57,7 @@ class SearchAccountProviderPresenterTest {
}.test {
val initialState = awaitItem()
assertThat(initialState.userInput).isEmpty()
assertThat(initialState.userInputResult).isEqualTo(Async.Uninitialized)
assertThat(initialState.userInputResult).isEqualTo(AsyncData.Uninitialized)
}
}
@ -79,9 +79,9 @@ class SearchAccountProviderPresenterTest {
initialState.eventSink.invoke(SearchAccountProviderEvents.UserInput("test"))
val withInputState = awaitItem()
assertThat(withInputState.userInput).isEqualTo("test")
assertThat(initialState.userInputResult).isEqualTo(Async.Uninitialized)
assertThat(awaitItem().userInputResult).isInstanceOf(Async.Loading::class.java)
assertThat(awaitItem().userInputResult).isEqualTo(Async.Uninitialized)
assertThat(initialState.userInputResult).isEqualTo(AsyncData.Uninitialized)
assertThat(awaitItem().userInputResult).isInstanceOf(AsyncData.Loading::class.java)
assertThat(awaitItem().userInputResult).isEqualTo(AsyncData.Uninitialized)
}
}
@ -103,10 +103,10 @@ class SearchAccountProviderPresenterTest {
initialState.eventSink.invoke(SearchAccountProviderEvents.UserInput("https://test.org"))
val withInputState = awaitItem()
assertThat(withInputState.userInput).isEqualTo("https://test.org")
assertThat(initialState.userInputResult).isEqualTo(Async.Uninitialized)
assertThat(awaitItem().userInputResult).isInstanceOf(Async.Loading::class.java)
assertThat(initialState.userInputResult).isEqualTo(AsyncData.Uninitialized)
assertThat(awaitItem().userInputResult).isInstanceOf(AsyncData.Loading::class.java)
assertThat(awaitItem().userInputResult).isEqualTo(
Async.Success(
AsyncData.Success(
listOf(
aHomeserverData(homeserverUrl = "https://test.org", isWellknownValid = false, supportSlidingSync = false)
)
@ -138,10 +138,10 @@ class SearchAccountProviderPresenterTest {
initialState.eventSink.invoke(SearchAccountProviderEvents.UserInput("test"))
val withInputState = awaitItem()
assertThat(withInputState.userInput).isEqualTo("test")
assertThat(initialState.userInputResult).isEqualTo(Async.Uninitialized)
assertThat(awaitItem().userInputResult).isInstanceOf(Async.Loading::class.java)
assertThat(initialState.userInputResult).isEqualTo(AsyncData.Uninitialized)
assertThat(awaitItem().userInputResult).isInstanceOf(AsyncData.Loading::class.java)
assertThat(awaitItem().userInputResult).isEqualTo(
Async.Success(
AsyncData.Success(
listOf(
aHomeserverData(homeserverUrl = "https://test.org", isWellknownValid = true, supportSlidingSync = false)
)
@ -173,10 +173,10 @@ class SearchAccountProviderPresenterTest {
initialState.eventSink.invoke(SearchAccountProviderEvents.UserInput("test"))
val withInputState = awaitItem()
assertThat(withInputState.userInput).isEqualTo("test")
assertThat(initialState.userInputResult).isEqualTo(Async.Uninitialized)
assertThat(awaitItem().userInputResult).isInstanceOf(Async.Loading::class.java)
assertThat(initialState.userInputResult).isEqualTo(AsyncData.Uninitialized)
assertThat(awaitItem().userInputResult).isInstanceOf(AsyncData.Loading::class.java)
assertThat(awaitItem().userInputResult).isEqualTo(
Async.Success(
AsyncData.Success(
listOf(
aHomeserverData(homeserverUrl = "https://test.io")
)

View file

@ -22,7 +22,7 @@ import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import io.element.android.features.login.impl.DefaultLoginUserStory
import io.element.android.features.login.impl.screens.loginpassword.LoginFormState
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.test.A_HOMESERVER
import io.element.android.libraries.matrix.test.A_HOMESERVER_URL
@ -58,7 +58,7 @@ class WaitListPresenterTest {
val initialState = awaitItem()
assertThat(initialState.appName).isEqualTo("Application Name")
assertThat(initialState.serverName).isEqualTo(A_HOMESERVER_URL)
assertThat(initialState.loginAction).isEqualTo(Async.Uninitialized)
assertThat(initialState.loginAction).isEqualTo(AsyncData.Uninitialized)
}
}
@ -83,13 +83,13 @@ class WaitListPresenterTest {
expectNoEvents()
initialState.eventSink.invoke(WaitListEvents.AttemptLogin)
val submitState = awaitItem()
assertThat(submitState.loginAction).isInstanceOf(Async.Loading::class.java)
assertThat(submitState.loginAction).isInstanceOf(AsyncData.Loading::class.java)
val errorState = awaitItem()
assertThat(errorState.loginAction).isEqualTo(Async.Failure<SessionId>(A_THROWABLE))
assertThat(errorState.loginAction).isEqualTo(AsyncData.Failure<SessionId>(A_THROWABLE))
// Assert the error can be cleared
errorState.eventSink(WaitListEvents.ClearError)
val clearedState = awaitItem()
assertThat(clearedState.loginAction).isEqualTo(Async.Uninitialized)
assertThat(clearedState.loginAction).isEqualTo(AsyncData.Uninitialized)
}
}
@ -113,9 +113,9 @@ class WaitListPresenterTest {
expectNoEvents()
initialState.eventSink.invoke(WaitListEvents.AttemptLogin)
val submitState = awaitItem()
assertThat(submitState.loginAction).isInstanceOf(Async.Loading::class.java)
assertThat(submitState.loginAction).isInstanceOf(AsyncData.Loading::class.java)
val successState = awaitItem()
assertThat(successState.loginAction).isEqualTo(Async.Success(A_USER_ID))
assertThat(successState.loginAction).isEqualTo(AsyncData.Success(A_USER_ID))
assertThat(loginUserStory.loginFlowIsDone.value).isFalse()
successState.eventSink.invoke(WaitListEvents.Continue)
assertThat(loginUserStory.loginFlowIsDone.value).isTrue()