• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 package com.android.settings.location;
17 
18 import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT;
19 import static com.google.common.truth.Truth.assertThat;
20 import static org.mockito.ArgumentMatchers.any;
21 import static org.mockito.ArgumentMatchers.argThat;
22 import static org.mockito.ArgumentMatchers.eq;
23 import static org.mockito.Mockito.doReturn;
24 import static org.mockito.Mockito.mock;
25 import static org.mockito.Mockito.never;
26 import static org.mockito.Mockito.spy;
27 import static org.mockito.Mockito.verify;
28 import static org.mockito.Mockito.when;
29 
30 import android.arch.lifecycle.LifecycleOwner;
31 import android.content.Context;
32 import android.content.Intent;
33 import android.provider.Settings;
34 import android.support.v7.preference.Preference;
35 import android.support.v7.preference.PreferenceCategory;
36 import android.support.v7.preference.PreferenceScreen;
37 import android.text.TextUtils;
38 import com.android.settings.R;
39 import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
40 import com.android.settings.testutils.SettingsRobolectricTestRunner;
41 import com.android.settings.widget.AppPreference;
42 import com.android.settingslib.core.lifecycle.Lifecycle;
43 import com.android.settingslib.location.RecentLocationApps;
44 import com.android.settingslib.location.RecentLocationApps.Request;
45 import java.util.ArrayList;
46 import java.util.List;
47 import org.junit.Before;
48 import org.junit.Test;
49 import org.junit.runner.RunWith;
50 import org.mockito.ArgumentCaptor;
51 import org.mockito.ArgumentMatcher;
52 import org.mockito.InOrder;
53 import org.mockito.Mock;
54 import org.mockito.Mockito;
55 import org.mockito.MockitoAnnotations;
56 import org.robolectric.RuntimeEnvironment;
57 
58 @RunWith(SettingsRobolectricTestRunner.class)
59 public class RecentLocationRequestPreferenceControllerTest {
60 
61     @Mock
62     private LocationSettings mFragment;
63     @Mock
64     private PreferenceCategory mCategory;
65     @Mock
66     private PreferenceScreen mScreen;
67     @Mock
68     private RecentLocationApps mRecentLocationApps;
69     @Mock
70     private Preference mSeeAllButton;
71 
72     private Context mContext;
73     private RecentLocationRequestPreferenceController mController;
74     private LifecycleOwner mLifecycleOwner;
75     private Lifecycle mLifecycle;
76 
77     @Before
setUp()78     public void setUp() {
79         MockitoAnnotations.initMocks(this);
80         mContext = spy(RuntimeEnvironment.application);
81         mLifecycleOwner = () -> mLifecycle;
82         mLifecycle = new Lifecycle(mLifecycleOwner);
83         mController = spy(new RecentLocationRequestPreferenceController(
84                 mContext, mFragment, mLifecycle, mRecentLocationApps));
85         when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mCategory);
86         when(mScreen.findPreference(mController.KEY_SEE_ALL_BUTTON)).thenReturn(mSeeAllButton);
87         final String key = mController.getPreferenceKey();
88         when(mCategory.getKey()).thenReturn(key);
89         when(mCategory.getContext()).thenReturn(mContext);
90     }
91 
92     @Test
onLocationModeChanged_LocationOn_shouldEnablePreference()93     public void onLocationModeChanged_LocationOn_shouldEnablePreference() {
94         mController.displayPreference(mScreen);
95 
96         mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false);
97 
98         verify(mCategory).setEnabled(true);
99     }
100 
101     @Test
onLocationModeChanged_LocationOff_shouldDisablePreference()102     public void onLocationModeChanged_LocationOff_shouldDisablePreference() {
103         mController.displayPreference(mScreen);
104 
105         mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_OFF, false);
106 
107         verify(mCategory).setEnabled(false);
108     }
109 
110     @Test
updateState_noRecentRequest_shouldRemoveAllAndAddBanner()111     public void updateState_noRecentRequest_shouldRemoveAllAndAddBanner() {
112         doReturn(new ArrayList<>()).when(mRecentLocationApps).getAppListSorted();
113         mController.displayPreference(mScreen);
114 
115         mController.updateState(mCategory);
116 
117         verify(mCategory).removeAll();
118         final String title = mContext.getString(R.string.location_no_recent_apps);
119         verify(mCategory).addPreference(argThat(titleMatches(title)));
120     }
121 
122     @Test
updateState_hasRecentRequest_shouldRemoveAllAndAddInjectedSettings()123     public void updateState_hasRecentRequest_shouldRemoveAllAndAddInjectedSettings() {
124         List<Request> requests = createMockRequests(2);
125         doReturn(requests).when(mRecentLocationApps).getAppListSorted();
126 
127         mController.displayPreference(mScreen);
128         mController.updateState(mCategory);
129 
130         verify(mCategory).removeAll();
131         // Verifies two preferences are added in original order
132         InOrder inOrder = Mockito.inOrder(mCategory);
133         inOrder.verify(mCategory).addPreference(argThat(titleMatches("appTitle0")));
134         inOrder.verify(mCategory).addPreference(argThat(titleMatches("appTitle1")));
135     }
136 
137     @Test
updateState_hasOverThreeRequests_shouldDisplaySeeAllButton()138     public void updateState_hasOverThreeRequests_shouldDisplaySeeAllButton() {
139         List<Request> requests = createMockRequests(6);
140         when(mRecentLocationApps.getAppListSorted()).thenReturn(requests);
141 
142         mController.displayPreference(mScreen);
143         mController.updateState(mCategory);
144 
145         verify(mCategory).removeAll();
146         // Verifies the first three preferences are added
147         InOrder inOrder = Mockito.inOrder(mCategory);
148         inOrder.verify(mCategory).addPreference(argThat(titleMatches("appTitle0")));
149         inOrder.verify(mCategory).addPreference(argThat(titleMatches("appTitle1")));
150         inOrder.verify(mCategory).addPreference(argThat(titleMatches("appTitle2")));
151         verify(mCategory, never()).addPreference(argThat(titleMatches("appTitle3")));
152         // Verifies the "See all" preference is visible
153         verify(mSeeAllButton).setVisible(true);
154     }
155 
156     @Test
createAppPreference_shouldAddClickListener()157     public void createAppPreference_shouldAddClickListener() {
158         final Request request = mock(Request.class);
159         final AppPreference preference = mock(AppPreference.class);
160         doReturn(preference).when(mController).createAppPreference(any(Context.class));
161 
162         mController.createAppPreference(mContext, request);
163 
164         verify(preference).setOnPreferenceClickListener(
165                 any(RecentLocationRequestPreferenceController.PackageEntryClickedListener.class));
166     }
167 
168     @Test
onPreferenceClick_shouldLaunchAppDetails()169     public void onPreferenceClick_shouldLaunchAppDetails() {
170         final Context context= mock(Context.class);
171         when(mFragment.getContext()).thenReturn(context);
172 
173         final List<RecentLocationApps.Request> requests = new ArrayList<>();
174         final Request request = mock(Request.class);
175         requests.add(request);
176         doReturn(requests).when(mRecentLocationApps).getAppListSorted();
177         final AppPreference preference = new AppPreference(mContext);
178         doReturn(preference).when(mController).createAppPreference(any(Context.class));
179         mController.displayPreference(mScreen);
180         mController.updateState(mCategory);
181 
182         final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
183 
184         preference.performClick();
185 
186         verify(context).startActivity(intent.capture());
187 
188         assertThat(intent.getValue().getStringExtra(EXTRA_SHOW_FRAGMENT))
189                 .isEqualTo(AppInfoDashboardFragment.class.getName());
190     }
191 
titleMatches(String expected)192     private static ArgumentMatcher<Preference> titleMatches(String expected) {
193         return preference -> TextUtils.equals(expected, preference.getTitle());
194     }
195 
createMockRequests(int count)196     private List<RecentLocationApps.Request> createMockRequests(int count) {
197         List<RecentLocationApps.Request> requests = new ArrayList<>();
198         for (int i = 0; i < count; i++) {
199             // Add mock requests
200             Request req = mock(Request.class, "request" + i);
201             requests.add(req);
202             // Map mock AppPreferences with mock requests
203             String title = "appTitle" + i;
204             AppPreference appPreference = mock(AppPreference.class, "AppPreference" + i);
205             doReturn(title).when(appPreference).getTitle();
206             doReturn(appPreference)
207                 .when(mController).createAppPreference(any(Context.class), eq(req));
208         }
209         return requests;
210     }
211 }