Adding unit tests for signout sessions use case

This commit is contained in:
Maxime NATUREL 2022-10-25 14:20:38 +02:00
parent 727c7462df
commit a968ac08c3
5 changed files with 136 additions and 15 deletions

View File

@ -28,7 +28,6 @@ class SignoutSessionsUseCase @Inject constructor(
private val activeSessionHolder: ActiveSessionHolder,
) {
// TODO add unit tests
suspend fun execute(deviceIds: List<String>, userInteractiveAuthInterceptor: UserInteractiveAuthInterceptor): Result<Unit> {
return deleteDevices(deviceIds, userInteractiveAuthInterceptor)
}

View File

@ -22,10 +22,14 @@ import com.airbnb.mvrx.test.MavericksTestRule
import im.vector.app.core.session.clientinfo.MatrixClientInfoContent
import im.vector.app.features.settings.devices.v2.details.extended.DeviceExtendedInfo
import im.vector.app.features.settings.devices.v2.list.DeviceType
import im.vector.app.features.settings.devices.v2.signout.InterceptSignoutFlowResponseUseCase
import im.vector.app.features.settings.devices.v2.signout.SignoutSessionsUseCase
import im.vector.app.features.settings.devices.v2.verification.CheckIfCurrentSessionCanBeVerifiedUseCase
import im.vector.app.features.settings.devices.v2.verification.CurrentSessionCrossSigningInfo
import im.vector.app.features.settings.devices.v2.verification.GetCurrentSessionCrossSigningInfoUseCase
import im.vector.app.test.fakes.FakeActiveSessionHolder
import im.vector.app.test.fakes.FakePendingAuthHandler
import im.vector.app.test.fakes.FakeStringProvider
import im.vector.app.test.fakes.FakeVerificationService
import im.vector.app.test.test
import im.vector.app.test.testDispatcher
@ -53,21 +57,29 @@ class DevicesViewModelTest {
val mavericksTestRule = MavericksTestRule(testDispatcher = testDispatcher)
private val fakeActiveSessionHolder = FakeActiveSessionHolder()
private val fakeStringProvider = FakeStringProvider()
private val getCurrentSessionCrossSigningInfoUseCase = mockk<GetCurrentSessionCrossSigningInfoUseCase>()
private val getDeviceFullInfoListUseCase = mockk<GetDeviceFullInfoListUseCase>()
private val refreshDevicesUseCase = mockk<RefreshDevicesUseCase>(relaxUnitFun = true)
private val refreshDevicesOnCryptoDevicesChangeUseCase = mockk<RefreshDevicesOnCryptoDevicesChangeUseCase>()
private val checkIfCurrentSessionCanBeVerifiedUseCase = mockk<CheckIfCurrentSessionCanBeVerifiedUseCase>()
private val fakeSignoutSessionsUseCase = mockk<SignoutSessionsUseCase>()
private val fakeInterceptSignoutFlowResponseUseCase = mockk<InterceptSignoutFlowResponseUseCase>()
private val fakePendingAuthHandler = FakePendingAuthHandler()
private val refreshDevicesUseCase = mockk<RefreshDevicesUseCase>(relaxUnitFun = true)
private fun createViewModel(): DevicesViewModel {
return DevicesViewModel(
DevicesViewState(),
fakeActiveSessionHolder.instance,
getCurrentSessionCrossSigningInfoUseCase,
getDeviceFullInfoListUseCase,
refreshDevicesOnCryptoDevicesChangeUseCase,
checkIfCurrentSessionCanBeVerifiedUseCase,
refreshDevicesUseCase,
initialState = DevicesViewState(),
activeSessionHolder = fakeActiveSessionHolder.instance,
stringProvider = fakeStringProvider.instance,
getCurrentSessionCrossSigningInfoUseCase = getCurrentSessionCrossSigningInfoUseCase,
getDeviceFullInfoListUseCase = getDeviceFullInfoListUseCase,
refreshDevicesOnCryptoDevicesChangeUseCase = refreshDevicesOnCryptoDevicesChangeUseCase,
checkIfCurrentSessionCanBeVerifiedUseCase = checkIfCurrentSessionCanBeVerifiedUseCase,
signoutSessionsUseCase = fakeSignoutSessionsUseCase,
interceptSignoutFlowResponseUseCase = fakeInterceptSignoutFlowResponseUseCase,
pendingAuthHandler = fakePendingAuthHandler.instance,
refreshDevicesUseCase = refreshDevicesUseCase,
)
}

View File

@ -23,7 +23,11 @@ import im.vector.app.features.settings.devices.v2.DeviceFullInfo
import im.vector.app.features.settings.devices.v2.GetDeviceFullInfoListUseCase
import im.vector.app.features.settings.devices.v2.RefreshDevicesUseCase
import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterType
import im.vector.app.features.settings.devices.v2.signout.InterceptSignoutFlowResponseUseCase
import im.vector.app.features.settings.devices.v2.signout.SignoutSessionsUseCase
import im.vector.app.test.fakes.FakeActiveSessionHolder
import im.vector.app.test.fakes.FakePendingAuthHandler
import im.vector.app.test.fakes.FakeStringProvider
import im.vector.app.test.fakes.FakeVerificationService
import im.vector.app.test.fixtures.aDeviceFullInfo
import im.vector.app.test.test
@ -54,15 +58,24 @@ class OtherSessionsViewModelTest {
)
private val fakeActiveSessionHolder = FakeActiveSessionHolder()
private val fakeStringProvider = FakeStringProvider()
private val fakeGetDeviceFullInfoListUseCase = mockk<GetDeviceFullInfoListUseCase>()
private val fakeRefreshDevicesUseCaseUseCase = mockk<RefreshDevicesUseCase>()
private val fakeSignoutSessionsUseCase = mockk<SignoutSessionsUseCase>()
private val fakeInterceptSignoutFlowResponseUseCase = mockk<InterceptSignoutFlowResponseUseCase>()
private val fakePendingAuthHandler = FakePendingAuthHandler()
private fun createViewModel(args: OtherSessionsArgs = defaultArgs) = OtherSessionsViewModel(
initialState = OtherSessionsViewState(args),
activeSessionHolder = fakeActiveSessionHolder.instance,
getDeviceFullInfoListUseCase = fakeGetDeviceFullInfoListUseCase,
refreshDevicesUseCase = fakeRefreshDevicesUseCaseUseCase,
)
private fun createViewModel(args: OtherSessionsArgs = defaultArgs) =
OtherSessionsViewModel(
initialState = OtherSessionsViewState(args),
stringProvider = fakeStringProvider.instance,
activeSessionHolder = fakeActiveSessionHolder.instance,
getDeviceFullInfoListUseCase = fakeGetDeviceFullInfoListUseCase,
signoutSessionsUseCase = fakeSignoutSessionsUseCase,
interceptSignoutFlowResponseUseCase = fakeInterceptSignoutFlowResponseUseCase,
pendingAuthHandler = fakePendingAuthHandler.instance,
refreshDevicesUseCase = fakeRefreshDevicesUseCaseUseCase,
)
@Before
fun setup() {

View File

@ -0,0 +1,83 @@
/*
* 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.settings.devices.v2.signout
import im.vector.app.test.fakes.FakeActiveSessionHolder
import io.mockk.every
import io.mockk.mockk
import kotlinx.coroutines.test.runTest
import org.amshove.kluent.shouldBe
import org.junit.Test
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
private const val A_DEVICE_ID_1 = "device-id-1"
private const val A_DEVICE_ID_2 = "device-id-2"
class SignoutSessionsUseCaseTest {
private val fakeActiveSessionHolder = FakeActiveSessionHolder()
private val signoutSessionsUseCase = SignoutSessionsUseCase(
activeSessionHolder = fakeActiveSessionHolder.instance
)
@Test
fun `given a list of device ids when signing out with success then success result is returned`() = runTest {
// Given
val interceptor = givenAuthInterceptor()
val deviceIds = listOf(A_DEVICE_ID_1, A_DEVICE_ID_2)
fakeActiveSessionHolder.fakeSession
.fakeCryptoService
.givenDeleteDevicesSucceeds(deviceIds)
// When
val result = signoutSessionsUseCase.execute(deviceIds, interceptor)
// Then
result.isSuccess shouldBe true
every {
fakeActiveSessionHolder.fakeSession
.fakeCryptoService
.deleteDevices(deviceIds, interceptor, any())
}
}
@Test
fun `given a list of device ids when signing out with error then failure result is returned`() = runTest {
// Given
val interceptor = givenAuthInterceptor()
val deviceIds = listOf(A_DEVICE_ID_1, A_DEVICE_ID_2)
val error = mockk<Exception>()
fakeActiveSessionHolder.fakeSession
.fakeCryptoService
.givenDeleteDevicesFailsWithError(deviceIds, error)
// When
val result = signoutSessionsUseCase.execute(deviceIds, interceptor)
// Then
result.isFailure shouldBe true
every {
fakeActiveSessionHolder.fakeSession
.fakeCryptoService
.deleteDevices(deviceIds, interceptor, any())
}
}
private fun givenAuthInterceptor() = mockk<UserInteractiveAuthInterceptor>()
}

View File

@ -84,5 +84,19 @@ class FakeCryptoService(
}
}
fun givenDeleteDevicesSucceeds(deviceIds: List<String>) {
val matrixCallback = slot<MatrixCallback<Unit>>()
every { deleteDevices(deviceIds, any(), capture(matrixCallback)) } answers {
thirdArg<MatrixCallback<Unit>>().onSuccess(Unit)
}
}
fun givenDeleteDevicesFailsWithError(deviceIds: List<String>, error: Exception) {
val matrixCallback = slot<MatrixCallback<Unit>>()
every { deleteDevices(deviceIds, any(), capture(matrixCallback)) } answers {
thirdArg<MatrixCallback<Unit>>().onFailure(error)
}
}
override fun getMyDevice() = cryptoDeviceInfo
}