Add missing abstractions and fakes

This commit is contained in:
Jorge Martín
2025-12-04 18:02:59 +01:00
parent e814906ba1
commit 5d88a04ab0
12 changed files with 133 additions and 8 deletions

View File

@@ -22,6 +22,7 @@ import io.element.android.libraries.matrix.impl.paths.SessionPaths
import io.element.android.libraries.matrix.impl.paths.getSessionPaths
import io.element.android.libraries.matrix.impl.proxy.ProxyProvider
import io.element.android.libraries.matrix.impl.room.TimelineEventTypeFilterFactory
import io.element.android.libraries.matrix.impl.storage.SqliteStoreBuilderProvider
import io.element.android.libraries.matrix.impl.util.anonymizedTokens
import io.element.android.libraries.network.useragent.UserAgentProvider
import io.element.android.libraries.sessionstorage.api.SessionData
@@ -36,7 +37,6 @@ import org.matrix.rustcomponents.sdk.RequestConfig
import org.matrix.rustcomponents.sdk.Session
import org.matrix.rustcomponents.sdk.SlidingSyncVersion
import org.matrix.rustcomponents.sdk.SlidingSyncVersionBuilder
import org.matrix.rustcomponents.sdk.SqliteStoreBuilder
import org.matrix.rustcomponents.sdk.use
import timber.log.Timber
import uniffi.matrix_sdk_base.MediaRetentionPolicy
@@ -62,6 +62,7 @@ class RustMatrixClientFactory(
private val featureFlagService: FeatureFlagService,
private val timelineEventTypeFilterFactory: TimelineEventTypeFilterFactory,
private val clientBuilderProvider: ClientBuilderProvider,
private val sqliteStoreBuilderProvider: SqliteStoreBuilderProvider,
) {
private val sessionDelegate = RustClientSessionDelegate(sessionStore, appCoroutineScope, coroutineDispatchers)
@@ -126,12 +127,11 @@ class RustMatrixClientFactory(
slidingSyncType: ClientBuilderSlidingSync,
): ClientBuilder {
return clientBuilderProvider.provide()
.sqliteStore(
SqliteStoreBuilder(
dataPath = sessionPaths.fileDirectory.absolutePath,
cachePath = sessionPaths.cacheDirectory.absolutePath,
).passphrase(passphrase)
)
.run {
sqliteStoreBuilderProvider.provide(sessionPaths)
.passphrase(passphrase)
.setupClientBuilder(this)
}
.setSessionDelegate(sessionDelegate)
.userAgent(userAgentProvider.provide())
.addRootCertificates(userCertificatesProvider.provides())

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2025 Element Creations 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.storage
import io.element.android.libraries.matrix.impl.paths.SessionPaths
import org.matrix.rustcomponents.sdk.ClientBuilder
import org.matrix.rustcomponents.sdk.SqliteStoreBuilder as SdkSqliteStoreBuilder
interface SqliteStoreBuilder {
fun passphrase(passphrase: String?): SqliteStoreBuilder
fun setupClientBuilder(clientBuilder: ClientBuilder): ClientBuilder
}
class RustSqliteStoreBuilder(
private val sessionPaths: SessionPaths,
) : SqliteStoreBuilder {
private var inner = SdkSqliteStoreBuilder(
dataPath = sessionPaths.fileDirectory.absolutePath,
cachePath = sessionPaths.cacheDirectory.absolutePath,
)
override fun passphrase(passphrase: String?): SqliteStoreBuilder {
inner = inner.passphrase(passphrase)
return this
}
override fun setupClientBuilder(clientBuilder: ClientBuilder): ClientBuilder {
return clientBuilder.sqliteStore(this.inner)
}
}

View File

@@ -0,0 +1,23 @@
/*
* Copyright (c) 2025 Element Creations 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.storage
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding
import io.element.android.libraries.matrix.impl.paths.SessionPaths
interface SqliteStoreBuilderProvider {
fun provide(sessionPaths: SessionPaths): SqliteStoreBuilder
}
@ContributesBinding(AppScope::class)
class RustSqliteStoreBuilderProvider : SqliteStoreBuilderProvider {
override fun provide(sessionPaths: SessionPaths): SqliteStoreBuilder {
return RustSqliteStoreBuilder(sessionPaths)
}
}

View File

@@ -0,0 +1,19 @@
/*
* Copyright (c) 2025 Element Creations 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
import org.matrix.rustcomponents.sdk.NoHandle
import org.matrix.rustcomponents.sdk.SqliteStoreBuilder
class FakeFfiSqliteStoreBuilder : SqliteStoreBuilder(NoHandle) {
override fun cacheSize(cacheSize: UInt?): SqliteStoreBuilder = this
override fun journalSizeLimit(limit: UInt?): SqliteStoreBuilder = this
override fun passphrase(passphrase: String?): SqliteStoreBuilder = this
override fun poolMaxSize(poolMaxSize: UInt?): SqliteStoreBuilder = this
override fun systemIsMemoryConstrained(): SqliteStoreBuilder = this
}

View File

@@ -14,6 +14,7 @@ import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.impl.auth.FakeProxyProvider
import io.element.android.libraries.matrix.impl.auth.FakeUserCertificatesProvider
import io.element.android.libraries.matrix.impl.room.FakeTimelineEventTypeFilterFactory
import io.element.android.libraries.matrix.impl.storage.FakeSqliteStoreBuilderProvider
import io.element.android.libraries.network.useragent.SimpleUserAgentProvider
import io.element.android.libraries.sessionstorage.api.SessionStore
import io.element.android.libraries.sessionstorage.test.InMemorySessionStore
@@ -55,4 +56,5 @@ fun TestScope.createRustMatrixClientFactory(
featureFlagService = FakeFeatureFlagService(),
timelineEventTypeFilterFactory = FakeTimelineEventTypeFilterFactory(),
clientBuilderProvider = clientBuilderProvider,
sqliteStoreBuilderProvider = FakeSqliteStoreBuilderProvider(),
)

View File

@@ -27,7 +27,7 @@ import org.junit.Test
import java.io.File
class RustMatrixAuthenticationServiceTest {
@Test
@Test
fun `setHomeserver is successful`() = runTest {
val sut = createRustMatrixAuthenticationService(
clientBuilderProvider = FakeClientBuilderProvider(

View File

@@ -33,6 +33,7 @@ import org.matrix.rustcomponents.sdk.SyncServiceBuilder
import org.matrix.rustcomponents.sdk.TaskHandle
import org.matrix.rustcomponents.sdk.UnableToDecryptDelegate
import org.matrix.rustcomponents.sdk.UserProfile
import uniffi.matrix_sdk_base.MediaRetentionPolicy
class FakeFfiClient(
private val userId: String = A_USER_ID.value,
@@ -88,5 +89,7 @@ class FakeFfiClient(
return homeserverLoginDetailsResult()
}
override suspend fun setMediaRetentionPolicy(policy: MediaRetentionPolicy) {}
override fun close() = closeResult()
}

View File

@@ -44,5 +44,6 @@ class FakeFfiClientBuilder(
override fun enableShareHistoryOnInvite(enableShareHistoryOnInvite: Boolean): ClientBuilder = this
override fun threadsEnabled(enabled: Boolean, threadSubscriptions: Boolean): ClientBuilder = this
override fun sqliteStore(config: SqliteStoreBuilder): ClientBuilder = this
override fun inMemoryStore(): ClientBuilder = this
override suspend fun build() = buildResult()
}

View File

@@ -13,6 +13,7 @@ import io.element.android.libraries.matrix.impl.fixtures.factories.aRustRoomInfo
import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.tests.testutils.lambda.lambdaError
import org.matrix.rustcomponents.sdk.EventTimelineItem
import org.matrix.rustcomponents.sdk.LatestEventValue
import org.matrix.rustcomponents.sdk.NoHandle
import org.matrix.rustcomponents.sdk.Room
import org.matrix.rustcomponents.sdk.RoomInfo
@@ -25,6 +26,7 @@ class FakeFfiRoom(
private val getMembersNoSync: () -> RoomMembersIterator = { lambdaError() },
private val leaveLambda: () -> Unit = { lambdaError() },
private val latestEventLambda: () -> EventTimelineItem? = { lambdaError() },
private val newLatestEventLambda: () -> LatestEventValue = { lambdaError() },
private val suggestedRoleForUserLambda: (String) -> RoomMemberRole = { lambdaError() },
private val roomInfo: RoomInfo = aRustRoomInfo(id = roomId.value),
) : Room(NoHandle) {
@@ -56,6 +58,10 @@ class FakeFfiRoom(
return suggestedRoleForUserLambda(userId)
}
override suspend fun newLatestEvent(): LatestEventValue {
return newLatestEventLambda()
}
override fun close() {
// No-op
}

View File

@@ -22,6 +22,7 @@ import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.matrix.rustcomponents.sdk.LatestEventValue
import org.matrix.rustcomponents.sdk.RoomListEntriesUpdate
class RoomSummaryListProcessorTest {
@@ -174,6 +175,7 @@ class RoomSummaryListProcessorTest {
private fun aRustRoom(roomId: RoomId = A_ROOM_ID) = FakeFfiRoom(
roomId = roomId,
latestEventLambda = { null },
newLatestEventLambda = { LatestEventValue.None }
)
private fun TestScope.createProcessor() = RoomSummaryListProcessor(

View File

@@ -0,0 +1,18 @@
/*
* Copyright (c) 2025 Element Creations 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.storage
import org.matrix.rustcomponents.sdk.ClientBuilder
class FakeSqliteStoreBuilder : SqliteStoreBuilder {
override fun passphrase(passphrase: String?): SqliteStoreBuilder = this
override fun setupClientBuilder(clientBuilder: ClientBuilder): ClientBuilder {
return clientBuilder
}
}

View File

@@ -0,0 +1,16 @@
/*
* Copyright (c) 2025 Element Creations 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.storage
import io.element.android.libraries.matrix.impl.paths.SessionPaths
class FakeSqliteStoreBuilderProvider : SqliteStoreBuilderProvider {
override fun provide(sessionPaths: SessionPaths): SqliteStoreBuilder {
return FakeSqliteStoreBuilder()
}
}