chromium/chrome/browser/ui/android/plus_addresses/junit/src/org/chromium/chrome/browser/ui/plus_addresses/PlusAddressCreationViewBridgeTest.java

// Copyright 2023 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.ui.plus_addresses;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;

import android.app.Activity;

import androidx.test.filters.SmallTest;

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.robolectric.annotation.Config;

import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.base.test.util.JniMocker;
import org.chromium.chrome.browser.layouts.LayoutManagerAppUtils;
import org.chromium.chrome.browser.layouts.ManagedLayoutManager;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.test.util.browser.tabmodel.MockTabModel;
import org.chromium.components.browser_ui.bottomsheet.BottomSheetControllerFactory;
import org.chromium.components.browser_ui.bottomsheet.ManagedBottomSheetController;
import org.chromium.ui.base.TestActivity;
import org.chromium.ui.base.WindowAndroid;
import org.chromium.url.GURL;

@RunWith(BaseRobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class PlusAddressCreationViewBridgeTest {
    private static final long NATIVE_PLUS_ADDRESS_CREATION_VIEW = 100L;
    private static final String MODAL_TITLE = "lorem ipsum title";
    private static final String MODAL_PLUS_ADDRESS_DESCRIPTION = "lorem ipsum description";
    private static final String MODAL_PLUS_ADDRESS_NOTICE =
            "lorem ipsum description <link>test link</link> <b>test bold</b>";
    private static final String MODAL_PROPOSED_PLUS_ADDRESS_PLACEHOLDER = "placeholder";
    private static final String MODAL_OK = "ok";
    private static final String MODAL_CANCEL = "cancel";
    private static final String MODAL_PROPOSED_PLUS_ADDRESS = "[email protected]";
    private static final String MODAL_ERROR_MESSAGE = "error! <link>test link</link>";
    private static final String LEARN_MORE_URL = "learn.more.com";
    private static final String ERROR_URL = "bug.com";
    private static final boolean REFRESH_SUPPORTED = true;

    @Rule public JniMocker mJniMocker = new JniMocker();
    @Mock private Profile mProfile;
    @Mock private PlusAddressCreationViewBridge.Natives mBridgeNatives;
    @Mock private ManagedBottomSheetController mBottomSheetController;
    @Mock private ManagedLayoutManager mLayoutManager;
    @Mock private TabModelSelector mTabModelSelector;
    @Mock private PlusAddressCreationCoordinator mCoordinator;
    @Mock private PlusAddressCreationViewBridge.CoordinatorFactory mCoordinatorFactory;

    private Activity mActivity;
    private MockTabModel mTabModel;
    private WindowAndroid mWindow;
    private PlusAddressCreationViewBridge mPlusAddressCreationViewBridge;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mActivity = Robolectric.setupActivity(TestActivity.class);
        mWindow = new WindowAndroid(mActivity);
        mTabModel = new MockTabModel(mProfile, null);
        BottomSheetControllerFactory.attach(mWindow, mBottomSheetController);
        LayoutManagerAppUtils.attach(mWindow, mLayoutManager);
        mPlusAddressCreationViewBridge =
                new PlusAddressCreationViewBridge(
                        NATIVE_PLUS_ADDRESS_CREATION_VIEW,
                        mWindow,
                        mTabModel,
                        mTabModelSelector,
                        mCoordinatorFactory);
        mPlusAddressCreationViewBridge.setActivityForTesting(mActivity);
        mJniMocker.mock(PlusAddressCreationViewBridgeJni.TEST_HOOKS, mBridgeNatives);
    }

    @After
    public void tearDown() {
        BottomSheetControllerFactory.detach(mBottomSheetController);
        LayoutManagerAppUtils.detach(mLayoutManager);
        mWindow.destroy();
    }

    private void setupCoordinatorFactory() {
        when(mCoordinatorFactory.create(
                        mActivity,
                        mBottomSheetController,
                        mLayoutManager,
                        mTabModel,
                        mTabModelSelector,
                        mPlusAddressCreationViewBridge,
                        MODAL_TITLE,
                        MODAL_PLUS_ADDRESS_DESCRIPTION,
                        MODAL_PLUS_ADDRESS_NOTICE,
                        MODAL_PROPOSED_PLUS_ADDRESS_PLACEHOLDER,
                        MODAL_OK,
                        MODAL_CANCEL,
                        MODAL_ERROR_MESSAGE,
                        REFRESH_SUPPORTED,
                        new GURL(LEARN_MORE_URL),
                        new GURL(ERROR_URL)))
                .thenReturn(mCoordinator);
    }

    private void showBottomSheet() {
        mPlusAddressCreationViewBridge.show(
                MODAL_TITLE,
                MODAL_PLUS_ADDRESS_DESCRIPTION,
                MODAL_PLUS_ADDRESS_NOTICE,
                MODAL_PROPOSED_PLUS_ADDRESS_PLACEHOLDER,
                MODAL_OK,
                MODAL_CANCEL,
                MODAL_ERROR_MESSAGE,
                LEARN_MORE_URL,
                ERROR_URL,
                REFRESH_SUPPORTED);
    }

    @Test
    @SmallTest
    public void testRequestShowContent_requestsShowOnCoordinator() {
        setupCoordinatorFactory();
        showBottomSheet();
        verify(mCoordinator, times(1)).requestShowContent();
    }

    @Test
    @SmallTest
    public void testDestroy_callsCoordinatorDestroy() {
        setupCoordinatorFactory();
        showBottomSheet();
        mPlusAddressCreationViewBridge.destroy();
        verify(mCoordinator, times(1)).destroy();
    }

    @Test
    @SmallTest
    public void testDestroyTwice_destroysCoordinatorOnce() {
        setupCoordinatorFactory();
        showBottomSheet();

        mPlusAddressCreationViewBridge.destroy();
        mPlusAddressCreationViewBridge.destroy();

        verify(mCoordinator, times(1)).destroy();
    }

    @Test
    @SmallTest
    public void testOnRefreshClicked_callsNativeOnRefreshClicked() {
        mPlusAddressCreationViewBridge.onRefreshClicked();
        verify(mBridgeNatives).onRefreshClicked(eq(NATIVE_PLUS_ADDRESS_CREATION_VIEW), any());
    }

    @Test
    @SmallTest
    public void testRefreshClicked_doesNotCallNative_afterDestroy() {
        mPlusAddressCreationViewBridge.destroy();
        mPlusAddressCreationViewBridge.onRefreshClicked();
        verifyNoInteractions(mBridgeNatives);
    }

    @Test
    @SmallTest
    public void testOnConfirmRequested_callsNativeOnConfirmRequested() {
        mPlusAddressCreationViewBridge.onConfirmRequested();
        verify(mBridgeNatives, times(1))
                .onConfirmRequested(eq(NATIVE_PLUS_ADDRESS_CREATION_VIEW), any());
    }

    @Test
    @SmallTest
    public void testOnConfirmRequested_doesNotCallNative_afterDestroy() {
        mPlusAddressCreationViewBridge.destroy();
        mPlusAddressCreationViewBridge.onConfirmRequested();
        verifyNoInteractions(mBridgeNatives);
    }

    @Test
    @SmallTest
    public void testOnCanceled_callsNativeOnCanceled() {
        mPlusAddressCreationViewBridge.onCanceled();
        verify(mBridgeNatives, times(1)).onCanceled(eq(NATIVE_PLUS_ADDRESS_CREATION_VIEW), any());
    }

    @Test
    @SmallTest
    public void testOnUiCanceled_doesNotCallNative_afterDestroy() {
        mPlusAddressCreationViewBridge.destroy();
        mPlusAddressCreationViewBridge.onCanceled();
        verifyNoInteractions(mBridgeNatives);
    }

    @Test
    @SmallTest
    public void testOnPromptDismissed_callsNativePromptDismissed() {
        mPlusAddressCreationViewBridge.onPromptDismissed();
        verify(mBridgeNatives, times(1))
                .promptDismissed(eq(NATIVE_PLUS_ADDRESS_CREATION_VIEW), any());
    }

    @Test
    @SmallTest
    public void testOnUiIgnored_doesNotCallNative_afterDestroy() {
        mPlusAddressCreationViewBridge.destroy();
        mPlusAddressCreationViewBridge.onPromptDismissed();
        verifyNoInteractions(mBridgeNatives);
    }

    @Test
    @SmallTest
    public void testUpdateProposedPlusAddress_withPlusAddress_callsCoordinator() {
        setupCoordinatorFactory();
        showBottomSheet();
        mPlusAddressCreationViewBridge.updateProposedPlusAddress(MODAL_PROPOSED_PLUS_ADDRESS);
        verify(mCoordinator, times(1)).updateProposedPlusAddress(MODAL_PROPOSED_PLUS_ADDRESS);
    }

    @Test
    @SmallTest
    public void testShowError_callsCoordinator() {
        setupCoordinatorFactory();
        showBottomSheet();
        mPlusAddressCreationViewBridge.showError();
        verify(mCoordinator, times(1)).showError();
    }

    @Test
    @SmallTest
    public void testHideRefreshButton_callsCoordinator() {
        setupCoordinatorFactory();
        showBottomSheet();
        mPlusAddressCreationViewBridge.hideRefreshButton();
        verify(mCoordinator).hideRefreshButton();
    }

    @Test
    @SmallTest
    public void testFinishConfirm_callsCoordinator() {
        setupCoordinatorFactory();
        showBottomSheet();
        mPlusAddressCreationViewBridge.finishConfirm();
        verify(mCoordinator, times(1)).finishConfirm();
    }

    @Test
    @SmallTest
    public void testwhenCoordinatorHasNotBeenCreated() {
        mPlusAddressCreationViewBridge.updateProposedPlusAddress(MODAL_PROPOSED_PLUS_ADDRESS);
        mPlusAddressCreationViewBridge.showError();
        mPlusAddressCreationViewBridge.finishConfirm();
        mPlusAddressCreationViewBridge.destroy();
        verifyNoInteractions(mCoordinator);
    }
}