chromium/chrome/browser/ui/android/default_browser_promo/java/src/org/chromium/chrome/browser/ui/default_browser_promo/DefaultBrowserPromoManagerTest.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.default_browser_promo;

import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.Activity;
import android.app.role.RoleManager;
import android.content.Context;
import android.content.Intent;

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.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.base.test.util.Batch;
import org.chromium.base.test.util.Features.EnableFeatures;
import org.chromium.base.test.util.HistogramWatcher;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.ui.default_browser_promo.DefaultBrowserPromoUtils.DefaultBrowserState;
import org.chromium.ui.base.WindowAndroid;
import org.chromium.ui.base.WindowAndroid.IntentCallback;

/** Test whether metrics are correctly recorded by {@link DefaultBrowserPromoManager}. */
@RunWith(BaseRobolectricTestRunner.class)
@Batch(Batch.UNIT_TESTS)
@EnableFeatures(ChromeFeatureList.DEFAULT_BROWSER_PROMO_ANDROID)
public class DefaultBrowserPromoManagerTest {

    @Mock WindowAndroid mWindowAndroid;
    @Mock Activity mActivity;
    @Mock RoleManager mRoleManager;
    @Mock Intent mIntent;
    @Mock DefaultBrowserPromoImpressionCounter mImpressionCounter;
    @Mock DefaultBrowserStateProvider mStateProvider;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        doReturn(mRoleManager).when(mActivity).getSystemService(Context.ROLE_SERVICE);
        doReturn(mIntent).when(mRoleManager).createRequestRoleIntent(RoleManager.ROLE_BROWSER);
    }

    @Test
    public void testRecordWhenNoDefault_OutcomeNoDefault() {
        testRecord(DefaultBrowserState.NO_DEFAULT, DefaultBrowserState.NO_DEFAULT);
    }

    @Test
    public void testRecordWhenNoDefault_OutcomeOtherDefault() {
        testRecord(DefaultBrowserState.NO_DEFAULT, DefaultBrowserState.OTHER_DEFAULT);
    }

    @Test
    public void testRecordWhenNoDefault_OutcomeChromeDefault() {
        testRecord(DefaultBrowserState.NO_DEFAULT, DefaultBrowserState.CHROME_DEFAULT);
    }

    @Test
    public void testRecordWhenOtherDefault_OutComeNoDefault() {
        testRecord(DefaultBrowserState.OTHER_DEFAULT, DefaultBrowserState.NO_DEFAULT);
    }

    @Test
    public void testRecordWhenOtherDefault_OutComeOtherDefault() {
        testRecord(DefaultBrowserState.OTHER_DEFAULT, DefaultBrowserState.OTHER_DEFAULT);
    }

    @Test
    public void testRecordWhenOtherDefault_OutComeChromeDefault() {
        testRecord(DefaultBrowserState.OTHER_DEFAULT, DefaultBrowserState.CHROME_DEFAULT);
    }

    @Test
    public void testRecordWhenNoDefault_OutcomeChromeDefault_FirstPromo() {
        when(mImpressionCounter.getPromoCount()).thenReturn(1);
        testRecord(
                DefaultBrowserState.OTHER_DEFAULT,
                DefaultBrowserState.CHROME_DEFAULT,
                "Android.DefaultBrowserPromo.Outcome.OtherDefault.FirstPromo");
    }

    @Test
    public void testRecordWhenNoDefault_OutcomeChromeDefault_SecondPromo() {
        when(mImpressionCounter.getPromoCount()).thenReturn(2);
        testRecord(
                DefaultBrowserState.OTHER_DEFAULT,
                DefaultBrowserState.CHROME_DEFAULT,
                "Android.DefaultBrowserPromo.Outcome.OtherDefault.SecondPromo");
    }

    @Test
    public void testRecordWhenNoDefault_OutcomeChromeDefault_ThirdPromo() {
        when(mImpressionCounter.getPromoCount()).thenReturn(3);
        testRecord(
                DefaultBrowserState.OTHER_DEFAULT,
                DefaultBrowserState.CHROME_DEFAULT,
                "Android.DefaultBrowserPromo.Outcome.OtherDefault.ThirdPromo");
    }

    @Test
    public void testRecordWhenNoDefault_OutcomeChromeDefault_FourthPromo() {
        when(mImpressionCounter.getPromoCount()).thenReturn(4);
        testRecord(
                DefaultBrowserState.OTHER_DEFAULT,
                DefaultBrowserState.CHROME_DEFAULT,
                "Android.DefaultBrowserPromo.Outcome.OtherDefault.FourthPromo");
    }

    @Test
    public void testRecordWhenNoDefault_OutcomeChromeDefault_SixthPromo() {
        when(mImpressionCounter.getPromoCount()).thenReturn(6);
        testRecord(
                DefaultBrowserState.OTHER_DEFAULT,
                DefaultBrowserState.CHROME_DEFAULT,
                "Android.DefaultBrowserPromo.Outcome.OtherDefault.FifthOrMorePromo");
    }

    private void testRecord(
            @DefaultBrowserState int currentState, @DefaultBrowserState int outcomeState) {
        testRecord(currentState, outcomeState, null);
    }

    private void testRecord(
            @DefaultBrowserState int currentState,
            @DefaultBrowserState int outcomeState,
            String extraHistogram) {
        var manager =
                new DefaultBrowserPromoManager(
                        mActivity, mWindowAndroid, mImpressionCounter, mStateProvider);

        String outcomeHistogram =
                currentState == DefaultBrowserState.NO_DEFAULT
                        ? "Android.DefaultBrowserPromo.Outcome.NoDefault"
                        : "Android.DefaultBrowserPromo.Outcome.OtherDefault";

        var histogramBuilder =
                HistogramWatcher.newBuilder()
                        .expectIntRecord(
                                "Android.DefaultBrowserPromo.RoleManagerShown", currentState)
                        .expectIntRecord(outcomeHistogram, outcomeState);
        if (extraHistogram != null) {
            histogramBuilder.expectIntRecord(extraHistogram, outcomeState);
        }
        var histogram = histogramBuilder.build();

        doReturn(1).when(mWindowAndroid).showCancelableIntent(any(Intent.class), any(), any());
        when(mStateProvider.getCurrentDefaultBrowserState()).thenReturn(currentState, outcomeState);
        ArgumentCaptor<IntentCallback> onShowCallbackCaptor =
                ArgumentCaptor.forClass(IntentCallback.class);
        manager.promoByRoleManager();
        verify(mWindowAndroid)
                .showCancelableIntent(eq(mIntent), onShowCallbackCaptor.capture(), any());
        onShowCallbackCaptor.getValue().onIntentCompleted(1, null);
        histogram.assertExpected("BrowserState is not correctly recorded");
    }
}