Skip to content

Commit

Permalink
Add warning to password management screen for incompatible WebViews
Browse files Browse the repository at this point in the history
  • Loading branch information
CDRussell committed Apr 11, 2024
1 parent 33acbf8 commit 3afba55
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import com.duckduckgo.app.browser.favicon.FaviconManager
import com.duckduckgo.app.statistics.pixels.Pixel
import com.duckduckgo.autofill.api.domain.app.LoginCredentials
import com.duckduckgo.autofill.api.email.EmailManager
import com.duckduckgo.autofill.impl.InternalAutofillCapabilityChecker
import com.duckduckgo.autofill.impl.R
import com.duckduckgo.autofill.impl.deviceauth.DeviceAuthenticator
import com.duckduckgo.autofill.impl.deviceauth.DeviceAuthenticator.AuthConfiguration
Expand Down Expand Up @@ -107,6 +108,7 @@ class AutofillSettingsViewModel @Inject constructor(
private val duckAddressIdentifier: DuckAddressIdentifier,
private val syncEngine: SyncEngine,
private val neverSavedSiteRepository: NeverSavedSiteRepository,
private val capabilityChecker: InternalAutofillCapabilityChecker,
) : ViewModel() {

private val _viewState = MutableStateFlow(ViewState())
Expand Down Expand Up @@ -360,7 +362,11 @@ class AutofillSettingsViewModel @Inject constructor(
fun onViewCreated() {
if (combineJob != null) return
combineJob = viewModelScope.launch(dispatchers.io()) {
_viewState.value = _viewState.value.copy(autofillEnabled = autofillStore.autofillEnabled)
_viewState.value = _viewState.value.copy(
autofillEnabled = autofillStore.autofillEnabled,
webViewCompatible = capabilityChecker.webViewSupportsAutofill(),
)

val allCredentials = autofillStore.getAllCredentials().distinctUntilChanged()
val combined = allCredentials.combine(searchQueryFilter) { credentials, filter ->
credentialListFilter.filter(credentials, filter)
Expand Down Expand Up @@ -640,6 +646,7 @@ class AutofillSettingsViewModel @Inject constructor(
val logins: List<LoginCredentials>? = null,
val credentialMode: CredentialMode? = null,
val credentialSearchQuery: String = "",
val webViewCompatible: Boolean = true,
)

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,12 @@ class AutofillManagementListMode : DuckDuckGoFragment(R.layout.fragment_autofill
binding.credentialToggleGroup.gone()
binding.logins.updateTopMargin(resources.getDimensionPixelSize(CommonR.dimen.keyline_4))
}

if (state.webViewCompatible) {
binding.webViewUnsupportedWarningPanel.gone()
} else {
binding.webViewUnsupportedWarningPanel.show()
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">

<com.duckduckgo.common.ui.view.InfoPanel
android:id="@+id/webViewUnsupportedWarningPanel"
style="@style/Widget.DuckDuckGo.InfoPanel"
android:visibility="gone"
android:layout_margin="@dimen/keyline_4"
app:panelText="@string/credentialManagementWebViewIncompatibleErrorMessage"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:panelBackground="@drawable/info_panel_alert_background"
app:panelDrawable="@drawable/ic_info_panel_alert" />

<com.duckduckgo.common.ui.view.listitem.TwoLineListItem
android:id="@+id/enabledToggle"
android:layout_width="0dp"
Expand All @@ -36,7 +48,7 @@
app:showSwitch="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintTop_toBottomOf="@id/webViewUnsupportedWarningPanel"/>

<com.duckduckgo.common.ui.view.divider.HorizontalDivider
android:id="@+id/topDivider"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import com.duckduckgo.app.statistics.pixels.Pixel.PixelName
import com.duckduckgo.app.statistics.pixels.Pixel.PixelType.COUNT
import com.duckduckgo.autofill.api.domain.app.LoginCredentials
import com.duckduckgo.autofill.api.email.EmailManager
import com.duckduckgo.autofill.impl.InternalAutofillCapabilityChecker
import com.duckduckgo.autofill.impl.deviceauth.DeviceAuthenticator
import com.duckduckgo.autofill.impl.pixel.AutofillPixelNames.AUTOFILL_ENABLE_AUTOFILL_TOGGLE_MANUALLY_DISABLED
import com.duckduckgo.autofill.impl.pixel.AutofillPixelNames.AUTOFILL_ENABLE_AUTOFILL_TOGGLE_MANUALLY_ENABLED
Expand Down Expand Up @@ -91,6 +92,7 @@ class AutofillSettingsViewModelTest {
private val webUrlIdentifier: WebUrlIdentifier = mock()
private val duckAddressIdentifier: DuckAddressIdentifier = RealDuckAddressIdentifier()
private val neverSavedSiteRepository: NeverSavedSiteRepository = mock()
private val capabilityChecker: InternalAutofillCapabilityChecker = mock()
private val testee = AutofillSettingsViewModel(
autofillStore = mockStore,
clipboardInteractor = clipboardInteractor,
Expand All @@ -105,6 +107,7 @@ class AutofillSettingsViewModelTest {
duckAddressIdentifier = duckAddressIdentifier,
syncEngine = mock(),
neverSavedSiteRepository = neverSavedSiteRepository,
capabilityChecker = capabilityChecker,
)

@Before
Expand Down Expand Up @@ -568,6 +571,26 @@ class AutofillSettingsViewModelTest {
}
}

@Test
fun whenInListModeAndWebViewCompatibleThenPassedInViewState() = runTest {
whenever(capabilityChecker.webViewSupportsAutofill()).thenReturn(true)
testee.onViewCreated()
testee.viewState.test {
assertTrue(awaitItem().webViewCompatible)
cancelAndIgnoreRemainingEvents()
}
}

@Test
fun whenInListModeAndWebViewIncompatibleThenPassedInViewState() = runTest {
whenever(capabilityChecker.webViewSupportsAutofill()).thenReturn(false)
testee.onViewCreated()
testee.viewState.test {
assertFalse(awaitItem().webViewCompatible)
cancelAndIgnoreRemainingEvents()
}
}

@Test
fun whenObserveCredentialsCalledWithAutofillDisabledThenAutofillEnabledStateIsReturned() = runTest {
whenever(mockStore.autofillEnabled).thenReturn(false)
Expand Down

0 comments on commit 3afba55

Please sign in to comment.