Skip to content

Commit bd43d86

Browse files
committed
Ensure that the current account provider is set when using a login deeplink. Fixes #5004
1 parent 77bc9b8 commit bd43d86

File tree

4 files changed

+66
-21
lines changed

4 files changed

+66
-21
lines changed

features/login/impl/src/main/kotlin/io/element/android/features/login/impl/accountprovider/AccountProviderDataSource.kt

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,28 +21,34 @@ import kotlinx.coroutines.flow.asStateFlow
2121
class AccountProviderDataSource(
2222
enterpriseService: EnterpriseService,
2323
) {
24-
private val defaultAccountProvider =
25-
(enterpriseService.defaultHomeserverList().firstOrNull { it != EnterpriseService.ANY_ACCOUNT_PROVIDER } ?: AuthenticationConfig.MATRIX_ORG_URL)
26-
.let { url ->
27-
AccountProvider(
28-
url = url,
29-
subtitle = null,
30-
isPublic = url == AuthenticationConfig.MATRIX_ORG_URL,
31-
isMatrixOrg = url == AuthenticationConfig.MATRIX_ORG_URL,
32-
)
33-
}
34-
35-
private val accountProvider: MutableStateFlow<AccountProvider> = MutableStateFlow(
36-
defaultAccountProvider
24+
private val defaultAccountProvider = createAccountProvider(
25+
url = enterpriseService.defaultHomeserverList()
26+
.firstOrNull { it != EnterpriseService.ANY_ACCOUNT_PROVIDER }
27+
?: AuthenticationConfig.MATRIX_ORG_URL
3728
)
3829

30+
private val accountProvider: MutableStateFlow<AccountProvider> = MutableStateFlow(defaultAccountProvider)
31+
3932
val flow: StateFlow<AccountProvider> = accountProvider.asStateFlow()
4033

4134
fun reset() {
4235
accountProvider.tryEmit(defaultAccountProvider)
4336
}
4437

38+
fun setUrl(url: String) {
39+
userSelection(createAccountProvider(url))
40+
}
41+
4542
fun userSelection(data: AccountProvider) {
4643
accountProvider.tryEmit(data)
4744
}
45+
46+
private fun createAccountProvider(url: String): AccountProvider {
47+
return AccountProvider(
48+
url = url,
49+
subtitle = null,
50+
isPublic = url == AuthenticationConfig.MATRIX_ORG_URL,
51+
isMatrixOrg = url == AuthenticationConfig.MATRIX_ORG_URL,
52+
)
53+
}
4854
}

features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingPresenter.kt

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import io.element.android.appconfig.OnBoardingConfig
2323
import io.element.android.features.enterprise.api.EnterpriseService
2424
import io.element.android.features.enterprise.api.canConnectToAnyHomeserver
2525
import io.element.android.features.login.impl.accesscontrol.DefaultAccountProviderAccessControl
26+
import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource
2627
import io.element.android.features.login.impl.login.LoginHelper
2728
import io.element.android.features.rageshake.api.RageshakeFeatureAvailability
2829
import io.element.android.libraries.architecture.Presenter
@@ -40,6 +41,7 @@ class OnBoardingPresenter(
4041
private val loginHelper: LoginHelper,
4142
private val onBoardingLogoResIdProvider: OnBoardingLogoResIdProvider,
4243
private val sessionStore: SessionStore,
44+
private val accountProviderDataSource: AccountProviderDataSource,
4345
) : Presenter<OnBoardingState> {
4446
@AssistedFactory
4547
interface Factory {
@@ -97,12 +99,16 @@ class OnBoardingPresenter(
9799

98100
fun handleEvent(event: OnBoardingEvents) {
99101
when (event) {
100-
is OnBoardingEvents.OnSignIn -> loginHelper.submit(
101-
coroutineScope = localCoroutineScope,
102-
isAccountCreation = false,
103-
homeserverUrl = event.defaultAccountProvider,
104-
loginHint = params.loginHint?.takeIf { forcedAccountProvider == null },
105-
)
102+
is OnBoardingEvents.OnSignIn -> {
103+
// Ensure that the current account provider is set
104+
accountProviderDataSource.setUrl(event.defaultAccountProvider)
105+
loginHelper.submit(
106+
coroutineScope = localCoroutineScope,
107+
isAccountCreation = false,
108+
homeserverUrl = event.defaultAccountProvider,
109+
loginHint = params.loginHint?.takeIf { forcedAccountProvider == null },
110+
)
111+
}
106112
OnBoardingEvents.ClearError -> loginHelper.clearError()
107113
OnBoardingEvents.OnVersionClick -> {
108114
if (canReportBug) {

features/login/impl/src/test/kotlin/io/element/android/features/login/impl/accountprovider/AccountProviderDataSourceTest.kt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,27 @@ class AccountProviderDataSourceTest {
102102
assertThat(resetState.url).isEqualTo(AuthenticationConfig.MATRIX_ORG_URL)
103103
}
104104
}
105+
106+
@Test
107+
fun `present - set url and reset`() = runTest {
108+
val sut = AccountProviderDataSource(FakeEnterpriseService())
109+
sut.flow.test {
110+
val initialState = awaitItem()
111+
assertThat(initialState.url).isEqualTo(AuthenticationConfig.MATRIX_ORG_URL)
112+
sut.setUrl(url = "https://example.com")
113+
val changedState = awaitItem()
114+
assertThat(changedState).isEqualTo(
115+
AccountProvider(
116+
url = "https://example.com",
117+
title = "example.com",
118+
subtitle = null,
119+
isPublic = false,
120+
isMatrixOrg = false,
121+
)
122+
)
123+
sut.reset()
124+
val resetState = awaitItem()
125+
assertThat(resetState.url).isEqualTo(AuthenticationConfig.MATRIX_ORG_URL)
126+
}
127+
}
105128
}

features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingPresenterTest.kt

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
package io.element.android.features.login.impl.screens.onboarding
99

1010
import com.google.common.truth.Truth.assertThat
11+
import io.element.android.appconfig.AuthenticationConfig
1112
import io.element.android.appconfig.OnBoardingConfig
1213
import io.element.android.features.enterprise.api.EnterpriseService
1314
import io.element.android.features.enterprise.test.FakeEnterpriseService
1415
import io.element.android.features.login.impl.accesscontrol.DefaultAccountProviderAccessControl
16+
import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource
1517
import io.element.android.features.login.impl.login.LoginHelper
1618
import io.element.android.features.login.impl.web.FakeWebClientUrlForAuthenticationRetriever
1719
import io.element.android.features.login.impl.web.WebClientUrlForAuthenticationRetriever
@@ -24,6 +26,7 @@ import io.element.android.libraries.matrix.test.AN_ACCOUNT_PROVIDER_2
2426
import io.element.android.libraries.matrix.test.AN_ACCOUNT_PROVIDER_3
2527
import io.element.android.libraries.matrix.test.AN_EXCEPTION
2628
import io.element.android.libraries.matrix.test.A_HOMESERVER_URL
29+
import io.element.android.libraries.matrix.test.A_HOMESERVER_URL_2
2730
import io.element.android.libraries.matrix.test.A_LOGIN_HINT
2831
import io.element.android.libraries.matrix.test.auth.FakeMatrixAuthenticationService
2932
import io.element.android.libraries.matrix.test.core.aBuildMeta
@@ -36,6 +39,7 @@ import io.element.android.libraries.wellknown.api.WellknownRetriever
3639
import io.element.android.tests.testutils.WarmUpRule
3740
import io.element.android.tests.testutils.test
3841
import kotlinx.coroutines.flow.Flow
42+
import kotlinx.coroutines.flow.first
3943
import kotlinx.coroutines.flow.flowOf
4044
import kotlinx.coroutines.test.runTest
4145
import org.junit.Rule
@@ -219,6 +223,7 @@ class OnBoardingPresenterTest {
219223
Result.failure(AN_EXCEPTION)
220224
},
221225
)
226+
val accountProviderDataSource = AccountProviderDataSource(FakeEnterpriseService())
222227
val presenter = createPresenter(
223228
params = OnBoardingNode.Params(
224229
accountProvider = A_HOMESERVER_URL,
@@ -230,14 +235,17 @@ class OnBoardingPresenterTest {
230235
loginHelper = createLoginHelper(
231236
authenticationService = authenticationService,
232237
),
238+
accountProviderDataSource = accountProviderDataSource,
233239
)
234240
presenter.test {
235241
skipItems(3)
236242
awaitItem().also {
237243
assertThat(it.defaultAccountProvider).isEqualTo(A_HOMESERVER_URL)
238-
it.eventSink(OnBoardingEvents.OnSignIn(A_HOMESERVER_URL))
244+
assertThat(accountProviderDataSource.flow.first().url).isEqualTo(AuthenticationConfig.MATRIX_ORG_URL)
245+
it.eventSink(OnBoardingEvents.OnSignIn(A_HOMESERVER_URL_2))
239246
skipItems(1) // Loading
240-
247+
// Account data source has been updated
248+
assertThat(accountProviderDataSource.flow.first().url).isEqualTo(A_HOMESERVER_URL_2)
241249
// Check an error was returned
242250
val submittedState = awaitItem()
243251
assertThat(submittedState.loginMode).isInstanceOf(AsyncData.Failure::class.java)
@@ -260,6 +268,7 @@ private fun createPresenter(
260268
loginHelper: LoginHelper = createLoginHelper(),
261269
onBoardingLogoResIdProvider: OnBoardingLogoResIdProvider = OnBoardingLogoResIdProvider { null },
262270
sessionStore: SessionStore = InMemorySessionStore(),
271+
accountProviderDataSource: AccountProviderDataSource = AccountProviderDataSource(FakeEnterpriseService()),
263272
) = OnBoardingPresenter(
264273
params = params,
265274
buildMeta = buildMeta,
@@ -272,6 +281,7 @@ private fun createPresenter(
272281
loginHelper = loginHelper,
273282
onBoardingLogoResIdProvider = onBoardingLogoResIdProvider,
274283
sessionStore = sessionStore,
284+
accountProviderDataSource = accountProviderDataSource,
275285
)
276286

277287
fun createLoginHelper(

0 commit comments

Comments
 (0)