From b6d09984dde8bb1798c84f2f9da99b0bb2f16724 Mon Sep 17 00:00:00 2001 From: sergeibakhtiarov Date: Wed, 11 Dec 2024 14:59:26 +0000 Subject: [PATCH] feat: add more debug information (WPB-14930) (#3725) Co-authored-by: sergei.bakhtiarov --- .../wire/android/ui/debug/DebugDataOptions.kt | 15 ++ .../android/ui/debug/DebugDataOptionsState.kt | 5 +- .../ui/debug/DebugDataOptionsViewModel.kt | 34 ++++ app/src/main/res/values/strings.xml | 5 + .../debug/DebugDataOptionsViewModelTest.kt | 186 ++++++++++++++++++ 5 files changed, 244 insertions(+), 1 deletion(-) diff --git a/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptions.kt b/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptions.kt index 756669e1442..165da415254 100644 --- a/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptions.kt +++ b/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptions.kt @@ -161,6 +161,21 @@ fun DebugDataOptionsContent( ) ) + Column { + SettingsItem( + title = stringResource(R.string.debug_federation_enabled), + text = state.isFederationEnabled.toString(), + ) + SettingsItem( + title = stringResource(R.string.debug_default_backend_protocol), + text = state.defaultProtocol, + ) + SettingsItem( + title = stringResource(R.string.debug_current_api_version), + text = state.currentApiVersion, + ) + } + if (BuildConfig.DEBUG) { GetE2EICertificateSwitch( enrollE2EI = enrollE2EICertificate diff --git a/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsState.kt b/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsState.kt index acc93712f82..3f7387e53d3 100644 --- a/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsState.kt +++ b/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsState.kt @@ -29,5 +29,8 @@ data class DebugDataOptionsState( val certificate: String = "null", val showCertificate: Boolean = false, val startGettingE2EICertificate: Boolean = false, - val analyticsTrackingId: String = "null" + val analyticsTrackingId: String = "null", + val isFederationEnabled: Boolean = false, + val currentApiVersion: String = "null", + val defaultProtocol: String = "null", ) diff --git a/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt b/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt index b23e0d65238..e98c20eb903 100644 --- a/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt +++ b/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt @@ -34,6 +34,8 @@ import com.wire.android.util.getGitBuildId import com.wire.android.util.ui.UIText import com.wire.kalium.logic.CoreFailure import com.wire.kalium.logic.E2EIFailure +import com.wire.kalium.logic.configuration.server.CommonApiVersionType +import com.wire.kalium.logic.data.user.SupportedProtocol import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.logic.feature.analytics.GetCurrentAnalyticsTrackingIdentifierUseCase import com.wire.kalium.logic.feature.e2ei.CheckCrlRevocationListUseCase @@ -42,6 +44,8 @@ import com.wire.kalium.logic.feature.keypackage.MLSKeyPackageCountResult import com.wire.kalium.logic.feature.keypackage.MLSKeyPackageCountUseCase import com.wire.kalium.logic.feature.notificationToken.SendFCMTokenError import com.wire.kalium.logic.feature.notificationToken.SendFCMTokenUseCase +import com.wire.kalium.logic.feature.user.GetDefaultProtocolUseCase +import com.wire.kalium.logic.feature.user.SelfServerConfigUseCase import com.wire.kalium.logic.functional.Either import com.wire.kalium.logic.functional.fold import com.wire.kalium.logic.sync.periodic.UpdateApiVersionsScheduler @@ -87,6 +91,8 @@ class DebugDataOptionsViewModelImpl private val getCurrentAnalyticsTrackingIdentifier: GetCurrentAnalyticsTrackingIdentifierUseCase, private val sendFCMToken: SendFCMTokenUseCase, private val dispatcherProvider: DispatcherProvider, + private val selfServerConfigUseCase: SelfServerConfigUseCase, + private val getDefaultProtocolUseCase: GetDefaultProtocolUseCase, ) : ViewModel(), DebugDataOptionsViewModel { var state by mutableStateOf( @@ -102,6 +108,34 @@ class DebugDataOptionsViewModelImpl checkIfCanTriggerManualMigration() setGitHashAndDeviceId() setAnalyticsTrackingId() + setServerConfigData() + setDefaultProtocol() + } + + private fun setDefaultProtocol() { + viewModelScope.launch { + state = state.copy( + defaultProtocol = when (getDefaultProtocolUseCase()) { + SupportedProtocol.PROTEUS -> "Proteus" + SupportedProtocol.MLS -> "MLS" + } + ) + } + } + + private fun setServerConfigData() { + viewModelScope.launch { + val result = selfServerConfigUseCase() + if (result is SelfServerConfigUseCase.Result.Success) { + state = state.copy( + isFederationEnabled = result.serverLinks.metaData.federation, + currentApiVersion = when (result.serverLinks.metaData.commonApiVersion) { + CommonApiVersionType.Unknown -> "Unknown" + else -> result.serverLinks.metaData.commonApiVersion.version.toString() + }, + ) + } + } } private fun setAnalyticsTrackingId() { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 060d2d7a6c2..3583986c1a3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -23,6 +23,11 @@ Analytics Tracking Identifier + Federation Enabled + + Default Backend Protocol + + Current API Version New Login OK diff --git a/app/src/test/kotlin/com/wire/android/ui/settings/debug/DebugDataOptionsViewModelTest.kt b/app/src/test/kotlin/com/wire/android/ui/settings/debug/DebugDataOptionsViewModelTest.kt index f4476ca976c..b14eb1d1cdf 100644 --- a/app/src/test/kotlin/com/wire/android/ui/settings/debug/DebugDataOptionsViewModelTest.kt +++ b/app/src/test/kotlin/com/wire/android/ui/settings/debug/DebugDataOptionsViewModelTest.kt @@ -31,7 +31,11 @@ import com.wire.android.ui.debug.DebugDataOptionsViewModelImpl import com.wire.android.util.getDeviceIdString import com.wire.android.util.getGitBuildId import com.wire.android.util.ui.UIText +import com.wire.kalium.logic.CoreFailure +import com.wire.kalium.logic.configuration.server.CommonApiVersionType +import com.wire.kalium.logic.configuration.server.ServerConfig import com.wire.kalium.logic.data.conversation.ClientId +import com.wire.kalium.logic.data.user.SupportedProtocol import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.logic.feature.analytics.GetCurrentAnalyticsTrackingIdentifierUseCase import com.wire.kalium.logic.feature.e2ei.CheckCrlRevocationListUseCase @@ -39,6 +43,8 @@ import com.wire.kalium.logic.feature.keypackage.MLSKeyPackageCountResult import com.wire.kalium.logic.feature.keypackage.MLSKeyPackageCountUseCase import com.wire.kalium.logic.feature.notificationToken.SendFCMTokenError import com.wire.kalium.logic.feature.notificationToken.SendFCMTokenUseCase +import com.wire.kalium.logic.feature.user.GetDefaultProtocolUseCase +import com.wire.kalium.logic.feature.user.SelfServerConfigUseCase import com.wire.kalium.logic.functional.Either import com.wire.kalium.logic.sync.periodic.UpdateApiVersionsScheduler import com.wire.kalium.logic.sync.slow.RestartSlowSyncProcessForRecoveryUseCase @@ -46,6 +52,7 @@ import io.mockk.MockKAnnotations import io.mockk.coEvery import io.mockk.every import io.mockk.impl.annotations.MockK +import io.mockk.mockk import io.mockk.mockkStatic import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -128,6 +135,77 @@ class DebugDataOptionsViewModelTest { assertEquals(UIText.DynamicString("Can't register token, error: error message"), result) } } + + @Test + fun `given that Proteus protocol is used, view state should have Proteus protocol name`() = runTest { + // given + val (_, viewModel) = DebugDataOptionsHiltArrangement() + .withProteusProtocolSetup() + .arrange() + + assertEquals("Proteus", viewModel.state.defaultProtocol) + } + + @Test + fun `given that Mls protocol is used, view state should have proteus Mls name`() = runTest { + // given + val (_, viewModel) = DebugDataOptionsHiltArrangement() + .withMlsProtocolSetup() + .arrange() + + assertEquals("MLS", viewModel.state.defaultProtocol) + } + + @Test + fun `given that federation is disabled, view state should have federation value of false`() = runTest { + // given + val (_, viewModel) = DebugDataOptionsHiltArrangement() + .withFederationDisabled() + .arrange() + + assertEquals(false, viewModel.state.isFederationEnabled) + } + + @Test + fun `given that federation is enabled, view state should have federation value of true`() = runTest { + // given + val (_, viewModel) = DebugDataOptionsHiltArrangement() + .withFederationEnabled() + .arrange() + + assertEquals(true, viewModel.state.isFederationEnabled) + } + + @Test + fun `given that api version is unknown, view state should have api version unknown`() = runTest { + // given + val (_, viewModel) = DebugDataOptionsHiltArrangement() + .withApiVersionUnknown() + .arrange() + + assertEquals("Unknown", viewModel.state.currentApiVersion) + } + + @Test + fun `given that api version is set, view state should have api version set`() = runTest { + // given + val (_, viewModel) = DebugDataOptionsHiltArrangement() + .withApiVersionSet(7) + .arrange() + + assertEquals("7", viewModel.state.currentApiVersion) + } + + @Test + fun `given server config failure, view state should have default values`() = runTest { + // given + val (_, viewModel) = DebugDataOptionsHiltArrangement() + .withServerConfigError() + .arrange() + + assertEquals("null", viewModel.state.currentApiVersion) + assertEquals(false, viewModel.state.isFederationEnabled) + } } internal class DebugDataOptionsHiltArrangement { @@ -155,6 +233,12 @@ internal class DebugDataOptionsHiltArrangement { @MockK lateinit var getCurrentAnalyticsTrackingIdentifier: GetCurrentAnalyticsTrackingIdentifierUseCase + @MockK + lateinit var selfServerConfigUseCase: SelfServerConfigUseCase + + @MockK + lateinit var getDefaultProtocolUseCase: GetDefaultProtocolUseCase + @MockK lateinit var sendFCMToken: SendFCMTokenUseCase @@ -170,6 +254,8 @@ internal class DebugDataOptionsHiltArrangement { getCurrentAnalyticsTrackingIdentifier = getCurrentAnalyticsTrackingIdentifier, sendFCMToken = sendFCMToken, dispatcherProvider = TestDispatcherProvider(), + selfServerConfigUseCase = selfServerConfigUseCase, + getDefaultProtocolUseCase = getDefaultProtocolUseCase, ) } @@ -196,6 +282,22 @@ internal class DebugDataOptionsHiltArrangement { coEvery { globalDataStore.getUserMigrationStatus(TestUser.SELF_USER_ID.value) } returns flowOf(UserMigrationStatus.NoNeed) + coEvery { + selfServerConfigUseCase() + } returns SelfServerConfigUseCase.Result.Success( + ServerConfig( + id = "id", + links = mockk(), + metaData = ServerConfig.MetaData( + federation = true, + commonApiVersion = CommonApiVersionType.Unknown, + domain = null, + ) + ) + ) + every { + getDefaultProtocolUseCase() + } returns SupportedProtocol.PROTEUS } fun arrange() = this to viewModel @@ -223,4 +325,88 @@ internal class DebugDataOptionsHiltArrangement { sendFCMToken() } returns Either.Left(SendFCMTokenError(SendFCMTokenError.Reason.CANT_REGISTER_TOKEN, "error message")) } + + fun withProteusProtocolSetup() = apply { + every { + getDefaultProtocolUseCase() + } returns SupportedProtocol.PROTEUS + } + + fun withMlsProtocolSetup() = apply { + every { + getDefaultProtocolUseCase() + } returns SupportedProtocol.MLS + } + + fun withFederationEnabled() = apply { + coEvery { + selfServerConfigUseCase() + } returns SelfServerConfigUseCase.Result.Success( + ServerConfig( + id = "id", + links = mockk(), + metaData = ServerConfig.MetaData( + federation = true, + commonApiVersion = CommonApiVersionType.Unknown, + domain = null, + ) + ) + ) + } + + fun withFederationDisabled() = apply { + coEvery { + selfServerConfigUseCase() + } returns SelfServerConfigUseCase.Result.Success( + ServerConfig( + id = "id", + links = mockk(), + metaData = ServerConfig.MetaData( + federation = false, + commonApiVersion = CommonApiVersionType.Unknown, + domain = null, + ) + ) + ) + } + + fun withApiVersionUnknown() = apply { + coEvery { + selfServerConfigUseCase() + } returns SelfServerConfigUseCase.Result.Success( + ServerConfig( + id = "id", + links = mockk(), + metaData = ServerConfig.MetaData( + federation = true, + commonApiVersion = CommonApiVersionType.Unknown, + domain = null, + ) + ) + ) + } + + fun withApiVersionSet(version: Int) = apply { + coEvery { + selfServerConfigUseCase() + } returns SelfServerConfigUseCase.Result.Success( + ServerConfig( + id = "id", + links = mockk(), + metaData = ServerConfig.MetaData( + federation = true, + commonApiVersion = CommonApiVersionType.Valid(version), + domain = null, + ) + ) + ) + } + + fun withServerConfigError() = apply { + coEvery { + selfServerConfigUseCase() + } returns SelfServerConfigUseCase.Result.Failure( + CoreFailure.Unknown(IllegalStateException()) + ) + } }