BIT-2307: Add logic to migrate crash logging behavior (#1335)

This commit is contained in:
David Perez 2024-05-03 10:39:33 -05:00 committed by Álison Fernandes
parent 7920d2104f
commit 652593ffb5
6 changed files with 122 additions and 0 deletions

View file

@ -1,5 +1,6 @@
package com.x8bit.bitwarden.data.platform.datasource.disk.di
import android.app.Application
import android.content.Context
import android.content.SharedPreferences
import com.x8bit.bitwarden.data.platform.datasource.di.EncryptedPreferences
@ -10,10 +11,13 @@ import com.x8bit.bitwarden.data.platform.datasource.disk.PushDiskSource
import com.x8bit.bitwarden.data.platform.datasource.disk.PushDiskSourceImpl
import com.x8bit.bitwarden.data.platform.datasource.disk.SettingsDiskSource
import com.x8bit.bitwarden.data.platform.datasource.disk.SettingsDiskSourceImpl
import com.x8bit.bitwarden.data.platform.datasource.disk.legacy.LegacyAppCenterMigrator
import com.x8bit.bitwarden.data.platform.datasource.disk.legacy.LegacyAppCenterMigratorImpl
import com.x8bit.bitwarden.data.platform.datasource.disk.legacy.LegacySecureStorage
import com.x8bit.bitwarden.data.platform.datasource.disk.legacy.LegacySecureStorageImpl
import com.x8bit.bitwarden.data.platform.datasource.disk.legacy.LegacySecureStorageMigrator
import com.x8bit.bitwarden.data.platform.datasource.disk.legacy.LegacySecureStorageMigratorImpl
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@ -60,6 +64,20 @@ object PlatformDiskModule {
encryptedSharedPreferences = encryptedSharedPreferences,
)
@Provides
@Singleton
fun provideLegacyAppCenterMigrator(
application: Application,
settingsRepository: SettingsRepository,
): LegacyAppCenterMigrator =
LegacyAppCenterMigratorImpl(
settingsRepository = settingsRepository,
appCenterPreferences = application.getSharedPreferences(
"AppCenter",
Context.MODE_PRIVATE,
),
)
@Provides
@Singleton
fun providePushDiskSource(

View file

@ -0,0 +1,12 @@
package com.x8bit.bitwarden.data.platform.datasource.disk.legacy
/**
* Provides the ability to migrate from a legacy AppCenter system to this app.
*/
interface LegacyAppCenterMigrator {
/**
* Migrates any data from the legacy AppCenter system to the new app.
* After migration, data will be removed from the legacy system.
*/
fun migrateIfNecessary()
}

View file

@ -0,0 +1,25 @@
package com.x8bit.bitwarden.data.platform.datasource.disk.legacy
import android.content.SharedPreferences
import androidx.core.content.edit
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
private const val LEGACY_ENABLED_CRASHES = "enabled_Crashes"
/**
* Primary implementation of [LegacyAppCenterMigrator].
*/
class LegacyAppCenterMigratorImpl(
private val settingsRepository: SettingsRepository,
private val appCenterPreferences: SharedPreferences,
) : LegacyAppCenterMigrator {
override fun migrateIfNecessary() {
// If the data is not present, then we return since there is nothing to migrate.
if (!appCenterPreferences.contains(LEGACY_ENABLED_CRASHES)) return
settingsRepository.isCrashLoggingEnabled = appCenterPreferences.getBoolean(
LEGACY_ENABLED_CRASHES,
true,
)
appCenterPreferences.edit { clear() }
}
}

View file

@ -6,6 +6,7 @@ import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
import com.x8bit.bitwarden.data.platform.datasource.disk.PushDiskSource
import com.x8bit.bitwarden.data.platform.datasource.disk.SettingsDiskSource
import com.x8bit.bitwarden.data.platform.datasource.disk.legacy.LegacyAppCenterMigrator
import com.x8bit.bitwarden.data.platform.datasource.network.authenticator.RefreshAuthenticator
import com.x8bit.bitwarden.data.platform.datasource.network.interceptor.AuthTokenInterceptor
import com.x8bit.bitwarden.data.platform.datasource.network.interceptor.BaseUrlInterceptors
@ -160,8 +161,10 @@ object PlatformManagerModule {
@Provides
@Singleton
fun provideCrashLogsManager(
legacyAppCenterMigrator: LegacyAppCenterMigrator,
settingsRepository: SettingsRepository,
): CrashLogsManager = CrashLogsManagerImpl(
settingsRepository = settingsRepository,
legacyAppCenterMigrator = legacyAppCenterMigrator,
)
}

View file

@ -2,13 +2,17 @@ package com.x8bit.bitwarden.data.platform.manager
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase
import com.x8bit.bitwarden.data.platform.annotation.OmitFromCoverage
import com.x8bit.bitwarden.data.platform.datasource.disk.legacy.LegacyAppCenterMigrator
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
/**
* CrashLogsManager implementation for standard flavor builds.
*/
@OmitFromCoverage
class CrashLogsManagerImpl(
private val settingsRepository: SettingsRepository,
legacyAppCenterMigrator: LegacyAppCenterMigrator,
) : CrashLogsManager {
override var isEnabled: Boolean
@ -19,6 +23,7 @@ class CrashLogsManagerImpl(
}
init {
legacyAppCenterMigrator.migrateIfNecessary()
isEnabled = settingsRepository.isCrashLoggingEnabled
}
}

View file

@ -0,0 +1,59 @@
package com.x8bit.bitwarden.data.platform.datasource.disk.legacy
import androidx.core.content.edit
import com.x8bit.bitwarden.data.platform.base.FakeSharedPreferences
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
import io.mockk.every
import io.mockk.just
import io.mockk.mockk
import io.mockk.runs
import io.mockk.verify
import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Test
class LegacyAppCenterMigratorTest {
private val settingsRepository = mockk<SettingsRepository>()
private val fakeSharedPreferences = FakeSharedPreferences()
private val migrator = LegacyAppCenterMigratorImpl(
settingsRepository = settingsRepository,
appCenterPreferences = fakeSharedPreferences,
)
@Test
fun `migrateIfNecessary should do nothing when there is nothing to migrate`() {
migrator.migrateIfNecessary()
verify(exactly = 0) {
settingsRepository.isCrashLoggingEnabled = any()
}
}
@Test
fun `migrateIfNecessary should migrate the data when it is present and true`() {
val isEnabled = true
fakeSharedPreferences.edit { putBoolean("enabled_Crashes", isEnabled) }
every { settingsRepository.isCrashLoggingEnabled = isEnabled } just runs
migrator.migrateIfNecessary()
verify(exactly = 1) {
settingsRepository.isCrashLoggingEnabled = isEnabled
}
assertFalse(fakeSharedPreferences.contains("enabled_Crashes"))
}
@Test
fun `migrateIfNecessary should migrate the data when it is present and false`() {
val isEnabled = false
fakeSharedPreferences.edit { putBoolean("enabled_Crashes", isEnabled) }
every { settingsRepository.isCrashLoggingEnabled = isEnabled } just runs
migrator.migrateIfNecessary()
verify(exactly = 1) {
settingsRepository.isCrashLoggingEnabled = isEnabled
}
assertFalse(fakeSharedPreferences.contains("enabled_Crashes"))
}
}