mirror of
https://github.com/bitwarden/android.git
synced 2025-02-13 18:39:56 +03:00
PM-13908 fixing copy on step2 and step3 and making vault url dynamic (#4154)
This commit is contained in:
parent
21a5242abe
commit
05c768610e
6 changed files with 100 additions and 11 deletions
app/src
main
java/com/x8bit/bitwarden/ui/vault/feature/importlogins
res/values
test/java/com/x8bit/bitwarden/ui/vault/feature/importlogins
|
@ -171,6 +171,7 @@ fun ImportLoginsScreen(
|
|||
|
||||
ImportLoginsState.ViewState.ImportStepTwo -> {
|
||||
ImportLoginsStepTwoContent(
|
||||
vaultUrl = state.currentWebVaultUrl,
|
||||
onBackClick = handler.onMoveToStepOne,
|
||||
onContinueClick = handler.onMoveToStepThree,
|
||||
onHelpClick = handler.onHelpClick,
|
||||
|
@ -355,6 +356,7 @@ private fun ImportLoginsStepOneContent(
|
|||
|
||||
@Composable
|
||||
private fun ImportLoginsStepTwoContent(
|
||||
vaultUrl: String,
|
||||
onContinueClick: () -> Unit,
|
||||
onBackClick: () -> Unit,
|
||||
onHelpClick: () -> Unit,
|
||||
|
@ -363,8 +365,14 @@ private fun ImportLoginsStepTwoContent(
|
|||
val instruction1 = createAnnotatedString(
|
||||
mainString = stringResource(
|
||||
R.string.on_your_computer_open_a_new_browser_tab_and_go_to_vault_bitwarden_com,
|
||||
vaultUrl,
|
||||
),
|
||||
highlights = listOf(
|
||||
stringResource(
|
||||
R.string.go_to_vault_bitwarden_com_highlight,
|
||||
vaultUrl,
|
||||
),
|
||||
),
|
||||
highlights = listOf(stringResource(R.string.go_to_vault_bitwarden_com_highlight)),
|
||||
highlightStyle = bitwardenBoldSpanStyle,
|
||||
)
|
||||
val instruction2Text = stringResource(R.string.log_in_to_the_bitwarden_web_app)
|
||||
|
@ -618,12 +626,14 @@ private class ImportLoginsDialogContentPreviewProvider :
|
|||
viewState = ImportLoginsState.ViewState.InitialContent,
|
||||
isVaultSyncing = false,
|
||||
showBottomSheet = false,
|
||||
currentWebVaultUrl = "vault.bitwarden.com",
|
||||
),
|
||||
ImportLoginsState(
|
||||
dialogState = ImportLoginsState.DialogState.ImportLater,
|
||||
viewState = ImportLoginsState.ViewState.InitialContent,
|
||||
isVaultSyncing = false,
|
||||
showBottomSheet = false,
|
||||
currentWebVaultUrl = "vault.bitwarden.com",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ package com.x8bit.bitwarden.ui.vault.feature.importlogins
|
|||
import androidx.lifecycle.viewModelScope
|
||||
import com.x8bit.bitwarden.R
|
||||
import com.x8bit.bitwarden.data.platform.manager.FirstTimeActionManager
|
||||
import com.x8bit.bitwarden.data.platform.repository.EnvironmentRepository
|
||||
import com.x8bit.bitwarden.data.platform.util.toUriOrNull
|
||||
import com.x8bit.bitwarden.data.vault.repository.VaultRepository
|
||||
import com.x8bit.bitwarden.data.vault.repository.model.SyncVaultDataResult
|
||||
import com.x8bit.bitwarden.ui.platform.base.BaseViewModel
|
||||
|
@ -21,14 +23,21 @@ import javax.inject.Inject
|
|||
class ImportLoginsViewModel @Inject constructor(
|
||||
private val vaultRepository: VaultRepository,
|
||||
private val firstTimeActionManager: FirstTimeActionManager,
|
||||
private val environmentRepository: EnvironmentRepository,
|
||||
) :
|
||||
BaseViewModel<ImportLoginsState, ImportLoginsEvent, ImportLoginsAction>(
|
||||
initialState = ImportLoginsState(
|
||||
null,
|
||||
viewState = ImportLoginsState.ViewState.InitialContent,
|
||||
isVaultSyncing = false,
|
||||
showBottomSheet = false,
|
||||
),
|
||||
initialState = run {
|
||||
val vaultUrl = environmentRepository.environment.environmentUrlData.webVault
|
||||
?: environmentRepository.environment.environmentUrlData.base
|
||||
ImportLoginsState(
|
||||
dialogState = null,
|
||||
viewState = ImportLoginsState.ViewState.InitialContent,
|
||||
isVaultSyncing = false,
|
||||
showBottomSheet = false,
|
||||
// attempt to trim the scheme of the vault url
|
||||
currentWebVaultUrl = vaultUrl.toUriOrNull()?.host ?: vaultUrl,
|
||||
)
|
||||
},
|
||||
) {
|
||||
override fun handleAction(action: ImportLoginsAction) {
|
||||
when (action) {
|
||||
|
@ -203,6 +212,7 @@ data class ImportLoginsState(
|
|||
val viewState: ViewState,
|
||||
val isVaultSyncing: Boolean,
|
||||
val showBottomSheet: Boolean,
|
||||
val currentWebVaultUrl: String,
|
||||
) {
|
||||
/**
|
||||
* Dialog states for the [ImportLoginsViewModel].
|
||||
|
|
|
@ -74,7 +74,7 @@ fun ImportLoginsInstructionStep(
|
|||
Spacer(Modifier.height(24.dp))
|
||||
Text(
|
||||
text = createClickableAnnotatedString(
|
||||
mainString = stringResource(R.string.need_help_checkout_out_import_help),
|
||||
mainString = stringResource(R.string.need_help_check_out_import_help),
|
||||
highlights = listOf(
|
||||
ClickableTextHighlight(
|
||||
textToHighlight = stringResource(R.string.import_help_highlight),
|
||||
|
|
|
@ -1040,8 +1040,8 @@ Do you want to switch to this account?</string>
|
|||
<string name="step_1_of_3">Step 1 of 3</string>
|
||||
<string name="export_your_saved_logins">Export your saved logins</string>
|
||||
<string name="delete_this_file_after_import_is_complete">You’ll delete this file after import is complete.</string>
|
||||
<string name="on_your_computer_open_a_new_browser_tab_and_go_to_vault_bitwarden_com">On your computer, open a new browser tab and go to vault.bitwarden.com</string>
|
||||
<string name="go_to_vault_bitwarden_com_highlight">go to vault.bitwarden.com</string>
|
||||
<string name="on_your_computer_open_a_new_browser_tab_and_go_to_vault_bitwarden_com">On your computer, open a new browser tab and go to %1$s</string>
|
||||
<string name="go_to_vault_bitwarden_com_highlight">go to %1$s</string>
|
||||
<string name="log_in_to_the_bitwarden_web_app">Log in to the Bitwarden web app.</string>
|
||||
<string name="step_2_of_3">Step 2 of 3</string>
|
||||
<string name="log_in_to_bitwarden">Log in to Bitwarden</string>
|
||||
|
@ -1055,7 +1055,7 @@ Do you want to switch to this account?</string>
|
|||
<string name="then_done_highlight">then Done</string>
|
||||
<string name="for_your_security_be_sure_to_delete_your_saved_password_file">For your security, be sure to delete your saved password file.</string>
|
||||
<string name="delete_your_saved_password_file">delete your saved password file.</string>
|
||||
<string name="need_help_checkout_out_import_help">Need help? Checkout out import help.</string>
|
||||
<string name="need_help_check_out_import_help">Need help? Check out import help.</string>
|
||||
<string name="import_help_highlight">import help</string>
|
||||
<string name="save_the_exported_file_somewhere_on_your_computer_you_can_find_easily">Save the exported file somewhere on your computer you can find easily.</string>
|
||||
<string name="save_the_exported_file_highlight">Save the exported file</string>
|
||||
|
|
|
@ -259,6 +259,24 @@ class ImportLoginsScreenTest : BaseComposeTest() {
|
|||
.assertIsDisplayed()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Step two content shows correct vault url when vault url is set`() {
|
||||
val url = "vault.bitwarden.com.testing"
|
||||
mutableImportLoginsStateFlow.update {
|
||||
it.copy(
|
||||
viewState = ImportLoginsState.ViewState.ImportStepTwo,
|
||||
currentWebVaultUrl = url,
|
||||
)
|
||||
}
|
||||
composeTestRule
|
||||
.onNodeWithText("Step 2 of 3")
|
||||
.assertIsDisplayed()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText(url, substring = true)
|
||||
.assertIsDisplayed()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `while on step two correct actions are sent when buttons are clicked`() {
|
||||
mutableImportLoginsStateFlow.update {
|
||||
|
@ -472,4 +490,5 @@ private val DEFAULT_STATE = ImportLoginsState(
|
|||
viewState = ImportLoginsState.ViewState.InitialContent,
|
||||
isVaultSyncing = false,
|
||||
showBottomSheet = false,
|
||||
currentWebVaultUrl = "vault.bitwarden.com",
|
||||
)
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package com.x8bit.bitwarden.ui.vault.feature.importlogins
|
||||
|
||||
import android.net.Uri
|
||||
import app.cash.turbine.test
|
||||
import com.x8bit.bitwarden.R
|
||||
import com.x8bit.bitwarden.data.platform.manager.FirstTimeActionManager
|
||||
import com.x8bit.bitwarden.data.platform.repository.EnvironmentRepository
|
||||
import com.x8bit.bitwarden.data.platform.repository.model.Environment
|
||||
import com.x8bit.bitwarden.data.vault.repository.VaultRepository
|
||||
import com.x8bit.bitwarden.data.vault.repository.model.SyncVaultDataResult
|
||||
import com.x8bit.bitwarden.ui.platform.base.BaseViewModelTest
|
||||
|
@ -14,10 +17,14 @@ import io.mockk.just
|
|||
import io.mockk.mockk
|
||||
import io.mockk.runs
|
||||
import io.mockk.verify
|
||||
import io.mockk.mockkStatic
|
||||
import io.mockk.unmockkStatic
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertNotNull
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class ImportLoginsViewModelTest : BaseViewModelTest() {
|
||||
|
@ -31,6 +38,23 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
|
|||
every { storeShowImportLoginsSettingsBadge(any()) } just runs
|
||||
}
|
||||
|
||||
private val environmentRepository: EnvironmentRepository = mockk {
|
||||
every { environment } returns Environment.Us
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
mockkStatic(Uri::parse)
|
||||
every { Uri.parse(Environment.Us.environmentUrlData.base) } returns mockk {
|
||||
every { host } returns DEFAULT_VAULT_URL
|
||||
}
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
fun tearDown() {
|
||||
unmockkStatic(Uri::parse)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `initial state is correct`() {
|
||||
val viewModel = createViewModel()
|
||||
|
@ -50,6 +74,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
|
|||
viewState = ImportLoginsState.ViewState.InitialContent,
|
||||
isVaultSyncing = false,
|
||||
showBottomSheet = false,
|
||||
currentWebVaultUrl = DEFAULT_VAULT_URL,
|
||||
),
|
||||
viewModel.stateFlow.value,
|
||||
)
|
||||
|
@ -65,6 +90,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
|
|||
viewState = ImportLoginsState.ViewState.InitialContent,
|
||||
isVaultSyncing = false,
|
||||
showBottomSheet = false,
|
||||
currentWebVaultUrl = DEFAULT_VAULT_URL,
|
||||
),
|
||||
viewModel.stateFlow.value,
|
||||
)
|
||||
|
@ -85,6 +111,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
|
|||
viewState = ImportLoginsState.ViewState.InitialContent,
|
||||
isVaultSyncing = false,
|
||||
showBottomSheet = false,
|
||||
currentWebVaultUrl = DEFAULT_VAULT_URL,
|
||||
),
|
||||
awaitItem(),
|
||||
)
|
||||
|
@ -95,6 +122,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
|
|||
viewState = ImportLoginsState.ViewState.InitialContent,
|
||||
isVaultSyncing = false,
|
||||
showBottomSheet = false,
|
||||
currentWebVaultUrl = DEFAULT_VAULT_URL,
|
||||
),
|
||||
awaitItem(),
|
||||
)
|
||||
|
@ -117,6 +145,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
|
|||
viewState = ImportLoginsState.ViewState.InitialContent,
|
||||
isVaultSyncing = false,
|
||||
showBottomSheet = false,
|
||||
currentWebVaultUrl = DEFAULT_VAULT_URL,
|
||||
),
|
||||
stateFlow.awaitItem(),
|
||||
)
|
||||
|
@ -127,6 +156,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
|
|||
viewState = ImportLoginsState.ViewState.InitialContent,
|
||||
isVaultSyncing = false,
|
||||
showBottomSheet = false,
|
||||
currentWebVaultUrl = DEFAULT_VAULT_URL,
|
||||
),
|
||||
stateFlow.awaitItem(),
|
||||
)
|
||||
|
@ -156,6 +186,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
|
|||
viewState = ImportLoginsState.ViewState.InitialContent,
|
||||
isVaultSyncing = false,
|
||||
showBottomSheet = false,
|
||||
currentWebVaultUrl = DEFAULT_VAULT_URL,
|
||||
),
|
||||
awaitItem(),
|
||||
)
|
||||
|
@ -166,6 +197,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
|
|||
viewState = ImportLoginsState.ViewState.ImportStepOne,
|
||||
isVaultSyncing = false,
|
||||
showBottomSheet = false,
|
||||
currentWebVaultUrl = DEFAULT_VAULT_URL,
|
||||
),
|
||||
awaitItem(),
|
||||
)
|
||||
|
@ -206,6 +238,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
|
|||
viewState = ImportLoginsState.ViewState.ImportStepOne,
|
||||
isVaultSyncing = false,
|
||||
showBottomSheet = false,
|
||||
currentWebVaultUrl = DEFAULT_VAULT_URL,
|
||||
),
|
||||
viewModel.stateFlow.value,
|
||||
)
|
||||
|
@ -221,6 +254,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
|
|||
viewState = ImportLoginsState.ViewState.ImportStepTwo,
|
||||
isVaultSyncing = false,
|
||||
showBottomSheet = false,
|
||||
currentWebVaultUrl = DEFAULT_VAULT_URL,
|
||||
),
|
||||
viewModel.stateFlow.value,
|
||||
)
|
||||
|
@ -236,6 +270,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
|
|||
viewState = ImportLoginsState.ViewState.ImportStepThree,
|
||||
isVaultSyncing = false,
|
||||
showBottomSheet = false,
|
||||
currentWebVaultUrl = DEFAULT_VAULT_URL,
|
||||
),
|
||||
viewModel.stateFlow.value,
|
||||
)
|
||||
|
@ -255,6 +290,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
|
|||
viewState = ImportLoginsState.ViewState.InitialContent,
|
||||
isVaultSyncing = false,
|
||||
showBottomSheet = false,
|
||||
currentWebVaultUrl = DEFAULT_VAULT_URL,
|
||||
),
|
||||
viewModel.stateFlow.value,
|
||||
)
|
||||
|
@ -275,6 +311,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
|
|||
viewState = ImportLoginsState.ViewState.InitialContent,
|
||||
isVaultSyncing = true,
|
||||
showBottomSheet = false,
|
||||
currentWebVaultUrl = DEFAULT_VAULT_URL,
|
||||
),
|
||||
awaitItem(),
|
||||
)
|
||||
|
@ -302,6 +339,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
|
|||
viewState = ImportLoginsState.ViewState.InitialContent,
|
||||
isVaultSyncing = true,
|
||||
showBottomSheet = false,
|
||||
currentWebVaultUrl = DEFAULT_VAULT_URL,
|
||||
),
|
||||
awaitItem(),
|
||||
)
|
||||
|
@ -321,6 +359,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
|
|||
viewState = ImportLoginsState.ViewState.InitialContent,
|
||||
isVaultSyncing = false,
|
||||
showBottomSheet = true,
|
||||
currentWebVaultUrl = DEFAULT_VAULT_URL,
|
||||
),
|
||||
viewModel.stateFlow.value,
|
||||
)
|
||||
|
@ -350,6 +389,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
|
|||
viewState = ImportLoginsState.ViewState.InitialContent,
|
||||
isVaultSyncing = true,
|
||||
showBottomSheet = false,
|
||||
currentWebVaultUrl = DEFAULT_VAULT_URL,
|
||||
),
|
||||
awaitItem(),
|
||||
)
|
||||
|
@ -359,6 +399,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
|
|||
viewState = ImportLoginsState.ViewState.InitialContent,
|
||||
isVaultSyncing = false,
|
||||
showBottomSheet = false,
|
||||
currentWebVaultUrl = DEFAULT_VAULT_URL,
|
||||
),
|
||||
awaitItem(),
|
||||
)
|
||||
|
@ -376,6 +417,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
|
|||
viewState = ImportLoginsState.ViewState.InitialContent,
|
||||
isVaultSyncing = false,
|
||||
showBottomSheet = false,
|
||||
currentWebVaultUrl = DEFAULT_VAULT_URL,
|
||||
),
|
||||
viewModel.stateFlow.value,
|
||||
)
|
||||
|
@ -398,6 +440,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
|
|||
viewState = ImportLoginsState.ViewState.InitialContent,
|
||||
isVaultSyncing = false,
|
||||
showBottomSheet = false,
|
||||
currentWebVaultUrl = DEFAULT_VAULT_URL,
|
||||
),
|
||||
viewModel.stateFlow.value,
|
||||
)
|
||||
|
@ -421,6 +464,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
|
|||
viewState = ImportLoginsState.ViewState.InitialContent,
|
||||
isVaultSyncing = true,
|
||||
showBottomSheet = false,
|
||||
currentWebVaultUrl = DEFAULT_VAULT_URL,
|
||||
),
|
||||
stateFlow.awaitItem(),
|
||||
)
|
||||
|
@ -430,6 +474,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
|
|||
viewState = ImportLoginsState.ViewState.InitialContent,
|
||||
isVaultSyncing = false,
|
||||
showBottomSheet = true,
|
||||
currentWebVaultUrl = DEFAULT_VAULT_URL,
|
||||
),
|
||||
stateFlow.awaitItem(),
|
||||
)
|
||||
|
@ -440,6 +485,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
|
|||
viewState = ImportLoginsState.ViewState.InitialContent,
|
||||
isVaultSyncing = false,
|
||||
showBottomSheet = false,
|
||||
currentWebVaultUrl = DEFAULT_VAULT_URL,
|
||||
),
|
||||
stateFlow.awaitItem(),
|
||||
)
|
||||
|
@ -450,12 +496,16 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
|
|||
private fun createViewModel(): ImportLoginsViewModel = ImportLoginsViewModel(
|
||||
vaultRepository = vaultRepository,
|
||||
firstTimeActionManager = firstTimeActionManager,
|
||||
environmentRepository = environmentRepository,
|
||||
)
|
||||
}
|
||||
|
||||
private const val DEFAULT_VAULT_URL = "vault.bitwarden.com"
|
||||
|
||||
private val DEFAULT_STATE = ImportLoginsState(
|
||||
dialogState = null,
|
||||
viewState = ImportLoginsState.ViewState.InitialContent,
|
||||
isVaultSyncing = false,
|
||||
showBottomSheet = false,
|
||||
currentWebVaultUrl = DEFAULT_VAULT_URL,
|
||||
)
|
||||
|
|
Loading…
Add table
Reference in a new issue