GetDeviceFullInfoListUseCase unit tests

This commit is contained in:
Maxime NATUREL 2022-09-06 14:47:18 +02:00
parent 7511d21a6f
commit 6394c7efde
4 changed files with 199 additions and 15 deletions

View File

@ -27,7 +27,6 @@ import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo
import org.matrix.android.sdk.flow.flow
import javax.inject.Inject
// TODO add unit tests
class GetDeviceFullInfoListUseCase @Inject constructor(
private val activeSessionHolder: ActiveSessionHolder,
private val checkIfSessionIsInactiveUseCase: CheckIfSessionIsInactiveUseCase,
@ -58,9 +57,9 @@ class GetDeviceFullInfoListUseCase @Inject constructor(
.sortedByDescending { it.lastSeenTs }
.map { deviceInfo ->
val cryptoDeviceInfo = cryptoList.firstOrNull { it.deviceId == deviceInfo.deviceId }
val trustLevelForShield = getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoDeviceInfo)
val roomEncryptionTrustLevel = getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoDeviceInfo)
val isInactive = checkIfSessionIsInactiveUseCase.execute(deviceInfo.lastSeenTs ?: 0)
DeviceFullInfo(deviceInfo, cryptoDeviceInfo, trustLevelForShield, isInactive)
DeviceFullInfo(deviceInfo, cryptoDeviceInfo, roomEncryptionTrustLevel, isInactive)
}
}
}

View File

