chromium/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicyTest.java

// Copyright 2015 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.contextualsearch;

import static org.mockito.Mockito.when;

import androidx.test.filters.SmallTest;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import org.chromium.base.ThreadUtils;
import org.chromium.base.test.util.Batch;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.Feature;
import org.chromium.chrome.browser.flags.ChromeSwitches;
import org.chromium.chrome.browser.preferences.Pref;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.profiles.ProfileManager;
import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory;
import org.chromium.chrome.browser.signin.services.UnifiedConsentServiceBridge;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
import org.chromium.chrome.test.batch.BlankCTATabInitialStateRule;
import org.chromium.components.prefs.PrefService;
import org.chromium.components.search_engines.TemplateUrl;
import org.chromium.components.search_engines.TemplateUrlService;
import org.chromium.components.user_prefs.UserPrefs;
import org.chromium.url.GURL;

/** Tests for the ContextualSearchPolicy class. */
@RunWith(ChromeJUnit4ClassRunner.class)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
@Batch(Batch.PER_CLASS)
public class ContextualSearchPolicyTest {
    @ClassRule
    public static ChromeTabbedActivityTestRule sActivityTestRule =
            new ChromeTabbedActivityTestRule();

    @Rule
    public BlankCTATabInitialStateRule mInitialStateRule =
            new BlankCTATabInitialStateRule(sActivityTestRule, false);

    @Mock private ContextualSearchFakeServer mMockServer;

    private ContextualSearchPolicy mPolicy;
    private Profile mProfile;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        ThreadUtils.runOnUiThreadBlocking(
                () -> {
                    mProfile = ProfileManager.getLastUsedRegularProfile();
                    mPolicy = new ContextualSearchPolicy(mProfile, null, mMockServer);
                });

