1035cbc70972ebcd503756cef4626cb585e64feddDaniel Nishi/*
2035cbc70972ebcd503756cef4626cb585e64feddDaniel Nishi * Copyright (C) 2016 The Android Open Source Project
3035cbc70972ebcd503756cef4626cb585e64feddDaniel Nishi *
4035cbc70972ebcd503756cef4626cb585e64feddDaniel Nishi * Licensed under the Apache License, Version 2.0 (the "License");
5035cbc70972ebcd503756cef4626cb585e64feddDaniel Nishi * you may not use this file except in compliance with the License.
6035cbc70972ebcd503756cef4626cb585e64feddDaniel Nishi * You may obtain a copy of the License at
7035cbc70972ebcd503756cef4626cb585e64feddDaniel Nishi *
8035cbc70972ebcd503756cef4626cb585e64feddDaniel Nishi *      http://www.apache.org/licenses/LICENSE-2.0
9035cbc70972ebcd503756cef4626cb585e64feddDaniel Nishi *
10035cbc70972ebcd503756cef4626cb585e64feddDaniel Nishi * Unless required by applicable law or agreed to in writing, software
11035cbc70972ebcd503756cef4626cb585e64feddDaniel Nishi * distributed under the License is distributed on an "AS IS" BASIS,
12035cbc70972ebcd503756cef4626cb585e64feddDaniel Nishi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13035cbc70972ebcd503756cef4626cb585e64feddDaniel Nishi * See the License for the specific language governing permissions and
14035cbc70972ebcd503756cef4626cb585e64feddDaniel Nishi * limitations under the License.
15035cbc70972ebcd503756cef4626cb585e64feddDaniel Nishi */
16035cbc70972ebcd503756cef4626cb585e64feddDaniel Nishi
17bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jungpackage com.android.settings.applications;
18bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung
19e3535d9998363cbf352b5f8feb9277475e380944Fan Zhangimport static com.google.common.truth.Truth.assertThat;
20e3535d9998363cbf352b5f8feb9277475e380944Fan Zhangimport static org.mockito.Matchers.any;
21e3535d9998363cbf352b5f8feb9277475e380944Fan Zhangimport static org.mockito.Matchers.anyInt;
22e3535d9998363cbf352b5f8feb9277475e380944Fan Zhangimport static org.mockito.Matchers.eq;
23e3535d9998363cbf352b5f8feb9277475e380944Fan Zhangimport static org.mockito.Mockito.doNothing;
24e3535d9998363cbf352b5f8feb9277475e380944Fan Zhangimport static org.mockito.Mockito.mock;
25e3535d9998363cbf352b5f8feb9277475e380944Fan Zhangimport static org.mockito.Mockito.never;
26e3535d9998363cbf352b5f8feb9277475e380944Fan Zhangimport static org.mockito.Mockito.spy;
27e3535d9998363cbf352b5f8feb9277475e380944Fan Zhangimport static org.mockito.Mockito.verify;
28e3535d9998363cbf352b5f8feb9277475e380944Fan Zhangimport static org.mockito.Mockito.when;
29e3535d9998363cbf352b5f8feb9277475e380944Fan Zhang
30b8642c746451babc42beb141347781e425bb2017Doris Lingimport android.app.Activity;
31e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Lingimport android.content.Context;
32b8642c746451babc42beb141347781e425bb2017Doris Lingimport android.content.pm.ApplicationInfo;
33b8642c746451babc42beb141347781e425bb2017Doris Lingimport android.content.pm.PackageManager;
34e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Lingimport android.os.Handler;
35bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jungimport android.os.Looper;
36e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Lingimport android.view.LayoutInflater;
37d1c41a306415e04b4acfb217058b40b90884547bFan Zhangimport android.view.Menu;
38d1c41a306415e04b4acfb217058b40b90884547bFan Zhangimport android.view.MenuItem;
39e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Lingimport android.view.View;
40e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Lingimport android.view.ViewGroup;
41b8642c746451babc42beb141347781e425bb2017Doris Lingimport android.widget.TextView;
42d1c41a306415e04b4acfb217058b40b90884547bFan Zhang
43b8642c746451babc42beb141347781e425bb2017Doris Lingimport com.android.settings.R;
44bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jungimport com.android.settings.Settings;
45bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jungimport com.android.settings.TestConfig;
46e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Lingimport com.android.settings.testutils.SettingsRobolectricTestRunner;
47bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jungimport com.android.settings.testutils.shadow.SettingsShadowResources;
48bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jungimport com.android.settings.testutils.shadow.SettingsShadowResources.SettingsShadowTheme;
49c6ca314c0b872f75926807ca7d6eb24ebe7cb684Fan Zhangimport com.android.settings.testutils.shadow.ShadowEventLogWriter;
50896f1b363c446366d96654e703e38dc069fef3d2Fan Zhangimport com.android.settings.widget.LoadingViewController;
51bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jungimport com.android.settingslib.applications.ApplicationsState;
52777ed2535a7fd6f618a0d12f381af99252283574Juan Langimport com.android.settingslib.core.lifecycle.Lifecycle;
53d1c41a306415e04b4acfb217058b40b90884547bFan Zhang
54bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jungimport org.junit.Before;
55bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jungimport org.junit.Test;
56bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jungimport org.junit.runner.RunWith;
57bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jungimport org.mockito.Mock;
58bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jungimport org.mockito.MockitoAnnotations;
59e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Lingimport org.robolectric.RuntimeEnvironment;
60bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jungimport org.robolectric.annotation.Config;
61d1c41a306415e04b4acfb217058b40b90884547bFan Zhangimport org.robolectric.fakes.RoboMenuItem;
62bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jungimport org.robolectric.util.ReflectionHelpers;
63bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung
64896f1b363c446366d96654e703e38dc069fef3d2Fan Zhangimport java.util.ArrayList;
65896f1b363c446366d96654e703e38dc069fef3d2Fan Zhang
66bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung/**
67bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung * Tests for {@link ManageApplications}.
68bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung */
69bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung@RunWith(SettingsRobolectricTestRunner.class)
70bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung// TODO: Consider making the shadow class set global using a robolectric.properties file.
71bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung@Config(manifest = TestConfig.MANIFEST_PATH,
72bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung        sdk = TestConfig.SDK_VERSION,
73bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung        shadows = {
74bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung                SettingsShadowResources.class,
75bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung                SettingsShadowTheme.class,
76c6ca314c0b872f75926807ca7d6eb24ebe7cb684Fan Zhang                ShadowEventLogWriter.class
77bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung        })
78bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jungpublic class ManageApplicationsTest {
79bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung
80d1c41a306415e04b4acfb217058b40b90884547bFan Zhang    @Mock
81d1c41a306415e04b4acfb217058b40b90884547bFan Zhang    private ApplicationsState mState;
82d1c41a306415e04b4acfb217058b40b90884547bFan Zhang    @Mock
83d1c41a306415e04b4acfb217058b40b90884547bFan Zhang    private ApplicationsState.Session mSession;
84d1c41a306415e04b4acfb217058b40b90884547bFan Zhang    @Mock
85d1c41a306415e04b4acfb217058b40b90884547bFan Zhang    private Menu mMenu;
86d1c41a306415e04b4acfb217058b40b90884547bFan Zhang    private MenuItem mAppReset;
87bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung    private Looper mBgLooper;
88bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung    private ManageApplications mFragment;
89c6ca314c0b872f75926807ca7d6eb24ebe7cb684Fan Zhang
90bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung    @Before
91bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung    public void setUp() {
92bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung        MockitoAnnotations.initMocks(this);
93d1c41a306415e04b4acfb217058b40b90884547bFan Zhang        mAppReset = new RoboMenuItem(R.id.reset_app_preferences);
94bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung        ReflectionHelpers.setStaticField(ApplicationsState.class, "sInstance", mState);
95bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung        when(mState.newSession(any())).thenReturn(mSession);
96bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung        mBgLooper = Looper.myLooper();
97bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung        when(mState.getBackgroundLooper()).thenReturn(mBgLooper);
98bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung
99bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung        mFragment = new ManageApplications();
100c6ca314c0b872f75926807ca7d6eb24ebe7cb684Fan Zhang        ReflectionHelpers.setField(mFragment, "mLifecycle", new Lifecycle());
101bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung    }
102bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung
103bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung    @Test
104bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung    public void launchFragment() {
105bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung        SettingsRobolectricTestRunner.startSettingsFragment(
106bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung                mFragment, Settings.ManageApplicationsActivity.class);
107bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung    }
108b8642c746451babc42beb141347781e425bb2017Doris Ling
109b8642c746451babc42beb141347781e425bb2017Doris Ling    @Test
110b8642c746451babc42beb141347781e425bb2017Doris Ling    public void updateDisableView_appDisabledUntilUsed_shouldSetDisabled() {
111b8642c746451babc42beb141347781e425bb2017Doris Ling        final TextView view = mock(TextView.class);
112b8642c746451babc42beb141347781e425bb2017Doris Ling        final ApplicationInfo info = new ApplicationInfo();
113b8642c746451babc42beb141347781e425bb2017Doris Ling        info.flags = ApplicationInfo.FLAG_INSTALLED;
114b8642c746451babc42beb141347781e425bb2017Doris Ling        info.enabled = true;
115b8642c746451babc42beb141347781e425bb2017Doris Ling        info.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
116b8642c746451babc42beb141347781e425bb2017Doris Ling        ManageApplications fragment = mock(ManageApplications.class);
117b8642c746451babc42beb141347781e425bb2017Doris Ling        when(fragment.getActivity()).thenReturn(mock(Activity.class));
118b8642c746451babc42beb141347781e425bb2017Doris Ling        final ManageApplications.ApplicationsAdapter adapter =
119d1c41a306415e04b4acfb217058b40b90884547bFan Zhang                new ManageApplications.ApplicationsAdapter(mState, fragment, 0);
120b8642c746451babc42beb141347781e425bb2017Doris Ling
121b8642c746451babc42beb141347781e425bb2017Doris Ling        adapter.updateDisableView(view, info);
122b8642c746451babc42beb141347781e425bb2017Doris Ling
123b8642c746451babc42beb141347781e425bb2017Doris Ling        verify(view).setText(R.string.disabled);
124b8642c746451babc42beb141347781e425bb2017Doris Ling    }
125d1c41a306415e04b4acfb217058b40b90884547bFan Zhang
126d1c41a306415e04b4acfb217058b40b90884547bFan Zhang    @Test
127d1c41a306415e04b4acfb217058b40b90884547bFan Zhang    public void updateMenu_mainListType_showAppReset() {
128d1c41a306415e04b4acfb217058b40b90884547bFan Zhang        setUpOptionMenus();
129d1c41a306415e04b4acfb217058b40b90884547bFan Zhang        ReflectionHelpers.setField(mFragment, "mListType", ManageApplications.LIST_TYPE_MAIN);
130d1c41a306415e04b4acfb217058b40b90884547bFan Zhang        ReflectionHelpers.setField(mFragment, "mOptionsMenu", mMenu);
131d1c41a306415e04b4acfb217058b40b90884547bFan Zhang
132d1c41a306415e04b4acfb217058b40b90884547bFan Zhang        mFragment.updateOptionsMenu();
133d1c41a306415e04b4acfb217058b40b90884547bFan Zhang        assertThat(mMenu.findItem(R.id.reset_app_preferences).isVisible()).isTrue();
134d1c41a306415e04b4acfb217058b40b90884547bFan Zhang    }
135d1c41a306415e04b4acfb217058b40b90884547bFan Zhang
136d1c41a306415e04b4acfb217058b40b90884547bFan Zhang    @Test
137d1c41a306415e04b4acfb217058b40b90884547bFan Zhang    public void updateMenu_batteryListType_hideAppReset() {
138d1c41a306415e04b4acfb217058b40b90884547bFan Zhang        setUpOptionMenus();
139d1c41a306415e04b4acfb217058b40b90884547bFan Zhang        ReflectionHelpers.setField(mFragment, "mListType", ManageApplications.LIST_TYPE_HIGH_POWER);
140d1c41a306415e04b4acfb217058b40b90884547bFan Zhang        ReflectionHelpers.setField(mFragment, "mOptionsMenu", mMenu);
141d1c41a306415e04b4acfb217058b40b90884547bFan Zhang
142d1c41a306415e04b4acfb217058b40b90884547bFan Zhang        mFragment.updateOptionsMenu();
143d1c41a306415e04b4acfb217058b40b90884547bFan Zhang        assertThat(mMenu.findItem(R.id.reset_app_preferences).isVisible()).isFalse();
144d1c41a306415e04b4acfb217058b40b90884547bFan Zhang    }
145d1c41a306415e04b4acfb217058b40b90884547bFan Zhang
146e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling    @Test
147e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling    public void onCreateView_shouldNotShowLoadingContainer() {
148e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        final ManageApplications fragment = spy(new ManageApplications());
149e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        ReflectionHelpers.setField(fragment, "mResetAppsHelper",
150e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling                mock(ResetAppsHelper.class));
151e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        doNothing().when(fragment).createHeader();
152e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling
153e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        final LayoutInflater layoutInflater = mock(LayoutInflater.class);
154e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        final View view = mock(View.class);
155e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        final View loadingContainer = mock(View.class);
156e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        when(layoutInflater.inflate(anyInt(), eq(null))).thenReturn(view);
157e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        when(view.findViewById(R.id.loading_container)).thenReturn(loadingContainer);
158e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling
159e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        fragment.onCreateView(layoutInflater, mock(ViewGroup.class), null);
160e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling
161e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        verify(loadingContainer, never()).setVisibility(View.VISIBLE);
162e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling    }
163e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling
164e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling    @Test
165e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling    public void updateLoading_appLoaded_shouldNotDelayCallToHandleLoadingContainer() {
166e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        final ManageApplications fragment = mock(ManageApplications.class);
167e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        ReflectionHelpers.setField(fragment, "mLoadingContainer", mock(View.class));
168e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        ReflectionHelpers.setField(fragment, "mListContainer", mock(View.class));
169e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        when(fragment.getActivity()).thenReturn(mock(Activity.class));
170e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        final Handler handler = mock(Handler.class);
171e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        final ManageApplications.ApplicationsAdapter adapter =
172e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling            spy(new ManageApplications.ApplicationsAdapter(mState, fragment, 0));
173896f1b363c446366d96654e703e38dc069fef3d2Fan Zhang        final LoadingViewController loadingViewController =
174896f1b363c446366d96654e703e38dc069fef3d2Fan Zhang                mock(LoadingViewController.class);
175896f1b363c446366d96654e703e38dc069fef3d2Fan Zhang        ReflectionHelpers.setField(adapter, "mLoadingViewController", loadingViewController);
176e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        ReflectionHelpers.setField(adapter, "mFgHandler", handler);
177e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling
178e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        // app loading completed
179e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        ReflectionHelpers.setField(adapter, "mHasReceivedLoadEntries", true);
180e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        final ArrayList<ApplicationsState.AppEntry> appList = new ArrayList<>();
181e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        appList.add(mock(ApplicationsState.AppEntry.class));
182e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        when(mSession.getAllApps()).thenReturn(appList);
183e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling
184e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        adapter.updateLoading();
185e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling
186896f1b363c446366d96654e703e38dc069fef3d2Fan Zhang        verify(loadingViewController, never()).showLoadingViewDelayed();
187e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling    }
188e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling
189e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling    @Test
190e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling    public void updateLoading_appNotLoaded_shouldDelayCallToHandleLoadingContainer() {
191e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        final ManageApplications fragment = mock(ManageApplications.class);
192e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        ReflectionHelpers.setField(fragment, "mLoadingContainer", mock(View.class));
193e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        ReflectionHelpers.setField(fragment, "mListContainer", mock(View.class));
194e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        when(fragment.getActivity()).thenReturn(mock(Activity.class));
195896f1b363c446366d96654e703e38dc069fef3d2Fan Zhang
196e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        final Handler handler = mock(Handler.class);
197e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        final ManageApplications.ApplicationsAdapter adapter =
198e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling            spy(new ManageApplications.ApplicationsAdapter(mState, fragment, 0));
199896f1b363c446366d96654e703e38dc069fef3d2Fan Zhang        final LoadingViewController loadingViewController =
200896f1b363c446366d96654e703e38dc069fef3d2Fan Zhang                mock(LoadingViewController.class);
201896f1b363c446366d96654e703e38dc069fef3d2Fan Zhang        ReflectionHelpers.setField(adapter, "mLoadingViewController", loadingViewController);
202e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        ReflectionHelpers.setField(adapter, "mFgHandler", handler);
203e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling
204e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        // app loading not yet completed
205e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        ReflectionHelpers.setField(adapter, "mHasReceivedLoadEntries", false);
206e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling
207e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        adapter.updateLoading();
208e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling
209896f1b363c446366d96654e703e38dc069fef3d2Fan Zhang        verify(loadingViewController).showLoadingViewDelayed();
210e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling    }
211e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling
212e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling    @Test
213896f1b363c446366d96654e703e38dc069fef3d2Fan Zhang    public void onRebuildComplete_shouldHideLoadingView() {
214e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        final Context context = RuntimeEnvironment.application;
215e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        final ManageApplications fragment = mock(ManageApplications.class);
216e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        final View loadingContainer = mock(View.class);
217e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        when(loadingContainer.getContext()).thenReturn(context);
218e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        final View listContainer = mock(View.class);
219e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        when(listContainer.getVisibility()).thenReturn(View.INVISIBLE);
220e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        when(listContainer.getContext()).thenReturn(context);
221e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        ReflectionHelpers.setField(fragment, "mLoadingContainer", loadingContainer);
222e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        ReflectionHelpers.setField(fragment, "mListContainer", listContainer);
223e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        when(fragment.getActivity()).thenReturn(mock(Activity.class));
224e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        final Handler handler = mock(Handler.class);
225e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        final ManageApplications.ApplicationsAdapter adapter =
226e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling            spy(new ManageApplications.ApplicationsAdapter(mState, fragment, 0));
227896f1b363c446366d96654e703e38dc069fef3d2Fan Zhang        final LoadingViewController loadingViewController =
228896f1b363c446366d96654e703e38dc069fef3d2Fan Zhang                mock(LoadingViewController.class);
229896f1b363c446366d96654e703e38dc069fef3d2Fan Zhang        ReflectionHelpers.setField(adapter, "mLoadingViewController", loadingViewController);
230e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        ReflectionHelpers.setField(adapter, "mFgHandler", handler);
231e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        ReflectionHelpers.setField(adapter, "mFilterMode", -1);
232e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling
233e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        // app loading not yet completed
234e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        ReflectionHelpers.setField(adapter, "mHasReceivedLoadEntries", false);
235e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        adapter.updateLoading();
236e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling
237e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        // app loading completed
238e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        ReflectionHelpers.setField(adapter, "mHasReceivedLoadEntries", true);
239e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        final ArrayList<ApplicationsState.AppEntry> appList = new ArrayList<>();
240e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        appList.add(mock(ApplicationsState.AppEntry.class));
241e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        when(mSession.getAllApps()).thenReturn(appList);
242e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling
243e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling        adapter.onRebuildComplete(null);
244e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling
245896f1b363c446366d96654e703e38dc069fef3d2Fan Zhang        verify(loadingViewController).showContent(true /* animate */);
246e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling    }
247e9060a3cb6bd5e3087d24d72e48d9d1fdbd371e7Doris Ling
248d1c41a306415e04b4acfb217058b40b90884547bFan Zhang    private void setUpOptionMenus() {
249d1c41a306415e04b4acfb217058b40b90884547bFan Zhang        when(mMenu.findItem(anyInt())).thenAnswer(invocation -> {
250d1c41a306415e04b4acfb217058b40b90884547bFan Zhang            final Object[] args = invocation.getArguments();
251d1c41a306415e04b4acfb217058b40b90884547bFan Zhang            final int id = (int) args[0];
252d1c41a306415e04b4acfb217058b40b90884547bFan Zhang            if (id == mAppReset.getItemId()) {
253d1c41a306415e04b4acfb217058b40b90884547bFan Zhang                return mAppReset;
254d1c41a306415e04b4acfb217058b40b90884547bFan Zhang            }
255d1c41a306415e04b4acfb217058b40b90884547bFan Zhang            return new RoboMenuItem(id);
256d1c41a306415e04b4acfb217058b40b90884547bFan Zhang        });
257d1c41a306415e04b4acfb217058b40b90884547bFan Zhang    }
258bccd65250316ad6f6e65cc9a0cc84235a5c44d86Jaewoong Jung}
259