Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ec84e746 authored by Santiago Etchebehere's avatar Santiago Etchebehere
Browse files

Add initial Robolectric tests

Set up the infrastructure for tests and add a few initial Robolectric
tests for ThemePicker.

Bug: 118758604

Change-Id: Ie6f34c840d31d24349fd12355f93369f51168802
parent 8767b16b
Loading
Loading
Loading
Loading
+55 −0
Original line number Diff line number Diff line
# Copyright (C) 2019 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

#############################################
# ThenePicker Robolectric test target.      #
#############################################
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := ThemePickerRoboTests
LOCAL_SDK_VERSION := system_current
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_STATIC_JAVA_LIBRARIES := \
    androidx.test.runner \
    androidx.test.rules \
    mockito-robolectric-prebuilt \
    truth-prebuilt
LOCAL_JAVA_LIBRARIES := \
    platform-robolectric-3.6.2-prebuilt

LOCAL_JAVA_RESOURCE_DIRS := config

LOCAL_INSTRUMENTATION_FOR := ThemePicker
LOCAL_MODULE_TAGS := optional

include $(BUILD_STATIC_JAVA_LIBRARY)

############################################
# Target to run the previous target.       #
############################################
include $(CLEAR_VARS)

LOCAL_MODULE := RunThemePickerRoboTests
LOCAL_SDK_VERSION := system_current
LOCAL_JAVA_LIBRARIES := \
    ThemePickerRoboTests

LOCAL_TEST_PACKAGE := ThemePicker

LOCAL_INSTRUMENT_SOURCE_DIRS := $(dir $(LOCAL_PATH))../src \

LOCAL_ROBOTEST_TIMEOUT := 36000

include prebuilts/misc/common/robolectric/3.6.2/run_robotests.mk
+2 −0
Original line number Diff line number Diff line
manifest=vendor/unbundled_google/packages/WallpaperPickerGoogle/AndroidManifest.xml
sdk=27
+3 −0
Original line number Diff line number Diff line
# Do not include the manifest definition in this version
# as it is specified directly in the gradle file
sdk=27
 No newline at end of file
+73 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.customization.model.grid;

import static junit.framework.TestCase.fail;

import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import androidx.annotation.Nullable;

import com.android.customization.model.CustomizationManager.Callback;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;

@RunWith(RobolectricTestRunner.class)
public class GridOptionsManagerTest {

    @Mock LauncherGridOptionsProvider mProvider;
    private GridOptionsManager mManager;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mManager = new GridOptionsManager(mProvider);
    }

    @Test
    public void testApply() {
        String gridName = "testName";
        GridOption grid = new GridOption("testTitle", gridName, false, 2, 2, null, 1, "");
        when(mProvider.applyGrid(gridName)).thenReturn(1);

        mManager.apply(grid, new Callback() {
            @Override
            public void onSuccess() {
                //Nothing to do here, the test passed
            }

            @Override
            public void onError(@Nullable Throwable throwable) {
                fail("onError was called when grid had been applied successfully");
            }
        });
    }

    @Test
    public void testFetch_backgroundThread() {
        mManager.fetchOptions(null);
        Robolectric.flushBackgroundThreadScheduler();
        verify(mProvider).fetch(anyBoolean());
    }
}
+171 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.customization.model.theme;

import static com.android.customization.model.ResourceConstants.ANDROID_PACKAGE;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_COLOR;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_FONT;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_ANDROID;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SETTINGS;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SYSUI;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_SHAPE;
import static com.android.customization.model.ResourceConstants.SETTINGS_PACKAGE;
import static com.android.customization.model.ResourceConstants.SYSUI_PACKAGE;
import static com.android.customization.model.ResourceConstants.THEME_SETTING;

import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertTrue;

import static org.junit.Assert.assertFalse;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import android.app.Activity;
import android.provider.Settings;

import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;

import com.android.customization.model.CustomizationManager.Callback;
import com.android.customization.testutils.Condition;
import com.android.customization.testutils.OverlayManagerMocks;
import com.android.customization.testutils.Wait;
import com.android.wallpaper.module.WallpaperSetter;

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.Robolectric;
import org.robolectric.RobolectricTestRunner;

import java.util.Map;

@RunWith(RobolectricTestRunner.class)
public class ThemeManagerTest {

