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

Commit cf36d22d authored by Christian Göllner's avatar Christian Göllner
Browse files

Fix and re-enable QSFragmentTest

QSFragmentTest has been disabled for a long time, as it is failing.
QSFragment is a crucial component of SysUI and should have tests.

The fix was to make sure all dependencies are correctly set up.
This also applied to the layout inflater and views. By default the
code was inflating the real view, and some of the sub-views have
dependencies that were not there.

Fixes: 227167398
Test: QSFragmentTest passes
Change-Id: I0a0a23c4e5b023d1178d9f96a561730051cd98aa
parent 18f93518
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -262,17 +262,23 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
        if (mListening) {
            setListening(false);
        }
        if (mQSCustomizerController != null) {
            mQSCustomizerController.setQs(null);
        }
        mScrollListener = null;
        if (mContainer != null) {
            mDumpManager.unregisterDumpable(mContainer.getClass().getName());
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean(EXTRA_EXPANDED, mQsExpanded);
        outState.putBoolean(EXTRA_LISTENING, mListening);
        if (mQSCustomizerController != null) {
            mQSCustomizerController.saveInstanceState(outState);
        }
        if (mQsExpanded) {
            mQSPanelController.getTileLayout().saveInstanceState(outState);
        }
+87 −43
Original line number Diff line number Diff line
@@ -14,37 +14,37 @@

package com.android.systemui.qs;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

import android.app.Fragment;
import android.content.Context;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.testing.AndroidTestingRunner;
import android.testing.LayoutInflaterBuilder;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.view.ViewGroup;

import androidx.test.filters.SmallTest;
import androidx.test.filters.Suppress;

import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
import com.android.keyguard.CarrierText;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.SysuiBaseFragmentTest;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.media.MediaHost;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.customize.QSCustomizerController;
import com.android.systemui.qs.dagger.QSFragmentComponent;
import com.android.systemui.qs.external.CustomTileStatePersister;
import com.android.systemui.qs.external.TileLifecycleManager;
@@ -55,18 +55,16 @@ import com.android.systemui.settings.UserTracker;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.AutoTileManager;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.policy.Clock;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.animation.UniqueObjectHostView;
import com.android.systemui.util.settings.SecureSettings;

import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -75,12 +73,10 @@ import org.mockito.MockitoAnnotations;
import java.util.Optional;

@RunWith(AndroidTestingRunner.class)
@RunWithLooper
@RunWithLooper(setAsMainLooper = true)
@SmallTest
@Suppress
public class QSFragmentTest extends SysuiBaseFragmentTest {

    private MetricsLogger mMockMetricsLogger;
    @Mock
    private QSFragmentComponent.Factory mQsComponentFactory;
    @Mock
@@ -99,41 +95,41 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
    private TileServiceRequestController.Builder mTileServiceRequestControllerBuilder;
    @Mock
    private TileServiceRequestController mTileServiceRequestController;
    @Mock
    private QSCustomizerController mQsCustomizerController;
    @Mock
    private QuickQSPanelController mQuickQSPanelController;
    @Mock
    private FooterActionsController mQSFooterActionController;
    @Mock
    private QSContainerImplController mQSContainerImplController;
    @Mock
    private QSContainerImpl mContainer;
    @Mock
    private QSFooter mFooter;
    @Mock
    private LayoutInflater mLayoutInflater;
    @Mock
    private NonInterceptingScrollView mQSPanelScrollView;
    @Mock
    private QuickStatusBarHeader mHeader;
    @Mock
    private QSPanel.QSTileLayout mQsTileLayout;
    @Mock
    private QSPanel.QSTileLayout mQQsTileLayout;
    private View mQsFragmentView;

    public QSFragmentTest() {
        super(QSFragment.class);
        injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
    }

    @Before
    @Ignore("failing")
    public void addLeakCheckDependencies() {
        MockitoAnnotations.initMocks(this);
        when(mQsComponentFactory.create(any(QSFragment.class))).thenReturn(mQsFragmentComponent);
        when(mQsFragmentComponent.getQSPanelController()).thenReturn(mQSPanelController);

        when(mTileServiceRequestControllerBuilder.create(any()))
                .thenReturn(mTileServiceRequestController);

        mMockMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
        mContext.addMockSystemService(Context.LAYOUT_INFLATER_SERVICE,
                new LayoutInflaterBuilder(mContext)
                        .replace("com.android.systemui.statusbar.policy.SplitClockView",
                                FrameLayout.class)
                        .replace("TextClock", View.class)
                        .replace(CarrierText.class, View.class)
                        .replace(Clock.class, View.class)
                        .build());

        mDependency.injectTestDependency(Dependency.BG_LOOPER,
                TestableLooper.get(this).getLooper());
        mDependency.injectMockDependency(UserSwitcherController.class);
    public void setup() {
        injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
    }

    @Test
    @Ignore("failing")
    public void testListening() {
        assertEquals(Looper.myLooper(), Looper.getMainLooper());
        QSFragment qs = (QSFragment) mFragment;
        mFragments.dispatchResume();
        processAllMessages();
@@ -157,13 +153,11 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
    }

    @Test
    @Ignore("failing")
    public void testSaveState() {
        QSFragment qs = (QSFragment) mFragment;

        mFragments.dispatchResume();
        processAllMessages();

        QSFragment qs = (QSFragment) mFragment;
        qs.setListening(true);
        qs.setExpanded(true);
        processAllMessages();
@@ -178,7 +172,15 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {

    @Override
    protected Fragment instantiate(Context context, String className, Bundle arguments) {
        MockitoAnnotations.initMocks(this);
        CommandQueue commandQueue = new CommandQueue(context);

        setupQsComponent();
        setUpViews();
        setUpInflater();
        setUpMedia();
        setUpOther();

        return new QSFragment(
                new RemoteInputQuickSettingsDisabler(context, commandQueue,
                        mock(ConfigurationController.class)),
@@ -193,4 +195,46 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
                mFalsingManager,
                mock(DumpManager.class));
    }

    private void setUpOther() {
        when(mTileServiceRequestControllerBuilder.create(any()))
                .thenReturn(mTileServiceRequestController);
        when(mQSContainerImplController.getView()).thenReturn(mContainer);
        when(mQSPanelController.getTileLayout()).thenReturn(mQQsTileLayout);
        when(mQuickQSPanelController.getTileLayout()).thenReturn(mQsTileLayout);
    }

    private void setUpMedia() {
        when(mQSMediaHost.getCurrentClipping()).thenReturn(new Rect());
        when(mQSMediaHost.getHostView()).thenReturn(new UniqueObjectHostView(mContext));
        when(mQQSMediaHost.getHostView()).thenReturn(new UniqueObjectHostView(mContext));
    }

    private void setUpViews() {
        mQsFragmentView = spy(new View(mContext));
        when(mQsFragmentView.findViewById(R.id.expanded_qs_scroll_view)).thenReturn(
                mQSPanelScrollView);
        when(mQsFragmentView.findViewById(R.id.header)).thenReturn(mHeader);
        when(mQsFragmentView.findViewById(android.R.id.edit)).thenReturn(new View(mContext));
    }

    private void setUpInflater() {
        when(mLayoutInflater.cloneInContext(any(Context.class))).thenReturn(mLayoutInflater);
        when(mLayoutInflater.inflate(anyInt(), any(ViewGroup.class), anyBoolean()))
                .thenReturn(mQsFragmentView);
        mContext.addMockSystemService(Context.LAYOUT_INFLATER_SERVICE,
                mLayoutInflater);
    }

    private void setupQsComponent() {
        when(mQsComponentFactory.create(any(QSFragment.class))).thenReturn(mQsFragmentComponent);
        when(mQsFragmentComponent.getQSPanelController()).thenReturn(mQSPanelController);
        when(mQsFragmentComponent.getQuickQSPanelController()).thenReturn(mQuickQSPanelController);
        when(mQsFragmentComponent.getQSCustomizerController()).thenReturn(mQsCustomizerController);
        when(mQsFragmentComponent.getQSContainerImplController()).thenReturn(
                mQSContainerImplController);
        when(mQsFragmentComponent.getQSFooter()).thenReturn(mFooter);
        when(mQsFragmentComponent.getQSFooterActionController()).thenReturn(
                mQSFooterActionController);
    }
}