blob: 3b0b968aff752e66ca1f1d1056d8edb595e0307d [file] [log] [blame]
// Copyright 2019 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.tasks.tab_management;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.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.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.res.Resources;
import android.os.Handler;
import android.view.View;
import androidx.test.filters.SmallTest;
import org.junit.After;
import org.junit.Assert;
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.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.LooperMode;
import org.robolectric.shadows.ShadowLooper;
import org.chromium.base.UserDataHost;
import org.chromium.base.supplier.LazyOneshotSupplier;
import org.chromium.base.supplier.ObservableSupplierImpl;
import org.chromium.base.supplier.OneshotSupplierImpl;
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.base.test.util.Features;
import org.chromium.base.test.util.Features.DisableFeatures;
import org.chromium.base.test.util.Features.EnableFeatures;
import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
import org.chromium.chrome.browser.compositor.CompositorViewHolder;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.incognito.reauth.IncognitoReauthController;
import org.chromium.chrome.browser.incognito.reauth.IncognitoReauthManager;
import org.chromium.chrome.browser.layouts.LayoutType;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabSelectionType;
import org.chromium.chrome.browser.tab_ui.TabContentManager;
import org.chromium.chrome.browser.tab_ui.TabSwitcher;
import org.chromium.chrome.browser.tab_ui.TabSwitcher.TabSwitcherViewObserver;
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.TabModelObserver;
import org.chromium.chrome.browser.tabmodel.TabModelSelectorImpl;
import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver;
import org.chromium.chrome.browser.tasks.tab_management.TabListEditorCoordinator.TabListEditorController;
import org.chromium.chrome.tab_ui.R;
import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel;
import org.chromium.ui.modelutil.PropertyObservable;
import org.chromium.url.GURL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/** Tests for {@link TabSwitcherMediator}. */
@SuppressWarnings({"ResultOfMethodCallIgnored", "ArraysAsListWithZeroOrOneArgument", "unchecked"})
@RunWith(BaseRobolectricTestRunner.class)
@Config(manifest = Config.NONE)
@LooperMode(LooperMode.Mode.LEGACY)
@DisableFeatures({ChromeFeatureList.START_SURFACE_ANDROID})
@EnableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
public class TabSwitcherMediatorUnitTest {
@Rule public TestRule mProcessor = new Features.JUnitProcessor();
private static final int CONTROL_HEIGHT_DEFAULT = 56;
private static final int CONTROL_HEIGHT_MODIFIED = 0;
private static final int CONTROL_HEIGHT_INCREASED = 76;
private static final String TAB1_TITLE = "Tab1";
private static final String TAB2_TITLE = "Tab2";
private static final String TAB3_TITLE = "Tab3";
private static final String TAB4_TITLE = "Tab4";
private static final int TAB1_ID = 456;
private static final int TAB2_ID = 789;
private static final int TAB3_ID = 123;
private static final int TAB4_ID = 357;
private static final int TAB_MODEL_FILTER_INDEX = 2;
private final OneshotSupplierImpl<IncognitoReauthController>
mIncognitoReauthControllerSupplier = new OneshotSupplierImpl<>();
private LazyOneshotSupplier<TabGridDialogMediator.DialogController>
mTabGridDialogControllerSupplier;
@Mock private TabSwitcherResetHandler mResetHandler;
@Mock private Runnable mTabSwitcherVisibilityDelegate;
@Mock private TabContentManager mTabContentManager;
@Mock private TabModelSelectorImpl mTabModelSelector;
@Mock private TabModel mTabModel;
@Mock private TabModelFilter mTabModelFilter;
@Mock private TabModelFilterProvider mTabModelFilterProvider;
@Mock private Context mContext;
@Mock private Resources mResources;
@Mock private BrowserControlsStateProvider mBrowserControlsStateProvider;
@Mock private PropertyObservable.PropertyObserver<PropertyKey> mPropertyObserver;
@Mock private TabSwitcherViewObserver mTabSwitcherViewObserver;
@Mock private CompositorViewHolder mCompositorViewHolder;
@Mock private TabSwitcher.OnTabSelectingListener mOnTabSelectingListener;
@Mock private TabGridDialogMediator.DialogController mTabGridDialogController;
@Mock private PriceMessageService mPriceMessageService;
@Mock private IncognitoReauthController mIncognitoReauthController;
@Mock private View mCustomViewMock;
@Mock private TabListEditorController mEditorController;
@Captor private ArgumentCaptor<TabModelObserver> mTabModelObserverCaptor;
@Captor private ArgumentCaptor<TabModelSelectorObserver> mTabModelSelectorObserverCaptor;
@Captor
private ArgumentCaptor<BrowserControlsStateProvider.Observer>
mBrowserControlsStateProviderObserverCaptor;
@Captor
private ArgumentCaptor<IncognitoReauthManager.IncognitoReauthCallback>
mIncognitoReauthCallbackArgumentCaptor;
private final ObservableSupplierImpl<Boolean> mEditorControllerBackPressChangedSupplier =
new ObservableSupplierImpl<>();
private final ObservableSupplierImpl<TabListEditorController> mEditorControllerSupplier =
new ObservableSupplierImpl<>();
private Tab mTab1;
private Tab mTab2;
private Tab mTab3;
private TabSwitcherMediator mMediator;
private PropertyModel mModel;
private Handler mHandler;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mHandler = spy(new Handler());
mTab1 = prepareTab(TAB1_ID, TAB1_TITLE);
mTab2 = prepareTab(TAB2_ID, TAB2_TITLE);
mTab3 = prepareTab(TAB3_ID, TAB3_TITLE);
List<TabModel> tabModelList = new ArrayList<>();
tabModelList.add(mTabModel);
doNothing()
.when(mTabContentManager)
.getTabThumbnailWithCallback(anyInt(), any(), any(), anyBoolean(), anyBoolean());
doReturn(mResources).when(mContext).getResources();
doReturn(mTabModel).when(mTabModelSelector).getCurrentModel();
doReturn(tabModelList).when(mTabModelSelector).getModels();
doNothing().when(mTabModelSelector).addObserver(mTabModelSelectorObserverCaptor.capture());
doReturn(mTabModelFilterProvider).when(mTabModelSelector).getTabModelFilterProvider();
doReturn(mTabModelFilter).when(mTabModelFilterProvider).getCurrentTabModelFilter();
doNothing()
.when(mTabModelFilterProvider)
.addTabModelFilterObserver(mTabModelObserverCaptor.capture());
doReturn(mTab1).when(mTabModelFilter).getTabAt(0);
doReturn(mTab2).when(mTabModelFilter).getTabAt(1);
doReturn(mTab3).when(mTabModelFilter).getTabAt(2);
doReturn(false).when(mTabModelFilter).isIncognito();
doReturn(TAB_MODEL_FILTER_INDEX).when(mTabModelFilter).index();
doReturn(3).when(mTabModelFilter).getCount();
doReturn(2).when(mTabModel).index();
doReturn(3).when(mTabModel).getCount();
doReturn(mTab1).when(mTabModel).getTabAt(0);
doReturn(mTab2).when(mTabModel).getTabAt(1);
doReturn(mTab3).when(mTabModel).getTabAt(2);
doReturn(CONTROL_HEIGHT_DEFAULT)
.when(mBrowserControlsStateProvider)
.getBottomControlsHeight();
doReturn(CONTROL_HEIGHT_DEFAULT).when(mBrowserControlsStateProvider).getTopControlsHeight();
doReturn(CONTROL_HEIGHT_DEFAULT).when(mBrowserControlsStateProvider).getContentOffset();
doNothing()
.when(mBrowserControlsStateProvider)
.addObserver(mBrowserControlsStateProviderObserverCaptor.capture());
doReturn(mEditorControllerBackPressChangedSupplier)
.when(mEditorController)
.getHandleBackPressChangedSupplier();
doReturn(new ObservableSupplierImpl<Boolean>())
.when(mTabGridDialogController)
.getHandleBackPressChangedSupplier();
when(mIncognitoReauthController.isIncognitoReauthPending()).thenReturn(false);
mIncognitoReauthControllerSupplier.set(mIncognitoReauthController);
mTabGridDialogControllerSupplier = LazyOneshotSupplier.fromValue(mTabGridDialogController);
mTabGridDialogControllerSupplier.get();
mModel = new PropertyModel(TabListContainerProperties.ALL_KEYS);
mModel.addObserver(mPropertyObserver);
mMediator =
new TabSwitcherMediator(
mContext,
mResetHandler,
mModel,
mTabModelSelector,
mBrowserControlsStateProvider,
mCompositorViewHolder,
mHandler,
TabListCoordinator.TabListMode.GRID,
mIncognitoReauthControllerSupplier,
null,
mTabGridDialogControllerSupplier,
mTabSwitcherVisibilityDelegate,
null);
mMediator.initWithNative(null);
mEditorControllerSupplier.set(mEditorController);
mMediator.setTabListEditorControllerSupplier(mEditorControllerSupplier);
mMediator.addTabSwitcherViewObserver(mTabSwitcherViewObserver);
mMediator.setOnTabSelectingListener(mOnTabSelectingListener);
verify(mIncognitoReauthController, times(1))
.addIncognitoReauthCallback(mIncognitoReauthCallbackArgumentCaptor.capture());
assertTrue(mEditorControllerSupplier.hasObservers());
assertTrue(mEditorControllerBackPressChangedSupplier.hasObservers());
}
@After
public void tearDown() {
mMediator.destroy();
assertFalse(mEditorControllerSupplier.hasObservers());
assertFalse(mEditorControllerBackPressChangedSupplier.hasObservers());
}
@Test
public void initializesWithCurrentModelOnCreation() {
initAndAssertAllProperties();
}
@Test
public void showsWithAnimation() {
initAndAssertAllProperties();
mMediator.showTabSwitcherView(true);
assertThat(
mModel.get(TabListContainerProperties.ANIMATE_VISIBILITY_CHANGES), equalTo(true));
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(true));
}
@Test
public void showsWithoutAnimation() {
doReturn(true).when(mTabModelSelector).isTabStateInitialized();
initAndAssertAllProperties();
mMediator.showTabSwitcherView(false);
InOrder inOrder = inOrder(mPropertyObserver, mPropertyObserver);
inOrder.verify(mPropertyObserver)
.onPropertyChanged(mModel, TabListContainerProperties.ANIMATE_VISIBILITY_CHANGES);
inOrder.verify(mPropertyObserver)
.onPropertyChanged(mModel, TabListContainerProperties.IS_VISIBLE);
inOrder.verify(mPropertyObserver)
.onPropertyChanged(mModel, TabListContainerProperties.ANIMATE_VISIBILITY_CHANGES);
assertThat(
mModel.get(TabListContainerProperties.ANIMATE_VISIBILITY_CHANGES), equalTo(true));
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(true));
}
@Test
public void showsWithoutAnimation_withTabGroups() {
doReturn(2).when(mTabModelFilter).getCount();
doReturn(true).when(mTabModelSelector).isTabStateInitialized();
initAndAssertAllProperties();
mMediator.showTabSwitcherView(false);
InOrder inOrder = inOrder(mPropertyObserver, mPropertyObserver);
inOrder.verify(mPropertyObserver)
.onPropertyChanged(mModel, TabListContainerProperties.ANIMATE_VISIBILITY_CHANGES);
inOrder.verify(mPropertyObserver)
.onPropertyChanged(mModel, TabListContainerProperties.IS_VISIBLE);
inOrder.verify(mPropertyObserver)
.onPropertyChanged(mModel, TabListContainerProperties.ANIMATE_VISIBILITY_CHANGES);
assertThat(
mModel.get(TabListContainerProperties.ANIMATE_VISIBILITY_CHANGES), equalTo(true));
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(true));
}
@Test
public void hidesWithAnimation() {
initAndAssertAllProperties();
mMediator.showTabSwitcherView(true);
assertThat(
mModel.get(TabListContainerProperties.ANIMATE_VISIBILITY_CHANGES), equalTo(true));
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(true));
mMediator.hideTabSwitcherView(true);
assertThat(
mModel.get(TabListContainerProperties.ANIMATE_VISIBILITY_CHANGES), equalTo(true));
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(false));
verify(mTabGridDialogController).hideDialog(eq(false));
}
@Test
public void hidesWithoutAnimation() {
initAndAssertAllProperties();
mMediator.showTabSwitcherView(true);
assertThat(
mModel.get(TabListContainerProperties.ANIMATE_VISIBILITY_CHANGES), equalTo(true));
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(true));
mMediator.hideTabSwitcherView(false);
InOrder inOrder = inOrder(mPropertyObserver, mPropertyObserver);
inOrder.verify(mPropertyObserver)
.onPropertyChanged(mModel, TabListContainerProperties.ANIMATE_VISIBILITY_CHANGES);
inOrder.verify(mPropertyObserver)
.onPropertyChanged(mModel, TabListContainerProperties.IS_VISIBLE);
inOrder.verify(mPropertyObserver)
.onPropertyChanged(mModel, TabListContainerProperties.ANIMATE_VISIBILITY_CHANGES);
assertThat(
mModel.get(TabListContainerProperties.ANIMATE_VISIBILITY_CHANGES), equalTo(true));
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(false));
verify(mTabGridDialogController).hideDialog(eq(false));
}
@Test
public void beforeHideTabSwitcherView_WithController() {
mMediator.prepareHideTabSwitcherView();
verify(mTabGridDialogController).hideDialog(eq(false));
}
@Test
public void startedShowingPropagatesToObservers() {
initAndAssertAllProperties();
mModel.get(TabListContainerProperties.VISIBILITY_LISTENER).startedShowing(true);
verify(mTabSwitcherViewObserver).startedShowing();
}
@Test
public void finishedShowingPropagatesToObservers() {
initAndAssertAllProperties();
mModel.get(TabListContainerProperties.VISIBILITY_LISTENER).finishedShowing();
verify(mTabSwitcherViewObserver).finishedShowing();
}
@Test
public void startedHidingPropagatesToObservers() {
initAndAssertAllProperties();
mModel.get(TabListContainerProperties.VISIBILITY_LISTENER).startedHiding(true);
verify(mTabSwitcherViewObserver).startedHiding();
}
@Test
public void finishedHidingPropagatesToObservers() {
initAndAssertAllProperties();
mModel.get(TabListContainerProperties.VISIBILITY_LISTENER).finishedHiding();
verify(mTabSwitcherViewObserver).finishedHiding();
}
@Test
public void resetsToNullAfterHidingFinishes() {
initAndAssertAllProperties();
reset(mHandler);
mMediator.postHiding();
verify(mHandler).postDelayed(eq(mMediator.mSoftClearTabListRunnable), eq(3_000L));
verify(mHandler).postDelayed(eq(mMediator.mClearTabListRunnable), eq(30_000L));
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
verify(mResetHandler).softCleanup();
verify(mResetHandler).resetWithTabList(eq(null), eq(false));
}
@Test
public void resetsAfterNewTabModelSelected() {
initAndAssertAllProperties();
mModel.set(TabListContainerProperties.IS_VISIBLE, true);
doReturn(true).when(mTabModelFilter).isIncognito();
mTabModelSelectorObserverCaptor.getValue().onTabModelSelected(mTabModel, null);
verify(mResetHandler).resetWithTabList(eq(mTabModelFilter), eq(false));
verify(mTabGridDialogController).hideDialog(eq(false));
assertThat(mModel.get(TabListContainerProperties.IS_INCOGNITO), equalTo(true));
// Switching TabModels by itself shouldn't cause visibility changes.
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(true));
}
@Test
public void noResetsAfterNewTabModelSelected_InvisibleGTS() {
initAndAssertAllProperties();
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(false));
doReturn(true).when(mTabModelFilter).isIncognito();
mTabModelSelectorObserverCaptor.getValue().onTabModelSelected(mTabModel, null);
verify(mResetHandler, never()).resetWithTabList(any(), anyBoolean());
verify(mTabGridDialogController).hideDialog(eq(false));
assertThat(mModel.get(TabListContainerProperties.IS_INCOGNITO), equalTo(true));
// Switching TabModels by itself shouldn't cause visibility changes.
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(false));
}
@Test
public void scrollAfterNewTabModelSelected() {
initAndAssertAllProperties();
mModel.set(TabListContainerProperties.IS_VISIBLE, true);
TabModel incognitoTabModel = mock(TabModel.class);
doReturn(0).when(mTabModelFilter).index();
mTabModelSelectorObserverCaptor.getValue().onTabModelSelected(incognitoTabModel, mTabModel);
assertThat(mModel.get(TabListContainerProperties.INITIAL_SCROLL_INDEX), equalTo(0));
doReturn(1).when(mTabModelFilter).index();
mTabModelSelectorObserverCaptor.getValue().onTabModelSelected(incognitoTabModel, mTabModel);
assertThat(mModel.get(TabListContainerProperties.INITIAL_SCROLL_INDEX), equalTo(1));
doReturn(2).when(mTabModelFilter).index();
mTabModelSelectorObserverCaptor.getValue().onTabModelSelected(incognitoTabModel, mTabModel);
assertThat(mModel.get(TabListContainerProperties.INITIAL_SCROLL_INDEX), equalTo(2));
doReturn(3).when(mTabModelFilter).index();
mTabModelSelectorObserverCaptor.getValue().onTabModelSelected(incognitoTabModel, mTabModel);
assertThat(mModel.get(TabListContainerProperties.INITIAL_SCROLL_INDEX), equalTo(3));
}
@Test
public void updatesMarginWithBottomBarChanges() {
initAndAssertAllProperties();
assertThat(
mModel.get(TabListContainerProperties.BOTTOM_CONTROLS_HEIGHT),
equalTo(CONTROL_HEIGHT_DEFAULT));
mBrowserControlsStateProviderObserverCaptor
.getValue()
.onBottomControlsHeightChanged(CONTROL_HEIGHT_MODIFIED, 0);
assertThat(
mModel.get(TabListContainerProperties.BOTTOM_CONTROLS_HEIGHT),
equalTo(CONTROL_HEIGHT_MODIFIED));
}
@Test
public void hidesWhenATabIsSelected() {
initAndAssertAllProperties();
mMediator.showTabSwitcherView(true);
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(true));
doReturn(true).when(mTabModelSelector).isTabStateInitialized();
mTabModelObserverCaptor.getValue().didSelectTab(mTab1, TabSelectionType.FROM_USER, TAB3_ID);
verify(mOnTabSelectingListener).onTabSelecting(eq(TAB1_ID));
}
@Test
public void doesNotHideWhenSelectedTabChangedDueToTabClosure() {
doReturn(true).when(mTabModelSelector).isTabStateInitialized();
initAndAssertAllProperties();
mMediator.showTabSwitcherView(true);
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(true));
doReturn(true).when(mTab3).isClosing();
mTabModelObserverCaptor
.getValue()
.didSelectTab(mTab1, TabSelectionType.FROM_CLOSE, TAB3_ID);
verify(mOnTabSelectingListener, never()).onTabSelecting(anyInt());
mTabModelObserverCaptor.getValue().didSelectTab(mTab1, TabSelectionType.FROM_USER, TAB3_ID);
verify(mOnTabSelectingListener).onTabSelecting(eq(TAB1_ID));
}
@Test
public void doesNotHideWhenSelectedTabChangedDueToUndoTabClosure() {
doReturn(true).when(mTabModelSelector).isTabStateInitialized();
initAndAssertAllProperties();
mMediator.showTabSwitcherView(true);
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(true));
doReturn(true).when(mTab3).isClosing();
mTabModelObserverCaptor.getValue().didSelectTab(mTab1, TabSelectionType.FROM_UNDO, TAB3_ID);
verify(mOnTabSelectingListener, never()).onTabSelecting(anyInt());
mTabModelObserverCaptor.getValue().didSelectTab(mTab1, TabSelectionType.FROM_USER, TAB3_ID);
verify(mOnTabSelectingListener).onTabSelecting(eq(TAB1_ID));
}
@Test
public void doesNotHideWhenSelectedTabChangedDueToModelChange() {
doReturn(true).when(mTabModelSelector).isTabStateInitialized();
initAndAssertAllProperties();
mMediator.showTabSwitcherView(true);
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(true));
mTabModelSelectorObserverCaptor.getValue().onTabModelSelected(mTabModel, null);
mTabModelObserverCaptor.getValue().didSelectTab(mTab1, TabSelectionType.FROM_USER, TAB3_ID);
verify(mOnTabSelectingListener, never()).onTabSelecting(anyInt());
mTabModelObserverCaptor.getValue().didSelectTab(mTab1, TabSelectionType.FROM_USER, TAB3_ID);
verify(mOnTabSelectingListener).onTabSelecting(eq(TAB1_ID));
}
@Test
public void updatesResetHandlerOnRestoreCompleted() {
initAndAssertAllProperties();
mMediator.showTabSwitcherView(true);
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(true));
mTabModelObserverCaptor.getValue().restoreCompleted();
// MRU will be false unless the start surface is enabled.
verify(mResetHandler).resetWithTabList(mTabModelFilter, false);
}
@Test
public void setInitialScrollIndexOnRestoreCompleted() {
initAndAssertAllProperties();
mMediator.showTabSwitcherView(true);
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(true));
// Set to an "invalid" value and ensure it gets changed.
mModel.set(TabListContainerProperties.INITIAL_SCROLL_INDEX, 1337);
mTabModelObserverCaptor.getValue().restoreCompleted();
assertThat(mModel.get(TabListContainerProperties.INITIAL_SCROLL_INDEX), equalTo(2));
}
@Test
public void testScrollToTab() {
initAndAssertAllProperties();
mMediator.scrollToTab(0);
assertThat(mModel.get(TabListContainerProperties.INITIAL_SCROLL_INDEX), equalTo(0));
mMediator.scrollToTab(1);
assertThat(mModel.get(TabListContainerProperties.INITIAL_SCROLL_INDEX), equalTo(1));
}
@Test
public void showOverviewDoesNotUpdateResetHandlerBeforeRestoreCompleted() {
initAndAssertAllProperties();
doReturn(false).when(mTabModelSelector).isTabStateInitialized();
mMediator.showTabSwitcherView(true);
// MRU will be false unless the start surface is enabled.
verify(mResetHandler, never()).resetWithTabList(mTabModelFilter, true);
}
@Test
public void prepareOverviewDoesNotUpdateResetHandlerBeforeRestoreCompleted() {
initAndAssertAllProperties();
doReturn(false).when(mTabModelSelector).isTabStateInitialized();
mMediator.prepareTabSwitcherView();
// MRU will be false unless the start surface is enabled.
verify(mResetHandler, never()).resetWithTabList(mTabModelFilter, false);
}
@Test
public void showOverviewUpdatesResetHandlerAfterRestoreCompleted() {
initAndAssertAllProperties();
doReturn(true).when(mTabModelSelector).isTabStateInitialized();
mMediator.showTabSwitcherView(true);
// MRU will be false unless the start surface is enabled.
verify(mResetHandler).resetWithTabList(mTabModelFilter, true);
}
@Test
public void prepareOverviewUpdatesResetHandlerAfterRestoreCompleted() {
initAndAssertAllProperties();
doReturn(true).when(mTabModelSelector).isTabStateInitialized();
mMediator.prepareTabSwitcherView();
// MRU will be false unless the start surface is enabled.
verify(mResetHandler).resetWithTabList(mTabModelFilter, false);
}
@Test
public void prepareOverviewSetsInitialScrollIndexAfterRestoreCompleted() {
initAndAssertAllProperties();
doReturn(true).when(mTabModelSelector).isTabStateInitialized();
// Set to an "invalid" value and ensure it gets changed.
mModel.set(TabListContainerProperties.INITIAL_SCROLL_INDEX, 1337);
mMediator.prepareTabSwitcherView();
assertThat(mModel.get(TabListContainerProperties.INITIAL_SCROLL_INDEX), equalTo(2));
}
@Test
public void openDialogButton_SingleTab() {
// Mock that tab 1 is a single tab.
doReturn(new ArrayList<>(Arrays.asList(mTab1)))
.when(mTabModelFilter)
.getRelatedTabList(TAB1_ID);
assertThat(mMediator.openTabGridDialog(mTab1), equalTo(null));
}
@Test
public void openDialogButton_SingleTab_IsTabGroup() {
// Mock that tab 1 is a single tab.
List<Tab> tabs = new ArrayList<>(Arrays.asList(mTab1));
doReturn(tabs).when(mTabModelFilter).getRelatedTabList(TAB1_ID);
doReturn(true).when(mTabModelFilter).isTabInTabGroup(mTab1);
TabListMediator.TabActionListener listener = mMediator.openTabGridDialog(mTab1);
assertThat(listener, notNullValue());
listener.run(TAB1_ID);
verify(mTabGridDialogController).resetWithListOfTabs(eq(tabs));
}
@Test
public void openDialogButton_TabGroup_NotEmpty() {
// Set up a tab group.
Tab newTab = prepareTab(TAB4_ID, TAB4_TITLE);
List<Tab> tabs = new ArrayList<>(Arrays.asList(mTab1, newTab));
doReturn(tabs).when(mTabModelFilter).getRelatedTabList(TAB1_ID);
doReturn(true).when(mTabModelFilter).isTabInTabGroup(mTab1);
TabListMediator.TabActionListener listener = mMediator.openTabGridDialog(mTab1);
assertThat(listener, notNullValue());
listener.run(TAB1_ID);
verify(mTabGridDialogController).resetWithListOfTabs(eq(tabs));
}
@Test
public void openDialogButton_TabGroup_Empty() {
// Assume that due to tab model change, current group becomes empty in current model, but
// was already open.
doReturn(new ArrayList<>()).when(mTabModelFilter).getRelatedTabList(TAB1_ID);
doReturn(true).when(mTabModelFilter).isTabInTabGroup(mTab1);
TabListMediator.TabActionListener listener = mMediator.openTabGridDialog(mTab1);
assertThat(listener, notNullValue());
listener.run(TAB1_ID);
verify(mTabGridDialogController).resetWithListOfTabs(eq(null));
}
@Test
public void updatesPropertiesWithTopControlsChanges() {
assertEquals(
"Wrong initial top margin.",
CONTROL_HEIGHT_DEFAULT,
mModel.get(TabListContainerProperties.TOP_MARGIN));
assertEquals(
"Wrong initial shadow top offset",
CONTROL_HEIGHT_DEFAULT,
mModel.get(TabListContainerProperties.SHADOW_TOP_OFFSET));
// Change top controls height without animation.
doReturn(CONTROL_HEIGHT_INCREASED)
.when(mBrowserControlsStateProvider)
.getTopControlsHeight();
doReturn(CONTROL_HEIGHT_INCREASED).when(mBrowserControlsStateProvider).getContentOffset();
mBrowserControlsStateProviderObserverCaptor
.getValue()
.onTopControlsHeightChanged(CONTROL_HEIGHT_INCREASED, 0);
mBrowserControlsStateProviderObserverCaptor
.getValue()
.onControlsOffsetChanged(0, 0, 0, 0, false);
assertEquals(
"Top margin should be equal to top controls height if controls are fully shown.",
CONTROL_HEIGHT_INCREASED,
mModel.get(TabListContainerProperties.TOP_MARGIN));
assertEquals(
"Shadow offset should follow the content offset.",
CONTROL_HEIGHT_INCREASED,
mModel.get(TabListContainerProperties.SHADOW_TOP_OFFSET));
// Change top controls height without animation.
doReturn(CONTROL_HEIGHT_DEFAULT).when(mBrowserControlsStateProvider).getTopControlsHeight();
doReturn(CONTROL_HEIGHT_DEFAULT).when(mBrowserControlsStateProvider).getContentOffset();
mBrowserControlsStateProviderObserverCaptor
.getValue()
.onTopControlsHeightChanged(CONTROL_HEIGHT_DEFAULT, 0);
mBrowserControlsStateProviderObserverCaptor
.getValue()
.onControlsOffsetChanged(0, 0, 0, 0, false);
assertEquals(
"Top margin should be equal to top controls height if controls are at rest.",
CONTROL_HEIGHT_DEFAULT,
mModel.get(TabListContainerProperties.TOP_MARGIN));
assertEquals(
"Shadow offset should follow the content offset.",
CONTROL_HEIGHT_DEFAULT,
mModel.get(TabListContainerProperties.SHADOW_TOP_OFFSET));
}
@Test
public void testTopControlsHeightAnimations() {
assertEquals(
"Wrong initial top margin.",
CONTROL_HEIGHT_DEFAULT,
mModel.get(TabListContainerProperties.TOP_MARGIN));
assertEquals(
"Wrong initial shadow top offset",
CONTROL_HEIGHT_DEFAULT,
mModel.get(TabListContainerProperties.SHADOW_TOP_OFFSET));
// Increase the height.
doReturn(CONTROL_HEIGHT_INCREASED)
.when(mBrowserControlsStateProvider)
.getTopControlsHeight();
mBrowserControlsStateProviderObserverCaptor
.getValue()
.onTopControlsHeightChanged(CONTROL_HEIGHT_INCREASED, 20);
assertEquals(
"Top margin shouldn't change until the animation starts.",
CONTROL_HEIGHT_DEFAULT,
mModel.get(TabListContainerProperties.TOP_MARGIN));
assertEquals(
"Shadow offset should follow the content offset.",
CONTROL_HEIGHT_DEFAULT,
mModel.get(TabListContainerProperties.SHADOW_TOP_OFFSET));
// Animate by changing the content offset.
for (int offset = CONTROL_HEIGHT_DEFAULT; offset < CONTROL_HEIGHT_INCREASED; offset += 5) {
doReturn(offset).when(mBrowserControlsStateProvider).getContentOffset();
mBrowserControlsStateProviderObserverCaptor
.getValue()
.onControlsOffsetChanged(
offset - CONTROL_HEIGHT_INCREASED,
offset - CONTROL_HEIGHT_DEFAULT,
0,
0,
false);
assertEquals(
"Top margin should follow the content offset during the animation.",
offset,
mModel.get(TabListContainerProperties.TOP_MARGIN));
assertEquals(
"Shadow offset should follow the content offset.",
offset,
mModel.get(TabListContainerProperties.SHADOW_TOP_OFFSET));
}
// End the animation.
doReturn(CONTROL_HEIGHT_INCREASED).when(mBrowserControlsStateProvider).getContentOffset();
mBrowserControlsStateProviderObserverCaptor
.getValue()
.onControlsOffsetChanged(0, 20, 0, 0, false);
assertEquals(
"Top margin should be updated to the new height when the animation ends.",
CONTROL_HEIGHT_INCREASED,
mModel.get(TabListContainerProperties.TOP_MARGIN));
assertEquals(
"Shadow offset should follow the content offset.",
CONTROL_HEIGHT_INCREASED,
mModel.get(TabListContainerProperties.SHADOW_TOP_OFFSET));
// Now decrease the height, back to the default.
doReturn(CONTROL_HEIGHT_DEFAULT).when(mBrowserControlsStateProvider).getTopControlsHeight();
mBrowserControlsStateProviderObserverCaptor
.getValue()
.onTopControlsHeightChanged(CONTROL_HEIGHT_DEFAULT, 0);
assertEquals(
"Top margin shouldn't change until the animation starts.",
CONTROL_HEIGHT_INCREASED,
mModel.get(TabListContainerProperties.TOP_MARGIN));
assertEquals(
"Shadow offset should follow the content offset.",
CONTROL_HEIGHT_INCREASED,
mModel.get(TabListContainerProperties.SHADOW_TOP_OFFSET));
// Animate by changing the content offset.
for (int offset = CONTROL_HEIGHT_INCREASED; offset > CONTROL_HEIGHT_DEFAULT; offset -= 5) {
doReturn(offset).when(mBrowserControlsStateProvider).getContentOffset();
mBrowserControlsStateProviderObserverCaptor
.getValue()
.onControlsOffsetChanged(
offset - CONTROL_HEIGHT_DEFAULT,
CONTROL_HEIGHT_INCREASED - offset,
0,
0,
false);
assertEquals(
"Top margin should follow the content offset during the animation.",
offset,
mModel.get(TabListContainerProperties.TOP_MARGIN));
assertEquals(
"Shadow offset should follow the content offset.",
offset,
mModel.get(TabListContainerProperties.SHADOW_TOP_OFFSET));
}
// End the animation.
doReturn(CONTROL_HEIGHT_DEFAULT).when(mBrowserControlsStateProvider).getContentOffset();
mBrowserControlsStateProviderObserverCaptor
.getValue()
.onControlsOffsetChanged(0, 0, 0, 0, false);
assertEquals(
"Top margin should be updated to the new height at the end of the animation.",
CONTROL_HEIGHT_DEFAULT,
mModel.get(TabListContainerProperties.TOP_MARGIN));
assertEquals(
"Shadow offset should follow the content offset.",
CONTROL_HEIGHT_DEFAULT,
mModel.get(TabListContainerProperties.SHADOW_TOP_OFFSET));
}
@Test
public void updatesBottomPaddingOnlyInGridMode() {
doReturn(16f).when(mResources).getDimension(R.dimen.tab_grid_bottom_padding);
assertEquals(0, mModel.get(TabListContainerProperties.BOTTOM_PADDING));
new TabSwitcherMediator(
mContext,
mResetHandler,
mModel,
mTabModelSelector,
mBrowserControlsStateProvider,
mCompositorViewHolder,
mHandler,
TabListCoordinator.TabListMode.GRID,
mIncognitoReauthControllerSupplier,
null,
mTabGridDialogControllerSupplier,
mTabSwitcherVisibilityDelegate,
null);
assertEquals(16, mModel.get(TabListContainerProperties.BOTTOM_PADDING));
mModel.set(TabListContainerProperties.BOTTOM_PADDING, 0);
new TabSwitcherMediator(
mContext,
mResetHandler,
mModel,
mTabModelSelector,
mBrowserControlsStateProvider,
mCompositorViewHolder,
mHandler,
TabListCoordinator.TabListMode.STRIP,
mIncognitoReauthControllerSupplier,
null,
mTabGridDialogControllerSupplier,
mTabSwitcherVisibilityDelegate,
null);
assertEquals(0, mModel.get(TabListContainerProperties.BOTTOM_PADDING));
}
@Test
@EnableFeatures(ChromeFeatureList.BACK_GESTURE_REFACTOR)
public void testBackPress() {
initAndAssertAllProperties();
Assert.assertFalse(mMediator.shouldInterceptBackPress());
doReturn(true).when(mTabGridDialogController).isVisible();
Assert.assertTrue(
"Should intercept back press if tab grid dialog is visible",
mMediator.shouldInterceptBackPress());
doReturn(false).when(mTabGridDialogController).isVisible();
mMediator.showTabSwitcherView(false);
doReturn(mTab1).when(mTabModelSelector).getCurrentTab();
Assert.assertTrue(mMediator.shouldInterceptBackPress());
}
@Test
@EnableFeatures(ChromeFeatureList.BACK_GESTURE_REFACTOR)
public void testBackPressAfterSwitchIncognitoMode() {
initAndAssertAllProperties();
Assert.assertFalse(mMediator.shouldInterceptBackPress());
doReturn(false).when(mTabGridDialogController).isVisible();
mMediator.showTabSwitcherView(false);
doReturn(null).when(mTabModelSelector).getCurrentTab();
mMediator.showTabSwitcherView(true);
Assert.assertFalse(mMediator.shouldInterceptBackPress());
Assert.assertEquals(Boolean.FALSE, mMediator.getHandleBackPressChangedSupplier().get());
// Switch to incognito mode.
mModel.set(TabListContainerProperties.IS_VISIBLE, true);
doReturn(true).when(mTabModelFilter).isIncognito();
doReturn(true).when(mTabModelSelector).isIncognitoSelected();
doReturn(true).when(mTabModelSelector).isTabStateInitialized();
doReturn(false).when(mIncognitoReauthController).isIncognitoReauthPending();
doReturn(true).when(mTabModel).isIncognito();
doReturn(mTab1).when(mTabModelSelector).getCurrentTab();
mTabModelSelectorObserverCaptor.getValue().onTabModelSelected(mTabModel, null);
mMediator.showTabSwitcherView(true);
Assert.assertTrue(mMediator.shouldInterceptBackPress());
Assert.assertEquals(Boolean.TRUE, mMediator.getHandleBackPressChangedSupplier().get());
// Switch to normal mode.
mModel.set(TabListContainerProperties.IS_VISIBLE, true);
doReturn(false).when(mTabModelFilter).isIncognito();
doReturn(false).when(mTabModelSelector).isIncognitoSelected();
doReturn(true).when(mTabModelSelector).isTabStateInitialized();
doReturn(false).when(mIncognitoReauthController).isIncognitoReauthPending();
doReturn(false).when(mTabModel).isIncognito();
doReturn(null).when(mTabModelSelector).getCurrentTab();
mTabModelSelectorObserverCaptor.getValue().onTabModelSelected(mTabModel, null);
Assert.assertFalse(mMediator.shouldInterceptBackPress());
Assert.assertEquals(Boolean.FALSE, mMediator.getHandleBackPressChangedSupplier().get());
}
@Test
@EnableFeatures(ChromeFeatureList.BACK_GESTURE_REFACTOR)
public void testBackPressAfterTabClosedBySite() {
initAndAssertAllProperties();
Assert.assertFalse(mMediator.shouldInterceptBackPress());
mModel.set(TabListContainerProperties.IS_VISIBLE, true);
doReturn(false).when(mTabModelFilter).isIncognito();
doReturn(false).when(mTabModelSelector).isIncognitoSelected();
doReturn(true).when(mTabModelSelector).isTabStateInitialized();
doReturn(false).when(mIncognitoReauthController).isIncognitoReauthPending();
doReturn(true).when(mTabModel).isIncognito();
doReturn(mTab1).when(mTabModelSelector).getCurrentTab();
mTabModelSelectorObserverCaptor.getValue().onTabModelSelected(mTabModel, null);
mMediator.showTabSwitcherView(true);
Assert.assertTrue(mMediator.shouldInterceptBackPress());
Assert.assertEquals(Boolean.TRUE, mMediator.getHandleBackPressChangedSupplier().get());
// If tab is closed by the site rather than user's input, only
// onFinishingTabClosure will be triggered.
mModel.set(TabListContainerProperties.IS_VISIBLE, true);
doReturn(false).when(mTabModelFilter).isIncognito();
doReturn(false).when(mTabModelSelector).isIncognitoSelected();
doReturn(true).when(mTabModelSelector).isTabStateInitialized();
doReturn(false).when(mIncognitoReauthController).isIncognitoReauthPending();
doReturn(false).when(mTabModel).isIncognito();
doReturn(null).when(mTabModelSelector).getCurrentTab();
mTabModelObserverCaptor.getValue().onFinishingTabClosure(mTab1);
Assert.assertFalse(mMediator.shouldInterceptBackPress());
Assert.assertEquals(Boolean.FALSE, mMediator.getHandleBackPressChangedSupplier().get());
}
@Test
public void testBackPressDuringTransition() {
initAndAssertAllProperties();
Assert.assertFalse(mMediator.shouldInterceptBackPress());
mMediator.prepareShowTabSwitcherView();
Assert.assertTrue(mMediator.shouldInterceptBackPress());
Assert.assertTrue(mMediator.getHandleBackPressChangedSupplier().get());
doReturn(false).when(mTabGridDialogController).isVisible();
mMediator.showTabSwitcherView(false);
doReturn(null).when(mTabModelSelector).getCurrentTab();
mMediator.showTabSwitcherView(true);
Assert.assertFalse(mMediator.shouldInterceptBackPress());
Assert.assertFalse(mMediator.getHandleBackPressChangedSupplier().get());
}
@Test
public void testBackPressToReturnToStartSurface() {
initAndAssertAllProperties();
Assert.assertFalse(mMediator.shouldInterceptBackPress());
doReturn(false).when(mTabGridDialogController).isVisible();
doReturn(mTab1).when(mTabModelSelector).getCurrentTab();
doReturn(false).when(mTabModelSelector).isIncognitoSelected();
mMediator.showTabSwitcherView(false);
// Verifies that TabSwitcherMediator no longer handles the return to Start surface case.
mMediator.setLastActiveLayoutTypeForTesting(LayoutType.START_SURFACE);
Assert.assertFalse(mMediator.shouldInterceptBackPress());
// Verifies that TabSwitcherMediator still handles the back operation in incognito mode.
doReturn(true).when(mTabModelSelector).isIncognitoSelected();
Assert.assertTrue(mMediator.shouldInterceptBackPress());
mMediator.setLastActiveLayoutTypeForTesting(LayoutType.BROWSING);
Assert.assertTrue(mMediator.shouldInterceptBackPress());
}
@Test
public void testOnTabModelSelected_NewModelIncognito_ReauthPending_ClearsTabList() {
initAndAssertAllProperties();
mModel.set(TabListContainerProperties.IS_VISIBLE, true);
doReturn(true).when(mTabModelFilter).isIncognito();
doReturn(true).when(mTabModelSelector).isIncognitoSelected();
doReturn(true).when(mTabModelSelector).isTabStateInitialized();
doReturn(true).when(mIncognitoReauthController).isIncognitoReauthPending();
doReturn(true).when(mTabModel).isIncognito();
mTabModelSelectorObserverCaptor.getValue().onTabModelSelected(mTabModel, null);
verify(mResetHandler, times(1)).resetWithTabList(eq(null), eq(false));
}
@Test
public void testAddingCustomView_ClearsTabList_Requested_ClearsTabList() {
initAndAssertAllProperties();
mMediator.addCustomView(mCustomViewMock, null, /* clearTabList= */ true);
verify(mResetHandler, times(1)).resetWithTabList(eq(null), eq(false));
}
@Test
public void testAddingCustomView_ClearsTabList_NotRequested_DoesNotClearTabList() {
initAndAssertAllProperties();
mMediator.addCustomView(mCustomViewMock, null, /* clearTabList= */ false);
verifyNoInteractions(mResetHandler);
}
@Test
public void testRemoveCustomView_ResetTabList() {
initAndAssertAllProperties();
mMediator.addCustomView(mCustomViewMock, null, /* clearTabList= */ true);
verify(mResetHandler, times(1)).resetWithTabList(eq(null), eq(false));
mMediator.removeCustomView(mCustomViewMock);
verify(mResetHandler, times(1)).resetWithTabList(eq(mTabModelFilter), eq(false));
}
@Test
public void testOnTabModelSelected_NewModelIncognito_ReauthSuccessful_RestoresTabList() {
initAndAssertAllProperties();
mModel.set(TabListContainerProperties.IS_VISIBLE, true);
doReturn(true).when(mTabModelFilter).isIncognito();
doReturn(true).when(mTabModelSelector).isIncognitoSelected();
doReturn(true).when(mTabModelSelector).isTabStateInitialized();
doReturn(true).when(mIncognitoReauthController).isIncognitoReauthPending();
doReturn(true).when(mTabModel).isIncognito();
mTabModelSelectorObserverCaptor.getValue().onTabModelSelected(mTabModel, null);
verify(mResetHandler, times(1)).resetWithTabList(eq(null), eq(false));
// Mock that the re-auth was successful.
doReturn(false).when(mIncognitoReauthController).isIncognitoReauthPending();
mIncognitoReauthCallbackArgumentCaptor.getValue().onIncognitoReauthSuccess();
// Verify we reset the tab-list with the current tab model filter.
verify(mResetHandler, times(1)).resetWithTabList(eq(mTabModelFilter), eq(false));
// Check we don't call reset handler on other cases
mIncognitoReauthCallbackArgumentCaptor.getValue().onIncognitoReauthNotPossible();
mIncognitoReauthCallbackArgumentCaptor.getValue().onIncognitoReauthFailure();
// Verify we don't reset the tab-list with the current tab model filter again.
verifyNoMoreInteractions(mResetHandler);
}
@Test
@SmallTest
public void testFocusTabForAccessibility_IsInvoked_OnIncognitoReauthSuccess() {
initAndAssertAllProperties();
mModel.set(TabListContainerProperties.IS_VISIBLE, true);
doReturn(true).when(mTabModelFilter).isIncognito();
doReturn(true).when(mTabModelSelector).isIncognitoSelected();
doReturn(true).when(mTabModelSelector).isTabStateInitialized();
doReturn(false).when(mIncognitoReauthController).isReauthPageShowing();
doReturn(true).when(mTabModel).isIncognito();
// Mock showing overview mode.
doNothing().when(mTabSwitcherViewObserver).finishedShowing();
mMediator.finishedShowing();
// Mock that the re-auth was successful.
mIncognitoReauthCallbackArgumentCaptor.getValue().onIncognitoReauthSuccess();
assertThat(
mModel.get(TabListContainerProperties.FOCUS_TAB_INDEX_FOR_ACCESSIBILITY),
equalTo(TAB_MODEL_FILTER_INDEX));
}
@Test
@SmallTest
public void testFocusTabForAccessibility_IsInvoked_OnOverviewModeFinishedShowing() {
initAndAssertAllProperties();
doReturn(true).when(mTabModelSelector).isTabStateInitialized();
// Mock showing overview mode.
doNothing().when(mTabSwitcherViewObserver).finishedShowing();
mMediator.finishedShowing();
assertThat(
mModel.get(TabListContainerProperties.FOCUS_TAB_INDEX_FOR_ACCESSIBILITY),
equalTo(TAB_MODEL_FILTER_INDEX));
}
@Test
@SmallTest
public void testFocusTabForAccessibility_IsInvoked_OnTabModelSelected() {
initAndAssertAllProperties();
mModel.set(TabListContainerProperties.IS_VISIBLE, true);
doReturn(true).when(mTabModelSelector).isTabStateInitialized();
// Mock showing overview mode.
doNothing().when(mTabSwitcherViewObserver).finishedShowing();
mMediator.finishedShowing();
mTabModelSelectorObserverCaptor.getValue().onTabModelSelected(mTabModel, null);
assertThat(
mModel.get(TabListContainerProperties.FOCUS_TAB_INDEX_FOR_ACCESSIBILITY),
equalTo(TAB_MODEL_FILTER_INDEX));
}
@Test
@SmallTest
public void testChangeEditorController() {
mEditorControllerSupplier.set(null);
assertFalse(mEditorControllerBackPressChangedSupplier.hasObservers());
mEditorControllerSupplier.set(mEditorController);
assertTrue(mEditorControllerBackPressChangedSupplier.hasObservers());
}
private void initAndAssertAllProperties() {
assertThat(
mModel.get(TabListContainerProperties.VISIBILITY_LISTENER),
instanceOf(TabSwitcherMediator.class));
assertThat(
mModel.get(TabListContainerProperties.ANIMATE_VISIBILITY_CHANGES), equalTo(true));
assertThat(
mModel.get(TabListContainerProperties.IS_INCOGNITO),
equalTo(mTabModel.isIncognito()));
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(false));
assertThat(
mModel.get(TabListContainerProperties.TOP_MARGIN), equalTo(CONTROL_HEIGHT_DEFAULT));
assertThat(
mModel.get(TabListContainerProperties.BOTTOM_CONTROLS_HEIGHT),
equalTo(CONTROL_HEIGHT_DEFAULT));
}
private Tab prepareTab(int id, String title) {
Tab tab = mock(Tab.class);
when(tab.getView()).thenReturn(mock(View.class));
when(tab.getUserDataHost()).thenReturn(new UserDataHost());
doReturn(id).when(tab).getId();
doReturn(GURL.emptyGURL()).when(tab).getUrl();
doReturn(title).when(tab).getTitle();
doReturn(false).when(tab).isClosing();
return tab;
}
}