@ -17,6 +17,7 @@
package im.vector.app.features.settings.devices.v2
import im.vector.app.test.fakes.FakeActiveSessionHolder
import im.vector.app.test.fakes.FakeSession
import im.vector.app.test.test
import im.vector.app.test.testDispatcher
import io.mockk.every
@ -30,11 +31,8 @@ import org.junit.After
import org.junit.Before
import org.junit.Test
import org.matrix.android.sdk.api.auth.data.SessionParams
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo
import org.matrix.android.sdk.api.util.toOptional
import org.matrix.android.sdk.flow.FlowSession
import org.matrix.android.sdk.flow.flow
private const val A_DEVICE_ID = "device-id"
@ -59,7 +57,7 @@ class GetCurrentSessionCrossSigningInfoUseCaseTest {
@Test
fun `given the active session and existing cross signing info when getting these info then the result is correct`() = runTest(testDispatcher) {
val fakeSession = givenSession(A_DEVICE_ID)
val fakeFlowSession = givenFlowSession(fakeSession)
val fakeFlowSession = fakeSession.givenFlowSession()
val isCrossSigningVerified = true
val mxCrossSigningInfo = givenMxCrossSigningInfo(isCrossSigningVerified)
every { fakeFlowSession.liveCrossSigningInfo(any()) } returns flowOf(mxCrossSigningInfo.toOptional())
@ -80,7 +78,7 @@ class GetCurrentSessionCrossSigningInfoUseCaseTest {
@Test
fun `given the active session and no existing cross signing info when getting these info then the result is correct`() = runTest(testDispatcher) {
val fakeSession = givenSession(A_DEVICE_ID)
val fakeFlowSession = givenFlowSession(fakeSession)
val fakeFlowSession = fakeSession.givenFlowSession()
val mxCrossSigningInfo = null
every { fakeFlowSession.liveCrossSigningInfo(any()) } returns flowOf(mxCrossSigningInfo.toOptional())
val expectedResult = CurrentSessionCrossSigningInfo(
@ -108,7 +106,7 @@ class GetCurrentSessionCrossSigningInfoUseCaseTest {
.finish()
}
private fun givenSession(deviceId: String): Session {
private fun givenSession(deviceId: String): FakeSession {
val sessionParams = mockk<SessionParams>()
every { sessionParams.deviceId } returns deviceId
@ -118,12 +116,6 @@ class GetCurrentSessionCrossSigningInfoUseCaseTest {
return fakeSession
}
private fun givenFlowSession(session: Session): FlowSession {
val fakeFlowSession = mockk<FlowSession>()
every { session.flow() } returns fakeFlowSession
return fakeFlowSession
}
private fun givenMxCrossSigningInfo(isTrusted: Boolean) = mockk<MXCrossSigningInfo>()
.also {
every { it.isTrusted() } returns isTrusted

View File

@ -0,0 +1,182 @@
/*
* 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
import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase
import im.vector.app.test.fakes.FakeActiveSessionHolder
import im.vector.app.test.test
import im.vector.app.test.testDispatcher
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkStatic
import io.mockk.unmockkAll
import io.mockk.verify
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.runTest
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo
import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo
import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
private const val A_DEVICE_ID_1 = "device-id-1"
private const val A_DEVICE_ID_2 = "device-id-2"
private const val A_DEVICE_ID_3 = "device-id-3"
private const val A_TIMESTAMP_1 = 100L
private const val A_TIMESTAMP_2 = 200L
private const val A_TIMESTAMP_3 = 300L
class GetDeviceFullInfoListUseCaseTest {
private val fakeActiveSessionHolder = FakeActiveSessionHolder()
private val checkIfSessionIsInactiveUseCase = mockk<CheckIfSessionIsInactiveUseCase>()
private val getEncryptionTrustLevelForDeviceUseCase = mockk<GetEncryptionTrustLevelForDeviceUseCase>()
private val getCurrentSessionCrossSigningInfoUseCase = mockk<GetCurrentSessionCrossSigningInfoUseCase>()
private val getDeviceFullInfoListUseCase = GetDeviceFullInfoListUseCase(
activeSessionHolder = fakeActiveSessionHolder.instance,
checkIfSessionIsInactiveUseCase = checkIfSessionIsInactiveUseCase,
getEncryptionTrustLevelForDeviceUseCase = getEncryptionTrustLevelForDeviceUseCase,
getCurrentSessionCrossSigningInfoUseCase = getCurrentSessionCrossSigningInfoUseCase,
)
@Before
fun setUp() {
mockkStatic("org.matrix.android.sdk.flow.FlowSessionKt")
}
@After
fun tearDown() {
unmockkAll()
}
@Test
fun `given active session when getting list of device full info then the result list is correct and sorted in descending order`() = runTest(testDispatcher) {
// Given
val currentSessionCrossSigningInfo = givenCurrentSessionCrossSigningInfo()
val fakeFlowSession = fakeActiveSessionHolder.fakeSession.givenFlowSession()
val cryptoDeviceInfo1 = givenACryptoDeviceInfo(A_DEVICE_ID_1)
val cryptoDeviceInfo2 = givenACryptoDeviceInfo(A_DEVICE_ID_2)
val cryptoDeviceInfo3 = givenACryptoDeviceInfo(A_DEVICE_ID_3)
val cryptoDeviceInfoList = listOf(cryptoDeviceInfo1, cryptoDeviceInfo2, cryptoDeviceInfo3)
every { fakeFlowSession.liveUserCryptoDevices(any()) } returns flowOf(cryptoDeviceInfoList)
val deviceInfo1 = givenADevicesInfo(
deviceId = A_DEVICE_ID_1,
lastSeenTs = A_TIMESTAMP_1,
isInactive = true,
roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Trusted,
cryptoDeviceInfo = cryptoDeviceInfo1
)
val deviceInfo2 = givenADevicesInfo(
deviceId = A_DEVICE_ID_2,
lastSeenTs = A_TIMESTAMP_2,
isInactive = false,
roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Trusted,
cryptoDeviceInfo = cryptoDeviceInfo2
)
val deviceInfo3 = givenADevicesInfo(
deviceId = A_DEVICE_ID_3,
lastSeenTs = A_TIMESTAMP_3,
isInactive = false,
roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Warning,
cryptoDeviceInfo = cryptoDeviceInfo3
)
val deviceInfoList = listOf(deviceInfo1, deviceInfo2, deviceInfo3)
every { fakeFlowSession.liveMyDevicesInfo() } returns flowOf(deviceInfoList)
val expectedResult1 = DeviceFullInfo(
deviceInfo = deviceInfo1,
cryptoDeviceInfo = cryptoDeviceInfo1,
roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Trusted,
isInactive = true
)
val expectedResult2 = DeviceFullInfo(
deviceInfo = deviceInfo2,
cryptoDeviceInfo = cryptoDeviceInfo2,
roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Trusted,
isInactive = false
)
val expectedResult3 = DeviceFullInfo(
deviceInfo = deviceInfo3,
cryptoDeviceInfo = cryptoDeviceInfo3,
roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Warning,
isInactive = false
)
val expectedResult = listOf(expectedResult3, expectedResult2, expectedResult1)
// When
val result = getDeviceFullInfoListUseCase.execute()
.test(this)
// Then
result.assertValues(expectedResult)
.finish()
verify {
getCurrentSessionCrossSigningInfoUseCase.execute()
fakeFlowSession.liveUserCryptoDevices(fakeActiveSessionHolder.fakeSession.myUserId)
fakeFlowSession.liveMyDevicesInfo()
getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoDeviceInfo1)
getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoDeviceInfo2)
getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoDeviceInfo3)
checkIfSessionIsInactiveUseCase.execute(A_TIMESTAMP_1)
checkIfSessionIsInactiveUseCase.execute(A_TIMESTAMP_2)
checkIfSessionIsInactiveUseCase.execute(A_TIMESTAMP_3)
}
}
@Test
fun `given no active session when getting list then the result is empty`() = runTest(testDispatcher) {
// Given
fakeActiveSessionHolder.givenGetSafeActiveSessionReturns(null)
// When
val result = getDeviceFullInfoListUseCase.execute()
.test(this)
// Then
result.assertNoValues()
.finish()
}
private fun givenCurrentSessionCrossSigningInfo(): CurrentSessionCrossSigningInfo {
val currentSessionCrossSigningInfo = mockk<CurrentSessionCrossSigningInfo>()
every { getCurrentSessionCrossSigningInfoUseCase.execute() } returns flowOf(currentSessionCrossSigningInfo)
return currentSessionCrossSigningInfo
}
private fun givenACryptoDeviceInfo(deviceId: String): CryptoDeviceInfo {
val cryptoDeviceInfo = mockk<CryptoDeviceInfo>()
every { cryptoDeviceInfo.deviceId } returns deviceId
return cryptoDeviceInfo
}
private fun givenADevicesInfo(
deviceId: String,
lastSeenTs: Long,
isInactive: Boolean,
roomEncryptionTrustLevel: RoomEncryptionTrustLevel,
cryptoDeviceInfo: CryptoDeviceInfo,
): DeviceInfo {
val deviceInfo = mockk<DeviceInfo>()
every { deviceInfo.deviceId } returns deviceId
every { deviceInfo.lastSeenTs } returns lastSeenTs
every { getEncryptionTrustLevelForDeviceUseCase.execute(any(), cryptoDeviceInfo) } returns roomEncryptionTrustLevel
every { checkIfSessionIsInactiveUseCase.execute(lastSeenTs) } returns isInactive
return deviceInfo
}
}

View File

@ -32,6 +32,8 @@ import org.matrix.android.sdk.api.session.getRoomSummary
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService
import org.matrix.android.sdk.api.session.profile.ProfileService
import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.flow.FlowSession
import org.matrix.android.sdk.flow.flow
class FakeSession(
val fakeCryptoService: FakeCryptoService = FakeCryptoService(),
@ -76,6 +78,15 @@ class FakeSession(
every { this@FakeSession.sessionParams } returns sessionParams
}
/**
* Do not forget to call mockkStatic("org.matrix.android.sdk.flow.FlowSessionKt") in the setup method of the tests.
*/
fun givenFlowSession(): FlowSession {
val fakeFlowSession = mockk<FlowSession>()
every { flow() } returns fakeFlowSession
return fakeFlowSession
}
companion object {
fun withRoomSummary(roomSummary: RoomSummary) = FakeSession().apply {