blob: fa3fc93b46d751ab4c7fc7cf71220b30b38cb747 [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// 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;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.chromium.ui.test.util.MockitoHelper.doRunnable;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.view.accessibility.AccessibilityManager;
import androidx.annotation.StringRes;
import androidx.recyclerview.widget.RecyclerView;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.annotation.Config;
import org.chromium.base.Callback;
import org.chromium.base.supplier.ObservableSupplierImpl;
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.base.test.util.Batch;
import org.chromium.base.test.util.JniMocker;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.bookmarks.BookmarkListEntry.ViewType;
import org.chromium.chrome.browser.bookmarks.BookmarkRow.Location;
import org.chromium.chrome.browser.bookmarks.BookmarkUiPrefs.BookmarkRowDisplayPref;
import org.chromium.chrome.browser.bookmarks.BookmarkUiState.BookmarkUiMode;
import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.signin.services.IdentityServicesProvider;
import org.chromium.chrome.browser.signin.services.SigninManager;
import org.chromium.chrome.browser.sync.SyncService;
import org.chromium.chrome.browser.sync.SyncService.SyncStateChangedListener;
import org.chromium.chrome.test.util.browser.Features;
import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
import org.chromium.components.bookmarks.BookmarkId;
import org.chromium.components.bookmarks.BookmarkItem;
import org.chromium.components.bookmarks.BookmarkType;
import org.chromium.components.browser_ui.widget.dragreorder.DragReorderableRecyclerViewAdapter;
import org.chromium.components.browser_ui.widget.dragreorder.DragReorderableRecyclerViewAdapter.DragListener;
import org.chromium.components.browser_ui.widget.dragreorder.DragReorderableRecyclerViewAdapter.DraggabilityProvider;
import org.chromium.components.browser_ui.widget.listmenu.BasicListMenu;
import org.chromium.components.browser_ui.widget.listmenu.ListMenuItemProperties;
import org.chromium.components.browser_ui.widget.selectable_list.SelectableListLayout;
import org.chromium.components.browser_ui.widget.selectable_list.SelectionDelegate;
import org.chromium.components.favicon.IconType;
import org.chromium.components.favicon.LargeIconBridge;
import org.chromium.components.favicon.LargeIconBridge.LargeIconCallback;
import org.chromium.components.feature_engagement.Tracker;
import org.chromium.components.image_fetcher.ImageFetcher;
import org.chromium.components.payments.CurrencyFormatter;
import org.chromium.components.payments.CurrencyFormatterJni;
import org.chromium.components.power_bookmarks.PowerBookmarkMeta;
import org.chromium.components.power_bookmarks.ProductPrice;
import org.chromium.components.power_bookmarks.ShoppingSpecifics;
import org.chromium.components.signin.AccountManagerFacade;
import org.chromium.components.signin.AccountManagerFacadeProvider;
import org.chromium.components.signin.identitymanager.IdentityManager;
import org.chromium.components.url_formatter.UrlFormatter;
import org.chromium.components.url_formatter.UrlFormatterJni;
import org.chromium.ui.base.TestActivity;
import org.chromium.ui.modelutil.MVCListAdapter.ListItem;
import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
import org.chromium.ui.modelutil.PropertyModel;
import org.chromium.url.GURL;
import org.chromium.url.JUnitTestGURLs;
import java.util.Arrays;
import java.util.Collections;
/** Unit tests for {@link BookmarkManagerMediator}. */
@Batch(Batch.UNIT_TESTS)
@RunWith(BaseRobolectricTestRunner.class)
@Config(manifest = Config.NONE)
@Features.EnableFeatures({ChromeFeatureList.BOOKMARKS_REFRESH, ChromeFeatureList.SHOPPING_LIST})
public class BookmarkManagerMediatorTest {
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
@Rule
public ActivityScenarioRule<TestActivity> mActivityScenarioRule =
new ActivityScenarioRule<>(TestActivity.class);
@Rule
public TestRule mFeaturesProcessorRule = new Features.JUnitProcessor();
@Rule
public JniMocker mJniMocker = new JniMocker();
@Mock
private BookmarkModel mBookmarkModel;
@Mock
private BookmarkOpener mBookmarkOpener;
@Mock
private SelectableListLayout<BookmarkId> mSelectableListLayout;
@Mock
private SelectionDelegate<BookmarkId> mSelectionDelegate;
@Mock
private RecyclerView mRecyclerView;
@Mock
private LargeIconBridge mLargeIconBridge;
@Mock
private BookmarkUiObserver mBookmarkUiObserver;
@Mock
private Profile mProfile;
@Mock
private SyncService mSyncService;
@Mock
private IdentityServicesProvider mIdentityServicesProvider;
@Mock
private SigninManager mSigninManager;
@Mock
private IdentityManager mIdentityManager;
@Mock
private AccountManagerFacade mAccountManagerFacade;
@Mock
private BookmarkUndoController mBookmarkUndoController;
@Mock
private AccessibilityManager mAccessibilityManager;
@Mock
private Runnable mHideKeyboardRunnable;
@Mock
private UrlFormatter.Natives mUrlFormatterJniMock;
@Mock
private CurrencyFormatter.Natives mCurrencyFormatterJniMock;
@Mock
private Tracker mTracker;
@Mock
private ImageFetcher mImageFetcher;
@Captor
private ArgumentCaptor<BookmarkModelObserver> mBookmarkModelObserverArgumentCaptor;
@Captor
private ArgumentCaptor<DragListener> mDragListenerArgumentCaptor;
@Captor
private ArgumentCaptor<SyncStateChangedListener> mSyncStateChangedListenerCaptor;
@Captor
private ArgumentCaptor<Runnable> mFinishLoadingBookmarkModelCaptor;
private final ObservableSupplierImpl<Boolean> mBackPressStateSupplier =
new ObservableSupplierImpl<>();
private final ObservableSupplierImpl<Boolean>
mSelectableListLayoutHandleBackPressChangedSupplier = new ObservableSupplierImpl<>();
private final BookmarkId mRootFolderId = new BookmarkId(/*id=*/1, BookmarkType.NORMAL);
private final BookmarkId mFolderId1 = new BookmarkId(/*id=*/2, BookmarkType.NORMAL);
private final BookmarkId mFolderId2 = new BookmarkId(/*id=*/3, BookmarkType.NORMAL);
private final BookmarkId mFolderId3 = new BookmarkId(/*id=*/4, BookmarkType.NORMAL);
private final BookmarkId mBookmarkId21 = new BookmarkId(/*id=*/5, BookmarkType.NORMAL);
private final BookmarkId mReadingListFolderId =
new BookmarkId(/*id=*/5, BookmarkType.READING_LIST);
private final BookmarkId mReadingListId = new BookmarkId(/*id=*/6, BookmarkType.READING_LIST);
private final BookmarkItem mFolderItem1 =
new BookmarkItem(mFolderId1, "Folder1", null, true, null, true, false, 0, false);
private final BookmarkItem mFolderItem2 =
new BookmarkItem(mFolderId2, "Folder2", null, true, mFolderId1, true, false, 0, false);
private final BookmarkItem mFolderItem3 =
new BookmarkItem(mFolderId3, "Folder3", null, true, mFolderId1, true, false, 0, false);
private final BookmarkItem mBookmarkItem21 = new BookmarkItem(mBookmarkId21, "Bookmark21",
JUnitTestGURLs.getGURL(JUnitTestGURLs.EXAMPLE_URL), false, mFolderId1, true, false, 0,
false);
private final BookmarkItem mReadingListFolderItem = new BookmarkItem(mReadingListFolderId,
"ReadingList", JUnitTestGURLs.getGURL(JUnitTestGURLs.EXAMPLE_URL), true, null, false,
false, 0, false);
private final BookmarkItem mReadingListItem = new BookmarkItem(mReadingListId, "ReadingList",
JUnitTestGURLs.getGURL(JUnitTestGURLs.EXAMPLE_URL), false, mReadingListFolderId, true,
false, 0, false);
private final ModelList mModelList = new ModelList();
private final Bitmap mBitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
private BookmarkUiPrefs mBookmarkUiPrefs =
new BookmarkUiPrefs(SharedPreferencesManager.getInstance());
private Activity mActivity;
private BookmarkManagerMediator mMediator;
private DragReorderableRecyclerViewAdapter mDragReorderableRecyclerViewAdapter;
@Before
public void setUp() {
mActivityScenarioRule.getScenario().onActivity((activity) -> {
mActivity = spy(activity);
// Setup UrlFormatter.
mJniMocker.mock(UrlFormatterJni.TEST_HOOKS, mUrlFormatterJniMock);
doAnswer(invocation -> {
GURL url = invocation.getArgument(0);
return url.getSpec();
})
.when(mUrlFormatterJniMock)
.formatUrlForSecurityDisplay(any(), anyInt());
// Setup CurrencyFormatter.
mJniMocker.mock(CurrencyFormatterJni.TEST_HOOKS, mCurrencyFormatterJniMock);
// Setup TrackerFactory.
TrackerFactory.setTrackerForTests(mTracker);
// Setup BookmarkModel.
doReturn(mRootFolderId).when(mBookmarkModel).getRootFolderId();
doReturn(mReadingListFolderId).when(mBookmarkModel).getReadingListFolder();
doReturn(true).when(mBookmarkModel).doesBookmarkExist(any());
doReturn(Arrays.asList(mFolderId2, mFolderId3))
.when(mBookmarkModel)
.getChildIds(mFolderId1);
doReturn(mFolderItem1).when(mBookmarkModel).getBookmarkById(mFolderId1);
doReturn(mFolderItem2).when(mBookmarkModel).getBookmarkById(mFolderId2);
doReturn(mBookmarkItem21).when(mBookmarkModel).getBookmarkById(mBookmarkId21);
doReturn(Arrays.asList(mBookmarkId21)).when(mBookmarkModel).getChildIds(mFolderId2);
doReturn(1).when(mBookmarkModel).getTotalBookmarkCount(mFolderId2);
doReturn(mFolderItem3).when(mBookmarkModel).getBookmarkById(mFolderId3);
doReturn(Arrays.asList(mReadingListId))
.when(mBookmarkModel)
.getChildIds(mReadingListFolderId);
doReturn(mReadingListFolderItem)
.when(mBookmarkModel)
.getBookmarkById(mReadingListFolderId);
doReturn(mReadingListItem).when(mBookmarkModel).getBookmarkById(mReadingListId);
// Setup SelectableListLayout.
doReturn(mActivity).when(mSelectableListLayout).getContext();
doReturn(mSelectableListLayoutHandleBackPressChangedSupplier)
.when(mSelectableListLayout)
.getHandleBackPressChangedSupplier();
doReturn(mAccessibilityManager)
.when(mActivity)
.getSystemService(Context.ACCESSIBILITY_SERVICE);
// Setup BookmarkUIObserver.
doRunnable(() -> mMediator.removeUiObserver(mBookmarkUiObserver))
.when(mBookmarkUiObserver)
.onDestroy();
// Setup LargeIconBridge.
doAnswer(invocation -> {
LargeIconCallback cb = invocation.getArgument(2);
cb.onLargeIconAvailable(mBitmap, Color.GREEN, false, IconType.FAVICON);
return null;
})
.when(mLargeIconBridge)
.getLargeIconForUrl(any(), anyInt(), any());
// Setup BookmarkUiPrefs.
mBookmarkUiPrefs.setBookmarkRowDisplayPref(BookmarkRowDisplayPref.COMPACT);
// Setup sync/identify mocks.
SyncService.overrideForTests(mSyncService);
IdentityServicesProvider.setInstanceForTests(mIdentityServicesProvider);
doReturn(mSigninManager).when(mIdentityServicesProvider).getSigninManager(any());
doReturn(mIdentityManager).when(mSigninManager).getIdentityManager();
AccountManagerFacadeProvider.setInstanceForTests(mAccountManagerFacade);
// Setup image fetching.
doAnswer((invocation) -> {
Callback<GURL> callback = invocation.getArgument(1);
callback.onResult(JUnitTestGURLs.getGURL(JUnitTestGURLs.EXAMPLE_URL));
return null;
})
.when(mBookmarkModel)
.getImageUrlForBookmark(any(), any());
doAnswer((invocation) -> {
Callback<Bitmap> callback = invocation.getArgument(1);
callback.onResult(mBitmap);
return null;
})
.when(mImageFetcher)
.fetchImage(any(), any());
mDragReorderableRecyclerViewAdapter =
spy(new DragReorderableRecyclerViewAdapter(mActivity, mModelList));
mMediator = new BookmarkManagerMediator(mActivity, mBookmarkModel, mBookmarkOpener,
mSelectableListLayout, mSelectionDelegate, mRecyclerView,
mDragReorderableRecyclerViewAdapter, mLargeIconBridge, /*isDialogUi=*/true,
/*isIncognito=*/false, mBackPressStateSupplier, mProfile,
mBookmarkUndoController, mModelList, mBookmarkUiPrefs, mHideKeyboardRunnable,
mImageFetcher);
mMediator.addUiObserver(mBookmarkUiObserver);
});
}
void finishLoading() {
when(mBookmarkModel.isBookmarkModelLoaded()).thenReturn(true);
verify(mBookmarkModel, atLeast(0))
.finishLoadingBookmarkModel(mFinishLoadingBookmarkModelCaptor.capture());
for (Runnable finishLoadingBookmarkModel :
mFinishLoadingBookmarkModelCaptor.getAllValues()) {
finishLoadingBookmarkModel.run();
}
}
void verifyBookmarkListMenuItem(ListItem item, @StringRes int titleId, boolean enabled) {
assertEquals(item.model.get(ListMenuItemProperties.TITLE_ID), titleId);
assertEquals(item.model.get(ListMenuItemProperties.ENABLED), enabled);
}
@Test
public void initAndLoadBookmarkModel() {
finishLoading();
assertEquals(BookmarkUiMode.LOADING, mMediator.getCurrentUiMode());
}
@Test
public void setUrlBeforeModelLoaded() {
// Setting a URL prior to the model loading should set the state for when it loads.
mMediator.updateForUrl("chrome-native://bookmarks/folder/" + mFolderId1.getId());
finishLoading();
assertEquals(BookmarkUiMode.FOLDER, mMediator.getCurrentUiMode());
}
@Test
public void syncStateChangedBeforeModelLoaded() {
verify(mSyncService, atLeast(1))
.addSyncStateChangedListener(mSyncStateChangedListenerCaptor.capture());
for (SyncStateChangedListener syncStateChangedListener :
mSyncStateChangedListenerCaptor.getAllValues()) {
syncStateChangedListener.syncStateChanged();
}
verify(mBookmarkModel, times(0)).getDesktopFolderId();
verify(mBookmarkModel, times(0)).getMobileFolderId();
verify(mBookmarkModel, times(0)).getOtherFolderId();
verify(mBookmarkModel, times(0)).getTopLevelFolderIds(true, false);
finishLoading();
verify(mBookmarkModel, times(1)).getDesktopFolderId();
verify(mBookmarkModel, times(1)).getMobileFolderId();
verify(mBookmarkModel, times(1)).getOtherFolderId();
verify(mBookmarkModel, times(1)).getTopLevelFolderIds(true, false);
}
@Test
public void testDestroy() {
finishLoading();
mMediator.onDestroy();
verify(mBookmarkUiObserver).onDestroy();
verify(mBookmarkUndoController).destroy();
verify(mAccessibilityManager).removeAccessibilityStateChangeListener(any());
}
@Test
public void onBackPressed_SelectableListLayoutIntercepts() {
finishLoading();
doReturn(true).when(mSelectableListLayout).onBackPressed();
assertTrue(mMediator.onBackPressed());
}
@Test
public void onBackPressed_EmptyStateStack() {
finishLoading();
mMediator.clearStateStackForTesting();
assertFalse(mMediator.onBackPressed());
}
@Test
public void onBackPressed_SingleStateStack() {
finishLoading();
assertFalse(mMediator.onBackPressed());
}
@Test
public void onBackPressed_MultipleStateStack() {
finishLoading();
mMediator.openFolder(mFolderId1);
mMediator.openFolder(mFolderId2);
assertTrue(mMediator.onBackPressed());
}
@Test
public void testMoveDownUp() {
finishLoading();
mMediator.openFolder(mFolderId1);
mMediator.moveDownOne(mFolderId2);
verify(mBookmarkModel)
.reorderBookmarks(mFolderId1, new long[] {mFolderId3.getId(), mFolderId2.getId()});
mMediator.moveUpOne(mFolderId2);
verify(mBookmarkModel)
.reorderBookmarks(mFolderId1, new long[] {mFolderId2.getId(), mFolderId3.getId()});
}
@Test
public void testDrag() {
finishLoading();
mMediator.openFolder(mFolderId1);
DraggabilityProvider draggabilityProvider = mMediator.getDraggabilityProvider();
assertTrue(draggabilityProvider.isPassivelyDraggable(mModelList.get(0).model));
assertFalse(draggabilityProvider.isActivelyDraggable(mModelList.get(0).model));
when(mSelectionDelegate.isItemSelected(mFolderId2)).thenReturn(true);
assertTrue(draggabilityProvider.isActivelyDraggable(mModelList.get(0).model));
mModelList.move(0, 1);
verify(mDragReorderableRecyclerViewAdapter)
.addDragListener(mDragListenerArgumentCaptor.capture());
mDragListenerArgumentCaptor.getValue().onSwap();
verify(mBookmarkModel)
.reorderBookmarks(mFolderId1, new long[] {mFolderId3.getId(), mFolderId2.getId()});
}
@Test
public void testSearch() {
when(mBookmarkModel.searchBookmarks(anyString(), anyInt()))
.thenReturn(Collections.singletonList(mFolderId3));
finishLoading();
mMediator.openFolder(mFolderId1);
assertEquals(2, mModelList.size());
mMediator.openSearchUi();
mMediator.search("3");
assertEquals(1, mModelList.size());
mMediator.onEndSearch();
assertEquals(2, mModelList.size());
}
@Test
public void testBookmarkRemoved() {
finishLoading();
mMediator.openFolder(mFolderId1);
assertEquals(2, mModelList.size());
doReturn(Arrays.asList(mFolderId3)).when(mBookmarkModel).getChildIds(mFolderId1);
verify(mBookmarkModel).addObserver(mBookmarkModelObserverArgumentCaptor.capture());
mBookmarkModelObserverArgumentCaptor.getValue().bookmarkNodeRemoved(
mFolderItem1, 0, mFolderItem2, /*isDoingExtensiveChanges*/ false);
assertEquals(1, mModelList.size());
}
@Test
public void testAttachmentChanges() {
mMediator.onAttachedToWindow();
verify(mBookmarkUndoController).setEnabled(true);
mMediator.onDetachedFromWindow();
verify(mBookmarkUndoController).setEnabled(false);
}
@Test
@EnableFeatures(ChromeFeatureList.ANDROID_IMPROVED_BOOKMARKS)
public void onPreferenceChanged_ViewPreferenceUpdated() {
mMediator.openFolder(mFolderId1);
mBookmarkUiPrefs.setBookmarkRowDisplayPref(BookmarkRowDisplayPref.VISUAL);
assertEquals(ViewType.IMPROVED_BOOKMARK_VISUAL, mModelList.get(0).type);
}
@Test
@EnableFeatures(ChromeFeatureList.ANDROID_IMPROVED_BOOKMARKS)
public void testBuildImprovedBookmarkRow() {
finishLoading();
mMediator.openFolder(mFolderId2);
assertEquals(1, mModelList.size());
ListItem item = mModelList.get(0);
assertEquals(ViewType.IMPROVED_BOOKMARK_COMPACT, item.type);
PropertyModel model = item.model;
assertNotNull(model);
assertEquals(mBookmarkItem21,
model.get(BookmarkManagerProperties.BOOKMARK_LIST_ENTRY).getBookmarkItem());
assertEquals(mBookmarkId21, model.get(BookmarkManagerProperties.BOOKMARK_ID));
assertEquals(mBookmarkItem21.getTitle(), model.get(ImprovedBookmarkRowProperties.TITLE));
assertEquals(
"https://www.example.com/", model.get(ImprovedBookmarkRowProperties.DESCRIPTION));
assertNotNull(model.get(ImprovedBookmarkRowProperties.BOOKMARK_DRAWABLE));
assertNotNull(model.get(ImprovedBookmarkRowProperties.POPUP_LISTENER));
assertEquals(false, model.get(ImprovedBookmarkRowProperties.SELECTION_ACTIVE));
assertEquals(false, model.get(ImprovedBookmarkRowProperties.DRAG_ENABLED));
assertNotNull(model.get(ImprovedBookmarkRowProperties.LIST_MENU_BUTTON_DELEGATE));
assertEquals(true, model.get(ImprovedBookmarkRowProperties.EDITABLE));
assertNotNull(model.get(ImprovedBookmarkRowProperties.OPEN_BOOKMARK_CALLBACK));
}
@Test
@EnableFeatures(ChromeFeatureList.ANDROID_IMPROVED_BOOKMARKS)
public void testBuildImprovedBookmarkRow_ReadingList() {
finishLoading();
mMediator.openFolder(mReadingListFolderId);
assertEquals(3, mModelList.size());
ListItem item = mModelList.get(1);
assertEquals(ViewType.IMPROVED_BOOKMARK_COMPACT, item.type);
PropertyModel model = item.model;
assertNotNull(model);
assertEquals(mReadingListItem,
model.get(BookmarkManagerProperties.BOOKMARK_LIST_ENTRY).getBookmarkItem());
assertEquals(mReadingListId, model.get(BookmarkManagerProperties.BOOKMARK_ID));
assertEquals(mReadingListItem.getTitle(), model.get(ImprovedBookmarkRowProperties.TITLE));
assertEquals(
"https://www.example.com/", model.get(ImprovedBookmarkRowProperties.DESCRIPTION));
assertNotNull(model.get(ImprovedBookmarkRowProperties.BOOKMARK_DRAWABLE));
}
@Test
@EnableFeatures(ChromeFeatureList.ANDROID_IMPROVED_BOOKMARKS)
public void testBuildImprovedBookmarkRow_Visual() {
finishLoading();
mMediator.openFolder(mFolderId2);
mBookmarkUiPrefs.setBookmarkRowDisplayPref(BookmarkRowDisplayPref.VISUAL);
assertEquals(1, mModelList.size());
ListItem item = mMediator.buildImprovedBookmarkRow(BookmarkListEntry.createBookmarkEntry(
mBookmarkItem21, null, mBookmarkUiPrefs.getBookmarkRowDisplayPref()));
assertEquals(ViewType.IMPROVED_BOOKMARK_VISUAL, item.type);
PropertyModel model = item.model;
assertNotNull(model);
assertEquals(mBookmarkItem21,
model.get(BookmarkManagerProperties.BOOKMARK_LIST_ENTRY).getBookmarkItem());
assertEquals(mBookmarkId21, model.get(BookmarkManagerProperties.BOOKMARK_ID));
assertEquals(mBookmarkItem21.getTitle(), model.get(ImprovedBookmarkRowProperties.TITLE));
assertEquals(
"https://www.example.com/", model.get(ImprovedBookmarkRowProperties.DESCRIPTION));
assertNotNull(model.get(ImprovedBookmarkRowProperties.BOOKMARK_DRAWABLE));
assertNotNull(model.get(ImprovedBookmarkRowProperties.POPUP_LISTENER));
assertEquals(false, model.get(ImprovedBookmarkRowProperties.SELECTION_ACTIVE));
assertEquals(false, model.get(ImprovedBookmarkRowProperties.DRAG_ENABLED));
assertNotNull(model.get(ImprovedBookmarkRowProperties.LIST_MENU_BUTTON_DELEGATE));
assertEquals(true, model.get(ImprovedBookmarkRowProperties.EDITABLE));
assertNotNull(model.get(ImprovedBookmarkRowProperties.OPEN_BOOKMARK_CALLBACK));
}
@Test
@EnableFeatures(ChromeFeatureList.ANDROID_IMPROVED_BOOKMARKS)
public void testBuildImprovedBookmarkRow_Shopping() {
ShoppingSpecifics specifics = ShoppingSpecifics.newBuilder()
.setCurrentPrice(ProductPrice.newBuilder()
.setCurrencyCode("USD")
.setAmountMicros(100)
.build())
.setPreviousPrice(ProductPrice.newBuilder()
.setCurrencyCode("USD")
.setAmountMicros(100)
.build())
.setIsPriceTracked(true)
.build();
PowerBookmarkMeta meta =
PowerBookmarkMeta.newBuilder().setShoppingSpecifics(specifics).build();
doReturn(meta).when(mBookmarkModel).getPowerBookmarkMeta(mBookmarkId21);
finishLoading();
mMediator.openFolder(mFolderId2);
assertEquals(1, mModelList.size());
ListItem item = mModelList.get(0);
assertEquals(ViewType.IMPROVED_BOOKMARK_COMPACT, item.type);
PropertyModel model = item.model;
assertNotNull(model);
assertNotNull(model.get(ImprovedBookmarkRowProperties.ACCESSORY_VIEW));
}
@Test
@EnableFeatures(ChromeFeatureList.ANDROID_IMPROVED_BOOKMARKS)
public void testBuildImprovedBookmarkRow_Folder() {
finishLoading();
mMediator.openFolder(mFolderId1);
assertEquals(2, mModelList.size());
ListItem item = mModelList.get(0);
assertEquals(ViewType.IMPROVED_BOOKMARK_COMPACT, item.type);
PropertyModel model = item.model;
assertNotNull(model);
assertEquals(mFolderItem2,
model.get(BookmarkManagerProperties.BOOKMARK_LIST_ENTRY).getBookmarkItem());
assertEquals(mFolderId2, model.get(BookmarkManagerProperties.BOOKMARK_ID));
assertEquals(mFolderItem2.getTitle(), model.get(ImprovedBookmarkRowProperties.TITLE));
assertEquals("1 bookmark", model.get(ImprovedBookmarkRowProperties.DESCRIPTION));
assertNotNull(model.get(ImprovedBookmarkRowProperties.BOOKMARK_DRAWABLE));
assertNotNull(model.get(ImprovedBookmarkRowProperties.POPUP_LISTENER));
assertEquals(false, model.get(ImprovedBookmarkRowProperties.SELECTION_ACTIVE));
assertEquals(false, model.get(ImprovedBookmarkRowProperties.DRAG_ENABLED));
assertNotNull(model.get(ImprovedBookmarkRowProperties.LIST_MENU_BUTTON_DELEGATE));
assertEquals(true, model.get(ImprovedBookmarkRowProperties.EDITABLE));
assertNotNull(model.get(ImprovedBookmarkRowProperties.OPEN_BOOKMARK_CALLBACK));
}
@Test
@EnableFeatures(ChromeFeatureList.ANDROID_IMPROVED_BOOKMARKS)
public void testBuildImprovedBookmarkRow_FolderVisual() {
finishLoading();
mMediator.openFolder(mFolderId1);
mBookmarkUiPrefs.setBookmarkRowDisplayPref(BookmarkRowDisplayPref.VISUAL);
assertEquals(2, mModelList.size());
ListItem item = mModelList.get(0);
assertEquals(ViewType.IMPROVED_BOOKMARK_VISUAL, item.type);
PropertyModel model = item.model;
assertNotNull(model);
assertEquals(mFolderItem2,
model.get(BookmarkManagerProperties.BOOKMARK_LIST_ENTRY).getBookmarkItem());
assertEquals(mFolderId2, model.get(BookmarkManagerProperties.BOOKMARK_ID));
assertEquals(mFolderItem2.getTitle(), model.get(ImprovedBookmarkRowProperties.TITLE));
assertEquals("1 bookmark", model.get(ImprovedBookmarkRowProperties.DESCRIPTION));
assertNull(model.get(ImprovedBookmarkRowProperties.BOOKMARK_DRAWABLE));
assertNotNull(model.get(ImprovedBookmarkRowProperties.FOLDER_DRAWABLES));
assertNotNull(model.get(ImprovedBookmarkRowProperties.POPUP_LISTENER));
assertEquals(false, model.get(ImprovedBookmarkRowProperties.SELECTION_ACTIVE));
assertEquals(false, model.get(ImprovedBookmarkRowProperties.DRAG_ENABLED));
assertNotNull(model.get(ImprovedBookmarkRowProperties.LIST_MENU_BUTTON_DELEGATE));
assertEquals(true, model.get(ImprovedBookmarkRowProperties.EDITABLE));
assertNotNull(model.get(ImprovedBookmarkRowProperties.OPEN_BOOKMARK_CALLBACK));
}
@Test
@EnableFeatures(ChromeFeatureList.ANDROID_IMPROVED_BOOKMARKS)
public void testBuildImprovedBookmarkRow_FolderVisual_NullUrl() {
doAnswer((invocation) -> {
Callback<GURL> callback = invocation.getArgument(1);
callback.onResult(null);
return null;
})
.when(mBookmarkModel)
.getImageUrlForBookmark(any(), any());
finishLoading();
mMediator.openFolder(mFolderId1);
mBookmarkUiPrefs.setBookmarkRowDisplayPref(BookmarkRowDisplayPref.VISUAL);
assertEquals(2, mModelList.size());
ListItem item = mModelList.get(0);
assertEquals(ViewType.IMPROVED_BOOKMARK_VISUAL, item.type);
PropertyModel model = item.model;
assertNotNull(model);
assertEquals(mFolderItem2,
model.get(BookmarkManagerProperties.BOOKMARK_LIST_ENTRY).getBookmarkItem());
assertEquals(mFolderId2, model.get(BookmarkManagerProperties.BOOKMARK_ID));
assertEquals(mFolderItem2.getTitle(), model.get(ImprovedBookmarkRowProperties.TITLE));
assertEquals("1 bookmark", model.get(ImprovedBookmarkRowProperties.DESCRIPTION));
assertNull(model.get(ImprovedBookmarkRowProperties.BOOKMARK_DRAWABLE));
assertNotNull(model.get(ImprovedBookmarkRowProperties.FOLDER_DRAWABLES));
assertNull(model.get(ImprovedBookmarkRowProperties.FOLDER_DRAWABLES).first);
assertNull(model.get(ImprovedBookmarkRowProperties.FOLDER_DRAWABLES).second);
assertNotNull(model.get(ImprovedBookmarkRowProperties.POPUP_LISTENER));
assertEquals(false, model.get(ImprovedBookmarkRowProperties.SELECTION_ACTIVE));
assertEquals(false, model.get(ImprovedBookmarkRowProperties.DRAG_ENABLED));
assertNotNull(model.get(ImprovedBookmarkRowProperties.LIST_MENU_BUTTON_DELEGATE));
assertEquals(true, model.get(ImprovedBookmarkRowProperties.EDITABLE));
assertNotNull(model.get(ImprovedBookmarkRowProperties.OPEN_BOOKMARK_CALLBACK));
}
@Test
@EnableFeatures(ChromeFeatureList.ANDROID_IMPROVED_BOOKMARKS)
public void testBuildImprovedBookmarkRow_FolderVisual_NullImage() {
doAnswer((invocation) -> {
Callback<Bitmap> callback = invocation.getArgument(1);
callback.onResult(null);
return null;
})
.when(mImageFetcher)
.fetchImage(any(), any());
finishLoading();
mMediator.openFolder(mFolderId1);
mBookmarkUiPrefs.setBookmarkRowDisplayPref(BookmarkRowDisplayPref.VISUAL);
assertEquals(2, mModelList.size());
ListItem item = mModelList.get(0);
assertEquals(ViewType.IMPROVED_BOOKMARK_VISUAL, item.type);
PropertyModel model = item.model;
assertNotNull(model);
assertEquals(mFolderItem2,
model.get(BookmarkManagerProperties.BOOKMARK_LIST_ENTRY).getBookmarkItem());
assertEquals(mFolderId2, model.get(BookmarkManagerProperties.BOOKMARK_ID));
assertEquals(mFolderItem2.getTitle(), model.get(ImprovedBookmarkRowProperties.TITLE));
assertEquals("1 bookmark", model.get(ImprovedBookmarkRowProperties.DESCRIPTION));
assertNull(model.get(ImprovedBookmarkRowProperties.BOOKMARK_DRAWABLE));
assertNotNull(model.get(ImprovedBookmarkRowProperties.FOLDER_DRAWABLES));
assertNull(model.get(ImprovedBookmarkRowProperties.FOLDER_DRAWABLES).first);
assertNull(model.get(ImprovedBookmarkRowProperties.FOLDER_DRAWABLES).second);
assertNotNull(model.get(ImprovedBookmarkRowProperties.POPUP_LISTENER));
assertEquals(false, model.get(ImprovedBookmarkRowProperties.SELECTION_ACTIVE));
assertEquals(false, model.get(ImprovedBookmarkRowProperties.DRAG_ENABLED));
assertNotNull(model.get(ImprovedBookmarkRowProperties.LIST_MENU_BUTTON_DELEGATE));
assertEquals(true, model.get(ImprovedBookmarkRowProperties.EDITABLE));
assertNotNull(model.get(ImprovedBookmarkRowProperties.OPEN_BOOKMARK_CALLBACK));
}
@Test
public void testcreateListMenuModelList() {
finishLoading();
mMediator.openFolder(mFolderId2);
ModelList modelList = mMediator.createListMenuModelList(mBookmarkId21, Location.MIDDLE);
assertEquals(6, modelList.size());
verifyBookmarkListMenuItem(modelList.get(0), R.string.bookmark_item_select, true);
verifyBookmarkListMenuItem(modelList.get(1), R.string.bookmark_item_edit, true);
verifyBookmarkListMenuItem(modelList.get(2), R.string.bookmark_item_move, true);
verifyBookmarkListMenuItem(modelList.get(3), R.string.bookmark_item_delete, true);
verifyBookmarkListMenuItem(modelList.get(4), R.string.menu_item_move_up, true);
verifyBookmarkListMenuItem(modelList.get(5), R.string.menu_item_move_down, true);
modelList = mMediator.createListMenuModelList(mBookmarkId21, Location.TOP);
assertEquals(5, modelList.size());
verifyBookmarkListMenuItem(modelList.get(4), R.string.menu_item_move_down, true);
modelList = mMediator.createListMenuModelList(mBookmarkId21, Location.BOTTOM);
assertEquals(5, modelList.size());
verifyBookmarkListMenuItem(modelList.get(4), R.string.menu_item_move_up, true);
mMediator.openFolder(mRootFolderId);
modelList = mMediator.createListMenuModelList(mBookmarkId21, Location.MIDDLE);
assertEquals("neither move option should be visible", 4, modelList.size());
mMediator.openSearchUi();
modelList = mMediator.createListMenuModelList(mBookmarkId21, Location.MIDDLE);
assertEquals(5, modelList.size());
verifyBookmarkListMenuItem(modelList.get(4), R.string.bookmark_show_in_folder, true);
}
@Test
public void testCreateListMenuModelList_ReadingList() {
finishLoading();
mMediator.openFolder(mReadingListFolderId);
ModelList modelList = mMediator.createListMenuModelList(mReadingListId, Location.MIDDLE);
assertEquals(5, modelList.size());
verifyBookmarkListMenuItem(modelList.get(0), R.string.reading_list_mark_as_read, true);
verifyBookmarkListMenuItem(modelList.get(1), R.string.bookmark_item_select, true);
verifyBookmarkListMenuItem(modelList.get(2), R.string.bookmark_item_edit, true);
verifyBookmarkListMenuItem(modelList.get(3), R.string.bookmark_item_move, true);
verifyBookmarkListMenuItem(modelList.get(4), R.string.bookmark_item_delete, true);
}
@Test
public void testCreateListMenuForBookmark() {
finishLoading();
mMediator.openFolder(mFolderId2);
// This is the first item mFolderId2.
BasicListMenu menu =
(BasicListMenu) mMediator.createListMenuForBookmark(mModelList.get(0).model);
assertNotNull(menu);
// select
menu.onItemClick(null, null, 0, 0);
verify(mSelectionDelegate).toggleSelectionForItem(mBookmarkId21);
// edit
// TODO(crbug.com/1444544): This doesn't actually open the activity yet.
menu.onItemClick(null, null, 1, 0);
// move
// TODO(crbug.com/1444544): This doesn't actually open the activity yet.
menu.onItemClick(null, null, 2, 0);
// delete.
menu.onItemClick(null, null, 3, 0);
verify(mBookmarkModel).deleteBookmarks(mBookmarkId21);
}
}