diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/autofill/blockautofill/AddEditBlockedUriDialog.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/autofill/blockautofill/AddEditBlockedUriDialog.kt
index c8790f199e..0ae8ff8a2e 100644
--- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/autofill/blockautofill/AddEditBlockedUriDialog.kt
+++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/autofill/blockautofill/AddEditBlockedUriDialog.kt
@@ -42,7 +42,6 @@ fun AddEditBlockedUriDialog(
onUriChange: (String) -> Unit,
onCancelClick: () -> Unit,
onSaveClick: (String) -> Unit,
- onDeleteClick: (() -> Unit)? = null,
onDismissRequest: () -> Unit,
) {
Dialog(
@@ -66,7 +65,13 @@ fun AddEditBlockedUriDialog(
modifier = Modifier
.padding(top = 24.dp, start = 24.dp, end = 24.dp)
.fillMaxWidth(),
- text = stringResource(id = BitwardenString.new_uri),
+ text = stringResource(
+ id = if (isEdit) {
+ BitwardenString.edit_blocked_uri
+ } else {
+ BitwardenString.new_blocked_uri
+ },
+ ),
color = BitwardenTheme.colorScheme.text.primary,
style = BitwardenTheme.typography.headlineSmall,
)
@@ -104,13 +109,6 @@ fun AddEditBlockedUriDialog(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.padding(start = 8.dp, top = 24.dp, bottom = 24.dp, end = 24.dp),
) {
- if (isEdit && onDeleteClick != null) {
- BitwardenTextButton(
- label = stringResource(id = BitwardenString.remove),
- onClick = onDeleteClick,
- )
- }
-
BitwardenTextButton(
label = stringResource(id = BitwardenString.cancel),
onClick = onCancelClick,
diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/autofill/blockautofill/BlockAutoFillScreen.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/autofill/blockautofill/BlockAutoFillScreen.kt
index 1909e8b97e..e900f0383a 100644
--- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/autofill/blockautofill/BlockAutoFillScreen.kt
+++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/autofill/blockautofill/BlockAutoFillScreen.kt
@@ -4,8 +4,6 @@ import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.scaleIn
import androidx.compose.animation.scaleOut
import androidx.compose.foundation.Image
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@@ -17,17 +15,17 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.lazy.items
+import androidx.compose.foundation.lazy.itemsIndexed
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
-import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberTopAppBarState
-import androidx.compose.material3.ripple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
@@ -38,18 +36,24 @@ import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.bitwarden.ui.platform.base.util.EventsEffect
-import com.bitwarden.ui.platform.base.util.bottomDivider
+import com.bitwarden.ui.platform.base.util.cardStyle
+import com.bitwarden.ui.platform.base.util.standardHorizontalMargin
+import com.bitwarden.ui.platform.base.util.toListItemCardStyle
import com.bitwarden.ui.platform.components.appbar.BitwardenTopAppBar
-import com.bitwarden.ui.platform.components.button.BitwardenOutlinedButton
+import com.bitwarden.ui.platform.components.appbar.action.BitwardenOverflowActionItem
+import com.bitwarden.ui.platform.components.appbar.model.OverflowMenuItemData
+import com.bitwarden.ui.platform.components.button.BitwardenFilledButton
import com.bitwarden.ui.platform.components.fab.BitwardenFloatingActionButton
+import com.bitwarden.ui.platform.components.model.CardStyle
import com.bitwarden.ui.platform.components.scaffold.BitwardenScaffold
import com.bitwarden.ui.platform.components.util.rememberVectorPainter
import com.bitwarden.ui.platform.resource.BitwardenDrawable
import com.bitwarden.ui.platform.resource.BitwardenString
import com.bitwarden.ui.platform.theme.BitwardenTheme
+import kotlinx.collections.immutable.persistentListOf
/**
- * Displays the block auto-fill screen.
+ * Displays the block autofill screen.
*/
@Suppress("LongMethod")
@OptIn(ExperimentalMaterial3Api::class)
@@ -74,7 +78,6 @@ fun BlockAutoFillScreen(
BlockAutoFillAction.SaveUri(newUri = newUri, originalUri = originalUri),
)
},
- onRemoveClick = { viewModel.trySendAction(BlockAutoFillAction.RemoveUriClick(it)) },
onDismissRequest = { viewModel.trySendAction(BlockAutoFillAction.DismissDialog) },
)
@@ -107,84 +110,94 @@ fun BlockAutoFillScreen(
}
},
) {
- LazyColumn(
- modifier = Modifier.fillMaxSize(),
- ) {
- when (val viewState = state.viewState) {
- is BlockAutoFillState.ViewState.Content -> {
- item {
- Row(
- modifier = Modifier
- .padding(vertical = 8.dp, horizontal = 20.dp)
- .fillMaxWidth(),
- verticalAlignment = Alignment.CenterVertically,
- horizontalArrangement = Arrangement.Center,
- ) {
- Text(
- text = stringResource(
- id = BitwardenString
- .auto_fill_will_not_be_offered_for_these_ur_is,
- ),
- color = BitwardenTheme.colorScheme.text.primary,
- style = BitwardenTheme.typography.bodyMedium,
- modifier = Modifier.align(Alignment.CenterVertically),
- )
- }
- }
-
- items(viewState.blockedUris, key = { it }) { uri ->
- BlockAutoFillListItem(
- label = uri,
- onClick = {
- viewModel.trySendAction(BlockAutoFillAction.EditUriClick(uri))
- },
- modifier = Modifier
- .padding(horizontal = 16.dp)
- .fillMaxWidth(),
- )
- }
- }
-
- is BlockAutoFillState.ViewState.Empty -> {
- item {
- BlockAutoFillNoItems(
- addItemClickAction = {
- viewModel.trySendAction(BlockAutoFillAction.AddUriClick)
- },
- modifier = Modifier.fillMaxSize(),
- )
- }
- }
+ when (val viewState = state.viewState) {
+ is BlockAutoFillState.ViewState.Content -> {
+ BlockedAutofillContent(
+ viewState = viewState,
+ onEditUriClick = {
+ viewModel.trySendAction(BlockAutoFillAction.EditUriClick(it))
+ },
+ onRemoveClick = {
+ viewModel.trySendAction(BlockAutoFillAction.RemoveUriClick(it))
+ },
+ modifier = Modifier.fillMaxSize(),
+ )
}
- item {
- Spacer(modifier = Modifier.height(height = 16.dp))
- Spacer(modifier = Modifier.navigationBarsPadding())
+
+ BlockAutoFillState.ViewState.Empty -> {
+ BlockAutoFillNoItems(
+ addItemClickAction = {
+ viewModel.trySendAction(BlockAutoFillAction.AddUriClick)
+ },
+ modifier = Modifier.fillMaxSize(),
+ )
}
}
}
}
+@Composable
+private fun BlockedAutofillContent(
+ viewState: BlockAutoFillState.ViewState.Content,
+ onEditUriClick: (String) -> Unit,
+ onRemoveClick: (String) -> Unit,
+ modifier: Modifier = Modifier,
+) {
+ LazyColumn(modifier = modifier) {
+ item {
+ Spacer(modifier = Modifier.height(height = 24.dp))
+ Text(
+ text = stringResource(
+ id = BitwardenString.auto_fill_will_not_be_offered_for_these_ur_is,
+ ),
+ textAlign = TextAlign.Center,
+ color = BitwardenTheme.colorScheme.text.secondary,
+ style = BitwardenTheme.typography.bodyMedium,
+ modifier = Modifier
+ .fillMaxWidth()
+ .standardHorizontalMargin()
+ .animateItem(),
+ )
+ Spacer(modifier = Modifier.height(height = 24.dp))
+ }
+
+ itemsIndexed(
+ items = viewState.blockedUris,
+ key = { _, uri -> uri },
+ ) { index, uri ->
+ BlockAutoFillListItem(
+ label = uri,
+ onDeleteClick = { onRemoveClick(uri) },
+ onEditClick = { onEditUriClick(uri) },
+ cardStyle = viewState.blockedUris.toListItemCardStyle(index = index),
+ modifier = Modifier
+ .standardHorizontalMargin()
+ .fillMaxWidth()
+ .animateItem(),
+ )
+ }
+ item {
+ Spacer(modifier = Modifier.height(height = 16.dp))
+ Spacer(modifier = Modifier.navigationBarsPadding())
+ }
+ }
+}
+
@Composable
private fun BlockAutoFillDialogs(
dialogState: BlockAutoFillState.DialogState? = null,
onUriTextChange: (String) -> Unit,
onSaveClick: (String, String?) -> Unit,
- onRemoveClick: (String) -> Unit,
onDismissRequest: () -> Unit,
) {
when (dialogState) {
is BlockAutoFillState.DialogState.AddEdit -> {
AddEditBlockedUriDialog(
uri = dialogState.uri,
- isEdit = dialogState.originalUri != null,
+ isEdit = dialogState.isEdit,
errorMessage = dialogState.errorMessage?.invoke(),
onUriChange = onUriTextChange,
onDismissRequest = onDismissRequest,
- onDeleteClick = if (dialogState.isEdit) {
- { dialogState.originalUri?.let { onRemoveClick(it) } }
- } else {
- null
- },
onCancelClick = onDismissRequest,
onSaveClick = { newUri -> onSaveClick(newUri, dialogState.originalUri) },
)
@@ -203,7 +216,7 @@ private fun BlockAutoFillNoItems(
modifier: Modifier = Modifier,
) {
Column(
- modifier = modifier,
+ modifier = modifier.verticalScroll(state = rememberScrollState()),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
@@ -217,66 +230,87 @@ private fun BlockAutoFillNoItems(
.size(size = 124.dp)
.align(Alignment.CenterHorizontally),
)
- Spacer(modifier = Modifier.height(32.dp))
+ Spacer(modifier = Modifier.height(height = 24.dp))
Text(
textAlign = TextAlign.Center,
+ text = stringResource(id = BitwardenString.no_uris_blocked),
+ style = BitwardenTheme.typography.titleMedium,
+ color = BitwardenTheme.colorScheme.text.primary,
modifier = Modifier
.fillMaxWidth()
- .padding(horizontal = 16.dp),
+ .standardHorizontalMargin(),
+ )
+
+ Spacer(modifier = Modifier.height(height = 12.dp))
+
+ Text(
+ textAlign = TextAlign.Center,
text = stringResource(
id = BitwardenString.auto_fill_will_not_be_offered_for_these_ur_is,
),
style = BitwardenTheme.typography.bodyMedium,
+ color = BitwardenTheme.colorScheme.text.primary,
+ modifier = Modifier
+ .fillMaxWidth()
+ .standardHorizontalMargin(),
)
Spacer(modifier = Modifier.height(24.dp))
- BitwardenOutlinedButton(
- modifier = Modifier
- .fillMaxWidth()
- .padding(horizontal = 16.dp),
+ BitwardenFilledButton(
label = stringResource(id = BitwardenString.new_blocked_uri),
onClick = addItemClickAction,
+ icon = rememberVectorPainter(id = BitwardenDrawable.ic_plus_small),
+ modifier = Modifier
+ .wrapContentWidth()
+ .standardHorizontalMargin(),
)
+ Spacer(modifier = Modifier.height(height = 24.dp))
+ Spacer(modifier = Modifier.navigationBarsPadding())
}
}
@Composable
private fun BlockAutoFillListItem(
label: String,
- onClick: () -> Unit,
+ onEditClick: () -> Unit,
+ onDeleteClick: () -> Unit,
+ cardStyle: CardStyle,
modifier: Modifier = Modifier,
) {
Row(
- modifier = Modifier
- .defaultMinSize(minHeight = 60.dp)
- .clickable(
- interactionSource = remember { MutableInteractionSource() },
- indication = ripple(
- color = BitwardenTheme.colorScheme.background.pressed,
- ),
- onClick = onClick,
- )
- .bottomDivider(paddingStart = 16.dp)
- .padding(end = 8.dp, top = 16.dp, bottom = 16.dp)
- .then(modifier),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
+ modifier = modifier
+ .defaultMinSize(minHeight = 60.dp)
+ .cardStyle(
+ cardStyle = cardStyle,
+ paddingStart = 16.dp,
+ paddingEnd = 4.dp,
+ ),
) {
Text(
- modifier = Modifier
- .padding(end = 16.dp)
- .weight(1f),
text = label,
style = BitwardenTheme.typography.bodyLarge,
color = BitwardenTheme.colorScheme.text.primary,
+ modifier = Modifier
+ .padding(end = 16.dp)
+ .weight(weight = 1f),
)
- Icon(
- painter = rememberVectorPainter(id = BitwardenDrawable.ic_pencil_square),
- contentDescription = null,
- tint = BitwardenTheme.colorScheme.icon.primary,
- modifier = Modifier.size(24.dp),
+ BitwardenOverflowActionItem(
+ menuItemDataList = persistentListOf(
+ OverflowMenuItemData(
+ text = stringResource(id = BitwardenString.edit),
+ onClick = onEditClick,
+ ),
+ OverflowMenuItemData(
+ text = stringResource(id = BitwardenString.delete),
+ onClick = onDeleteClick,
+ ),
+ ),
+ vectorIconRes = BitwardenDrawable.ic_ellipsis_horizontal,
+ testTag = "Options",
)
}
}
diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/autofill/blockautofill/BlockAutoFillViewModel.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/autofill/blockautofill/BlockAutoFillViewModel.kt
index 63ab805f4c..e77945fe10 100644
--- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/autofill/blockautofill/BlockAutoFillViewModel.kt
+++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/autofill/blockautofill/BlockAutoFillViewModel.kt
@@ -10,6 +10,9 @@ import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
import com.x8bit.bitwarden.ui.platform.feature.settings.autofill.blockautofill.util.isValidPattern
import com.x8bit.bitwarden.ui.platform.feature.settings.autofill.blockautofill.util.validateUri
import dagger.hilt.android.lifecycle.HiltViewModel
+import kotlinx.collections.immutable.ImmutableList
+import kotlinx.collections.immutable.persistentListOf
+import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.update
import kotlinx.parcelize.Parcelize
import javax.inject.Inject
@@ -40,7 +43,9 @@ class BlockAutoFillViewModel @Inject constructor(
mutableStateFlow.update { currentState ->
if (uris.isNotEmpty()) {
currentState.copy(
- viewState = BlockAutoFillState.ViewState.Content(uris.map { it }),
+ viewState = BlockAutoFillState.ViewState.Content(
+ blockedUris = uris.distinct().toImmutableList(),
+ ),
)
} else {
currentState.copy(
@@ -163,7 +168,7 @@ class BlockAutoFillViewModel @Inject constructor(
}
/**
- * Represents the state for block auto fill.
+ * Represents the state for block autofill.
*
* @property viewState indicates what view state the screen is in.
*/
@@ -203,7 +208,7 @@ data class BlockAutoFillState(
*/
@Parcelize
data class Content(
- val blockedUris: List = emptyList(),
+ val blockedUris: ImmutableList = persistentListOf(),
) : ViewState()
/**
diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/autofill/blockautofill/BlockAutoFillScreenTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/autofill/blockautofill/BlockAutoFillScreenTest.kt
index 69bc3c2f3e..968eaecc5b 100644
--- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/autofill/blockautofill/BlockAutoFillScreenTest.kt
+++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/autofill/blockautofill/BlockAutoFillScreenTest.kt
@@ -11,10 +11,12 @@ import androidx.compose.ui.test.performScrollTo
import com.bitwarden.core.data.repository.util.bufferedMutableSharedFlow
import com.bitwarden.ui.util.asText
import com.bitwarden.ui.util.assertNoDialogExists
+import com.bitwarden.ui.util.assertNoPopupExists
import com.x8bit.bitwarden.ui.platform.base.BitwardenComposeTest
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
+import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.MutableStateFlow
import org.junit.Assert.assertTrue
import org.junit.Before
@@ -68,7 +70,7 @@ class BlockAutoFillScreenTest : BitwardenComposeTest() {
@Test
fun `Screen should display content state view when in ViewState Content`() {
mutableStateFlow.value = BlockAutoFillState(
- viewState = BlockAutoFillState.ViewState.Content(listOf("uri1", "uri2")),
+ viewState = BlockAutoFillState.ViewState.Content(persistentListOf("uri1", "uri2")),
)
listOf("uri1", "uri2").forEach { uri ->
@@ -109,17 +111,6 @@ class BlockAutoFillScreenTest : BitwardenComposeTest() {
verify { viewModel.trySendAction(BlockAutoFillAction.AddUriClick) }
}
- @Test
- fun `on URI item click should send EditUriClick`() {
- mutableStateFlow.value = BlockAutoFillState(
- viewState = BlockAutoFillState.ViewState.Content(listOf("uri1")),
- )
-
- composeTestRule.onNodeWithText("uri1").performClick()
-
- verify { viewModel.trySendAction(BlockAutoFillAction.EditUriClick(uri = "uri1")) }
- }
-
@Test
fun `should show add URI dialog according to state`() {
composeTestRule.assertNoDialogExists()
@@ -130,33 +121,36 @@ class BlockAutoFillScreenTest : BitwardenComposeTest() {
originalUri = null,
errorMessage = null,
),
- viewState = BlockAutoFillState.ViewState.Content(listOf("uri1")),
+ viewState = BlockAutoFillState.ViewState.Content(persistentListOf("uri1")),
)
composeTestRule
- .onNodeWithText("New URI")
+ .onNodeWithText("New blocked URI")
.assert(hasAnyAncestor(isDialog()))
}
@Test
- fun `clicking a uri from the list should send EditUriClick action`() {
- val testUri = "http://test.com"
-
- composeTestRule.assertNoDialogExists()
+ fun `clicking edit in popup menu should send EditUriClick action`() {
+ composeTestRule.assertNoPopupExists()
+ val uriToRemove = "http://uriToRemove.com"
mutableStateFlow.value = BlockAutoFillState(
- dialog = BlockAutoFillState.DialogState.AddEdit(
- uri = testUri,
- originalUri = testUri,
- errorMessage = null,
+ viewState = BlockAutoFillState.ViewState.Content(
+ blockedUris = persistentListOf(uriToRemove),
),
- viewState = BlockAutoFillState.ViewState.Content(listOf("uri1")),
)
composeTestRule
- .onNodeWithText("New URI")
- .assert(hasAnyAncestor(isDialog()))
- .assertIsDisplayed()
+ .onNodeWithContentDescription(label = "More options")
+ .performScrollTo()
+ .performClick()
+
+ composeTestRule
+ .onNodeWithText(text = "Edit")
+ .performScrollTo()
+ .performClick()
+
+ verify { viewModel.trySendAction(BlockAutoFillAction.EditUriClick(uri = uriToRemove)) }
}
@Test
@@ -171,7 +165,7 @@ class BlockAutoFillScreenTest : BitwardenComposeTest() {
originalUri = null,
errorMessage = errorMessage.asText(),
),
- viewState = BlockAutoFillState.ViewState.Content(listOf("uri1")),
+ viewState = BlockAutoFillState.ViewState.Content(persistentListOf("uri1")),
)
composeTestRule
@@ -190,7 +184,7 @@ class BlockAutoFillScreenTest : BitwardenComposeTest() {
originalUri = null,
errorMessage = null,
),
- viewState = BlockAutoFillState.ViewState.Content(listOf("existingUri")),
+ viewState = BlockAutoFillState.ViewState.Content(persistentListOf("existingUri")),
)
val newUri = "http://newuri.com"
@@ -209,7 +203,7 @@ class BlockAutoFillScreenTest : BitwardenComposeTest() {
originalUri = null,
errorMessage = null,
),
- viewState = BlockAutoFillState.ViewState.Content(emptyList()),
+ viewState = BlockAutoFillState.ViewState.Content(persistentListOf()),
)
composeTestRule.onNodeWithText("Cancel").performClick()
@@ -218,20 +212,25 @@ class BlockAutoFillScreenTest : BitwardenComposeTest() {
}
@Test
- fun `clicking remove in dialog should send RemoveUriClick action`() {
- composeTestRule.assertNoDialogExists()
+ fun `clicking delete in popup menu should send RemoveUriClick action`() {
+ composeTestRule.assertNoPopupExists()
val uriToRemove = "http://uriToRemove.com"
mutableStateFlow.value = BlockAutoFillState(
- dialog = BlockAutoFillState.DialogState.AddEdit(
- uri = uriToRemove,
- originalUri = uriToRemove,
- errorMessage = null,
+ viewState = BlockAutoFillState.ViewState.Content(
+ blockedUris = persistentListOf(uriToRemove),
),
- viewState = BlockAutoFillState.ViewState.Content(listOf(uriToRemove, "otherUri")),
)
- composeTestRule.onNodeWithText("Remove").performClick()
+ composeTestRule
+ .onNodeWithContentDescription(label = "More options")
+ .performScrollTo()
+ .performClick()
+
+ composeTestRule
+ .onNodeWithText(text = "Delete")
+ .performScrollTo()
+ .performClick()
verify { viewModel.trySendAction(BlockAutoFillAction.RemoveUriClick(uri = uriToRemove)) }
}
diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/autofill/blockautofill/BlockAutoFillViewModelTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/autofill/blockautofill/BlockAutoFillViewModelTest.kt
index 6de569f2e6..c702e47d1f 100644
--- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/autofill/blockautofill/BlockAutoFillViewModelTest.kt
+++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/autofill/blockautofill/BlockAutoFillViewModelTest.kt
@@ -8,6 +8,8 @@ import com.bitwarden.ui.util.asText
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
import io.mockk.every
import io.mockk.mockk
+import kotlinx.collections.immutable.persistentListOf
+import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
@@ -24,7 +26,7 @@ class BlockAutoFillViewModelTest : BaseViewModelTest() {
val viewModel = createViewModel()
val expectedState = BlockAutoFillState(
viewState = BlockAutoFillState.ViewState.Content(
- blockedUris = listOf("blockedUri"),
+ blockedUris = persistentListOf("blockedUri"),
),
)
@@ -64,7 +66,9 @@ class BlockAutoFillViewModelTest : BaseViewModelTest() {
originalUri = null,
errorMessage = null,
),
- viewState = BlockAutoFillState.ViewState.Content(blockedUris = listOf("blockedUri")),
+ viewState = BlockAutoFillState.ViewState.Content(
+ blockedUris = persistentListOf("blockedUri"),
+ ),
)
assertEquals(expectedState, viewModel.stateFlow.value)
@@ -82,7 +86,7 @@ class BlockAutoFillViewModelTest : BaseViewModelTest() {
originalUri = testUri,
errorMessage = null,
),
- viewState = BlockAutoFillState.ViewState.Content(listOf("blockedUri")),
+ viewState = BlockAutoFillState.ViewState.Content(persistentListOf("blockedUri")),
)
assertEquals(expectedState, viewModel.stateFlow.value)
@@ -104,7 +108,7 @@ class BlockAutoFillViewModelTest : BaseViewModelTest() {
val expectedState = BlockAutoFillState(
dialog = null,
viewState = BlockAutoFillState.ViewState.Content(
- blockedUris = listOf("http://b.com"),
+ blockedUris = persistentListOf("http://b.com"),
),
)
@@ -128,7 +132,7 @@ class BlockAutoFillViewModelTest : BaseViewModelTest() {
val expectedState = BlockAutoFillState(
dialog = null,
viewState = BlockAutoFillState.ViewState.Content(
- blockedUris = blockedUris,
+ blockedUris = blockedUris.toImmutableList(),
),
)
@@ -152,7 +156,11 @@ class BlockAutoFillViewModelTest : BaseViewModelTest() {
val expectedState = BlockAutoFillState(
dialog = null,
viewState = BlockAutoFillState.ViewState.Content(
- blockedUris = listOf("http://existing.com", "http://new.com", "http://another.com"),
+ blockedUris = persistentListOf(
+ "http://existing.com",
+ "http://new.com",
+ "http://another.com",
+ ),
),
)
@@ -189,7 +197,7 @@ class BlockAutoFillViewModelTest : BaseViewModelTest() {
val expectedState = BlockAutoFillState(
dialog = null,
viewState = BlockAutoFillState.ViewState.Content(
- blockedUris = listOf("http://other.com", "http://new.com"),
+ blockedUris = persistentListOf("http://other.com", "http://new.com"),
),
)
@@ -217,7 +225,7 @@ class BlockAutoFillViewModelTest : BaseViewModelTest() {
val expectedState = BlockAutoFillState(
dialog = null,
viewState = BlockAutoFillState.ViewState.Content(
- blockedUris = listOf("http://other.com", "http://same.com"),
+ blockedUris = persistentListOf("http://other.com", "http://same.com"),
),
)
@@ -249,7 +257,7 @@ class BlockAutoFillViewModelTest : BaseViewModelTest() {
errorMessage = BitwardenString.the_urix_is_already_blocked.asText("http://b.com"),
),
viewState = BlockAutoFillState.ViewState.Content(
- blockedUris = listOf("http://a.com", "http://b.com"),
+ blockedUris = persistentListOf("http://a.com", "http://b.com"),
),
)
diff --git a/ui/src/main/res/values/strings.xml b/ui/src/main/res/values/strings.xml
index 7e730a253d..44d2dae339 100644
--- a/ui/src/main/res/values/strings.xml
+++ b/ui/src/main/res/values/strings.xml
@@ -295,7 +295,6 @@ Scanning will happen automatically.
Text
What type of custom field do you want to add?
Remove
- New URI
Add website
Base domain
Default (%1$s)
@@ -667,7 +666,9 @@ Do you want to switch to this account?
You will be notified once approved.
Trouble logging in?
Block autofill
+ No URIs blocked
Autofill will not be offered for these URIs.
+ Edit blocked URI
New blocked URI
Invalid format. Use https://, http://, or androidapp://
Enter URI