chromium/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/InstalledWebappDataRecorderTest.java

// Copyright 2018 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.browserservices;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;

import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.base.test.util.Feature;
import org.chromium.components.embedder_support.util.Origin;
import org.chromium.components.embedder_support.util.ShadowUrlUtilities;

/** Tests for {@link InstalledWebappDataRecorder}. */
@RunWith(BaseRobolectricTestRunner.class)
@Config(
        manifest = Config.NONE,
        shadows = {ShadowUrlUtilities.class})
public class InstalledWebappDataRecorderTest {
    private static final int APP_UID = 123;
    private static final String APP_NAME = "Example App";
    private static final String APP_PACKAGE = "com.example.app";
    private static final String MISSING_PACKAGE = "com.missing.app";
    private static final Origin ORIGIN = Origin.create("https://www.example.com/");
    private static final Origin OTHER_ORIGIN = Origin.create("https://www.other.com/");

    @Mock private InstalledWebappDataRegister mRegister;
    @Mock private PackageManager mPackageManager;

    private InstalledWebappDataRecorder mRecorder;

    private static String transform(String origin) {
        // Just an arbitrary string transformation so we can check it is applied.
        return origin.toUpperCase();
    }

    @Before
    public void setUp() throws PackageManager.NameNotFoundException {
        MockitoAnnotations.initMocks(this);

        ApplicationInfo appInfo = new ApplicationInfo();
        appInfo.uid = APP_UID;

        // Even though we're not actually calling getApplicationInfo here, the code needs to deal
        // with a checked exception.
        doReturn(appInfo).when(mPackageManager).getApplicationInfo(eq(APP_PACKAGE), anyInt());
        doReturn(APP_NAME).when(mPackageManager).getApplicationLabel(appInfo);

        doThrow(new PackageManager.NameNotFoundException())
                .when(mPackageManager)
                .getApplicationInfo(eq(MISSING_PACKAGE), anyInt());

        Context context = mock(Context.class);
        when(context.getPackageManager()).thenReturn(mPackageManager);

        ShadowUrlUtilities.setTestImpl(
                new ShadowUrlUtilities.TestImpl() {
                    @Override
                    public String getDomainAndRegistry(
                            String uri, boolean includePrivateRegistries) {
                        return transform(uri);
                    }
                });

        mRecorder = new InstalledWebappDataRecorder(context, mRegister);
    }

    @After
    public void tearDown() {
        ShadowUrlUtilities.reset();
    }

    @Test
    @Feature("TrustedWebActivities")
    public void testRegister() {
        mRecorder.register(APP_PACKAGE, ORIGIN);
        verifyRegistration(ORIGIN);
    }

    @Test
    @Feature("TrustedWebActivities")
    public void testDeduplicate() {
        mRecorder.register(APP_PACKAGE, ORIGIN);
        mRecorder.register(APP_PACKAGE, ORIGIN);
        verifyRegistration(ORIGIN);
    }

    @Test
    @Feature("TrustedWebActivities")
    public void testDifferentOrigins() {
        mRecorder.register(APP_PACKAGE, ORIGIN);
        mRecorder.register(APP_PACKAGE, OTHER_ORIGIN);
        verifyRegistration(ORIGIN);
        verifyRegistration(OTHER_ORIGIN);
    }

    @Test
    @Feature("TrustedWebActivities")
    public void testMisingPackage() {
        mRecorder.register(MISSING_PACKAGE, ORIGIN);
        // Implicitly checking we don't throw.
        verify(mRegister, never())
                .registerPackageForOrigin(anyInt(), anyString(), anyString(), any(), any());
    }

    private void verifyRegistration(Origin origin) {
        verify(mRegister)
                .registerPackageForOrigin(
                        APP_UID, APP_NAME, APP_PACKAGE, transform(origin.toString()), origin);
    }
}