Unify the internal pinunlock.SignOut and the new LogoutUseCase classes
This commit is contained in:
parent
043682300a
commit
fc6436dada
13 changed files with 104 additions and 149 deletions
|
|
@ -41,6 +41,7 @@ dependencies {
|
||||||
implementation(projects.libraries.featureflag.api)
|
implementation(projects.libraries.featureflag.api)
|
||||||
implementation(projects.libraries.cryptography.api)
|
implementation(projects.libraries.cryptography.api)
|
||||||
implementation(projects.libraries.preferences.api)
|
implementation(projects.libraries.preferences.api)
|
||||||
|
implementation(projects.features.logout.api)
|
||||||
implementation(projects.libraries.uiStrings)
|
implementation(projects.libraries.uiStrings)
|
||||||
implementation(projects.libraries.sessionStorage.api)
|
implementation(projects.libraries.sessionStorage.api)
|
||||||
implementation(projects.services.appnavstate.api)
|
implementation(projects.services.appnavstate.api)
|
||||||
|
|
@ -59,4 +60,5 @@ dependencies {
|
||||||
testImplementation(projects.libraries.featureflag.test)
|
testImplementation(projects.libraries.featureflag.test)
|
||||||
testImplementation(projects.libraries.sessionStorage.test)
|
testImplementation(projects.libraries.sessionStorage.test)
|
||||||
testImplementation(projects.services.appnavstate.test)
|
testImplementation(projects.services.appnavstate.test)
|
||||||
|
testImplementation(projects.features.logout.test)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ import io.element.android.features.lockscreen.impl.biometric.BiometricUnlockMana
|
||||||
import io.element.android.features.lockscreen.impl.pin.PinCodeManager
|
import io.element.android.features.lockscreen.impl.pin.PinCodeManager
|
||||||
import io.element.android.features.lockscreen.impl.pin.model.PinEntry
|
import io.element.android.features.lockscreen.impl.pin.model.PinEntry
|
||||||
import io.element.android.features.lockscreen.impl.unlock.keypad.PinKeypadModel
|
import io.element.android.features.lockscreen.impl.unlock.keypad.PinKeypadModel
|
||||||
import io.element.android.features.lockscreen.impl.unlock.signout.SignOut
|
import io.element.android.features.logout.api.LogoutUseCase
|
||||||
import io.element.android.libraries.architecture.AsyncData
|
import io.element.android.libraries.architecture.AsyncData
|
||||||
import io.element.android.libraries.architecture.Presenter
|
import io.element.android.libraries.architecture.Presenter
|
||||||
import io.element.android.libraries.architecture.runCatchingUpdatingState
|
import io.element.android.libraries.architecture.runCatchingUpdatingState
|
||||||
|
|
@ -41,7 +41,7 @@ import javax.inject.Inject
|
||||||
class PinUnlockPresenter @Inject constructor(
|
class PinUnlockPresenter @Inject constructor(
|
||||||
private val pinCodeManager: PinCodeManager,
|
private val pinCodeManager: PinCodeManager,
|
||||||
private val biometricUnlockManager: BiometricUnlockManager,
|
private val biometricUnlockManager: BiometricUnlockManager,
|
||||||
private val signOut: SignOut,
|
private val logoutUseCase: LogoutUseCase,
|
||||||
private val coroutineScope: CoroutineScope,
|
private val coroutineScope: CoroutineScope,
|
||||||
private val pinUnlockHelper: PinUnlockHelper,
|
private val pinUnlockHelper: PinUnlockHelper,
|
||||||
) : Presenter<PinUnlockState> {
|
) : Presenter<PinUnlockState> {
|
||||||
|
|
@ -179,7 +179,7 @@ class PinUnlockPresenter @Inject constructor(
|
||||||
|
|
||||||
private fun CoroutineScope.signOut(signOutAction: MutableState<AsyncData<String?>>) = launch {
|
private fun CoroutineScope.signOut(signOutAction: MutableState<AsyncData<String?>>) = launch {
|
||||||
suspend {
|
suspend {
|
||||||
signOut()
|
logoutUseCase.logout(ignoreSdkError = true)
|
||||||
}.runCatchingUpdatingState(signOutAction)
|
}.runCatchingUpdatingState(signOutAction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,9 @@ package io.element.android.features.lockscreen.impl.unlock.di
|
||||||
|
|
||||||
import com.squareup.anvil.annotations.ContributesTo
|
import com.squareup.anvil.annotations.ContributesTo
|
||||||
import io.element.android.features.lockscreen.impl.unlock.activity.PinUnlockActivity
|
import io.element.android.features.lockscreen.impl.unlock.activity.PinUnlockActivity
|
||||||
import io.element.android.libraries.di.AppScope
|
import io.element.android.libraries.di.SessionScope
|
||||||
|
|
||||||
@ContributesTo(AppScope::class)
|
@ContributesTo(SessionScope::class)
|
||||||
interface PinUnlockBindings {
|
interface PinUnlockBindings {
|
||||||
fun inject(activity: PinUnlockActivity)
|
fun inject(activity: PinUnlockActivity)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2024 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 io.element.android.features.lockscreen.impl.unlock.signout
|
|
||||||
|
|
||||||
import com.squareup.anvil.annotations.ContributesBinding
|
|
||||||
import io.element.android.libraries.di.AppScope
|
|
||||||
import io.element.android.libraries.matrix.api.MatrixClientProvider
|
|
||||||
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
@ContributesBinding(AppScope::class)
|
|
||||||
class DefaultSignOut @Inject constructor(
|
|
||||||
private val authenticationService: MatrixAuthenticationService,
|
|
||||||
private val matrixClientProvider: MatrixClientProvider,
|
|
||||||
) : SignOut {
|
|
||||||
override suspend fun invoke(): String? {
|
|
||||||
val currentSession = authenticationService.getLatestSessionId()
|
|
||||||
return if (currentSession != null) {
|
|
||||||
matrixClientProvider.getOrRestore(currentSession)
|
|
||||||
.getOrThrow()
|
|
||||||
.logout(ignoreSdkError = true)
|
|
||||||
} else {
|
|
||||||
error("No session to sign out")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2024 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 io.element.android.features.lockscreen.impl.unlock
|
|
||||||
|
|
||||||
import com.google.common.truth.Truth.assertThat
|
|
||||||
import io.element.android.features.lockscreen.impl.unlock.signout.DefaultSignOut
|
|
||||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
|
||||||
import io.element.android.libraries.matrix.test.FakeMatrixClientProvider
|
|
||||||
import io.element.android.libraries.matrix.test.auth.FakeMatrixAuthenticationService
|
|
||||||
import io.element.android.tests.testutils.lambda.assert
|
|
||||||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
|
||||||
import kotlinx.coroutines.test.runTest
|
|
||||||
import org.junit.Test
|
|
||||||
|
|
||||||
class DefaultSignOutTest {
|
|
||||||
private val matrixClient = FakeMatrixClient()
|
|
||||||
private val authenticationService = FakeMatrixAuthenticationService()
|
|
||||||
private val matrixClientProvider = FakeMatrixClientProvider(getClient = { Result.success(matrixClient) })
|
|
||||||
private val sut = DefaultSignOut(authenticationService, matrixClientProvider)
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `when no active session then it throws`() = runTest {
|
|
||||||
authenticationService.getLatestSessionIdLambda = { null }
|
|
||||||
val result = runCatching { sut.invoke() }
|
|
||||||
assertThat(result.isFailure).isTrue()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `with one active session and successful logout on client`() = runTest {
|
|
||||||
val logoutLambda = lambdaRecorder<Boolean, String?> { _: Boolean -> null }
|
|
||||||
authenticationService.getLatestSessionIdLambda = { matrixClient.sessionId }
|
|
||||||
matrixClient.logoutLambda = logoutLambda
|
|
||||||
val result = runCatching { sut.invoke() }
|
|
||||||
assertThat(result.isSuccess).isTrue()
|
|
||||||
assert(logoutLambda).isCalledOnce()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `with one active session and and failed logout on client`() = runTest {
|
|
||||||
val logoutLambda = lambdaRecorder<Boolean, String?> { _: Boolean -> error("Failed to logout") }
|
|
||||||
authenticationService.getLatestSessionIdLambda = { matrixClient.sessionId }
|
|
||||||
matrixClient.logoutLambda = logoutLambda
|
|
||||||
val result = runCatching { sut.invoke() }
|
|
||||||
assertThat(result.isFailure).isTrue()
|
|
||||||
assert(logoutLambda).isCalledOnce()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -28,7 +28,7 @@ import io.element.android.features.lockscreen.impl.pin.PinCodeManager
|
||||||
import io.element.android.features.lockscreen.impl.pin.model.PinEntry
|
import io.element.android.features.lockscreen.impl.pin.model.PinEntry
|
||||||
import io.element.android.features.lockscreen.impl.pin.model.assertText
|
import io.element.android.features.lockscreen.impl.pin.model.assertText
|
||||||
import io.element.android.features.lockscreen.impl.unlock.keypad.PinKeypadModel
|
import io.element.android.features.lockscreen.impl.unlock.keypad.PinKeypadModel
|
||||||
import io.element.android.features.lockscreen.impl.unlock.signout.SignOut
|
import io.element.android.features.logout.test.FakeLogoutUseCase
|
||||||
import io.element.android.libraries.architecture.AsyncData
|
import io.element.android.libraries.architecture.AsyncData
|
||||||
import io.element.android.tests.testutils.lambda.assert
|
import io.element.android.tests.testutils.lambda.assert
|
||||||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||||
|
|
@ -106,9 +106,9 @@ class PinUnlockPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - forgot pin flow`() = runTest {
|
fun `present - forgot pin flow`() = runTest {
|
||||||
val signOutLambda = lambdaRecorder<String?> { null }
|
val signOutLambda = lambdaRecorder<Boolean, String> { "" }
|
||||||
val signOut = FakeSignOut(signOutLambda)
|
val signOut = FakeLogoutUseCase(signOutLambda)
|
||||||
val presenter = createPinUnlockPresenter(this, signOut = signOut)
|
val presenter = createPinUnlockPresenter(this, logoutUseCase = signOut)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
|
|
@ -135,7 +135,7 @@ class PinUnlockPresenterTest {
|
||||||
awaitItem().also { state ->
|
awaitItem().also { state ->
|
||||||
assertThat(state.signOutAction).isInstanceOf(AsyncData.Success::class.java)
|
assertThat(state.signOutAction).isInstanceOf(AsyncData.Success::class.java)
|
||||||
}
|
}
|
||||||
assert(signOutLambda).isCalledOnce().withNoParameter()
|
assert(signOutLambda).isCalledOnce()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -147,7 +147,7 @@ class PinUnlockPresenterTest {
|
||||||
scope: CoroutineScope,
|
scope: CoroutineScope,
|
||||||
biometricUnlockManager: BiometricUnlockManager = FakeBiometricUnlockManager(),
|
biometricUnlockManager: BiometricUnlockManager = FakeBiometricUnlockManager(),
|
||||||
callback: PinCodeManager.Callback = DefaultPinCodeManagerCallback(),
|
callback: PinCodeManager.Callback = DefaultPinCodeManagerCallback(),
|
||||||
signOut: SignOut = FakeSignOut(),
|
logoutUseCase: FakeLogoutUseCase = FakeLogoutUseCase(logoutLambda = { "" }),
|
||||||
): PinUnlockPresenter {
|
): PinUnlockPresenter {
|
||||||
val pinCodeManager = aPinCodeManager().apply {
|
val pinCodeManager = aPinCodeManager().apply {
|
||||||
addCallback(callback)
|
addCallback(callback)
|
||||||
|
|
@ -156,7 +156,7 @@ class PinUnlockPresenterTest {
|
||||||
return PinUnlockPresenter(
|
return PinUnlockPresenter(
|
||||||
pinCodeManager = pinCodeManager,
|
pinCodeManager = pinCodeManager,
|
||||||
biometricUnlockManager = biometricUnlockManager,
|
biometricUnlockManager = biometricUnlockManager,
|
||||||
signOut = signOut,
|
logoutUseCase = logoutUseCase,
|
||||||
coroutineScope = scope,
|
coroutineScope = scope,
|
||||||
pinUnlockHelper = PinUnlockHelper(biometricUnlockManager, pinCodeManager),
|
pinUnlockHelper = PinUnlockHelper(biometricUnlockManager, pinCodeManager),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,11 @@ interface LogoutUseCase {
|
||||||
/**
|
/**
|
||||||
* Log out the current user and then perform any needed cleanup tasks.
|
* Log out the current user and then perform any needed cleanup tasks.
|
||||||
* @param ignoreSdkError if true, the SDK error will be ignored and the user will be logged out anyway.
|
* @param ignoreSdkError if true, the SDK error will be ignored and the user will be logged out anyway.
|
||||||
|
* @return the session id of the logged out user.
|
||||||
*/
|
*/
|
||||||
suspend fun logout(ignoreSdkError: Boolean)
|
suspend fun logout(ignoreSdkError: Boolean): String
|
||||||
|
|
||||||
|
interface Factory {
|
||||||
|
fun create(sessionId: String): LogoutUseCase
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,16 +17,27 @@
|
||||||
package io.element.android.features.logout.impl
|
package io.element.android.features.logout.impl
|
||||||
|
|
||||||
import com.squareup.anvil.annotations.ContributesBinding
|
import com.squareup.anvil.annotations.ContributesBinding
|
||||||
|
import dagger.assisted.Assisted
|
||||||
|
import dagger.assisted.AssistedFactory
|
||||||
|
import dagger.assisted.AssistedInject
|
||||||
import io.element.android.features.logout.api.LogoutUseCase
|
import io.element.android.features.logout.api.LogoutUseCase
|
||||||
import io.element.android.libraries.di.SessionScope
|
import io.element.android.libraries.di.AppScope
|
||||||
import io.element.android.libraries.matrix.api.MatrixClient
|
import io.element.android.libraries.matrix.api.MatrixClientProvider
|
||||||
import javax.inject.Inject
|
import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
|
|
||||||
@ContributesBinding(SessionScope::class)
|
class DefaultLogoutUseCase @AssistedInject constructor(
|
||||||
class DefaultLogoutUseCase @Inject constructor(
|
@Assisted private val sessionId: String,
|
||||||
private val matrixClient: MatrixClient
|
private val matrixClientProvider: MatrixClientProvider,
|
||||||
) : LogoutUseCase {
|
) : LogoutUseCase {
|
||||||
override suspend fun logout(ignoreSdkError: Boolean) {
|
@ContributesBinding(AppScope::class)
|
||||||
|
@AssistedFactory
|
||||||
|
interface Factory : LogoutUseCase.Factory {
|
||||||
|
override fun create(sessionId: String): DefaultLogoutUseCase
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun logout(ignoreSdkError: Boolean): String {
|
||||||
|
val matrixClient = matrixClientProvider.getOrRestore(SessionId(sessionId)).getOrThrow()
|
||||||
matrixClient.logout(ignoreSdkError = ignoreSdkError)
|
matrixClient.logout(ignoreSdkError = ignoreSdkError)
|
||||||
|
return sessionId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 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
|
||||||
|
*
|
||||||
|
* https://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 io.element.android.features.logout.impl
|
||||||
|
|
||||||
|
import com.squareup.anvil.annotations.ContributesTo
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import io.element.android.features.logout.api.LogoutUseCase
|
||||||
|
import io.element.android.libraries.di.SessionScope
|
||||||
|
import io.element.android.libraries.matrix.api.user.CurrentSessionIdHolder
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@ContributesTo(SessionScope::class)
|
||||||
|
object SessionLogoutModule {
|
||||||
|
@Provides
|
||||||
|
fun provideLogoutUseCase(
|
||||||
|
currentSessionIdHolder: CurrentSessionIdHolder,
|
||||||
|
factory: DefaultLogoutUseCase.Factory,
|
||||||
|
): LogoutUseCase {
|
||||||
|
return factory.create(currentSessionIdHolder.current.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
|
@ -14,8 +14,16 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.features.lockscreen.impl.unlock.signout
|
plugins {
|
||||||
|
id("io.element.android-library")
|
||||||
interface SignOut {
|
}
|
||||||
suspend operator fun invoke(): String?
|
|
||||||
|
android {
|
||||||
|
namespace = "io.element.android.features.logout.test"
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(libs.coroutines.core)
|
||||||
|
implementation(projects.tests.testutils)
|
||||||
|
api(projects.features.logout.api)
|
||||||
}
|
}
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
|
@ -14,15 +14,15 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.features.lockscreen.impl.unlock
|
package io.element.android.features.logout.test
|
||||||
|
|
||||||
import io.element.android.features.lockscreen.impl.unlock.signout.SignOut
|
import io.element.android.features.logout.api.LogoutUseCase
|
||||||
import io.element.android.tests.testutils.simulateLongTask
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
|
||||||
class FakeSignOut(
|
class FakeLogoutUseCase(
|
||||||
var lambda: () -> String? = { null }
|
var logoutLambda: (Boolean) -> String = lambdaError()
|
||||||
) : SignOut {
|
) : LogoutUseCase {
|
||||||
override suspend fun invoke(): String? = simulateLongTask {
|
override suspend fun logout(ignoreSdkError: Boolean): String {
|
||||||
lambda()
|
return logoutLambda(ignoreSdkError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -90,6 +90,7 @@ dependencies {
|
||||||
testImplementation(projects.features.ftue.test)
|
testImplementation(projects.features.ftue.test)
|
||||||
testImplementation(projects.features.rageshake.test)
|
testImplementation(projects.features.rageshake.test)
|
||||||
testImplementation(projects.features.rageshake.impl)
|
testImplementation(projects.features.rageshake.impl)
|
||||||
|
testImplementation(projects.features.logout.test)
|
||||||
testImplementation(projects.features.roomlist.test)
|
testImplementation(projects.features.roomlist.test)
|
||||||
testImplementation(projects.libraries.indicator.impl)
|
testImplementation(projects.libraries.indicator.impl)
|
||||||
testImplementation(projects.libraries.pushproviders.test)
|
testImplementation(projects.libraries.pushproviders.test)
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import app.cash.molecule.moleculeFlow
|
||||||
import app.cash.turbine.test
|
import app.cash.turbine.test
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import io.element.android.appconfig.ElementCallConfig
|
import io.element.android.appconfig.ElementCallConfig
|
||||||
import io.element.android.features.logout.api.LogoutUseCase
|
import io.element.android.features.logout.test.FakeLogoutUseCase
|
||||||
import io.element.android.features.preferences.impl.tasks.FakeClearCacheUseCase
|
import io.element.android.features.preferences.impl.tasks.FakeClearCacheUseCase
|
||||||
import io.element.android.features.preferences.impl.tasks.FakeComputeCacheSizeUseCase
|
import io.element.android.features.preferences.impl.tasks.FakeComputeCacheSizeUseCase
|
||||||
import io.element.android.features.rageshake.impl.preferences.DefaultRageshakePreferencesPresenter
|
import io.element.android.features.rageshake.impl.preferences.DefaultRageshakePreferencesPresenter
|
||||||
|
|
@ -36,6 +36,7 @@ import io.element.android.libraries.matrix.test.core.aBuildMeta
|
||||||
import io.element.android.libraries.preferences.test.InMemoryAppPreferencesStore
|
import io.element.android.libraries.preferences.test.InMemoryAppPreferencesStore
|
||||||
import io.element.android.tests.testutils.WarmUpRule
|
import io.element.android.tests.testutils.WarmUpRule
|
||||||
import io.element.android.tests.testutils.awaitLastSequentialItem
|
import io.element.android.tests.testutils.awaitLastSequentialItem
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
|
|
@ -165,7 +166,8 @@ class DeveloperSettingsPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - toggling simplified sliding sync changes the preferences and logs out the user`() = runTest {
|
fun `present - toggling simplified sliding sync changes the preferences and logs out the user`() = runTest {
|
||||||
val logoutUseCase = FakeLogoutUseCase()
|
val logoutCallRecorder = lambdaRecorder<Boolean, String> { "" }
|
||||||
|
val logoutUseCase = FakeLogoutUseCase(logoutLambda = logoutCallRecorder)
|
||||||
val preferences = InMemoryAppPreferencesStore()
|
val preferences = InMemoryAppPreferencesStore()
|
||||||
val presenter = createDeveloperSettingsPresenter(preferencesStore = preferences, logoutUseCase = logoutUseCase)
|
val presenter = createDeveloperSettingsPresenter(preferencesStore = preferences, logoutUseCase = logoutUseCase)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
|
@ -177,12 +179,12 @@ class DeveloperSettingsPresenterTest {
|
||||||
initialState.eventSink(DeveloperSettingsEvents.SetSimplifiedSlidingSyncEnabled(true))
|
initialState.eventSink(DeveloperSettingsEvents.SetSimplifiedSlidingSyncEnabled(true))
|
||||||
assertThat(awaitItem().isSimpleSlidingSyncEnabled).isTrue()
|
assertThat(awaitItem().isSimpleSlidingSyncEnabled).isTrue()
|
||||||
assertThat(preferences.isSimplifiedSlidingSyncEnabledFlow().first()).isTrue()
|
assertThat(preferences.isSimplifiedSlidingSyncEnabledFlow().first()).isTrue()
|
||||||
assertThat(logoutUseCase.logoutCallCount).isEqualTo(1)
|
logoutCallRecorder.assertions().isCalledOnce()
|
||||||
|
|
||||||
initialState.eventSink(DeveloperSettingsEvents.SetSimplifiedSlidingSyncEnabled(false))
|
initialState.eventSink(DeveloperSettingsEvents.SetSimplifiedSlidingSyncEnabled(false))
|
||||||
assertThat(awaitItem().isSimpleSlidingSyncEnabled).isFalse()
|
assertThat(awaitItem().isSimpleSlidingSyncEnabled).isFalse()
|
||||||
assertThat(preferences.isSimplifiedSlidingSyncEnabledFlow().first()).isFalse()
|
assertThat(preferences.isSimplifiedSlidingSyncEnabledFlow().first()).isFalse()
|
||||||
assertThat(logoutUseCase.logoutCallCount).isEqualTo(2)
|
logoutCallRecorder.assertions().isCalledExactly(times = 2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -193,7 +195,7 @@ class DeveloperSettingsPresenterTest {
|
||||||
rageshakePresenter: DefaultRageshakePreferencesPresenter = DefaultRageshakePreferencesPresenter(FakeRageShake(), FakeRageshakeDataStore()),
|
rageshakePresenter: DefaultRageshakePreferencesPresenter = DefaultRageshakePreferencesPresenter(FakeRageShake(), FakeRageshakeDataStore()),
|
||||||
preferencesStore: InMemoryAppPreferencesStore = InMemoryAppPreferencesStore(),
|
preferencesStore: InMemoryAppPreferencesStore = InMemoryAppPreferencesStore(),
|
||||||
buildMeta: BuildMeta = aBuildMeta(),
|
buildMeta: BuildMeta = aBuildMeta(),
|
||||||
logoutUseCase: FakeLogoutUseCase = FakeLogoutUseCase()
|
logoutUseCase: FakeLogoutUseCase = FakeLogoutUseCase(logoutLambda = { "" })
|
||||||
): DeveloperSettingsPresenter {
|
): DeveloperSettingsPresenter {
|
||||||
return DeveloperSettingsPresenter(
|
return DeveloperSettingsPresenter(
|
||||||
featureFlagService = featureFlagService,
|
featureFlagService = featureFlagService,
|
||||||
|
|
@ -206,12 +208,3 @@ class DeveloperSettingsPresenterTest {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FakeLogoutUseCase : LogoutUseCase {
|
|
||||||
var logoutCallCount = 0
|
|
||||||
private set
|
|
||||||
|
|
||||||
override suspend fun logout(ignoreSdkError: Boolean) {
|
|
||||||
logoutCallCount++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue