mirror of
https://github.com/bitwarden/android.git
synced 2025-03-15 18:58:59 +03:00
BIT-1093: Setup TOTP auto copy settings (#928)
This commit is contained in:
parent
3fe0950983
commit
7738f75bfb
12 changed files with 213 additions and 10 deletions
|
@ -57,6 +57,7 @@ object AutofillModule {
|
|||
authRepository: AuthRepository,
|
||||
clipboardManager: BitwardenClipboardManager,
|
||||
dispatcherManager: DispatcherManager,
|
||||
settingsRepository: SettingsRepository,
|
||||
vaultRepository: VaultRepository,
|
||||
): AutofillCompletionManager =
|
||||
AutofillCompletionManagerImpl(
|
||||
|
@ -64,6 +65,7 @@ object AutofillModule {
|
|||
autofillParser = autofillParser,
|
||||
clipboardManager = clipboardManager,
|
||||
dispatcherManager = dispatcherManager,
|
||||
settingsRepository = settingsRepository,
|
||||
vaultRepository = vaultRepository,
|
||||
)
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ import com.x8bit.bitwarden.data.autofill.util.toAutofillAppInfo
|
|||
import com.x8bit.bitwarden.data.autofill.util.toAutofillCipherProvider
|
||||
import com.x8bit.bitwarden.data.platform.manager.clipboard.BitwardenClipboardManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
|
||||
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
|
||||
import com.x8bit.bitwarden.data.vault.repository.VaultRepository
|
||||
import com.x8bit.bitwarden.data.vault.repository.model.GenerateTotpResult
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
@ -26,6 +27,7 @@ import kotlinx.coroutines.launch
|
|||
/**
|
||||
* Primary implementation of [AutofillCompletionManager].
|
||||
*/
|
||||
@Suppress("LongParameterList")
|
||||
class AutofillCompletionManagerImpl(
|
||||
private val authRepository: AuthRepository,
|
||||
private val autofillParser: AutofillParser,
|
||||
|
@ -33,6 +35,7 @@ class AutofillCompletionManagerImpl(
|
|||
private val dispatcherManager: DispatcherManager,
|
||||
private val filledDataBuilderProvider: (CipherView) -> FilledDataBuilder =
|
||||
{ createSingleItemFilledDataBuilder(cipherView = it) },
|
||||
private val settingsRepository: SettingsRepository,
|
||||
private val vaultRepository: VaultRepository,
|
||||
) : AutofillCompletionManager {
|
||||
private val mainScope = CoroutineScope(dispatcherManager.main)
|
||||
|
@ -97,9 +100,9 @@ class AutofillCompletionManagerImpl(
|
|||
) {
|
||||
val isPremium = authRepository.userStateFlow.value?.activeAccount?.isPremium == true
|
||||
val totpCode = cipherView.login?.totp
|
||||
val isTotpDisabled = settingsRepository.isAutoCopyTotpDisabled
|
||||
|
||||
// TODO check global TOTP enabled status BIT-1093
|
||||
if (isPremium && totpCode != null) {
|
||||
if (!isTotpDisabled && isPremium && totpCode != null) {
|
||||
val totpResult = vaultRepository.generateTotp(
|
||||
time = DateTime.now(),
|
||||
totpCode = totpCode,
|
||||
|
|
|
@ -81,6 +81,20 @@ interface SettingsDiskSource {
|
|||
value: Boolean?,
|
||||
)
|
||||
|
||||
/**
|
||||
* Retrieves the preference indicating whether the TOTP code should be automatically copied to
|
||||
* the clipboard for autofill suggestions associated with the specified [userId].
|
||||
*/
|
||||
fun getAutoCopyTotpDisabled(userId: String): Boolean?
|
||||
|
||||
/**
|
||||
* Stores the given [isAutomaticallyCopyTotpDisabled] for the given [userId].
|
||||
*/
|
||||
fun storeAutoCopyTotpDisabled(
|
||||
userId: String,
|
||||
isAutomaticallyCopyTotpDisabled: Boolean?,
|
||||
)
|
||||
|
||||
/**
|
||||
* Gets the last time the app synced the vault data for a given [userId] (or `null` if the
|
||||
* vault has never been synced).
|
||||
|
|
|
@ -24,6 +24,7 @@ private const val VAULT_LAST_SYNC_TIME = "$BASE_KEY:vaultLastSyncTime"
|
|||
private const val VAULT_TIMEOUT_ACTION_KEY = "$BASE_KEY:vaultTimeoutAction"
|
||||
private const val VAULT_TIME_IN_MINUTES_KEY = "$BASE_KEY:vaultTimeout"
|
||||
private const val DEFAULT_URI_MATCH_TYPE_KEY = "$BASE_KEY:defaultUriMatch"
|
||||
private const val DISABLE_AUTO_TOTP_COPY_KEY = "$BASE_KEY:disableAutoTotpCopy"
|
||||
private const val DISABLE_AUTOFILL_SAVE_PROMPT_KEY = "$BASE_KEY:autofillDisableSavePrompt"
|
||||
private const val DISABLE_ICON_LOADING_KEY = "$BASE_KEY:disableFavicon"
|
||||
private const val APPROVE_PASSWORDLESS_LOGINS_KEY = "$BASE_KEY:approvePasswordlessLogins"
|
||||
|
@ -137,6 +138,7 @@ class SettingsDiskSourceImpl(
|
|||
storeVaultTimeoutInMinutes(userId = userId, vaultTimeoutInMinutes = null)
|
||||
storeVaultTimeoutAction(userId = userId, vaultTimeoutAction = null)
|
||||
storeDefaultUriMatchType(userId = userId, uriMatchType = null)
|
||||
storeAutoCopyTotpDisabled(userId = userId, isAutomaticallyCopyTotpDisabled = null)
|
||||
storeAutofillSavePromptDisabled(userId = userId, isAutofillSavePromptDisabled = null)
|
||||
storePullToRefreshEnabled(userId = userId, isPullToRefreshEnabled = null)
|
||||
storeInlineAutofillEnabled(userId = userId, isInlineAutofillEnabled = null)
|
||||
|
@ -170,6 +172,19 @@ class SettingsDiskSourceImpl(
|
|||
)
|
||||
}
|
||||
|
||||
override fun getAutoCopyTotpDisabled(userId: String): Boolean? =
|
||||
getBoolean(key = "${DISABLE_AUTO_TOTP_COPY_KEY}_$userId")
|
||||
|
||||
override fun storeAutoCopyTotpDisabled(
|
||||
userId: String,
|
||||
isAutomaticallyCopyTotpDisabled: Boolean?,
|
||||
) {
|
||||
putBoolean(
|
||||
key = "${DISABLE_AUTO_TOTP_COPY_KEY}_$userId",
|
||||
value = isAutomaticallyCopyTotpDisabled,
|
||||
)
|
||||
}
|
||||
|
||||
override fun getLastSyncTime(userId: String): Instant? =
|
||||
getLong(key = "${VAULT_LAST_SYNC_TIME}_$userId")?.let { Instant.ofEpochMilli(it) }
|
||||
|
||||
|
|
|
@ -103,6 +103,11 @@ interface SettingsRepository {
|
|||
*/
|
||||
var isInlineAutofillEnabled: Boolean
|
||||
|
||||
/**
|
||||
* Whether or not the auto copying totp when autofilling is disabled for the current user.
|
||||
*/
|
||||
var isAutoCopyTotpDisabled: Boolean
|
||||
|
||||
/**
|
||||
* Whether or not the autofill save prompt is disabled for the current user.
|
||||
*/
|
||||
|
|
|
@ -201,6 +201,18 @@ class SettingsRepositoryImpl(
|
|||
)
|
||||
}
|
||||
|
||||
override var isAutoCopyTotpDisabled: Boolean
|
||||
get() = activeUserId
|
||||
?.let { settingsDiskSource.getAutoCopyTotpDisabled(userId = it) }
|
||||
?: false
|
||||
set(value) {
|
||||
val userId = activeUserId ?: return
|
||||
settingsDiskSource.storeAutoCopyTotpDisabled(
|
||||
userId = userId,
|
||||
isAutomaticallyCopyTotpDisabled = value,
|
||||
)
|
||||
}
|
||||
|
||||
override var isAutofillSavePromptDisabled: Boolean
|
||||
get() = activeUserId
|
||||
?.let { settingsDiskSource.getAutofillSavePromptDisabled(userId = it) }
|
||||
|
|
|
@ -7,7 +7,6 @@ import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
|
|||
import com.x8bit.bitwarden.data.platform.repository.model.UriMatchType
|
||||
import com.x8bit.bitwarden.ui.platform.base.BaseViewModel
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.Text
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.asText
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
@ -31,7 +30,7 @@ class AutoFillViewModel @Inject constructor(
|
|||
?: AutoFillState(
|
||||
isAskToAddLoginEnabled = !settingsRepository.isAutofillSavePromptDisabled,
|
||||
isAutoFillServicesEnabled = settingsRepository.isAutofillEnabledStateFlow.value,
|
||||
isCopyTotpAutomaticallyEnabled = false,
|
||||
isCopyTotpAutomaticallyEnabled = !settingsRepository.isAutoCopyTotpDisabled,
|
||||
isUseInlineAutoFillEnabled = settingsRepository.isInlineAutofillEnabled,
|
||||
defaultUriMatchType = settingsRepository.defaultUriMatchType,
|
||||
),
|
||||
|
@ -84,8 +83,7 @@ class AutoFillViewModel @Inject constructor(
|
|||
private fun handleCopyTotpAutomaticallyClick(
|
||||
action: AutoFillAction.CopyTotpAutomaticallyClick,
|
||||
) {
|
||||
// TODO BIT-1093: Persist selection
|
||||
sendEvent(AutoFillEvent.ShowToast("Not yet implemented.".asText()))
|
||||
settingsRepository.isAutoCopyTotpDisabled = !action.isEnabled
|
||||
mutableStateFlow.update { it.copy(isCopyTotpAutomaticallyEnabled = action.isEnabled) }
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import com.x8bit.bitwarden.data.autofill.util.getAutofillAssistStructureOrNull
|
|||
import com.x8bit.bitwarden.data.autofill.util.toAutofillAppInfo
|
||||
import com.x8bit.bitwarden.data.platform.base.FakeDispatcherManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.clipboard.BitwardenClipboardManager
|
||||
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
|
||||
import com.x8bit.bitwarden.data.vault.repository.VaultRepository
|
||||
import com.x8bit.bitwarden.data.vault.repository.model.GenerateTotpResult
|
||||
import io.mockk.coEvery
|
||||
|
@ -63,6 +64,7 @@ class AutofillCompletionManagerTest {
|
|||
private val filledDataBuilder: FilledDataBuilder = mockk()
|
||||
private val filledPartition: FilledPartition = mockk()
|
||||
private val mockIntent: Intent = mockk()
|
||||
private val settingsRepository: SettingsRepository = mockk()
|
||||
private val resultIntent: Intent = mockk()
|
||||
private val toast: Toast = mockk {
|
||||
every { show() } just runs
|
||||
|
@ -76,6 +78,7 @@ class AutofillCompletionManagerTest {
|
|||
clipboardManager = clipboardManager,
|
||||
dispatcherManager = dispatcherManager,
|
||||
filledDataBuilderProvider = { filledDataBuilder },
|
||||
settingsRepository = settingsRepository,
|
||||
vaultRepository = vaultRepository,
|
||||
)
|
||||
|
||||
|
@ -239,6 +242,7 @@ class AutofillCompletionManagerTest {
|
|||
autofillAppInfo = autofillAppInfo,
|
||||
)
|
||||
} returns dataset
|
||||
every { settingsRepository.isAutoCopyTotpDisabled } returns false
|
||||
every { createAutofillSelectionResultIntent(dataset = dataset) } returns resultIntent
|
||||
coEvery {
|
||||
vaultRepository.generateTotp(
|
||||
|
@ -278,6 +282,7 @@ class AutofillCompletionManagerTest {
|
|||
authIntentSender = null,
|
||||
autofillAppInfo = autofillAppInfo,
|
||||
)
|
||||
settingsRepository.isAutoCopyTotpDisabled
|
||||
createAutofillSelectionResultIntent(dataset = dataset)
|
||||
Toast.makeText(
|
||||
context,
|
||||
|
@ -319,6 +324,7 @@ class AutofillCompletionManagerTest {
|
|||
autofillAppInfo = autofillAppInfo,
|
||||
)
|
||||
} returns dataset
|
||||
every { settingsRepository.isAutoCopyTotpDisabled } returns false
|
||||
every { createAutofillSelectionResultIntent(dataset = dataset) } returns resultIntent
|
||||
coEvery {
|
||||
vaultRepository.generateTotp(
|
||||
|
@ -350,6 +356,7 @@ class AutofillCompletionManagerTest {
|
|||
authIntentSender = null,
|
||||
autofillAppInfo = autofillAppInfo,
|
||||
)
|
||||
settingsRepository.isAutoCopyTotpDisabled
|
||||
createAutofillSelectionResultIntent(dataset = dataset)
|
||||
}
|
||||
coVerify {
|
||||
|
@ -385,6 +392,7 @@ class AutofillCompletionManagerTest {
|
|||
autofillAppInfo = autofillAppInfo,
|
||||
)
|
||||
} returns dataset
|
||||
every { settingsRepository.isAutoCopyTotpDisabled } returns false
|
||||
every { createAutofillSelectionResultIntent(dataset = dataset) } returns resultIntent
|
||||
mutableUserStateFlow.value = mockk {
|
||||
every { activeAccount.isPremium } returns true
|
||||
|
@ -400,6 +408,7 @@ class AutofillCompletionManagerTest {
|
|||
activity.finish()
|
||||
}
|
||||
verify {
|
||||
settingsRepository.isAutoCopyTotpDisabled
|
||||
activity.intent
|
||||
mockIntent.getAutofillAssistStructureOrNull()
|
||||
autofillParser.parse(
|
||||
|
@ -410,6 +419,7 @@ class AutofillCompletionManagerTest {
|
|||
authIntentSender = null,
|
||||
autofillAppInfo = autofillAppInfo,
|
||||
)
|
||||
settingsRepository.isAutoCopyTotpDisabled
|
||||
createAutofillSelectionResultIntent(dataset = dataset)
|
||||
}
|
||||
coVerify {
|
||||
|
@ -441,6 +451,7 @@ class AutofillCompletionManagerTest {
|
|||
autofillAppInfo = autofillAppInfo,
|
||||
)
|
||||
} returns dataset
|
||||
every { settingsRepository.isAutoCopyTotpDisabled } returns false
|
||||
every { createAutofillSelectionResultIntent(dataset = dataset) } returns resultIntent
|
||||
mutableUserStateFlow.value = mockk {
|
||||
every { activeAccount.isPremium } returns false
|
||||
|
@ -466,6 +477,65 @@ class AutofillCompletionManagerTest {
|
|||
authIntentSender = null,
|
||||
autofillAppInfo = autofillAppInfo,
|
||||
)
|
||||
settingsRepository.isAutoCopyTotpDisabled
|
||||
createAutofillSelectionResultIntent(dataset = dataset)
|
||||
}
|
||||
coVerify {
|
||||
filledDataBuilder.build(autofillRequest = fillableRequest)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `completeAutofill when filled partition and totp copy disabled should build a dataset, place it in a result Intent, and finish the Activity`() {
|
||||
val filledData: FilledData = mockk {
|
||||
every { filledPartitions } returns listOf(filledPartition)
|
||||
}
|
||||
every { activity.intent } returns mockIntent
|
||||
every { mockIntent.getAutofillAssistStructureOrNull() } returns assistStructure
|
||||
every {
|
||||
autofillParser.parse(
|
||||
autofillAppInfo = autofillAppInfo,
|
||||
assistStructure = assistStructure,
|
||||
)
|
||||
} returns fillableRequest
|
||||
every { cipherView.login?.totp } returns TOTP_CODE
|
||||
coEvery {
|
||||
filledDataBuilder.build(autofillRequest = fillableRequest)
|
||||
} returns filledData
|
||||
every {
|
||||
filledPartition.buildDataset(
|
||||
authIntentSender = null,
|
||||
autofillAppInfo = autofillAppInfo,
|
||||
)
|
||||
} returns dataset
|
||||
every { settingsRepository.isAutoCopyTotpDisabled } returns true
|
||||
every { createAutofillSelectionResultIntent(dataset = dataset) } returns resultIntent
|
||||
mutableUserStateFlow.value = mockk {
|
||||
every { activeAccount.isPremium } returns true
|
||||
}
|
||||
|
||||
autofillCompletionManager.completeAutofill(
|
||||
activity = activity,
|
||||
cipherView = cipherView,
|
||||
)
|
||||
|
||||
verify {
|
||||
activity.setResult(Activity.RESULT_OK, resultIntent)
|
||||
activity.finish()
|
||||
}
|
||||
verify {
|
||||
activity.intent
|
||||
mockIntent.getAutofillAssistStructureOrNull()
|
||||
autofillParser.parse(
|
||||
autofillAppInfo = autofillAppInfo,
|
||||
assistStructure = assistStructure,
|
||||
)
|
||||
filledPartition.buildDataset(
|
||||
authIntentSender = null,
|
||||
autofillAppInfo = autofillAppInfo,
|
||||
)
|
||||
settingsRepository.isAutoCopyTotpDisabled
|
||||
createAutofillSelectionResultIntent(dataset = dataset)
|
||||
}
|
||||
coVerify {
|
||||
|
|
|
@ -107,6 +107,10 @@ class SettingsDiskSourceTest {
|
|||
userId = userId,
|
||||
uriMatchType = UriMatchType.REGULAR_EXPRESSION,
|
||||
)
|
||||
settingsDiskSource.storeAutoCopyTotpDisabled(
|
||||
userId = userId,
|
||||
isAutomaticallyCopyTotpDisabled = true,
|
||||
)
|
||||
settingsDiskSource.storeAutofillSavePromptDisabled(
|
||||
userId = userId,
|
||||
isAutofillSavePromptDisabled = true,
|
||||
|
@ -147,6 +151,7 @@ class SettingsDiskSourceTest {
|
|||
assertNull(settingsDiskSource.getVaultTimeoutInMinutes(userId = userId))
|
||||
assertNull(settingsDiskSource.getVaultTimeoutAction(userId = userId))
|
||||
assertNull(settingsDiskSource.getDefaultUriMatchType(userId = userId))
|
||||
assertNull(settingsDiskSource.getAutoCopyTotpDisabled(userId = userId))
|
||||
assertNull(settingsDiskSource.getAutofillSavePromptDisabled(userId = userId))
|
||||
assertNull(settingsDiskSource.getPullToRefreshEnabled(userId = userId))
|
||||
assertNull(settingsDiskSource.getInlineAutofillEnabled(userId = userId))
|
||||
|
@ -561,6 +566,50 @@ class SettingsDiskSourceTest {
|
|||
assertFalse(fakeSharedPreferences.contains(defaultUriMatchTypeKey))
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `getAutoCopyTotpDisabled when values are present should pull from SharedPreferences`() {
|
||||
val disableAutoTotpCopyBaseKey = "bwPreferencesStorage:disableAutoTotpCopy"
|
||||
val mockUserId = "mockUserId"
|
||||
val disableAutoTotpCopyKey = "${disableAutoTotpCopyBaseKey}_$mockUserId"
|
||||
fakeSharedPreferences
|
||||
.edit {
|
||||
putBoolean(disableAutoTotpCopyKey, true)
|
||||
}
|
||||
assertEquals(true, settingsDiskSource.getAutoCopyTotpDisabled(userId = mockUserId))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getAutoCopyTotpDisabled when values are absent should return null`() {
|
||||
val mockUserId = "mockUserId"
|
||||
assertNull(settingsDiskSource.getAutoCopyTotpDisabled(userId = mockUserId))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `storeAutoCopyTotpDisabled for non-null values should update SharedPreferences`() {
|
||||
val disableAutoTotpCopyBaseKey = "bwPreferencesStorage:disableAutoTotpCopy"
|
||||
val mockUserId = "mockUserId"
|
||||
val disableAutoTotpCopyKey = "${disableAutoTotpCopyBaseKey}_$mockUserId"
|
||||
settingsDiskSource.storeAutoCopyTotpDisabled(
|
||||
userId = mockUserId,
|
||||
isAutomaticallyCopyTotpDisabled = true,
|
||||
)
|
||||
assertTrue(fakeSharedPreferences.getBoolean(disableAutoTotpCopyKey, false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `storeAutoCopyTotpDisabled for null values should clear SharedPreferences`() {
|
||||
val disableAutoTotpCopyBaseKey = "bwPreferencesStorage:disableAutoTotpCopy"
|
||||
val mockUserId = "mockUserId"
|
||||
val disableAutoTotpCopyKey = "${disableAutoTotpCopyBaseKey}_$mockUserId"
|
||||
fakeSharedPreferences.edit { putBoolean(disableAutoTotpCopyKey, false) }
|
||||
settingsDiskSource.storeAutoCopyTotpDisabled(
|
||||
userId = mockUserId,
|
||||
isAutomaticallyCopyTotpDisabled = null,
|
||||
)
|
||||
assertFalse(fakeSharedPreferences.contains(disableAutoTotpCopyKey))
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `getAutofillSavePromptDisabled when values are present should pull from SharedPreferences`() {
|
||||
|
|
|
@ -45,6 +45,7 @@ class FakeSettingsDiskSource : SettingsDiskSource {
|
|||
private val storedVaultTimeoutInMinutes = mutableMapOf<String, Int?>()
|
||||
private val storedUriMatchTypes = mutableMapOf<String, UriMatchType?>()
|
||||
private val storedClearClipboardFrequency = mutableMapOf<String, Int?>()
|
||||
private val storedDisableAutoTotpCopy = mutableMapOf<String, Boolean?>()
|
||||
private val storedDisableAutofillSavePrompt = mutableMapOf<String, Boolean?>()
|
||||
private val storedPullToRefreshEnabled = mutableMapOf<String, Boolean?>()
|
||||
private val storedInlineAutofillEnabled = mutableMapOf<String, Boolean?>()
|
||||
|
@ -124,6 +125,7 @@ class FakeSettingsDiskSource : SettingsDiskSource {
|
|||
storedVaultTimeoutActions.remove(userId)
|
||||
storedVaultTimeoutInMinutes.remove(userId)
|
||||
storedUriMatchTypes.remove(userId)
|
||||
storedDisableAutoTotpCopy.remove(userId)
|
||||
storedDisableAutofillSavePrompt.remove(userId)
|
||||
storedPullToRefreshEnabled.remove(userId)
|
||||
storedInlineAutofillEnabled.remove(userId)
|
||||
|
@ -194,6 +196,16 @@ class FakeSettingsDiskSource : SettingsDiskSource {
|
|||
storedUriMatchTypes[userId] = uriMatchType
|
||||
}
|
||||
|
||||
override fun getAutoCopyTotpDisabled(userId: String): Boolean? =
|
||||
storedDisableAutoTotpCopy[userId]
|
||||
|
||||
override fun storeAutoCopyTotpDisabled(
|
||||
userId: String,
|
||||
isAutomaticallyCopyTotpDisabled: Boolean?,
|
||||
) {
|
||||
storedDisableAutoTotpCopy[userId] = isAutomaticallyCopyTotpDisabled
|
||||
}
|
||||
|
||||
override fun getAutofillSavePromptDisabled(userId: String): Boolean? =
|
||||
storedDisableAutofillSavePrompt[userId]
|
||||
|
||||
|
|
|
@ -473,6 +473,24 @@ class SettingsRepositoryTest {
|
|||
assertTrue(fakeSettingsDiskSource.getInlineAutofillEnabled(userId = userId)!!)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `isAutoCopyTotpDisabled should pull from and update SettingsDiskSource`() {
|
||||
val userId = "userId"
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
assertFalse(settingsRepository.isAutoCopyTotpDisabled)
|
||||
|
||||
// Updates to the disk source change the repository value.
|
||||
fakeSettingsDiskSource.storeAutoCopyTotpDisabled(
|
||||
userId = userId,
|
||||
isAutomaticallyCopyTotpDisabled = true,
|
||||
)
|
||||
assertTrue(settingsRepository.isAutoCopyTotpDisabled)
|
||||
|
||||
// Updates to the repository change the disk source value
|
||||
settingsRepository.isAutoCopyTotpDisabled = false
|
||||
assertFalse(fakeSettingsDiskSource.getAutoCopyTotpDisabled(userId = userId)!!)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `isAutofillSavePromptDisabled should pull from and update SettingsDiskSource`() {
|
||||
val userId = "userId"
|
||||
|
|
|
@ -5,7 +5,6 @@ import app.cash.turbine.test
|
|||
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
|
||||
import com.x8bit.bitwarden.data.platform.repository.model.UriMatchType
|
||||
import com.x8bit.bitwarden.ui.platform.base.BaseViewModelTest
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.asText
|
||||
import io.mockk.every
|
||||
import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
|
@ -22,6 +21,8 @@ class AutoFillViewModelTest : BaseViewModelTest() {
|
|||
private val settingsRepository: SettingsRepository = mockk() {
|
||||
every { isInlineAutofillEnabled } returns true
|
||||
every { isInlineAutofillEnabled = any() } just runs
|
||||
every { isAutoCopyTotpDisabled } returns true
|
||||
every { isAutoCopyTotpDisabled = any() } just runs
|
||||
every { isAutofillSavePromptDisabled } returns true
|
||||
every { isAutofillSavePromptDisabled = any() } just runs
|
||||
every { defaultUriMatchType } returns UriMatchType.DOMAIN
|
||||
|
@ -117,19 +118,23 @@ class AutoFillViewModelTest : BaseViewModelTest() {
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `on CopyTotpAutomaticallyClick should update the isCopyTotpAutomaticallyEnabled state`() =
|
||||
fun `on CopyTotpAutomaticallyClick should update the isCopyTotpAutomaticallyEnabled state and save new value to settings`() =
|
||||
runTest {
|
||||
val viewModel = createViewModel()
|
||||
val isEnabled = true
|
||||
viewModel.trySendAction(AutoFillAction.CopyTotpAutomaticallyClick(isEnabled))
|
||||
viewModel.eventFlow.test {
|
||||
viewModel.trySendAction(AutoFillAction.CopyTotpAutomaticallyClick(isEnabled))
|
||||
assertEquals(AutoFillEvent.ShowToast("Not yet implemented.".asText()), awaitItem())
|
||||
expectNoEvents()
|
||||
}
|
||||
assertEquals(
|
||||
DEFAULT_STATE.copy(isCopyTotpAutomaticallyEnabled = isEnabled),
|
||||
viewModel.stateFlow.value,
|
||||
)
|
||||
|
||||
// The UI enables the value, so the value gets flipped to save it as a "disabled" value.
|
||||
verify { settingsRepository.isAutoCopyTotpDisabled = !isEnabled }
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Add table
Reference in a new issue