        ThreadUtils.runOnUiThreadBlocking(
                () -> {
                    // Clear Prefs
                    PrefService prefService = UserPrefs.get(mProfile);
                    prefService.clearPref(Pref.CONTEXTUAL_SEARCH_ENABLED);
                    prefService.clearPref(Pref.CONTEXTUAL_SEARCH_WAS_FULLY_PRIVACY_ENABLED);
                    prefService.clearPref(Pref.CONTEXTUAL_SEARCH_PROMO_CARD_SHOWN_COUNT);
                });
    }

    @After
    public void tearDown() throws Exception {
        ThreadUtils.runOnUiThreadBlocking(
                () -> {
                    // Clear Prefs
                    PrefService prefService = UserPrefs.get(mProfile);
                    prefService.clearPref(Pref.CONTEXTUAL_SEARCH_ENABLED);
                    prefService.clearPref(Pref.CONTEXTUAL_SEARCH_WAS_FULLY_PRIVACY_ENABLED);
                    prefService.clearPref(Pref.CONTEXTUAL_SEARCH_PROMO_CARD_SHOWN_COUNT);
                });
    }

    /** Call on the UI thread to set up all the conditions needed for sending the URL. */
    private void setupAllConditionsToSendUrl() {
        mPolicy.overrideDecidedStateForTesting(true);
        UnifiedConsentServiceBridge.setUrlKeyedAnonymizedDataCollectionEnabled(mProfile, true);
        try {
            when(mMockServer.getBasePageUrl()).thenReturn(new GURL("https://someUrl"));
        } catch (Exception e) {
            Assert.fail("Exception raised building a sample URL");
        }
    }

    @Test
    @SmallTest
    @Feature({"ContextualSearch"})
    public void testDoSendBasePageUrlDefaultCase() {
        // We don't send the URL by default.
        ThreadUtils.runOnUiThreadBlocking(() -> Assert.assertFalse(mPolicy.doSendBasePageUrl()));
    }

    @Test
    @SmallTest
    @Feature({"ContextualSearch"})
    public void testDoSendBasePageUrlEnabledCase() {
        // Test that we do send the URL when all the requirements are enabled.
        ThreadUtils.runOnUiThreadBlocking(
                () -> {
                    setupAllConditionsToSendUrl();
                    Assert.assertTrue(mPolicy.doSendBasePageUrl());
                });
    }

    @Test
    @SmallTest
    @Feature({"ContextualSearch"})
    public void testDoSendBasePageUrlWhenNotOptedIn() {
        ThreadUtils.runOnUiThreadBlocking(
                () -> {
                    setupAllConditionsToSendUrl();
                    mPolicy.overrideDecidedStateForTesting(false);
                    Assert.assertFalse(mPolicy.doSendBasePageUrl());
                });
    }

    @Test
    @SmallTest
    @Feature({"ContextualSearch"})
    public void testDoSendBasePageUrlWhenNotMakingSearchAndBrowsingBetter() {
        ThreadUtils.runOnUiThreadBlocking(
                () -> {
                    setupAllConditionsToSendUrl();
                    UnifiedConsentServiceBridge.setUrlKeyedAnonymizedDataCollectionEnabled(
                            mProfile, false);
                    Assert.assertFalse(mPolicy.doSendBasePageUrl());
                });
    }

    @Test
    @SmallTest
    @Feature({"ContextualSearch"})
    public void testDoSendBasePageUrlWhenFtpProtocol() {
        ThreadUtils.runOnUiThreadBlocking(
                () -> {
                    setupAllConditionsToSendUrl();
                    try {
                        when(mMockServer.getBasePageUrl()).thenReturn(new GURL("ftp://someSource"));
                    } catch (Exception e) {
                        Assert.fail("Exception building FTP Uri");
                    }
                    Assert.assertFalse(mPolicy.doSendBasePageUrl());
                });
    }

    @Test
    @SmallTest
    @Feature({"ContextualSearch"})
    public void testDoSendBasePageUrlWhenNonGoogleSearchEngine() {
        ThreadUtils.runOnUiThreadBlocking(
                () -> {
                    TemplateUrlService templateUrlService =
                            TemplateUrlServiceFactory.getForProfile(mProfile);
                    TemplateUrl defaultSearchEngine =
                            templateUrlService.getDefaultSearchEngineTemplateUrl();
                    setupAllConditionsToSendUrl();
                    templateUrlService.setSearchEngine("yahoo.com");
                    Assert.assertFalse(mPolicy.doSendBasePageUrl());
                    // Set default search engine back to default to prevent cross-talk from
                    // this test which sets it to Yahoo
                    templateUrlService.setSearchEngine(defaultSearchEngine.getShortName());
                });
    }

    @Test
    @SmallTest
    @Feature({"ContextualSearch"})
    public void testIsUserUndecided_Disable() {
        ThreadUtils.runOnUiThreadBlocking(
                () -> {
                    Assert.assertTrue(mPolicy.isUserUndecided());
                    ContextualSearchPolicy.setContextualSearchFullyOptedIn(mProfile, false);
                    Assert.assertFalse(mPolicy.isUserUndecided());
                    Assert.assertTrue(
                            ContextualSearchPolicy.isContextualSearchUninitialized(mProfile));
                });
    }

    @Test
    @SmallTest
    @Feature({"ContextualSearch"})
    public void testIsUserUndecided_Enable() {
        ThreadUtils.runOnUiThreadBlocking(
                () -> {
                    Assert.assertTrue(mPolicy.isUserUndecided());
                    ContextualSearchPolicy.setContextualSearchFullyOptedIn(mProfile, true);
                    Assert.assertFalse(mPolicy.isUserUndecided());
                    Assert.assertTrue(ContextualSearchPolicy.isContextualSearchEnabled(mProfile));
                });
    }

    @Test
    @SmallTest
    @Feature({"ContextualSearch"})
    public void testIsPromoAvailable() {
        ThreadUtils.runOnUiThreadBlocking(
                () -> {
                    Assert.assertTrue(mPolicy.isPromoAvailable());
                    Assert.assertEquals(
                            0,
                            ContextualSearchPolicy.getContextualSearchPromoCardShownCount(
                                    mProfile));

                    // Promo show 1 time and promo is still available.
                    ContextualSearchPolicy.onPromoShown(mProfile);
                    Assert.assertTrue(mPolicy.isPromoAvailable());
                    Assert.assertEquals(
                            1,
                            ContextualSearchPolicy.getContextualSearchPromoCardShownCount(
                                    mProfile));

                    // After promo show 3 times, promo is not available.
                    ContextualSearchPolicy.onPromoShown(mProfile);
                    ContextualSearchPolicy.onPromoShown(mProfile);
                    Assert.assertFalse(mPolicy.isPromoAvailable());
                    Assert.assertEquals(
                            3,
                            ContextualSearchPolicy.getContextualSearchPromoCardShownCount(
                                    mProfile));
                });
    }

    @Test
    @SmallTest
    @Feature({"ContextualSearch"})
    public void testIsContextualSearchFullyOptedIn() {
        ThreadUtils.runOnUiThreadBlocking(
                () -> {
                    // Default is not fully opted in.
                    Assert.assertFalse(
                            ContextualSearchPolicy.isContextualSearchPrefFullyOptedIn(mProfile));

                    // Choose not to opt in.
                    ContextualSearchPolicy.setContextualSearchFullyOptedIn(mProfile, false);
                    Assert.assertFalse(
                            ContextualSearchPolicy.isContextualSearchPrefFullyOptedIn(mProfile));

                    // Choose to opt in.
                    ContextualSearchPolicy.setContextualSearchFullyOptedIn(mProfile, true);
                    Assert.assertTrue(
                            ContextualSearchPolicy.isContextualSearchPrefFullyOptedIn(mProfile));
                });
    }

    @Test
    @SmallTest
    @Feature({"ContextualSearch"})
    public void testSetContextualSearchFullyOptedIn() {
        ThreadUtils.runOnUiThreadBlocking(
                () -> {
                    // Default is not fully opted in.
                    Assert.assertFalse(
                            ContextualSearchPolicy.isContextualSearchPrefFullyOptedIn(mProfile));

                    // Choose to fully opt in.
                    ContextualSearchPolicy.setContextualSearchFullyOptedIn(mProfile, true);
                    Assert.assertTrue(
                            ContextualSearchPolicy.isContextualSearchPrefFullyOptedIn(mProfile));

                    // Choose to disable Contextual Search.
                    ContextualSearchPolicy.setContextualSearchState(mProfile, false);
                    // The Contextual Search pref is disabled, but opt-in pref should still be
                    // enabled since it is not disabled explicitly.
                    Assert.assertTrue(ContextualSearchPolicy.isContextualSearchDisabled(mProfile));
                    Assert.assertTrue(
                            ContextualSearchPolicy.isContextualSearchPrefFullyOptedIn(mProfile));

                    // Enable the Contextual Search again.
                    ContextualSearchPolicy.setContextualSearchState(mProfile, true);
                    Assert.assertTrue(
                            ContextualSearchPolicy.isContextualSearchPrefFullyOptedIn(mProfile));
                });
    }

    @Test
    @SmallTest
    @Feature({"ContextualSearch"})
    public void testShouldPreviousGestureResolve() {
        ThreadUtils.runOnUiThreadBlocking(
                () -> {
                    Assert.assertFalse(mPolicy.shouldPreviousGestureResolve());

                    ContextualSearchPolicy.setContextualSearchFullyOptedIn(mProfile, true);
                    Assert.assertTrue(mPolicy.shouldPreviousGestureResolve());

                    ContextualSearchPolicy.setContextualSearchFullyOptedIn(mProfile, false);
                    Assert.assertFalse(mPolicy.shouldPreviousGestureResolve());
                });
    }

    @Test
    @SmallTest
    @Feature({"ContextualSearch"})
    public void testIsContextualSearchFullyEnabled() {
        ThreadUtils.runOnUiThreadBlocking(
                () -> {
                    Assert.assertFalse(mPolicy.isContextualSearchFullyEnabled());

                    ContextualSearchPolicy.setContextualSearchFullyOptedIn(mProfile, true);
                    Assert.assertTrue(mPolicy.isContextualSearchFullyEnabled());

                    ContextualSearchPolicy.setContextualSearchFullyOptedIn(mProfile, false);
                    Assert.assertFalse(mPolicy.isContextualSearchFullyEnabled());
                });
    }
    // TODO(donnd): This set of tests is not complete, add more tests.
}