PM-13847: Totp click on search should go directly to edit screen (#4123)

This commit is contained in:
David Perez 2024-10-21 14:48:54 -05:00 committed by GitHub
parent 27beb25bf7
commit b82614e5fa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 34 additions and 8 deletions

View file

@ -17,6 +17,7 @@ import com.x8bit.bitwarden.data.platform.manager.clipboard.BitwardenClipboardMan
import com.x8bit.bitwarden.data.platform.manager.event.OrganizationEventManager
import com.x8bit.bitwarden.data.platform.manager.model.OrganizationEvent
import com.x8bit.bitwarden.data.platform.manager.util.toAutofillSelectionDataOrNull
import com.x8bit.bitwarden.data.platform.manager.util.toTotpDataOrNull
import com.x8bit.bitwarden.data.platform.repository.EnvironmentRepository
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
import com.x8bit.bitwarden.data.platform.repository.model.DataState
@ -46,6 +47,7 @@ import com.x8bit.bitwarden.ui.vault.feature.vault.model.VaultFilterData
import com.x8bit.bitwarden.ui.vault.feature.vault.model.VaultFilterType
import com.x8bit.bitwarden.ui.vault.feature.vault.util.toFilteredList
import com.x8bit.bitwarden.ui.vault.feature.vault.util.toVaultFilterData
import com.x8bit.bitwarden.ui.vault.model.TotpData
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
@ -82,9 +84,7 @@ class SearchViewModel @Inject constructor(
?: run {
val searchType = SearchArgs(savedStateHandle).type
val userState = requireNotNull(authRepo.userStateFlow.value)
val autofillSelectionData = specialCircumstanceManager
.specialCircumstance
?.toAutofillSelectionDataOrNull()
val specialCircumstance = specialCircumstanceManager.specialCircumstance
SearchState(
searchTerm = "",
@ -102,7 +102,8 @@ class SearchViewModel @Inject constructor(
baseWebSendUrl = environmentRepo.environment.environmentUrlData.baseWebSendUrl,
baseIconUrl = environmentRepo.environment.environmentUrlData.baseIconUrl,
isIconLoadingDisabled = settingsRepo.isIconLoadingDisabled,
autofillSelectionData = autofillSelectionData,
autofillSelectionData = specialCircumstance?.toAutofillSelectionDataOrNull(),
totpData = specialCircumstance?.toTotpDataOrNull(),
hasMasterPassword = userState.activeAccount.hasMasterPassword,
isPremium = userState.activeAccount.isPremium,
)
@ -151,7 +152,11 @@ class SearchViewModel @Inject constructor(
private fun handleItemClick(action: SearchAction.ItemClick) {
val event = when (state.searchType) {
is SearchTypeData.Vault -> {
SearchEvent.NavigateToViewCipher(cipherId = action.itemId)
if (state.isTotp) {
SearchEvent.NavigateToEditCipher(cipherId = action.itemId)
} else {
SearchEvent.NavigateToViewCipher(cipherId = action.itemId)
}
}
is SearchTypeData.Sends -> {
@ -718,7 +723,8 @@ data class SearchState(
val baseIconUrl: String,
val isIconLoadingDisabled: Boolean,
// Internal
val autofillSelectionData: AutofillSelectionData? = null,
val autofillSelectionData: AutofillSelectionData?,
val totpData: TotpData?,
val hasMasterPassword: Boolean,
val isPremium: Boolean,
) : Parcelable {
@ -729,6 +735,11 @@ data class SearchState(
val isAutofill: Boolean
get() = autofillSelectionData != null
/**
* Whether or not this represents a listing screen for totp.
*/
val isTotp: Boolean get() = totpData != null
/**
* Represents the specific view states for the search screen.
*/

View file

@ -890,6 +890,8 @@ private val DEFAULT_STATE: SearchState = SearchState(
baseIconUrl = "www.test.com",
isIconLoadingDisabled = false,
hasMasterPassword = true,
totpData = null,
autofillSelectionData = null,
isPremium = true,
)

View file

@ -9,7 +9,6 @@ import com.bitwarden.vault.LoginUriView
import com.x8bit.bitwarden.R
import com.x8bit.bitwarden.data.auth.datasource.disk.model.OnboardingStatus
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
import com.x8bit.bitwarden.data.platform.manager.model.FirstTimeState
import com.x8bit.bitwarden.data.auth.repository.model.UserState
import com.x8bit.bitwarden.data.auth.repository.model.ValidatePasswordResult
import com.x8bit.bitwarden.data.autofill.accessibility.manager.AccessibilitySelectionManager
@ -23,6 +22,7 @@ import com.x8bit.bitwarden.data.platform.manager.SpecialCircumstanceManager
import com.x8bit.bitwarden.data.platform.manager.SpecialCircumstanceManagerImpl
import com.x8bit.bitwarden.data.platform.manager.clipboard.BitwardenClipboardManager
import com.x8bit.bitwarden.data.platform.manager.event.OrganizationEventManager
import com.x8bit.bitwarden.data.platform.manager.model.FirstTimeState
import com.x8bit.bitwarden.data.platform.manager.model.OrganizationEvent
import com.x8bit.bitwarden.data.platform.manager.model.SpecialCircumstance
import com.x8bit.bitwarden.data.platform.repository.EnvironmentRepository
@ -193,7 +193,7 @@ class SearchViewModelTest : BaseViewModelTest() {
}
@Test
fun `ItemClick for vault item should emit NavigateToViewCipher`() = runTest {
fun `ItemClick for vault item without totp should emit NavigateToViewCipher`() = runTest {
val viewModel = createViewModel()
viewModel.eventFlow.test {
viewModel.trySendAction(SearchAction.ItemClick(itemId = "mock"))
@ -201,6 +201,17 @@ class SearchViewModelTest : BaseViewModelTest() {
}
}
@Test
fun `ItemClick for vault item with totp should emit NavigateToEditCipher`() = runTest {
specialCircumstanceManager.specialCircumstance =
SpecialCircumstance.AddTotpLoginItem(mockk())
val viewModel = createViewModel()
viewModel.eventFlow.test {
viewModel.trySendAction(SearchAction.ItemClick(itemId = "mock"))
assertEquals(SearchEvent.NavigateToEditCipher(cipherId = "mock"), awaitItem())
}
}
@Test
fun `ItemClick for send item should emit NavigateToEditSend`() = runTest {
val viewModel = createViewModel(DEFAULT_STATE.copy(searchType = SearchTypeData.Sends.All))
@ -1515,6 +1526,8 @@ private val DEFAULT_STATE: SearchState = SearchState(
baseIconUrl = "https://vault.bitwarden.com/icons",
isIconLoadingDisabled = false,
hasMasterPassword = true,
totpData = null,
autofillSelectionData = null,
isPremium = true,
)