diff --git a/changelog.d/5628.misc b/changelog.d/5628.misc
new file mode 100644
index 0000000000..9c4894c164
--- /dev/null
+++ b/changelog.d/5628.misc
@@ -0,0 +1 @@
+Adds unit tests around the login with matrix id flow
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/Result.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/Result.kt
index 3734c5dc1d..12adf16cbc 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/Result.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/Result.kt
@@ -21,3 +21,11 @@ fun Result.foldToCallback(callback: MatrixCallback): Unit = fold(
{ callback.onSuccess(it) },
{ callback.onFailure(it) }
)
+
+@Suppress("UNCHECKED_CAST") // We're casting null failure results to R
+inline fun Result.andThen(block: (T) -> Result): Result {
+ return when (val result = getOrNull()) {
+ null -> this as Result
+ else -> block(result)
+ }
+}
diff --git a/vector/src/main/java/im/vector/app/features/onboarding/DirectLoginUseCase.kt b/vector/src/main/java/im/vector/app/features/onboarding/DirectLoginUseCase.kt
new file mode 100644
index 0000000000..7ef4dfb609
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/onboarding/DirectLoginUseCase.kt
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.onboarding
+
+import im.vector.app.R
+import im.vector.app.core.resources.StringProvider
+import im.vector.app.features.onboarding.OnboardingAction.LoginOrRegister
+import org.matrix.android.sdk.api.MatrixPatterns.getDomain
+import org.matrix.android.sdk.api.auth.AuthenticationService
+import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
+import org.matrix.android.sdk.api.auth.wellknown.WellknownResult
+import org.matrix.android.sdk.api.session.Session
+import org.matrix.android.sdk.internal.extensions.andThen
+import javax.inject.Inject
+
+class DirectLoginUseCase @Inject constructor(
+ private val authenticationService: AuthenticationService,
+ private val stringProvider: StringProvider,
+ private val uriFactory: UriFactory
+) {
+
+ suspend fun execute(action: LoginOrRegister, homeServerConnectionConfig: HomeServerConnectionConfig?): Result {
+ return fetchWellKnown(action.username, homeServerConnectionConfig)
+ .andThen { wellKnown -> createSessionFor(wellKnown, action, homeServerConnectionConfig) }
+ }
+
+ private suspend fun fetchWellKnown(matrixId: String, config: HomeServerConnectionConfig?) = runCatching {
+ authenticationService.getWellKnownData(matrixId, config)
+ }
+
+ private suspend fun createSessionFor(data: WellknownResult, action: LoginOrRegister, config: HomeServerConnectionConfig?) = when (data) {
+ is WellknownResult.Prompt -> loginDirect(action, data, config)
+ is WellknownResult.FailPrompt -> handleFailPrompt(data, action, config)
+ else -> onWellKnownError()
+ }
+
+ private suspend fun handleFailPrompt(data: WellknownResult.FailPrompt, action: LoginOrRegister, config: HomeServerConnectionConfig?): Result {
+ // Relax on IS discovery if homeserver is valid
+ val isMissingInformationToLogin = data.homeServerUrl == null || data.wellKnown == null
+ return when {
+ isMissingInformationToLogin -> onWellKnownError()
+ else -> loginDirect(action, WellknownResult.Prompt(data.homeServerUrl!!, null, data.wellKnown!!), config)
+ }
+ }
+
+ private suspend fun loginDirect(action: LoginOrRegister, wellKnownPrompt: WellknownResult.Prompt, config: HomeServerConnectionConfig?): Result {
+ val alteredHomeServerConnectionConfig = config?.updateWith(wellKnownPrompt) ?: fallbackConfig(action, wellKnownPrompt)
+ return runCatching {
+ authenticationService.directAuthentication(
+ alteredHomeServerConnectionConfig,
+ action.username,
+ action.password,
+ action.initialDeviceName
+ )
+ }
+ }
+
+ private fun HomeServerConnectionConfig.updateWith(wellKnownPrompt: WellknownResult.Prompt) = copy(
+ homeServerUriBase = uriFactory.parse(wellKnownPrompt.homeServerUrl),
+ identityServerUri = wellKnownPrompt.identityServerUrl?.let { uriFactory.parse(it) }
+ )
+
+ private fun fallbackConfig(action: LoginOrRegister, wellKnownPrompt: WellknownResult.Prompt) = HomeServerConnectionConfig(
+ homeServerUri = uriFactory.parse("https://${action.username.getDomain()}"),
+ homeServerUriBase = uriFactory.parse(wellKnownPrompt.homeServerUrl),
+ identityServerUri = wellKnownPrompt.identityServerUrl?.let { uriFactory.parse(it) }
+ )
+
+ private fun onWellKnownError() = Result.failure(Exception(stringProvider.getString(R.string.autodiscover_well_known_error)))
+}
diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt
index 3fb52619da..6d959ef124 100644
--- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt
@@ -17,7 +17,6 @@
package im.vector.app.features.onboarding
import android.content.Context
-import android.net.Uri
import com.airbnb.mvrx.MavericksViewModelFactory
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
@@ -45,7 +44,6 @@ import im.vector.app.features.login.SignMode
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.launch
-import org.matrix.android.sdk.api.MatrixPatterns.getDomain
import org.matrix.android.sdk.api.auth.AuthenticationService
import org.matrix.android.sdk.api.auth.HomeServerHistoryService
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
@@ -55,9 +53,6 @@ import org.matrix.android.sdk.api.auth.registration.FlowResult
import org.matrix.android.sdk.api.auth.registration.RegistrationResult
import org.matrix.android.sdk.api.auth.registration.RegistrationWizard
import org.matrix.android.sdk.api.auth.registration.Stage
-import org.matrix.android.sdk.api.auth.wellknown.WellknownResult
-import org.matrix.android.sdk.api.failure.Failure
-import org.matrix.android.sdk.api.failure.MatrixIdFailure
import org.matrix.android.sdk.api.session.Session
import timber.log.Timber
import java.util.UUID
@@ -79,6 +74,7 @@ class OnboardingViewModel @AssistedInject constructor(
private val analyticsTracker: AnalyticsTracker,
private val uriFilenameResolver: UriFilenameResolver,
private val registrationActionHandler: RegistrationActionHandler,
+ private val directLoginUseCase: DirectLoginUseCase,
private val vectorOverrides: VectorOverrides
) : VectorViewModel(initialState) {
@@ -470,74 +466,14 @@ class OnboardingViewModel @AssistedInject constructor(
private fun handleDirectLogin(action: OnboardingAction.LoginOrRegister, homeServerConnectionConfig: HomeServerConnectionConfig?) {
setState { copy(isLoading = true) }
-
currentJob = viewModelScope.launch {
- val data = try {
- authenticationService.getWellKnownData(action.username, homeServerConnectionConfig)
- } catch (failure: Throwable) {
- onDirectLoginError(failure)
- return@launch
- }
- when (data) {
- is WellknownResult.Prompt ->
- directLoginOnWellknownSuccess(action, data, homeServerConnectionConfig)
- is WellknownResult.FailPrompt ->
- // Relax on IS discovery if homeserver is valid
- if (data.homeServerUrl != null && data.wellKnown != null) {
- directLoginOnWellknownSuccess(action, WellknownResult.Prompt(data.homeServerUrl!!, null, data.wellKnown!!), homeServerConnectionConfig)
- } else {
- onWellKnownError()
+ directLoginUseCase.execute(action, homeServerConnectionConfig).fold(
+ onSuccess = { onSessionCreated(it, isAccountCreated = false) },
+ onFailure = {
+ setState { copy(isLoading = false) }
+ _viewEvents.post(OnboardingViewEvents.Failure(it))
}
- else -> {
- onWellKnownError()
- }
- }
- }
- }
-
- private fun onWellKnownError() {
- setState { copy(isLoading = false) }
- _viewEvents.post(OnboardingViewEvents.Failure(Exception(stringProvider.getString(R.string.autodiscover_well_known_error))))
- }
-
- private suspend fun directLoginOnWellknownSuccess(action: OnboardingAction.LoginOrRegister,
- wellKnownPrompt: WellknownResult.Prompt,
- homeServerConnectionConfig: HomeServerConnectionConfig?) {
- val alteredHomeServerConnectionConfig = homeServerConnectionConfig
- ?.copy(
- homeServerUriBase = Uri.parse(wellKnownPrompt.homeServerUrl),
- identityServerUri = wellKnownPrompt.identityServerUrl?.let { Uri.parse(it) }
- )
- ?: HomeServerConnectionConfig(
- homeServerUri = Uri.parse("https://${action.username.getDomain()}"),
- homeServerUriBase = Uri.parse(wellKnownPrompt.homeServerUrl),
- identityServerUri = wellKnownPrompt.identityServerUrl?.let { Uri.parse(it) }
- )
-
- val data = try {
- authenticationService.directAuthentication(
- alteredHomeServerConnectionConfig,
- action.username,
- action.password,
- action.initialDeviceName)
- } catch (failure: Throwable) {
- onDirectLoginError(failure)
- return
- }
- onSessionCreated(data, isAccountCreated = false)
- }
-
- private fun onDirectLoginError(failure: Throwable) {
- when (failure) {
- is MatrixIdFailure.InvalidMatrixId,
- is Failure.UnrecognizedCertificateFailure -> {
- setState { copy(isLoading = false) }
- // Display this error in a dialog
- _viewEvents.post(OnboardingViewEvents.Failure(failure))
- }
- else -> {
- setState { copy(isLoading = false) }
- }
+ )
}
}
diff --git a/vector/src/main/java/im/vector/app/features/onboarding/UriFactory.kt b/vector/src/main/java/im/vector/app/features/onboarding/UriFactory.kt
new file mode 100644
index 0000000000..f9e7a3458c
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/onboarding/UriFactory.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.onboarding
+
+import android.net.Uri
+import javax.inject.Inject
+
+class UriFactory @Inject constructor() {
+
+ fun parse(value: String): Uri {
+ return Uri.parse(value)
+ }
+}
diff --git a/vector/src/test/java/im/vector/app/features/onboarding/DirectLoginUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/onboarding/DirectLoginUseCaseTest.kt
new file mode 100644
index 0000000000..5a3c323316
--- /dev/null
+++ b/vector/src/test/java/im/vector/app/features/onboarding/DirectLoginUseCaseTest.kt
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.onboarding
+
+import im.vector.app.R
+import im.vector.app.test.fakes.FakeAuthenticationService
+import im.vector.app.test.fakes.FakeSession
+import im.vector.app.test.fakes.FakeStringProvider
+import im.vector.app.test.fakes.FakeUri
+import im.vector.app.test.fakes.FakeUriFactory
+import im.vector.app.test.fakes.toTestString
+import kotlinx.coroutines.test.runTest
+import org.amshove.kluent.should
+import org.amshove.kluent.shouldBeEqualTo
+import org.junit.Test
+import org.matrix.android.sdk.api.MatrixPatterns.getDomain
+import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
+import org.matrix.android.sdk.api.auth.data.WellKnown
+import org.matrix.android.sdk.api.auth.wellknown.WellknownResult
+
+private val A_LOGIN_OR_REGISTER_ACTION = OnboardingAction.LoginOrRegister("@a-user:id.org", "a-password", "a-device-name")
+private val A_WELLKNOWN_SUCCESS_RESULT = WellknownResult.Prompt("https://homeserverurl.com", identityServerUrl = null, WellKnown())
+private val A_WELLKNOWN_FAILED_WITH_CONTENT_RESULT = WellknownResult.FailPrompt("https://homeserverurl.com", WellKnown())
+private val A_WELLKNOWN_FAILED_WITHOUT_CONTENT_RESULT = WellknownResult.FailPrompt(null, null)
+private val NO_HOMESERVER_CONFIG: HomeServerConnectionConfig? = null
+private val A_FALLBACK_CONFIG: HomeServerConnectionConfig = HomeServerConnectionConfig(
+ homeServerUri = FakeUri("https://${A_LOGIN_OR_REGISTER_ACTION.username.getDomain()}").instance,
+ homeServerUriBase = FakeUri(A_WELLKNOWN_SUCCESS_RESULT.homeServerUrl).instance,
+ identityServerUri = null
+)
+private val AN_ERROR = RuntimeException()
+
+class DirectLoginUseCaseTest {
+
+ private val fakeAuthenticationService = FakeAuthenticationService()
+ private val fakeStringProvider = FakeStringProvider()
+ private val fakeSession = FakeSession()
+
+ private val useCase = DirectLoginUseCase(fakeAuthenticationService, fakeStringProvider.instance, FakeUriFactory().instance)
+
+ @Test
+ fun `when logging in directly, then returns success with direct session result`() = runTest {
+ fakeAuthenticationService.givenWellKnown(A_LOGIN_OR_REGISTER_ACTION.username, config = NO_HOMESERVER_CONFIG, result = A_WELLKNOWN_SUCCESS_RESULT)
+ val (username, password, initialDeviceName) = A_LOGIN_OR_REGISTER_ACTION
+ fakeAuthenticationService.givenDirectAuthentication(A_FALLBACK_CONFIG, username, password, initialDeviceName, result = fakeSession)
+
+ val result = useCase.execute(A_LOGIN_OR_REGISTER_ACTION, homeServerConnectionConfig = NO_HOMESERVER_CONFIG)
+
+ result shouldBeEqualTo Result.success(fakeSession)
+ }
+
+ @Test
+ fun `given wellknown fails with content, when logging in directly, then returns success with direct session result`() = runTest {
+ fakeAuthenticationService.givenWellKnown(A_LOGIN_OR_REGISTER_ACTION.username, config = NO_HOMESERVER_CONFIG, result = A_WELLKNOWN_FAILED_WITH_CONTENT_RESULT)
+ val (username, password, initialDeviceName) = A_LOGIN_OR_REGISTER_ACTION
+ fakeAuthenticationService.givenDirectAuthentication(A_FALLBACK_CONFIG, username, password, initialDeviceName, result = fakeSession)
+
+ val result = useCase.execute(A_LOGIN_OR_REGISTER_ACTION, homeServerConnectionConfig = NO_HOMESERVER_CONFIG)
+
+ result shouldBeEqualTo Result.success(fakeSession)
+ }
+
+ @Test
+ fun `given wellknown fails without content, when logging in directly, then returns well known error`() = runTest {
+ fakeAuthenticationService.givenWellKnown(A_LOGIN_OR_REGISTER_ACTION.username, config = NO_HOMESERVER_CONFIG, result = A_WELLKNOWN_FAILED_WITHOUT_CONTENT_RESULT)
+ val (username, password, initialDeviceName) = A_LOGIN_OR_REGISTER_ACTION
+ fakeAuthenticationService.givenDirectAuthentication(A_FALLBACK_CONFIG, username, password, initialDeviceName, result = fakeSession)
+
+ val result = useCase.execute(A_LOGIN_OR_REGISTER_ACTION, homeServerConnectionConfig = NO_HOMESERVER_CONFIG)
+
+ result should { this.isFailure }
+ result should { this.exceptionOrNull() is Exception }
+ result should { this.exceptionOrNull()?.message == R.string.autodiscover_well_known_error.toTestString() }
+ }
+
+ @Test
+ fun `given wellknown throws, when logging in directly, then returns failure result with original cause`() = runTest {
+ fakeAuthenticationService.givenWellKnownThrows(A_LOGIN_OR_REGISTER_ACTION.username, config = NO_HOMESERVER_CONFIG, cause = AN_ERROR)
+
+ val result = useCase.execute(A_LOGIN_OR_REGISTER_ACTION, homeServerConnectionConfig = NO_HOMESERVER_CONFIG)
+
+ result shouldBeEqualTo Result.failure(AN_ERROR)
+ }
+
+ @Test
+ fun `given direct authentication throws, when logging in directly, then returns failure result with original cause`() = runTest {
+ fakeAuthenticationService.givenWellKnown(A_LOGIN_OR_REGISTER_ACTION.username, config = NO_HOMESERVER_CONFIG, result = A_WELLKNOWN_SUCCESS_RESULT)
+ val (username, password, initialDeviceName) = A_LOGIN_OR_REGISTER_ACTION
+ fakeAuthenticationService.givenDirectAuthenticationThrows(A_FALLBACK_CONFIG, username, password, initialDeviceName, cause = AN_ERROR)
+
+ val result = useCase.execute(A_LOGIN_OR_REGISTER_ACTION, homeServerConnectionConfig = NO_HOMESERVER_CONFIG)
+
+ result shouldBeEqualTo Result.failure(AN_ERROR)
+ }
+}
diff --git a/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt b/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt
index df4e0de65e..118bf689d2 100644
--- a/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt
+++ b/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt
@@ -24,6 +24,7 @@ import im.vector.app.test.fakes.FakeActiveSessionHolder
import im.vector.app.test.fakes.FakeAnalyticsTracker
import im.vector.app.test.fakes.FakeAuthenticationService
import im.vector.app.test.fakes.FakeContext
+import im.vector.app.test.fakes.FakeDirectLoginUseCase
import im.vector.app.test.fakes.FakeHomeServerConnectionConfigFactory
import im.vector.app.test.fakes.FakeHomeServerHistoryService
import im.vector.app.test.fakes.FakeRegisterActionHandler
@@ -44,6 +45,7 @@ import org.matrix.android.sdk.api.auth.registration.FlowResult
import org.matrix.android.sdk.api.auth.registration.RegisterThreePid
import org.matrix.android.sdk.api.auth.registration.RegistrationResult
import org.matrix.android.sdk.api.auth.registration.Stage
+import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
private const val A_DISPLAY_NAME = "a display name"
@@ -55,6 +57,7 @@ private val A_RESULT_IGNORED_REGISTER_ACTION = RegisterAction.AddThreePid(Regist
private val A_HOMESERVER_CAPABILITIES = aHomeServerCapabilities(canChangeDisplayName = true, canChangeAvatar = true)
private val AN_IGNORED_FLOW_RESULT = FlowResult(missingStages = emptyList(), completedStages = emptyList())
private val ANY_CONTINUING_REGISTRATION_RESULT = RegistrationResult.FlowResponse(AN_IGNORED_FLOW_RESULT)
+private val A_LOGIN_OR_REGISTER_ACTION = OnboardingAction.LoginOrRegister("@a-user:id.org", "a-password", "a-device-name")
class OnboardingViewModelTest {
@@ -69,6 +72,7 @@ class OnboardingViewModelTest {
private val fakeActiveSessionHolder = FakeActiveSessionHolder(fakeSession)
private val fakeAuthenticationService = FakeAuthenticationService()
private val fakeRegisterActionHandler = FakeRegisterActionHandler()
+ private val fakeDirectLoginUseCase = FakeDirectLoginUseCase()
lateinit var viewModel: OnboardingViewModel
@@ -114,6 +118,46 @@ class OnboardingViewModelTest {
.finish()
}
+ @Test
+ fun `given has sign in with matrix id sign mode, when handling login or register action, then logs in directly`() = runTest {
+ val initialState = initialState.copy(signMode = SignMode.SignInWithMatrixId)
+ viewModel = createViewModel(initialState)
+ fakeDirectLoginUseCase.givenSuccessResult(A_LOGIN_OR_REGISTER_ACTION, config = null, result = fakeSession)
+ givenInitialisesSession(fakeSession)
+ val test = viewModel.test()
+
+ viewModel.handle(A_LOGIN_OR_REGISTER_ACTION)
+
+ test
+ .assertStatesChanges(
+ initialState,
+ { copy(isLoading = true) },
+ { copy(isLoading = false) }
+ )
+ .assertEvents(OnboardingViewEvents.OnAccountSignedIn)
+ .finish()
+ }
+
+ @Test
+ fun `given has sign in with matrix id sign mode, when handling login or register action fails, then emits error`() = runTest {
+ val initialState = initialState.copy(signMode = SignMode.SignInWithMatrixId)
+ viewModel = createViewModel(initialState)
+ fakeDirectLoginUseCase.givenFailureResult(A_LOGIN_OR_REGISTER_ACTION, config = null, cause = AN_ERROR)
+ givenInitialisesSession(fakeSession)
+ val test = viewModel.test()
+
+ viewModel.handle(A_LOGIN_OR_REGISTER_ACTION)
+
+ test
+ .assertStatesChanges(
+ initialState,
+ { copy(isLoading = true) },
+ { copy(isLoading = false) }
+ )
+ .assertEvents(OnboardingViewEvents.Failure(AN_ERROR))
+ .finish()
+ }
+
@Test
fun `when handling SignUp then sets sign mode to sign up and starts registration`() = runTest {
givenRegistrationResultFor(RegisterAction.StartRegistration, ANY_CONTINUING_REGISTRATION_RESULT)
@@ -344,6 +388,7 @@ class OnboardingViewModelTest {
FakeAnalyticsTracker(),
fakeUriFilenameResolver.instance,
fakeRegisterActionHandler.instance,
+ fakeDirectLoginUseCase.instance,
FakeVectorOverrides()
)
}
@@ -384,7 +429,11 @@ class OnboardingViewModelTest {
private fun givenSuccessfullyCreatesAccount(homeServerCapabilities: HomeServerCapabilities) {
fakeSession.fakeHomeServerCapabilitiesService.givenCapabilities(homeServerCapabilities)
- fakeActiveSessionHolder.expectSetsActiveSession(fakeSession)
+ givenInitialisesSession(fakeSession)
+ }
+
+ private fun givenInitialisesSession(session: Session) {
+ fakeActiveSessionHolder.expectSetsActiveSession(session)
fakeAuthenticationService.expectReset()
fakeSession.expectStartsSyncing()
}
diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeAuthenticationService.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeAuthenticationService.kt
index 10daf5de1e..9175fd3750 100644
--- a/vector/src/test/java/im/vector/app/test/fakes/FakeAuthenticationService.kt
+++ b/vector/src/test/java/im/vector/app/test/fakes/FakeAuthenticationService.kt
@@ -16,11 +16,14 @@
package im.vector.app.test.fakes
+import io.mockk.coEvery
import io.mockk.coJustRun
import io.mockk.every
import io.mockk.mockk
import org.matrix.android.sdk.api.auth.AuthenticationService
+import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
import org.matrix.android.sdk.api.auth.registration.RegistrationWizard
+import org.matrix.android.sdk.api.auth.wellknown.WellknownResult
class FakeAuthenticationService : AuthenticationService by mockk() {
@@ -35,4 +38,20 @@ class FakeAuthenticationService : AuthenticationService by mockk() {
fun expectReset() {
coJustRun { reset() }
}
+
+ fun givenWellKnown(matrixId: String, config: HomeServerConnectionConfig?, result: WellknownResult) {
+ coEvery { getWellKnownData(matrixId, config) } returns result
+ }
+
+ fun givenWellKnownThrows(matrixId: String, config: HomeServerConnectionConfig?, cause: Throwable) {
+ coEvery { getWellKnownData(matrixId, config) } throws cause
+ }
+
+ fun givenDirectAuthentication(config: HomeServerConnectionConfig, matrixId: String, password: String, deviceName: String, result: FakeSession) {
+ coEvery { directAuthentication(config, matrixId, password, deviceName) } returns result
+ }
+
+ fun givenDirectAuthenticationThrows(config: HomeServerConnectionConfig, matrixId: String, password: String, deviceName: String, cause: Throwable) {
+ coEvery { directAuthentication(config, matrixId, password, deviceName) } throws cause
+ }
}
diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeDirectLoginUseCase.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeDirectLoginUseCase.kt
new file mode 100644
index 0000000000..8a5c6b1cee
--- /dev/null
+++ b/vector/src/test/java/im/vector/app/test/fakes/FakeDirectLoginUseCase.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.test.fakes
+
+import im.vector.app.features.onboarding.DirectLoginUseCase
+import im.vector.app.features.onboarding.OnboardingAction
+import io.mockk.coEvery
+import io.mockk.mockk
+import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
+
+class FakeDirectLoginUseCase {
+ val instance = mockk()
+
+ fun givenSuccessResult(action: OnboardingAction.LoginOrRegister, config: HomeServerConnectionConfig?, result: FakeSession) {
+ coEvery { instance.execute(action, config) } returns Result.success(result)
+ }
+
+ fun givenFailureResult(action: OnboardingAction.LoginOrRegister, config: HomeServerConnectionConfig?, cause: Throwable) {
+ coEvery { instance.execute(action, config) } returns Result.failure(cause)
+ }
+}
diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeStringProvider.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeStringProvider.kt
index f9001e3f8a..1a4f5cb85b 100644
--- a/vector/src/test/java/im/vector/app/test/fakes/FakeStringProvider.kt
+++ b/vector/src/test/java/im/vector/app/test/fakes/FakeStringProvider.kt
@@ -30,3 +30,5 @@ class FakeStringProvider {
}
}
}
+
+fun Int.toTestString() = "test-$this"
diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeUri.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeUri.kt
index 99f2cf39aa..675401d72f 100644
--- a/vector/src/test/java/im/vector/app/test/fakes/FakeUri.kt
+++ b/vector/src/test/java/im/vector/app/test/fakes/FakeUri.kt
@@ -20,9 +20,14 @@ import android.net.Uri
import io.mockk.every
import io.mockk.mockk
-class FakeUri {
+class FakeUri(contentEquals: String? = null) {
+
val instance = mockk()
+ init {
+ contentEquals?.let { givenEquals(it) }
+ }
+
fun givenNonHierarchical() {
givenContent(schema = "mail", path = null)
}
@@ -31,4 +36,12 @@ class FakeUri {
every { instance.scheme } returns schema
every { instance.path } returns path
}
+
+ @Suppress("ReplaceCallWithBinaryOperator")
+ fun givenEquals(content: String) {
+ every { instance.equals(any()) } answers {
+ it.invocation.args.first() == content
+ }
+ every { instance.hashCode() } answers { content.hashCode() }
+ }
}
diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeUriFactory.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeUriFactory.kt
new file mode 100644
index 0000000000..90b615cb7c
--- /dev/null
+++ b/vector/src/test/java/im/vector/app/test/fakes/FakeUriFactory.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.test.fakes
+
+import im.vector.app.features.onboarding.UriFactory
+import io.mockk.every
+import io.mockk.mockk
+
+class FakeUriFactory {
+
+ val instance = mockk().also {
+ every { it.parse(any()) } answers {
+ val input = it.invocation.args.first() as String
+ FakeUri().also { it.givenEquals(input) }.instance
+ }
+ }
+}