chromium/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxBridgeTest.java

// Copyright 2022 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.privacy_sandbox;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import androidx.annotation.Nullable;
import androidx.test.filters.SmallTest;

import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;

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.PayloadCallbackHelper;
import org.chromium.base.test.util.UserActionTester;
import org.chromium.chrome.browser.flags.ChromeSwitches;
import org.chromium.chrome.browser.profiles.ProfileManager;
import org.chromium.chrome.test.ChromeBrowserTestRule;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;

import java.util.List;

/** Tests for PrivacySandboxBridge. */
@RunWith(ChromeJUnit4ClassRunner.class)
@CommandLineFlags.Add({
    ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
    "enable-features=PrivacySandboxSettings4:show-sample-data/true"
})
@Batch(Batch.PER_CLASS)
public class PrivacySandboxBridgeTest {
    @ClassRule
    public static final ChromeBrowserTestRule sBrowserTestRule = new ChromeBrowserTestRule();

    private PrivacySandboxBridge mPrivacySandboxBridge;
    private UserActionTester mUserActionTester;

    @Before
    public void setUp() {
        mPrivacySandboxBridge =
                ThreadUtils.runOnUiThreadBlocking(
                        () -> new PrivacySandboxBridge(ProfileManager.getLastUsedRegularProfile()));
    }

    @Test
    @SmallTest
    public void testNoDialogWhenFreDisabled() {
        // Check that when ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE is present, the bridge
        // returns that no dialog is shown. This is important to prevent tests that rely on using
        // that flag to get a blank activity with no dialogs from breaking.
        ThreadUtils.runOnUiThreadBlocking(
                () ->
                        assertEquals(
                                "Returned dialog type",
                                PromptType.NONE,
                                mPrivacySandboxBridge.getRequiredPromptType(SurfaceType.BR_APP)));
    }

    @Test
    @SmallTest
    public void testGetCurrentTopics() {
        // Check that this function returns a valid list. We currently can't control from the Java
        // side what they actually return, so just check that it is not null and there is no crash.
        ThreadUtils.runOnUiThreadBlocking(
                () -> assertNotNull(mPrivacySandboxBridge.getCurrentTopTopics()));
    }

    @Test
    @SmallTest
    public void testBlockedTopics() {
        // Check that this function returns a valid list. We currently can't control from the Java
        // side what they actually return, so just check that it is not null and there is no crash.
        ThreadUtils.runOnUiThreadBlocking(
                () -> assertNotNull(mPrivacySandboxBridge.getBlockedTopics()));
    }

    @Test
    @SmallTest
    public void testFakeTopics() {
        Topic topic1 = new Topic(1, 1, "Arts & entertainment");
        Topic topic2 = new Topic(2, 1, "Acting & theater");
        Topic topic3 = new Topic(3, 1, "Comics");
        Topic topic4 = new Topic(4, 1, "Concerts & music festivals");

        ThreadUtils.runOnUiThreadBlocking(
                () -> {
                    mPrivacySandboxBridge.setAllPrivacySandboxAllowedForTesting();
                    assertThat(
                            mPrivacySandboxBridge.getCurrentTopTopics(), contains(topic2, topic1));
                    assertThat(mPrivacySandboxBridge.getBlockedTopics(), contains(topic3, topic4));
                    mPrivacySandboxBridge.setTopicAllowed(topic1, false);
                    assertThat(mPrivacySandboxBridge.getCurrentTopTopics(), contains(topic2));
                    assertThat(
                            mPrivacySandboxBridge.getBlockedTopics(),
                            contains(topic1, topic3, topic4));
                    mPrivacySandboxBridge.setTopicAllowed(topic4, true);
                    assertThat(
                            mPrivacySandboxBridge.getCurrentTopTopics(), contains(topic2, topic4));
                    assertThat(mPrivacySandboxBridge.getBlockedTopics(), contains(topic1, topic3));
                });
    }

    @Nullable
    private List<String> getFledgeJoiningEtlds() {
        PayloadCallbackHelper<List<String>> callbackHelper = new PayloadCallbackHelper<>();
        ThreadUtils.runOnUiThreadBlocking(
                () ->
                        mPrivacySandboxBridge.getFledgeJoiningEtldPlusOneForDisplay(
                                callbackHelper::notifyCalled));
        return callbackHelper.getOnlyPayloadBlocking();
    }

    @Test
    @SmallTest
    public void testGetFledgeJoiningEtldPlusOneForDisplay() {
        // Check that this function returns a valid list. We currently can't control from the Java
        // side what they actually return, so just check that it is not null and there is no crash.
        assertNotNull(getFledgeJoiningEtlds());
    }

    @Test
    @SmallTest
    public void testGetBlockedFledgeJoiningTopFramesForDisplay() {
        // Check that this function returns a valid list. We currently can't control from the Java
        // side what they actually return, so just check that it is not null and there is no crash.
        ThreadUtils.runOnUiThreadBlocking(
                () ->
                        assertNotNull(
                                mPrivacySandboxBridge
                                        .getBlockedFledgeJoiningTopFramesForDisplay()));
    }

    @Test
    @SmallTest
    public void testFledgeBlocking() {
        String site1 = "a.com";
        String site2 = "b.com";
        String site3 = "c.com";

        ThreadUtils.runOnUiThreadBlocking(
                () -> {
                    mPrivacySandboxBridge.setFledgeJoiningAllowed(site1, false);
                    assertThat(
                            mPrivacySandboxBridge.getBlockedFledgeJoiningTopFramesForDisplay(),
                            contains(site1));

                    mPrivacySandboxBridge.setFledgeJoiningAllowed(site2, false);
                    mPrivacySandboxBridge.setFledgeJoiningAllowed(site3, false);
                    assertThat(
                            mPrivacySandboxBridge.getBlockedFledgeJoiningTopFramesForDisplay(),
                            contains(site1, site2, site3));

                    mPrivacySandboxBridge.setFledgeJoiningAllowed(site2, true);
                    assertThat(
                            mPrivacySandboxBridge.getBlockedFledgeJoiningTopFramesForDisplay(),
                            contains(site1, site3));
                });
    }

    @Test
    @SmallTest
    public void testPromptActionOccuredRecordsUserAction() {
        mUserActionTester = new UserActionTester();

        ThreadUtils.runOnUiThreadBlocking(
                () -> {
                    mPrivacySandboxBridge.promptActionOccurred(
                            PromptAction.CONSENT_SHOWN, SurfaceType.BR_APP);
                    assertTrue(
                            mUserActionTester
                                    .getActions()
                                    .contains("Settings.PrivacySandbox.Consent.Shown"));
                });
    }
}