chromium/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarCoordinatorUnitTest.java

// Copyright 2024 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.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.isNull;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import static org.chromium.chrome.browser.flags.ChromeFeatureList.SHARE_CUSTOM_ACTIONS_IN_CCT;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;

import dagger.Lazy;

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.MockitoAnnotations;
import org.robolectric.Robolectric;

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.browser.browser_controls.BrowserControlsVisibilityManager;
import org.chromium.chrome.browser.browserservices.intents.CustomButtonParams;
import org.chromium.chrome.browser.customtabs.CloseButtonVisibilityManager;
import org.chromium.chrome.browser.customtabs.CustomButtonParamsImpl;
import org.chromium.chrome.browser.customtabs.CustomTabCompositorContentInitializer;
import org.chromium.chrome.browser.customtabs.content.CustomTabActivityContentTestEnvironment;
import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabController;
import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabProvider;
import org.chromium.chrome.browser.share.ShareDelegate;
import org.chromium.chrome.browser.share.ShareDelegateSupplier;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.ui.base.ActivityWindowAndroid;
import org.chromium.url.GURL;

/** Tests for {@link CustomTabToolbarCoordinator}. */
@RunWith(BaseRobolectricTestRunner.class)
@EnableFeatures({SHARE_CUSTOM_ACTIONS_IN_CCT})
public class CustomTabToolbarCoordinatorUnitTest {
    @Rule
    public final CustomTabActivityContentTestEnvironment env =
            new CustomTabActivityContentTestEnvironment();

    @Mock private ShareDelegate mShareDelegate;
    @Mock private ShareDelegateSupplier mShareDelegateSupplier;
    @Mock private CustomTabActivityTabProvider mTabProvider;
    @Mock private ActivityWindowAndroid mActivityWindowAndroid;
    @Mock private Lazy<BrowserControlsVisibilityManager> mBrowserControlsVisibilityManager;
    @Mock private CloseButtonVisibilityManager mCloseButtonVisibilityManager;
    @Mock private CustomTabBrowserControlsVisibilityDelegate mVisibilityDelegate;
    @Mock private CustomTabCompositorContentInitializer mCompositorContentInitializer;
    @Mock private CustomTabToolbarColorController mToolbarColorController;
    @Mock private Tab mTab;
    @Mock private CustomButtonParams mCustomButtonParams;
    @Mock private PendingIntent mPendingIntent;

    private Activity mActivity;
    private CustomTabActivityTabController mTabController;
    private CustomTabToolbarCoordinator mCoordinator;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);

        mActivity = Robolectric.setupActivity(Activity.class);
        mTabController = env.createTabController();

        mCoordinator =
                new CustomTabToolbarCoordinator(
                        env.intentDataProvider,
                        mTabProvider,
                        env.connection,
                        mActivity,
                        mActivityWindowAndroid,
                        mActivity,
                        mTabController,
                        mBrowserControlsVisibilityManager,
                        env.createNavigationController(mTabController),
                        mCloseButtonVisibilityManager,
                        mVisibilityDelegate,
                        mCompositorContentInitializer,
                        mToolbarColorController);

        ShareDelegateSupplier.setInstanceForTesting(mShareDelegateSupplier);
        when(mShareDelegateSupplier.get()).thenReturn(mShareDelegate);
        when(mTabProvider.getTab()).thenReturn(mTab);
        when(mTab.getOriginalUrl()).thenReturn(GURL.emptyGURL());
        when(mTab.getTitle()).thenReturn("");
        when(mCustomButtonParams.getDescription()).thenReturn("");
        when(mCustomButtonParams.getPendingIntent()).thenReturn(mPendingIntent);
    }

    @After
    public void tearDown() {
        mActivity.finish();
    }

    private void clickButtonAndVerifyPendingIntent() {
        try {
            mCoordinator.onCustomButtonClick(mCustomButtonParams);
            verify(mShareDelegate, never()).share(any(Tab.class), eq(false), anyInt());
            verify(mPendingIntent)
                    .send(
                            eq(mActivity),
                            eq(0),
                            any(Intent.class),
                            any(),
                            isNull(),
                            isNull(),
                            any());
        } catch (PendingIntent.CanceledException e) {
            assert false;
        }
    }

    @Test
    public void testCreateShareButtonWithCustomActions() {
        int testColor = 0x99aabbcc;
        mCoordinator.onCustomButtonClick(
                CustomButtonParamsImpl.createShareButton(mActivity, testColor));
        verify(mShareDelegate)
                .share(any(), eq(false), eq(ShareDelegate.ShareOrigin.CUSTOM_TAB_SHARE_BUTTON));
    }

    @Test
    public void testCustomButtonClicked() {
        when(mCustomButtonParams.getType()).thenReturn(CustomButtonParams.ButtonType.OTHER);
        clickButtonAndVerifyPendingIntent();
    }

    @Test
    public void testNullSupplierShareButtonClick() {
        when(mCustomButtonParams.getType())
                .thenReturn(CustomButtonParams.ButtonType.CCT_SHARE_BUTTON);

        // Test null supplier.
        when(mShareDelegateSupplier.get()).thenReturn(null);
        clickButtonAndVerifyPendingIntent();
    }

    @Test
    @DisableFeatures({SHARE_CUSTOM_ACTIONS_IN_CCT})
    public void testShareWithoutCustomActions() {
        when(mCustomButtonParams.getType())
                .thenReturn(CustomButtonParams.ButtonType.CCT_SHARE_BUTTON);

        clickButtonAndVerifyPendingIntent();
    }
}