Allow configuration to provide multiple account providers. (#4742)
* Allow several account provider in configuration * Target latest private modules. * Fix tests * Target latest private modules. * Trigger CI * Fix formatting issue
This commit is contained in:
Submodule enterprise updated: c754703e72...d3dffc97bf
@@ -13,7 +13,7 @@ import io.element.android.libraries.matrix.api.core.SessionId
|
||||
interface EnterpriseService {
|
||||
val isEnterpriseBuild: Boolean
|
||||
suspend fun isEnterpriseUser(sessionId: SessionId): Boolean
|
||||
fun defaultHomeserver(): String?
|
||||
fun defaultHomeserverList(): List<String>
|
||||
suspend fun isAllowedToConnectToHomeserver(homeserverUrl: String): Boolean
|
||||
|
||||
fun semanticColorsLight(): SemanticColors
|
||||
|
||||
@@ -22,7 +22,7 @@ class DefaultEnterpriseService @Inject constructor() : EnterpriseService {
|
||||
|
||||
override suspend fun isEnterpriseUser(sessionId: SessionId) = false
|
||||
|
||||
override fun defaultHomeserver() = null
|
||||
override fun defaultHomeserverList(): List<String> = emptyList()
|
||||
override suspend fun isAllowedToConnectToHomeserver(homeserverUrl: String) = true
|
||||
|
||||
override fun semanticColorsLight(): SemanticColors = compoundColorsLight
|
||||
|
||||
@@ -21,9 +21,9 @@ class DefaultEnterpriseServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `defaultHomeserver should return null`() {
|
||||
fun `defaultHomeserverList should return empty list`() {
|
||||
val defaultEnterpriseService = DefaultEnterpriseService()
|
||||
assertThat<String?>(defaultEnterpriseService.defaultHomeserver()).isNull()
|
||||
assertThat(defaultEnterpriseService.defaultHomeserverList()).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -16,7 +16,7 @@ import io.element.android.tests.testutils.simulateLongTask
|
||||
class FakeEnterpriseService(
|
||||
override val isEnterpriseBuild: Boolean = false,
|
||||
private val isEnterpriseUserResult: (SessionId) -> Boolean = { lambdaError() },
|
||||
private val defaultHomeserverResult: () -> String? = { A_FAKE_HOMESERVER },
|
||||
private val defaultHomeserverListResult: () -> List<String> = { emptyList() },
|
||||
private val isAllowedToConnectToHomeserverResult: (String) -> Boolean = { lambdaError() },
|
||||
private val semanticColorsLightResult: () -> SemanticColors = { lambdaError() },
|
||||
private val semanticColorsDarkResult: () -> SemanticColors = { lambdaError() },
|
||||
@@ -27,8 +27,8 @@ class FakeEnterpriseService(
|
||||
isEnterpriseUserResult(sessionId)
|
||||
}
|
||||
|
||||
override fun defaultHomeserver(): String? {
|
||||
return defaultHomeserverResult()
|
||||
override fun defaultHomeserverList(): List<String> {
|
||||
return defaultHomeserverListResult()
|
||||
}
|
||||
|
||||
override suspend fun isAllowedToConnectToHomeserver(homeserverUrl: String): Boolean = simulateLongTask {
|
||||
|
||||
@@ -20,14 +20,15 @@ import javax.inject.Inject
|
||||
class AccountProviderDataSource @Inject constructor(
|
||||
enterpriseService: EnterpriseService,
|
||||
) {
|
||||
private val defaultAccountProvider = (enterpriseService.defaultHomeserver() ?: AuthenticationConfig.MATRIX_ORG_URL).let { url ->
|
||||
AccountProvider(
|
||||
url = url,
|
||||
subtitle = null,
|
||||
isPublic = url == AuthenticationConfig.MATRIX_ORG_URL,
|
||||
isMatrixOrg = url == AuthenticationConfig.MATRIX_ORG_URL,
|
||||
)
|
||||
}
|
||||
private val defaultAccountProvider = (enterpriseService.defaultHomeserverList().firstOrNull() ?: AuthenticationConfig.MATRIX_ORG_URL)
|
||||
.let { url ->
|
||||
AccountProvider(
|
||||
url = url,
|
||||
subtitle = null,
|
||||
isPublic = url == AuthenticationConfig.MATRIX_ORG_URL,
|
||||
isMatrixOrg = url == AuthenticationConfig.MATRIX_ORG_URL,
|
||||
)
|
||||
}
|
||||
|
||||
private val accountProvider: MutableStateFlow<AccountProvider> = MutableStateFlow(
|
||||
defaultAccountProvider
|
||||
|
||||
@@ -8,29 +8,39 @@
|
||||
package io.element.android.features.login.impl.screens.changeaccountprovider
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import io.element.android.appconfig.AuthenticationConfig
|
||||
import io.element.android.features.enterprise.api.EnterpriseService
|
||||
import io.element.android.features.login.impl.accountprovider.AccountProvider
|
||||
import io.element.android.features.login.impl.changeserver.ChangeServerState
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.core.uri.ensureProtocol
|
||||
import javax.inject.Inject
|
||||
|
||||
class ChangeAccountProviderPresenter @Inject constructor(
|
||||
private val changeServerPresenter: Presenter<ChangeServerState>,
|
||||
private val enterpriseService: EnterpriseService,
|
||||
) : Presenter<ChangeAccountProviderState> {
|
||||
@Composable
|
||||
override fun present(): ChangeAccountProviderState {
|
||||
val staticAccountProviderList = remember {
|
||||
enterpriseService.defaultHomeserverList()
|
||||
.map { it.ensureProtocol() }
|
||||
.ifEmpty { listOf(AuthenticationConfig.MATRIX_ORG_URL) }
|
||||
.map { url ->
|
||||
AccountProvider(
|
||||
url = url,
|
||||
subtitle = null,
|
||||
isPublic = url == AuthenticationConfig.MATRIX_ORG_URL,
|
||||
isMatrixOrg = url == AuthenticationConfig.MATRIX_ORG_URL,
|
||||
isValid = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val changeServerState = changeServerPresenter.present()
|
||||
return ChangeAccountProviderState(
|
||||
// Just matrix.org by default for now
|
||||
accountProviders = listOf(
|
||||
AccountProvider(
|
||||
url = AuthenticationConfig.MATRIX_ORG_URL,
|
||||
subtitle = null,
|
||||
isPublic = true,
|
||||
isMatrixOrg = true,
|
||||
isValid = true,
|
||||
)
|
||||
),
|
||||
accountProviders = staticAccountProviderList,
|
||||
changeServerState = changeServerState,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import io.element.android.features.login.impl.accountprovider.AccountProvider
|
||||
import io.element.android.features.login.impl.changeserver.ChangeServerState
|
||||
|
||||
// Do not use default value, so no member get forgotten in the presenters.
|
||||
data class ChangeAccountProviderState constructor(
|
||||
data class ChangeAccountProviderState(
|
||||
val accountProviders: List<AccountProvider>,
|
||||
val changeServerState: ChangeServerState,
|
||||
)
|
||||
|
||||
@@ -27,11 +27,11 @@ class AccountProviderDataSourceTest {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState).isEqualTo(
|
||||
AccountProvider(
|
||||
url = FakeEnterpriseService.A_FAKE_HOMESERVER,
|
||||
title = FakeEnterpriseService.A_FAKE_HOMESERVER,
|
||||
url = AuthenticationConfig.MATRIX_ORG_URL,
|
||||
title = "matrix.org",
|
||||
subtitle = null,
|
||||
isPublic = false,
|
||||
isMatrixOrg = false,
|
||||
isPublic = true,
|
||||
isMatrixOrg = true,
|
||||
isValid = false,
|
||||
)
|
||||
)
|
||||
@@ -40,9 +40,11 @@ class AccountProviderDataSourceTest {
|
||||
|
||||
@Test
|
||||
fun `present - initial state - matrix org`() = runTest {
|
||||
val sut = AccountProviderDataSource(FakeEnterpriseService(
|
||||
defaultHomeserverResult = { AuthenticationConfig.MATRIX_ORG_URL }
|
||||
))
|
||||
val sut = AccountProviderDataSource(
|
||||
FakeEnterpriseService(
|
||||
defaultHomeserverListResult = { listOf(AuthenticationConfig.MATRIX_ORG_URL) }
|
||||
)
|
||||
)
|
||||
sut.flow.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState).isEqualTo(
|
||||
@@ -63,7 +65,7 @@ class AccountProviderDataSourceTest {
|
||||
val sut = AccountProviderDataSource(FakeEnterpriseService())
|
||||
sut.flow.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.url).isEqualTo(FakeEnterpriseService.A_FAKE_HOMESERVER)
|
||||
assertThat(initialState.url).isEqualTo(AuthenticationConfig.MATRIX_ORG_URL)
|
||||
sut.userSelection(AccountProvider(url = "https://example.com"))
|
||||
val changedState = awaitItem()
|
||||
assertThat(changedState).isEqualTo(
|
||||
@@ -78,7 +80,7 @@ class AccountProviderDataSourceTest {
|
||||
)
|
||||
sut.reset()
|
||||
val resetState = awaitItem()
|
||||
assertThat(resetState.url).isEqualTo(FakeEnterpriseService.A_FAKE_HOMESERVER)
|
||||
assertThat(resetState.url).isEqualTo(AuthenticationConfig.MATRIX_ORG_URL)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ 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.test.FakeEnterpriseService
|
||||
import io.element.android.features.login.impl.accountprovider.AccountProvider
|
||||
import io.element.android.features.login.impl.changeserver.aChangeServerState
|
||||
import io.element.android.tests.testutils.WarmUpRule
|
||||
@@ -25,7 +26,8 @@ class ChangeAccountProviderPresenterTest {
|
||||
@Test
|
||||
fun `present - initial state`() = runTest {
|
||||
val presenter = ChangeAccountProviderPresenter(
|
||||
changeServerPresenter = { aChangeServerState() }
|
||||
changeServerPresenter = { aChangeServerState() },
|
||||
enterpriseService = FakeEnterpriseService(),
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
|
||||
@@ -11,6 +11,7 @@ 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
|
||||
import io.element.android.features.login.impl.DefaultLoginUserStory
|
||||
import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource
|
||||
@@ -44,7 +45,7 @@ class ConfirmAccountProviderPresenterTest {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.isAccountCreation).isFalse()
|
||||
assertThat(initialState.submitEnabled).isTrue()
|
||||
assertThat(initialState.accountProvider.url).isEqualTo(FakeEnterpriseService.A_FAKE_HOMESERVER)
|
||||
assertThat(initialState.accountProvider.url).isEqualTo(AuthenticationConfig.MATRIX_ORG_URL)
|
||||
assertThat(initialState.loginFlow).isEqualTo(AsyncData.Uninitialized)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
package io.element.android.features.login.impl.screens.createaccount
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.appconfig.AuthenticationConfig
|
||||
import io.element.android.features.enterprise.test.FakeEnterpriseService
|
||||
import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource
|
||||
import io.element.android.libraries.matrix.api.auth.external.ExternalSession
|
||||
@@ -60,7 +61,7 @@ class DefaultMessageParserTest {
|
||||
// missing homeServer
|
||||
assertThat(sut.parse(validMessage.replace(""""home_server": "home_server",""", ""))).isEqualTo(
|
||||
anExternalSession(
|
||||
homeserverUrl = FakeEnterpriseService.A_FAKE_HOMESERVER,
|
||||
homeserverUrl = AuthenticationConfig.MATRIX_ORG_URL,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
package io.element.android.features.login.impl.screens.loginpassword
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.appconfig.AuthenticationConfig
|
||||
import io.element.android.features.enterprise.test.FakeEnterpriseService
|
||||
import io.element.android.features.login.impl.DefaultLoginUserStory
|
||||
import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource
|
||||
@@ -33,7 +34,7 @@ class LoginPasswordPresenterTest {
|
||||
fun `present - initial state`() = runTest {
|
||||
createLoginPasswordPresenter().test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.accountProvider.url).isEqualTo(FakeEnterpriseService.A_FAKE_HOMESERVER)
|
||||
assertThat(initialState.accountProvider.url).isEqualTo(AuthenticationConfig.MATRIX_ORG_URL)
|
||||
assertThat(initialState.formState).isEqualTo(LoginFormState.Default)
|
||||
assertThat(initialState.loginAction).isEqualTo(AsyncData.Uninitialized)
|
||||
assertThat(initialState.submitEnabled).isFalse()
|
||||
|
||||
Reference in New Issue
Block a user