Exposing the matrix client info into the DeviceFullInfo

This commit is contained in:
Maxime NATUREL 2022-10-05 17:02:57 +02:00
parent 93fe22d18e
commit acd05a0233
10 changed files with 113 additions and 30 deletions

View file

@ -16,6 +16,8 @@
package im.vector.app.features.settings.devices.v2
import im.vector.app.core.session.clientinfo.MatrixClientInfoContent
import im.vector.app.features.settings.devices.v2.details.extended.DeviceExtendedInfo
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
@ -27,4 +29,5 @@ data class DeviceFullInfo(
val isInactive: Boolean,
val isCurrentDevice: Boolean,
val deviceExtendedInfo: DeviceExtendedInfo,
val matrixClientInfo: MatrixClientInfoContent?,
)

View file

@ -17,6 +17,7 @@
package im.vector.app.features.settings.devices.v2
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.session.clientinfo.GetMatrixClientInfoUseCase
import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterType
import im.vector.app.features.settings.devices.v2.filter.FilterDevicesUseCase
import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase
@ -27,6 +28,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.emptyFlow
import org.matrix.android.sdk.api.session.Session
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.flow.flow
@ -39,6 +41,7 @@ class GetDeviceFullInfoListUseCase @Inject constructor(
private val getCurrentSessionCrossSigningInfoUseCase: GetCurrentSessionCrossSigningInfoUseCase,
private val filterDevicesUseCase: FilterDevicesUseCase,
private val parseDeviceUserAgentUseCase: ParseDeviceUserAgentUseCase,
private val getMatrixClientInfoUseCase: GetMatrixClientInfoUseCase,
) {
fun execute(filterType: DeviceManagerFilterType, excludeCurrentDevice: Boolean = false): Flow<List<DeviceFullInfo>> {
@ -48,7 +51,7 @@ class GetDeviceFullInfoListUseCase @Inject constructor(
session.flow().liveUserCryptoDevices(session.myUserId),
session.flow().liveMyDevicesInfo()
) { currentSessionCrossSigningInfo, cryptoList, infoList ->
val deviceFullInfoList = convertToDeviceFullInfoList(currentSessionCrossSigningInfo, cryptoList, infoList)
val deviceFullInfoList = convertToDeviceFullInfoList(session, currentSessionCrossSigningInfo, cryptoList, infoList)
val excludedDeviceIds = if (excludeCurrentDevice) {
listOf(currentSessionCrossSigningInfo.deviceId)
} else {
@ -62,6 +65,7 @@ class GetDeviceFullInfoListUseCase @Inject constructor(
}
private fun convertToDeviceFullInfoList(
session: Session,
currentSessionCrossSigningInfo: CurrentSessionCrossSigningInfo,
cryptoList: List<CryptoDeviceInfo>,
infoList: List<DeviceInfo>,
@ -73,8 +77,20 @@ class GetDeviceFullInfoListUseCase @Inject constructor(
val roomEncryptionTrustLevel = getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoDeviceInfo)
val isInactive = checkIfSessionIsInactiveUseCase.execute(deviceInfo.lastSeenTs ?: 0)
val isCurrentDevice = currentSessionCrossSigningInfo.deviceId == cryptoDeviceInfo?.deviceId
val deviceUserAgent = parseDeviceUserAgentUseCase.execute(deviceInfo.getBestLastSeenUserAgent())
DeviceFullInfo(deviceInfo, cryptoDeviceInfo, roomEncryptionTrustLevel, isInactive, isCurrentDevice, deviceUserAgent)
val deviceExtendedInfo = parseDeviceUserAgentUseCase.execute(deviceInfo.getBestLastSeenUserAgent())
val matrixClientInfo = deviceInfo.deviceId
?.takeIf { it.isNotEmpty() }
?.let { getMatrixClientInfoUseCase.execute(session, it) }
DeviceFullInfo(
deviceInfo = deviceInfo,
cryptoDeviceInfo = cryptoDeviceInfo,
roomEncryptionTrustLevel = roomEncryptionTrustLevel,
isInactive = isInactive,
isCurrentDevice = isCurrentDevice,
deviceExtendedInfo = deviceExtendedInfo,
matrixClientInfo = matrixClientInfo
)
}
}
}

View file

@ -16,6 +16,7 @@
package im.vector.app.features.settings.devices.v2
import im.vector.app.features.settings.devices.v2.details.extended.DeviceExtendedInfo
import im.vector.app.features.settings.devices.v2.list.DeviceType
import org.matrix.android.sdk.api.extensions.orFalse
import javax.inject.Inject

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package im.vector.app.features.settings.devices.v2
package im.vector.app.features.settings.devices.v2.details.extended
import im.vector.app.features.settings.devices.v2.list.DeviceType

View file

@ -18,6 +18,7 @@ package im.vector.app.features.settings.devices.v2.overview
import androidx.lifecycle.asFlow
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.session.clientinfo.GetMatrixClientInfoUseCase
import im.vector.app.features.settings.devices.v2.DeviceFullInfo
import im.vector.app.features.settings.devices.v2.ParseDeviceUserAgentUseCase
import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase
@ -36,6 +37,7 @@ class GetDeviceFullInfoUseCase @Inject constructor(
private val getEncryptionTrustLevelForDeviceUseCase: GetEncryptionTrustLevelForDeviceUseCase,
private val checkIfSessionIsInactiveUseCase: CheckIfSessionIsInactiveUseCase,
private val parseDeviceUserAgentUseCase: ParseDeviceUserAgentUseCase,
private val getMatrixClientInfoUseCase: GetMatrixClientInfoUseCase,
) {
fun execute(deviceId: String): Flow<DeviceFullInfo> {
@ -52,6 +54,10 @@ class GetDeviceFullInfoUseCase @Inject constructor(
val isInactive = checkIfSessionIsInactiveUseCase.execute(info.lastSeenTs ?: 0)
val isCurrentDevice = currentSessionCrossSigningInfo.deviceId == cryptoInfo.deviceId
val deviceUserAgent = parseDeviceUserAgentUseCase.execute(info.getBestLastSeenUserAgent())
val matrixClientInfo = info.deviceId
?.takeIf { it.isNotEmpty() }
?.let { getMatrixClientInfoUseCase.execute(session, it) }
DeviceFullInfo(
deviceInfo = info,
cryptoDeviceInfo = cryptoInfo,
@ -59,6 +65,7 @@ class GetDeviceFullInfoUseCase @Inject constructor(
isInactive = isInactive,
isCurrentDevice = isCurrentDevice,
deviceExtendedInfo = deviceUserAgent,
matrixClientInfo = matrixClientInfo
)
} else {
null

View file

@ -19,6 +19,8 @@ package im.vector.app.features.settings.devices.v2
import android.os.SystemClock
import com.airbnb.mvrx.Success
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.verification.CheckIfCurrentSessionCanBeVerifiedUseCase
import im.vector.app.features.settings.devices.v2.verification.CurrentSessionCrossSigningInfo
@ -245,7 +247,8 @@ class DevicesViewModelTest {
roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Trusted,
isInactive = false,
isCurrentDevice = true,
deviceExtendedInfo = DeviceExtendedInfo(DeviceType.MOBILE)
deviceExtendedInfo = DeviceExtendedInfo(DeviceType.MOBILE),
matrixClientInfo = MatrixClientInfoContent(),
)
val deviceFullInfo2 = DeviceFullInfo(
deviceInfo = mockk(),
@ -253,7 +256,8 @@ class DevicesViewModelTest {
roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Warning,
isInactive = true,
isCurrentDevice = false,
deviceExtendedInfo = DeviceExtendedInfo(DeviceType.MOBILE)
deviceExtendedInfo = DeviceExtendedInfo(DeviceType.MOBILE),
matrixClientInfo = MatrixClientInfoContent(),
)
val deviceFullInfoList = listOf(deviceFullInfo1, deviceFullInfo2)
val deviceFullInfoListFlow = flowOf(deviceFullInfoList)

View file

@ -16,6 +16,9 @@
package im.vector.app.features.settings.devices.v2
import im.vector.app.core.session.clientinfo.GetMatrixClientInfoUseCase
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.filter.DeviceManagerFilterType
import im.vector.app.features.settings.devices.v2.filter.FilterDevicesUseCase
import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase
@ -55,6 +58,7 @@ class GetDeviceFullInfoListUseCaseTest {
private val getCurrentSessionCrossSigningInfoUseCase = mockk<GetCurrentSessionCrossSigningInfoUseCase>()
private val filterDevicesUseCase = mockk<FilterDevicesUseCase>()
private val parseDeviceUserAgentUseCase = mockk<ParseDeviceUserAgentUseCase>()
private val getMatrixClientInfoUseCase = mockk<GetMatrixClientInfoUseCase>()
private val getDeviceFullInfoListUseCase = GetDeviceFullInfoListUseCase(
activeSessionHolder = fakeActiveSessionHolder.instance,
@ -63,6 +67,7 @@ class GetDeviceFullInfoListUseCaseTest {
getCurrentSessionCrossSigningInfoUseCase = getCurrentSessionCrossSigningInfoUseCase,
filterDevicesUseCase = filterDevicesUseCase,
parseDeviceUserAgentUseCase = parseDeviceUserAgentUseCase,
getMatrixClientInfoUseCase = getMatrixClientInfoUseCase,
)
@Before
@ -108,13 +113,17 @@ class GetDeviceFullInfoListUseCaseTest {
)
val deviceInfoList = listOf(deviceInfo1, deviceInfo2, deviceInfo3)
every { fakeFlowSession.liveMyDevicesInfo() } returns flowOf(deviceInfoList)
val matrixClientInfo1 = givenAMatrixClientInfo(A_DEVICE_ID_1)
val matrixClientInfo2 = givenAMatrixClientInfo(A_DEVICE_ID_2)
val matrixClientInfo3 = givenAMatrixClientInfo(A_DEVICE_ID_3)
val expectedResult1 = DeviceFullInfo(
deviceInfo = deviceInfo1,
cryptoDeviceInfo = cryptoDeviceInfo1,
roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Trusted,
isInactive = true,
isCurrentDevice = true,
deviceExtendedInfo = DeviceExtendedInfo(DeviceType.MOBILE)
deviceExtendedInfo = DeviceExtendedInfo(DeviceType.MOBILE),
matrixClientInfo = matrixClientInfo1,
)
val expectedResult2 = DeviceFullInfo(
deviceInfo = deviceInfo2,
@ -122,7 +131,8 @@ class GetDeviceFullInfoListUseCaseTest {
roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Trusted,
isInactive = false,
isCurrentDevice = false,
deviceExtendedInfo = DeviceExtendedInfo(DeviceType.MOBILE)
deviceExtendedInfo = DeviceExtendedInfo(DeviceType.MOBILE),
matrixClientInfo = matrixClientInfo2,
)
val expectedResult3 = DeviceFullInfo(
deviceInfo = deviceInfo3,
@ -130,7 +140,8 @@ class GetDeviceFullInfoListUseCaseTest {
roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Warning,
isInactive = false,
isCurrentDevice = false,
deviceExtendedInfo = DeviceExtendedInfo(DeviceType.MOBILE)
deviceExtendedInfo = DeviceExtendedInfo(DeviceType.MOBILE),
matrixClientInfo = matrixClientInfo3,
)
val expectedResult = listOf(expectedResult3, expectedResult2, expectedResult1)
every { filterDevicesUseCase.execute(any(), any()) } returns expectedResult
@ -152,6 +163,9 @@ class GetDeviceFullInfoListUseCaseTest {
checkIfSessionIsInactiveUseCase.execute(A_TIMESTAMP_1)
checkIfSessionIsInactiveUseCase.execute(A_TIMESTAMP_2)
checkIfSessionIsInactiveUseCase.execute(A_TIMESTAMP_3)
getMatrixClientInfoUseCase.execute(fakeActiveSessionHolder.fakeSession, A_DEVICE_ID_1)
getMatrixClientInfoUseCase.execute(fakeActiveSessionHolder.fakeSession, A_DEVICE_ID_2)
getMatrixClientInfoUseCase.execute(fakeActiveSessionHolder.fakeSession, A_DEVICE_ID_3)
}
}
@ -201,4 +215,10 @@ class GetDeviceFullInfoListUseCaseTest {
return deviceInfo
}
private fun givenAMatrixClientInfo(deviceId: String): MatrixClientInfoContent {
val matrixClientInfo = mockk<MatrixClientInfoContent>()
every { getMatrixClientInfoUseCase.execute(fakeActiveSessionHolder.fakeSession, deviceId) } returns matrixClientInfo
return matrixClientInfo
}
}

View file

@ -16,6 +16,7 @@
package im.vector.app.features.settings.devices.v2
import im.vector.app.features.settings.devices.v2.details.extended.DeviceExtendedInfo
import im.vector.app.features.settings.devices.v2.list.DeviceType
import org.amshove.kluent.shouldBeEqualTo
import org.junit.Test

View file

@ -16,7 +16,8 @@
package im.vector.app.features.settings.devices.v2.filter
import im.vector.app.features.settings.devices.v2.DeviceExtendedInfo
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.DeviceFullInfo
import im.vector.app.features.settings.devices.v2.list.DeviceType
import org.amshove.kluent.shouldBeEqualTo
@ -37,7 +38,8 @@ private val activeVerifiedDevice = DeviceFullInfo(
roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Trusted,
isInactive = false,
isCurrentDevice = true,
deviceExtendedInfo = DeviceExtendedInfo(DeviceType.MOBILE)
deviceExtendedInfo = DeviceExtendedInfo(DeviceType.MOBILE),
matrixClientInfo = MatrixClientInfoContent(),
)
private val inactiveVerifiedDevice = DeviceFullInfo(
deviceInfo = DeviceInfo(deviceId = "INACTIVE_VERIFIED_DEVICE"),
@ -49,7 +51,8 @@ private val inactiveVerifiedDevice = DeviceFullInfo(
roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Trusted,
isInactive = true,
isCurrentDevice = false,
deviceExtendedInfo = DeviceExtendedInfo(DeviceType.MOBILE)
deviceExtendedInfo = DeviceExtendedInfo(DeviceType.MOBILE),
matrixClientInfo = MatrixClientInfoContent(),
)
private val activeUnverifiedDevice = DeviceFullInfo(
deviceInfo = DeviceInfo(deviceId = "ACTIVE_UNVERIFIED_DEVICE"),
@ -61,7 +64,8 @@ private val activeUnverifiedDevice = DeviceFullInfo(
roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Warning,
isInactive = false,
isCurrentDevice = false,
deviceExtendedInfo = DeviceExtendedInfo(DeviceType.MOBILE)
deviceExtendedInfo = DeviceExtendedInfo(DeviceType.MOBILE),
matrixClientInfo = MatrixClientInfoContent(),
)
private val inactiveUnverifiedDevice = DeviceFullInfo(
deviceInfo = DeviceInfo(deviceId = "INACTIVE_UNVERIFIED_DEVICE"),
@ -73,7 +77,8 @@ private val inactiveUnverifiedDevice = DeviceFullInfo(
roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Warning,
isInactive = true,
isCurrentDevice = false,
deviceExtendedInfo = DeviceExtendedInfo(DeviceType.MOBILE)
deviceExtendedInfo = DeviceExtendedInfo(DeviceType.MOBILE),
matrixClientInfo = MatrixClientInfoContent(),
)
private val devices = listOf(

View file

@ -18,9 +18,11 @@ package im.vector.app.features.settings.devices.v2.overview
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.asFlow
import im.vector.app.features.settings.devices.v2.DeviceExtendedInfo
import im.vector.app.core.session.clientinfo.GetMatrixClientInfoUseCase
import im.vector.app.core.session.clientinfo.MatrixClientInfoContent
import im.vector.app.features.settings.devices.v2.DeviceFullInfo
import im.vector.app.features.settings.devices.v2.ParseDeviceUserAgentUseCase
import im.vector.app.features.settings.devices.v2.details.extended.DeviceExtendedInfo
import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase
import im.vector.app.features.settings.devices.v2.list.DeviceType
import im.vector.app.features.settings.devices.v2.verification.CurrentSessionCrossSigningInfo
@ -57,6 +59,7 @@ class GetDeviceFullInfoUseCaseTest {
private val checkIfSessionIsInactiveUseCase = mockk<CheckIfSessionIsInactiveUseCase>()
private val fakeFlowLiveDataConversions = FakeFlowLiveDataConversions()
private val parseDeviceUserAgentUseCase = mockk<ParseDeviceUserAgentUseCase>()
private val getMatrixClientInfoUseCase = mockk<GetMatrixClientInfoUseCase>()
private val getDeviceFullInfoUseCase = GetDeviceFullInfoUseCase(
activeSessionHolder = fakeActiveSessionHolder.instance,
@ -64,6 +67,7 @@ class GetDeviceFullInfoUseCaseTest {
getEncryptionTrustLevelForDeviceUseCase = getEncryptionTrustLevelForDeviceUseCase,
checkIfSessionIsInactiveUseCase = checkIfSessionIsInactiveUseCase,
parseDeviceUserAgentUseCase = parseDeviceUserAgentUseCase,
getMatrixClientInfoUseCase = getMatrixClientInfoUseCase,
)
@Before
@ -80,19 +84,14 @@ class GetDeviceFullInfoUseCaseTest {
fun `given current session and info for device when getting device info then the result is correct`() = runTest {
// Given
val currentSessionCrossSigningInfo = givenCurrentSessionCrossSigningInfo()
val deviceInfo = DeviceInfo(
lastSeenTs = A_TIMESTAMP,
)
fakeActiveSessionHolder.fakeSession.fakeCryptoService.myDevicesInfoWithIdLiveData = MutableLiveData(Optional(deviceInfo))
fakeActiveSessionHolder.fakeSession.fakeCryptoService.myDevicesInfoWithIdLiveData.givenAsFlow()
val cryptoDeviceInfo = CryptoDeviceInfo(deviceId = A_DEVICE_ID, userId = "")
fakeActiveSessionHolder.fakeSession.fakeCryptoService.cryptoDeviceInfoWithIdLiveData = MutableLiveData(Optional(cryptoDeviceInfo))
fakeActiveSessionHolder.fakeSession.fakeCryptoService.cryptoDeviceInfoWithIdLiveData.givenAsFlow()
val deviceInfo = givenADeviceInfo()
val cryptoDeviceInfo = givenACryptoDeviceInfo()
val trustLevel = givenTrustLevel(currentSessionCrossSigningInfo, cryptoDeviceInfo)
val isInactive = false
val isCurrentDevice = true
every { checkIfSessionIsInactiveUseCase.execute(any()) } returns isInactive
every { parseDeviceUserAgentUseCase.execute(any()) } returns DeviceExtendedInfo(DeviceType.MOBILE)
val matrixClientInfo = givenAMatrixClientInfo()
// When
val deviceFullInfo = getDeviceFullInfoUseCase.execute(A_DEVICE_ID).firstOrNull()
@ -104,14 +103,18 @@ class GetDeviceFullInfoUseCaseTest {
roomEncryptionTrustLevel = trustLevel,
isInactive = isInactive,
isCurrentDevice = isCurrentDevice,
deviceExtendedInfo = DeviceExtendedInfo(DeviceType.MOBILE)
deviceExtendedInfo = DeviceExtendedInfo(DeviceType.MOBILE),
matrixClientInfo = matrixClientInfo,
)
verify { fakeActiveSessionHolder.instance.getSafeActiveSession() }
verify { getCurrentSessionCrossSigningInfoUseCase.execute() }
verify { getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoDeviceInfo) }
verify { fakeActiveSessionHolder.fakeSession.fakeCryptoService.getMyDevicesInfoLive(A_DEVICE_ID).asFlow() }
verify { fakeActiveSessionHolder.fakeSession.fakeCryptoService.getLiveCryptoDeviceInfoWithId(A_DEVICE_ID).asFlow() }
verify { checkIfSessionIsInactiveUseCase.execute(A_TIMESTAMP) }
verify {
fakeActiveSessionHolder.instance.getSafeActiveSession()
getCurrentSessionCrossSigningInfoUseCase.execute()
getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoDeviceInfo)
fakeActiveSessionHolder.fakeSession.fakeCryptoService.getMyDevicesInfoLive(A_DEVICE_ID).asFlow()
fakeActiveSessionHolder.fakeSession.fakeCryptoService.getLiveCryptoDeviceInfoWithId(A_DEVICE_ID).asFlow()
checkIfSessionIsInactiveUseCase.execute(A_TIMESTAMP)
getMatrixClientInfoUseCase.execute(fakeActiveSessionHolder.fakeSession, A_DEVICE_ID)
}
}
@Test
@ -161,4 +164,27 @@ class GetDeviceFullInfoUseCaseTest {
every { getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoDeviceInfo) } returns trustLevel
return trustLevel
}
private fun givenADeviceInfo(): DeviceInfo {
val deviceInfo = DeviceInfo(
deviceId = A_DEVICE_ID,
lastSeenTs = A_TIMESTAMP,
)
fakeActiveSessionHolder.fakeSession.fakeCryptoService.myDevicesInfoWithIdLiveData = MutableLiveData(Optional(deviceInfo))
fakeActiveSessionHolder.fakeSession.fakeCryptoService.myDevicesInfoWithIdLiveData.givenAsFlow()
return deviceInfo
}
private fun givenACryptoDeviceInfo(): CryptoDeviceInfo {
val cryptoDeviceInfo = CryptoDeviceInfo(deviceId = A_DEVICE_ID, userId = "")
fakeActiveSessionHolder.fakeSession.fakeCryptoService.cryptoDeviceInfoWithIdLiveData = MutableLiveData(Optional(cryptoDeviceInfo))
fakeActiveSessionHolder.fakeSession.fakeCryptoService.cryptoDeviceInfoWithIdLiveData.givenAsFlow()
return cryptoDeviceInfo
}
private fun givenAMatrixClientInfo(): MatrixClientInfoContent {
val matrixClientInfo = mockk<MatrixClientInfoContent>()
every { getMatrixClientInfoUseCase.execute(fakeActiveSessionHolder.fakeSession, A_DEVICE_ID) } returns matrixClientInfo
return matrixClientInfo
}
}