Home | History | Annotate | Download | only in manageapplications
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.settings.applications.manageapplications;
     18 
     19 import static android.support.v7.widget.RecyclerView.SCROLL_STATE_DRAGGING;
     20 import static android.support.v7.widget.RecyclerView.SCROLL_STATE_IDLE;
     21 import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_ALL;
     22 import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_MAIN;
     23 import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_NOTIFICATION;
     24 import static com.google.common.truth.Truth.assertThat;
     25 
     26 import static junit.framework.Assert.assertEquals;
     27 
     28 import static org.mockito.ArgumentMatchers.anyBoolean;
     29 import static org.mockito.Matchers.any;
     30 import static org.mockito.Matchers.anyInt;
     31 import static org.mockito.Matchers.eq;
     32 import static org.mockito.Mockito.doNothing;
     33 import static org.mockito.Mockito.mock;
     34 import static org.mockito.Mockito.never;
     35 import static org.mockito.Mockito.spy;
     36 import static org.mockito.Mockito.verify;
     37 import static org.mockito.Mockito.when;
     38 
     39 import android.app.Activity;
     40 import android.content.Context;
     41 import android.os.Bundle;
     42 import android.os.Looper;
     43 import android.os.UserManager;
     44 import android.support.v7.widget.RecyclerView;
     45 import android.view.LayoutInflater;
     46 import android.view.Menu;
     47 import android.view.MenuItem;
     48 import android.view.View;
     49 import android.view.ViewGroup;
     50 
     51 import com.android.settings.R;
     52 import com.android.settings.testutils.SettingsRobolectricTestRunner;
     53 import com.android.settings.widget.LoadingViewController;
     54 import com.android.settingslib.applications.ApplicationsState;
     55 
     56 import org.junit.Before;
     57 import org.junit.Test;
     58 import org.junit.runner.RunWith;
     59 import org.mockito.Mock;
     60 import org.mockito.MockitoAnnotations;
     61 import org.robolectric.RuntimeEnvironment;
     62 import org.robolectric.fakes.RoboMenuItem;
     63 import org.robolectric.util.ReflectionHelpers;
     64 
     65 import java.util.ArrayList;
     66 
     67 @RunWith(SettingsRobolectricTestRunner.class)
     68 public class ManageApplicationsTest {
     69 
     70     @Mock
     71     private ApplicationsState mState;
     72     @Mock
     73     private ApplicationsState.Session mSession;
     74     @Mock
     75     private Menu mMenu;
     76     private MenuItem mAppReset;
     77     private MenuItem mSortRecent;
     78     private MenuItem mSortFrequent;
     79     private ManageApplications mFragment;
     80 
     81     @Before
     82     public void setUp() {
     83         MockitoAnnotations.initMocks(this);
     84         mAppReset = new RoboMenuItem(R.id.reset_app_preferences);
     85         mSortRecent = new RoboMenuItem(R.id.sort_order_recent_notification);
     86         mSortFrequent = new RoboMenuItem(R.id.sort_order_frequent_notification);
     87         ReflectionHelpers.setStaticField(ApplicationsState.class, "sInstance", mState);
     88         when(mState.newSession(any())).thenReturn(mSession);
     89         when(mState.getBackgroundLooper()).thenReturn(Looper.myLooper());
     90 
     91         mFragment = new ManageApplications();
     92     }
     93 
     94     @Test
     95     public void updateMenu_mainListType_showAppReset() {
     96         setUpOptionMenus();
     97         ReflectionHelpers.setField(mFragment, "mListType", LIST_TYPE_MAIN);
     98         ReflectionHelpers.setField(mFragment, "mOptionsMenu", mMenu);
     99 
    100         mFragment.updateOptionsMenu();
    101         assertThat(mMenu.findItem(R.id.reset_app_preferences).isVisible()).isTrue();
    102     }
    103 
    104     @Test
    105     public void updateMenu_batteryListType_hideAppReset() {
    106         setUpOptionMenus();
    107         ReflectionHelpers.setField(mFragment, "mListType", ManageApplications.LIST_TYPE_HIGH_POWER);
    108         ReflectionHelpers.setField(mFragment, "mOptionsMenu", mMenu);
    109 
    110         mFragment.updateOptionsMenu();
    111         assertThat(mMenu.findItem(R.id.reset_app_preferences).isVisible()).isFalse();
    112     }
    113 
    114     @Test
    115     public void updateMenu_hideNotificationOptions() {
    116         setUpOptionMenus();
    117         ReflectionHelpers.setField(mFragment, "mListType", LIST_TYPE_NOTIFICATION);
    118         ReflectionHelpers.setField(mFragment, "mOptionsMenu", mMenu);
    119 
    120         mFragment.updateOptionsMenu();
    121         assertThat(mMenu.findItem(R.id.sort_order_recent_notification).isVisible()).isFalse();
    122         assertThat(mMenu.findItem(R.id.sort_order_frequent_notification).isVisible()).isFalse();
    123     }
    124 
    125 
    126     @Test
    127     public void onCreateView_shouldNotShowLoadingContainer() {
    128         final ManageApplications fragment = spy(new ManageApplications());
    129         ReflectionHelpers.setField(fragment, "mResetAppsHelper",
    130                 mock(ResetAppsHelper.class));
    131         doNothing().when(fragment).createHeader();
    132 
    133         final LayoutInflater layoutInflater = mock(LayoutInflater.class);
    134         final View view = mock(View.class);
    135         final View loadingContainer = mock(View.class);
    136         when(layoutInflater.inflate(anyInt(), eq(null))).thenReturn(view);
    137         when(view.findViewById(R.id.loading_container)).thenReturn(loadingContainer);
    138 
    139         fragment.onCreateView(layoutInflater, mock(ViewGroup.class), null);
    140 
    141         verify(loadingContainer, never()).setVisibility(View.VISIBLE);
    142     }
    143 
    144     @Test
    145     public void updateLoading_appLoaded_shouldNotDelayCallToHandleLoadingContainer() {
    146         final ManageApplications fragment = mock(ManageApplications.class);
    147         ReflectionHelpers.setField(fragment, "mLoadingContainer", mock(View.class));
    148         ReflectionHelpers.setField(fragment, "mListContainer", mock(View.class));
    149         when(fragment.getActivity()).thenReturn(mock(Activity.class));
    150         final ManageApplications.ApplicationsAdapter adapter =
    151                 spy(new ManageApplications.ApplicationsAdapter(mState, fragment,
    152                         AppFilterRegistry.getInstance().get(FILTER_APPS_ALL), new Bundle()));
    153         final LoadingViewController loadingViewController =
    154                 mock(LoadingViewController.class);
    155         ReflectionHelpers.setField(adapter, "mLoadingViewController", loadingViewController);
    156 
    157         // app loading completed
    158         ReflectionHelpers.setField(adapter, "mHasReceivedLoadEntries", true);
    159         final ArrayList<ApplicationsState.AppEntry> appList = new ArrayList<>();
    160         appList.add(mock(ApplicationsState.AppEntry.class));
    161         when(mSession.getAllApps()).thenReturn(appList);
    162 
    163         adapter.updateLoading();
    164 
    165         verify(loadingViewController, never()).showLoadingViewDelayed();
    166     }
    167 
    168     @Test
    169     public void updateLoading_appNotLoaded_shouldDelayCallToHandleLoadingContainer() {
    170         final ManageApplications fragment = mock(ManageApplications.class);
    171         ReflectionHelpers.setField(fragment, "mLoadingContainer", mock(View.class));
    172         ReflectionHelpers.setField(fragment, "mListContainer", mock(View.class));
    173         when(fragment.getActivity()).thenReturn(mock(Activity.class));
    174         final ManageApplications.ApplicationsAdapter adapter =
    175                 spy(new ManageApplications.ApplicationsAdapter(mState, fragment,
    176                         AppFilterRegistry.getInstance().get(FILTER_APPS_ALL), new Bundle()));
    177         final LoadingViewController loadingViewController =
    178                 mock(LoadingViewController.class);
    179         ReflectionHelpers.setField(adapter, "mLoadingViewController", loadingViewController);
    180 
    181         // app loading not yet completed
    182         ReflectionHelpers.setField(adapter, "mHasReceivedLoadEntries", false);
    183 
    184         adapter.updateLoading();
    185 
    186         verify(loadingViewController).showLoadingViewDelayed();
    187     }
    188 
    189     @Test
    190     public void shouldUseStableItemHeight_mainType_yes() {
    191         assertThat(ManageApplications.ApplicationsAdapter.shouldUseStableItemHeight(
    192                 LIST_TYPE_MAIN))
    193                 .isTrue();
    194         assertThat(ManageApplications.ApplicationsAdapter.shouldUseStableItemHeight(
    195                 LIST_TYPE_NOTIFICATION))
    196                 .isFalse();
    197     }
    198 
    199     @Test
    200     public void onRebuildComplete_shouldHideLoadingView() {
    201         final Context context = RuntimeEnvironment.application;
    202         final ManageApplications fragment = mock(ManageApplications.class);
    203         final RecyclerView recyclerView = mock(RecyclerView.class);
    204         final View emptyView = mock(View.class);
    205         ReflectionHelpers.setField(fragment, "mRecyclerView", recyclerView);
    206         ReflectionHelpers.setField(fragment, "mEmptyView", emptyView);
    207         final View loadingContainer = mock(View.class);
    208         when(loadingContainer.getContext()).thenReturn(context);
    209         final View listContainer = mock(View.class);
    210         when(listContainer.getVisibility()).thenReturn(View.INVISIBLE);
    211         when(listContainer.getContext()).thenReturn(context);
    212         ReflectionHelpers.setField(fragment, "mLoadingContainer", loadingContainer);
    213         ReflectionHelpers.setField(fragment, "mListContainer", listContainer);
    214         when(fragment.getActivity()).thenReturn(mock(Activity.class));
    215         final ManageApplications.ApplicationsAdapter adapter =
    216                 spy(new ManageApplications.ApplicationsAdapter(mState, fragment,
    217                         AppFilterRegistry.getInstance().get(FILTER_APPS_ALL), new Bundle()));
    218         final LoadingViewController loadingViewController =
    219                 mock(LoadingViewController.class);
    220         ReflectionHelpers.setField(adapter, "mLoadingViewController", loadingViewController);
    221         ReflectionHelpers.setField(adapter, "mAppFilter",
    222                 AppFilterRegistry.getInstance().get(FILTER_APPS_ALL));
    223 
    224         // app loading not yet completed
    225         ReflectionHelpers.setField(adapter, "mHasReceivedLoadEntries", false);
    226         adapter.updateLoading();
    227 
    228         // app loading completed
    229         ReflectionHelpers.setField(adapter, "mHasReceivedLoadEntries", true);
    230         final ArrayList<ApplicationsState.AppEntry> appList = new ArrayList<>();
    231         appList.add(mock(ApplicationsState.AppEntry.class));
    232         when(mSession.getAllApps()).thenReturn(appList);
    233 
    234         adapter.onRebuildComplete(null);
    235 
    236         verify(loadingViewController).showContent(true /* animate */);
    237     }
    238 
    239     @Test
    240     public void notifyItemChange_recyclerViewIdle_shouldNotify() {
    241         final RecyclerView recyclerView = mock(RecyclerView.class);
    242         final ManageApplications.ApplicationsAdapter adapter =
    243                 spy(new ManageApplications.ApplicationsAdapter(mState,
    244                         mock(ManageApplications.class),
    245                         AppFilterRegistry.getInstance().get(FILTER_APPS_ALL), new Bundle()));
    246 
    247         adapter.onAttachedToRecyclerView(recyclerView);
    248         adapter.mOnScrollListener.onScrollStateChanged(recyclerView, SCROLL_STATE_IDLE);
    249         adapter.mOnScrollListener.postNotifyItemChange(0 /* index */);
    250 
    251         verify(adapter).notifyItemChanged(0);
    252     }
    253 
    254     @Test
    255     public void notifyItemChange_recyclerViewScrolling_shouldNotifyWhenIdle() {
    256         final RecyclerView recyclerView = mock(RecyclerView.class);
    257         final ManageApplications.ApplicationsAdapter adapter =
    258                 spy(new ManageApplications.ApplicationsAdapter(mState,
    259                         mock(ManageApplications.class),
    260                         AppFilterRegistry.getInstance().get(FILTER_APPS_ALL), new Bundle()));
    261 
    262         adapter.onAttachedToRecyclerView(recyclerView);
    263         adapter.mOnScrollListener.onScrollStateChanged(recyclerView, SCROLL_STATE_DRAGGING);
    264         adapter.mOnScrollListener.postNotifyItemChange(0 /* index */);
    265 
    266         verify(adapter, never()).notifyItemChanged(0);
    267         verify(adapter, never()).notifyDataSetChanged();
    268 
    269         adapter.mOnScrollListener.onScrollStateChanged(recyclerView, SCROLL_STATE_IDLE);
    270         verify(adapter).notifyDataSetChanged();
    271     }
    272 
    273     @Test
    274     public void applicationsAdapter_onBindViewHolder_updateSwitch_notifications() {
    275         ManageApplications manageApplications = mock(ManageApplications.class);
    276         when(manageApplications.getActivity()).thenReturn(mock(Activity.class));
    277         UserManager um = mock(UserManager.class);
    278         when(um.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{});
    279         ReflectionHelpers.setField(manageApplications, "mUserManager", um);
    280         manageApplications.mListType = LIST_TYPE_NOTIFICATION;
    281         ApplicationViewHolder holder = mock(ApplicationViewHolder.class);
    282         ReflectionHelpers.setField(holder, "itemView", mock(View.class));
    283         ManageApplications.ApplicationsAdapter adapter =
    284                 new ManageApplications.ApplicationsAdapter(mState,
    285                         manageApplications, mock(AppFilterItem.class),
    286                         mock(Bundle.class));
    287         final ArrayList<ApplicationsState.AppEntry> appList = new ArrayList<>();
    288         appList.add(mock(ApplicationsState.AppEntry.class));
    289         ReflectionHelpers.setField(adapter, "mEntries", appList);
    290 
    291         adapter.onBindViewHolder(holder, 0);
    292         verify(holder).updateSwitch(any(), anyBoolean(), anyBoolean());
    293     }
    294 
    295     @Test
    296     public void applicationsAdapter_onBindViewHolder_updateSwitch_notNotifications() {
    297         ManageApplications manageApplications = mock(ManageApplications.class);
    298         manageApplications.mListType = LIST_TYPE_MAIN;
    299         ApplicationViewHolder holder = mock(ApplicationViewHolder.class);
    300         ReflectionHelpers.setField(holder, "itemView", mock(View.class));
    301         UserManager um = mock(UserManager.class);
    302         when(um.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{});
    303         ReflectionHelpers.setField(manageApplications, "mUserManager", um);
    304         ManageApplications.ApplicationsAdapter adapter =
    305                 new ManageApplications.ApplicationsAdapter(mState,
    306                         manageApplications, mock(AppFilterItem.class),
    307                         mock(Bundle.class));
    308         final ArrayList<ApplicationsState.AppEntry> appList = new ArrayList<>();
    309         appList.add(mock(ApplicationsState.AppEntry.class));
    310         ReflectionHelpers.setField(adapter, "mEntries", appList);
    311 
    312         adapter.onBindViewHolder(holder, 0);
    313         verify(holder, never()).updateSwitch(any(), anyBoolean(), anyBoolean());
    314     }
    315 
    316     @Test
    317     public void sortOrderSavedOnRebuild() {
    318         ManageApplications manageApplications = mock(ManageApplications.class);
    319         when(manageApplications.getActivity()).thenReturn(mock(Activity.class));
    320         UserManager um = mock(UserManager.class);
    321         when(um.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{});
    322         ReflectionHelpers.setField(manageApplications, "mUserManager", um);
    323         manageApplications.mListType = LIST_TYPE_NOTIFICATION;
    324         manageApplications.mSortOrder = -1;
    325         ManageApplications.ApplicationsAdapter adapter =
    326                 new ManageApplications.ApplicationsAdapter(mState,
    327                         manageApplications, mock(AppFilterItem.class),
    328                         mock(Bundle.class));
    329 
    330         adapter.rebuild(mSortRecent.getItemId());
    331         assertThat(manageApplications.mSortOrder).isEqualTo(mSortRecent.getItemId());
    332 
    333         adapter.rebuild(mSortFrequent.getItemId());
    334         assertThat(manageApplications.mSortOrder).isEqualTo(mSortFrequent.getItemId());
    335     }
    336 
    337     private void setUpOptionMenus() {
    338         when(mMenu.findItem(anyInt())).thenAnswer(invocation -> {
    339             final Object[] args = invocation.getArguments();
    340             final int id = (int) args[0];
    341             if (id == mAppReset.getItemId()) {
    342                 return mAppReset;
    343             }
    344             if (id == mSortFrequent.getItemId()) {
    345                 return mSortFrequent;
    346             }
    347             if (id == mSortRecent.getItemId()) {
    348                 return mSortRecent;
    349             }
    350             return new RoboMenuItem(id);
    351         });
    352     }
    353 }
    354