From 0939d65471dc4cf64e32ebc9f3259f64679d3b74 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 27 May 2025 18:42:52 +0200 Subject: [PATCH] Cleanup testImplementation dependencies --- appnav/build.gradle.kts | 4 +- .../appnav/intent/IntentResolverTest.kt | 64 ++++------- features/ftue/impl/build.gradle.kts | 1 - .../ftue/impl/DefaultFtueServiceTest.kt | 2 +- .../NotificationsOptInPresenterTest.kt | 2 +- features/login/impl/build.gradle.kts | 2 +- .../ConfirmAccountProviderPresenterTest.kt | 12 +-- .../onboarding/OnBoardingPresenterTest.kt | 4 +- features/messages/impl/build.gradle.kts | 1 - features/preferences/impl/build.gradle.kts | 5 +- .../impl/root/PreferencesRootPresenterTest.kt | 33 ++++-- features/roomlist/impl/build.gradle.kts | 2 +- .../roomlist/impl/RoomListPresenterTest.kt | 31 ++---- libraries/indicator/impl/build.gradle.kts | 1 + .../impl/DefaultIndicatorServiceTest.kt | 102 ++++++++++++++++++ libraries/indicator/test/build.gradle.kts | 19 ++++ .../indicator/test/FakeIndicatorService.kt | 37 +++++++ libraries/oidc/impl/build.gradle.kts | 1 + .../impl/DefaultOidcIntentResolverTest.kt | 69 ++++++++++++ .../customtab/DefaultOidcActionFlowTest.kt | 33 ++++++ libraries/oidc/test/build.gradle.kts | 20 ++++ .../oidc/test/FakeOidcIntentResolver.kt | 21 ++++ .../oidc/test/customtab/FakeOidcActionFlow.kt | 32 ++++++ ...tionTroubleshootCheckPermissionTestTest.kt | 2 +- .../test}/FakePermissionStateProvider.kt | 2 +- 25 files changed, 409 insertions(+), 93 deletions(-) create mode 100644 libraries/indicator/impl/src/test/kotlin/io/element/android/libraries/indicator/impl/DefaultIndicatorServiceTest.kt create mode 100644 libraries/indicator/test/build.gradle.kts create mode 100644 libraries/indicator/test/src/main/kotlin/io/element/android/libraries/indicator/test/FakeIndicatorService.kt create mode 100644 libraries/oidc/impl/src/test/kotlin/io/element/android/libraries/oidc/impl/DefaultOidcIntentResolverTest.kt create mode 100644 libraries/oidc/impl/src/test/kotlin/io/element/android/libraries/oidc/impl/customtab/DefaultOidcActionFlowTest.kt create mode 100644 libraries/oidc/test/build.gradle.kts create mode 100644 libraries/oidc/test/src/main/kotlin/io/element/android/libraries/oidc/test/FakeOidcIntentResolver.kt create mode 100644 libraries/oidc/test/src/main/kotlin/io/element/android/libraries/oidc/test/customtab/FakeOidcActionFlow.kt rename libraries/permissions/{impl/src/main/kotlin/io/element/android/libraries/permissions/impl => test/src/main/kotlin/io/element/android/libraries/permissions/test}/FakePermissionStateProvider.kt (96%) diff --git a/appnav/build.gradle.kts b/appnav/build.gradle.kts index a5fe7f0ec39..09b0a634a44 100644 --- a/appnav/build.gradle.kts +++ b/appnav/build.gradle.kts @@ -55,15 +55,13 @@ dependencies { testImplementation(libs.test.turbine) testImplementation(projects.features.login.test) testImplementation(projects.libraries.matrix.test) - testImplementation(projects.libraries.oidc.impl) + testImplementation(projects.libraries.oidc.test) testImplementation(projects.libraries.preferences.test) testImplementation(projects.libraries.push.test) testImplementation(projects.libraries.pushproviders.test) testImplementation(projects.features.networkmonitor.test) - testImplementation(projects.features.login.impl) testImplementation(projects.tests.testutils) testImplementation(projects.features.rageshake.test) - testImplementation(projects.features.rageshake.impl) testImplementation(projects.features.share.test) testImplementation(projects.services.appnavstate.test) testImplementation(projects.services.analytics.test) diff --git a/appnav/src/test/kotlin/io/element/android/appnav/intent/IntentResolverTest.kt b/appnav/src/test/kotlin/io/element/android/appnav/intent/IntentResolverTest.kt index 3fe9a9b728e..e95eb66cc38 100644 --- a/appnav/src/test/kotlin/io/element/android/appnav/intent/IntentResolverTest.kt +++ b/appnav/src/test/kotlin/io/element/android/appnav/intent/IntentResolverTest.kt @@ -22,13 +22,10 @@ import io.element.android.libraries.matrix.api.permalink.PermalinkData import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.A_THREAD_ID -import io.element.android.libraries.matrix.test.auth.FakeOidcRedirectUrlProvider import io.element.android.libraries.matrix.test.permalink.FakePermalinkParser import io.element.android.libraries.oidc.api.OidcAction -import io.element.android.libraries.oidc.impl.DefaultOidcIntentResolver -import io.element.android.libraries.oidc.impl.DefaultOidcUrlParser +import io.element.android.libraries.oidc.test.FakeOidcIntentResolver import io.element.android.tests.testutils.lambda.lambdaError -import org.junit.Assert.assertThrows import org.junit.Test import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner @@ -118,8 +115,10 @@ class IntentResolverTest { } @Test - fun `test resolve oidc go back`() { - val sut = createIntentResolver() + fun `test resolve oidc`() { + val sut = createIntentResolver( + oidcIntentResolverResult = { OidcAction.GoBack }, + ) val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { action = Intent.ACTION_VIEW data = "io.element.android:/?error=access_denied&state=IFF1UETGye2ZA8pO".toUri() @@ -132,35 +131,6 @@ class IntentResolverTest { ) } - @Test - fun `test resolve oidc success`() { - val sut = createIntentResolver() - val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { - action = Intent.ACTION_VIEW - data = "io.element.android:/?state=IFF1UETGye2ZA8pO&code=y6X1GZeqA3xxOWcTeShgv8nkgFJXyzWB".toUri() - } - val result = sut.resolve(intent) - assertThat(result).isEqualTo( - ResolvedIntent.Oidc( - oidcAction = OidcAction.Success( - url = "io.element.android:/?state=IFF1UETGye2ZA8pO&code=y6X1GZeqA3xxOWcTeShgv8nkgFJXyzWB" - ) - ) - ) - } - - @Test - fun `test resolve oidc invalid`() { - val sut = createIntentResolver() - val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { - action = Intent.ACTION_VIEW - data = "io.element.android:/invalid".toUri() - } - assertThrows(IllegalStateException::class.java) { - sut.resolve(intent) - } - } - @Test fun `test resolve external permalink`() { val permalinkData = PermalinkData.UserLink( @@ -168,7 +138,8 @@ class IntentResolverTest { ) val sut = createIntentResolver( loginIntentResolverResult = { null }, - permalinkParserResult = { permalinkData } + permalinkParserResult = { permalinkData }, + oidcIntentResolverResult = { null }, ) val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { action = Intent.ACTION_VIEW @@ -187,6 +158,7 @@ class IntentResolverTest { val sut = createIntentResolver( permalinkParserResult = { PermalinkData.FallbackLink(Uri.parse("https://matrix.org")) }, loginIntentResolverResult = { null }, + oidcIntentResolverResult = { null }, ) val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { action = Intent.ACTION_VIEW @@ -202,7 +174,8 @@ class IntentResolverTest { userId = UserId("@alice:matrix.org") ) val sut = createIntentResolver( - permalinkParserResult = { permalinkData } + permalinkParserResult = { permalinkData }, + oidcIntentResolverResult = { null }, ) val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { action = Intent.ACTION_BATTERY_LOW @@ -214,7 +187,9 @@ class IntentResolverTest { @Test fun `test incoming share simple`() { - val sut = createIntentResolver() + val sut = createIntentResolver( + oidcIntentResolverResult = { null }, + ) val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { action = Intent.ACTION_SEND } @@ -224,7 +199,9 @@ class IntentResolverTest { @Test fun `test incoming share multiple`() { - val sut = createIntentResolver() + val sut = createIntentResolver( + oidcIntentResolverResult = { null }, + ) val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { action = Intent.ACTION_SEND_MULTIPLE } @@ -237,6 +214,7 @@ class IntentResolverTest { val sut = createIntentResolver( permalinkParserResult = { PermalinkData.FallbackLink(Uri.parse("https://matrix.org")) }, loginIntentResolverResult = { null }, + oidcIntentResolverResult = { null }, ) val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { action = Intent.ACTION_VIEW @@ -251,6 +229,7 @@ class IntentResolverTest { val aLoginParams = LoginParams("accountProvider", null) val sut = createIntentResolver( loginIntentResolverResult = { aLoginParams }, + oidcIntentResolverResult = { null }, ) val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { action = Intent.ACTION_VIEW @@ -263,16 +242,15 @@ class IntentResolverTest { private fun createIntentResolver( permalinkParserResult: (String) -> PermalinkData = { lambdaError() }, loginIntentResolverResult: (String) -> LoginParams? = { lambdaError() }, + oidcIntentResolverResult: (Intent) -> OidcAction? = { lambdaError() }, ): IntentResolver { return IntentResolver( deeplinkParser = DeeplinkParser(), loginIntentResolver = FakeLoginIntentResolver( parseResult = loginIntentResolverResult, ), - oidcIntentResolver = DefaultOidcIntentResolver( - oidcUrlParser = DefaultOidcUrlParser( - oidcRedirectUrlProvider = FakeOidcRedirectUrlProvider(), - ) + oidcIntentResolver = FakeOidcIntentResolver( + resolveResult = oidcIntentResolverResult, ), permalinkParser = FakePermalinkParser( result = permalinkParserResult diff --git a/features/ftue/impl/build.gradle.kts b/features/ftue/impl/build.gradle.kts index 4b7e982474b..e95a4697ae9 100644 --- a/features/ftue/impl/build.gradle.kts +++ b/features/ftue/impl/build.gradle.kts @@ -57,7 +57,6 @@ dependencies { testImplementation(projects.libraries.matrix.test) testImplementation(projects.services.analytics.test) testImplementation(projects.services.analytics.noop) - testImplementation(projects.libraries.permissions.impl) testImplementation(projects.libraries.permissions.test) testImplementation(projects.libraries.preferences.test) testImplementation(projects.features.lockscreen.test) diff --git a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/DefaultFtueServiceTest.kt b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/DefaultFtueServiceTest.kt index 9ee2f519946..4a05433e5e3 100644 --- a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/DefaultFtueServiceTest.kt +++ b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/DefaultFtueServiceTest.kt @@ -19,7 +19,7 @@ import io.element.android.libraries.matrix.api.verification.SessionVerificationS import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus import io.element.android.libraries.matrix.test.verification.FakeSessionVerificationService import io.element.android.libraries.permissions.api.PermissionStateProvider -import io.element.android.libraries.permissions.impl.FakePermissionStateProvider +import io.element.android.libraries.permissions.test.FakePermissionStateProvider import io.element.android.libraries.preferences.api.store.SessionPreferencesStore import io.element.android.libraries.preferences.test.InMemorySessionPreferencesStore import io.element.android.services.analytics.api.AnalyticsService diff --git a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenterTest.kt b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenterTest.kt index 55bc1b92438..fbdc9d1dd17 100644 --- a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenterTest.kt +++ b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenterTest.kt @@ -14,7 +14,7 @@ import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import io.element.android.libraries.permissions.api.PermissionStateProvider import io.element.android.libraries.permissions.api.PermissionsPresenter -import io.element.android.libraries.permissions.impl.FakePermissionStateProvider +import io.element.android.libraries.permissions.test.FakePermissionStateProvider import io.element.android.libraries.permissions.test.FakePermissionsPresenter import io.element.android.libraries.permissions.test.FakePermissionsPresenterFactory import io.element.android.services.toolbox.test.sdk.FakeBuildVersionSdkIntProvider diff --git a/features/login/impl/build.gradle.kts b/features/login/impl/build.gradle.kts index 9fb87aa7f18..1d92cf00c99 100644 --- a/features/login/impl/build.gradle.kts +++ b/features/login/impl/build.gradle.kts @@ -62,7 +62,7 @@ dependencies { testImplementation(projects.features.enterprise.test) testImplementation(projects.libraries.featureflag.test) testImplementation(projects.libraries.matrix.test) - testImplementation(projects.libraries.oidc.impl) + testImplementation(projects.libraries.oidc.test) testImplementation(projects.libraries.permissions.test) testImplementation(projects.tests.testutils) testReleaseImplementation(libs.androidx.compose.ui.test.manifest) diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenterTest.kt index e8be30c1276..a2384baaeb2 100644 --- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenterTest.kt +++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenterTest.kt @@ -28,7 +28,7 @@ import io.element.android.libraries.matrix.test.A_THROWABLE import io.element.android.libraries.matrix.test.auth.FakeMatrixAuthenticationService import io.element.android.libraries.oidc.api.OidcAction import io.element.android.libraries.oidc.api.OidcActionFlow -import io.element.android.libraries.oidc.impl.customtab.DefaultOidcActionFlow +import io.element.android.libraries.oidc.test.customtab.FakeOidcActionFlow import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.waitForPredicate import kotlinx.coroutines.test.runTest @@ -100,7 +100,7 @@ class ConfirmAccountProviderPresenterTest { @Test fun `present - oidc - cancel with failure`() = runTest { val authenticationService = FakeMatrixAuthenticationService() - val defaultOidcActionFlow = DefaultOidcActionFlow() + val defaultOidcActionFlow = FakeOidcActionFlow() val presenter = createConfirmAccountProviderPresenter( matrixAuthenticationService = authenticationService, defaultOidcActionFlow = defaultOidcActionFlow, @@ -128,7 +128,7 @@ class ConfirmAccountProviderPresenterTest { @Test fun `present - oidc - cancel with success`() = runTest { val authenticationService = FakeMatrixAuthenticationService() - val defaultOidcActionFlow = DefaultOidcActionFlow() + val defaultOidcActionFlow = FakeOidcActionFlow() val presenter = createConfirmAccountProviderPresenter( matrixAuthenticationService = authenticationService, defaultOidcActionFlow = defaultOidcActionFlow, @@ -155,7 +155,7 @@ class ConfirmAccountProviderPresenterTest { @Test fun `present - oidc - success with failure`() = runTest { val authenticationService = FakeMatrixAuthenticationService() - val defaultOidcActionFlow = DefaultOidcActionFlow() + val defaultOidcActionFlow = FakeOidcActionFlow() val presenter = createConfirmAccountProviderPresenter( matrixAuthenticationService = authenticationService, defaultOidcActionFlow = defaultOidcActionFlow, @@ -185,7 +185,7 @@ class ConfirmAccountProviderPresenterTest { @Test fun `present - oidc - success with success`() = runTest { val authenticationService = FakeMatrixAuthenticationService() - val defaultOidcActionFlow = DefaultOidcActionFlow() + val defaultOidcActionFlow = FakeOidcActionFlow() val defaultLoginUserStory = DefaultLoginUserStory().apply { setLoginFlowIsDone(false) } @@ -356,7 +356,7 @@ class ConfirmAccountProviderPresenterTest { params: ConfirmAccountProviderPresenter.Params = ConfirmAccountProviderPresenter.Params(isAccountCreation = false), accountProviderDataSource: AccountProviderDataSource = AccountProviderDataSource(FakeEnterpriseService()), matrixAuthenticationService: MatrixAuthenticationService = FakeMatrixAuthenticationService(), - defaultOidcActionFlow: OidcActionFlow = DefaultOidcActionFlow(), + defaultOidcActionFlow: OidcActionFlow = FakeOidcActionFlow(), defaultLoginUserStory: DefaultLoginUserStory = DefaultLoginUserStory(), webClientUrlForAuthenticationRetriever: WebClientUrlForAuthenticationRetriever = FakeWebClientUrlForAuthenticationRetriever(), ) = ConfirmAccountProviderPresenter( diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingPresenterTest.kt index 45be02b1283..d57c67df7ee 100644 --- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingPresenterTest.kt +++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingPresenterTest.kt @@ -30,7 +30,7 @@ import io.element.android.libraries.matrix.test.A_THROWABLE import io.element.android.libraries.matrix.test.auth.FakeMatrixAuthenticationService import io.element.android.libraries.matrix.test.core.aBuildMeta import io.element.android.libraries.oidc.api.OidcActionFlow -import io.element.android.libraries.oidc.impl.customtab.DefaultOidcActionFlow +import io.element.android.libraries.oidc.test.customtab.FakeOidcActionFlow import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.test import kotlinx.coroutines.test.runTest @@ -226,7 +226,7 @@ private fun createPresenter( ) fun createLoginHelper( - oidcActionFlow: OidcActionFlow = DefaultOidcActionFlow(), + oidcActionFlow: OidcActionFlow = FakeOidcActionFlow(), authenticationService: MatrixAuthenticationService = FakeMatrixAuthenticationService(), defaultLoginUserStory: DefaultLoginUserStory = DefaultLoginUserStory(), webClientUrlForAuthenticationRetriever: WebClientUrlForAuthenticationRetriever = FakeWebClientUrlForAuthenticationRetriever(), diff --git a/features/messages/impl/build.gradle.kts b/features/messages/impl/build.gradle.kts index cf8f73f47a4..aed90d3e9f2 100644 --- a/features/messages/impl/build.gradle.kts +++ b/features/messages/impl/build.gradle.kts @@ -93,7 +93,6 @@ dependencies { testImplementation(libs.test.mockk) testImplementation(libs.test.robolectric) testImplementation(projects.features.poll.test) - testImplementation(projects.features.poll.impl) testImplementation(libs.androidx.compose.ui.test.junit) testImplementation(projects.libraries.eventformatter.test) testReleaseImplementation(libs.androidx.compose.ui.test.manifest) diff --git a/features/preferences/impl/build.gradle.kts b/features/preferences/impl/build.gradle.kts index 397d0c7acb0..6fb6e4a55b2 100644 --- a/features/preferences/impl/build.gradle.kts +++ b/features/preferences/impl/build.gradle.kts @@ -107,14 +107,11 @@ dependencies { testImplementation(projects.features.ftue.test) testImplementation(projects.features.invite.test) testImplementation(projects.features.rageshake.test) - testImplementation(projects.features.rageshake.impl) testImplementation(projects.features.logout.test) - testImplementation(projects.libraries.indicator.impl) + testImplementation(projects.libraries.indicator.test) testImplementation(projects.libraries.pushproviders.test) - testImplementation(projects.features.logout.impl) testImplementation(projects.services.analytics.test) testImplementation(projects.services.toolbox.test) - testImplementation(projects.features.analytics.impl) testImplementation(projects.tests.testutils) testImplementation(libs.androidx.compose.ui.test.junit) testReleaseImplementation(libs.androidx.compose.ui.test.manifest) diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt index 8075a43485e..1f1b527a45c 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt @@ -17,14 +17,14 @@ import io.element.android.features.rageshake.api.RageshakeFeatureAvailability import io.element.android.libraries.core.meta.BuildType import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher import io.element.android.libraries.featureflag.test.FakeFeatureFlagService -import io.element.android.libraries.indicator.impl.DefaultIndicatorService +import io.element.android.libraries.indicator.api.IndicatorService +import io.element.android.libraries.indicator.test.FakeIndicatorService import io.element.android.libraries.matrix.api.oidc.AccountManagementAction import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.test.AN_AVATAR_URL import io.element.android.libraries.matrix.test.A_USER_NAME import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.core.aBuildMeta -import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService import io.element.android.libraries.matrix.test.verification.FakeSessionVerificationService import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.tests.testutils.WarmUpRule @@ -71,7 +71,7 @@ class PreferencesRootPresenterTest { ) assertThat(initialState.version).isEqualTo("A Version") assertThat(loadedState.showSecureBackup).isFalse() - assertThat(loadedState.showSecureBackupBadge).isTrue() + assertThat(loadedState.showSecureBackupBadge).isFalse() assertThat(loadedState.accountManagementUrl).isNull() assertThat(loadedState.devicesManagementUrl).isNull() assertThat(loadedState.showAnalyticsSettings).isFalse() @@ -110,6 +110,27 @@ class PreferencesRootPresenterTest { } } + @Test + fun `present - secure backup badge`() = runTest { + val matrixClient = FakeMatrixClient( + canDeactivateAccountResult = { true }, + accountManagementUrlResult = { Result.success("") }, + ) + val indicatorService = FakeIndicatorService() + createPresenter( + matrixClient = matrixClient, + rageshakeFeatureAvailability = { false }, + indicatorService = indicatorService, + ).test { + skipItems(1) + val initialState = awaitItem() + assertThat(initialState.showSecureBackupBadge).isFalse() + indicatorService.setShowSettingChatBackupIndicator(true) + val finalState = awaitItem() + assertThat(finalState.showSecureBackupBadge).isTrue() + } + } + @Test fun `present - can deactivate account is false if the Matrix client say so`() = runTest { createPresenter( @@ -165,6 +186,7 @@ class PreferencesRootPresenterTest { sessionVerificationService: FakeSessionVerificationService = FakeSessionVerificationService(), showDeveloperSettingsProvider: ShowDeveloperSettingsProvider = ShowDeveloperSettingsProvider(aBuildMeta(BuildType.DEBUG)), rageshakeFeatureAvailability: RageshakeFeatureAvailability = RageshakeFeatureAvailability { true }, + indicatorService: IndicatorService = FakeIndicatorService(), ) = PreferencesRootPresenter( matrixClient = matrixClient, sessionVerificationService = sessionVerificationService, @@ -172,10 +194,7 @@ class PreferencesRootPresenterTest { versionFormatter = FakeVersionFormatter(), snackbarDispatcher = SnackbarDispatcher(), featureFlagService = FakeFeatureFlagService(), - indicatorService = DefaultIndicatorService( - sessionVerificationService = sessionVerificationService, - encryptionService = FakeEncryptionService(), - ), + indicatorService = indicatorService, directLogoutPresenter = { aDirectLogoutState() }, showDeveloperSettingsProvider = showDeveloperSettingsProvider, rageshakeFeatureAvailability = rageshakeFeatureAvailability, diff --git a/features/roomlist/impl/build.gradle.kts b/features/roomlist/impl/build.gradle.kts index 847787d774b..e0d795efd61 100644 --- a/features/roomlist/impl/build.gradle.kts +++ b/features/roomlist/impl/build.gradle.kts @@ -69,7 +69,7 @@ dependencies { testImplementation(projects.libraries.featureflag.test) testImplementation(projects.libraries.dateformatter.test) testImplementation(projects.libraries.eventformatter.test) - testImplementation(projects.libraries.indicator.impl) + testImplementation(projects.libraries.indicator.test) testImplementation(projects.libraries.permissions.noop) testImplementation(projects.libraries.permissions.test) testImplementation(projects.libraries.preferences.test) diff --git a/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTest.kt b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTest.kt index c5d09f7656c..5726eb1eb0b 100644 --- a/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTest.kt +++ b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTest.kt @@ -40,11 +40,11 @@ import io.element.android.libraries.eventformatter.test.FakeRoomLastMessageForma import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.fullscreenintent.api.aFullScreenIntentPermissionsState -import io.element.android.libraries.indicator.impl.DefaultIndicatorService +import io.element.android.libraries.indicator.api.IndicatorService +import io.element.android.libraries.indicator.test.FakeIndicatorService import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.SessionId -import io.element.android.libraries.matrix.api.encryption.BackupState import io.element.android.libraries.matrix.api.encryption.RecoveryState import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.RoomNotificationMode @@ -121,31 +121,24 @@ class RoomListPresenterTest { assertThat(withUserState.matrixUser.userId).isEqualTo(A_USER_ID) assertThat(withUserState.matrixUser.displayName).isEqualTo(A_USER_NAME) assertThat(withUserState.matrixUser.avatarUrl).isEqualTo(AN_AVATAR_URL) - assertThat(withUserState.showAvatarIndicator).isTrue() + assertThat(withUserState.showAvatarIndicator).isFalse() } } @Test fun `present - show avatar indicator`() = runTest { - val encryptionService = FakeEncryptionService() - val sessionVerificationService = FakeSessionVerificationService() - val matrixClient = FakeMatrixClient( - encryptionService = encryptionService, - sessionVerificationService = sessionVerificationService, - ) + val indicatorService = FakeIndicatorService() val presenter = createRoomListPresenter( - client = matrixClient, + indicatorService = indicatorService, ) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { val initialState = awaitItem() - assertThat(initialState.showAvatarIndicator).isTrue() - assertThat(initialState.canReportBug).isTrue() - sessionVerificationService.emitNeedsSessionVerification(false) - encryptionService.emitBackupState(BackupState.ENABLED) + assertThat(initialState.showAvatarIndicator).isFalse() + indicatorService.setShowRoomListTopBarIndicator(true) val finalState = awaitItem() - assertThat(finalState.showAvatarIndicator).isFalse() + assertThat(finalState.showAvatarIndicator).isTrue() } } @@ -686,7 +679,8 @@ class RoomListPresenterTest { notificationCleaner: NotificationCleaner = FakeNotificationCleaner(), appPreferencesStore: AppPreferencesStore = InMemoryAppPreferencesStore(), rageshakeFeatureAvailability: RageshakeFeatureAvailability = RageshakeFeatureAvailability { true }, - seenInvitesStore: SeenInvitesStore = InMemorySeenInvitesStore() + seenInvitesStore: SeenInvitesStore = InMemorySeenInvitesStore(), + indicatorService: IndicatorService = FakeIndicatorService(), ) = RoomListPresenter( client = client, syncService = syncService, @@ -704,10 +698,7 @@ class RoomListPresenterTest { dateTimeObserver = FakeDateTimeObserver(), ), featureFlagService = featureFlagService, - indicatorService = DefaultIndicatorService( - sessionVerificationService = client.sessionVerificationService(), - encryptionService = client.encryptionService(), - ), + indicatorService = indicatorService, searchPresenter = searchPresenter, sessionPreferencesStore = sessionPreferencesStore, filtersPresenter = filtersPresenter, diff --git a/libraries/indicator/impl/build.gradle.kts b/libraries/indicator/impl/build.gradle.kts index 4ce892325c7..d5046eb00cd 100644 --- a/libraries/indicator/impl/build.gradle.kts +++ b/libraries/indicator/impl/build.gradle.kts @@ -31,6 +31,7 @@ dependencies { testImplementation(projects.libraries.matrix.test) testImplementation(libs.test.junit) testImplementation(libs.coroutines.test) + testImplementation(libs.molecule.runtime) testImplementation(libs.test.turbine) testImplementation(libs.test.truth) } diff --git a/libraries/indicator/impl/src/test/kotlin/io/element/android/libraries/indicator/impl/DefaultIndicatorServiceTest.kt b/libraries/indicator/impl/src/test/kotlin/io/element/android/libraries/indicator/impl/DefaultIndicatorServiceTest.kt new file mode 100644 index 00000000000..9e325a65739 --- /dev/null +++ b/libraries/indicator/impl/src/test/kotlin/io/element/android/libraries/indicator/impl/DefaultIndicatorServiceTest.kt @@ -0,0 +1,102 @@ +/* + * 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.indicator.impl + +import app.cash.molecule.RecompositionMode +import app.cash.molecule.moleculeFlow +import app.cash.turbine.test +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.matrix.api.encryption.BackupState +import io.element.android.libraries.matrix.api.encryption.RecoveryState +import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService +import io.element.android.libraries.matrix.test.verification.FakeSessionVerificationService +import kotlinx.coroutines.test.runTest +import org.junit.Test + +class DefaultIndicatorServiceTest { + @Test + fun `test - showRoomListTopBarIndicator`() = runTest { + val encryptionService = FakeEncryptionService() + val sessionVerificationService = FakeSessionVerificationService() + val sut = DefaultIndicatorService( + sessionVerificationService = sessionVerificationService, + encryptionService = encryptionService, + ) + moleculeFlow(RecompositionMode.Immediate) { + sut.showRoomListTopBarIndicator().value + }.test { + assertThat(awaitItem()).isTrue() + sessionVerificationService.emitNeedsSessionVerification(false) + encryptionService.emitBackupState(BackupState.ENABLED) + encryptionService.emitRecoveryState(RecoveryState.ENABLED) + assertThat(awaitItem()).isFalse() + sessionVerificationService.emitNeedsSessionVerification(true) + assertThat(awaitItem()).isTrue() + } + } + + @Test + fun `test - showSettingChatBackupIndicator is true when BackupState is UNKNOWN`() = runTest { + val encryptionService = FakeEncryptionService() + val sessionVerificationService = FakeSessionVerificationService() + val sut = DefaultIndicatorService( + sessionVerificationService = sessionVerificationService, + encryptionService = encryptionService, + ) + moleculeFlow(RecompositionMode.Immediate) { + sut.showSettingChatBackupIndicator().value + }.test { + assertThat(awaitItem()).isTrue() + encryptionService.emitBackupState(BackupState.ENABLED) + encryptionService.emitRecoveryState(RecoveryState.ENABLED) + assertThat(awaitItem()).isFalse() + encryptionService.emitBackupState(BackupState.UNKNOWN) + assertThat(awaitItem()).isTrue() + } + } + + @Test + fun `test - showSettingChatBackupIndicator is true when recoveryState is DISABLED`() = runTest { + val encryptionService = FakeEncryptionService() + val sessionVerificationService = FakeSessionVerificationService() + val sut = DefaultIndicatorService( + sessionVerificationService = sessionVerificationService, + encryptionService = encryptionService, + ) + moleculeFlow(RecompositionMode.Immediate) { + sut.showSettingChatBackupIndicator().value + }.test { + assertThat(awaitItem()).isTrue() + encryptionService.emitBackupState(BackupState.ENABLED) + encryptionService.emitRecoveryState(RecoveryState.ENABLED) + assertThat(awaitItem()).isFalse() + encryptionService.emitRecoveryState(RecoveryState.DISABLED) + assertThat(awaitItem()).isTrue() + } + } + + @Test + fun `test - showSettingChatBackupIndicator is true when recoveryState is INCOMPLETE`() = runTest { + val encryptionService = FakeEncryptionService() + val sessionVerificationService = FakeSessionVerificationService() + val sut = DefaultIndicatorService( + sessionVerificationService = sessionVerificationService, + encryptionService = encryptionService, + ) + moleculeFlow(RecompositionMode.Immediate) { + sut.showSettingChatBackupIndicator().value + }.test { + assertThat(awaitItem()).isTrue() + encryptionService.emitBackupState(BackupState.ENABLED) + encryptionService.emitRecoveryState(RecoveryState.ENABLED) + assertThat(awaitItem()).isFalse() + encryptionService.emitRecoveryState(RecoveryState.INCOMPLETE) + assertThat(awaitItem()).isTrue() + } + } +} diff --git a/libraries/indicator/test/build.gradle.kts b/libraries/indicator/test/build.gradle.kts new file mode 100644 index 00000000000..5d61dde8be9 --- /dev/null +++ b/libraries/indicator/test/build.gradle.kts @@ -0,0 +1,19 @@ +/* + * 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. + */ + +plugins { + id("io.element.android-compose-library") +} + +android { + namespace = "io.element.android.libraries.indicator.test" +} + +dependencies { + implementation(projects.libraries.matrix.api) + api(projects.libraries.indicator.api) +} diff --git a/libraries/indicator/test/src/main/kotlin/io/element/android/libraries/indicator/test/FakeIndicatorService.kt b/libraries/indicator/test/src/main/kotlin/io/element/android/libraries/indicator/test/FakeIndicatorService.kt new file mode 100644 index 00000000000..26f8547b66d --- /dev/null +++ b/libraries/indicator/test/src/main/kotlin/io/element/android/libraries/indicator/test/FakeIndicatorService.kt @@ -0,0 +1,37 @@ +/* + * 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.indicator.test + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.State +import androidx.compose.runtime.mutableStateOf +import io.element.android.libraries.indicator.api.IndicatorService + +class FakeIndicatorService : IndicatorService { + private val showRoomListTopBarIndicatorResult: MutableState = mutableStateOf(false) + private val showSettingChatBackupIndicatorResult: MutableState = mutableStateOf(false) + + fun setShowRoomListTopBarIndicator(value: Boolean) { + showRoomListTopBarIndicatorResult.value = value + } + + fun setShowSettingChatBackupIndicator(value: Boolean) { + showSettingChatBackupIndicatorResult.value = value + } + + @Composable + override fun showRoomListTopBarIndicator(): State { + return showRoomListTopBarIndicatorResult + } + + @Composable + override fun showSettingChatBackupIndicator(): State { + return showSettingChatBackupIndicatorResult + } +} diff --git a/libraries/oidc/impl/build.gradle.kts b/libraries/oidc/impl/build.gradle.kts index 2d4699c2463..c0f8e9d1d62 100644 --- a/libraries/oidc/impl/build.gradle.kts +++ b/libraries/oidc/impl/build.gradle.kts @@ -40,6 +40,7 @@ dependencies { api(projects.libraries.oidc.api) testImplementation(libs.test.junit) + testImplementation(libs.test.robolectric) testImplementation(libs.androidx.test.ext.junit) testImplementation(libs.coroutines.test) testImplementation(libs.molecule.runtime) diff --git a/libraries/oidc/impl/src/test/kotlin/io/element/android/libraries/oidc/impl/DefaultOidcIntentResolverTest.kt b/libraries/oidc/impl/src/test/kotlin/io/element/android/libraries/oidc/impl/DefaultOidcIntentResolverTest.kt new file mode 100644 index 00000000000..e48e0c2e1ee --- /dev/null +++ b/libraries/oidc/impl/src/test/kotlin/io/element/android/libraries/oidc/impl/DefaultOidcIntentResolverTest.kt @@ -0,0 +1,69 @@ +/* + * 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.oidc.impl + +import android.app.Activity +import android.content.Intent +import androidx.core.net.toUri +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.matrix.test.auth.FakeOidcRedirectUrlProvider +import io.element.android.libraries.oidc.api.OidcAction +import org.junit.Assert.assertThrows +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.RuntimeEnvironment + +@RunWith(RobolectricTestRunner::class) +class DefaultOidcIntentResolverTest { + @Test + fun `test resolve oidc go back`() { + val sut = createDefaultOidcIntentResolver() + val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { + action = Intent.ACTION_VIEW + data = "io.element.android:/?error=access_denied&state=IFF1UETGye2ZA8pO".toUri() + } + val result = sut.resolve(intent) + assertThat(result).isEqualTo(OidcAction.GoBack) + } + + @Test + fun `test resolve oidc success`() { + val sut = createDefaultOidcIntentResolver() + val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { + action = Intent.ACTION_VIEW + data = "io.element.android:/?state=IFF1UETGye2ZA8pO&code=y6X1GZeqA3xxOWcTeShgv8nkgFJXyzWB".toUri() + } + val result = sut.resolve(intent) + assertThat(result).isEqualTo( + OidcAction.Success( + url = "io.element.android:/?state=IFF1UETGye2ZA8pO&code=y6X1GZeqA3xxOWcTeShgv8nkgFJXyzWB" + ) + ) + } + + @Test + fun `test resolve oidc invalid`() { + val sut = createDefaultOidcIntentResolver() + val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { + action = Intent.ACTION_VIEW + data = "io.element.android:/invalid".toUri() + } + assertThrows(IllegalStateException::class.java) { + sut.resolve(intent) + } + } + + private fun createDefaultOidcIntentResolver(): DefaultOidcIntentResolver { + return DefaultOidcIntentResolver( + oidcUrlParser = DefaultOidcUrlParser( + oidcRedirectUrlProvider = FakeOidcRedirectUrlProvider(), + ), + ) + } +} diff --git a/libraries/oidc/impl/src/test/kotlin/io/element/android/libraries/oidc/impl/customtab/DefaultOidcActionFlowTest.kt b/libraries/oidc/impl/src/test/kotlin/io/element/android/libraries/oidc/impl/customtab/DefaultOidcActionFlowTest.kt new file mode 100644 index 00000000000..104ff6c3471 --- /dev/null +++ b/libraries/oidc/impl/src/test/kotlin/io/element/android/libraries/oidc/impl/customtab/DefaultOidcActionFlowTest.kt @@ -0,0 +1,33 @@ +/* + * 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.oidc.impl.customtab + +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.oidc.api.OidcAction +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.runTest +import org.junit.Test + +class DefaultOidcActionFlowTest { + @Test + fun `collect gets all the posted events`() = runTest { + val data = mutableListOf() + val sut = DefaultOidcActionFlow() + backgroundScope.launch { + sut.collect { action -> + data.add(action) + } + } + sut.post(OidcAction.GoBack) + delay(1) + sut.reset() + delay(1) + assertThat(data).containsExactly(OidcAction.GoBack, null) + } +} diff --git a/libraries/oidc/test/build.gradle.kts b/libraries/oidc/test/build.gradle.kts new file mode 100644 index 00000000000..ac9d4cfda83 --- /dev/null +++ b/libraries/oidc/test/build.gradle.kts @@ -0,0 +1,20 @@ +/* + * 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. + */ + +plugins { + id("io.element.android-library") +} + +android { + namespace = "io.element.android.libraries.oidc.test" +} + +dependencies { + implementation(libs.coroutines.core) + api(projects.libraries.oidc.api) + implementation(projects.tests.testutils) +} diff --git a/libraries/oidc/test/src/main/kotlin/io/element/android/libraries/oidc/test/FakeOidcIntentResolver.kt b/libraries/oidc/test/src/main/kotlin/io/element/android/libraries/oidc/test/FakeOidcIntentResolver.kt new file mode 100644 index 00000000000..1fa5947c3f9 --- /dev/null +++ b/libraries/oidc/test/src/main/kotlin/io/element/android/libraries/oidc/test/FakeOidcIntentResolver.kt @@ -0,0 +1,21 @@ +/* + * 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.oidc.test + +import android.content.Intent +import io.element.android.libraries.oidc.api.OidcAction +import io.element.android.libraries.oidc.api.OidcIntentResolver +import io.element.android.tests.testutils.lambda.lambdaError + +class FakeOidcIntentResolver( + private val resolveResult: (Intent) -> OidcAction? = { lambdaError() } +) : OidcIntentResolver { + override fun resolve(intent: Intent): OidcAction? { + return resolveResult(intent) + } +} diff --git a/libraries/oidc/test/src/main/kotlin/io/element/android/libraries/oidc/test/customtab/FakeOidcActionFlow.kt b/libraries/oidc/test/src/main/kotlin/io/element/android/libraries/oidc/test/customtab/FakeOidcActionFlow.kt new file mode 100644 index 00000000000..d1673d8bc8a --- /dev/null +++ b/libraries/oidc/test/src/main/kotlin/io/element/android/libraries/oidc/test/customtab/FakeOidcActionFlow.kt @@ -0,0 +1,32 @@ +/* + * 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.oidc.test.customtab + +import io.element.android.libraries.oidc.api.OidcAction +import io.element.android.libraries.oidc.api.OidcActionFlow +import kotlinx.coroutines.flow.FlowCollector +import kotlinx.coroutines.flow.MutableStateFlow + +/** + * This is actually a copy of DefaultOidcActionFlow. + */ +class FakeOidcActionFlow : OidcActionFlow { + private val mutableStateFlow = MutableStateFlow(null) + + override fun post(oidcAction: OidcAction) { + mutableStateFlow.value = oidcAction + } + + override suspend fun collect(collector: FlowCollector) { + mutableStateFlow.collect(collector) + } + + override fun reset() { + mutableStateFlow.value = null + } +} diff --git a/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/troubleshoot/NotificationTroubleshootCheckPermissionTestTest.kt b/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/troubleshoot/NotificationTroubleshootCheckPermissionTestTest.kt index b50cc16e69d..a530b8dbee4 100644 --- a/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/troubleshoot/NotificationTroubleshootCheckPermissionTestTest.kt +++ b/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/troubleshoot/NotificationTroubleshootCheckPermissionTestTest.kt @@ -10,8 +10,8 @@ package io.element.android.libraries.permissions.impl.troubleshoot import android.os.Build import app.cash.turbine.test import com.google.common.truth.Truth.assertThat -import io.element.android.libraries.permissions.impl.FakePermissionStateProvider import io.element.android.libraries.permissions.impl.action.FakePermissionActions +import io.element.android.libraries.permissions.test.FakePermissionStateProvider import io.element.android.libraries.troubleshoot.api.test.NotificationTroubleshootTestState import io.element.android.services.toolbox.test.sdk.FakeBuildVersionSdkIntProvider import io.element.android.services.toolbox.test.strings.FakeStringProvider diff --git a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/FakePermissionStateProvider.kt b/libraries/permissions/test/src/main/kotlin/io/element/android/libraries/permissions/test/FakePermissionStateProvider.kt similarity index 96% rename from libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/FakePermissionStateProvider.kt rename to libraries/permissions/test/src/main/kotlin/io/element/android/libraries/permissions/test/FakePermissionStateProvider.kt index ebd945c8e6b..c97057bc7d9 100644 --- a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/FakePermissionStateProvider.kt +++ b/libraries/permissions/test/src/main/kotlin/io/element/android/libraries/permissions/test/FakePermissionStateProvider.kt @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.libraries.permissions.impl +package io.element.android.libraries.permissions.test import io.element.android.libraries.permissions.api.PermissionStateProvider import kotlinx.coroutines.flow.Flow