// Copyright 2020 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.app.appmenu;
import static androidx.test.espresso.matcher.ViewMatchers.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.pm.PackageManager;
import android.view.ContextThemeWrapper;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.widget.PopupMenu;
import androidx.annotation.NonNull;
import androidx.test.filters.SmallTest;
import org.hamcrest.Matchers;
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.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.LooperMode;
import org.robolectric.shadows.ShadowPackageManager;
import org.chromium.base.ContextUtils;
import org.chromium.base.FeatureList;
import org.chromium.base.FeatureList.TestValues;
import org.chromium.base.ResettersForTesting;
import org.chromium.base.ThreadUtils;
import org.chromium.base.supplier.ObservableSupplierImpl;
import org.chromium.base.supplier.OneshotSupplierImpl;
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.base.test.util.JniMocker;
import org.chromium.build.BuildConfig;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ActivityTabProvider;
import org.chromium.chrome.browser.app.appmenu.AppMenuPropertiesDelegateImpl.MenuGroup;
import org.chromium.chrome.browser.bookmarks.BookmarkModel;
import org.chromium.chrome.browser.bookmarks.PowerBookmarkUtils;
import org.chromium.chrome.browser.commerce.ShoppingFeatures;
import org.chromium.chrome.browser.commerce.ShoppingServiceFactory;
import org.chromium.chrome.browser.device.DeviceConditions;
import org.chromium.chrome.browser.device.ShadowDeviceConditions;
import org.chromium.chrome.browser.enterprise.util.ManagedBrowserUtils;
import org.chromium.chrome.browser.enterprise.util.ManagedBrowserUtilsJni;
import org.chromium.chrome.browser.incognito.IncognitoUtils;
import org.chromium.chrome.browser.incognito.IncognitoUtilsJni;
import org.chromium.chrome.browser.incognito.reauth.IncognitoReauthController;
import org.chromium.chrome.browser.layouts.LayoutStateProvider;
import org.chromium.chrome.browser.layouts.LayoutType;
import org.chromium.chrome.browser.multiwindow.MultiWindowModeStateDispatcher;
import org.chromium.chrome.browser.omaha.UpdateMenuItemHelper;
import org.chromium.chrome.browser.preferences.Pref;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.readaloud.ReadAloudController;
import org.chromium.chrome.browser.signin.services.IdentityServicesProvider;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.TabModel;
import org.chromium.chrome.browser.tabmodel.TabModelFilter;
import org.chromium.chrome.browser.tabmodel.TabModelFilterProvider;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.toolbar.ToolbarManager;
import org.chromium.chrome.browser.toolbar.menu_button.MenuUiState;
import org.chromium.chrome.browser.translate.TranslateBridge;
import org.chromium.chrome.browser.translate.TranslateBridgeJni;
import org.chromium.chrome.browser.ui.appmenu.AppMenuHandler;
import org.chromium.chrome.browser.ui.appmenu.AppMenuItemProperties;
import org.chromium.chrome.browser.ui.appmenu.AppMenuPropertiesDelegate;
import org.chromium.chrome.browser.ui.appmenu.CustomViewBinder;
import org.chromium.chrome.browser.ui.native_page.NativePage;
import org.chromium.chrome.browser.webapps.WebappRegistry;
import org.chromium.components.bookmarks.BookmarkId;
import org.chromium.components.browser_ui.accessibility.PageZoomCoordinator;
import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridge;
import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridgeJni;
import org.chromium.components.commerce.core.ShoppingService;
import org.chromium.components.content_settings.ContentSettingValues;
import org.chromium.components.power_bookmarks.PowerBookmarkMeta;
import org.chromium.components.power_bookmarks.PowerBookmarkType;
import org.chromium.components.power_bookmarks.ShoppingSpecifics;
import org.chromium.components.prefs.PrefService;
import org.chromium.components.signin.identitymanager.IdentityManager;
import org.chromium.components.user_prefs.UserPrefs;
import org.chromium.components.user_prefs.UserPrefsJni;
import org.chromium.components.webapps.AppBannerManager;
import org.chromium.components.webapps.AppBannerManagerJni;
import org.chromium.content_public.browser.NavigationController;
import org.chromium.content_public.browser.WebContents;
import org.chromium.net.ConnectionType;
import org.chromium.ui.accessibility.AccessibilityState;
import org.chromium.ui.modelutil.MVCListAdapter.ListItem;
import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
import org.chromium.url.GURL;
import org.chromium.url.JUnitTestGURLs;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
/** Unit tests for {@link AppMenuPropertiesDelegateImpl}. */
@RunWith(BaseRobolectricTestRunner.class)
@LooperMode(LooperMode.Mode.LEGACY)
public class AppMenuPropertiesDelegateUnitTest {
@Rule public JniMocker mJniMocker = new JniMocker();
@Mock private ActivityTabProvider mActivityTabProvider;
@Mock private Tab mTab;
@Mock private WebContents mWebContents;
@Mock private NavigationController mNavigationController;
@Mock private MultiWindowModeStateDispatcher mMultiWindowModeStateDispatcher;
@Mock private TabModelSelector mTabModelSelector;
@Mock private TabModel mTabModel;
@Mock private TabModel mIncognitoTabModel;
@Mock private ToolbarManager mToolbarManager;
@Mock private View mDecorView;
@Mock private LayoutStateProvider mLayoutStateProvider;
@Mock private UpdateMenuItemHelper mUpdateMenuItemHelper;
@Mock private UserPrefs.Natives mUserPrefsJniMock;
@Mock private Profile mProfile;
@Mock private PrefService mPrefService;
@Mock private TabModelFilterProvider mTabModelFilterProvider;
@Mock private TabModelFilter mTabModelFilter;
@Mock public WebsitePreferenceBridge.Natives mWebsitePreferenceBridgeJniMock;
@Mock public BookmarkModel mBookmarkModel;
@Mock private IdentityManager mIdentityManagerMock;
@Mock private IdentityServicesProvider mIdentityServicesProviderMock;
@Mock private ManagedBrowserUtils.Natives mManagedBrowserUtilsJniMock;
@Mock private IncognitoReauthController mIncognitoReauthControllerMock;
@Mock private IncognitoUtils.Natives mIncognitoUtilsJniMock;
@Mock private ShoppingService mShoppingService;
@Mock private AppBannerManager.Natives mAppBannerManagerJniMock;
@Mock private ReadAloudController mReadAloudController;
@Mock private TranslateBridge.Natives mTranslateBridgeJniMock;
@Mock private AppMenuHandler mAppMenuHandler;
@Mock private AppMenuPropertiesDelegate.CustomItemViewTypeProvider mCustomItemViewTypeProvider;
@Mock private NativePage mNativePage;
private OneshotSupplierImpl<IncognitoReauthController> mIncognitoReauthControllerSupplier =
new OneshotSupplierImpl<>();
private OneshotSupplierImpl<LayoutStateProvider> mLayoutStateProviderSupplier =
new OneshotSupplierImpl<>();
private ObservableSupplierImpl<BookmarkModel> mBookmarkModelSupplier =
new ObservableSupplierImpl<>();
private ObservableSupplierImpl<ReadAloudController> mReadAloudControllerSupplier =
new ObservableSupplierImpl<>();
private final TestValues mTestValues = new TestValues();
private AppMenuPropertiesDelegateImpl mAppMenuPropertiesDelegate;
private MenuUiState mMenuUiState;
private ShadowPackageManager mShadowPackageManager;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
setupFeatureDefaults();
Context context =
new ContextThemeWrapper(
ContextUtils.getApplicationContext(), R.style.Theme_BrowserUI_DayNight);
mShadowPackageManager = Shadows.shadowOf(context.getPackageManager());
mLayoutStateProviderSupplier.set(mLayoutStateProvider);
mIncognitoReauthControllerSupplier.set(mIncognitoReauthControllerMock);
mReadAloudControllerSupplier.set(mReadAloudController);
when(mTab.getWebContents()).thenReturn(mWebContents);
when(mTab.getProfile()).thenReturn(mProfile);
when(mWebContents.getNavigationController()).thenReturn(mNavigationController);
when(mNavigationController.getUseDesktopUserAgent()).thenReturn(false);
when(mTabModelSelector.isTabStateInitialized()).thenReturn(true);
when(mTabModelSelector.getCurrentModel()).thenReturn(mTabModel);
when(mTabModelSelector.getModel(false)).thenReturn((mTabModel));
when(mTabModelSelector.getModel(true)).thenReturn((mIncognitoTabModel));
when(mTabModelSelector.getTabModelFilterProvider()).thenReturn(mTabModelFilterProvider);
when(mTabModelFilterProvider.getCurrentTabModelFilter()).thenReturn(mTabModelFilter);
when(mTabModelFilter.getTabModel()).thenReturn(mTabModel);
when(mTabModel.isIncognito()).thenReturn(false);
when(mIncognitoTabModel.isIncognito()).thenReturn(true);
PageZoomCoordinator.setShouldShowMenuItemForTesting(false);
UpdateMenuItemHelper.setInstanceForTesting(mUpdateMenuItemHelper);
mMenuUiState = new MenuUiState();
doReturn(mMenuUiState).when(mUpdateMenuItemHelper).getUiState();
mJniMocker.mock(UserPrefsJni.TEST_HOOKS, mUserPrefsJniMock);
mJniMocker.mock(WebsitePreferenceBridgeJni.TEST_HOOKS, mWebsitePreferenceBridgeJniMock);
Mockito.when(mUserPrefsJniMock.get(mProfile)).thenReturn(mPrefService);
PowerBookmarkUtils.setPriceTrackingEligibleForTesting(false);
WebappRegistry.refreshSharedPrefsForTesting();
mJniMocker.mock(ManagedBrowserUtilsJni.TEST_HOOKS, mManagedBrowserUtilsJniMock);
Mockito.when(mManagedBrowserUtilsJniMock.isBrowserManaged(mProfile)).thenReturn(false);
Mockito.when(mManagedBrowserUtilsJniMock.getTitle(mProfile)).thenReturn("title");
mJniMocker.mock(AppBannerManagerJni.TEST_HOOKS, mAppBannerManagerJniMock);
Mockito.when(mAppBannerManagerJniMock.getInstallableWebAppManifestId(any()))
.thenReturn(null);
mJniMocker.mock(TranslateBridgeJni.TEST_HOOKS, mTranslateBridgeJniMock);
Mockito.when(mTranslateBridgeJniMock.canManuallyTranslate(any(), anyBoolean()))
.thenReturn(false);
mJniMocker.mock(IncognitoUtilsJni.TEST_HOOKS, mIncognitoUtilsJniMock);
mBookmarkModelSupplier.set(mBookmarkModel);
PowerBookmarkUtils.setPriceTrackingEligibleForTesting(false);
PowerBookmarkUtils.setPowerBookmarkMetaForTesting(PowerBookmarkMeta.newBuilder().build());
mAppMenuPropertiesDelegate =
Mockito.spy(
new AppMenuPropertiesDelegateImpl(
context,
mActivityTabProvider,
mMultiWindowModeStateDispatcher,
mTabModelSelector,
mToolbarManager,
mDecorView,
mLayoutStateProviderSupplier,
mBookmarkModelSupplier,
mIncognitoReauthControllerSupplier,
mReadAloudControllerSupplier));
ShoppingServiceFactory.setShoppingServiceForTesting(mShoppingService);
BuildConfig.IS_DESKTOP_ANDROID = false;
ResettersForTesting.register(() -> BuildConfig.IS_DESKTOP_ANDROID = false);
}
@After
public void tearDown() {
AccessibilityState.setIsScreenReaderEnabledForTesting(false);
}
private void setupFeatureDefaults() {
setShoppingListEligible(false);
setShoppingListEligible(false);
FeatureList.setTestValues(mTestValues);
}
private void setShoppingListEligible(boolean enabled) {
ShoppingFeatures.setShoppingListEligibleForTesting(enabled);
FeatureList.setTestValues(mTestValues);
}
@Test
@Config(qualifiers = "sw320dp")
public void testShouldShowPageMenu_Phone() {
setUpMocksForPageMenu();
assertTrue(mAppMenuPropertiesDelegate.shouldShowPageMenu());
Assert.assertEquals(MenuGroup.PAGE_MENU, mAppMenuPropertiesDelegate.getMenuGroup());
}
@Test
@Config(qualifiers = "sw600dp")
public void testShouldShowPageMenu_Tablet() {
when(mLayoutStateProvider.isLayoutVisible(LayoutType.TAB_SWITCHER)).thenReturn(false);
when(mTabModel.getCount()).thenReturn(1);
assertTrue(mAppMenuPropertiesDelegate.shouldShowPageMenu());
Assert.assertEquals(MenuGroup.PAGE_MENU, mAppMenuPropertiesDelegate.getMenuGroup());
}
@Test
@Config(qualifiers = "sw600dp")
public void testShouldShowOverviewMenu_Tablet() {
when(mLayoutStateProvider.isLayoutVisible(LayoutType.TAB_SWITCHER)).thenReturn(true);
when(mTabModel.getCount()).thenReturn(1);
Assert.assertFalse(mAppMenuPropertiesDelegate.shouldShowPageMenu());
Assert.assertEquals(
MenuGroup.OVERVIEW_MODE_MENU, mAppMenuPropertiesDelegate.getMenuGroup());
}
@Test
@Config(qualifiers = "sw320dp")
public void testShouldShowIconRow_Phone() {
assertTrue(mAppMenuPropertiesDelegate.shouldShowIconRow());
}
@Test
@Config(qualifiers = "sw600dp")
public void testShouldShowIconRow_Tablet() {
when(mDecorView.getWidth())
.thenReturn(
(int)
(600
* ContextUtils.getApplicationContext()
.getResources()
.getDisplayMetrics()
.density));
Assert.assertFalse(mAppMenuPropertiesDelegate.shouldShowIconRow());
}
@Test
@Config(qualifiers = "sw600dp")
public void testShouldShowIconRow_TabletNarrow() {
when(mDecorView.getWidth())
.thenReturn(
(int)
(100
* ContextUtils.getApplicationContext()
.getResources()
.getDisplayMetrics()
.density));
assertTrue(mAppMenuPropertiesDelegate.shouldShowIconRow());
}
@Test
@Config(qualifiers = "sw320dp")
public void testPageMenuItems_Phone_Ntp() {
setUpMocksForPageMenu();
when(mTab.getUrl()).thenReturn(JUnitTestGURLs.NTP_URL);
when(mTab.isNativePage()).thenReturn(true);
when(mNativePage.isPdf()).thenReturn(false);
when(mTab.getNativePage()).thenReturn(mNativePage);
doReturn(false)
.when(mAppMenuPropertiesDelegate)
.shouldShowTranslateMenuItem(any(Tab.class));
Assert.assertEquals(MenuGroup.PAGE_MENU, mAppMenuPropertiesDelegate.getMenuGroup());
Menu menu = createTestMenu();
mAppMenuPropertiesDelegate.prepareMenu(menu, null);
Integer[] expectedItems = {
R.id.icon_row_menu_id,
R.id.new_tab_menu_id,
R.id.new_incognito_tab_menu_id,
R.id.divider_line_id,
R.id.open_history_menu_id,
R.id.quick_delete_menu_id,
R.id.quick_delete_divider_line_id,
R.id.downloads_menu_id,
R.id.all_bookmarks_menu_id,
R.id.recent_tabs_menu_id,
R.id.divider_line_id,
R.id.preferences_id,
R.id.help_id
};
assertMenuItemsAreEqual(menu, expectedItems);
}
@Test
@Config(qualifiers = "sw320dp")
public void testPageMenuItems_Phone_Pdf() {
setUpMocksForPageMenu();
when(mTab.getUrl()).thenReturn(JUnitTestGURLs.URL_1_WITH_PDF_PATH);
when(mTab.isNativePage()).thenReturn(true);
when(mNativePage.isPdf()).thenReturn(true);
when(mTab.getNativePage()).thenReturn(mNativePage);
doReturn(false)
.when(mAppMenuPropertiesDelegate)
.shouldShowTranslateMenuItem(any(Tab.class));
Assert.assertEquals(MenuGroup.PAGE_MENU, mAppMenuPropertiesDelegate.getMenuGroup());
Menu menu = createTestMenu();
mAppMenuPropertiesDelegate.prepareMenu(menu, null);
Integer[] expectedItems = {
R.id.icon_row_menu_id,
R.id.new_tab_menu_id,
R.id.new_incognito_tab_menu_id,
R.id.divider_line_id,
R.id.open_history_menu_id,
R.id.quick_delete_menu_id,
R.id.quick_delete_divider_line_id,
R.id.downloads_menu_id,
R.id.all_bookmarks_menu_id,
R.id.recent_tabs_menu_id,
R.id.divider_line_id,
R.id.find_in_page_id,
R.id.divider_line_id,
R.id.preferences_id,
R.id.help_id
};
assertMenuItemsAreEqual(menu, expectedItems);
}
@Test
@Config(qualifiers = "sw320dp")
public void testPageMenuItems_Phone_RegularPage() {
setUpMocksForPageMenu();
setMenuOptions(
new MenuOptions()
.withShowTranslate()
.withShowAddToHomeScreen()
.withAutoDarkEnabled());
Assert.assertEquals(MenuGroup.PAGE_MENU, mAppMenuPropertiesDelegate.getMenuGroup());
Menu menu = createTestMenu();
mAppMenuPropertiesDelegate.prepareMenu(menu, null);
Integer[] expectedItems = {
R.id.icon_row_menu_id,
R.id.new_tab_menu_id,
R.id.new_incognito_tab_menu_id,
R.id.divider_line_id,
R.id.open_history_menu_id,
R.id.quick_delete_menu_id,
R.id.quick_delete_divider_line_id,
R.id.downloads_menu_id,
R.id.all_bookmarks_menu_id,
R.id.recent_tabs_menu_id,
R.id.divider_line_id,
R.id.share_row_menu_id,
R.id.find_in_page_id,
R.id.translate_id,
R.id.universal_install,
R.id.request_desktop_site_row_menu_id,
R.id.auto_dark_web_contents_row_menu_id,
R.id.divider_line_id,
R.id.preferences_id,
R.id.help_id
};
Integer[] expectedTitles = {
0,
R.string.menu_new_tab,
R.string.menu_new_incognito_tab,
0,
R.string.menu_history,
R.string.menu_quick_delete,
0,
R.string.menu_downloads,
R.string.menu_bookmarks,
R.string.menu_recent_tabs,
0,
0,
R.string.menu_find_in_page,
R.string.menu_translate,
R.string.menu_add_to_homescreen,
0,
0,
0,
R.string.menu_settings,
R.string.menu_help
};
Integer[] expectedActionBarItems = {
R.id.forward_menu_id,
R.id.bookmark_this_page_id,
R.id.offline_page_id,
R.id.info_menu_id,
R.id.reload_menu_id
};
assertMenuItemsAreEqual(menu, expectedItems);
assertMenuTitlesAreEqual(menu, expectedTitles);
assertActionBarItemsAreEqual(menu, expectedActionBarItems);
}
@Test
@Config(qualifiers = "sw320dp")
public void testPageMenuItems_Phone_RegularPage_WithPwa() {
setUpMocksForPageMenu();
setMenuOptions(
new MenuOptions()
.withShowTranslate()
.withShowAddToHomeScreen()
.withAutoDarkEnabled());
Assert.assertEquals(MenuGroup.PAGE_MENU, mAppMenuPropertiesDelegate.getMenuGroup());
Menu menu = createTestMenu();
mAppMenuPropertiesDelegate.prepareMenu(menu, null);
Integer[] expectedItems = {
R.id.icon_row_menu_id,
R.id.new_tab_menu_id,
R.id.new_incognito_tab_menu_id,
R.id.divider_line_id,
R.id.open_history_menu_id,
R.id.quick_delete_menu_id,
R.id.quick_delete_divider_line_id,
R.id.downloads_menu_id,
R.id.all_bookmarks_menu_id,
R.id.recent_tabs_menu_id,
R.id.divider_line_id,
R.id.translate_id,
R.id.share_row_menu_id,
R.id.find_in_page_id,
R.id.universal_install,
R.id.request_desktop_site_row_menu_id,
R.id.auto_dark_web_contents_row_menu_id,
R.id.divider_line_id,
R.id.preferences_id,
R.id.help_id
};
Integer[] expectedTitles = {
0,
R.string.menu_new_tab,
R.string.menu_new_incognito_tab,
0,
R.string.menu_history,
R.string.menu_quick_delete,
0,
R.string.menu_downloads,
R.string.menu_bookmarks,
R.string.menu_recent_tabs,
0,
0,
R.string.menu_find_in_page,
R.string.menu_translate,
R.string.menu_add_to_homescreen,
0,
0,
0,
R.string.menu_settings,
R.string.menu_help
};
Integer[] expectedActionBarItems = {
R.id.forward_menu_id,
R.id.bookmark_this_page_id,
R.id.offline_page_id,
R.id.info_menu_id,
R.id.reload_menu_id
};
assertMenuItemsAreEqual(menu, expectedItems);
assertMenuTitlesAreEqual(menu, expectedTitles);
assertActionBarItemsAreEqual(menu, expectedActionBarItems);
}
@Test
@Config(qualifiers = "sw320dp")
public void testPageMenuItems_Phone_RegularPage_enterprise_user() {
setUpMocksForPageMenu();
setMenuOptions(
new MenuOptions()
.withShowTranslate()
.withShowAddToHomeScreen()
.withAutoDarkEnabled());
doReturn(true).when(mAppMenuPropertiesDelegate).shouldShowManagedByMenuItem(any(Tab.class));
Assert.assertEquals(MenuGroup.PAGE_MENU, mAppMenuPropertiesDelegate.getMenuGroup());
Menu menu = createTestMenu();
mAppMenuPropertiesDelegate.prepareMenu(menu, null);
Integer[] expectedItems = {
R.id.icon_row_menu_id,
R.id.new_tab_menu_id,
R.id.new_incognito_tab_menu_id,
R.id.divider_line_id,
R.id.open_history_menu_id,
R.id.quick_delete_menu_id,
R.id.quick_delete_divider_line_id,
R.id.downloads_menu_id,
R.id.all_bookmarks_menu_id,
R.id.recent_tabs_menu_id,
R.id.divider_line_id,
R.id.share_row_menu_id,
R.id.find_in_page_id,
R.id.translate_id,
R.id.universal_install,
R.id.request_desktop_site_row_menu_id,
R.id.auto_dark_web_contents_row_menu_id,
R.id.divider_line_id,
R.id.preferences_id,
R.id.help_id,
R.id.managed_by_divider_line_id,
R.id.managed_by_menu_id
};
assertMenuItemsAreEqual(menu, expectedItems);
}
@Test
@Config(qualifiers = "sw320dp")
public void testPageMenuItems_DesktopAndroid() {
BuildConfig.IS_DESKTOP_ANDROID = true;
setUpMocksForPageMenu();
setMenuOptions(
new MenuOptions()
.withShowTranslate()
.withShowAddToHomeScreen()
.withAutoDarkEnabled());
Assert.assertEquals(MenuGroup.PAGE_MENU, mAppMenuPropertiesDelegate.getMenuGroup());
Menu menu = createTestMenu();
mAppMenuPropertiesDelegate.prepareMenu(menu, null);
Integer[] expectedItems = {
R.id.icon_row_menu_id,
R.id.new_tab_menu_id,
R.id.new_incognito_tab_menu_id,
R.id.divider_line_id,
R.id.open_history_menu_id,
R.id.quick_delete_menu_id,
R.id.quick_delete_divider_line_id,
R.id.downloads_menu_id,
R.id.all_bookmarks_menu_id,
R.id.recent_tabs_menu_id,
R.id.divider_line_id,
R.id.share_row_menu_id,
R.id.find_in_page_id,
R.id.translate_id,
R.id.universal_install,
// Request desktop site is hidden.
R.id.auto_dark_web_contents_row_menu_id,
R.id.divider_line_id,
R.id.preferences_id,
R.id.help_id
};
assertMenuItemsAreEqual(menu, expectedItems);
}
@Test
@Config(qualifiers = "sw320dp")
public void testPageMenuItemsIcons_Phone_RegularPage_iconsAfterMenuItems() {
setUpMocksForPageMenu();
setMenuOptions(new MenuOptions().withAllSet().setNativePage(false));
Assert.assertEquals(MenuGroup.PAGE_MENU, mAppMenuPropertiesDelegate.getMenuGroup());
Menu menu = createTestMenu();
mAppMenuPropertiesDelegate.prepareMenu(menu, null);
Integer[] expectedItems = {R.id.update_menu_id, R.id.reader_mode_prefs_id};
assertMenuItemsHaveIcons(menu, expectedItems);
}
@Test
@Config(qualifiers = "sw320dp")
public void testPageMenuItemsIcons_Phone_RegularPage_iconsBeforeMenuItems() {
setUpMocksForPageMenu();
setMenuOptions(
new MenuOptions()
.withAllSet()
.setNativePage(false)
.setShowMoveToOtherWindow(false)
.setShowPaintPreview(false));
doReturn(true).when(mAppMenuPropertiesDelegate).shouldShowIconBeforeItem();
Assert.assertEquals(MenuGroup.PAGE_MENU, mAppMenuPropertiesDelegate.getMenuGroup());
Menu menu = createTestMenu();
mAppMenuPropertiesDelegate.prepareMenu(menu, null);
Integer[] expectedItems = {
R.id.update_menu_id,
R.id.new_tab_menu_id,
R.id.new_incognito_tab_menu_id,
R.id.open_history_menu_id,
R.id.quick_delete_menu_id,
R.id.downloads_menu_id,
R.id.all_bookmarks_menu_id,
R.id.recent_tabs_menu_id,
R.id.translate_id,
R.id.find_in_page_id,
R.id.universal_install,
R.id.reader_mode_prefs_id,
R.id.preferences_id,
R.id.help_id
};
assertMenuItemsHaveIcons(menu, expectedItems);
}
private void checkOverviewMenuItemsPhone(int tabSelectionEditorMenuItemId) {
setUpMocksForOverviewMenu(LayoutType.TAB_SWITCHER);
when(mIncognitoTabModel.getCount()).thenReturn(0);
Assert.assertFalse(mAppMenuPropertiesDelegate.shouldShowPageMenu());
Assert.assertEquals(
MenuGroup.OVERVIEW_MODE_MENU, mAppMenuPropertiesDelegate.getMenuGroup());
Menu menu = createTestMenu();
mAppMenuPropertiesDelegate.prepareMenu(menu, null);
Integer[] expectedItems = {
R.id.new_tab_menu_id,
R.id.new_incognito_tab_menu_id,
R.id.close_all_tabs_menu_id,
tabSelectionEditorMenuItemId,
R.id.quick_delete_menu_id,
R.id.preferences_id
};
assertMenuItemsAreEqual(menu, expectedItems);
}
@Test
@Config(qualifiers = "sw320dp")
public void testOverviewMenuItems_Phone_SelectTabs() {
checkOverviewMenuItemsPhone(R.id.menu_select_tabs);
}
@Test
@Config(qualifiers = "sw600dp")
public void testOverviewMenuItems_Tablet_NoTabs() {
setUpIncognitoMocks();
when(mLayoutStateProvider.isLayoutVisible(LayoutType.TAB_SWITCHER)).thenReturn(false);
when(mTabModel.getCount()).thenReturn(0);
Assert.assertEquals(
MenuGroup.TABLET_EMPTY_MODE_MENU, mAppMenuPropertiesDelegate.getMenuGroup());
Assert.assertFalse(mAppMenuPropertiesDelegate.shouldShowPageMenu());
Menu menu = createTestMenu();
mAppMenuPropertiesDelegate.prepareMenu(menu, null);
Integer[] expectedItems = {
R.id.new_tab_menu_id,
R.id.new_incognito_tab_menu_id,
R.id.preferences_id,
R.id.quick_delete_menu_id
};
assertMenuItemsAreEqual(menu, expectedItems);
}
@Test
public void testMenuItems_Accessibility_ImageDescriptions() {
setUpMocksForPageMenu();
when(mTab.getUrl()).thenReturn(JUnitTestGURLs.SEARCH_URL);
when(mTab.isNativePage()).thenReturn(false);
doReturn(false)
.when(mAppMenuPropertiesDelegate)
.shouldShowPaintPreview(anyBoolean(), any(Tab.class), anyBoolean());
doReturn(false)
.when(mAppMenuPropertiesDelegate)
.shouldShowTranslateMenuItem(any(Tab.class));
// Ensure the get image descriptions option is shown as needed
when(mPrefService.getBoolean(Pref.ACCESSIBILITY_IMAGE_LABELS_ENABLED_ANDROID))
.thenReturn(false);
// Test specific setup
ThreadUtils.setThreadAssertsDisabledForTesting(true);
AccessibilityState.setIsScreenReaderEnabledForTesting(true);
Menu menu = createTestMenu();
mAppMenuPropertiesDelegate.prepareMenu(menu, null);
Integer[] expectedItems = {
R.id.icon_row_menu_id,
R.id.new_tab_menu_id,
R.id.new_incognito_tab_menu_id,
R.id.divider_line_id,
R.id.open_history_menu_id,
R.id.quick_delete_menu_id,
R.id.quick_delete_divider_line_id,
R.id.downloads_menu_id,
R.id.all_bookmarks_menu_id,
R.id.recent_tabs_menu_id,
R.id.divider_line_id,
R.id.share_row_menu_id,
R.id.get_image_descriptions_id,
R.id.find_in_page_id,
R.id.universal_install,
R.id.request_desktop_site_row_menu_id,
R.id.auto_dark_web_contents_row_menu_id,
R.id.divider_line_id,
R.id.preferences_id,
R.id.help_id
};
assertMenuItemsAreEqual(menu, expectedItems);
// Ensure the text of the menu item is correct
Assert.assertEquals(
"Get image descriptions", menu.findItem(R.id.get_image_descriptions_id).getTitle());
// Enable the feature and ensure text changes
when(mPrefService.getBoolean(Pref.ACCESSIBILITY_IMAGE_LABELS_ENABLED_ANDROID))
.thenReturn(true);
mAppMenuPropertiesDelegate.prepareMenu(menu, null);
Assert.assertEquals(
"Stop image descriptions",
menu.findItem(R.id.get_image_descriptions_id).getTitle());
// Setup no wifi condition, and "only on wifi" user option.
DeviceConditions noWifi =
new DeviceConditions(false, 75, ConnectionType.CONNECTION_2G, false, false, true);
ShadowDeviceConditions.setCurrentConditions(noWifi);
when(mPrefService.getBoolean(Pref.ACCESSIBILITY_IMAGE_LABELS_ONLY_ON_WIFI))
.thenReturn(true);
mAppMenuPropertiesDelegate.prepareMenu(menu, null);
Assert.assertEquals(
"Get image descriptions", menu.findItem(R.id.get_image_descriptions_id).getTitle());
}
@Test
public void updateBookmarkMenuItemShortcut() {
doReturn(true).when(mBookmarkModel).isEditBookmarksEnabled();
MenuItem bookmarkMenuItemShortcut = mock(MenuItem.class);
mAppMenuPropertiesDelegate.updateBookmarkMenuItemShortcut(
bookmarkMenuItemShortcut, mTab, /* fromCCT= */ false);
verify(bookmarkMenuItemShortcut).setEnabled(true);
}
@Test
public void updateBookmarkMenuItemShortcut_fromCCT() {
doReturn(true).when(mBookmarkModel).isEditBookmarksEnabled();
MenuItem bookmarkMenuItemShortcut = mock(MenuItem.class);
mAppMenuPropertiesDelegate.updateBookmarkMenuItemShortcut(
bookmarkMenuItemShortcut, mTab, /* fromCCT= */ true);
verify(bookmarkMenuItemShortcut).setEnabled(true);
}
@Test
public void updateBookmarkMenuItemShortcut_NullTab() {
MenuItem bookmarkMenuItemShortcut = mock(MenuItem.class);
mAppMenuPropertiesDelegate.updateBookmarkMenuItemShortcut(
bookmarkMenuItemShortcut, null, /* fromCCT= */ false);
verify(bookmarkMenuItemShortcut).setEnabled(false);
}
@Test
public void updateBookmarkMenuItemShortcut_NullBookmarkModel() {
mBookmarkModelSupplier.set(null);
MenuItem bookmarkMenuItemShortcut = mock(MenuItem.class);
mAppMenuPropertiesDelegate.updateBookmarkMenuItemShortcut(
bookmarkMenuItemShortcut, mTab, /* fromCCT= */ false);
verify(bookmarkMenuItemShortcut).setEnabled(false);
}
@Test
public void enablePriceTrackingItemRow() {
setShoppingListEligible(true);
PowerBookmarkUtils.setPriceTrackingEligibleForTesting(true);
doReturn(true).when(mBookmarkModel).isEditBookmarksEnabled();
doReturn(mock(BookmarkId.class)).when(mBookmarkModel).getUserBookmarkIdForTab(any());
PowerBookmarkMeta meta =
PowerBookmarkMeta.newBuilder()
.setShoppingSpecifics(
ShoppingSpecifics.newBuilder().setIsPriceTracked(false).build())
.build();
doReturn(meta).when(mBookmarkModel).getPowerBookmarkMeta(any());
MenuItem startPriceTrackingMenuItem = mock(MenuItem.class);
MenuItem stopPriceTrackingMenuItem = mock(MenuItem.class);
mAppMenuPropertiesDelegate.updatePriceTrackingMenuItemRow(
startPriceTrackingMenuItem, stopPriceTrackingMenuItem, mTab);
verify(startPriceTrackingMenuItem).setVisible(true);
verify(startPriceTrackingMenuItem).setEnabled(true);
verify(stopPriceTrackingMenuItem).setVisible(false);
}
@Test
public void enablePriceTrackingItemRow_NullBookmarkModel() {
setShoppingListEligible(true);
PowerBookmarkUtils.setPriceTrackingEligibleForTesting(true);
mBookmarkModelSupplier.set(null);
MenuItem startPriceTrackingMenuItem = mock(MenuItem.class);
MenuItem stopPriceTrackingMenuItem = mock(MenuItem.class);
mAppMenuPropertiesDelegate.updatePriceTrackingMenuItemRow(
startPriceTrackingMenuItem, stopPriceTrackingMenuItem, mTab);
verify(startPriceTrackingMenuItem).setVisible(false);
verify(stopPriceTrackingMenuItem).setVisible(false);
}
@Test
public void enablePriceTrackingItemRow_NullBookmarkId() {
setShoppingListEligible(true);
PowerBookmarkUtils.setPriceTrackingEligibleForTesting(true);
doReturn(true).when(mBookmarkModel).isEditBookmarksEnabled();
doReturn(null).when(mBookmarkModel).getUserBookmarkIdForTab(any());
PowerBookmarkMeta meta =
PowerBookmarkMeta.newBuilder()
.setShoppingSpecifics(
ShoppingSpecifics.newBuilder().setIsPriceTracked(false).build())
.build();
doReturn(meta).when(mBookmarkModel).getPowerBookmarkMeta(any());
MenuItem startPriceTrackingMenuItem = mock(MenuItem.class);
MenuItem stopPriceTrackingMenuItem = mock(MenuItem.class);
mAppMenuPropertiesDelegate.updatePriceTrackingMenuItemRow(
startPriceTrackingMenuItem, stopPriceTrackingMenuItem, mTab);
verify(startPriceTrackingMenuItem).setVisible(true);
verify(startPriceTrackingMenuItem).setEnabled(true);
verify(stopPriceTrackingMenuItem).setVisible(false);
}
@Test
public void enablePriceTrackingItemRow_PriceTrackingEnabled() {
setShoppingListEligible(true);
PowerBookmarkUtils.setPriceTrackingEligibleForTesting(true);
doReturn(true).when(mBookmarkModel).isEditBookmarksEnabled();
BookmarkId bookmarkId = mock(BookmarkId.class);
List<BookmarkId> allBookmarks = new ArrayList<>();
allBookmarks.add(bookmarkId);
doReturn(bookmarkId).when(mBookmarkModel).getUserBookmarkIdForTab(any());
doReturn(allBookmarks)
.when(mBookmarkModel)
.getBookmarksOfType(eq(PowerBookmarkType.SHOPPING));
Long clusterId = 1L;
doReturn(
new ShoppingService.ProductInfo(
"",
new GURL(""),
Optional.of(clusterId),
Optional.empty(),
"",
0,
"",
Optional.empty()))
.when(mShoppingService)
.getAvailableProductInfoForUrl(any());
doReturn(true).when(mShoppingService).isSubscribedFromCache(any());
PowerBookmarkMeta meta =
PowerBookmarkMeta.newBuilder()
.setShoppingSpecifics(
ShoppingSpecifics.newBuilder()
.setIsPriceTracked(true)
.setProductClusterId(clusterId)
.build())
.build();
PowerBookmarkUtils.setPowerBookmarkMetaForTesting(meta);
doReturn(meta).when(mBookmarkModel).getPowerBookmarkMeta(any());
MenuItem startPriceTrackingMenuItem = mock(MenuItem.class);
MenuItem stopPriceTrackingMenuItem = mock(MenuItem.class);
mAppMenuPropertiesDelegate.updatePriceTrackingMenuItemRow(
startPriceTrackingMenuItem, stopPriceTrackingMenuItem, mTab);
verify(stopPriceTrackingMenuItem).setVisible(true);
verify(stopPriceTrackingMenuItem).setEnabled(true);
verify(startPriceTrackingMenuItem).setVisible(false);
}
@Test
public void enablePriceTrackingItemRow_PriceTrackingEnabled_NoProductInfo() {
setShoppingListEligible(true);
PowerBookmarkUtils.setPriceTrackingEligibleForTesting(false);
doReturn(true).when(mBookmarkModel).isEditBookmarksEnabled();
BookmarkId bookmarkId = mock(BookmarkId.class);
doReturn(bookmarkId).when(mBookmarkModel).getUserBookmarkIdForTab(any());
doReturn(new ArrayList<BookmarkId>())
.when(mBookmarkModel)
.getBookmarksOfType(eq(PowerBookmarkType.SHOPPING));
MenuItem startPriceTrackingMenuItem = mock(MenuItem.class);
MenuItem stopPriceTrackingMenuItem = mock(MenuItem.class);
mAppMenuPropertiesDelegate.updatePriceTrackingMenuItemRow(
startPriceTrackingMenuItem, stopPriceTrackingMenuItem, mTab);
verify(stopPriceTrackingMenuItem).setVisible(false);
verify(startPriceTrackingMenuItem).setVisible(false);
}
@Test
public void shouldCheckBookmarkStar() {
doReturn(true).when(mBookmarkModel).hasBookmarkIdForTab(mTab);
assertTrue(mAppMenuPropertiesDelegate.shouldCheckBookmarkStar(mTab));
}
@Test
public void shouldCheckBookmarkStar_NullBookmarkModel() {
mBookmarkModelSupplier.set(null);
Assert.assertFalse(mAppMenuPropertiesDelegate.shouldCheckBookmarkStar(mTab));
}
@Test
public void managedByMenuItem_ChromeManagementPage() {
setUpMocksForPageMenu();
setMenuOptions(new MenuOptions().withShowAddToHomeScreen());
doReturn(true).when(mAppMenuPropertiesDelegate).shouldShowManagedByMenuItem(any(Tab.class));
Assert.assertEquals(MenuGroup.PAGE_MENU, mAppMenuPropertiesDelegate.getMenuGroup());
Menu menu = createTestMenu();
mAppMenuPropertiesDelegate.prepareMenu(menu, null);
MenuItem managedByMenuItem = menu.findItem(R.id.managed_by_menu_id);
Assert.assertNotNull(managedByMenuItem);
assertTrue(managedByMenuItem.isVisible());
}
@Test
@SmallTest
public void testNewIncognitoTabOption_WithReauthInProgress() {
setUpMocksForPageMenu();
setMenuOptions(
new MenuOptions()
.withShowTranslate()
.withShowAddToHomeScreen()
.withAutoDarkEnabled());
doReturn(true).when(mIncognitoReauthControllerMock).isReauthPageShowing();
doReturn(mIncognitoTabModel).when(mTabModelSelector).getCurrentModel();
Menu menu = createTestMenu();
mAppMenuPropertiesDelegate.prepareMenu(menu, null);
verify(mIncognitoReauthControllerMock, times(1)).isReauthPageShowing();
MenuItem item = menu.findItem(R.id.new_incognito_tab_menu_id);
assertFalse(item.isEnabled());
}
@Test
@SmallTest
public void testNewIncognitoTabOption_FromRegularMode_WithReauthNotInProgress() {
setUpMocksForPageMenu();
setMenuOptions(
new MenuOptions()
.withShowTranslate()
.withShowAddToHomeScreen()
.withAutoDarkEnabled());
doReturn(mTabModel).when(mTabModelSelector).getCurrentModel();
Menu menu = createTestMenu();
mAppMenuPropertiesDelegate.prepareMenu(menu, null);
verifyNoMoreInteractions(mIncognitoReauthControllerMock);
MenuItem item = menu.findItem(R.id.new_incognito_tab_menu_id);
assertTrue(item.isEnabled());
}
private Menu setUpMenuWithIncognitoReauthPage(boolean isShowing) {
setUpMocksForOverviewMenu(LayoutType.TAB_SWITCHER);
when(mTabModelSelector.getCurrentModel()).thenReturn(mIncognitoTabModel);
prepareMocksForGroupTabsOnTabModel(mIncognitoTabModel);
doReturn(isShowing).when(mIncognitoReauthControllerMock).isReauthPageShowing();
Menu menu = createTestMenu();
mAppMenuPropertiesDelegate.prepareMenu(menu, null);
verify(mIncognitoReauthControllerMock, times(1)).isReauthPageShowing();
return menu;
}
@Test
@SmallTest
public void testSelectTabsOption_IsEnabled_InIncognitoMode_When_IncognitoReauthIsNotShowing() {
Menu menu = setUpMenuWithIncognitoReauthPage(/* isShowing= */ false);
MenuItem item = menu.findItem(R.id.menu_select_tabs);
assertTrue(item.isEnabled());
}
@Test
@SmallTest
public void testSelectTabsOption_IsDisabled_InIncognitoMode_When_IncognitoReauthIsShowing() {
Menu menu = setUpMenuWithIncognitoReauthPage(/* isShowing= */ true);
MenuItem item = menu.findItem(R.id.menu_select_tabs);
assertFalse(item.isEnabled());
}
@Test
@SmallTest
public void testSelectTabsOption_IsEnabled_InRegularMode_IndependentOfIncognitoReauth() {
setUpMocksForOverviewMenu(LayoutType.TAB_SWITCHER);
when(mTabModelSelector.getCurrentModel()).thenReturn(mTabModel);
prepareMocksForGroupTabsOnTabModel(mTabModel);
Menu menu = createTestMenu();
mAppMenuPropertiesDelegate.prepareMenu(menu, null);
// Check group tabs enabled decision in regular mode doesn't depend on re-auth.
verify(mIncognitoReauthControllerMock, times(0)).isReauthPageShowing();
MenuItem item = menu.findItem(R.id.menu_select_tabs);
assertTrue(item.isEnabled());
}
@Test
@SmallTest
public void testSelectTabsOption_IsDisabled_InRegularMode_TabStateNotInitialized() {
setUpMocksForOverviewMenu(LayoutType.TAB_SWITCHER);
when(mTabModelSelector.getCurrentModel()).thenReturn(mTabModel);
prepareMocksForGroupTabsOnTabModel(mTabModel);
when(mTabModelSelector.isTabStateInitialized()).thenReturn(false);
Menu menu = createTestMenu();
mAppMenuPropertiesDelegate.prepareMenu(menu, null);
// Check group tabs enabled decision in regular mode doesn't depend on re-auth.
verify(mIncognitoReauthControllerMock, times(0)).isReauthPageShowing();
MenuItem item = menu.findItem(R.id.menu_select_tabs);
assertFalse(item.isEnabled());
}
@Test
@SmallTest
public void testSelectTabsOption_IsEnabledOneTab_InRegularMode_IndependentOfIncognitoReauth() {
setUpMocksForOverviewMenu(LayoutType.TAB_SWITCHER);
when(mTabModelSelector.getCurrentModel()).thenReturn(mTabModel);
when(mTabModelFilter.getTabModel()).thenReturn(mTabModel);
when(mTabModelFilter.getCount()).thenReturn(1);
when(mTabModel.getCount()).thenReturn(1);
Tab mockTab1 = mock(Tab.class);
when(mTabModel.getTabAt(0)).thenReturn(mockTab1);
Menu menu = createTestMenu();
mAppMenuPropertiesDelegate.prepareMenu(menu, null);
// Check group tabs enabled decision in regular mode doesn't depend on re-auth.
verify(mIncognitoReauthControllerMock, times(0)).isReauthPageShowing();
MenuItem item = menu.findItem(R.id.menu_select_tabs);
assertTrue(item.isEnabled());
}
@Test
@SmallTest
public void testSelectTabsOption_IsDisabled_InRegularMode_IndependentOfIncognitoReauth() {
setUpMocksForOverviewMenu(LayoutType.TAB_SWITCHER);
when(mTabModelSelector.getCurrentModel()).thenReturn(mTabModel);
Menu menu = createTestMenu();
mAppMenuPropertiesDelegate.prepareMenu(menu, null);
// Check group tabs enabled decision in regular mode doesn't depend on re-auth.
verify(mIncognitoReauthControllerMock, times(0)).isReauthPageShowing();
MenuItem item = menu.findItem(R.id.menu_select_tabs);
assertFalse(item.isEnabled());
}
@Test
public void testShouldShowNewMenu_alreadyMaxWindows_returnsFalse() {
assertFalse(
doTestShouldShowNewMenu(
/* isAutomotive= */ false,
/* isInstanceSwitcherEnabled= */ true,
/* currentWindowInstances= */ 10,
/* isTabletSizeScreen= */ true,
/* canEnterMultiWindowMode= */ false,
/* isChromeRunningInAdjacentWindow= */ false,
/* isInMultiWindowMode= */ false,
/* isInMultiDisplayMode= */ false,
/* isMultiInstanceRunning= */ false));
verify(mAppMenuPropertiesDelegate, never()).isTabletSizeScreen();
}
@Test
public void testShouldShowNewMenu_isAutomotive_returnsFalse() {
assertFalse(
doTestShouldShowNewMenu(
/* isAutomotive= */ true,
/* isInstanceSwitcherEnabled= */ true,
/* currentWindowInstances= */ 1,
/* isTabletSizeScreen= */ true,
/* canEnterMultiWindowMode= */ false,
/* isChromeRunningInAdjacentWindow= */ false,
/* isInMultiWindowMode= */ false,
/* isInMultiDisplayMode= */ false,
/* isMultiInstanceRunning= */ false));
verify(mAppMenuPropertiesDelegate, never()).isTabletSizeScreen();
}
@Test
public void testShouldShowNewMenu_instanceSwitcherDisabled_isAutomotive_returnsFalse() {
assertFalse(
doTestShouldShowNewMenu(
/* isAutomotive= */ true,
/* isInstanceSwitcherEnabled= */ false,
/* currentWindowInstances= */ 1,
/* isTabletSizeScreen= */ true,
/* canEnterMultiWindowMode= */ false,
/* isChromeRunningInAdjacentWindow= */ false,
/* isInMultiWindowMode= */ false,
/* isInMultiDisplayMode= */ true,
/* isMultiInstanceRunning= */ false));
verify(mAppMenuPropertiesDelegate, never()).isTabletSizeScreen();
}
@Test
public void testShouldShowMoveToOtherWindow_returnsTrue() {
assertTrue(
doTestShouldShowMoveToOtherWindowMenu(
/* totalTabCount= */ 1,
/* isInstanceSwitcherEnabled= */ false,
/* currentWindowInstances= */ 1,
/* isTabletSizeScreen= */ true,
/* canEnterMultiWindowMode= */ false,
/* isChromeRunningInAdjacentWindow= */ false,
/* isInMultiWindowMode= */ false,
/* isInMultiDisplayMode= */ false,
/* isMultiInstanceRunning= */ false,
/* isMoveToOtherWindowSupported= */ true));
}
@Test
public void testShouldShowMoveToOtherWindow_dispatcherReturnsFalse_returnsFalse() {
assertFalse(
doTestShouldShowMoveToOtherWindowMenu(
/* totalTabCount= */ 1,
/* isInstanceSwitcherEnabled= */ false,
/* currentWindowInstances= */ 1,
/* isTabletSizeScreen= */ true,
/* canEnterMultiWindowMode= */ false,
/* isChromeRunningInAdjacentWindow= */ false,
/* isInMultiWindowMode= */ false,
/* isInMultiDisplayMode= */ true,
/* isMultiInstanceRunning= */ false,
/* isMoveToOtherWindowSupported= */ false));
verify(mAppMenuPropertiesDelegate, never()).isTabletSizeScreen();
}
@Test
public void testShouldShowNewMenu_isTabletSizedScreen_returnsTrue() {
assertTrue(
doTestShouldShowNewMenu(
/* isAutomotive= */ false,
/* isInstanceSwitcherEnabled= */ true,
/* currentWindowInstances= */ 1,
/* isTabletSizeScreen= */ true,
/* canEnterMultiWindowMode= */ false,
/* isChromeRunningInAdjacentWindow= */ false,
/* isInMultiWindowMode= */ false,
/* isInMultiDisplayMode= */ false,
/* isMultiInstanceRunning= */ false));
verify(mAppMenuPropertiesDelegate, atLeastOnce()).isTabletSizeScreen();
}
@Test
public void testShouldShowNewMenu_chromeRunningInAdjacentWindow_returnsFalse() {
assertFalse(
doTestShouldShowNewMenu(
/* isAutomotive= */ false,
/* isInstanceSwitcherEnabled= */ true,
/* currentWindowInstances= */ 1,
/* isTabletSizeScreen= */ false,
/* canEnterMultiWindowMode= */ false,
/* isChromeRunningInAdjacentWindow= */ true,
/* isInMultiWindowMode= */ true,
/* isInMultiDisplayMode= */ true,
/* isMultiInstanceRunning= */ false));
verify(mAppMenuPropertiesDelegate, atLeastOnce()).isTabletSizeScreen();
}
@Test
public void testShouldShowNewMenu_multiWindowMode_returnsTrue() {
assertTrue(
doTestShouldShowNewMenu(
/* isAutomotive= */ false,
/* isInstanceSwitcherEnabled= */ true,
/* currentWindowInstances= */ 1,
/* isTabletSizeScreen= */ false,
/* canEnterMultiWindowMode= */ false,
/* isChromeRunningInAdjacentWindow= */ false,
/* isInMultiWindowMode= */ true,
/* isInMultiDisplayMode= */ false,
/* isMultiInstanceRunning= */ false));
verify(mAppMenuPropertiesDelegate, atLeastOnce()).isTabletSizeScreen();
}
@Test
public void testShouldShowNewMenu_multiDisplayMode_returnsTrue() {
assertTrue(
doTestShouldShowNewMenu(
/* isAutomotive= */ false,
/* isInstanceSwitcherEnabled= */ true,
/* currentWindowInstances= */ 1,
/* isTabletSizeScreen= */ false,
/* canEnterMultiWindowMode= */ false,
/* isChromeRunningInAdjacentWindow= */ false,
/* isInMultiWindowMode= */ false,
/* isInMultiDisplayMode= */ true,
/* isMultiInstanceRunning= */ false));
verify(mAppMenuPropertiesDelegate, atLeastOnce()).isTabletSizeScreen();
}
@Test
public void testShouldShowNewMenu_multiInstanceRunning_returnsFalse() {
assertFalse(
doTestShouldShowNewMenu(
/* isAutomotive= */ false,
/* isInstanceSwitcherEnabled= */ false,
/* currentWindowInstances= */ 1,
/* isTabletSizeScreen= */ false,
/* canEnterMultiWindowMode= */ false,
/* isChromeRunningInAdjacentWindow= */ false,
/* isInMultiWindowMode= */ false,
/* isInMultiDisplayMode= */ false,
/* isMultiInstanceRunning= */ true));
verify(mAppMenuPropertiesDelegate, never()).isTabletSizeScreen();
verify(mAppMenuPropertiesDelegate, never()).getInstanceCount();
}
@Test
public void testShouldShowNewMenu_canEnterMultiWindowMode_returnsTrue() {
assertTrue(
doTestShouldShowNewMenu(
/* isAutomotive= */ false,
/* isInstanceSwitcherEnabled= */ false,
/* currentWindowInstances= */ 1,
/* isTabletSizeScreen= */ true,
/* canEnterMultiWindowMode= */ true,
/* isChromeRunningInAdjacentWindow= */ false,
/* isInMultiWindowMode= */ false,
/* isInMultiDisplayMode= */ false,
/* isMultiInstanceRunning= */ false));
verify(mAppMenuPropertiesDelegate, atLeastOnce()).isTabletSizeScreen();
verify(mAppMenuPropertiesDelegate, never()).getInstanceCount();
}
@Test
public void testShouldShowNewMenu_instanceSwitcherDisabled_multiWindowMode_returnsTrue() {
assertTrue(
doTestShouldShowNewMenu(
/* isAutomotive= */ false,
/* isInstanceSwitcherEnabled= */ false,
/* currentWindowInstances= */ 1,
/* isTabletSizeScreen= */ false,
/* canEnterMultiWindowMode= */ false,
/* isChromeRunningInAdjacentWindow= */ false,
/* isInMultiWindowMode= */ true,
/* isInMultiDisplayMode= */ false,
/* isMultiInstanceRunning= */ false));
verify(mAppMenuPropertiesDelegate, never()).getInstanceCount();
}
@Test
public void testShouldShowNewMenu_instanceSwitcherDisabled_multiDisplayMode_returnsTrue() {
assertTrue(
doTestShouldShowNewMenu(
/* isAutomotive= */ false,
/* isInstanceSwitcherEnabled= */ false,
/* currentWindowInstances= */ 1,
/* isTabletSizeScreen= */ false,
/* canEnterMultiWindowMode= */ false,
/* isChromeRunningInAdjacentWindow= */ false,
/* isInMultiWindowMode= */ false,
/* isInMultiDisplayMode= */ true,
/* isMultiInstanceRunning= */ false));
verify(mAppMenuPropertiesDelegate, never()).getInstanceCount();
}
@Test
public void testReadAloudMenuItem_readAloudNotEnabled() {
mReadAloudControllerSupplier.set(null);
when(mTab.getUrl()).thenReturn(JUnitTestGURLs.EXAMPLE_URL);
setUpMocksForPageMenu();
Menu menu = createTestMenu();
mAppMenuPropertiesDelegate.prepareMenu(menu, null);
assertFalse(menu.findItem(R.id.readaloud_menu_id).isVisible());
}
@Test
public void testReadAloudMenuItem_notReadable() {
when(mTab.getUrl()).thenReturn(JUnitTestGURLs.EXAMPLE_URL);
when(mReadAloudController.isReadable(any())).thenReturn(false);
setUpMocksForPageMenu();
Menu menu = createTestMenu();
mAppMenuPropertiesDelegate.prepareMenu(menu, null);
assertFalse(menu.findItem(R.id.readaloud_menu_id).isVisible());
}
@Test
public void testReadAloudMenuItem_readable() {
when(mTab.getUrl()).thenReturn(JUnitTestGURLs.EXAMPLE_URL);
when(mReadAloudController.isReadable(any())).thenReturn(true);
setUpMocksForPageMenu();
Menu menu = createTestMenu();
mAppMenuPropertiesDelegate.prepareMenu(menu, null);
assertTrue(menu.findItem(R.id.readaloud_menu_id).isVisible());
}
@Test
public void testReadaloudMenuItem_readableBecomesUnreadable() {
testReadAloudMenuItemUpdates(/* initiallyReadable= */ true, /* laterReadable= */ false);
}
@Test
public void testReadaloudMenuItem_unreadableBecomesReadable() {
testReadAloudMenuItemUpdates(/* initiallyReadable= */ false, /* laterReadable= */ true);
}
@Test
public void testReadaloudMenuItem_noChangeInReadability_notReadable() {
testReadAloudMenuItemUpdates(/* initiallyReadable= */ false, /* laterReadable= */ false);
}
@Test
public void testReadaloudMenuItem_noChangeInReadability_readable() {
testReadAloudMenuItemUpdates(/* initiallyReadable= */ true, /* laterReadable= */ true);
}
private void testReadAloudMenuItemUpdates(boolean initiallyReadable, boolean laterReadable) {
AccessibilityState.setIsScreenReaderEnabledForTesting(false);
when(mTab.getUrl()).thenReturn(JUnitTestGURLs.EXAMPLE_URL);
when(mReadAloudController.isReadable(mTab)).thenReturn(initiallyReadable);
setUpMocksForPageMenu();
Menu menu = createTestMenu();
mAppMenuPropertiesDelegate.getMenuItemsForMenu(
menu, mCustomItemViewTypeProvider, mAppMenuHandler);
// When menu is created, the visibility should match readability state at that time
assertEquals(initiallyReadable, hasReadAloudInMenu());
when(mCustomItemViewTypeProvider.fromMenuItemId(anyInt()))
.thenReturn(CustomViewBinder.NOT_HANDLED);
when(mReadAloudController.isReadable(mTab)).thenReturn(laterReadable);
// When a new readability result is retrieved, ensure that the menu item visibility matches
// the current readability state.
mAppMenuPropertiesDelegate.getReadAloudmenuResetter().run();
assertEquals(laterReadable, hasReadAloudInMenu());
}
private boolean hasReadAloudInMenu() {
ModelList modelList = mAppMenuPropertiesDelegate.getModelList();
if (modelList == null) {
return false;
}
Iterator<ListItem> it = modelList.iterator();
while (it.hasNext()) {
ListItem li = it.next();
int id = li.model.get(AppMenuItemProperties.MENU_ITEM_ID);
if (id == R.id.readaloud_menu_id) {
return true;
}
}
return false;
}
private boolean doTestShouldShowNewMenu(
boolean isAutomotive,
boolean isInstanceSwitcherEnabled,
int currentWindowInstances,
boolean isTabletSizeScreen,
boolean canEnterMultiWindowMode,
boolean isChromeRunningInAdjacentWindow,
boolean isInMultiWindowMode,
boolean isInMultiDisplayMode,
boolean isMultiInstanceRunning) {
mShadowPackageManager.setSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, isAutomotive);
doReturn(isInstanceSwitcherEnabled)
.when(mAppMenuPropertiesDelegate)
.instanceSwitcherWithMultiInstanceEnabled();
doReturn(currentWindowInstances).when(mAppMenuPropertiesDelegate).getInstanceCount();
doReturn(isTabletSizeScreen).when(mAppMenuPropertiesDelegate).isTabletSizeScreen();
doReturn(canEnterMultiWindowMode)
.when(mMultiWindowModeStateDispatcher)
.canEnterMultiWindowMode();
doReturn(isChromeRunningInAdjacentWindow)
.when(mMultiWindowModeStateDispatcher)
.isChromeRunningInAdjacentWindow();
doReturn(isInMultiWindowMode).when(mMultiWindowModeStateDispatcher).isInMultiWindowMode();
doReturn(isInMultiDisplayMode).when(mMultiWindowModeStateDispatcher).isInMultiDisplayMode();
doReturn(isMultiInstanceRunning)
.when(mMultiWindowModeStateDispatcher)
.isMultiInstanceRunning();
return mAppMenuPropertiesDelegate.shouldShowNewWindow();
}
private boolean doTestShouldShowMoveToOtherWindowMenu(
int totalTabCount,
boolean isInstanceSwitcherEnabled,
int currentWindowInstances,
boolean isTabletSizeScreen,
boolean canEnterMultiWindowMode,
boolean isChromeRunningInAdjacentWindow,
boolean isInMultiWindowMode,
boolean isInMultiDisplayMode,
boolean isMultiInstanceRunning,
boolean isMoveToOtherWindowSupported) {
doReturn(isInstanceSwitcherEnabled)
.when(mAppMenuPropertiesDelegate)
.instanceSwitcherWithMultiInstanceEnabled();
doReturn(currentWindowInstances).when(mAppMenuPropertiesDelegate).getInstanceCount();
doReturn(isTabletSizeScreen).when(mAppMenuPropertiesDelegate).isTabletSizeScreen();
doReturn(canEnterMultiWindowMode)
.when(mMultiWindowModeStateDispatcher)
.canEnterMultiWindowMode();
doReturn(isChromeRunningInAdjacentWindow)
.when(mMultiWindowModeStateDispatcher)
.isChromeRunningInAdjacentWindow();
doReturn(isInMultiWindowMode).when(mMultiWindowModeStateDispatcher).isInMultiWindowMode();
doReturn(isInMultiDisplayMode).when(mMultiWindowModeStateDispatcher).isInMultiDisplayMode();
doReturn(isMultiInstanceRunning)
.when(mMultiWindowModeStateDispatcher)
.isMultiInstanceRunning();
doReturn(isMoveToOtherWindowSupported)
.when(mMultiWindowModeStateDispatcher)
.isMoveToOtherWindowSupported(any());
return mAppMenuPropertiesDelegate.shouldShowMoveToOtherWindow();
}
private void setUpMocksForPageMenu() {
when(mActivityTabProvider.get()).thenReturn(mTab);
when(mLayoutStateProvider.isLayoutVisible(LayoutType.TAB_SWITCHER)).thenReturn(false);
doReturn(false).when(mAppMenuPropertiesDelegate).shouldCheckBookmarkStar(any(Tab.class));
doReturn(false).when(mAppMenuPropertiesDelegate).shouldEnableDownloadPage(any(Tab.class));
doReturn(false).when(mAppMenuPropertiesDelegate).shouldShowReaderModePrefs(any(Tab.class));
doReturn(false)
.when(mAppMenuPropertiesDelegate)
.shouldShowManagedByMenuItem(any(Tab.class));
doReturn(true).when(mAppMenuPropertiesDelegate).isAutoDarkWebContentsEnabled();
setUpIncognitoMocks();
}
private void setUpMocksForOverviewMenu(@LayoutType int layoutType) {
when(mLayoutStateProvider.isLayoutVisible(layoutType)).thenReturn(true);
when(mTabModelSelector.getTotalTabCount()).thenReturn(1);
setUpIncognitoMocks();
}
private void setUpIncognitoMocks() {
doReturn(true).when(mAppMenuPropertiesDelegate).isIncognitoEnabled();
doReturn(false).when(mIncognitoReauthControllerMock).isIncognitoReauthPending();
doReturn(false).when(mIncognitoReauthControllerMock).isReauthPageShowing();
}
private Menu createTestMenu() {
PopupMenu tempMenu = new PopupMenu(ContextUtils.getApplicationContext(), mDecorView);
tempMenu.inflate(mAppMenuPropertiesDelegate.getAppMenuLayoutId());
Menu menu = tempMenu.getMenu();
return menu;
}
private void assertMenuItemsAreEqual(Menu menu, Integer... expectedItems) {
List<Integer> actualItems = new ArrayList<>();
for (int i = 0; i < menu.size(); i++) {
if (menu.getItem(i).isVisible()) {
actualItems.add(menu.getItem(i).getItemId());
}
}
assertThat(
"Populated menu items were:" + getMenuTitles(menu),
actualItems,
Matchers.containsInAnyOrder(expectedItems));
}
private void assertMenuTitlesAreEqual(Menu menu, Integer... expectedTitles) {
Context context = ContextUtils.getApplicationContext();
int expectedIndex = 0;
for (int i = 0; i < menu.size(); i++) {
if (menu.getItem(i).isVisible()) {
Assert.assertEquals(
expectedTitles[expectedIndex] == 0
? null
: context.getString(expectedTitles[expectedIndex]),
menu.getItem(i).getTitle());
expectedIndex++;
}
}
}
private void assertActionBarItemsAreEqual(Menu menu, Integer... expectedItems) {
SubMenu actionBar = menu.findItem(R.id.icon_row_menu_id).getSubMenu();
List<Integer> actualItems = new ArrayList<>();
for (int i = 0; i < actionBar.size(); i++) {
if (actionBar.getItem(i).isVisible()) {
actualItems.add(actionBar.getItem(i).getItemId());
}
}
assertThat(
"Populated action bar items were:" + getMenuTitles(actionBar),
actualItems,
Matchers.containsInAnyOrder(expectedItems));
}
private void assertMenuItemsHaveIcons(Menu menu, Integer... expectedItems) {
List<Integer> actualItems = new ArrayList<>();
for (int i = 0; i < menu.size(); i++) {
if (menu.getItem(i).isVisible() && menu.getItem(i).getIcon() != null) {
actualItems.add(menu.getItem(i).getItemId());
}
}
assertThat(
"menu items with icons were:" + getMenuTitles(menu),
actualItems,
Matchers.containsInAnyOrder(expectedItems));
}
private String getMenuTitles(Menu menu) {
StringBuilder items = new StringBuilder();
for (int i = 0; i < menu.size(); i++) {
if (menu.getItem(i).isVisible()) {
items.append("\n").append(menu.getItem(i).getTitle());
}
}
return items.toString();
}
/** Options for tests that control how Menu is being rendered. */
private static class MenuOptions {
private boolean mIsNativePage;
private boolean mShowTranslate;
private boolean mShowUpdate;
private boolean mShowMoveToOtherWindow;
private boolean mShowReaderModePrefs;
private boolean mShowAddToHomeScreen;
private boolean mShowPaintPreview;
private boolean mIsAutoDarkEnabled;
protected boolean isNativePage() {
return mIsNativePage;
}
protected boolean showTranslate() {
return mShowTranslate;
}
protected boolean showUpdate() {
return mShowUpdate;
}
protected boolean showMoveToOtherWindow() {
return mShowMoveToOtherWindow;
}
protected boolean showReaderModePrefs() {
return mShowReaderModePrefs;
}
protected boolean showAddToHomeScreen() {
return mShowAddToHomeScreen;
}
protected boolean showPaintPreview() {
return mShowPaintPreview;
}
protected boolean isAutoDarkEnabled() {
return mIsAutoDarkEnabled;
}
protected MenuOptions setNativePage(boolean state) {
mIsNativePage = state;
return this;
}
protected MenuOptions setShowTranslate(boolean state) {
mShowTranslate = state;
return this;
}
protected MenuOptions setShowUpdate(boolean state) {
mShowUpdate = state;
return this;
}
protected MenuOptions setShowMoveToOtherWindow(boolean state) {
mShowMoveToOtherWindow = state;
return this;
}
protected MenuOptions setShowReaderModePrefs(boolean state) {
mShowReaderModePrefs = state;
return this;
}
protected MenuOptions setShowAddToHomeScreen(boolean state) {
mShowAddToHomeScreen = state;
return this;
}
protected MenuOptions setShowPaintPreview(boolean state) {
mShowPaintPreview = state;
return this;
}
protected MenuOptions setAutoDarkEnabled(boolean state) {
mIsAutoDarkEnabled = state;
return this;
}
protected MenuOptions withNativePage() {
return setNativePage(true);
}
protected MenuOptions withShowTranslate() {
return setShowTranslate(true);
}
protected MenuOptions withShowUpdate() {
return setShowUpdate(true);
}
protected MenuOptions withShowMoveToOtherWindow() {
return setShowMoveToOtherWindow(true);
}
protected MenuOptions withShowReaderModePrefs() {
return setShowReaderModePrefs(true);
}
protected MenuOptions withShowAddToHomeScreen() {
return setShowAddToHomeScreen(true);
}
protected MenuOptions withShowPaintPreview() {
return setShowPaintPreview(true);
}
protected MenuOptions withAutoDarkEnabled() {
return setAutoDarkEnabled(true);
}
protected MenuOptions withAllSet() {
return this.withNativePage()
.withShowTranslate()
.withShowUpdate()
.withShowReaderModePrefs()
.withShowAddToHomeScreen()
.withShowPaintPreview()
.withAutoDarkEnabled();
}
}
private void setMenuOptions(MenuOptions options) {
when(mTab.getUrl()).thenReturn(JUnitTestGURLs.SEARCH_URL);
when(mTab.isNativePage()).thenReturn(options.isNativePage());
doReturn(options.showTranslate())
.when(mAppMenuPropertiesDelegate)
.shouldShowTranslateMenuItem(any(Tab.class));
doReturn(options.showUpdate()).when(mAppMenuPropertiesDelegate).shouldShowUpdateMenuItem();
doReturn(options.showMoveToOtherWindow())
.when(mAppMenuPropertiesDelegate)
.shouldShowMoveToOtherWindow();
doReturn(options.showReaderModePrefs())
.when(mAppMenuPropertiesDelegate)
.shouldShowReaderModePrefs(any(Tab.class));
doReturn(options.showPaintPreview())
.when(mAppMenuPropertiesDelegate)
.shouldShowPaintPreview(anyBoolean(), any(Tab.class), anyBoolean());
when(mWebsitePreferenceBridgeJniMock.getContentSetting(any(), anyInt(), any(), any()))
.thenReturn(
options.isAutoDarkEnabled()
? ContentSettingValues.DEFAULT
: ContentSettingValues.BLOCK);
}
private void verifyManagedByMenuItem(boolean chromeManagementPageEnabled) {}
/**
* Preparation to mock the "final" method TabModelFilter#getTabsWithNoOtherRelatedTabs which
* plays a part to enable group tabs.
*/
private void prepareMocksForGroupTabsOnTabModel(@NonNull TabModel tabmodel) {
when(mTabModelFilter.getTabModel()).thenReturn(tabmodel);
when(mTabModelFilter.getCount()).thenReturn(2);
when(tabmodel.getCount()).thenReturn(2);
Tab mockTab1 = mock(Tab.class);
Tab mockTab2 = mock(Tab.class);
when(tabmodel.getTabAt(0)).thenReturn(mockTab1);
when(tabmodel.getTabAt(1)).thenReturn(mockTab2);
}
}