| // 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(); |
| } |
| } |