Merge branch 'develop' into separate_import_error

This commit is contained in:
Benoit Marty 2025-10-07 17:23:19 +02:00 committed by GitHub
commit 700ea331fe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
679 changed files with 12323 additions and 1753 deletions

View file

@ -23,13 +23,8 @@ import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters
import io.element.android.libraries.matrix.api.createroom.RoomPreset
import io.element.android.libraries.matrix.api.encryption.EncryptionService
import io.element.android.libraries.matrix.api.media.MatrixMediaLoader
import io.element.android.libraries.matrix.api.media.MediaPreviewService
import io.element.android.libraries.matrix.api.notification.NotificationService
import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService
import io.element.android.libraries.matrix.api.oidc.AccountManagementAction
import io.element.android.libraries.matrix.api.pusher.PushersService
import io.element.android.libraries.matrix.api.room.BaseRoom
import io.element.android.libraries.matrix.api.room.CurrentUserMembership
import io.element.android.libraries.matrix.api.room.JoinedRoom
@ -39,16 +34,13 @@ import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias
import io.element.android.libraries.matrix.api.room.join.JoinRule
import io.element.android.libraries.matrix.api.roomdirectory.RoomDirectoryService
import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility
import io.element.android.libraries.matrix.api.roomlist.RoomListService
import io.element.android.libraries.matrix.api.spaces.SpaceService
import io.element.android.libraries.matrix.api.sync.SlidingSyncVersion
import io.element.android.libraries.matrix.api.sync.SyncService
import io.element.android.libraries.matrix.api.sync.SyncState
import io.element.android.libraries.matrix.api.user.MatrixSearchUserResults
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
import io.element.android.libraries.matrix.impl.encryption.RustEncryptionService
import io.element.android.libraries.matrix.impl.exception.mapClientException
import io.element.android.libraries.matrix.impl.mapper.map
@ -128,11 +120,10 @@ import org.matrix.rustcomponents.sdk.SyncService as ClientSyncService
class RustMatrixClient(
private val innerClient: Client,
private val baseDirectory: File,
private val sessionStore: SessionStore,
private val appCoroutineScope: CoroutineScope,
private val sessionDelegate: RustClientSessionDelegate,
private val innerSyncService: ClientSyncService,
appCoroutineScope: CoroutineScope,
dispatchers: CoroutineDispatchers,
baseCacheDirectory: File,
clock: SystemClock,
@ -147,27 +138,29 @@ class RustMatrixClient(
private val innerRoomListService = innerSyncService.roomListService()
private val innerSpaceService = innerClient.spaceService()
private val rustSyncService = RustSyncService(
override val roomMembershipObserver = RoomMembershipObserver()
override val syncService = RustSyncService(
inner = innerSyncService,
dispatcher = sessionDispatcher,
sessionCoroutineScope = sessionCoroutineScope
)
private val pushersService = RustPushersService(
override val pushersService = RustPushersService(
client = innerClient,
dispatchers = dispatchers,
)
private val notificationProcessSetup = NotificationProcessSetup.SingleProcess(innerSyncService)
private val innerNotificationClient = runBlocking { innerClient.notificationClient(notificationProcessSetup) }
private val notificationService = RustNotificationService(sessionId, innerNotificationClient, dispatchers, clock)
private val notificationSettingsService = RustNotificationSettingsService(innerClient, sessionCoroutineScope, dispatchers)
private val encryptionService = RustEncryptionService(
override val notificationService = RustNotificationService(sessionId, innerNotificationClient, dispatchers, clock)
override val notificationSettingsService = RustNotificationSettingsService(innerClient, sessionCoroutineScope, dispatchers)
override val encryptionService = RustEncryptionService(
client = innerClient,
syncService = rustSyncService,
syncService = syncService,
sessionCoroutineScope = sessionCoroutineScope,
dispatchers = dispatchers,
)
private val roomDirectoryService = RustRoomDirectoryService(
override val roomDirectoryService = RustRoomDirectoryService(
client = innerClient,
sessionDispatcher = sessionDispatcher,
)
@ -189,18 +182,19 @@ class RustMatrixClient(
override val spaceService: SpaceService = RustSpaceService(
innerSpaceService = innerSpaceService,
roomMembershipObserver = roomMembershipObserver,
sessionCoroutineScope = sessionCoroutineScope,
sessionDispatcher = sessionDispatcher,
)
private val verificationService = RustSessionVerificationService(
override val sessionVerificationService = RustSessionVerificationService(
client = innerClient,
isSyncServiceReady = rustSyncService.syncState.map { it == SyncState.Running },
isSyncServiceReady = syncService.syncState.map { it == SyncState.Running },
sessionCoroutineScope = sessionCoroutineScope,
)
private val roomInfoMapper = RoomInfoMapper()
private val roomMembershipObserver = RoomMembershipObserver()
private val roomFactory = RustRoomFactory(
roomListService = roomListService,
innerRoomListService = innerRoomListService,
@ -218,13 +212,13 @@ class RustMatrixClient(
featureFlagService = featureFlagService,
)
override val mediaLoader: MatrixMediaLoader = RustMediaLoader(
override val matrixMediaLoader: MatrixMediaLoader = RustMediaLoader(
baseCacheDirectory = baseCacheDirectory,
dispatchers = dispatchers,
innerClient = innerClient,
)
private val mediaPreviewService = RustMediaPreviewService(
override val mediaPreviewService = RustMediaPreviewService(
sessionCoroutineScope = sessionCoroutineScope,
innerClient = innerClient,
sessionDispatcher = sessionDispatcher,
@ -535,33 +529,17 @@ class RustMatrixClient(
}.mapFailure { it.mapClientException() }
}
override fun syncService(): SyncService = rustSyncService
override fun sessionVerificationService(): SessionVerificationService = verificationService
override fun pushersService(): PushersService = pushersService
override fun notificationService(): NotificationService = notificationService
override fun encryptionService(): EncryptionService = encryptionService
override fun notificationSettingsService(): NotificationSettingsService = notificationSettingsService
override fun roomDirectoryService(): RoomDirectoryService = roomDirectoryService
override fun mediaPreviewService(): MediaPreviewService = mediaPreviewService
internal suspend fun destroy() {
innerNotificationClient.close()
roomFactory.destroy()
rustSyncService.destroy()
syncService.destroy()
notificationSettingsService.destroy()
notificationProcessSetup.destroy()
sessionCoroutineScope.cancel()
clientDelegateTaskHandle?.cancelAndDestroy()
verificationService.destroy()
sessionVerificationService.destroy()
sessionDelegate.clearCurrentClient()
innerRoomListService.close()
@ -572,7 +550,7 @@ class RustMatrixClient(
}
override suspend fun getCacheSize(): Long {
return baseDirectory.getCacheSize()
return getCacheSize(includeCryptoDb = false)
}
override suspend fun clearCache() {
@ -671,8 +649,6 @@ class RustMatrixClient(
}
}
override fun roomMembershipObserver(): RoomMembershipObserver = roomMembershipObserver
override fun getRoomInfoFlow(roomId: RoomId): Flow<Optional<RoomInfo>> {
return mxCallbackFlow {
val roomNotFound = innerRoomListService.roomOrNull(roomId.value).use { it == null }
@ -737,7 +713,7 @@ class RustMatrixClient(
}
}
private suspend fun File.getCacheSize(
private suspend fun getCacheSize(
includeCryptoDb: Boolean = false,
): Long = withContext(sessionDispatcher) {
val sessionDirectory = sessionPathsProvider.provides(sessionId) ?: return@withContext 0L

View file

@ -9,7 +9,6 @@ package io.element.android.libraries.matrix.impl
import dev.zacsweers.metro.Inject
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.di.BaseDirectory
import io.element.android.libraries.di.CacheDirectory
import io.element.android.libraries.di.annotations.AppCoroutineScope
import io.element.android.libraries.featureflag.api.FeatureFlagService
@ -43,7 +42,6 @@ import java.io.File
@Inject
class RustMatrixClientFactory(
@BaseDirectory private val baseDirectory: File,
@CacheDirectory private val cacheDirectory: File,
@AppCoroutineScope
private val appCoroutineScope: CoroutineScope,
@ -87,7 +85,6 @@ class RustMatrixClientFactory(
return RustMatrixClient(
innerClient = client,
baseDirectory = baseDirectory,
sessionStore = sessionStore,
appCoroutineScope = appCoroutineScope,
sessionDelegate = sessionDelegate,
@ -136,13 +133,15 @@ class RustMatrixClientFactory(
)
.enableShareHistoryOnInvite(featureFlagService.isFeatureEnabled(FeatureFlags.EnableKeyShareOnInvite))
.threadsEnabled(featureFlagService.isFeatureEnabled(FeatureFlags.Threads), threadSubscriptions = false)
.requestConfig(RequestConfig(
timeout = 30_000uL,
retryLimit = 0u,
// Use default values for the rest
maxConcurrentRequests = null,
maxRetryTime = null,
))
.requestConfig(
RequestConfig(
timeout = 30_000uL,
retryLimit = 0u,
// Use default values for the rest
maxConcurrentRequests = null,
maxRetryTime = null,
)
)
.run {
// Apply sliding sync version settings
when (slidingSyncType) {

View file

@ -21,6 +21,7 @@ import io.element.android.libraries.matrix.api.notificationsettings.Notification
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
import io.element.android.libraries.matrix.api.roomdirectory.RoomDirectoryService
import io.element.android.libraries.matrix.api.roomlist.RoomListService
import io.element.android.libraries.matrix.api.spaces.SpaceService
import io.element.android.libraries.matrix.api.sync.SyncService
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
import kotlinx.coroutines.CoroutineScope
@ -35,17 +36,17 @@ object SessionMatrixModule {
@Provides
fun providesSessionVerificationService(matrixClient: MatrixClient): SessionVerificationService {
return matrixClient.sessionVerificationService()
return matrixClient.sessionVerificationService
}
@Provides
fun providesNotificationSettingsService(matrixClient: MatrixClient): NotificationSettingsService {
return matrixClient.notificationSettingsService()
return matrixClient.notificationSettingsService
}
@Provides
fun provideRoomMembershipObserver(matrixClient: MatrixClient): RoomMembershipObserver {
return matrixClient.roomMembershipObserver()
return matrixClient.roomMembershipObserver
}
@Provides
@ -55,32 +56,37 @@ object SessionMatrixModule {
@Provides
fun providesSyncService(matrixClient: MatrixClient): SyncService {
return matrixClient.syncService()
return matrixClient.syncService
}
@Provides
fun providesEncryptionService(matrixClient: MatrixClient): EncryptionService {
return matrixClient.encryptionService()
return matrixClient.encryptionService
}
@Provides
fun provideMediaLoader(matrixClient: MatrixClient): MatrixMediaLoader {
return matrixClient.mediaLoader
fun providesMatrixMediaLoader(matrixClient: MatrixClient): MatrixMediaLoader {
return matrixClient.matrixMediaLoader
}
@SessionCoroutineScope
@Provides
fun provideSessionCoroutineScope(matrixClient: MatrixClient): CoroutineScope {
fun providesSessionCoroutineScope(matrixClient: MatrixClient): CoroutineScope {
return matrixClient.sessionCoroutineScope
}
@Provides
fun providesRoomDirectoryService(matrixClient: MatrixClient): RoomDirectoryService {
return matrixClient.roomDirectoryService()
return matrixClient.roomDirectoryService
}
@Provides
fun providesMediaPreviewService(matrixClient: MatrixClient): MediaPreviewService {
return matrixClient.mediaPreviewService()
return matrixClient.mediaPreviewService
}
@Provides
fun providesSpaceService(matrixClient: MatrixClient): SpaceService {
return matrixClient.spaceService
}
}

View file

@ -23,6 +23,9 @@ fun Throwable.mapRecoveryException(): RecoveryException {
message = errorMessage
)
is RustRecoveryException.BackupExistsOnServer -> RecoveryException.BackupExistsOnServer
is RustRecoveryException.Import -> RecoveryException.Import(
message = errorMessage
)
is RustRecoveryException.Client -> RecoveryException.Client(
source.mapClientException()
)

View file

@ -21,6 +21,7 @@ import io.element.android.libraries.matrix.api.encryption.IdentityResetHandle
import io.element.android.libraries.matrix.api.encryption.RecoveryState
import io.element.android.libraries.matrix.api.encryption.identity.IdentityState
import io.element.android.libraries.matrix.api.sync.SyncState
import io.element.android.libraries.matrix.impl.exception.mapClientException
import io.element.android.libraries.matrix.impl.sync.RustSyncService
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
@ -46,7 +47,7 @@ import org.matrix.rustcomponents.sdk.EnableRecoveryProgress as RustEnableRecover
import org.matrix.rustcomponents.sdk.SteadyStateException as RustSteadyStateException
import org.matrix.rustcomponents.sdk.RecoveryException as RustRecoveryException
internal class RustEncryptionService(
class RustEncryptionService(
client: Client,
syncService: RustSyncService,
sessionCoroutineScope: CoroutineScope,
@ -97,6 +98,20 @@ internal class RustEncryptionService(
}
.stateIn(sessionCoroutineScope, SharingStarted.Eagerly, false)
/**
* Check if the user has any devices available to verify against every 5 seconds.
* TODO This is a temporary workaround, when we will have a way to observe
* the sessions, this code will have to be updated.
*/
override val hasDevicesToVerifyAgainst: StateFlow<Boolean> = flow {
while (currentCoroutineContext().isActive) {
val result = hasDevicesToVerifyAgainst().getOrDefault(false)
emit(result)
delay(5_000)
}
}
.stateIn(sessionCoroutineScope, SharingStarted.Eagerly, false)
override suspend fun enableBackups(): Result<Unit> = withContext(dispatchers.io) {
runCatchingExceptions {
service.enableBackups()
@ -172,6 +187,14 @@ internal class RustEncryptionService(
}
}
private suspend fun hasDevicesToVerifyAgainst(): Result<Boolean> = withContext(dispatchers.io) {
runCatchingExceptions {
service.hasDevicesToVerifyAgainst()
}.mapFailure {
it.mapClientException()
}
}
override suspend fun resetRecoveryKey(): Result<String> = withContext(dispatchers.io) {
runCatchingExceptions {
service.resetRecoveryKey()

View file

@ -29,7 +29,6 @@ import org.matrix.rustcomponents.sdk.RoomList as InnerRoomList
private val ROOM_LIST_RUST_FILTERS = listOf(
RoomListEntriesDynamicFilterKind.NonLeft,
RoomListEntriesDynamicFilterKind.NonSpace,
RoomListEntriesDynamicFilterKind.DeduplicateVersions
)

View file

@ -15,41 +15,57 @@ import io.element.android.libraries.matrix.api.roomlist.RoomSummary
val RoomListFilter.predicate
get() = when (this) {
is RoomListFilter.All -> { _: RoomSummary -> true }
is RoomListFilter.Any -> { _: RoomSummary -> true }
RoomListFilter.None -> { _: RoomSummary -> false }
is RoomListFilter.All -> { roomSummary -> NonSpacePredicate(roomSummary) || IsInvitedPredicate(roomSummary) }
is RoomListFilter.Any -> { roomSummary -> NonSpacePredicate(roomSummary) || IsInvitedPredicate(roomSummary) }
RoomListFilter.None -> { _ -> false }
RoomListFilter.Category.Group -> { roomSummary: RoomSummary ->
!roomSummary.info.isDm && !roomSummary.isInvited()
!roomSummary.info.isDm && NonInvitedPredicate(roomSummary) && NonSpacePredicate(roomSummary)
}
RoomListFilter.Category.People -> { roomSummary: RoomSummary ->
roomSummary.info.isDm && !roomSummary.isInvited()
roomSummary.info.isDm && NonInvitedPredicate(roomSummary) && NonSpacePredicate(roomSummary)
}
RoomListFilter.Category.Space -> IsSpacePredicate
RoomListFilter.Favorite -> { roomSummary: RoomSummary ->
roomSummary.info.isFavorite && !roomSummary.isInvited()
roomSummary.info.isFavorite && NonInvitedPredicate(roomSummary) && NonSpacePredicate(roomSummary)
}
RoomListFilter.Unread -> { roomSummary: RoomSummary ->
!roomSummary.isInvited() && (roomSummary.info.numUnreadNotifications > 0 || roomSummary.info.isMarkedUnread)
NonInvitedPredicate(roomSummary) &&
NonSpacePredicate(roomSummary) &&
(roomSummary.info.numUnreadNotifications > 0 || roomSummary.info.isMarkedUnread)
}
is RoomListFilter.NormalizedMatchRoomName -> { roomSummary: RoomSummary ->
roomSummary.info.name?.withoutAccents().orEmpty().contains(normalizedPattern, ignoreCase = true)
}
RoomListFilter.Invite -> { roomSummary: RoomSummary ->
roomSummary.isInvited()
roomSummary.info.name?.withoutAccents().orEmpty().contains(normalizedPattern, ignoreCase = true) &&
(NonSpacePredicate(roomSummary) || IsInvitedPredicate(roomSummary))
}
RoomListFilter.Invite -> IsInvitedPredicate
}
fun List<RoomSummary>.filter(filter: RoomListFilter): List<RoomSummary> {
return when (filter) {
is RoomListFilter.All -> {
val predicates = filter.filters.map { it.predicate }
val predicates = if (filter.filters.isNotEmpty()) {
filter.filters.map { it.predicate }
} else {
listOf(filter.predicate)
}
filter { roomSummary -> predicates.all { it(roomSummary) } }
}
is RoomListFilter.Any -> {
val predicates = filter.filters.map { it.predicate }
val predicates = if (filter.filters.isNotEmpty()) {
filter.filters.map { it.predicate }
} else {
listOf(filter.predicate)
}
filter { roomSummary -> predicates.any { it(roomSummary) } }
}
else -> filter(filter.predicate)
}
}
private fun RoomSummary.isInvited() = info.currentUserMembership == CurrentUserMembership.INVITED
private val IsSpacePredicate = { roomSummary: RoomSummary -> roomSummary.info.isSpace }
private val NonSpacePredicate = { roomSummary: RoomSummary -> !IsSpacePredicate(roomSummary) }
private val IsInvitedPredicate = { roomSummary: RoomSummary -> roomSummary.info.currentUserMembership == CurrentUserMembership.INVITED }
private val NonInvitedPredicate = { roomSummary: RoomSummary -> !IsInvitedPredicate(roomSummary) }

View file

@ -0,0 +1,68 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.matrix.impl.spaces
import io.element.android.libraries.core.extensions.runCatchingExceptions
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.room.CurrentUserMembership
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
import io.element.android.libraries.matrix.api.spaces.LeaveSpaceHandle
import io.element.android.libraries.matrix.api.spaces.LeaveSpaceRoom
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.launch
import timber.log.Timber
import org.matrix.rustcomponents.sdk.LeaveSpaceHandle as RustLeaveSpaceHandle
class RustLeaveSpaceHandle(
override val id: RoomId,
private val spaceRoomMapper: SpaceRoomMapper,
private val roomMembershipObserver: RoomMembershipObserver,
sessionCoroutineScope: CoroutineScope,
private val innerProvider: suspend () -> RustLeaveSpaceHandle,
) : LeaveSpaceHandle {
private val inner = CompletableDeferred<RustLeaveSpaceHandle>()
init {
sessionCoroutineScope.launch {
inner.complete(innerProvider())
}
}
override suspend fun rooms(): Result<List<LeaveSpaceRoom>> = runCatchingExceptions {
inner.await().rooms().map { leaveSpaceRoom ->
LeaveSpaceRoom(
spaceRoom = spaceRoomMapper.map(leaveSpaceRoom.spaceRoom),
isLastAdmin = leaveSpaceRoom.isLastAdmin,
)
}
}
override suspend fun leave(roomIds: List<RoomId>): Result<Unit> = runCatchingExceptions {
// Ensure the space is included and is the last room to be left
val roomToLeave = roomIds - id + id
inner.await().leave(roomToLeave.map { it.value })
}.onSuccess {
roomMembershipObserver.notifyUserLeftRoom(
roomId = id,
isSpace = true,
membershipBeforeLeft = CurrentUserMembership.JOINED,
)
}
@OptIn(ExperimentalCoroutinesApi::class)
override fun close() {
Timber.d("Destroying LeaveSpaceHandle $id")
try {
inner.getCompleted().destroy()
} catch (_: Exception) {
// Ignore, we just want to make sure it's completed
}
}
}

View file

@ -10,6 +10,8 @@ package io.element.android.libraries.matrix.impl.spaces
import io.element.android.libraries.core.coroutine.childScope
import io.element.android.libraries.core.extensions.runCatchingExceptions
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
import io.element.android.libraries.matrix.api.spaces.LeaveSpaceHandle
import io.element.android.libraries.matrix.api.spaces.SpaceRoom
import io.element.android.libraries.matrix.api.spaces.SpaceRoomList
import io.element.android.libraries.matrix.api.spaces.SpaceService
@ -37,6 +39,7 @@ class RustSpaceService(
private val innerSpaceService: ClientSpaceService,
private val sessionCoroutineScope: CoroutineScope,
private val sessionDispatcher: CoroutineDispatcher,
private val roomMembershipObserver: RoomMembershipObserver,
) : SpaceService {
private val spaceRoomMapper = SpaceRoomMapper()
override val spaceRoomsFlow = MutableSharedFlow<List<SpaceRoom>>(replay = 1, extraBufferCapacity = 1)
@ -64,6 +67,17 @@ class RustSpaceService(
)
}
override fun getLeaveSpaceHandle(spaceId: RoomId): LeaveSpaceHandle {
return RustLeaveSpaceHandle(
id = spaceId,
spaceRoomMapper = spaceRoomMapper,
roomMembershipObserver = roomMembershipObserver,
sessionCoroutineScope = sessionCoroutineScope,
) {
innerSpaceService.leaveSpace(spaceId.value)
}
}
init {
innerSpaceService
.spaceListUpdate()

View file

@ -24,7 +24,7 @@ class SpaceRoomMapper {
guestCanJoin = spaceRoom.guestCanJoin,
heroes = spaceRoom.heroes.orEmpty().map { it.map() },
joinRule = spaceRoom.joinRule?.map(),
name = spaceRoom.name,
rawName = spaceRoom.name,
numJoinedMembers = spaceRoom.numJoinedMembers.toInt(),
roomId = RoomId(spaceRoom.roomId),
roomType = spaceRoom.roomType.map(),
@ -32,6 +32,7 @@ class SpaceRoomMapper {
topic = spaceRoom.topic,
worldReadable = spaceRoom.worldReadable.orFalse(),
via = spaceRoom.via,
isDirect = spaceRoom.isDirect,
)
}
}

View file

@ -36,14 +36,12 @@ class RustMatrixClientFactoryTest {
}
fun TestScope.createRustMatrixClientFactory(
baseDirectory: File = File("/base"),
cacheDirectory: File = File("/cache"),
sessionStore: SessionStore = InMemorySessionStore(
updateUserProfileResult = { _, _, _ -> },
),
clientBuilderProvider: ClientBuilderProvider = FakeClientBuilderProvider(),
) = RustMatrixClientFactory(
baseDirectory = baseDirectory,
cacheDirectory = cacheDirectory,
appCoroutineScope = backgroundScope,
coroutineDispatchers = testCoroutineDispatchers(),

View file

@ -102,7 +102,6 @@ class RustMatrixClientTest {
),
) = RustMatrixClient(
innerClient = client,
baseDirectory = File(""),
sessionStore = sessionStore,
appCoroutineScope = backgroundScope,
sessionDelegate = aRustClientSessionDelegate(

View file

@ -53,7 +53,6 @@ class RustMatrixAuthenticationServiceTest {
val baseDirectory = File("/base")
val cacheDirectory = File("/cache")
val rustMatrixClientFactory = createRustMatrixClientFactory(
baseDirectory = baseDirectory,
cacheDirectory = cacheDirectory,
sessionStore = sessionStore,
clientBuilderProvider = clientBuilderProvider,

View file

@ -32,6 +32,10 @@ class FakeFfiEncryption : Encryption(NoPointer) {
return false
}
override suspend fun hasDevicesToVerifyAgainst(): Boolean {
return true
}
override fun backupState(): BackupState {
return BackupState.ENABLED
}

View file

@ -41,6 +41,14 @@ class RoomListFilterTest {
currentUserMembership = CurrentUserMembership.INVITED
)
private val space = aRoomSummary(
isSpace = true
)
private val invitedSpace = aRoomSummary(
isSpace = true,
currentUserMembership = CurrentUserMembership.INVITED
)
private val roomSummaries = listOf(
regularRoom,
dmRoom,
@ -49,13 +57,15 @@ class RoomListFilterTest {
unreadNotificationRoom,
roomToSearch,
roomWithAccent,
invitedRoom
invitedRoom,
space,
invitedSpace,
)
@Test
fun `Room list filter all empty`() = runTest {
val filter = RoomListFilter.all()
assertThat(roomSummaries.filter(filter)).isEqualTo(roomSummaries)
assertThat(roomSummaries.filter(filter)).isEqualTo(roomSummaries - space)
}
@Test
@ -83,6 +93,12 @@ class RoomListFilterTest {
)
}
@Test
fun `Room list filter space`() = runTest {
val filter = RoomListFilter.Category.Space
assertThat(roomSummaries.filter(filter)).containsExactly(space, invitedSpace)
}
@Test
fun `Room list filter favorite`() = runTest {
val filter = RoomListFilter.Favorite
@ -98,7 +114,7 @@ class RoomListFilterTest {
@Test
fun `Room list filter invites`() = runTest {
val filter = RoomListFilter.Invite
assertThat(roomSummaries.filter(filter)).containsExactly(invitedRoom)
assertThat(roomSummaries.filter(filter)).containsExactly(invitedRoom, invitedSpace)
}
@Test
@ -136,10 +152,4 @@ class RoomListFilterTest {
)
assertThat(roomSummaries.filter(filter)).isEmpty()
}
@Test
fun `Room list filter all with empty list`() = runTest {
val filter = RoomListFilter.all()
assertThat(roomSummaries.filter(filter)).isEqualTo(roomSummaries)
}
}