From b0aa25c523bf1c0a2a6fa0f007bd9903ffa91152 Mon Sep 17 00:00:00 2001 From: Mohamad Jaara Date: Wed, 15 Jan 2025 12:55:59 +0100 Subject: [PATCH] feat: database logger [WPB-14608] (#3798) --- .../ui/debug/DebugScreenComposeTest.kt | 3 +- .../com/wire/android/WireApplication.kt | 8 - .../android/debug/DatabaseProfilingManager.kt | 56 ------ .../com/wire/android/di/CoreLogicModule.kt | 16 -- .../android/di/accountScoped/DebugModule.kt | 67 +++++++ .../com/wire/android/ui/debug/DebugScreen.kt | 10 +- .../com/wire/android/ui/debug/LogOptions.kt | 63 +++++- .../android/ui/debug/UserDebugViewModel.kt | 22 ++- app/src/main/res/values/strings.xml | 1 + .../debug/DatabaseProfilingManagerTest.kt | 187 ------------------ kalium | 2 +- 11 files changed, 160 insertions(+), 275 deletions(-) delete mode 100644 app/src/main/kotlin/com/wire/android/debug/DatabaseProfilingManager.kt create mode 100644 app/src/main/kotlin/com/wire/android/di/accountScoped/DebugModule.kt delete mode 100644 app/src/test/kotlin/com/wire/android/debug/DatabaseProfilingManagerTest.kt diff --git a/app/src/androidTest/kotlin/com/wire/android/ui/debug/DebugScreenComposeTest.kt b/app/src/androidTest/kotlin/com/wire/android/ui/debug/DebugScreenComposeTest.kt index 857991fe472..9ef1398e2ff 100644 --- a/app/src/androidTest/kotlin/com/wire/android/ui/debug/DebugScreenComposeTest.kt +++ b/app/src/androidTest/kotlin/com/wire/android/ui/debug/DebugScreenComposeTest.kt @@ -38,7 +38,8 @@ class DebugScreenComposeTest { onManualMigrationPressed = {}, state = UserDebugState(logPath = "logPath"), onLoggingEnabledChange = {}, - onDeleteLogs = {} + onDeleteLogs = {}, + onDatabaseLoggerEnabledChanged = {}, ) } } diff --git a/app/src/main/kotlin/com/wire/android/WireApplication.kt b/app/src/main/kotlin/com/wire/android/WireApplication.kt index 58ed10c4a55..b1feeee16fe 100644 --- a/app/src/main/kotlin/com/wire/android/WireApplication.kt +++ b/app/src/main/kotlin/com/wire/android/WireApplication.kt @@ -29,7 +29,6 @@ import co.touchlab.kermit.platformLogWriter import com.wire.android.analytics.ObserveCurrentSessionAnalyticsUseCase import com.wire.android.datastore.GlobalDataStore import com.wire.android.datastore.UserDataStoreProvider -import com.wire.android.debug.DatabaseProfilingManager import com.wire.android.di.ApplicationScope import com.wire.android.di.KaliumCoreLogic import com.wire.android.feature.analytics.AnonymousAnalyticsManager @@ -94,9 +93,6 @@ class WireApplication : BaseApp() { @Inject lateinit var currentScreenManager: CurrentScreenManager - @Inject - lateinit var databaseProfilingManager: DatabaseProfilingManager - @Inject lateinit var analyticsManager: Lazy @@ -207,10 +203,6 @@ class WireApplication : BaseApp() { logDeviceInformation() // 5. Verify if we can initialize Anonymous Analytics initializeAnonymousAnalytics() - // 6. Observe and update profiling when needed - globalAppScope.launch { - databaseProfilingManager.observeAndUpdateProfiling() - } } private fun initializeAnonymousAnalytics() { diff --git a/app/src/main/kotlin/com/wire/android/debug/DatabaseProfilingManager.kt b/app/src/main/kotlin/com/wire/android/debug/DatabaseProfilingManager.kt deleted file mode 100644 index e6fcc1aa28c..00000000000 --- a/app/src/main/kotlin/com/wire/android/debug/DatabaseProfilingManager.kt +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Wire - * Copyright (C) 2024 Wire Swiss GmbH - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -package com.wire.android.debug - -import com.wire.android.datastore.GlobalDataStore -import com.wire.android.di.KaliumCoreLogic -import com.wire.kalium.logic.CoreLogic -import com.wire.kalium.logic.data.user.UserId -import com.wire.kalium.logic.functional.mapToRightOr -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.filter -import kotlinx.coroutines.flow.flatMapLatest -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.scan -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class DatabaseProfilingManager @Inject constructor( - @KaliumCoreLogic private val coreLogic: CoreLogic, - private val globalDataStore: GlobalDataStore, -) { - - suspend fun observeAndUpdateProfiling() { - globalDataStore.isLoggingEnabled() - .flatMapLatest { isLoggingEnabled -> - coreLogic.getGlobalScope().sessionRepository.allValidSessionsFlow() - .mapToRightOr(emptyList()) - .map { it.map { it.userId } } - .scan(emptyList()) { previousList, currentList -> currentList - previousList.toSet() } - .map { userIds -> isLoggingEnabled to userIds } - } - .filter { (_, userIds) -> userIds.isNotEmpty() } - .distinctUntilChanged() - .collect { (isLoggingEnabled, userIds) -> - userIds.forEach { userId -> - coreLogic.getSessionScope(userId).debug.changeProfiling(isLoggingEnabled) - } - } - } -} diff --git a/app/src/main/kotlin/com/wire/android/di/CoreLogicModule.kt b/app/src/main/kotlin/com/wire/android/di/CoreLogicModule.kt index 01e0ea54c89..60464085788 100644 --- a/app/src/main/kotlin/com/wire/android/di/CoreLogicModule.kt +++ b/app/src/main/kotlin/com/wire/android/di/CoreLogicModule.kt @@ -36,7 +36,6 @@ import com.wire.kalium.logic.feature.connection.BlockUserUseCase import com.wire.kalium.logic.feature.connection.UnblockUserUseCase import com.wire.kalium.logic.feature.conversation.ObserveOtherUserSecurityClassificationLabelUseCase import com.wire.kalium.logic.feature.conversation.ObserveSecurityClassificationLabelUseCase -import com.wire.kalium.logic.feature.debug.BreakSessionUseCase import com.wire.kalium.logic.feature.e2ei.usecase.FetchConversationMLSVerificationStatusUseCase import com.wire.kalium.logic.feature.featureConfig.ObserveIsAppLockEditableUseCase import com.wire.kalium.logic.feature.selfDeletingMessages.ObserveSelfDeletionTimerSettingsForConversationUseCase @@ -214,11 +213,6 @@ class UseCaseModule { fun provideUpdateApiVersionsUseCase(@KaliumCoreLogic coreLogic: CoreLogic) = coreLogic.getGlobalScope().updateApiVersions - @ViewModelScoped - @Provides - fun provideDisableEventProcessing(@KaliumCoreLogic coreLogic: CoreLogic, @CurrentAccount currentAccount: UserId) = - coreLogic.getSessionScope(currentAccount).debug.disableEventProcessing - @ViewModelScoped @Provides fun provideCurrentSessionFlowUseCase(@KaliumCoreLogic coreLogic: CoreLogic) = @@ -483,16 +477,6 @@ class UseCaseModule { @CurrentAccount currentAccount: UserId ): GetCurrentAnalyticsTrackingIdentifierUseCase = coreLogic.getSessionScope(currentAccount).getCurrentAnalyticsTrackingIdentifier - @ViewModelScoped - @Provides - fun provideBreakSessionUseCase(@KaliumCoreLogic coreLogic: CoreLogic, @CurrentAccount currentAccount: UserId): BreakSessionUseCase = - coreLogic.getSessionScope(currentAccount).debug.breakSession - - @ViewModelScoped - @Provides - fun provideSendFCMTokenToAPIUseCase(@KaliumCoreLogic coreLogic: CoreLogic, @CurrentAccount currentAccount: UserId) = - coreLogic.getSessionScope(currentAccount).debug.sendFCMTokenToServer - @ViewModelScoped @Provides fun provideMigrateFromPersonalToTeamUseCase( diff --git a/app/src/main/kotlin/com/wire/android/di/accountScoped/DebugModule.kt b/app/src/main/kotlin/com/wire/android/di/accountScoped/DebugModule.kt new file mode 100644 index 00000000000..d7aa664191b --- /dev/null +++ b/app/src/main/kotlin/com/wire/android/di/accountScoped/DebugModule.kt @@ -0,0 +1,67 @@ +/* + * Wire + * Copyright (C) 2025 Wire Swiss GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +package com.wire.android.di.accountScoped + +import com.wire.android.di.CurrentAccount +import com.wire.android.di.KaliumCoreLogic +import com.wire.kalium.logic.CoreLogic +import com.wire.kalium.logic.data.user.UserId +import com.wire.kalium.logic.feature.debug.BreakSessionUseCase +import com.wire.kalium.logic.feature.debug.DebugScope +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.components.ViewModelComponent +import dagger.hilt.android.scopes.ViewModelScoped + +@Module +@InstallIn(ViewModelComponent::class) +class DebugModule { + + @ViewModelScoped + @Provides + fun providesDebugScope( + @KaliumCoreLogic coreLogic: CoreLogic, + @CurrentAccount currentAccount: UserId + ): DebugScope = coreLogic.getSessionScope(currentAccount).debug + + @ViewModelScoped + @Provides + fun provideDisableEventProcessing(debugScope: DebugScope) = + debugScope.disableEventProcessing + + @ViewModelScoped + @Provides + fun provideBreakSessionUseCase(debugScope: DebugScope): BreakSessionUseCase = + debugScope.breakSession + + @ViewModelScoped + @Provides + fun provideSendFCMTokenToAPIUseCase(debugScope: DebugScope) = + debugScope.sendFCMTokenToServer + + @ViewModelScoped + @Provides + fun provideChangeProfilingUseCase(debugScope: DebugScope) = + debugScope.changeProfiling + + @ViewModelScoped + @Provides + fun provideObserveDatabaseLoggerState(debugScope: DebugScope) = + debugScope.observeDatabaseLoggerState +} diff --git a/app/src/main/kotlin/com/wire/android/ui/debug/DebugScreen.kt b/app/src/main/kotlin/com/wire/android/ui/debug/DebugScreen.kt index e1d8f67a671..07fd800774b 100644 --- a/app/src/main/kotlin/com/wire/android/ui/debug/DebugScreen.kt +++ b/app/src/main/kotlin/com/wire/android/ui/debug/DebugScreen.kt @@ -73,7 +73,8 @@ fun DebugScreen(navigator: Navigator, userDebugViewModel: UserDebugViewModel = h }, state = userDebugViewModel.state, onLoggingEnabledChange = userDebugViewModel::setLoggingEnabledState, - onDeleteLogs = userDebugViewModel::deleteLogs + onDeleteLogs = userDebugViewModel::deleteLogs, + onDatabaseLoggerEnabledChanged = userDebugViewModel::setDatabaseLoggerEnabledState ) } @@ -83,6 +84,7 @@ internal fun UserDebugContent( onNavigationPressed: () -> Unit, onManualMigrationPressed: (currentAccount: UserId) -> Unit, onLoggingEnabledChange: (Boolean) -> Unit, + onDatabaseLoggerEnabledChanged: (Boolean) -> Unit, onDeleteLogs: () -> Unit, ) { val debugContentState: DebugContentState = rememberDebugContentState(state.logPath) @@ -109,6 +111,9 @@ internal fun UserDebugContent( onLoggingEnabledChange = onLoggingEnabledChange, onDeleteLogs = onDeleteLogs, onShareLogs = debugContentState::shareLogs, + isDBLoggerEnabled = state.isDBLoggingEnabled, + onDBLoggerEnabledChange = onDatabaseLoggerEnabledChanged, + isPrivateBuild = BuildConfig.PRIVATE_BUILD, ) DebugDataOptions( appVersion = AppNameUtil.createAppName(), @@ -178,6 +183,7 @@ internal fun PreviewUserDebugContent() = WireTheme { onNavigationPressed = {}, onManualMigrationPressed = {}, onLoggingEnabledChange = {}, - onDeleteLogs = {} + onDeleteLogs = {}, + onDatabaseLoggerEnabledChanged = {} ) } diff --git a/app/src/main/kotlin/com/wire/android/ui/debug/LogOptions.kt b/app/src/main/kotlin/com/wire/android/ui/debug/LogOptions.kt index 7a3fe1e89f0..5a53f1d9a37 100644 --- a/app/src/main/kotlin/com/wire/android/ui/debug/LogOptions.kt +++ b/app/src/main/kotlin/com/wire/android/ui/debug/LogOptions.kt @@ -33,6 +33,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import com.wire.android.R import com.wire.android.model.Clickable +import com.wire.android.ui.common.RowItemTemplate import com.wire.android.ui.common.SurfaceBackgroundWrapper import com.wire.android.ui.common.WireSwitch import com.wire.android.ui.common.colorsScheme @@ -49,9 +50,12 @@ import com.wire.android.util.ui.PreviewMultipleThemes fun LogOptions( isLoggingEnabled: Boolean, onLoggingEnabledChange: (Boolean) -> Unit, + isDBLoggerEnabled: Boolean, + onDBLoggerEnabledChange: (Boolean) -> Unit, onDeleteLogs: () -> Unit, onShareLogs: () -> Unit, - modifier: Modifier = Modifier, + isPrivateBuild: Boolean, + modifier: Modifier = Modifier ) { Column(modifier = modifier) { FolderHeader(stringResource(R.string.label_logs_option_title)) @@ -59,6 +63,13 @@ fun LogOptions( isEnabled = isLoggingEnabled, onCheckedChange = onLoggingEnabledChange ) + + if (isPrivateBuild) { + UserDataBaseProfileSwitch( + isEnabled = isDBLoggerEnabled, + onCheckedChange = onDBLoggerEnabledChange + ) + } if (isLoggingEnabled) { SettingsItem( text = stringResource(R.string.label_share_logs), @@ -123,13 +134,59 @@ private fun EnableLoggingSwitch( } } +@Composable +private fun UserDataBaseProfileSwitch( + isEnabled: Boolean, + onCheckedChange: ((Boolean) -> Unit), +) { + RowItemTemplate( + title = { + Text( + style = MaterialTheme.wireTypography.body01, + color = MaterialTheme.wireColorScheme.onBackground, + text = stringResource(R.string.label_user_database_profile), + modifier = Modifier.padding(start = dimensions().spacing8x) + ) + }, + actions = { + WireSwitch( + checked = isEnabled, + onCheckedChange = onCheckedChange, + modifier = Modifier + .padding(end = dimensions().spacing8x) + .size( + width = dimensions().buttonSmallMinSize.width, + height = dimensions().buttonSmallMinSize.height + ) + ) + } + ) +} + +@PreviewMultipleThemes +@Composable +fun PreviewLoggingOptionsPublicBuild() { + LogOptions( + isLoggingEnabled = true, + onLoggingEnabledChange = {}, + isDBLoggerEnabled = true, + onDBLoggerEnabledChange = {}, + onDeleteLogs = {}, + onShareLogs = {}, + isPrivateBuild = false, + ) +} + @PreviewMultipleThemes @Composable -fun PreviewLoggingOptions() { +fun PreviewLoggingOptionsPrivateBuild() { LogOptions( isLoggingEnabled = true, onLoggingEnabledChange = {}, + isDBLoggerEnabled = true, + onDBLoggerEnabledChange = {}, onDeleteLogs = {}, - onShareLogs = {} + onShareLogs = {}, + isPrivateBuild = true, ) } diff --git a/app/src/main/kotlin/com/wire/android/ui/debug/UserDebugViewModel.kt b/app/src/main/kotlin/com/wire/android/ui/debug/UserDebugViewModel.kt index 511e94d8d7f..d70590afced 100644 --- a/app/src/main/kotlin/com/wire/android/ui/debug/UserDebugViewModel.kt +++ b/app/src/main/kotlin/com/wire/android/ui/debug/UserDebugViewModel.kt @@ -31,12 +31,15 @@ import com.wire.kalium.logger.KaliumLogLevel import com.wire.kalium.logic.CoreLogger import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.logic.feature.client.ObserveCurrentClientIdUseCase +import com.wire.kalium.logic.feature.debug.ChangeProfilingUseCase +import com.wire.kalium.logic.feature.debug.ObserveDatabaseLoggerStateUseCase import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch import javax.inject.Inject data class UserDebugState( val isLoggingEnabled: Boolean = false, + val isDBLoggingEnabled: Boolean = false, val clientId: String = String.EMPTY, val commitish: String = String.EMPTY, val debugId: String = String.EMPTY, @@ -50,7 +53,9 @@ class UserDebugViewModel @CurrentAccount val currentAccount: UserId, private val logFileWriter: LogFileWriter, private val currentClientIdUseCase: ObserveCurrentClientIdUseCase, - private val globalDataStore: GlobalDataStore + private val globalDataStore: GlobalDataStore, + private val changeProfilingUseCase: ChangeProfilingUseCase, + private val observeDatabaseLoggerState: ObserveDatabaseLoggerStateUseCase ) : ViewModel() { var state by mutableStateOf( @@ -60,6 +65,21 @@ class UserDebugViewModel init { observeLoggingState() observeCurrentClientId() + observeDBLoggingState() + } + + fun setDatabaseLoggerEnabledState(isEnabled: Boolean) { + viewModelScope.launch { + changeProfilingUseCase(isEnabled) + } + } + + fun observeDBLoggingState() { + viewModelScope.launch { + observeDatabaseLoggerState().collect { + state = state.copy(isDBLoggingEnabled = it) + } + } } fun deleteLogs() { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f1fe9cd5952..c496167f22d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1678,6 +1678,7 @@ In group conversations, the group admin can overwrite this setting. Wire could not complete your team creation due to an unknown error. You Select Reaction + Database Logger ā€œ%1$sā€ was moved to ā€œ%2$sā€ diff --git a/app/src/test/kotlin/com/wire/android/debug/DatabaseProfilingManagerTest.kt b/app/src/test/kotlin/com/wire/android/debug/DatabaseProfilingManagerTest.kt deleted file mode 100644 index b0dc851cc0d..00000000000 --- a/app/src/test/kotlin/com/wire/android/debug/DatabaseProfilingManagerTest.kt +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Wire - * Copyright (C) 2024 Wire Swiss GmbH - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -package com.wire.android.debug - -import com.wire.android.config.CoroutineTestExtension -import com.wire.android.datastore.GlobalDataStore -import com.wire.kalium.logic.CoreLogic -import com.wire.kalium.logic.StorageFailure -import com.wire.kalium.logic.data.auth.AccountInfo -import com.wire.kalium.logic.data.user.UserId -import com.wire.kalium.logic.functional.Either -import io.mockk.MockKAnnotations -import io.mockk.coEvery -import io.mockk.impl.annotations.MockK -import io.mockk.mockk -import kotlinx.collections.immutable.PersistentMap -import kotlinx.collections.immutable.persistentMapOf -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.flowOf -import kotlinx.coroutines.launch -import kotlinx.coroutines.test.advanceUntilIdle -import kotlinx.coroutines.test.runTest -import org.amshove.kluent.internal.assertEquals -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith - -@ExtendWith(CoroutineTestExtension::class) -class DatabaseProfilingManagerTest { - - @Test - fun `given valid session and logging enabled, when observing, then profiling should be enabled`() = - runTest { - // given - val account = AccountInfo.Valid(UserId("user", "domain")) - val (arrangement, databaseProfilingManager) = Arrangement() - .withAllValidSessions(flowOf(Either.Right(listOf(account)))) - .withIsLoggingEnabled(flowOf(true)) - .arrange() - - // when - val job = launch { - databaseProfilingManager.observeAndUpdateProfiling() - } - advanceUntilIdle() - // then - assertEquals(true, arrangement.profilingValues[account.userId]) - job.cancel() - } - - @Test - fun `given valid session and logging disabled, when observing, then profiling is disabled`() = - runTest { - // given - val account = AccountInfo.Valid(UserId("user", "domain")) - val (arrangement, databaseProfilingManager) = Arrangement() - .withAllValidSessions(flowOf(Either.Right(listOf(account)))) - .withIsLoggingEnabled(flowOf(false)) - .arrange() - // when - val job = launch { - databaseProfilingManager.observeAndUpdateProfiling() - } - advanceUntilIdle() - // then - assertEquals(false, arrangement.profilingValues[account.userId]) - job.cancel() - } - - @Test - fun `given valid session, when observing and logging changes from disabled to enabled, then profiling is enabled`() = - runTest { - // given - val account = AccountInfo.Valid(UserId("user", "domain")) - val (arrangement, databaseProfilingManager) = Arrangement() - .withAllValidSessions(flowOf(Either.Right(listOf(account)))) - .withIsLoggingEnabled(flowOf(false)) - .arrange() - // when - val job = launch { - databaseProfilingManager.observeAndUpdateProfiling() - } - arrangement.withIsLoggingEnabled(flowOf(true)) - advanceUntilIdle() - // then - assertEquals(true, arrangement.profilingValues[account.userId]) - job.cancel() - } - - @Test - fun `given two valid sessions, when observing and logging changes from disabled to enabled, then profiling is enabled for both`() = - runTest { - // given - val account1 = AccountInfo.Valid(UserId("user1", "domain")) - val account2 = AccountInfo.Valid(UserId("user2", "domain")) - val (arrangement, databaseProfilingManager) = Arrangement() - .withAllValidSessions(flowOf(Either.Right(listOf(account1, account2)))) - .withIsLoggingEnabled(flowOf(false)) - .arrange() - // when - val job = launch { - databaseProfilingManager.observeAndUpdateProfiling() - } - arrangement.withIsLoggingEnabled(flowOf(true)) - advanceUntilIdle() - // then - assertEquals(true, arrangement.profilingValues[account1.userId]) - assertEquals(true, arrangement.profilingValues[account2.userId]) - job.cancel() - } - - @Test - fun `given valid session and logging enabled, when observing and new session appears, then profiling is enabled for both`() = - runTest { - // given - val account1 = AccountInfo.Valid(UserId("user1", "domain")) - val account2 = AccountInfo.Valid(UserId("user2", "domain")) - val validSessionsFlow = MutableStateFlow(Either.Right(listOf(account1))) - val (arrangement, databaseProfilingManager) = Arrangement() - .withAllValidSessions(validSessionsFlow) - .withIsLoggingEnabled(flowOf(true)) - .arrange() - // when - val job = launch { - databaseProfilingManager.observeAndUpdateProfiling() - } - validSessionsFlow.value = Either.Right(listOf(account1, account2)) - advanceUntilIdle() - // then - assertEquals(true, arrangement.profilingValues[account1.userId]) - assertEquals(true, arrangement.profilingValues[account2.userId]) - job.cancel() - } - - private class Arrangement { - - @MockK - lateinit var coreLogic: CoreLogic - - @MockK - private lateinit var globalDataStore: GlobalDataStore - - var profilingValues: PersistentMap = persistentMapOf() - private set - - init { - MockKAnnotations.init(this, relaxed = true, relaxUnitFun = true) - coEvery { coreLogic.getSessionScope(any()).debug.changeProfiling(any()) } answers { - profilingValues = profilingValues.put(firstArg(), secondArg()) - } - coEvery { coreLogic.getSessionScope(any()) } answers { - val userId = firstArg() - mockk { - coEvery { debug.changeProfiling(any()) } answers { - val profilingValue = firstArg() - profilingValues = profilingValues.put(userId, profilingValue) - } - } - } - } - - fun withIsLoggingEnabled(isLoggingEnabledFlow: Flow) = apply { - coEvery { globalDataStore.isLoggingEnabled() } returns isLoggingEnabledFlow - } - - fun withAllValidSessions(allValidSessionsFlow: Flow>>) = apply { - coEvery { coreLogic.getGlobalScope().sessionRepository.allValidSessionsFlow() } returns allValidSessionsFlow - } - - fun arrange() = this to DatabaseProfilingManager(coreLogic, globalDataStore) - } -} diff --git a/kalium b/kalium index 4362a2300c2..b016dd9f6d3 160000 --- a/kalium +++ b/kalium @@ -1 +1 @@ -Subproject commit 4362a2300c265ad69d9d86756ce9099953035b17 +Subproject commit b016dd9f6d3d053be275fe57e3b50ecb68b32d14