BIT-2335: Onboarding flow (data) (#1346)

This commit is contained in:
Ramsey Smith 2024-05-09 10:44:30 -06:00 committed by Álison Fernandes
parent 74648c17bc
commit 1e4e92a43b
9 changed files with 109 additions and 0 deletions

View file

@ -723,6 +723,7 @@ class AuthRepositoryImpl(
}
is RegisterResponseJson.Success -> {
settingsRepository.hasUserLoggedInOrCreatedAccount = true
RegisterResult.Success(captchaToken = it.captchaBypassToken)
}
@ -1280,6 +1281,7 @@ class AuthRepositoryImpl(
refreshToken = loginResponse.refreshToken,
),
)
settingsRepository.hasUserLoggedInOrCreatedAccount = true
authDiskSource.userState = userStateJson
loginResponse.key?.let {
// Only set the value if it's present, since we may have set it already

View file

@ -58,6 +58,16 @@ interface SettingsDiskSource {
*/
val isCrashLoggingEnabledFlow: Flow<Boolean?>
/**
* The current status if a user has logged in or created an account.
*/
var hasUserLoggedInOrCreatedAccount: Boolean?
/**
* Emits updates that track [hasUserLoggedInOrCreatedAccount].
*/
val hasUserLoggedInOrCreatedAccountFlow: Flow<Boolean?>
/**
* Clears all the settings data for the given user.
*/

View file

@ -32,6 +32,7 @@ private const val ACCOUNT_BIOMETRIC_INTEGRITY_VALID_KEY = "accountBiometricInteg
private const val CRASH_LOGGING_ENABLED_KEY = "crashLoggingEnabled"
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"
/**
* Primary implementation of [SettingsDiskSource].
@ -59,6 +60,8 @@ class SettingsDiskSourceImpl(
private val mutableIsCrashLoggingEnabledFlow = bufferedMutableSharedFlow<Boolean?>()
private val mutableHasUserLoggedInOrCreatedAccountFlow = bufferedMutableSharedFlow<Boolean?>()
private val mutableScreenCaptureAllowedFlowMap =
mutableMapOf<String, MutableSharedFlow<Boolean?>>()
@ -129,6 +132,17 @@ class SettingsDiskSourceImpl(
get() = mutableIsCrashLoggingEnabledFlow
.onSubscription { emit(getBoolean(CRASH_LOGGING_ENABLED_KEY)) }
override var hasUserLoggedInOrCreatedAccount: Boolean?
get() = getBoolean(key = HAS_USER_LOGGED_IN_OR_CREATED_AN_ACCOUNT_KEY)
set(value) {
putBoolean(key = HAS_USER_LOGGED_IN_OR_CREATED_AN_ACCOUNT_KEY, value = value)
mutableHasUserLoggedInOrCreatedAccountFlow.tryEmit(value)
}
override val hasUserLoggedInOrCreatedAccountFlow: Flow<Boolean?>
get() = mutableHasUserLoggedInOrCreatedAccountFlow
.onSubscription { emit(getBoolean(HAS_USER_LOGGED_IN_OR_CREATED_AN_ACCOUNT_KEY)) }
override fun clearData(userId: String) {
storeVaultTimeoutInMinutes(userId = userId, vaultTimeoutInMinutes = null)
storeVaultTimeoutAction(userId = userId, vaultTimeoutAction = null)

View file

@ -72,6 +72,16 @@ interface SettingsRepository {
*/
val isCrashLoggingEnabledFlow: Flow<Boolean>
/**
* The current status if a user has logged in or created an account.
*/
var hasUserLoggedInOrCreatedAccount: Boolean
/**
* Emits updates that track the [hasUserLoggedInOrCreatedAccount] value.
*/
val hasUserLoggedInOrCreatedAccountFlow: Flow<Boolean>
/**
* The [VaultTimeout] for the current user.
*/

View file

@ -145,6 +145,22 @@ class SettingsRepositoryImpl(
initialValue = isCrashLoggingEnabled,
)
override var hasUserLoggedInOrCreatedAccount: Boolean
get() = settingsDiskSource.hasUserLoggedInOrCreatedAccount ?: false
set(value) {
settingsDiskSource.hasUserLoggedInOrCreatedAccount = value
}
override val hasUserLoggedInOrCreatedAccountFlow: Flow<Boolean>
get() = settingsDiskSource
.hasUserLoggedInOrCreatedAccountFlow
.map { it ?: hasUserLoggedInOrCreatedAccount }
.stateIn(
scope = unconfinedScope,
started = SharingStarted.Eagerly,
initialValue = hasUserLoggedInOrCreatedAccount,
)
override var vaultTimeout: VaultTimeout
get() = activeUserId
?.let {

View file

@ -149,6 +149,7 @@ class AuthRepositoryTest {
}
private val settingsRepository: SettingsRepository = mockk {
every { setDefaultsIfNecessary(any()) } just runs
every { hasUserLoggedInOrCreatedAccount = true } just runs
}
private val authSdkSource = mockk<AuthSdkSource> {
coEvery {

View file

@ -285,6 +285,33 @@ class SettingsDiskSourceTest {
)
}
@Test
fun `hasUserLoggedInOrCreatedAccount should pull from and update SharedPreferences`() {
val hasUserLoggedInOrCreatedAccount = "bwPreferencesStorage:hasUserLoggedInOrCreatedAccount"
val expected = false
assertNull(settingsDiskSource.hasUserLoggedInOrCreatedAccount)
fakeSharedPreferences
.edit {
putBoolean(
hasUserLoggedInOrCreatedAccount,
expected,
)
}
assertEquals(
expected,
settingsDiskSource.hasUserLoggedInOrCreatedAccount,
)
settingsDiskSource.hasUserLoggedInOrCreatedAccount = true
assertTrue(
fakeSharedPreferences.getBoolean(
hasUserLoggedInOrCreatedAccount, false,
),
)
}
@Test
fun `appTheme when values are present should pull from SharedPreferences`() {
val appThemeBaseKey = "bwPreferencesStorage:appTheme"

View file

@ -36,6 +36,9 @@ class FakeSettingsDiskSource : SettingsDiskSource {
private val mutableIsCrashLoggingEnabled =
bufferedMutableSharedFlow<Boolean?>()
private val mutableHasUserLoggedInOrCreatedAccount =
bufferedMutableSharedFlow<Boolean?>()
private val mutableScreenCaptureAllowedFlowMap =
mutableMapOf<String, MutableSharedFlow<Boolean?>>()
@ -52,6 +55,7 @@ class FakeSettingsDiskSource : SettingsDiskSource {
private val storedBlockedAutofillUris = mutableMapOf<String, List<String>?>()
private var storedIsIconLoadingDisabled: Boolean? = null
private var storedIsCrashLoggingEnabled: Boolean? = null
private var storedHasUserLoggedInOrCreatedAccount: Boolean? = null
private var storedInitialAutofillDialogShown: Boolean? = null
private val storedScreenCaptureAllowed = mutableMapOf<String, Boolean?>()
private var storedSystemBiometricIntegritySource: String? = null
@ -107,6 +111,18 @@ class FakeSettingsDiskSource : SettingsDiskSource {
emit(isCrashLoggingEnabled)
}
override var hasUserLoggedInOrCreatedAccount: Boolean?
get() = storedHasUserLoggedInOrCreatedAccount
set(value) {
storedHasUserLoggedInOrCreatedAccount = value
mutableHasUserLoggedInOrCreatedAccount.tryEmit(value)
}
override val hasUserLoggedInOrCreatedAccountFlow: Flow<Boolean?>
get() = mutableHasUserLoggedInOrCreatedAccount.onSubscription {
emit(hasUserLoggedInOrCreatedAccount)
}
override fun getAccountBiometricIntegrityValidity(
userId: String,
systemBioIntegrityState: String,

View file

@ -273,6 +273,19 @@ class SettingsRepositoryTest {
assertTrue(fakeSettingsDiskSource.isCrashLoggingEnabled!!)
}
@Test
fun `hasUserLoggedInOrCreatedAccount should pull from and update SettingsDiskSource`() {
assertFalse(settingsRepository.hasUserLoggedInOrCreatedAccount)
// Updates to the disk source change the repository value.
fakeSettingsDiskSource.hasUserLoggedInOrCreatedAccount = false
assertFalse(settingsRepository.hasUserLoggedInOrCreatedAccount)
// Updates to the repository change the disk source value
settingsRepository.hasUserLoggedInOrCreatedAccount = true
assertTrue(fakeSettingsDiskSource.hasUserLoggedInOrCreatedAccount!!)
}
@Test
fun `appTheme should pull from and update SettingsDiskSource`() {
fakeAuthDiskSource.userState = null