From 05d6c2f61e750da6fa3737574c20edac33eff70c Mon Sep 17 00:00:00 2001 From: Dave Severns <149429124+dseverns-livefront@users.noreply.github.com> Date: Fri, 20 Sep 2024 15:25:01 -0400 Subject: [PATCH] [PM-10622] Handle the skip unlock step in the onboarding, storing when the user selects to do so. (#3928) --- .../datasource/disk/SettingsDiskSource.kt | 12 +++++++++ .../datasource/disk/SettingsDiskSourceImpl.kt | 12 +++++++++ .../platform/repository/SettingsRepository.kt | 18 ++++++++++--- .../repository/SettingsRepositoryImpl.kt | 7 +++++ .../accountsetup/SetupUnlockViewModel.kt | 1 + .../datasource/disk/SettingsDiskSourceTest.kt | 24 +++++++++++++++++ .../disk/util/FakeSettingsDiskSource.kt | 8 ++++++ .../repository/SettingsRepositoryTest.kt | 27 +++++++++++++++++++ .../accountsetup/SetupUnlockViewModelTest.kt | 2 ++ 9 files changed, 108 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/x8bit/bitwarden/data/platform/datasource/disk/SettingsDiskSource.kt b/app/src/main/java/com/x8bit/bitwarden/data/platform/datasource/disk/SettingsDiskSource.kt index 12496968c..2758daff8 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/platform/datasource/disk/SettingsDiskSource.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/platform/datasource/disk/SettingsDiskSource.kt @@ -270,4 +270,16 @@ interface SettingsDiskSource { * enable autofill in onboarding. */ fun storeShowAutoFillSettingBadge(userId: String, showBadge: Boolean?) + + /** + * Gets whether or not the given [userId] has signalled they want to enable unlock options + * later, during onboarding. + */ + fun getShowUnlockSettingBadge(userId: String): Boolean? + + /** + * Stores the given value for whether or not the given [userId] has signalled they want to + * set up unlock options later, during onboarding. + */ + fun storeShowUnlockSettingBadge(userId: String, showBadge: Boolean?) } diff --git a/app/src/main/java/com/x8bit/bitwarden/data/platform/datasource/disk/SettingsDiskSourceImpl.kt b/app/src/main/java/com/x8bit/bitwarden/data/platform/datasource/disk/SettingsDiskSourceImpl.kt index e574c9ba4..e85faacd2 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/platform/datasource/disk/SettingsDiskSourceImpl.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/platform/datasource/disk/SettingsDiskSourceImpl.kt @@ -34,6 +34,7 @@ private const val CLEAR_CLIPBOARD_INTERVAL_KEY = "clearClipboard" private const val INITIAL_AUTOFILL_DIALOG_SHOWN = "addSitePromptShown" private const val HAS_USER_LOGGED_IN_OR_CREATED_AN_ACCOUNT_KEY = "hasUserLoggedInOrCreatedAccount" private const val SHOW_AUTOFILL_SETTING_BADGE = "showAutofillSettingBadge" +private const val SHOW_UNLOCK_SETTING_BADGE = "showUnlockSettingBadge" /** * Primary implementation of [SettingsDiskSource]. @@ -407,4 +408,15 @@ class SettingsDiskSourceImpl( key = SHOW_AUTOFILL_SETTING_BADGE.appendIdentifier(userId), value = showBadge, ) + + override fun getShowUnlockSettingBadge(userId: String): Boolean? = + getBoolean( + key = SHOW_UNLOCK_SETTING_BADGE.appendIdentifier(userId), + ) + + override fun storeShowUnlockSettingBadge(userId: String, showBadge: Boolean?) = + putBoolean( + key = SHOW_UNLOCK_SETTING_BADGE.appendIdentifier(userId), + value = showBadge, + ) } diff --git a/app/src/main/java/com/x8bit/bitwarden/data/platform/repository/SettingsRepository.kt b/app/src/main/java/com/x8bit/bitwarden/data/platform/repository/SettingsRepository.kt index a441c99d9..70cfcf3ed 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/platform/repository/SettingsRepository.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/platform/repository/SettingsRepository.kt @@ -256,14 +256,26 @@ interface SettingsRepository { fun storeUserHasLoggedInValue(userId: String) /** - * Gets whether or not the given [userId] has signalled they want to enable autofill in - * onboarding. + * Gets whether or not the given [userId] has signalled they want to enable autofill + * later, during onboarding. */ fun getShowAutoFillSettingBadge(userId: String): Boolean /** * Stores the given value for whether or not the given [userId] has signalled they want to - * enable autofill in onboarding. + * enable autofill later, during onboarding. */ fun storeShowAutoFillSettingBadge(userId: String, showBadge: Boolean) + + /** + * Gets whether or not the given [userId] has signalled they want to enable unlock options + * later, during onboarding. + */ + fun getShowUnlockSettingBadge(userId: String): Boolean + + /** + * Stores the given value for whether or not the given [userId] has signalled they want to + * set up unlock options later, during onboarding. + */ + fun storeShowUnlockSettingBadge(userId: String, showBadge: Boolean) } diff --git a/app/src/main/java/com/x8bit/bitwarden/data/platform/repository/SettingsRepositoryImpl.kt b/app/src/main/java/com/x8bit/bitwarden/data/platform/repository/SettingsRepositoryImpl.kt index fa8bb0543..65e09e9aa 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/platform/repository/SettingsRepositoryImpl.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/platform/repository/SettingsRepositoryImpl.kt @@ -545,6 +545,13 @@ class SettingsRepositoryImpl( settingsDiskSource.storeShowAutoFillSettingBadge(userId, showBadge) } + override fun getShowUnlockSettingBadge(userId: String): Boolean = + settingsDiskSource.getShowUnlockSettingBadge(userId) ?: false + + override fun storeShowUnlockSettingBadge(userId: String, showBadge: Boolean) { + settingsDiskSource.storeShowUnlockSettingBadge(userId, showBadge) + } + /** * If there isn't already one generated, generate a symmetric sync key that would be used * for communicating via IPC. diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/accountsetup/SetupUnlockViewModel.kt b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/accountsetup/SetupUnlockViewModel.kt index 3dc21468a..41c4d79f2 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/accountsetup/SetupUnlockViewModel.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/accountsetup/SetupUnlockViewModel.kt @@ -95,6 +95,7 @@ class SetupUnlockViewModel @Inject constructor( } private fun handleSetUpLaterClick() { + settingsRepository.storeShowUnlockSettingBadge(state.userId, true) updateOnboardingStatusToNextStep() } diff --git a/app/src/test/java/com/x8bit/bitwarden/data/platform/datasource/disk/SettingsDiskSourceTest.kt b/app/src/test/java/com/x8bit/bitwarden/data/platform/datasource/disk/SettingsDiskSourceTest.kt index 1a544af5a..3b333eff4 100644 --- a/app/src/test/java/com/x8bit/bitwarden/data/platform/datasource/disk/SettingsDiskSourceTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/data/platform/datasource/disk/SettingsDiskSourceTest.kt @@ -1053,4 +1053,28 @@ class SettingsDiskSourceTest { assertTrue(settingsDiskSource.getShowAutoFillSettingBadge(userId = mockUserId)!!) } + + @Test + fun `storeShowUnlockSettingBadge should update SharedPreferences`() { + val mockUserId = "mockUserId" + val showUnlockSettingBadgeKey = + "bwPreferencesStorage:showUnlockSettingBadge_$mockUserId" + settingsDiskSource.storeShowUnlockSettingBadge( + userId = mockUserId, + showBadge = true, + ) + assertTrue(fakeSharedPreferences.getBoolean(showUnlockSettingBadgeKey, false)) + } + + @Test + fun `getShowUnlockSettingBadge should pull value from shared preferences`() { + val mockUserId = "mockUserId" + val showUnlockSettingBadgeKey = + "bwPreferencesStorage:showUnlockSettingBadge_$mockUserId" + fakeSharedPreferences.edit { + putBoolean(showUnlockSettingBadgeKey, true) + } + + assertTrue(settingsDiskSource.getShowUnlockSettingBadge(userId = mockUserId)!!) + } } diff --git a/app/src/test/java/com/x8bit/bitwarden/data/platform/datasource/disk/util/FakeSettingsDiskSource.kt b/app/src/test/java/com/x8bit/bitwarden/data/platform/datasource/disk/util/FakeSettingsDiskSource.kt index 33b659cf6..19b28ce62 100644 --- a/app/src/test/java/com/x8bit/bitwarden/data/platform/datasource/disk/util/FakeSettingsDiskSource.kt +++ b/app/src/test/java/com/x8bit/bitwarden/data/platform/datasource/disk/util/FakeSettingsDiskSource.kt @@ -62,6 +62,7 @@ class FakeSettingsDiskSource : SettingsDiskSource { private val storedAccountBiometricIntegrityValidity = mutableMapOf() private val userSignIns = mutableMapOf() private val userShowAutoFillBadge = mutableMapOf() + private val userShowUnlockBadge = mutableMapOf() override var appLanguage: AppLanguage? = null @@ -292,6 +293,13 @@ class FakeSettingsDiskSource : SettingsDiskSource { userShowAutoFillBadge[userId] = showBadge } + override fun getShowUnlockSettingBadge(userId: String): Boolean? = + userShowUnlockBadge[userId] + + override fun storeShowUnlockSettingBadge(userId: String, showBadge: Boolean?) { + userShowUnlockBadge[userId] = showBadge + } + private fun getMutableScreenCaptureAllowedFlow(userId: String): MutableSharedFlow { return mutableScreenCaptureAllowedFlowMap.getOrPut(userId) { bufferedMutableSharedFlow(replay = 1) diff --git a/app/src/test/java/com/x8bit/bitwarden/data/platform/repository/SettingsRepositoryTest.kt b/app/src/test/java/com/x8bit/bitwarden/data/platform/repository/SettingsRepositoryTest.kt index 252b9aeab..c3a23ac1a 100644 --- a/app/src/test/java/com/x8bit/bitwarden/data/platform/repository/SettingsRepositoryTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/data/platform/repository/SettingsRepositoryTest.kt @@ -1175,6 +1175,33 @@ class SettingsRepositoryTest { fakeSettingsDiskSource.storeShowAutoFillSettingBadge(userId = userId, showBadge = true) assertTrue(settingsRepository.getShowAutoFillSettingBadge(userId = userId)) } + + @Test + fun `storeShowUnlockSettingBadge should store value of false to disk`() { + val userId = "userId" + settingsRepository.storeShowUnlockSettingBadge(userId = userId, showBadge = false) + assertFalse(fakeSettingsDiskSource.getShowUnlockSettingBadge(userId = userId)!!) + } + + @Test + fun `storeShowUnlockSettingBadge should store value of true to disk`() { + val userId = "userId" + settingsRepository.storeShowUnlockSettingBadge(userId = userId, showBadge = true) + assertTrue(fakeSettingsDiskSource.getShowUnlockSettingBadge(userId = userId)!!) + } + + @Test + fun `getUnlockSettingBadge get value of false if does not exist`() { + val userId = "userId" + assertFalse(settingsRepository.getShowUnlockSettingBadge(userId = userId)) + } + + @Test + fun `getShowUnlockSettingBadge should return the value saved to disk`() { + val userId = "userId" + fakeSettingsDiskSource.storeShowUnlockSettingBadge(userId = userId, showBadge = true) + assertTrue(settingsRepository.getShowUnlockSettingBadge(userId = userId)) + } } private const val USER_ID: String = "userId" diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/accountsetup/SetupUnlockViewModelTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/accountsetup/SetupUnlockViewModelTest.kt index 87ec1ffc7..68d7f4034 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/accountsetup/SetupUnlockViewModelTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/accountsetup/SetupUnlockViewModelTest.kt @@ -40,6 +40,7 @@ class SetupUnlockViewModelTest : BaseViewModelTest() { every { isUnlockWithPinEnabled } returns false every { isUnlockWithBiometricsEnabled } returns false every { isAutofillEnabledStateFlow } returns mutableAutofillEnabledStateFlow + every { storeShowUnlockSettingBadge(any(), any()) } just runs } private val biometricsEncryptionManager: BiometricsEncryptionManager = mockk { every { getOrCreateCipher(userId = DEFAULT_USER_ID) } returns CIPHER @@ -80,6 +81,7 @@ class SetupUnlockViewModelTest : BaseViewModelTest() { userId = DEFAULT_USER_ID, status = OnboardingStatus.AUTOFILL_SETUP, ) + settingsRepository.storeShowUnlockSettingBadge(DEFAULT_USER_ID, true) } }