blob: f38de87ec3487056ed07dbe934f637459e6eda61 [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.browserservices.trustedwebactivityui.controller;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider;
import org.chromium.chrome.browser.customtabs.CloseButtonVisibilityManager;
import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabProvider;
import org.chromium.chrome.browser.customtabs.content.TabObserverRegistrar;
import org.chromium.chrome.browser.customtabs.features.toolbar.CustomTabToolbarCoordinator;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabImpl;
import org.chromium.chrome.browser.webapps.WebDisplayMode;
import org.chromium.chrome.test.util.browser.webapps.WebApkInfoBuilder;
import org.chromium.components.security_state.ConnectionSecurityLevel;
import org.chromium.content_public.common.BrowserControlsState;
/**
* Tests for {@link TrustedWebActivityBrowserControlsVisibilityManager}.
*/
@RunWith(BaseRobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class TrustedWebActivityBrowserControlsVisibilityManagerTest {
@Mock
public TabObserverRegistrar mTabObserverRegistrar;
@Mock
public CustomTabActivityTabProvider mTabProvider;
@Mock
public TabImpl mTab;
@Mock
public CustomTabToolbarCoordinator mToolbarCoordinator;
@Mock
public CloseButtonVisibilityManager mCloseButtonVisibilityManager;
TrustedWebActivityBrowserControlsVisibilityManager mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mTabProvider.getTab()).thenReturn(mTab);
when(mTab.getParentId()).thenReturn(Tab.INVALID_TAB_ID);
setTabSecurityLevel(ConnectionSecurityLevel.NONE);
}
/**
* Browser controls should be shown for pages with certificate errors.
*/
@Test
public void testDangerousSecurityLevel() {
setTabSecurityLevel(ConnectionSecurityLevel.DANGEROUS);
mController = buildController(mock(BrowserServicesIntentDataProvider.class));
mController.updateIsInTwaMode(true);
assertEquals(BrowserControlsState.SHOWN, getLastBrowserControlsState());
assertFalse(getLastCloseButtonVisibility());
}
/**
* Browser controls should be shown for WebAPKs with 'minimal-ui' display mode.
*/
@Test
public void testMinimalUiDisplayMode() {
mController = buildController(buildWebApkIntentDataProvider(WebDisplayMode.MINIMAL_UI));
mController.updateIsInTwaMode(true);
assertEquals(BrowserControlsState.BOTH, getLastBrowserControlsState());
assertFalse(getLastCloseButtonVisibility());
}
/**
* Browser controls should not be shown for WebAPKs with 'standalone' display mode while in TWA
* mode.
*/
@Test
public void testStandaloneDisplayMode() {
mController = buildController(buildWebApkIntentDataProvider(WebDisplayMode.STANDALONE));
mController.updateIsInTwaMode(true);
assertEquals(BrowserControlsState.HIDDEN, getLastBrowserControlsState());
}
/**
* Browser controls should be shown for WebAPKs with 'standalone' display mode when outside of
* WebAPK's scope.
*/
@Test
public void testStandaloneDisplayModeOutOfScope() {
mController = buildController(buildWebApkIntentDataProvider(WebDisplayMode.STANDALONE));
mController.updateIsInTwaMode(true);
mController.updateIsInTwaMode(false);
assertEquals(BrowserControlsState.BOTH, getLastBrowserControlsState());
assertTrue(getLastCloseButtonVisibility());
}
/**
* Browser controls should not be shown for TWAs while in TWA mode.
*/
@Test
public void testTwa() {
mController = buildController(mock(BrowserServicesIntentDataProvider.class));
mController.updateIsInTwaMode(true);
assertEquals(BrowserControlsState.HIDDEN, getLastBrowserControlsState());
}
/**
* Browser controls should be shown for TWAs when outside of the TWA's scope.
*/
@Test
public void testTwaOutOfScope() {
mController = buildController(mock(BrowserServicesIntentDataProvider.class));
mController.updateIsInTwaMode(true);
mController.updateIsInTwaMode(false);
assertEquals(BrowserControlsState.BOTH, getLastBrowserControlsState());
assertTrue(getLastCloseButtonVisibility());
}
private void setTabSecurityLevel(int securityLevel) {
when(mTab.getSecurityLevel()).thenReturn(securityLevel);
}
private BrowserServicesIntentDataProvider buildWebApkIntentDataProvider(
@WebDisplayMode int displayMode) {
WebApkInfoBuilder webApkInfoBuilder =
new WebApkInfoBuilder("org.chromium.webapk.abcd", "https://pwa.rocks/");
webApkInfoBuilder.setDisplayMode(displayMode);
return webApkInfoBuilder.build().getProvider();
}
private TrustedWebActivityBrowserControlsVisibilityManager buildController(
BrowserServicesIntentDataProvider intentDataProvider) {
return new TrustedWebActivityBrowserControlsVisibilityManager(mTabObserverRegistrar,
mTabProvider, mToolbarCoordinator, mCloseButtonVisibilityManager,
intentDataProvider);
}
/**
* Returns the current browser controls state.
*/
private @BrowserControlsState int getLastBrowserControlsState() {
ArgumentCaptor<Integer> lastBrowserControlsState = ArgumentCaptor.forClass(Integer.class);
verify(mToolbarCoordinator, atLeast(0))
.setBrowserControlsState(lastBrowserControlsState.capture());
return lastBrowserControlsState.getAllValues().isEmpty()
? TrustedWebActivityBrowserControlsVisibilityManager.DEFAULT_BROWSER_CONTROLS_STATE
: lastBrowserControlsState.getValue();
}
/**
* Returns the current close button visibility.
*/
private boolean getLastCloseButtonVisibility() {
ArgumentCaptor<Boolean> lastCloseButtonVisiblity = ArgumentCaptor.forClass(Boolean.class);
verify(mCloseButtonVisibilityManager, atLeast(1))
.setVisibility(lastCloseButtonVisiblity.capture());
return lastCloseButtonVisiblity.getValue();
}
}