Commit e7c76c98 authored by Xing Liu's avatar Xing Liu Committed by Commit Bot

Read later: Implement bookmark bottom sheet view and click event.

This CL implements more details for bookmark bottom sheet.

The contents includes:

1. Load bookmark top level data to bottom sheet.
2. Implement the click event.
3. Implement the view holder. Reuse BookmarkRow but plumb data
through MVC view binder, might be good for future development.
4. A few integration tests are added to BookmarkBottomSheetTest.

doc: go/chrome-bottomsheet-mvc

Bug: 1133496
Change-Id: Id5ce9abb44351c3a6a350531e1622f08c725a1f0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2537785
Commit-Queue: Xing Liu <xingliu@chromium.org>
Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Reviewed-by: default avatarBrandon Wylie <wylieb@chromium.org>
Reviewed-by: default avatarShakti Sahu <shaktisahu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#828424}
parent 6d02181d
......@@ -776,6 +776,7 @@ chrome_java_resources = [
"java/res/layout/bookmark_action_bar.xml",
"java/res/layout/bookmark_add_edit_folder_activity.xml",
"java/res/layout/bookmark_bottom_sheet.xml",
"java/res/layout/bookmark_bottom_sheet_folder_row.xml",
"java/res/layout/bookmark_edit.xml",
"java/res/layout/bookmark_folder_row.xml",
"java/res/layout/bookmark_folder_select_activity.xml",
......
......@@ -168,6 +168,9 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeader.java",
"java/src/org/chromium/chrome/browser/bookmarks/bottomsheet/BookmarkBottomSheetContent.java",
"java/src/org/chromium/chrome/browser/bookmarks/bottomsheet/BookmarkBottomSheetCoordinator.java",
"java/src/org/chromium/chrome/browser/bookmarks/bottomsheet/BookmarkBottomSheetFolderRow.java",
"java/src/org/chromium/chrome/browser/bookmarks/bottomsheet/BookmarkBottomSheetItemProperties.java",
"java/src/org/chromium/chrome/browser/bookmarks/bottomsheet/BookmarkBottomSheetRowViewBinder.java",
"java/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkWidgetProvider.java",
"java/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkWidgetProxy.java",
"java/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkWidgetServiceImpl.java",
......
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2020 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<view class="org.chromium.chrome.browser.bookmarks.bottomsheet.BookmarkBottomSheetFolderRow"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
......@@ -448,41 +448,7 @@ class BookmarkItemsAdapter extends DragReorderableListAdapter<BookmarkListEntry>
}
private void populateTopLevelFoldersList() {
BookmarkId desktopNodeId = mDelegate.getModel().getDesktopFolderId();
BookmarkId mobileNodeId = mDelegate.getModel().getMobileFolderId();
BookmarkId othersNodeId = mDelegate.getModel().getOtherFolderId();
List<BookmarkId> specialFoldersIds =
mDelegate.getModel().getTopLevelFolderIDs(/*getSpecial=*/true, /*getNormal=*/false);
BookmarkId rootFolder = mDelegate.getModel().getRootFolderId();
// managed and partner bookmark folders will be put to the bottom.
List<BookmarkId> managedAndPartnerFolderIds = new ArrayList<>();
for (BookmarkId bookmarkId : specialFoldersIds) {
// Adds reading list as the first top level folder.
if (bookmarkId.getType() == BookmarkType.READING_LIST) {
mTopLevelFolders.add(bookmarkId);
continue;
}
BookmarkId parent = mDelegate.getModel().getBookmarkById(bookmarkId).getParentId();
if (parent.equals(rootFolder)) managedAndPartnerFolderIds.add(bookmarkId);
}
// Adds normal bookmark top level folders.
if (mDelegate.getModel().isFolderVisible(mobileNodeId)) {
mTopLevelFolders.add(mobileNodeId);
}
if (mDelegate.getModel().isFolderVisible(desktopNodeId)) {
mTopLevelFolders.add(desktopNodeId);
}
if (mDelegate.getModel().isFolderVisible(othersNodeId)) {
mTopLevelFolders.add(othersNodeId);
}
// Add any top-level managed and partner bookmark folders that are children of the root
// folder.
mTopLevelFolders.addAll(managedAndPartnerFolderIds);
mTopLevelFolders.addAll(BookmarkUtils.populateTopLevelFolders(mDelegate.getModel()));
}
@VisibleForTesting
......
......@@ -37,7 +37,8 @@ import java.util.List;
/**
* Common logic for bookmark and folder rows.
*/
abstract class BookmarkRow extends SelectableItemView<BookmarkId> implements BookmarkUIObserver {
public abstract class BookmarkRow
extends SelectableItemView<BookmarkId> implements BookmarkUIObserver {
protected ListMenuButton mMoreIcon;
protected ImageView mDragHandle;
protected BookmarkDelegate mDelegate;
......
......@@ -37,6 +37,9 @@ import org.chromium.components.embedder_support.util.UrlConstants;
import org.chromium.ui.base.DeviceFormFactor;
import org.chromium.ui.base.PageTransition;
import java.util.ArrayList;
import java.util.List;
/**
* A class holding static util functions for bookmark.
*/
......@@ -333,4 +336,49 @@ public class BookmarkUtils {
((Activity) context).finish();
}
}
/**
* Populates the top level bookmark folder ids.
* @param bookmarkModel The bookmark model that talks to bookmark native backend.
* @return The list of top level bookmark folder ids.
*/
public static List<BookmarkId> populateTopLevelFolders(BookmarkModel bookmarkModel) {
List<BookmarkId> topLevelFolders = new ArrayList<>();
BookmarkId desktopNodeId = bookmarkModel.getDesktopFolderId();
BookmarkId mobileNodeId = bookmarkModel.getMobileFolderId();
BookmarkId othersNodeId = bookmarkModel.getOtherFolderId();
List<BookmarkId> specialFoldersIds =
bookmarkModel.getTopLevelFolderIDs(/*getSpecial=*/true, /*getNormal=*/false);
BookmarkId rootFolder = bookmarkModel.getRootFolderId();
// managed and partner bookmark folders will be put to the bottom.
List<BookmarkId> managedAndPartnerFolderIds = new ArrayList<>();
for (BookmarkId bookmarkId : specialFoldersIds) {
// Adds reading list as the first top level folder.
if (bookmarkId.getType() == BookmarkType.READING_LIST) {
topLevelFolders.add(bookmarkId);
continue;
}
BookmarkId parent = bookmarkModel.getBookmarkById(bookmarkId).getParentId();
if (parent.equals(rootFolder)) managedAndPartnerFolderIds.add(bookmarkId);
}
// Adds normal bookmark top level folders.
if (bookmarkModel.isFolderVisible(mobileNodeId)) {
topLevelFolders.add(mobileNodeId);
}
if (bookmarkModel.isFolderVisible(desktopNodeId)) {
topLevelFolders.add(desktopNodeId);
}
if (bookmarkModel.isFolderVisible(othersNodeId)) {
topLevelFolders.add(othersNodeId);
}
// Add any top-level managed and partner bookmark folders that are children of the root
// folder.
topLevelFolders.addAll(managedAndPartnerFolderIds);
return topLevelFolders;
}
}
......@@ -9,12 +9,28 @@ import android.view.LayoutInflater;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.chromium.base.Callback;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
import org.chromium.chrome.browser.bookmarks.BookmarkModel;
import org.chromium.chrome.browser.bookmarks.BookmarkUtils;
import org.chromium.chrome.browser.bookmarks.bottomsheet.BookmarkBottomSheetItemProperties.ItemType;
import org.chromium.components.bookmarks.BookmarkId;
import org.chromium.components.bookmarks.BookmarkType;
import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
import org.chromium.ui.modelutil.LayoutViewBuilder;
import org.chromium.ui.modelutil.MVCListAdapter.ListItem;
import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
import org.chromium.ui.modelutil.PropertyModel;
import org.chromium.ui.modelutil.SimpleRecyclerViewAdapter;
import java.util.List;
/**
* The coordinator used to show the bookmark bottom sheet when trying to add a bookmark. The bottom
* sheet contains a list of folders that the bookmark can be added to.
......@@ -22,31 +38,105 @@ import org.chromium.ui.modelutil.SimpleRecyclerViewAdapter;
public class BookmarkBottomSheetCoordinator {
private final BottomSheetController mBottomSheetController;
private final Context mContext;
private final Callback<BookmarkItem> mCallback;
private BookmarkBottomSheetContent mBottomSheetContent;
private BookmarkModel mBookmarkModel;
/**
* Constructs the bookmark bottom sheet.
* @param context The Android context that contains the bookmark bottom sheet.
* @param bottomSheetController The controller to perform operations on the bottom sheet.
* @param bookmarkModel Bookmark model that loads data from the backend, must have been
* initialized.
* @param callback Invoked when the user clicked on a certain bookmark item.
*/
public BookmarkBottomSheetCoordinator(
Context context, @NonNull BottomSheetController bottomSheetController) {
public BookmarkBottomSheetCoordinator(Context context,
@NonNull BottomSheetController bottomSheetController,
@NonNull BookmarkModel bookmarkModel, @NonNull Callback<BookmarkItem> callback) {
mContext = context;
mBottomSheetController = bottomSheetController;
mBookmarkModel = bookmarkModel;
mCallback = callback;
}
/**
* Shows the bookmark bottom sheet.
*/
public void show() {
assert mBookmarkModel.isBookmarkModelLoaded();
// Load bookmark model data into recycler view.
View contentView = LayoutInflater.from(mContext).inflate(
org.chromium.chrome.R.layout.bookmark_bottom_sheet, /*root=*/null);
RecyclerView sheetItemListView =
contentView.findViewById(org.chromium.chrome.R.id.sheet_item_list);
// TODO(xingliu): Load actual top level bookmark folders.
sheetItemListView.setAdapter(new SimpleRecyclerViewAdapter(new ModelList()));
SimpleRecyclerViewAdapter adapter = new SimpleRecyclerViewAdapter(loadTopLevelFolders());
adapter.registerType(ItemType.FOLDER_ROW,
new LayoutViewBuilder(R.layout.bookmark_bottom_sheet_folder_row),
BookmarkBottomSheetRowViewBinder::bind);
sheetItemListView.setAdapter(adapter);
sheetItemListView.setLayoutManager(new LinearLayoutManager(mContext));
// Show the bottom sheet.
mBottomSheetContent = new BookmarkBottomSheetContent(
contentView, sheetItemListView::computeHorizontalScrollOffset);
mBottomSheetController.requestShowContent(mBottomSheetContent, /*animate=*/false);
}
// Loads top level bookmark folders into a ModelList.
private ModelList loadTopLevelFolders() {
List<BookmarkId> topLevelFolderIDs = BookmarkUtils.populateTopLevelFolders(mBookmarkModel);
ModelList modelList = new ModelList();
for (BookmarkId folderId : topLevelFolderIDs) {
BookmarkItem folderItem = mBookmarkModel.getBookmarkById(folderId);
modelList.add(new ListItem(ItemType.FOLDER_ROW, buildItemModel(folderItem)));
}
return modelList;
}
// Build the model for a single item in the bookmark bottom sheet.
private PropertyModel buildItemModel(BookmarkItem bookmarkItem) {
PropertyModel model =
new PropertyModel.Builder(BookmarkBottomSheetItemProperties.ALL_KEYS)
.with(BookmarkBottomSheetItemProperties.TITLE, bookmarkItem.getTitle())
.with(BookmarkBottomSheetItemProperties.SUBTITLE, getSubtitle(bookmarkItem))
.with(BookmarkBottomSheetItemProperties.ON_CLICK_LISTENER,
() -> onClick(bookmarkItem))
.build();
return model;
}
private @Nullable String getSubtitle(@NonNull final BookmarkItem bookmarkItem) {
switch (bookmarkItem.getId().getType()) {
case BookmarkType.NORMAL:
int totalCount = mBookmarkModel.getTotalBookmarkCount(bookmarkItem.getId());
return totalCount > 0 ? mContext.getResources().getQuantityString(
R.plurals.bookmarks_count, totalCount, totalCount)
: mContext.getResources().getString(R.string.no_bookmarks);
case BookmarkType.READING_LIST:
List<BookmarkId> children = mBookmarkModel.getChildIDs(bookmarkItem.getId());
int unreadCount = 0;
for (BookmarkId child : children) {
BookmarkItem childItem = mBookmarkModel.getBookmarkById(child);
if (!childItem.isRead()) unreadCount++;
}
return unreadCount > 0
? mContext.getResources().getQuantityString(
R.plurals.reading_list_unread_page_count, unreadCount, unreadCount)
: mContext.getResources().getString(R.string.reading_list_intro_text);
default:
return null;
}
}
private void onClick(BookmarkItem bookmarkItem) {
mBottomSheetController.hideContent(mBottomSheetContent, /*animate=*/false);
assert mCallback != null;
mCallback.onResult(bookmarkItem);
}
@VisibleForTesting
BookmarkBottomSheetContent getBottomSheetContentForTesting() {
return mBottomSheetContent;
}
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.bookmarks.bottomsheet;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.chromium.chrome.browser.bookmarks.BookmarkRow;
import org.chromium.chrome.browser.bookmarks.BookmarkUtils;
/**
* Represents a folder row in bookmark bottom sheet.
*/
class BookmarkBottomSheetFolderRow extends BookmarkRow {
private Runnable mOnClickListener;
/**
* Constructor for inflating from XML.
*/
public BookmarkBottomSheetFolderRow(Context context, AttributeSet attrs) {
super(context, attrs);
}
void setTitle(@NonNull String title) {
mTitleView.setText(title);
}
void setSubtitle(@Nullable String subtitle) {
mDescriptionView.setText(subtitle == null ? "" : subtitle);
}
void setOnClickListener(@NonNull Runnable listener) {
mOnClickListener = listener;
}
// SelectableItemViewBase overrides.
@Override
public void onClick() {}
// View overrides.
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mMoreIcon.setVisibility(GONE);
// TODO(xingliu): Load the correct icon.
setStartIconDrawable(BookmarkUtils.getFolderIcon(getContext()));
}
// BookmarkRow overrides.
@Override
public void onClick(View view) {
assert mOnClickListener != null;
mOnClickListener.run();
}
@Override
public boolean onLongClick(View view) {
return false;
}
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.bookmarks.bottomsheet;
import androidx.annotation.IntDef;
import androidx.recyclerview.widget.RecyclerView;
import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* The properties used to define UI elements in bookmark bottom sheet.
*/
class BookmarkBottomSheetItemProperties {
/**
* The view holder type used in the {@link RecyclerView} in the bookmark bottom sheet.
*/
@IntDef({ItemType.FOLDER_ROW})
@Retention(RetentionPolicy.SOURCE)
@interface ItemType {
int FOLDER_ROW = 1;
}
/**
* The title of the bottom sheet item. e.g. Mobile bookmarks, reading list.
*/
static final PropertyModel.ReadableObjectPropertyKey<String> TITLE =
new PropertyModel.ReadableObjectPropertyKey<>();
/**
* The subtitle of the bottom sheet item. e.g. 4 bookmarks, 8 unread pages.
*/
static final PropertyModel.ReadableObjectPropertyKey<String> SUBTITLE =
new PropertyModel.ReadableObjectPropertyKey<>();
/**
* A callback invoked when the bottom sheet bookmark item is clicked.
*/
static final PropertyModel.ReadableObjectPropertyKey<Runnable> ON_CLICK_LISTENER =
new PropertyModel.ReadableObjectPropertyKey<>();
static final PropertyKey[] ALL_KEYS = new PropertyKey[] {TITLE, SUBTITLE, ON_CLICK_LISTENER};
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.bookmarks.bottomsheet;
import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel;
/**
* The view binder to connect each bookmark bottom sheet row to {@link PropertyModel}.
*/
class BookmarkBottomSheetRowViewBinder {
static void bind(
PropertyModel model, BookmarkBottomSheetFolderRow view, PropertyKey propertyKey) {
if (BookmarkBottomSheetItemProperties.TITLE.equals(propertyKey)) {
view.setTitle(model.get(BookmarkBottomSheetItemProperties.TITLE));
} else if (BookmarkBottomSheetItemProperties.SUBTITLE.equals(propertyKey)) {
view.setSubtitle(model.get(BookmarkBottomSheetItemProperties.SUBTITLE));
} else if (BookmarkBottomSheetItemProperties.ON_CLICK_LISTENER.equals(propertyKey)) {
view.setOnClickListener(model.get(BookmarkBottomSheetItemProperties.ON_CLICK_LISTENER));
}
}
private BookmarkBottomSheetRowViewBinder() {}
}
......@@ -5,47 +5,91 @@
package org.chromium.chrome.browser.bookmarks.bottomsheet;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import android.view.View;
import androidx.recyclerview.widget.RecyclerView;
import androidx.test.filters.MediumTest;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.CriteriaHelper;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
import org.chromium.chrome.browser.bookmarks.BookmarkModel;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.flags.ChromeSwitches;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
import org.chromium.chrome.test.util.BookmarkTestUtil;
import org.chromium.chrome.test.util.browser.Features;
import org.chromium.components.bookmarks.BookmarkType;
import org.chromium.components.browser_ui.bottomsheet.BottomSheetContent;
import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.SheetState;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import java.util.ArrayList;
/**
* Test to verify bookmark bottom sheet.
*/
@RunWith(ChromeJUnit4ClassRunner.class)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
@Features.EnableFeatures({ChromeFeatureList.READ_LATER})
public class BookmarkBottomSheetTest {
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
@Rule
public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
private static final String TITLE = "bookmark title";
private static final String TEST_URL_A = "http://a.com";
private static final String TEST_URL_B = "http://b.com";
private BookmarkBottomSheetCoordinator mBottomSheetCoordinator;
private BottomSheetController mBottomSheetController;
private BookmarkModel mBookmarkModel;
private BookmarkItem mItemClicked;
@Before
public void setUp() {
mActivityTestRule.startMainActivityOnBlankPage();
TestThreadUtils.runOnUiThreadBlocking(() -> {
mBookmarkModel = new BookmarkModel(Profile.fromWebContents(
mActivityTestRule.getActivity().getActivityTab().getWebContents()));
});
mBottomSheetController = mActivityTestRule.getActivity()
.getRootUiCoordinatorForTesting()
.getBottomSheetController();
mBottomSheetCoordinator = new BookmarkBottomSheetCoordinator(
mActivityTestRule.getActivity(), mBottomSheetController);
mBottomSheetCoordinator =
new BookmarkBottomSheetCoordinator(mActivityTestRule.getActivity(),
mBottomSheetController, mBookmarkModel, this::onBottomSheetClicked);
waitForBookmarkModelLoaded();
}
@After
public void tearDown() {
mItemClicked = null;
}
private void onBottomSheetClicked(BookmarkItem item) {
mItemClicked = item;
}
private void showBottomSheet() {
......@@ -55,10 +99,93 @@ public class BookmarkBottomSheetTest {
() -> mBottomSheetController.getSheetState() == SheetState.FULL);
}
private void waitForBookmarkModelLoaded() {
// Must load partner bookmark backend, or the model will not be loaded.
TestThreadUtils.runOnUiThreadBlocking(
() -> mBookmarkModel.loadEmptyPartnerBookmarkShimForTesting());
BookmarkTestUtil.waitForBookmarkModelLoaded();
}
private void waitForBookmarkClicked() {
CriteriaHelper.pollUiThread(() -> mItemClicked != null);
}
private RecyclerView getRecyclerView() {
BottomSheetContent content = mBottomSheetCoordinator.getBottomSheetContentForTesting();
return content.getContentView().findViewById(org.chromium.chrome.R.id.sheet_item_list);
}
private void assertNoOverflowMenu(int position, String message) {
View view = getRecyclerView().findViewHolderForAdapterPosition(position).itemView;
Assert.assertEquals(message, View.GONE, view.findViewById(R.id.more).getVisibility());
}
private void assertViewHolderHasString(int position, String expectedString) {
View view = getRecyclerView().findViewHolderForAdapterPosition(position).itemView;
ArrayList<View> views = new ArrayList<>();
view.findViewsWithText(views, expectedString, View.FIND_VIEWS_WITH_TEXT);
Assert.assertFalse(views.isEmpty());
}
@Test
@MediumTest
public void testBottomSheetShow() {
public void testBottomSheetShowWithoutBookmarks() throws InterruptedException {
showBottomSheet();
onView(withId(R.id.sheet_title)).check(matches(isDisplayed()));
onView(withText("Reading list")).check(matches(isDisplayed()));
assertViewHolderHasString(0, "Save this page for later and get a reminder");
assertNoOverflowMenu(0, "No overflow menu for reading list folder.");
onView(withText("Mobile bookmarks")).check(matches(isDisplayed()));
assertViewHolderHasString(1, "No bookmarks");
assertNoOverflowMenu(1, "No overflow menu for mobile bookmark folder.");
}
@Test
@MediumTest
public void testBottomSheetShowWithOneBookmark() {
// Add 1 bookmark and 1 unread page.
TestThreadUtils.runOnUiThreadBlocking(() -> {
mBookmarkModel.addBookmark(mBookmarkModel.getMobileFolderId(), 0, TITLE, TEST_URL_A);
mBookmarkModel.addToReadingList(TITLE, TEST_URL_A);
});
showBottomSheet();
onView(withText("Reading list")).check(matches(isDisplayed()));
assertViewHolderHasString(0, "1 unread page");
onView(withText("Mobile bookmarks")).check(matches(isDisplayed()));
assertViewHolderHasString(1, "1 bookmark");
}
@Test
@MediumTest
public void testBottomSheetShowWithBookmarks() {
// Add multiple bookmarks unread reading list pages.
TestThreadUtils.runOnUiThreadBlocking(() -> {
mBookmarkModel.addBookmark(mBookmarkModel.getMobileFolderId(), 0, TITLE, TEST_URL_A);
mBookmarkModel.addBookmark(mBookmarkModel.getMobileFolderId(), 0, TITLE, TEST_URL_B);
mBookmarkModel.addToReadingList(TITLE, TEST_URL_A);
mBookmarkModel.addToReadingList(TITLE, TEST_URL_B);
});
showBottomSheet();
onView(withText("Reading list")).check(matches(isDisplayed()));
assertViewHolderHasString(0, "2 unread pages");
onView(withText("Mobile bookmarks")).check(matches(isDisplayed()));
assertViewHolderHasString(1, "2 bookmarks");
}
@Test
@MediumTest
public void testBottomSheetClickThrough() {
showBottomSheet();
onView(withText("Mobile bookmarks")).check(matches(isDisplayed()));
onView(withText("Reading list")).check(matches(isDisplayed())).perform(click());
waitForBookmarkClicked();
Assert.assertEquals(BookmarkType.READING_LIST, mItemClicked.getId().getType());
Assert.assertTrue(mItemClicked.isFolder());
}
}
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