• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 package com.android.settings.dashboard;
17 
18 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.DASHBOARD_CONTAINER;
19 import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_KEYHINT;
20 
21 import static com.google.common.truth.Truth.assertThat;
22 
23 import static org.mockito.ArgumentMatchers.nullable;
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.times;
28 import static org.mockito.Mockito.verify;
29 import static org.mockito.Mockito.when;
30 
31 import android.app.settings.SettingsEnums;
32 import android.content.Context;
33 import android.content.pm.ActivityInfo;
34 import android.os.Bundle;
35 
36 import androidx.preference.Preference;
37 import androidx.preference.PreferenceManager;
38 import androidx.preference.PreferenceScreen;
39 
40 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
41 import com.android.settings.core.PreferenceControllerMixin;
42 import com.android.settings.slices.BlockingSlicePrefController;
43 import com.android.settings.testutils.FakeFeatureFactory;
44 import com.android.settingslib.core.AbstractPreferenceController;
45 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
46 import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
47 import com.android.settingslib.drawer.DashboardCategory;
48 import com.android.settingslib.drawer.Tile;
49 
50 import org.junit.Before;
51 import org.junit.Test;
52 import org.junit.runner.RunWith;
53 import org.mockito.Mock;
54 import org.mockito.MockitoAnnotations;
55 import org.robolectric.RobolectricTestRunner;
56 import org.robolectric.RuntimeEnvironment;
57 import org.robolectric.annotation.Config;
58 import org.robolectric.util.ReflectionHelpers;
59 
60 import java.util.ArrayList;
61 import java.util.Arrays;
62 import java.util.HashMap;
63 import java.util.List;
64 import java.util.Map;
65 
66 @RunWith(RobolectricTestRunner.class)
67 public class DashboardFragmentTest {
68 
69     @Mock
70     private FakeFeatureFactory mFakeFeatureFactory;
71     private ActivityInfo mActivityInfo;
72     private DashboardCategory mDashboardCategory;
73     private Context mContext;
74     private TestFragment mTestFragment;
75     private List<AbstractPreferenceController> mControllers;
76 
77     @Before
setUp()78     public void setUp() {
79         MockitoAnnotations.initMocks(this);
80         mContext = spy(RuntimeEnvironment.application);
81         mActivityInfo = new ActivityInfo();
82         mActivityInfo.packageName = "pkg";
83         mActivityInfo.name = "class";
84         mActivityInfo.metaData = new Bundle();
85         mActivityInfo.metaData.putString(META_DATA_PREFERENCE_KEYHINT, "injected_tile_key");
86         mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
87         mDashboardCategory = new DashboardCategory("key");
88         mDashboardCategory.addTile(new Tile(mActivityInfo, mDashboardCategory.key));
89         mTestFragment = new TestFragment(RuntimeEnvironment.application);
90         when(mFakeFeatureFactory.dashboardFeatureProvider
91                 .getTilesForCategory(nullable(String.class)))
92                 .thenReturn(mDashboardCategory);
93         mTestFragment.onAttach(RuntimeEnvironment.application);
94         when(mContext.getPackageName()).thenReturn("TestPackage");
95         mControllers = new ArrayList<>();
96     }
97 
98     @Test
testPreferenceControllerGetterSetter_shouldAddAndGetProperly()99     public void testPreferenceControllerGetterSetter_shouldAddAndGetProperly() {
100         final TestPreferenceController controller = new TestPreferenceController(mContext);
101         mTestFragment.addPreferenceController(controller);
102 
103         final TestPreferenceController retrievedController = mTestFragment.use
104                 (TestPreferenceController.class);
105 
106         assertThat(controller).isSameAs(retrievedController);
107     }
108 
109     @Test
testPreferenceControllerSetter_shouldAddAndNotReplace()110     public void testPreferenceControllerSetter_shouldAddAndNotReplace() {
111         final TestPreferenceController controller1 = new TestPreferenceController(mContext);
112         mTestFragment.addPreferenceController(controller1);
113         final TestPreferenceController controller2 = new TestPreferenceController(mContext);
114         mTestFragment.addPreferenceController(controller2);
115 
116         final TestPreferenceController retrievedController = mTestFragment.use
117                 (TestPreferenceController.class);
118 
119         assertThat(controller1).isSameAs(retrievedController);
120     }
121 
122     @Test
displayTilesAsPreference_shouldAddTilesWithIntent()123     public void displayTilesAsPreference_shouldAddTilesWithIntent() {
124         when(mFakeFeatureFactory.dashboardFeatureProvider
125                 .getTilesForCategory(nullable(String.class)))
126                 .thenReturn(mDashboardCategory);
127         when(mFakeFeatureFactory.dashboardFeatureProvider
128                 .getDashboardKeyForTile(nullable(Tile.class)))
129                 .thenReturn("test_key");
130         mTestFragment.onCreatePreferences(new Bundle(), "rootKey");
131 
132         verify(mTestFragment.mScreen).addPreference(nullable(Preference.class));
133     }
134 
135     @Test
displayTilesAsPreference_shouldNotAddTilesWithoutIntent()136     public void displayTilesAsPreference_shouldNotAddTilesWithoutIntent() {
137         mTestFragment.onCreatePreferences(new Bundle(), "rootKey");
138 
139         verify(mTestFragment.mScreen, never()).addPreference(nullable(Preference.class));
140     }
141 
142     @Test
displayTilesAsPreference_withEmptyCategory_shouldNotAddTiles()143     public void displayTilesAsPreference_withEmptyCategory_shouldNotAddTiles() {
144         mDashboardCategory.removeTile(0);
145         mTestFragment.onCreatePreferences(new Bundle(), "rootKey");
146 
147         verify(mTestFragment.mScreen, never()).addPreference(nullable(Preference.class));
148     }
149 
150     @Test
151     @Config(qualifiers = "mcc999")
displayTilesAsPreference_shouldNotAddSuppressedTiles()152     public void displayTilesAsPreference_shouldNotAddSuppressedTiles() {
153         when(mFakeFeatureFactory.dashboardFeatureProvider
154                 .getTilesForCategory(nullable(String.class)))
155                 .thenReturn(mDashboardCategory);
156         when(mFakeFeatureFactory.dashboardFeatureProvider
157                 .getDashboardKeyForTile(nullable(Tile.class)))
158                 .thenReturn("test_key");
159         mTestFragment.onCreatePreferences(new Bundle(), "rootKey");
160 
161         verify(mTestFragment.mScreen, never()).addPreference(nullable(Preference.class));
162     }
163 
164     @Test
onAttach_shouldCreatePlaceholderPreferenceController()165     public void onAttach_shouldCreatePlaceholderPreferenceController() {
166         final AbstractPreferenceController controller = mTestFragment.use(
167                 DashboardTilePlaceholderPreferenceController.class);
168 
169         assertThat(controller).isNotNull();
170     }
171 
172     @Test
updateState_skipUnavailablePrefs()173     public void updateState_skipUnavailablePrefs() {
174         final List<AbstractPreferenceController> preferenceControllers = mTestFragment.mControllers;
175         final AbstractPreferenceController mockController1 =
176                 mock(AbstractPreferenceController.class);
177         final AbstractPreferenceController mockController2 =
178                 mock(AbstractPreferenceController.class);
179         when(mockController1.getPreferenceKey()).thenReturn("key1");
180         when(mockController2.getPreferenceKey()).thenReturn("key2");
181         preferenceControllers.add(mockController1);
182         preferenceControllers.add(mockController2);
183         when(mockController1.isAvailable()).thenReturn(false);
184         when(mockController2.isAvailable()).thenReturn(true);
185         mTestFragment.onAttach(RuntimeEnvironment.application);
186         mTestFragment.onResume();
187 
188         verify(mockController1).getPreferenceKey();
189         verify(mockController2, times(2)).getPreferenceKey();
190     }
191 
192     @Test
updateState_doesNotSkipControllersOfSameClass()193     public void updateState_doesNotSkipControllersOfSameClass() {
194         final AbstractPreferenceController mockController1 =
195                 mock(AbstractPreferenceController.class);
196         final AbstractPreferenceController mockController2 =
197                 mock(AbstractPreferenceController.class);
198         mTestFragment.addPreferenceController(mockController1);
199         mTestFragment.addPreferenceController(mockController2);
200         when(mockController1.isAvailable()).thenReturn(true);
201         when(mockController2.isAvailable()).thenReturn(true);
202 
203         mTestFragment.updatePreferenceStates();
204 
205         verify(mockController1).getPreferenceKey();
206         verify(mockController2).getPreferenceKey();
207     }
208 
209     @Test
onExpandButtonClick_shouldLogAdvancedButtonExpand()210     public void onExpandButtonClick_shouldLogAdvancedButtonExpand() {
211         final MetricsFeatureProvider metricsFeatureProvider
212                 = mFakeFeatureFactory.getMetricsFeatureProvider();
213         mTestFragment.onExpandButtonClick();
214 
215         verify(metricsFeatureProvider).action(SettingsEnums.PAGE_UNKNOWN,
216                 MetricsEvent.ACTION_SETTINGS_ADVANCED_BUTTON_EXPAND,
217                 DASHBOARD_CONTAINER, null, 0);
218     }
219 
220     @Test
updatePreferenceVisibility_prefKeyNull_shouldNotCrash()221     public void updatePreferenceVisibility_prefKeyNull_shouldNotCrash() {
222         final Map<Class, List<AbstractPreferenceController>> prefControllers = new HashMap<>();
223         final List<AbstractPreferenceController> controllerList = new ArrayList<>();
224         controllerList.add(new TestPreferenceController(mContext));
225         prefControllers.put(TestPreferenceController.class, controllerList);
226         mTestFragment.mBlockerController = new UiBlockerController(Arrays.asList("pref_key"));
227 
228         // Should not crash
229         mTestFragment.updatePreferenceVisibility(prefControllers);
230     }
231 
232     @Test
checkUiBlocker_noUiBlocker_controllerIsNull()233     public void checkUiBlocker_noUiBlocker_controllerIsNull() {
234         mTestFragment.mBlockerController = null;
235         mControllers.add(new TestPreferenceController(mContext));
236 
237         mTestFragment.checkUiBlocker(mControllers);
238 
239         assertThat(mTestFragment.mBlockerController).isNull();
240     }
241 
242     @Test
checkUiBlocker_hasUiBlocker_controllerNotNull()243     public void checkUiBlocker_hasUiBlocker_controllerNotNull() {
244         mTestFragment.mBlockerController = null;
245         mControllers.add(new TestPreferenceController(mContext));
246         mControllers.add(new BlockingSlicePrefController(mContext, "pref_key"));
247 
248         mTestFragment.checkUiBlocker(mControllers);
249 
250         assertThat(mTestFragment.mBlockerController).isNotNull();
251     }
252 
253     public static class TestPreferenceController extends AbstractPreferenceController
254             implements PreferenceControllerMixin {
255 
TestPreferenceController(Context context)256         private TestPreferenceController(Context context) {
257             super(context);
258         }
259 
260         @Override
handlePreferenceTreeClick(Preference preference)261         public boolean handlePreferenceTreeClick(Preference preference) {
262             return false;
263         }
264 
265         @Override
isAvailable()266         public boolean isAvailable() {
267             return false;
268         }
269 
270         @Override
getPreferenceKey()271         public String getPreferenceKey() {
272             return null;
273         }
274 
275         @Override
updateNonIndexableKeys(List<String> keys)276         public void updateNonIndexableKeys(List<String> keys) {
277         }
278     }
279 
280     public static class TestFragment extends DashboardFragment {
281 
282         private final PreferenceManager mPreferenceManager;
283         private final Context mContext;
284         private final List<AbstractPreferenceController> mControllers;
285 
286         public final PreferenceScreen mScreen;
287 
TestFragment(Context context)288         public TestFragment(Context context) {
289             mContext = context;
290             mPreferenceManager = mock(PreferenceManager.class);
291             mScreen = mock(PreferenceScreen.class);
292             mControllers = new ArrayList<>();
293 
294             when(mPreferenceManager.getContext()).thenReturn(mContext);
295             ReflectionHelpers.setField(
296                     this, "mVisibilityLoggerMixin", mock(VisibilityLoggerMixin.class));
297         }
298 
299         @Override
getContext()300         public Context getContext() {
301             return mContext;
302         }
303 
304         @Override
getMetricsCategory()305         public int getMetricsCategory() {
306             return DASHBOARD_CONTAINER;
307         }
308 
309         @Override
getPreferenceScreen()310         public PreferenceScreen getPreferenceScreen() {
311             return mScreen;
312         }
313 
314         @Override
getLogTag()315         protected String getLogTag() {
316             return "TEST_FRAG";
317         }
318 
319         @Override
getPreferenceScreenResId()320         protected int getPreferenceScreenResId() {
321             return 0;
322         }
323 
324         @Override
createPreferenceControllers(Context context)325         protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
326             return mControllers;
327         }
328 
329         @Override
getPreferenceManager()330         public PreferenceManager getPreferenceManager() {
331             return mPreferenceManager;
332         }
333     }
334 }
335