Skip to content

Commit

Permalink
PM-13908 Make vault url dynamic and fix copy
Browse files Browse the repository at this point in the history
  • Loading branch information
dseverns-livefront committed Oct 28, 2024
1 parent 0960f61 commit 35609ff
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ fun ImportLoginsScreen(

ImportLoginsState.ViewState.ImportStepTwo -> {
ImportLoginsStepTwoContent(
vaultUrl = state.currentWebVaultUrl,
onBackClick = handler.onMoveToStepOne,
onContinueClick = handler.onMoveToStepThree,
onHelpClick = handler.onHelpClick,
Expand Down Expand Up @@ -355,6 +356,7 @@ private fun ImportLoginsStepOneContent(

@Composable
private fun ImportLoginsStepTwoContent(
vaultUrl: String,
onContinueClick: () -> Unit,
onBackClick: () -> Unit,
onHelpClick: () -> Unit,
Expand All @@ -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)
Expand Down Expand Up @@ -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",
),
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.x8bit.bitwarden.ui.vault.feature.importlogins

import androidx.lifecycle.viewModelScope
import com.x8bit.bitwarden.R
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
Expand All @@ -19,14 +21,21 @@ import javax.inject.Inject
@HiltViewModel
class ImportLoginsViewModel @Inject constructor(
private val vaultRepository: VaultRepository,
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) {
Expand Down Expand Up @@ -197,6 +206,7 @@ data class ImportLoginsState(
val viewState: ViewState,
val isVaultSyncing: Boolean,
val showBottomSheet: Boolean,
val currentWebVaultUrl: String,
) {
/**
* Dialog states for the [ImportLoginsViewModel].
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
6 changes: 3 additions & 3 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -472,4 +490,5 @@ private val DEFAULT_STATE = ImportLoginsState(
viewState = ImportLoginsState.ViewState.InitialContent,
isVaultSyncing = false,
showBottomSheet = false,
currentWebVaultUrl = "vault.bitwarden.com",
)
Original file line number Diff line number Diff line change
@@ -1,26 +1,51 @@
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.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
import com.x8bit.bitwarden.ui.platform.base.util.asText
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.every
import io.mockk.mockk
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() {

private val vaultRepository: VaultRepository = mockk() {
private val vaultRepository: VaultRepository = mockk {
coEvery { syncForResult() } returns SyncVaultDataResult.Success(itemsAvailable = true)
}

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()
Expand All @@ -40,6 +65,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
viewState = ImportLoginsState.ViewState.InitialContent,
isVaultSyncing = false,
showBottomSheet = false,
currentWebVaultUrl = DEFAULT_VAULT_URL,
),
viewModel.stateFlow.value,
)
Expand All @@ -55,6 +81,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
viewState = ImportLoginsState.ViewState.InitialContent,
isVaultSyncing = false,
showBottomSheet = false,
currentWebVaultUrl = DEFAULT_VAULT_URL,
),
viewModel.stateFlow.value,
)
Expand All @@ -75,6 +102,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
viewState = ImportLoginsState.ViewState.InitialContent,
isVaultSyncing = false,
showBottomSheet = false,
currentWebVaultUrl = DEFAULT_VAULT_URL,
),
awaitItem(),
)
Expand All @@ -85,6 +113,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
viewState = ImportLoginsState.ViewState.InitialContent,
isVaultSyncing = false,
showBottomSheet = false,
currentWebVaultUrl = DEFAULT_VAULT_URL,
),
awaitItem(),
)
Expand All @@ -106,6 +135,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
viewState = ImportLoginsState.ViewState.InitialContent,
isVaultSyncing = false,
showBottomSheet = false,
currentWebVaultUrl = DEFAULT_VAULT_URL,
),
stateFlow.awaitItem(),
)
Expand All @@ -116,6 +146,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
viewState = ImportLoginsState.ViewState.InitialContent,
isVaultSyncing = false,
showBottomSheet = false,
currentWebVaultUrl = DEFAULT_VAULT_URL,
),
stateFlow.awaitItem(),
)
Expand All @@ -141,6 +172,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
viewState = ImportLoginsState.ViewState.InitialContent,
isVaultSyncing = false,
showBottomSheet = false,
currentWebVaultUrl = DEFAULT_VAULT_URL,
),
awaitItem(),
)
Expand All @@ -151,6 +183,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
viewState = ImportLoginsState.ViewState.ImportStepOne,
isVaultSyncing = false,
showBottomSheet = false,
currentWebVaultUrl = DEFAULT_VAULT_URL,
),
awaitItem(),
)
Expand Down Expand Up @@ -191,6 +224,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
viewState = ImportLoginsState.ViewState.ImportStepOne,
isVaultSyncing = false,
showBottomSheet = false,
currentWebVaultUrl = DEFAULT_VAULT_URL,
),
viewModel.stateFlow.value,
)
Expand All @@ -206,6 +240,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
viewState = ImportLoginsState.ViewState.ImportStepTwo,
isVaultSyncing = false,
showBottomSheet = false,
currentWebVaultUrl = DEFAULT_VAULT_URL,
),
viewModel.stateFlow.value,
)
Expand All @@ -221,6 +256,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
viewState = ImportLoginsState.ViewState.ImportStepThree,
isVaultSyncing = false,
showBottomSheet = false,
currentWebVaultUrl = DEFAULT_VAULT_URL,
),
viewModel.stateFlow.value,
)
Expand All @@ -240,6 +276,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
viewState = ImportLoginsState.ViewState.InitialContent,
isVaultSyncing = false,
showBottomSheet = false,
currentWebVaultUrl = DEFAULT_VAULT_URL,
),
viewModel.stateFlow.value,
)
Expand All @@ -260,6 +297,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
viewState = ImportLoginsState.ViewState.InitialContent,
isVaultSyncing = true,
showBottomSheet = false,
currentWebVaultUrl = DEFAULT_VAULT_URL,
),
awaitItem(),
)
Expand Down Expand Up @@ -287,6 +325,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
viewState = ImportLoginsState.ViewState.InitialContent,
isVaultSyncing = true,
showBottomSheet = false,
currentWebVaultUrl = DEFAULT_VAULT_URL,
),
awaitItem(),
)
Expand All @@ -305,6 +344,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
viewState = ImportLoginsState.ViewState.InitialContent,
isVaultSyncing = false,
showBottomSheet = true,
currentWebVaultUrl = DEFAULT_VAULT_URL,
),
viewModel.stateFlow.value,
)
Expand All @@ -330,6 +370,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
viewState = ImportLoginsState.ViewState.InitialContent,
isVaultSyncing = true,
showBottomSheet = false,
currentWebVaultUrl = DEFAULT_VAULT_URL,
),
awaitItem(),
)
Expand All @@ -339,6 +380,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
viewState = ImportLoginsState.ViewState.InitialContent,
isVaultSyncing = false,
showBottomSheet = false,
currentWebVaultUrl = DEFAULT_VAULT_URL,
),
awaitItem(),
)
Expand All @@ -356,6 +398,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
viewState = ImportLoginsState.ViewState.InitialContent,
isVaultSyncing = false,
showBottomSheet = false,
currentWebVaultUrl = DEFAULT_VAULT_URL,
),
viewModel.stateFlow.value,
)
Expand All @@ -378,6 +421,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
viewState = ImportLoginsState.ViewState.InitialContent,
isVaultSyncing = false,
showBottomSheet = false,
currentWebVaultUrl = DEFAULT_VAULT_URL,
),
viewModel.stateFlow.value,
)
Expand All @@ -401,6 +445,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
viewState = ImportLoginsState.ViewState.InitialContent,
isVaultSyncing = true,
showBottomSheet = false,
currentWebVaultUrl = DEFAULT_VAULT_URL,
),
stateFlow.awaitItem(),
)
Expand All @@ -410,6 +455,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
viewState = ImportLoginsState.ViewState.InitialContent,
isVaultSyncing = false,
showBottomSheet = true,
currentWebVaultUrl = DEFAULT_VAULT_URL,
),
stateFlow.awaitItem(),
)
Expand All @@ -420,6 +466,7 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {
viewState = ImportLoginsState.ViewState.InitialContent,
isVaultSyncing = false,
showBottomSheet = false,
currentWebVaultUrl = DEFAULT_VAULT_URL,
),
stateFlow.awaitItem(),
)
Expand All @@ -429,12 +476,16 @@ class ImportLoginsViewModelTest : BaseViewModelTest() {

private fun createViewModel(): ImportLoginsViewModel = ImportLoginsViewModel(
vaultRepository = vaultRepository,
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,
)

0 comments on commit 35609ff

Please sign in to comment.