blob: d24dccf4d297fc5a0debb9928e52e399c96c0098 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.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.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
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.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.res.Resources;
import android.view.View;
import org.junit.After;
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.chromium.base.UserDataHost;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.metrics.test.ShadowRecordHistogram;
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.chrome.browser.compositor.CompositorViewHolder;
import org.chromium.chrome.browser.compositor.layouts.Layout;
import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabImpl;
import org.chromium.chrome.browser.tab.TabSelectionType;
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.test.util.browser.Features;
import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel;
import org.chromium.ui.modelutil.PropertyObservable;
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, shadows = {ShadowRecordHistogram.class})
@DisableFeatures(
{ChromeFeatureList.TAB_SWITCHER_ON_RETURN, ChromeFeatureList.START_SURFACE_ANDROID})
@EnableFeatures({ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID, 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;
@Mock
TabSwitcherMediator.ResetHandler mResetHandler;
@Mock
TabContentManager mTabContentManager;
@Mock
TabModelSelectorImpl mTabModelSelector;
@Mock
TabModel mTabModel;
@Mock
TabModelFilter mTabModelFilter;
@Mock
TabModelFilterProvider mTabModelFilterProvider;
@Mock
Context mContext;
@Mock
Resources mResources;
@Mock
ChromeFullscreenManager mFullscreenManager;
@Mock
PropertyObservable.PropertyObserver<PropertyKey> mPropertyObserver;
@Mock
TabSwitcher.OverviewModeObserver mOverviewModeObserver;
@Mock
CompositorViewHolder mCompositorViewHolder;
@Mock
Layout mLayout;
@Mock
TabGridDialogMediator.DialogController mTabGridDialogController;
@Mock
TabSwitcherMediator.MessageItemsController mMessageItemsController;
@Captor
ArgumentCaptor<TabModelObserver> mTabModelObserverCaptor;
@Captor
ArgumentCaptor<TabModelSelectorObserver> mTabModelSelectorObserverCaptor;
@Captor
ArgumentCaptor<ChromeFullscreenManager.FullscreenListener> mFullscreenListenerCaptor;
private TabImpl mTab1;
private TabImpl mTab2;
private TabImpl mTab3;
private TabSwitcherMediator mMediator;
private PropertyModel mModel;
@Before
public void setUp() {
ShadowRecordHistogram.reset();
RecordHistogram.setDisabledForTests(true);
MockitoAnnotations.initMocks(this);
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(), 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(2).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(mFullscreenManager).getBottomControlsHeight();
doReturn(CONTROL_HEIGHT_DEFAULT).when(mFullscreenManager).getTopControlsHeight();
doNothing().when(mFullscreenManager).addListener(mFullscreenListenerCaptor.capture());
mModel = new PropertyModel(TabListContainerProperties.ALL_KEYS);
mModel.addObserver(mPropertyObserver);
mMediator = new TabSwitcherMediator(mResetHandler, mModel, mTabModelSelector,
mFullscreenManager, mCompositorViewHolder, null, mMessageItemsController,
TabListCoordinator.TabListMode.GRID);
mMediator.initWithNative(null);
mMediator.addOverviewModeObserver(mOverviewModeObserver);
mMediator.setOnTabSelectingListener(mLayout::onTabSelecting);
}
@After
public void tearDown() {
RecordHistogram.setDisabledForTests(false);
}
@Test
public void initializesWithCurrentModelOnCreation() {
initAndAssertAllProperties();
}
@Test
public void showsWithAnimation() {
initAndAssertAllProperties();
mMediator.showOverview(true);
assertThat(
mModel.get(TabListContainerProperties.ANIMATE_VISIBILITY_CHANGES), equalTo(true));
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(true));
assertThat(mMediator.overviewVisible(), equalTo(true));
}
@Test
public void showsWithoutAnimation() {
initAndAssertAllProperties();
mMediator.showOverview(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));
assertThat(mMediator.overviewVisible(), equalTo(true));
assertThat(ShadowRecordHistogram.getHistogramValueCountForTesting(
TabSwitcherMediator.TAB_COUNT_HISTOGRAM, 3),
equalTo(1));
assertThat(ShadowRecordHistogram.getHistogramValueCountForTesting(
TabSwitcherMediator.TAB_ENTRIES_HISTOGRAM, 3),
equalTo(1));
}
@Test
public void showsWithoutAnimation_withTabGroups() {
doReturn(2).when(mTabModelFilter).getCount();
initAndAssertAllProperties();
mMediator.showOverview(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));
assertThat(mMediator.overviewVisible(), equalTo(true));
assertThat(ShadowRecordHistogram.getHistogramValueCountForTesting(
TabSwitcherMediator.TAB_COUNT_HISTOGRAM, 3),
equalTo(1));
assertThat(ShadowRecordHistogram.getHistogramValueCountForTesting(
TabSwitcherMediator.TAB_ENTRIES_HISTOGRAM, 2),
equalTo(1));
}
@Test
public void hidesWithAnimation() {
initAndAssertAllProperties();
mMediator.setTabGridDialogController(mTabGridDialogController);
mMediator.showOverview(true);
assertThat(
mModel.get(TabListContainerProperties.ANIMATE_VISIBILITY_CHANGES), equalTo(true));
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(true));
mMediator.hideOverview(true);
assertThat(
mModel.get(TabListContainerProperties.ANIMATE_VISIBILITY_CHANGES), equalTo(true));
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(false));
assertThat(mMediator.overviewVisible(), equalTo(false));
verify(mTabGridDialogController).hideDialog(eq(false));
}
@Test
public void hidesWithoutAnimation() {
initAndAssertAllProperties();
mMediator.setTabGridDialogController(mTabGridDialogController);
mMediator.showOverview(true);
assertThat(
mModel.get(TabListContainerProperties.ANIMATE_VISIBILITY_CHANGES), equalTo(true));
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(true));
mMediator.hideOverview(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));
assertThat(mMediator.overviewVisible(), equalTo(false));
verify(mTabGridDialogController).hideDialog(eq(false));
}
@Test
public void startedShowingPropagatesToObservers() {
initAndAssertAllProperties();
mModel.get(TabListContainerProperties.VISIBILITY_LISTENER).startedShowing(true);
verify(mOverviewModeObserver).startedShowing();
}
@Test
public void finishedShowingPropagatesToObservers() {
initAndAssertAllProperties();
mModel.get(TabListContainerProperties.VISIBILITY_LISTENER).finishedShowing();
verify(mOverviewModeObserver).finishedShowing();
}
@Test
public void startedHidingPropagatesToObservers() {
initAndAssertAllProperties();
mModel.get(TabListContainerProperties.VISIBILITY_LISTENER).startedHiding(true);
verify(mOverviewModeObserver).startedHiding();
}
@Test
public void finishedHidingPropagatesToObservers() {
initAndAssertAllProperties();
mModel.get(TabListContainerProperties.VISIBILITY_LISTENER).finishedHiding();
verify(mOverviewModeObserver).finishedHiding();
}
@Test
public void resetsToNullAfterHidingFinishes() {
initAndAssertAllProperties();
mMediator.setSoftCleanupDelayForTesting(0);
mMediator.setCleanupDelayForTesting(0);
mMediator.postHiding();
verify(mResetHandler).softCleanup();
verify(mResetHandler).resetWithTabList(eq(null), eq(false), eq(false));
}
@Test
public void resetsAfterNewTabModelSelected_DialogEnabled() {
initAndAssertAllProperties();
mModel.set(TabListContainerProperties.IS_VISIBLE, true);
// Setup dialog reset handler. Default setup is that dialog handler is null.
mMediator.setTabGridDialogController(mTabGridDialogController);
doReturn(true).when(mTabModelFilter).isIncognito();
mTabModelSelectorObserverCaptor.getValue().onTabModelSelected(mTabModel, null);
verify(mResetHandler).resetWithTabList(eq(mTabModelFilter), eq(false), 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 resetsAfterNewTabModelSelected_DialogNotEnabled() {
initAndAssertAllProperties();
mModel.set(TabListContainerProperties.IS_VISIBLE, true);
doReturn(true).when(mTabModelFilter).isIncognito();
mTabModelSelectorObserverCaptor.getValue().onTabModelSelected(mTabModel, null);
verify(mResetHandler).resetWithTabList(eq(mTabModelFilter), eq(false), eq(false));
verify(mTabGridDialogController, never()).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));
// Setup dialog reset handler. Default setup is that dialog handler is null.
mMediator.setTabGridDialogController(mTabGridDialogController);
doReturn(true).when(mTabModelFilter).isIncognito();
mTabModelSelectorObserverCaptor.getValue().onTabModelSelected(mTabModel, null);
verify(mResetHandler, never()).resetWithTabList(any(), anyBoolean(), 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 updatesMarginWithBottomBarChanges() {
initAndAssertAllProperties();
assertThat(mModel.get(TabListContainerProperties.BOTTOM_CONTROLS_HEIGHT),
equalTo(CONTROL_HEIGHT_DEFAULT));
mFullscreenListenerCaptor.getValue().onBottomControlsHeightChanged(
CONTROL_HEIGHT_MODIFIED, 0);
assertThat(mModel.get(TabListContainerProperties.BOTTOM_CONTROLS_HEIGHT),
equalTo(CONTROL_HEIGHT_MODIFIED));
}
@Test
public void hidesWhenATabIsSelected() {
initAndAssertAllProperties();
mMediator.showOverview(true);
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(true));
mTabModelObserverCaptor.getValue().didSelectTab(mTab1, TabSelectionType.FROM_USER, TAB3_ID);
verify(mLayout).onTabSelecting(anyLong(), eq(TAB1_ID));
}
@Test
public void doesNotHideWhenSelectedTabChangedDueToTabClosure() {
initAndAssertAllProperties();
mMediator.showOverview(true);
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(true));
doReturn(true).when(mTab3).isClosing();
mTabModelObserverCaptor.getValue().didSelectTab(
mTab1, TabSelectionType.FROM_CLOSE, TAB3_ID);
verify(mLayout, never()).onTabSelecting(anyLong(), anyInt());
mTabModelObserverCaptor.getValue().didSelectTab(mTab1, TabSelectionType.FROM_USER, TAB3_ID);
verify(mLayout).onTabSelecting(anyLong(), eq(TAB1_ID));
}
@Test
public void doesNotHideWhenSelectedTabChangedDueToModelChange() {
initAndAssertAllProperties();
mMediator.showOverview(true);
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(true));
mTabModelSelectorObserverCaptor.getValue().onTabModelSelected(mTabModel, null);
mTabModelObserverCaptor.getValue().didSelectTab(mTab1, TabSelectionType.FROM_USER, TAB3_ID);
verify(mLayout, never()).onTabSelecting(anyLong(), anyInt());
mTabModelObserverCaptor.getValue().didSelectTab(mTab1, TabSelectionType.FROM_USER, TAB3_ID);
verify(mLayout).onTabSelecting(anyLong(), eq(TAB1_ID));
}
@Test
public void updatesResetHandlerOnRestoreCompleted() {
initAndAssertAllProperties();
mMediator.showOverview(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, false);
}
@Test
public void setInitialScrollIndexOnRestoreCompleted() {
initAndAssertAllProperties();
mMediator.showOverview(true);
assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(true));
mModel.set(TabListContainerProperties.INITIAL_SCROLL_INDEX, 1);
mTabModelObserverCaptor.getValue().restoreCompleted();
assertThat(mModel.get(TabListContainerProperties.INITIAL_SCROLL_INDEX), equalTo(0));
}
@Test
public void removeMessageItemsWhenCloseLastTab() {
initAndAssertAllProperties();
// Mock that mTab1 is not the only tab in the current tab model and it will be closed.
doReturn(2).when(mTabModel).getCount();
mTabModelObserverCaptor.getValue().willCloseTab(mTab1, false);
verify(mMessageItemsController, never()).removeAllAppendedMessage();
// Mock that mTab1 is the only tab in the current tab model and it will be closed.
doReturn(1).when(mTabModel).getCount();
mTabModelObserverCaptor.getValue().willCloseTab(mTab1, false);
verify(mMessageItemsController).removeAllAppendedMessage();
}
@Test
public void restoreMessageItemsWhenUndoLastTabClosure() {
initAndAssertAllProperties();
// Mock that mTab1 was not the only tab in the current tab model and its closure will be
// undone.
doReturn(2).when(mTabModel).getCount();
mTabModelObserverCaptor.getValue().tabClosureUndone(mTab1);
verify(mMessageItemsController, never()).restoreAllAppendedMessage();
// Mock that mTab1 was the only tab in the current tab model and its closure will be undone.
doReturn(1).when(mTabModel).getCount();
mTabModelObserverCaptor.getValue().tabClosureUndone(mTab1);
verify(mMessageItemsController).restoreAllAppendedMessage();
}
@Test
public void showOverviewDoesNotUpdateResetHandlerBeforeRestoreCompleted() {
initAndAssertAllProperties();
doReturn(false).when(mTabModelFilter).isTabModelRestored();
mMediator.showOverview(true);
// MRU will be false unless the start surface is enabled.
verify(mResetHandler, never()).resetWithTabList(mTabModelFilter, true, false);
}
@Test
public void prepareOverviewDoesNotUpdateResetHandlerBeforeRestoreCompleted() {
initAndAssertAllProperties();
doReturn(false).when(mTabModelFilter).isTabModelRestored();
mMediator.prepareOverview();
// MRU will be false unless the start surface is enabled.
verify(mResetHandler, never()).resetWithTabList(mTabModelFilter, false, false);
}
@Test
public void showOverviewUpdatesResetHandlerAfterRestoreCompleted() {
initAndAssertAllProperties();
doReturn(true).when(mTabModelFilter).isTabModelRestored();
mMediator.showOverview(true);
// MRU will be false unless the start surface is enabled.
verify(mResetHandler).resetWithTabList(mTabModelFilter, true, false);
}
@Test
public void prepareOverviewUpdatesResetHandlerAfterRestoreCompleted() {
initAndAssertAllProperties();
doReturn(true).when(mTabModelFilter).isTabModelRestored();
mMediator.prepareOverview();
// MRU will be false unless the start surface is enabled.
verify(mResetHandler).resetWithTabList(mTabModelFilter, false, false);
}
@Test
public void prepareOverviewSetsInitialScrollIndexAfterRestoreCompleted() {
initAndAssertAllProperties();
doReturn(true).when(mTabModelFilter).isTabModelRestored();
mModel.set(TabListContainerProperties.INITIAL_SCROLL_INDEX, 1);
mMediator.prepareOverview();
assertThat(mModel.get(TabListContainerProperties.INITIAL_SCROLL_INDEX), equalTo(0));
}
@Test
@Features.EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID})
public void openDialogButton_SingleTab() {
mMediator.setTabGridDialogController(mTabGridDialogController);
// 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
@Features.EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID})
public void openDialogButton_TabGroup_NotEmpty() {
mMediator.setTabGridDialogController(mTabGridDialogController);
// Set up a tab group.
TabImpl newTab = prepareTab(TAB4_ID, TAB4_TITLE);
List<Tab> tabs = new ArrayList<>(Arrays.asList(mTab1, newTab));
doReturn(tabs).when(mTabModelFilter).getRelatedTabList(TAB1_ID);
TabListMediator.TabActionListener listener = mMediator.openTabGridDialog(mTab1);
assertThat(listener, notNullValue());
listener.run(TAB1_ID);
verify(mTabGridDialogController).resetWithListOfTabs(eq(tabs));
}
@Test
@Features.EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID})
public void openDialogButton_TabGroup_Empty() {
mMediator.setTabGridDialogController(mTabGridDialogController);
// Assume that due to tab model change, current group becomes empty in current model.
doReturn(new ArrayList<>()).when(mTabModelFilter).getRelatedTabList(TAB1_ID);
TabListMediator.TabActionListener listener = mMediator.openTabGridDialog(mTab1);
assertThat(listener, notNullValue());
listener.run(TAB1_ID);
verify(mTabGridDialogController).resetWithListOfTabs(eq(null));
}
@Test
public void updatesPropertiesWithTopControlsChanges() {
assertEquals(
CONTROL_HEIGHT_DEFAULT, mModel.get(TabListContainerProperties.TOP_CONTROLS_HEIGHT));
assertEquals(
CONTROL_HEIGHT_DEFAULT, mModel.get(TabListContainerProperties.SHADOW_TOP_MARGIN));
mFullscreenListenerCaptor.getValue().onTopControlsHeightChanged(
CONTROL_HEIGHT_INCREASED, 0);
assertEquals(CONTROL_HEIGHT_INCREASED,
mModel.get(TabListContainerProperties.TOP_CONTROLS_HEIGHT));
assertEquals(
CONTROL_HEIGHT_INCREASED, mModel.get(TabListContainerProperties.SHADOW_TOP_MARGIN));
mFullscreenListenerCaptor.getValue().onTopControlsHeightChanged(CONTROL_HEIGHT_DEFAULT, 0);
assertEquals(
CONTROL_HEIGHT_DEFAULT, mModel.get(TabListContainerProperties.TOP_CONTROLS_HEIGHT));
assertEquals(
CONTROL_HEIGHT_DEFAULT, mModel.get(TabListContainerProperties.SHADOW_TOP_MARGIN));
}
@Test
@Features.EnableFeatures(ChromeFeatureList.START_SURFACE_ANDROID)
public void updatesPropertiesWithTopControlsChanges_StartSurface() {
assertEquals(0, mModel.get(TabListContainerProperties.TOP_CONTROLS_HEIGHT));
assertEquals(0, mModel.get(TabListContainerProperties.SHADOW_TOP_MARGIN));
mFullscreenListenerCaptor.getValue().onTopControlsHeightChanged(
CONTROL_HEIGHT_INCREASED, 0);
assertEquals(0, mModel.get(TabListContainerProperties.TOP_CONTROLS_HEIGHT));
assertEquals(0, mModel.get(TabListContainerProperties.SHADOW_TOP_MARGIN));
mFullscreenListenerCaptor.getValue().onTopControlsHeightChanged(CONTROL_HEIGHT_DEFAULT, 0);
assertEquals(0, mModel.get(TabListContainerProperties.TOP_CONTROLS_HEIGHT));
assertEquals(0, mModel.get(TabListContainerProperties.SHADOW_TOP_MARGIN));
}
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_CONTROLS_HEIGHT),
equalTo(CONTROL_HEIGHT_DEFAULT));
assertThat(mModel.get(TabListContainerProperties.BOTTOM_CONTROLS_HEIGHT),
equalTo(CONTROL_HEIGHT_DEFAULT));
}
private TabImpl prepareTab(int id, String title) {
TabImpl tab = mock(TabImpl.class);
when(tab.getView()).thenReturn(mock(View.class));
when(tab.getUserDataHost()).thenReturn(new UserDataHost());
doReturn(id).when(tab).getId();
doReturn("").when(tab).getUrlString();
doReturn(title).when(tab).getTitle();
doReturn(false).when(tab).isClosing();
return tab;
}
}