From fc795c9be833f53f145247ec226402abb246b731 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 19 Sep 2024 12:16:24 +0200 Subject: [PATCH] Add test skeleton for RustMatrixClientFactory and RustMatrixAuthenticationService --- libraries/matrix/impl/build.gradle.kts | 2 + .../matrix/impl/ClientBuilderProvider.kt | 23 ++++++++ .../matrix/impl/RustMatrixClientFactory.kt | 3 +- .../matrix/impl/FakeClientBuilderProvider.kt | 17 ++++++ .../impl/RustMatrixClientFactoryTest.kt | 57 +++++++++++++++++++ .../impl/auth/FakePassphraseGenerator.kt | 17 ++++++ .../matrix/impl/auth/FakeProxyProvider.kt | 16 ++++++ .../impl/auth/FakeUserCertificatesProvider.kt | 16 ++++++ .../RustMatrixAuthenticationServiceTest.kt | 57 +++++++++++++++++++ .../impl/fixtures/fakes/FakeRustClient.kt | 3 + .../fixtures/fakes/FakeRustClientBuilder.kt | 51 +++++++++++++++++ .../fakes/FakeRustSyncServiceBuilder.kt | 18 ++++++ .../android/libraries/matrix/test/TestData.kt | 1 + 13 files changed, 280 insertions(+), 1 deletion(-) create mode 100644 libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/ClientBuilderProvider.kt create mode 100644 libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/FakeClientBuilderProvider.kt create mode 100644 libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactoryTest.kt create mode 100644 libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/FakePassphraseGenerator.kt create mode 100644 libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/FakeProxyProvider.kt create mode 100644 libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/FakeUserCertificatesProvider.kt create mode 100644 libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationServiceTest.kt create mode 100644 libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeRustClientBuilder.kt create mode 100644 libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeRustSyncServiceBuilder.kt diff --git a/libraries/matrix/impl/build.gradle.kts b/libraries/matrix/impl/build.gradle.kts index c13189b198..4bd7f995d8 100644 --- a/libraries/matrix/impl/build.gradle.kts +++ b/libraries/matrix/impl/build.gradle.kts @@ -46,7 +46,9 @@ dependencies { testImplementation(libs.test.junit) testImplementation(libs.test.truth) testImplementation(libs.test.robolectric) + testImplementation(projects.libraries.featureflag.test) testImplementation(projects.libraries.matrix.test) + testImplementation(projects.libraries.preferences.test) testImplementation(projects.libraries.sessionStorage.implMemory) testImplementation(projects.libraries.sessionStorage.test) testImplementation(projects.services.analytics.test) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/ClientBuilderProvider.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/ClientBuilderProvider.kt new file mode 100644 index 0000000000..0bd05b4cdc --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/ClientBuilderProvider.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only + * Please see LICENSE in the repository root for full details. + */ + +package io.element.android.libraries.matrix.impl + +import com.squareup.anvil.annotations.ContributesBinding +import io.element.android.libraries.di.AppScope +import org.matrix.rustcomponents.sdk.ClientBuilder + +interface ClientBuilderProvider { + fun provide(): ClientBuilder +} + +@ContributesBinding(AppScope::class) +class RustClientBuilderProvider : ClientBuilderProvider { + override fun provide(): ClientBuilder { + return ClientBuilder() + } +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt index 507e63b4e7..e8c5f3dec3 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt @@ -47,6 +47,7 @@ class RustMatrixClientFactory @Inject constructor( private val utdTracker: UtdTracker, private val featureFlagService: FeatureFlagService, private val timelineEventTypeFilterFactory: TimelineEventTypeFilterFactory, + private val clientBuilderProvider: ClientBuilderProvider, ) { suspend fun create(sessionData: SessionData): RustMatrixClient = withContext(coroutineDispatchers.io) { val sessionDelegate = RustClientSessionDelegate(sessionStore, appCoroutineScope, coroutineDispatchers) @@ -89,7 +90,7 @@ class RustMatrixClientFactory @Inject constructor( passphrase: String?, slidingSyncType: ClientBuilderSlidingSync, ): ClientBuilder { - return ClientBuilder() + return clientBuilderProvider.provide() .sessionPaths( dataPath = sessionPaths.fileDirectory.absolutePath, cachePath = sessionPaths.cacheDirectory.absolutePath, diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/FakeClientBuilderProvider.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/FakeClientBuilderProvider.kt new file mode 100644 index 0000000000..be216b3d73 --- /dev/null +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/FakeClientBuilderProvider.kt @@ -0,0 +1,17 @@ +/* + * Copyright 2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only + * Please see LICENSE in the repository root for full details. + */ + +package io.element.android.libraries.matrix.impl + +import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeRustClientBuilder +import org.matrix.rustcomponents.sdk.ClientBuilder + +class FakeClientBuilderProvider : ClientBuilderProvider { + override fun provide(): ClientBuilder { + return FakeRustClientBuilder() + } +} diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactoryTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactoryTest.kt new file mode 100644 index 0000000000..b408574e92 --- /dev/null +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactoryTest.kt @@ -0,0 +1,57 @@ +/* + * Copyright 2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only + * Please see LICENSE in the repository root for full details. + */ + +package io.element.android.libraries.matrix.impl + +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.featureflag.test.FakeFeatureFlagService +import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.matrix.impl.analytics.UtdTracker +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.network.useragent.SimpleUserAgentProvider +import io.element.android.libraries.sessionstorage.api.SessionStore +import io.element.android.libraries.sessionstorage.impl.memory.InMemorySessionStore +import io.element.android.libraries.sessionstorage.test.aSessionData +import io.element.android.services.analytics.test.FakeAnalyticsService +import io.element.android.services.toolbox.test.systemclock.FakeSystemClock +import io.element.android.tests.testutils.testCoroutineDispatchers +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runTest +import org.junit.Test +import java.io.File + +class RustMatrixClientFactoryTest { + @Test + fun test() = runTest { + val sut = createRustMatrixClientFactory() + val result = sut.create(aSessionData()) + assertThat(result.sessionId).isEqualTo(SessionId("@alice:server.org")) + result.close() + } +} + +fun TestScope.createRustMatrixClientFactory( + baseDirectory: File = File("/base"), + cacheDirectory: File = File("/cache"), + sessionStore: SessionStore = InMemorySessionStore(), +) = RustMatrixClientFactory( + baseDirectory = baseDirectory, + cacheDirectory = cacheDirectory, + appCoroutineScope = this, + coroutineDispatchers = testCoroutineDispatchers(), + sessionStore = sessionStore, + userAgentProvider = SimpleUserAgentProvider(), + userCertificatesProvider = FakeUserCertificatesProvider(), + proxyProvider = FakeProxyProvider(), + clock = FakeSystemClock(), + utdTracker = UtdTracker(FakeAnalyticsService()), + featureFlagService = FakeFeatureFlagService(), + timelineEventTypeFilterFactory = FakeTimelineEventTypeFilterFactory(), + clientBuilderProvider = FakeClientBuilderProvider(), +) diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/FakePassphraseGenerator.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/FakePassphraseGenerator.kt new file mode 100644 index 0000000000..d882606dc2 --- /dev/null +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/FakePassphraseGenerator.kt @@ -0,0 +1,17 @@ +/* + * Copyright 2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only + * Please see LICENSE in the repository root for full details. + */ + +package io.element.android.libraries.matrix.impl.auth + +import io.element.android.libraries.matrix.impl.keys.PassphraseGenerator +import io.element.android.libraries.matrix.test.A_PASSPHRASE + +class FakePassphraseGenerator( + private val passphrase: () -> String? = { A_PASSPHRASE } +) : PassphraseGenerator { + override fun generatePassphrase(): String? = passphrase() +} diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/FakeProxyProvider.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/FakeProxyProvider.kt new file mode 100644 index 0000000000..3758be64a0 --- /dev/null +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/FakeProxyProvider.kt @@ -0,0 +1,16 @@ +/* + * Copyright 2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only + * Please see LICENSE in the repository root for full details. + */ + +package io.element.android.libraries.matrix.impl.auth + +import io.element.android.libraries.matrix.impl.proxy.ProxyProvider + +class FakeProxyProvider : ProxyProvider { + override fun provides(): String? { + return null + } +} diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/FakeUserCertificatesProvider.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/FakeUserCertificatesProvider.kt new file mode 100644 index 0000000000..85dd7f0ecc --- /dev/null +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/FakeUserCertificatesProvider.kt @@ -0,0 +1,16 @@ +/* + * Copyright 2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only + * Please see LICENSE in the repository root for full details. + */ + +package io.element.android.libraries.matrix.impl.auth + +import io.element.android.libraries.matrix.impl.certificates.UserCertificatesProvider + +class FakeUserCertificatesProvider : UserCertificatesProvider { + override fun provides(): List { + return emptyList() + } +} diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationServiceTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationServiceTest.kt new file mode 100644 index 0000000000..2a3cadd045 --- /dev/null +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationServiceTest.kt @@ -0,0 +1,57 @@ +/* + * Copyright 2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only + * Please see LICENSE in the repository root for full details. + */ + +package io.element.android.libraries.matrix.impl.auth + +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.matrix.impl.createRustMatrixClientFactory +import io.element.android.libraries.matrix.impl.paths.SessionPathsFactory +import io.element.android.libraries.preferences.test.InMemoryAppPreferencesStore +import io.element.android.libraries.sessionstorage.api.SessionStore +import io.element.android.libraries.sessionstorage.impl.memory.InMemorySessionStore +import io.element.android.libraries.sessionstorage.test.aSessionData +import io.element.android.tests.testutils.testCoroutineDispatchers +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runTest +import org.junit.Test +import java.io.File + +class RustMatrixAuthenticationServiceTest { + @Test + fun `getLatestSessionId should return the value from the store`() = runTest { + val sessionStore = InMemorySessionStore() + val sut = createRustMatrixAuthenticationService( + sessionStore = sessionStore, + ) + assertThat(sut.getLatestSessionId()).isNull() + sessionStore.storeData(aSessionData(sessionId = "@alice:server.org")) + assertThat(sut.getLatestSessionId()).isEqualTo(SessionId("@alice:server.org")) + } + + private fun TestScope.createRustMatrixAuthenticationService( + sessionStore: SessionStore = InMemorySessionStore(), + ): RustMatrixAuthenticationService { + val baseDirectory = File("/base") + val cacheDirectory = File("/cache") + val rustMatrixClientFactory = createRustMatrixClientFactory( + baseDirectory = baseDirectory, + cacheDirectory = cacheDirectory, + sessionStore = sessionStore, + ) + return RustMatrixAuthenticationService( + sessionPathsFactory = SessionPathsFactory(baseDirectory, cacheDirectory), + coroutineDispatchers = testCoroutineDispatchers(), + sessionStore = sessionStore, + rustMatrixClientFactory = rustMatrixClientFactory, + passphraseGenerator = FakePassphraseGenerator(), + oidcConfigurationProvider = OidcConfigurationProvider(baseDirectory), + appPreferencesStore = InMemoryAppPreferencesStore(), + ) + } +} + diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeRustClient.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeRustClient.kt index caa51b3a5c..fd9b02b417 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeRustClient.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeRustClient.kt @@ -18,6 +18,7 @@ import org.matrix.rustcomponents.sdk.NotificationClient import org.matrix.rustcomponents.sdk.NotificationProcessSetup import org.matrix.rustcomponents.sdk.NotificationSettings import org.matrix.rustcomponents.sdk.Session +import org.matrix.rustcomponents.sdk.SyncServiceBuilder import org.matrix.rustcomponents.sdk.TaskHandle class FakeRustClient( @@ -36,4 +37,6 @@ class FakeRustClient( override fun session(): Session = session override fun setDelegate(delegate: ClientDelegate?): TaskHandle = FakeRustTaskHandle() override fun cachedAvatarUrl(): String? = null + override suspend fun restoreSession(session: Session) = Unit + override fun syncService(): SyncServiceBuilder = FakeRustSyncServiceBuilder() } diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeRustClientBuilder.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeRustClientBuilder.kt new file mode 100644 index 0000000000..5f073b147c --- /dev/null +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeRustClientBuilder.kt @@ -0,0 +1,51 @@ +/* + * Copyright 2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only + * Please see LICENSE in the repository root for full details. + */ + +package io.element.android.libraries.matrix.impl.fixtures.fakes + +import org.matrix.rustcomponents.sdk.Client +import org.matrix.rustcomponents.sdk.ClientBuilder +import org.matrix.rustcomponents.sdk.ClientSessionDelegate +import org.matrix.rustcomponents.sdk.NoPointer +import org.matrix.rustcomponents.sdk.OidcConfiguration +import org.matrix.rustcomponents.sdk.QrCodeData +import org.matrix.rustcomponents.sdk.QrLoginProgressListener +import org.matrix.rustcomponents.sdk.RequestConfig +import org.matrix.rustcomponents.sdk.SlidingSyncVersionBuilder +import uniffi.matrix_sdk.BackupDownloadStrategy +import uniffi.matrix_sdk_crypto.CollectStrategy + +class FakeRustClientBuilder : ClientBuilder(NoPointer) { + override fun addRootCertificates(certificates: List) = this + override fun autoEnableBackups(autoEnableBackups: Boolean) = this + override fun autoEnableCrossSigning(autoEnableCrossSigning: Boolean) = this + override fun backupDownloadStrategy(backupDownloadStrategy: BackupDownloadStrategy) = this + override fun disableAutomaticTokenRefresh() = this + override fun disableBuiltInRootCertificates() = this + override fun disableSslVerification() = this + override fun enableCrossProcessRefreshLock(processId: String, sessionDelegate: ClientSessionDelegate) = this + override fun homeserverUrl(url: String) = this + override fun passphrase(passphrase: String?) = this + override fun proxy(url: String) = this + override fun requestConfig(config: RequestConfig) = this + override fun roomKeyRecipientStrategy(strategy: CollectStrategy) = this + override fun serverName(serverName: String) = this + override fun serverNameOrHomeserverUrl(serverNameOrUrl: String) = this + override fun sessionPaths(dataPath: String, cachePath: String) = this + override fun setSessionDelegate(sessionDelegate: ClientSessionDelegate) = this + override fun slidingSyncVersionBuilder(versionBuilder: SlidingSyncVersionBuilder) = this + override fun userAgent(userAgent: String) = this + override fun username(username: String) = this + + override suspend fun buildWithQrCode(qrCodeData: QrCodeData, oidcConfiguration: OidcConfiguration, progressListener: QrLoginProgressListener): Client { + return FakeRustClient() + } + + override suspend fun build(): Client { + return FakeRustClient() + } +} diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeRustSyncServiceBuilder.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeRustSyncServiceBuilder.kt new file mode 100644 index 0000000000..4cb9c0d314 --- /dev/null +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeRustSyncServiceBuilder.kt @@ -0,0 +1,18 @@ +/* + * Copyright 2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only + * Please see LICENSE in the repository root for full details. + */ + +package io.element.android.libraries.matrix.impl.fixtures.fakes + +import org.matrix.rustcomponents.sdk.NoPointer +import org.matrix.rustcomponents.sdk.SyncService +import org.matrix.rustcomponents.sdk.SyncServiceBuilder +import org.matrix.rustcomponents.sdk.UnableToDecryptDelegate + +class FakeRustSyncServiceBuilder : SyncServiceBuilder(NoPointer) { + override suspend fun withUtdHook(delegate: UnableToDecryptDelegate): SyncServiceBuilder = this + override suspend fun finish(): SyncService = FakeRustSyncService() +} diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt index add458ae00..d7dfc2dcb3 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt @@ -23,6 +23,7 @@ import io.element.android.libraries.matrix.api.room.RoomNotificationSettings const val A_USER_NAME = "alice" const val A_PASSWORD = "password" +const val A_PASSPHRASE = "passphrase" const val A_SECRET = "secret" val A_USER_ID = UserId("@alice:server.org")