1
0
Fork 0
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 ()

This commit is contained in:
Dave Severns 2024-10-28 15:11:25 -04:00 committed by GitHub
parent 21a5242abe
commit 05c768610e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
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

View file

@ -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",
),
)
}

View file

@ -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].

View file

@ -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),

View file

@ -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">Youll 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>

View file

@ -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",
)

View file

@ -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,
)