    @Mock OverlayManagerCompat mMockOm;
    @Mock WallpaperSetter mMockWallpaperSetter;
    private OverlayManagerMocks mMockOmHelper;
    private ThemeManager mThemeManager;
    private Activity mActivity;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        Activity activity = Robolectric.buildActivity(FragmentActivity.class).get();
        mActivity = spy(activity);
        mMockOmHelper = new OverlayManagerMocks();
        mMockOmHelper.setUpMock(mMockOm);
        ThemeBundleProvider provider = mock(ThemeBundleProvider.class);
        mThemeManager = new ThemeManager(provider, activity, mMockWallpaperSetter, mMockOm);
    }

    @After
    public void cleanUp() {
        mMockOmHelper.clearOverlays();
    }

    @Test
    public void testApply_DefaultTheme() {
        mMockOmHelper.addOverlay("test.package.name_color", ANDROID_PACKAGE,
                OVERLAY_CATEGORY_COLOR, true, 0);
        mMockOmHelper.addOverlay("test.package.name_font", ANDROID_PACKAGE,
                OVERLAY_CATEGORY_FONT, true, 0);
        mMockOmHelper.addOverlay("test.package.name_shape", ANDROID_PACKAGE,
                OVERLAY_CATEGORY_SHAPE, true, 0);
        mMockOmHelper.addOverlay("test.package.name_icon", ANDROID_PACKAGE,
                OVERLAY_CATEGORY_ICON_ANDROID, true, 0);
        mMockOmHelper.addOverlay("test.package.name_settings", SETTINGS_PACKAGE,
                OVERLAY_CATEGORY_ICON_SETTINGS, true, 0);
        mMockOmHelper.addOverlay("test.package.name_sysui", SYSUI_PACKAGE,
                OVERLAY_CATEGORY_ICON_SYSUI, true, 0);

        ThemeBundle defaultTheme = new ThemeBundle.Builder().asDefault().build();

        applyThemeAndWaitForCondition(defaultTheme, "Overlays didn't get disabled", () -> {
            verify(mMockOm, times(6)).disableOverlay(anyString(), anyInt());
            return true;
        });

        assertEquals("Secure Setting should be emtpy after applying default theme",
                "",
                Settings.Secure.getString(mActivity.getContentResolver(), THEME_SETTING));
    }

    @Test
    public void testApply_NonDefault() {
        final String bundleColorPackage = "test.package.name_color";
        final String bundleFontPackage = "test.package.name_font";
        final String otherPackage = "other.package.name_font";

        mMockOmHelper.addOverlay(bundleColorPackage, ANDROID_PACKAGE,
                OVERLAY_CATEGORY_COLOR, false, 0);
        mMockOmHelper.addOverlay(bundleFontPackage, ANDROID_PACKAGE,
                OVERLAY_CATEGORY_FONT, false, 0);
        mMockOmHelper.addOverlay(otherPackage, ANDROID_PACKAGE,
                OVERLAY_CATEGORY_FONT, false, 0);

        ThemeBundle theme = new ThemeBundle.Builder()
                .addOverlayPackage(OVERLAY_CATEGORY_COLOR, bundleColorPackage)
                .addOverlayPackage(OVERLAY_CATEGORY_FONT, bundleFontPackage)
                .build();

        applyThemeAndWaitForCondition(theme, "Overlays didn't get enabled", () -> {
            verify(mMockOm, times(2)).setEnabledExclusiveInCategory(anyString(), anyInt());
            Map<String, String> overlays = mMockOm.getEnabledOverlaysForTargets(ANDROID_PACKAGE);
            assertEquals(2, overlays.size());
            assertTrue(bundleColorPackage  + " should be enabled",
                    overlays.values().contains(bundleColorPackage));
            assertTrue(bundleFontPackage  + " should be enabled",
                    overlays.values().contains(bundleFontPackage));
            assertFalse(otherPackage  + " should not be enabled",
                    overlays.values().contains(otherPackage));
            return true;
        });

        assertEquals("Secure Setting was not properly set after applying theme",
                theme.getSerializedPackages(),
                Settings.Secure.getString(mActivity.getContentResolver(), THEME_SETTING));
    }

    private void applyThemeAndWaitForCondition(ThemeBundle theme, String message,
            Condition condition) {
        boolean[] done = {false, false};
        mThemeManager.apply(theme, new Callback() {
            @Override
            public void onSuccess() {
                done[0] = true;
            }

            @Override
            public void onError(@Nullable Throwable throwable) {
                done[0] = true;
                done[1] = true;
            }
        });
        // TODO: refactor these tests so we can get rid of the long wait.
        Wait.atMost(message, () -> done[0] && condition.isTrue(), 1000);
        // done[1] is only set to true in the onError callback.
        assertFalse(done[1]);
    }
}
Loading