Commit 41d06466 authored by Reda Tawfik's avatar Reda Tawfik Committed by Commit Bot

[Android][Mfill] Add search view to AllPasswordsBottomSheet

This CL adds a search view to the bottom sheet and filters
the credentials list with every newly typed character.

Screenshot: https://bugs.chromium.org/p/chromium/issues/detail?id=1104132#c18

Bug: 1104132
Change-Id: Ib9528abcc8ffa3981f37fe3d7334156aa71ff0fb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2391132
Commit-Queue: Reda Tawfik <redatawfik@google.com>
Reviewed-by: default avatarFriedrich [CET] <fhorschig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#807471}
parent 981f8f78
...@@ -3,9 +3,39 @@ ...@@ -3,9 +3,39 @@
Use of this source code is governed by a BSD-style license that can be Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. --> found in the LICENSE file. -->
<androidx.recyclerview.widget.RecyclerView <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_width="match_parent" /> android:layout_width="match_parent"
\ No newline at end of file android:orientation="vertical">
<TextView
android:id="@+id/sheet_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/all_passwords_bottom_sheet_title"
android:layout_marginEnd="@dimen/all_passwords_bottom_sheet_padding"
android:layout_marginStart="@dimen/all_passwords_bottom_sheet_padding"
android:layout_marginTop="@dimen/all_passwords_bottom_sheet_padding"
android:textAppearance="@style/TextAppearance.Headline.Primary" />
<SearchView
android:id="@+id/all_passwords_search_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:iconifiedByDefault="false"
android:layout_marginEnd="@dimen/all_passwords_bottom_sheet_search_view_padding"
android:layout_marginTop="@dimen/all_passwords_bottom_sheet_search_view_padding"
android:queryHint="@string/all_passwords_bottom_sheet_search_hint">
</SearchView>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/sheet_item_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_marginEnd="@dimen/all_passwords_bottom_sheet_recycler_view_padding"
android:layout_marginStart="@dimen/all_passwords_bottom_sheet_recycler_view_padding" />
</LinearLayout>
\ No newline at end of file
...@@ -27,4 +27,7 @@ ...@@ -27,4 +27,7 @@
<dimen name="keyboard_accessory_bar_item_cc_icon_width">32dp</dimen> <dimen name="keyboard_accessory_bar_item_cc_icon_width">32dp</dimen>
<dimen name="keyboard_accessory_tab_icon_width">40dp</dimen> <dimen name="keyboard_accessory_tab_icon_width">40dp</dimen>
<dimen name="keyboard_accessory_tab_size">@dimen/keyboard_accessory_height</dimen> <dimen name="keyboard_accessory_tab_size">@dimen/keyboard_accessory_height</dimen>
<dimen name="all_passwords_bottom_sheet_padding">20dp</dimen>
<dimen name="all_passwords_bottom_sheet_recycler_view_padding">6dp</dimen>
<dimen name="all_passwords_bottom_sheet_search_view_padding">14dp</dimen>
</resources> </resources>
...@@ -44,8 +44,8 @@ class AllPasswordsBottomSheetCoordinator { ...@@ -44,8 +44,8 @@ class AllPasswordsBottomSheetCoordinator {
*/ */
public void initialize(Context context, BottomSheetController sheetController, public void initialize(Context context, BottomSheetController sheetController,
AllPasswordsBottomSheetCoordinator.Delegate delegate) { AllPasswordsBottomSheetCoordinator.Delegate delegate) {
PropertyModel model = PropertyModel model = AllPasswordsBottomSheetProperties.createDefaultModel(
AllPasswordsBottomSheetProperties.createDefaultModel(mMediator::onDismissed); mMediator::onDismissed, mMediator::onQueryTextChange);
mMediator.initialize(delegate, model); mMediator.initialize(delegate, model);
setUpModelChangeProcessor(model, new AllPasswordsBottomSheetView(context, sheetController)); setUpModelChangeProcessor(model, new AllPasswordsBottomSheetView(context, sheetController));
} }
......
...@@ -11,6 +11,8 @@ import org.chromium.ui.modelutil.ListModel; ...@@ -11,6 +11,8 @@ import org.chromium.ui.modelutil.ListModel;
import org.chromium.ui.modelutil.MVCListAdapter.ListItem; import org.chromium.ui.modelutil.MVCListAdapter.ListItem;
import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel;
import java.util.Locale;
/** /**
* Contains the logic for the AllPasswordsBottomSheet. It sets the state of the model and reacts to * Contains the logic for the AllPasswordsBottomSheet. It sets the state of the model and reacts to
* events like clicks. * events like clicks.
...@@ -18,6 +20,8 @@ import org.chromium.ui.modelutil.PropertyModel; ...@@ -18,6 +20,8 @@ import org.chromium.ui.modelutil.PropertyModel;
class AllPasswordsBottomSheetMediator { class AllPasswordsBottomSheetMediator {
private AllPasswordsBottomSheetCoordinator.Delegate mDelegate; private AllPasswordsBottomSheetCoordinator.Delegate mDelegate;
private PropertyModel mModel; private PropertyModel mModel;
private Credential[] mCredentials;
private boolean mIsPasswordField;
void initialize(AllPasswordsBottomSheetCoordinator.Delegate delegate, PropertyModel model) { void initialize(AllPasswordsBottomSheetCoordinator.Delegate delegate, PropertyModel model) {
assert delegate != null; assert delegate != null;
...@@ -27,11 +31,13 @@ class AllPasswordsBottomSheetMediator { ...@@ -27,11 +31,13 @@ class AllPasswordsBottomSheetMediator {
void showCredentials(Credential[] credentials, boolean isPasswordField) { void showCredentials(Credential[] credentials, boolean isPasswordField) {
assert credentials != null; assert credentials != null;
mCredentials = credentials;
mIsPasswordField = isPasswordField;
ListModel<ListItem> sheetItems = mModel.get(SHEET_ITEMS); ListModel<ListItem> sheetItems = mModel.get(SHEET_ITEMS);
sheetItems.clear(); sheetItems.clear();
for (Credential credential : credentials) { for (Credential credential : mCredentials) {
final PropertyModel model = final PropertyModel model =
AllPasswordsBottomSheetProperties.CredentialProperties.createCredentialModel( AllPasswordsBottomSheetProperties.CredentialProperties.createCredentialModel(
credential, this::onCredentialSelected, isPasswordField); credential, this::onCredentialSelected, isPasswordField);
...@@ -42,6 +48,42 @@ class AllPasswordsBottomSheetMediator { ...@@ -42,6 +48,42 @@ class AllPasswordsBottomSheetMediator {
mModel.set(VISIBLE, true); mModel.set(VISIBLE, true);
} }
/**
* Filters the credentials list based on the passed text and adds the resulting credentials to
* the model.
* @param newText the text used to filter the credentials.
*/
void onQueryTextChange(String newText) {
ListModel<ListItem> sheetItems = mModel.get(SHEET_ITEMS);
sheetItems.clear();
for (Credential credential : mCredentials) {
if (shouldBeFiltered(newText, credential)) continue;
final PropertyModel model =
AllPasswordsBottomSheetProperties.CredentialProperties.createCredentialModel(
credential, this::onCredentialSelected, mIsPasswordField);
sheetItems.add(
new ListItem(AllPasswordsBottomSheetProperties.ItemType.CREDENTIAL, model));
}
}
/**
* Returns true if no substring in the passed credential matches the searchQuery ignoring the
* characters case.
* @param searchQuery the text to check if passed credential has it.
* @param credential its username and origin will be checked for matching string.
* @return Returns whether the entry with the passed credential should be filtered.
*/
private boolean shouldBeFiltered(final String searchQuery, final Credential credential) {
return searchQuery != null
&& !credential.getOriginUrl()
.toLowerCase(Locale.ENGLISH)
.contains(searchQuery.toLowerCase(Locale.ENGLISH))
&& !credential.getUsername()
.toLowerCase(Locale.getDefault())
.contains(searchQuery.toLowerCase(Locale.getDefault()));
}
void onCredentialSelected(Credential credential) { void onCredentialSelected(Credential credential) {
mModel.set(VISIBLE, false); mModel.set(VISIBLE, false);
mDelegate.onCredentialSelected(credential); mDelegate.onCredentialSelected(credential);
......
...@@ -26,14 +26,19 @@ class AllPasswordsBottomSheetProperties { ...@@ -26,14 +26,19 @@ class AllPasswordsBottomSheetProperties {
new PropertyModel.ReadableObjectPropertyKey<>("dismiss_handler"); new PropertyModel.ReadableObjectPropertyKey<>("dismiss_handler");
static final PropertyModel.ReadableObjectPropertyKey<ListModel<ListItem>> SHEET_ITEMS = static final PropertyModel.ReadableObjectPropertyKey<ListModel<ListItem>> SHEET_ITEMS =
new PropertyModel.ReadableObjectPropertyKey<>("sheet_items"); new PropertyModel.ReadableObjectPropertyKey<>("sheet_items");
static final PropertyModel.ReadableObjectPropertyKey<Callback<String>> ON_QUERY_TEXT_CHANGE =
new PropertyModel.ReadableObjectPropertyKey<>("on_query_text_change");
static final PropertyKey[] ALL_KEYS = {VISIBLE, DISMISS_HANDLER, SHEET_ITEMS}; static final PropertyKey[] ALL_KEYS = {
VISIBLE, DISMISS_HANDLER, SHEET_ITEMS, ON_QUERY_TEXT_CHANGE};
static PropertyModel createDefaultModel(Callback<Integer> handler) { static PropertyModel createDefaultModel(
Callback<Integer> dismissHandler, Callback<String> onSearchQueryChangeHandler) {
return new PropertyModel.Builder(ALL_KEYS) return new PropertyModel.Builder(ALL_KEYS)
.with(VISIBLE, false) .with(VISIBLE, false)
.with(SHEET_ITEMS, new ListModel<>()) .with(SHEET_ITEMS, new ListModel<>())
.with(DISMISS_HANDLER, handler) .with(DISMISS_HANDLER, dismissHandler)
.with(ON_QUERY_TEXT_CHANGE, onSearchQueryChangeHandler)
.build(); .build();
} }
......
...@@ -7,6 +7,9 @@ package org.chromium.chrome.browser.keyboard_accessory.all_passwords_bottom_shee ...@@ -7,6 +7,9 @@ package org.chromium.chrome.browser.keyboard_accessory.all_passwords_bottom_shee
import android.content.Context; import android.content.Context;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.LinearLayout;
import android.widget.SearchView;
import android.widget.SearchView.OnQueryTextListener;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
...@@ -28,6 +31,7 @@ class AllPasswordsBottomSheetView implements BottomSheetContent { ...@@ -28,6 +31,7 @@ class AllPasswordsBottomSheetView implements BottomSheetContent {
private final BottomSheetController mBottomSheetController; private final BottomSheetController mBottomSheetController;
private Callback<Integer> mDismissHandler; private Callback<Integer> mDismissHandler;
private final RecyclerView mSheetItemListView; private final RecyclerView mSheetItemListView;
private final LinearLayout mContentView;
private final BottomSheetObserver mBottomSheetObserver = new EmptyBottomSheetObserver() { private final BottomSheetObserver mBottomSheetObserver = new EmptyBottomSheetObserver() {
@Override @Override
...@@ -57,8 +61,9 @@ class AllPasswordsBottomSheetView implements BottomSheetContent { ...@@ -57,8 +61,9 @@ class AllPasswordsBottomSheetView implements BottomSheetContent {
public AllPasswordsBottomSheetView( public AllPasswordsBottomSheetView(
Context context, BottomSheetController bottomSheetController) { Context context, BottomSheetController bottomSheetController) {
mBottomSheetController = bottomSheetController; mBottomSheetController = bottomSheetController;
mSheetItemListView = (RecyclerView) LayoutInflater.from(context).inflate( mContentView = (LinearLayout) LayoutInflater.from(context).inflate(
R.layout.all_passwords_bottom_sheet, null); R.layout.all_passwords_bottom_sheet, null);
mSheetItemListView = mContentView.findViewById(R.id.sheet_item_list);
mSheetItemListView.setLayoutManager(new LinearLayoutManager( mSheetItemListView.setLayoutManager(new LinearLayoutManager(
mSheetItemListView.getContext(), LinearLayoutManager.VERTICAL, false)); mSheetItemListView.getContext(), LinearLayoutManager.VERTICAL, false));
mSheetItemListView.setItemAnimator(null); mSheetItemListView.setItemAnimator(null);
...@@ -93,9 +98,28 @@ class AllPasswordsBottomSheetView implements BottomSheetContent { ...@@ -93,9 +98,28 @@ class AllPasswordsBottomSheetView implements BottomSheetContent {
mSheetItemListView.setAdapter(adapter); mSheetItemListView.setAdapter(adapter);
} }
void setSearchQueryChangeHandler(Callback<String> callback) {
SearchView searchView = getSearchView();
searchView.setOnQueryTextListener(new OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
return false;
}
@Override
public boolean onQueryTextChange(String newString) {
callback.onResult(newString);
return true;
}
});
}
public SearchView getSearchView() {
return mContentView.findViewById(R.id.all_passwords_search_view);
}
@Override @Override
public View getContentView() { public View getContentView() {
return mSheetItemListView; return mContentView;
} }
@Nullable @Nullable
...@@ -106,7 +130,7 @@ class AllPasswordsBottomSheetView implements BottomSheetContent { ...@@ -106,7 +130,7 @@ class AllPasswordsBottomSheetView implements BottomSheetContent {
@Override @Override
public int getVerticalScrollOffset() { public int getVerticalScrollOffset() {
return 0; return mSheetItemListView.computeVerticalScrollOffset();
} }
@Override @Override
......
...@@ -8,6 +8,7 @@ import static org.chromium.chrome.browser.keyboard_accessory.all_passwords_botto ...@@ -8,6 +8,7 @@ import static org.chromium.chrome.browser.keyboard_accessory.all_passwords_botto
import static org.chromium.chrome.browser.keyboard_accessory.all_passwords_bottom_sheet.AllPasswordsBottomSheetProperties.CredentialProperties.IS_PASSWORD_FIELD; import static org.chromium.chrome.browser.keyboard_accessory.all_passwords_bottom_sheet.AllPasswordsBottomSheetProperties.CredentialProperties.IS_PASSWORD_FIELD;
import static org.chromium.chrome.browser.keyboard_accessory.all_passwords_bottom_sheet.AllPasswordsBottomSheetProperties.CredentialProperties.ON_CLICK_LISTENER; import static org.chromium.chrome.browser.keyboard_accessory.all_passwords_bottom_sheet.AllPasswordsBottomSheetProperties.CredentialProperties.ON_CLICK_LISTENER;
import static org.chromium.chrome.browser.keyboard_accessory.all_passwords_bottom_sheet.AllPasswordsBottomSheetProperties.DISMISS_HANDLER; import static org.chromium.chrome.browser.keyboard_accessory.all_passwords_bottom_sheet.AllPasswordsBottomSheetProperties.DISMISS_HANDLER;
import static org.chromium.chrome.browser.keyboard_accessory.all_passwords_bottom_sheet.AllPasswordsBottomSheetProperties.ON_QUERY_TEXT_CHANGE;
import static org.chromium.chrome.browser.keyboard_accessory.all_passwords_bottom_sheet.AllPasswordsBottomSheetProperties.SHEET_ITEMS; import static org.chromium.chrome.browser.keyboard_accessory.all_passwords_bottom_sheet.AllPasswordsBottomSheetProperties.SHEET_ITEMS;
import static org.chromium.chrome.browser.keyboard_accessory.all_passwords_bottom_sheet.AllPasswordsBottomSheetProperties.VISIBLE; import static org.chromium.chrome.browser.keyboard_accessory.all_passwords_bottom_sheet.AllPasswordsBottomSheetProperties.VISIBLE;
...@@ -50,6 +51,8 @@ class AllPasswordsBottomSheetViewBinder { ...@@ -50,6 +51,8 @@ class AllPasswordsBottomSheetViewBinder {
view.setDismissHandler(model.get(DISMISS_HANDLER)); view.setDismissHandler(model.get(DISMISS_HANDLER));
} else if (propertyKey == VISIBLE) { } else if (propertyKey == VISIBLE) {
view.setVisible(model.get(VISIBLE)); view.setVisible(model.get(VISIBLE));
} else if (propertyKey == ON_QUERY_TEXT_CHANGE) {
view.setSearchQueryChangeHandler(model.get(ON_QUERY_TEXT_CHANGE));
} else if (propertyKey == SHEET_ITEMS) { } else if (propertyKey == SHEET_ITEMS) {
view.setSheetItemListAdapter(new RecyclerViewAdapter<>( view.setSheetItemListAdapter(new RecyclerViewAdapter<>(
new SimpleRecyclerViewMcp<>(model.get(SHEET_ITEMS), new SimpleRecyclerViewMcp<>(model.get(SHEET_ITEMS),
......
...@@ -180,6 +180,12 @@ ...@@ -180,6 +180,12 @@
<message name="IDS_ALL_PASSWORDS_BOTTOM_SHEET_CLOSED" desc="Accessibility string read when the all passwords bottom sheet showing a list of the user's credentials is closed."> <message name="IDS_ALL_PASSWORDS_BOTTOM_SHEET_CLOSED" desc="Accessibility string read when the all passwords bottom sheet showing a list of the user's credentials is closed.">
List of credentials to be filled on touch is closed. List of credentials to be filled on touch is closed.
</message> </message>
<message name="IDS_ALL_PASSWORDS_BOTTOM_SHEET_TITLE" desc="The title string for the all passwords bottom sheet showing a list of the user's credentials.">
Passwords
</message>
<message name="IDS_ALL_PASSWORDS_BOTTOM_SHEET_SEARCH_HINT" desc="The label for a search button appears in all passwords bottom sheet.">
Search
</message>
<message name="IDS_AUTOFILL_KEYBOARD_ACCESSORY_CONTENT_DESCRIPTION" desc="The text announced by the screen reader when the password suggestions are shown."> <message name="IDS_AUTOFILL_KEYBOARD_ACCESSORY_CONTENT_DESCRIPTION" desc="The text announced by the screen reader when the password suggestions are shown.">
Passwords available Passwords available
</message> </message>
......
...@@ -61,6 +61,8 @@ public class AllPasswordsBottomSheetViewTest { ...@@ -61,6 +61,8 @@ public class AllPasswordsBottomSheetViewTest {
private Callback<Integer> mDismissHandler; private Callback<Integer> mDismissHandler;
@Mock @Mock
private Callback<Credential> mCredentialCallback; private Callback<Credential> mCredentialCallback;
@Mock
private Callback<String> mSearchQueryCallback;
private PropertyModel mModel; private PropertyModel mModel;
private AllPasswordsBottomSheetView mAllPasswordsBottomSheetView; private AllPasswordsBottomSheetView mAllPasswordsBottomSheetView;
...@@ -73,7 +75,8 @@ public class AllPasswordsBottomSheetViewTest { ...@@ -73,7 +75,8 @@ public class AllPasswordsBottomSheetViewTest {
public void setUp() throws InterruptedException { public void setUp() throws InterruptedException {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
mActivityTestRule.startMainActivityOnBlankPage(); mActivityTestRule.startMainActivityOnBlankPage();
mModel = AllPasswordsBottomSheetProperties.createDefaultModel(mDismissHandler); mModel = AllPasswordsBottomSheetProperties.createDefaultModel(
mDismissHandler, mSearchQueryCallback);
mBottomSheetController = mActivityTestRule.getActivity() mBottomSheetController = mActivityTestRule.getActivity()
.getRootUiCoordinatorForTesting() .getRootUiCoordinatorForTesting()
.getBottomSheetController(); .getBottomSheetController();
...@@ -102,24 +105,7 @@ public class AllPasswordsBottomSheetViewTest { ...@@ -102,24 +105,7 @@ public class AllPasswordsBottomSheetViewTest {
@Test @Test
@MediumTest @MediumTest
public void testCredentialsChangedByModel() { public void testCredentialsChangedByModel() {
TestThreadUtils.runOnUiThreadBlocking(() -> { addDefaultCredentialsToTheModel();
mAllPasswordsBottomSheetView.setVisible(true);
mModel.get(SHEET_ITEMS)
.add(new ListItem(AllPasswordsBottomSheetProperties.ItemType.CREDENTIAL,
AllPasswordsBottomSheetProperties.CredentialProperties
.createCredentialModel(
ANA, mCredentialCallback, IS_PASSWORD_FIELD)));
mModel.get(SHEET_ITEMS)
.add(new ListItem(AllPasswordsBottomSheetProperties.ItemType.CREDENTIAL,
AllPasswordsBottomSheetProperties.CredentialProperties
.createCredentialModel(
NO_ONE, mCredentialCallback, IS_PASSWORD_FIELD)));
mModel.get(SHEET_ITEMS)
.add(new ListItem(AllPasswordsBottomSheetProperties.ItemType.CREDENTIAL,
AllPasswordsBottomSheetProperties.CredentialProperties
.createCredentialModel(
BOB, mCredentialCallback, IS_PASSWORD_FIELD)));
});
pollUiThread(() -> getBottomSheetState() == SheetState.FULL); pollUiThread(() -> getBottomSheetState() == SheetState.FULL);
assertThat(getCredentials().getChildCount(), is(3)); assertThat(getCredentials().getChildCount(), is(3));
...@@ -163,6 +149,8 @@ public class AllPasswordsBottomSheetViewTest { ...@@ -163,6 +149,8 @@ public class AllPasswordsBottomSheetViewTest {
@Test @Test
@MediumTest @MediumTest
public void testDismissesWhenHidden() { public void testDismissesWhenHidden() {
addDefaultCredentialsToTheModel();
TestThreadUtils.runOnUiThreadBlocking(() -> mModel.set(VISIBLE, true)); TestThreadUtils.runOnUiThreadBlocking(() -> mModel.set(VISIBLE, true));
pollUiThread(() -> getBottomSheetState() == SheetState.FULL); pollUiThread(() -> getBottomSheetState() == SheetState.FULL);
TestThreadUtils.runOnUiThreadBlocking(() -> mModel.set(VISIBLE, false)); TestThreadUtils.runOnUiThreadBlocking(() -> mModel.set(VISIBLE, false));
...@@ -170,6 +158,35 @@ public class AllPasswordsBottomSheetViewTest { ...@@ -170,6 +158,35 @@ public class AllPasswordsBottomSheetViewTest {
verify(mDismissHandler).onResult(BottomSheetController.StateChangeReason.NONE); verify(mDismissHandler).onResult(BottomSheetController.StateChangeReason.NONE);
} }
@Test
@MediumTest
public void testSearchIsCalledOnSearchQueryChange() {
addDefaultCredentialsToTheModel();
pollUiThread(() -> mAllPasswordsBottomSheetView.getSearchView().setQuery("a", false));
verify(mSearchQueryCallback).onResult("a");
}
// Adds three credentials items to the model.
private void addDefaultCredentialsToTheModel() {
TestThreadUtils.runOnUiThreadBlocking(() -> {
mAllPasswordsBottomSheetView.setVisible(true);
mModel.get(SHEET_ITEMS)
.add(new ListItem(AllPasswordsBottomSheetProperties.ItemType.CREDENTIAL,
AllPasswordsBottomSheetProperties.CredentialProperties
.createCredentialModel(
ANA, mCredentialCallback, IS_PASSWORD_FIELD)));
mModel.get(SHEET_ITEMS)
.add(new ListItem(AllPasswordsBottomSheetProperties.ItemType.CREDENTIAL,
AllPasswordsBottomSheetProperties.CredentialProperties
.createCredentialModel(
NO_ONE, mCredentialCallback, IS_PASSWORD_FIELD)));
mModel.get(SHEET_ITEMS)
.add(new ListItem(AllPasswordsBottomSheetProperties.ItemType.CREDENTIAL,
AllPasswordsBottomSheetProperties.CredentialProperties
.createCredentialModel(
BOB, mCredentialCallback, IS_PASSWORD_FIELD)));
});
}
private ChromeActivity getActivity() { private ChromeActivity getActivity() {
return mActivityTestRule.getActivity(); return mActivityTestRule.getActivity();
} }
...@@ -179,7 +196,8 @@ public class AllPasswordsBottomSheetViewTest { ...@@ -179,7 +196,8 @@ public class AllPasswordsBottomSheetViewTest {
} }
private RecyclerView getCredentials() { private RecyclerView getCredentials() {
return (RecyclerView) mAllPasswordsBottomSheetView.getContentView(); return (RecyclerView) mAllPasswordsBottomSheetView.getContentView().findViewById(
R.id.sheet_item_list);
} }
private TextView getCredentialOriginAt(int index) { private TextView getCredentialOriginAt(int index) {
......
...@@ -56,7 +56,8 @@ public class AllPasswordsBottomSheetControllerTest { ...@@ -56,7 +56,8 @@ public class AllPasswordsBottomSheetControllerTest {
public void setUp() { public void setUp() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
mMediator = new AllPasswordsBottomSheetMediator(); mMediator = new AllPasswordsBottomSheetMediator();
mModel = AllPasswordsBottomSheetProperties.createDefaultModel(mMediator::onDismissed); mModel = AllPasswordsBottomSheetProperties.createDefaultModel(
mMediator::onDismissed, mMediator::onQueryTextChange);
mMediator.initialize(mMockDelegate, mModel); mMediator.initialize(mMockDelegate, mModel);
} }
...@@ -102,4 +103,18 @@ public class AllPasswordsBottomSheetControllerTest { ...@@ -102,4 +103,18 @@ public class AllPasswordsBottomSheetControllerTest {
assertThat(mModel.get(VISIBLE), is(false)); assertThat(mModel.get(VISIBLE), is(false));
verify(mMockDelegate).onDismissed(); verify(mMockDelegate).onDismissed();
} }
@Test
public void testSearchFilterByUsername() {
mMediator.showCredentials(TEST_CREDENTIALS, IS_PASSWORD_FIELD);
mMediator.onQueryTextChange("Bob");
assertThat(mModel.get(SHEET_ITEMS).size(), is(1));
}
@Test
public void testSearchFilterByURL() {
mMediator.showCredentials(TEST_CREDENTIALS, IS_PASSWORD_FIELD);
mMediator.onQueryTextChange("subdomain");
assertThat(mModel.get(SHEET_ITEMS).size(), is(1));
}
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment