// Copyright 2021 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.customtabs.features.toolbar;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
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.app.Activity;
import android.graphics.Color;
import android.os.Handler;
import android.os.Looper;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.MeasureSpec;
import android.widget.FrameLayout;
import android.widget.FrameLayout.LayoutParams;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.browser.customtabs.CustomTabsIntent;
import org.junit.After;
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.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.Robolectric;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.LooperMode;
import org.robolectric.annotation.LooperMode.Mode;
import org.robolectric.shadows.ShadowLooper;
import org.chromium.base.Callback;
import org.chromium.base.UserDataHost;
import org.chromium.base.supplier.ObservableSupplierImpl;
import org.chromium.base.task.TaskTraits;
import org.chromium.base.task.test.ShadowPostTask;
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.base.test.util.Features.DisableFeatures;
import org.chromium.base.test.util.Features.EnableFeatures;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.browser_controls.BrowserStateBrowserControlsVisibilityDelegate;
import org.chromium.chrome.browser.customtabs.CustomTabFeatureOverridesManager;
import org.chromium.chrome.browser.customtabs.features.minimizedcustomtab.MinimizedFeatureUtils;
import org.chromium.chrome.browser.customtabs.features.toolbar.CustomTabToolbar.CustomTabLocationBar;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.multiwindow.MultiWindowUtils;
import org.chromium.chrome.browser.omnibox.UrlBarData;
import org.chromium.chrome.browser.omnibox.status.PageInfoIPHController;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.toolbar.LocationBarModel;
import org.chromium.chrome.browser.toolbar.ToolbarDataProvider;
import org.chromium.chrome.browser.toolbar.ToolbarTabController;
import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonCoordinator;
import org.chromium.chrome.browser.toolbar.top.CaptureReadinessResult;
import org.chromium.chrome.browser.toolbar.top.NavigationPopup.HistoryDelegate;
import org.chromium.chrome.browser.toolbar.top.ToggleTabStackButtonCoordinator;
import org.chromium.chrome.browser.toolbar.top.ToolbarSnapshotDifference;
import org.chromium.chrome.browser.toolbar.top.ToolbarTablet.OfflineDownloader;
import org.chromium.chrome.browser.user_education.UserEducationHelper;
import org.chromium.components.content_settings.CookieBlocking3pcdStatus;
import org.chromium.components.feature_engagement.Tracker;
import org.chromium.components.security_state.ConnectionSecurityLevel;
import org.chromium.content_public.common.ContentUrlConstants;
import org.chromium.ui.base.TestActivity;
import org.chromium.ui.base.WindowAndroid;
import org.chromium.url.GURL;
import org.chromium.url.JUnitTestGURLs;
import java.lang.ref.WeakReference;
import java.util.concurrent.TimeUnit;
import java.util.function.BooleanSupplier;
/** Tests AMP url handling in the CustomTab Toolbar. */
@RunWith(BaseRobolectricTestRunner.class)
@Config(
manifest = Config.NONE,
shadows = {ShadowLooper.class, ShadowPostTask.class})
@LooperMode(Mode.PAUSED)
@DisableFeatures(ChromeFeatureList.SUPPRESS_TOOLBAR_CAPTURES)
public class CustomTabToolbarUnitTest {
private static final GURL TEST_URL = JUnitTestGURLs.INITIAL_URL;
private static final GURL AMP_URL =
new GURL("https://www.google.com/amp/www.nyt.com/ampthml/blogs.html");
private static final GURL AMP_CACHE_URL =
new GURL("https://www.google.com/amp/s/www.nyt.com/ampthml/blogs.html");
@Rule public MockitoRule mRule = MockitoJUnit.rule();
@Mock LocationBarModel mLocationBarModel;
@Mock ActionMode.Callback mActionModeCallback;
@Mock CustomTabToolbarAnimationDelegate mAnimationDelegate;
@Mock BrowserStateBrowserControlsVisibilityDelegate mControlsVisibleDelegate;
@Mock ToolbarDataProvider mToolbarDataProvider;
@Mock ToolbarTabController mTabController;
@Mock MenuButtonCoordinator mMenuButtonCoordinator;
@Mock private ToggleTabStackButtonCoordinator mTabSwitcherButtonCoordinator;
@Mock HistoryDelegate mHistoryDelegate;
@Mock BooleanSupplier mPartnerHomepageEnabledSupplier;
@Mock OfflineDownloader mOfflineDownloader;
@Mock UserEducationHelper mUserEducationHelper;
@Mock Tracker mTracker;
@Mock Tab mTab;
@Mock Callback<Integer> mContainerVisibilityChangeObserver;
@Mock View mParentView;
@Mock WindowAndroid mWindowAndroid;
private @Mock PageInfoIPHController mPageInfoIPHController;
@Mock private CustomTabFeatureOverridesManager mFeatureOverridesManager;
private Activity mActivity;
private CustomTabToolbar mToolbar;
private CustomTabLocationBar mLocationBar;
private TextView mTitleBar;
private TextView mUrlBar;
private ImageButton mSecurityButton;
private ImageButton mSecurityIcon;
@Before
public void setup() {
ShadowPostTask.setTestImpl(
(@TaskTraits int taskTraits, Runnable task, long delay) -> {
new Handler(Looper.getMainLooper()).postDelayed(task, delay);
});
Mockito.doReturn(R.string.accessibility_security_btn_secure)
.when(mLocationBarModel)
.getSecurityIconContentDescriptionResourceId();
Mockito.doReturn(R.color.default_icon_color_tint_list)
.when(mLocationBarModel)
.getSecurityIconColorStateList();
when(mToolbarDataProvider.getTab()).thenReturn(mTab);
when(mTab.getUserDataHost()).thenReturn(new UserDataHost());
setUpForUrl(TEST_URL);
mActivity = Robolectric.buildActivity(TestActivity.class).get();
mToolbar =
(CustomTabToolbar)
LayoutInflater.from(mActivity)
.inflate(R.layout.custom_tabs_toolbar, null, false);
ObservableSupplierImpl<Tracker> trackerSupplier = new ObservableSupplierImpl<>();
trackerSupplier.set(mTracker);
mToolbar.initialize(
mToolbarDataProvider,
mTabController,
mMenuButtonCoordinator,
mTabSwitcherButtonCoordinator,
mHistoryDelegate,
mPartnerHomepageEnabledSupplier,
mOfflineDownloader,
mUserEducationHelper,
trackerSupplier);
when(mFeatureOverridesManager.isFeatureEnabled(anyString())).thenReturn(null);
mToolbar.setFeatureOverridesManager(mFeatureOverridesManager);
mLocationBar =
(CustomTabLocationBar)
mToolbar.createLocationBar(
mLocationBarModel,
mActionModeCallback,
() -> null,
() -> null,
mControlsVisibleDelegate,
null);
mUrlBar = mToolbar.findViewById(R.id.url_bar);
mTitleBar = mToolbar.findViewById(R.id.title_bar);
mLocationBar.setAnimDelegateForTesting(mAnimationDelegate);
mLocationBar.setIPHControllerForTesting(mPageInfoIPHController);
mSecurityButton = mToolbar.findViewById(R.id.security_button);
mSecurityIcon = mToolbar.findViewById(R.id.security_icon);
}
@After
public void tearDown() {
mActivity.finish();
}
@Test
public void testParsesPublisherFromAmp() {
assertEquals("www.nyt.com", CustomTabToolbar.parsePublisherNameFromUrl(AMP_URL));
assertEquals("www.nyt.com", CustomTabToolbar.parsePublisherNameFromUrl(AMP_CACHE_URL));
assertEquals(
JUnitTestGURLs.EXAMPLE_URL.getSpec(),
CustomTabToolbar.parsePublisherNameFromUrl(JUnitTestGURLs.EXAMPLE_URL));
}
@Test
public void testToolbarBrandingDelegateImpl_EmptyToRegular() {
assertUrlAndTitleVisible(/* titleVisible= */ false, /* urlVisible= */ true);
mLocationBar.showEmptyLocationBar();
assertUrlAndTitleVisible(/* titleVisible= */ false, /* urlVisible= */ false);
// Attempt to update title and URL, should noop since location bar is still in empty state.
mLocationBar.onTitleChanged();
mLocationBar.onUrlChanged();
verify(mLocationBarModel, never()).notifySecurityStateChanged();
mLocationBar.showRegularToolbar();
assertUrlAndTitleVisible(/* titleVisible= */ false, /* urlVisible= */ true);
verify(mLocationBarModel).notifyTitleChanged();
verify(mLocationBarModel).notifySecurityStateChanged();
verifyBrowserControlVisibleForRequiredDuration();
// URL bar truncates trailing /.
assertUrlBarShowingText(TEST_URL.getSpec().replaceAll("/$", ""));
}
@Test
public void testToolbarBrandingDelegateImpl_EmptyToBranding() {
assertUrlAndTitleVisible(/* titleVisible= */ false, /* urlVisible= */ true);
mLocationBar.showEmptyLocationBar();
assertUrlAndTitleVisible(/* titleVisible= */ false, /* urlVisible= */ false);
// Attempt to update title and URL, should noop since location bar is still in empty state.
mLocationBar.setShowTitle(true);
mLocationBar.setUrlBarHidden(false);
verify(mLocationBarModel, never()).notifySecurityStateChanged();
mLocationBar.showBrandingLocationBar();
assertUrlAndTitleVisible(/* titleVisible= */ false, /* urlVisible= */ true);
verify(mAnimationDelegate).updateSecurityButton(anyInt());
assertBrandingTextShowingOnUrlBar();
// Attempt to update title and URL to show Title only - should be ignored during branding.
reset(mLocationBarModel);
setUpForUrl(TEST_URL);
mLocationBar.setShowTitle(true);
mLocationBar.setUrlBarHidden(true);
verifyNoMoreInteractions(mLocationBarModel);
// After getting back to regular toolbar, title should become visible now.
mLocationBar.showRegularToolbar();
assertUrlAndTitleVisible(/* titleVisible= */ true, /* urlVisible= */ false);
verify(mLocationBarModel, atLeastOnce()).notifyTitleChanged();
verify(mLocationBarModel, atLeastOnce()).notifySecurityStateChanged();
verifyBrowserControlVisibleForRequiredDuration();
}
@Test
@EnableFeatures(ChromeFeatureList.SUPPRESS_TOOLBAR_CAPTURES)
public void testIsReadyForTextureCapture() {
CaptureReadinessResult result = mToolbar.isReadyForTextureCapture();
assertTrue(result.isReady);
assertEquals(result.snapshotDifference, ToolbarSnapshotDifference.NULL);
fakeTextureCapture();
result = mToolbar.isReadyForTextureCapture();
assertEquals(result.snapshotDifference, ToolbarSnapshotDifference.NONE);
assertFalse(result.isReady);
when(mToolbarDataProvider.getPrimaryColor()).thenReturn(Color.RED);
mToolbar.onPrimaryColorChanged(false);
result = mToolbar.isReadyForTextureCapture();
assertTrue(result.isReady);
assertEquals(result.snapshotDifference, ToolbarSnapshotDifference.TINT);
fakeTextureCapture();
when(mToolbarDataProvider.getTab()).thenReturn(mTab);
when(mTab.getUserDataHost()).thenReturn(new UserDataHost());
when(mTab.getUrl()).thenReturn(JUnitTestGURLs.RED_1);
UrlBarData urlBarData = UrlBarData.forUrl(JUnitTestGURLs.RED_1);
when(mLocationBarModel.getUrlBarData()).thenReturn(urlBarData);
mLocationBar.onUrlChanged();
result = mToolbar.isReadyForTextureCapture();
assertTrue(result.isReady);
assertEquals(result.snapshotDifference, ToolbarSnapshotDifference.URL_TEXT);
fakeTextureCapture();
when(mLocationBarModel.hasTab()).thenReturn(true);
when(mLocationBarModel.getTitle()).thenReturn("Red 1");
mLocationBar.onTitleChanged();
result = mToolbar.isReadyForTextureCapture();
assertTrue(result.isReady);
assertEquals(result.snapshotDifference, ToolbarSnapshotDifference.TITLE_TEXT);
fakeTextureCapture();
when(mLocationBarModel.getSecurityIconResource(anyBoolean()))
.thenReturn(R.drawable.ic_globe_24dp);
when(mAnimationDelegate.getSecurityIconRes()).thenReturn(R.drawable.ic_globe_24dp);
mLocationBar.onSecurityStateChanged();
result = mToolbar.isReadyForTextureCapture();
assertTrue(result.isReady);
assertEquals(result.snapshotDifference, ToolbarSnapshotDifference.SECURITY_ICON);
fakeTextureCapture();
when(mAnimationDelegate.isInAnimation()).thenReturn(true);
result = mToolbar.isReadyForTextureCapture();
assertTrue(result.isReady);
assertEquals(result.snapshotDifference, ToolbarSnapshotDifference.CCT_ANIMATION);
when(mAnimationDelegate.isInAnimation()).thenReturn(false);
fakeTextureCapture();
mToolbar.layout(0, 0, 100, 100);
result = mToolbar.isReadyForTextureCapture();
assertTrue(result.isReady);
assertEquals(result.snapshotDifference, ToolbarSnapshotDifference.LOCATION_BAR_WIDTH);
}
@Test
public void testAboutBlankUrlIsShown() {
setUpForAboutBlank();
ShadowLooper.idleMainLooper();
mLocationBar.onUrlChanged();
assertEquals("The url bar should be visible.", View.VISIBLE, mUrlBar.getVisibility());
assertEquals(
"The url bar should show about:blank",
ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL,
mUrlBar.getText().toString());
}
@Test
public void testTitleIsHiddenForAboutBlank() {
setUpForAboutBlank();
mLocationBar.setShowTitle(true);
ShadowLooper.idleMainLooper();
mLocationBar.onUrlChanged();
assertEquals("The title should be gone.", View.GONE, mTitleBar.getVisibility());
}
@Test
public void testCannotHideUrlForAboutBlank() {
setUpForAboutBlank();
mLocationBar.setUrlBarHidden(true);
ShadowLooper.idleMainLooper();
mLocationBar.onUrlChanged();
assertEquals("The url bar should be visible.", View.VISIBLE, mUrlBar.getVisibility());
assertEquals(
"The url bar should show about:blank",
ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL,
mUrlBar.getText().toString());
}
@Test
public void testMaximizeButton() {
assertFalse(mToolbar.isMaximizeButtonEnabledForTesting());
mToolbar.initSideSheetMaximizeButton(/* maximizedOnInit= */ false, () -> true);
assertTrue(mToolbar.isMaximizeButtonEnabledForTesting());
var maximizeButton = mToolbar.findViewById(R.id.custom_tabs_sidepanel_maximize);
mToolbar.onFinishInflate();
View titleUrlContainer = Mockito.mock(View.class);
mLocationBar.setTitleUrlContainerForTesting(titleUrlContainer);
int maximizeButtonWidth =
mActivity
.getResources()
.getDimensionPixelSize(R.dimen.location_bar_action_icon_width);
int titleUrlPaddingEnd =
mActivity.getResources().getDimensionPixelSize(R.dimen.toolbar_edge_padding);
int threshold = maximizeButtonWidth * 2 - titleUrlPaddingEnd;
when(titleUrlContainer.getWidth()).thenReturn(threshold + 10);
when(titleUrlContainer.getLayoutParams())
.thenReturn(
new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
mToolbar.onMeasure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
when(titleUrlContainer.getWidth()).thenReturn(threshold - 10);
mToolbar.onMeasure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
assertEquals("Maximize button should be hidden", View.GONE, maximizeButton.getVisibility());
mToolbar.removeSideSheetMaximizeButton();
assertEquals("Maximize button should be hidden", View.GONE, maximizeButton.getVisibility());
mToolbar.removeSideSheetMaximizeButton();
assertFalse(mToolbar.isMaximizeButtonEnabledForTesting());
}
@Test
@EnableFeatures({ChromeFeatureList.CCT_MINIMIZED})
public void testMinimizeButtonEnabled() {
when(mTab.getWindowAndroid()).thenReturn(mWindowAndroid);
when(mWindowAndroid.getActivity()).thenReturn(new WeakReference<Activity>(mActivity));
MinimizedFeatureUtils.setDeviceEligibleForMinimizedCustomTabForTesting(true);
setup();
LinearLayout closeMinimizeLayout = mToolbar.findViewById(R.id.close_minimize_layout);
ImageButton minimizeButton = mToolbar.findViewById(R.id.custom_tabs_minimize_button);
View titleUrlContainer = Mockito.mock(View.class);
when(titleUrlContainer.getLayoutParams())
.thenReturn(
new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
mLocationBar.setTitleUrlContainerForTesting(titleUrlContainer);
// Button on left side
assertEquals(
"Minimize button should be visible", View.VISIBLE, minimizeButton.getVisibility());
assertEquals(
"Minimize button should be to the inside of close button",
closeMinimizeLayout.getChildAt(1),
minimizeButton);
// Button on right side
mToolbar.setCloseButtonPosition(CustomTabsIntent.CLOSE_BUTTON_POSITION_END);
mToolbar.onMeasure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
assertEquals(
"Minimize button should be visible", View.VISIBLE, minimizeButton.getVisibility());
assertEquals(
"Minimize button should be to the inside of close button",
closeMinimizeLayout.getChildAt(0),
minimizeButton);
// No space for minimize button
when(titleUrlContainer.getWidth()).thenReturn(60);
mToolbar.onMeasure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
assertEquals("Minimize button should be hidden", View.GONE, minimizeButton.getVisibility());
}
@Test
@DisableFeatures({ChromeFeatureList.CCT_MINIMIZED})
public void testMinimizeButtonDisabled() {
LinearLayout closeMinimizeLayout = mToolbar.findViewById(R.id.close_minimize_layout);
ImageButton minimizeButton = mToolbar.findViewById(R.id.custom_tabs_minimize_button);
ImageButton closeButton = mToolbar.findViewById(R.id.close_button);
// Button on left side
assertNull("Minimize button should never be initialized", minimizeButton);
assertEquals(
"Close button should still be present",
closeMinimizeLayout.getChildAt(0),
closeButton);
// Button on right side
mToolbar.setCloseButtonPosition(CustomTabsIntent.CLOSE_BUTTON_POSITION_END);
mToolbar.onMeasure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
assertNull("Minimize button should never be initialized", minimizeButton);
assertEquals(
"Close button should still be present",
closeMinimizeLayout.getChildAt(1),
closeButton);
}
@Test
@EnableFeatures({ChromeFeatureList.CCT_MINIMIZED})
public void testMinimizeButtonEnabled_MultiWindowMode() {
when(mTab.getWindowAndroid()).thenReturn(mWindowAndroid);
when(mWindowAndroid.getActivity()).thenReturn(new WeakReference<Activity>(mActivity));
MinimizedFeatureUtils.setDeviceEligibleForMinimizedCustomTabForTesting(true);
setup();
// Not in multi-window, show minimize button.
MultiWindowUtils.getInstance().setIsInMultiWindowModeForTesting(false);
LinearLayout closeMinimizeLayout = mToolbar.findViewById(R.id.close_minimize_layout);
mToolbar.onMeasure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
assertEquals(
"Close button should be visible",
View.VISIBLE,
closeMinimizeLayout.getChildAt(0).getVisibility());
assertEquals(
"Minimize button should be visible",
View.VISIBLE,
closeMinimizeLayout.getChildAt(1).getVisibility());
MinimizedFeatureUtils.setDeviceEligibleForMinimizedCustomTabForTesting(true);
setup();
// In multi-window, hide minimize button visibility.
MultiWindowUtils.getInstance().setIsInMultiWindowModeForTesting(true);
closeMinimizeLayout = mToolbar.findViewById(R.id.close_minimize_layout);
mToolbar.onMeasure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
assertNotNull(closeMinimizeLayout.getChildAt(1));
assertEquals(
"Minimize button should NOT be visible",
View.GONE,
closeMinimizeLayout.getChildAt(1).getVisibility());
assertEquals(
"Close button should be visible",
View.VISIBLE,
closeMinimizeLayout.getChildAt(0).getVisibility());
}
@Test
public void testContainerVisibilityChange() {
// Self changes should be ignored.
mToolbar.addContainerVisibilityChangeObserver(mContainerVisibilityChangeObserver);
mToolbar.onVisibilityChanged(mToolbar, View.VISIBLE);
verify(mContainerVisibilityChangeObserver, never()).onResult(any());
mToolbar.onVisibilityChanged(mParentView, View.VISIBLE);
verify(mContainerVisibilityChangeObserver, times(1)).onResult(View.VISIBLE);
// After removing, no more events.
reset(mContainerVisibilityChangeObserver);
mToolbar.removeContainerVisibilityChangeObserver(mContainerVisibilityChangeObserver);
mToolbar.onVisibilityChanged(mParentView, View.VISIBLE);
verify(mContainerVisibilityChangeObserver, never()).onResult(any());
}
@Test
public void testCookieControlsIcon_onHighlightCookieControl_animateOnPageStoppedLoading() {
verify(mAnimationDelegate, never()).updateSecurityButton(anyInt());
mLocationBar.onHighlightCookieControl(true);
verify(mAnimationDelegate, never()).updateSecurityButton(anyInt());
verify(mPageInfoIPHController, never()).showCookieControlsIPH(anyInt(), anyInt());
mLocationBar.onPageLoadStopped();
verify(mAnimationDelegate, times(1)).updateSecurityButton(R.drawable.ic_eye_crossed);
verify(mPageInfoIPHController, times(1)).showCookieControlsIPH(anyInt(), anyInt());
mLocationBar.onHighlightCookieControl(false);
mLocationBar.onPageLoadStopped();
verify(mAnimationDelegate, times(1)).updateSecurityButton(R.drawable.ic_eye_crossed);
verify(mPageInfoIPHController, times(1)).showCookieControlsIPH(anyInt(), anyInt());
}
@Test
public void
testCookieControlsIcon_trackingProtectionsEnabled_cookieBlockingDisabled_doesNotDisplayIPH() {
verify(mAnimationDelegate, never()).updateSecurityButton(anyInt());
mLocationBar.onHighlightCookieControl(true);
mLocationBar.onStatusChanged(
/* controls_visible= */ false,
/* protections_on= */ false,
/* enforcement= */ 0,
CookieBlocking3pcdStatus.LIMITED,
/* expiration= */ 0);
// None of the IPHs should be shown.
mLocationBar.onPageLoadStopped();
verify(mPageInfoIPHController, never()).showCookieControlsIPH(anyInt(), anyInt());
}
@Test
public void
testCookieControlsIcon_trackingProtectionDisabled_cookieBlockingEnabled_displaysCookieControlsIPH() {
verify(mAnimationDelegate, never()).updateSecurityButton(anyInt());
mLocationBar.onHighlightCookieControl(true);
mLocationBar.onStatusChanged(
/* controls_visible= */ true,
/* protections_on= */ true,
/* enforcement= */ 0,
CookieBlocking3pcdStatus.NOT_IN3PCD,
/* expiration= */ 0);
// Should show only the Cookie controls IPH.
mLocationBar.onPageLoadStopped();
verify(mPageInfoIPHController, times(1)).showCookieControlsIPH(anyInt(), anyInt());
}
@Test
@DisableFeatures({
ChromeFeatureList.CCT_REVAMPED_BRANDING,
ChromeFeatureList.CCT_NESTED_SECURITY_ICON
})
public void testSecurityIconVisibility() {
assertEquals(View.INVISIBLE, mSecurityButton.getVisibility());
assertEquals(View.GONE, mSecurityIcon.getVisibility());
}
@Test
@EnableFeatures({
ChromeFeatureList.CCT_REVAMPED_BRANDING,
ChromeFeatureList.CCT_NESTED_SECURITY_ICON
})
public void testSecurityIconVisibility_nestedIcon() {
assertEquals(View.GONE, mSecurityButton.getVisibility());
assertEquals(View.INVISIBLE, mSecurityIcon.getVisibility());
}
@Test
@EnableFeatures({
ChromeFeatureList.CCT_REVAMPED_BRANDING,
ChromeFeatureList.CCT_NESTED_SECURITY_ICON
})
public void testSecurityIconHidden() {
when(mLocationBarModel.getSecurityIconResource(anyBoolean()))
.thenReturn(R.drawable.omnibox_https_valid_refresh);
when(mLocationBarModel.getSecurityLevel()).thenReturn(ConnectionSecurityLevel.SECURE);
mLocationBar.onSecurityStateChanged();
verify(mAnimationDelegate).updateSecurityButton(0);
}
@Test
@EnableFeatures({
ChromeFeatureList.CCT_REVAMPED_BRANDING,
ChromeFeatureList.CCT_NESTED_SECURITY_ICON
})
public void testSecurityIconShown() {
when(mLocationBarModel.getSecurityIconResource(anyBoolean()))
.thenReturn(R.drawable.omnibox_info);
when(mLocationBarModel.getSecurityLevel()).thenReturn(ConnectionSecurityLevel.NONE);
mLocationBar.onSecurityStateChanged();
verify(mAnimationDelegate).updateSecurityButton(R.drawable.omnibox_info);
}
private void assertUrlAndTitleVisible(boolean titleVisible, boolean urlVisible) {
int expectedTitleVisibility = titleVisible ? View.VISIBLE : View.GONE;
int expectedUrlVisibility = urlVisible ? View.VISIBLE : View.GONE;
assertEquals(
"Title visibility is off.", expectedTitleVisibility, mTitleBar.getVisibility());
assertEquals("URL bar visibility is off.", expectedUrlVisibility, mUrlBar.getVisibility());
}
private void assertUrlBarShowingText(String expectedString) {
assertEquals("URL bar is not visible.", mUrlBar.getVisibility(), View.VISIBLE);
assertEquals("URL bar text does not match.", expectedString, mUrlBar.getText().toString());
}
private void assertBrandingTextShowingOnUrlBar() {
assertUrlBarShowingText(mActivity.getResources().getString(R.string.twa_running_in_chrome));
}
private void verifyBrowserControlVisibleForRequiredDuration() {
// Verify browser control is visible for required duration (3000ms).
ShadowLooper looper = Shadows.shadowOf(Looper.getMainLooper());
verify(mControlsVisibleDelegate).showControlsPersistent();
looper.idleFor(2999, TimeUnit.MILLISECONDS);
verify(mControlsVisibleDelegate, never()).releasePersistentShowingToken(anyInt());
looper.idleFor(1, TimeUnit.MILLISECONDS);
verify(mControlsVisibleDelegate).releasePersistentShowingToken(anyInt());
}
private void fakeTextureCapture() {
mToolbar.setTextureCaptureMode(true);
// Normally an actual capture would happen here.
mToolbar.setTextureCaptureMode(false);
}
private void setUpForAboutBlank() {
UrlBarData urlBarData = UrlBarData.forUrl(JUnitTestGURLs.ABOUT_BLANK);
when(mLocationBarModel.getUrlBarData()).thenReturn(urlBarData);
when(mTab.getUrl()).thenReturn(JUnitTestGURLs.ABOUT_BLANK);
}
private void setUpForUrl(GURL url) {
Mockito.doReturn(url).when(mTab).getUrl();
Mockito.doReturn(UrlBarData.forUrl(url)).when(mLocationBarModel).getUrlBarData();
}
}