BIT-971: Adding urls for two step login and change master password in… (#790)

This commit is contained in:
Joshua Queen 2024-01-26 15:30:43 -05:00 committed by Álison Fernandes
parent d938a7da70
commit a4e99745bc
4 changed files with 103 additions and 22 deletions

View file

@ -94,6 +94,14 @@ fun AccountSecurityScreen(
AccountSecurityEvent.NavigateToPendingRequests -> onNavigateToPendingRequests()
is AccountSecurityEvent.NavigateToTwoStepLogin -> {
intentManager.launchUri(event.url.toUri())
}
is AccountSecurityEvent.NavigateToChangeMasterPassword -> {
intentManager.launchUri(event.url.toUri())
}
is AccountSecurityEvent.ShowToast -> {
Toast.makeText(context, event.text(resources), Toast.LENGTH_SHORT).show()
}

View file

@ -5,9 +5,11 @@ import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.viewModelScope
import com.x8bit.bitwarden.R
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
import com.x8bit.bitwarden.data.platform.repository.EnvironmentRepository
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
import com.x8bit.bitwarden.data.platform.repository.model.VaultTimeout
import com.x8bit.bitwarden.data.platform.repository.model.VaultTimeoutAction
import com.x8bit.bitwarden.data.platform.repository.util.baseWebVaultUrlOrDefault
import com.x8bit.bitwarden.data.vault.repository.VaultRepository
import com.x8bit.bitwarden.ui.platform.base.BaseViewModel
import com.x8bit.bitwarden.ui.platform.base.util.Text
@ -30,6 +32,7 @@ class AccountSecurityViewModel @Inject constructor(
private val authRepository: AuthRepository,
private val vaultRepository: VaultRepository,
private val settingsRepository: SettingsRepository,
private val environmentRepository: EnvironmentRepository,
savedStateHandle: SavedStateHandle,
) : BaseViewModel<AccountSecurityState, AccountSecurityEvent, AccountSecurityAction>(
initialState = savedStateHandle[KEY_STATE]
@ -43,6 +46,14 @@ class AccountSecurityViewModel @Inject constructor(
vaultTimeoutAction = settingsRepository.vaultTimeoutAction,
),
) {
private val webSettingsUrl: String
get() {
val baseUrl = environmentRepository
.environment
.environmentUrlData
.baseWebVaultUrlOrDefault
return "$baseUrl/#/settings"
}
init {
stateFlow
@ -90,8 +101,7 @@ class AccountSecurityViewModel @Inject constructor(
private fun handleBackClick() = sendEvent(AccountSecurityEvent.NavigateBack)
private fun handleChangeMasterPasswordClick() {
// TODO BIT-971: Add Leaving app Dialog
sendEvent(AccountSecurityEvent.ShowToast("Not yet implemented.".asText()))
sendEvent(AccountSecurityEvent.NavigateToChangeMasterPassword(webSettingsUrl))
}
private fun handleConfirmLogoutClick() {
@ -198,8 +208,7 @@ class AccountSecurityViewModel @Inject constructor(
}
private fun handleTwoStepLoginClick() {
// TODO BIT-468: Implement two-step login
sendEvent(AccountSecurityEvent.ShowToast("Not yet implemented.".asText()))
sendEvent(AccountSecurityEvent.NavigateToTwoStepLogin(webSettingsUrl))
}
private fun handleUnlockWithBiometricToggled(
@ -300,6 +309,16 @@ sealed class AccountSecurityEvent {
*/
data object NavigateToPendingRequests : AccountSecurityEvent()
/**
* Navigate to the two step login screen.
*/
data class NavigateToTwoStepLogin(val url: String) : AccountSecurityEvent()
/**
* Navigate to the change master password screen.
*/
data class NavigateToChangeMasterPassword(val url: String) : AccountSecurityEvent()
/**
* Displays a toast with the given [Text].
*/

View file

@ -1060,6 +1060,13 @@ class AccountSecurityScreenTest : BaseComposeTest() {
verify { viewModel.trySendAction(AccountSecurityAction.TwoStepLoginClick) }
}
@Test
fun `on NavigateToTwoStepLogin should call launchUri on intentManager`() {
val uri = "testUri"
mutableEventFlow.tryEmit(AccountSecurityEvent.NavigateToTwoStepLogin(uri))
verify { intentManager.launchUri(uri.toUri()) }
}
@Suppress("MaxLineLength")
@Test
fun `on change master password click should display confirmation dialog and confirm should send ChangeMasterPasswordClick`() {
@ -1077,6 +1084,13 @@ class AccountSecurityScreenTest : BaseComposeTest() {
verify { viewModel.trySendAction(AccountSecurityAction.ChangeMasterPasswordClick) }
}
@Test
fun `on NavigateToChangeMasterPassword should call launchUri on intentManager`() {
val uri = "testUri"
mutableEventFlow.tryEmit(AccountSecurityEvent.NavigateToChangeMasterPassword(uri))
verify { intentManager.launchUri(uri.toUri()) }
}
@Test
fun `on Lock now click should send LockNowClick`() {
composeTestRule.onNodeWithText("Lock now").performScrollTo().performClick()

View file

@ -3,9 +3,12 @@ package com.x8bit.bitwarden.ui.platform.feature.settings.accountsecurity
import androidx.lifecycle.SavedStateHandle
import app.cash.turbine.test
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
import com.x8bit.bitwarden.data.platform.repository.EnvironmentRepository
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
import com.x8bit.bitwarden.data.platform.repository.model.Environment
import com.x8bit.bitwarden.data.platform.repository.model.VaultTimeout
import com.x8bit.bitwarden.data.platform.repository.model.VaultTimeoutAction
import com.x8bit.bitwarden.data.platform.repository.util.FakeEnvironmentRepository
import com.x8bit.bitwarden.data.vault.repository.VaultRepository
import com.x8bit.bitwarden.ui.platform.base.BaseViewModelTest
import com.x8bit.bitwarden.ui.platform.base.util.asText
@ -22,6 +25,8 @@ import org.junit.jupiter.api.Test
class AccountSecurityViewModelTest : BaseViewModelTest() {
private val fakeEnvironmentRepository = FakeEnvironmentRepository()
@Test
fun `initial state should be correct when saved state is set`() {
val viewModel = createViewModel(initialState = DEFAULT_STATE)
@ -74,17 +79,33 @@ class AccountSecurityViewModelTest : BaseViewModelTest() {
}
}
@Suppress("MaxLineLength")
@Test
fun `on ChangeMasterPasswordClick should emit ShowToast`() = runTest {
val viewModel = createViewModel()
viewModel.eventFlow.test {
viewModel.trySendAction(AccountSecurityAction.ChangeMasterPasswordClick)
assertEquals(
AccountSecurityEvent.ShowToast("Not yet implemented.".asText()),
awaitItem(),
)
fun `on ChangeMasterPasswordClick should emit NavigateToChangeMasterPassword with correct URL based on US and EU environments`() =
runTest {
fakeEnvironmentRepository.environment = Environment.Us
val viewModel = createViewModel()
viewModel.eventFlow.test {
viewModel.trySendAction(AccountSecurityAction.ChangeMasterPasswordClick)
assertEquals(
AccountSecurityEvent.NavigateToChangeMasterPassword(
"https://vault.bitwarden.com/#/settings",
),
awaitItem(),
)
fakeEnvironmentRepository.environment = Environment.Eu
viewModel.trySendAction(AccountSecurityAction.ChangeMasterPasswordClick)
assertEquals(
AccountSecurityEvent.NavigateToChangeMasterPassword(
"https://vault.bitwarden.eu/#/settings",
),
awaitItem(),
)
}
}
}
@Test
fun `on DeleteAccountClick should emit NavigateToDeleteAccount`() = runTest {
@ -184,17 +205,33 @@ class AccountSecurityViewModelTest : BaseViewModelTest() {
verify { settingsRepository.vaultTimeoutAction = VaultTimeoutAction.LOGOUT }
}
@Suppress("MaxLineLength")
@Test
fun `on TwoStepLoginClick should emit NavigateToTwoStepLogin`() = runTest {
val viewModel = createViewModel()
viewModel.eventFlow.test {
viewModel.trySendAction(AccountSecurityAction.TwoStepLoginClick)
assertEquals(
AccountSecurityEvent.ShowToast("Not yet implemented.".asText()),
awaitItem(),
)
fun `on TwoStepLoginClick should emit NavigateToTwoStepLogin with correct URL based on US and EU environments`() =
runTest {
fakeEnvironmentRepository.environment = Environment.Us
val viewModel = createViewModel()
viewModel.eventFlow.test {
viewModel.trySendAction(AccountSecurityAction.TwoStepLoginClick)
assertEquals(
AccountSecurityEvent.NavigateToTwoStepLogin(
"https://vault.bitwarden.com/#/settings",
),
awaitItem(),
)
fakeEnvironmentRepository.environment = Environment.Eu
viewModel.trySendAction(AccountSecurityAction.TwoStepLoginClick)
assertEquals(
AccountSecurityEvent.NavigateToTwoStepLogin(
"https://vault.bitwarden.eu/#/settings",
),
awaitItem(),
)
}
}
}
@Test
fun `on UnlockWithBiometricToggle should emit ShowToast`() = runTest {
@ -379,11 +416,13 @@ class AccountSecurityViewModelTest : BaseViewModelTest() {
}
}
@Suppress("LongParameterList")
private fun createViewModel(
initialState: AccountSecurityState? = DEFAULT_STATE,
authRepository: AuthRepository = mockk(relaxed = true),
vaultRepository: VaultRepository = mockk(relaxed = true),
settingsRepository: SettingsRepository = mockk(relaxed = true),
environmentRepository: EnvironmentRepository = fakeEnvironmentRepository,
savedStateHandle: SavedStateHandle = SavedStateHandle().apply {
set("state", initialState)
},
@ -391,6 +430,7 @@ class AccountSecurityViewModelTest : BaseViewModelTest() {
authRepository = authRepository,
vaultRepository = vaultRepository,
settingsRepository = settingsRepository,
environmentRepository = environmentRepository,
savedStateHandle = savedStateHandle,
)