• 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 
17 package com.android.settings.dashboard;
18 
19 import android.content.Context;
20 import android.support.v14.preference.PreferenceFragment;
21 import android.support.v7.preference.Preference;
22 import android.support.v7.preference.PreferenceManager;
23 import android.support.v7.preference.PreferenceScreen;
24 
25 import com.android.settings.R;
26 import com.android.settings.SettingsRobolectricTestRunner;
27 import com.android.settings.TestConfig;
28 import com.android.settings.testutils.FakeFeatureFactory;
29 
30 import org.junit.Before;
31 import org.junit.Test;
32 import org.junit.runner.RunWith;
33 import org.mockito.Answers;
34 import org.mockito.Mock;
35 import org.mockito.MockitoAnnotations;
36 import org.robolectric.annotation.Config;
37 import org.robolectric.shadows.ShadowApplication;
38 import org.robolectric.util.ReflectionHelpers;
39 
40 import java.util.List;
41 
42 import static com.google.common.truth.Truth.assertThat;
43 import static org.mockito.Matchers.any;
44 import static org.mockito.Matchers.anyInt;
45 import static org.mockito.Matchers.anyString;
46 import static org.mockito.Mockito.atLeastOnce;
47 import static org.mockito.Mockito.mock;
48 import static org.mockito.Mockito.never;
49 import static org.mockito.Mockito.spy;
50 import static org.mockito.Mockito.times;
51 import static org.mockito.Mockito.verify;
52 import static org.mockito.Mockito.when;
53 
54 @RunWith(SettingsRobolectricTestRunner.class)
55 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
56 public class ProgressiveDisclosureTest {
57 
58     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
59     private Context mContext;
60     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
61     private PreferenceFragment mPreferenceFragment;
62     @Mock
63     private ExpandPreference mExpandButton;
64     private PreferenceScreen mScreen;
65     private Context mAppContext;
66     private Preference mPreference;
67     private ProgressiveDisclosureMixin mMixin;
68 
69     @Before
setUp()70     public void setUp() {
71         MockitoAnnotations.initMocks(this);
72         FakeFeatureFactory.setupForTest(mContext);
73         mScreen = mPreferenceFragment.getPreferenceScreen();
74         mAppContext = ShadowApplication.getInstance().getApplicationContext();
75         mMixin = new ProgressiveDisclosureMixin(mAppContext,
76                 mPreferenceFragment, false /* keepExpanded */);
77         ReflectionHelpers.setField(mMixin, "mExpandButton", mExpandButton);
78         mPreference = new Preference(mAppContext);
79         mPreference.setKey("test");
80     }
81 
82     @Test
shouldNotCollapse_lessPreferenceThanLimit()83     public void shouldNotCollapse_lessPreferenceThanLimit() {
84         when(mScreen.getPreferenceCount()).thenReturn(5);
85 
86         mMixin.setTileLimit(10);
87 
88         assertThat(mMixin.shouldCollapse(mScreen)).isFalse();
89     }
90 
91     @Test
shouldNotCollapse_preferenceCountSameAsThreshold()92     public void shouldNotCollapse_preferenceCountSameAsThreshold() {
93         when(mScreen.getPreferenceCount()).thenReturn(5);
94 
95         mMixin.setTileLimit(5);
96 
97         assertThat(mMixin.shouldCollapse(mScreen)).isFalse();
98     }
99 
100     @Test
shouldNotCollapse_whenStartAsExpanded()101     public void shouldNotCollapse_whenStartAsExpanded() {
102         when(mScreen.getPreferenceCount()).thenReturn(5);
103 
104         mMixin = new ProgressiveDisclosureMixin(mAppContext,
105                 mPreferenceFragment, true /* keepExpanded */);
106         mMixin.setTileLimit(10);
107 
108         assertThat(mMixin.shouldCollapse(mScreen)).isFalse();
109     }
110 
111     @Test
shouldCollapse_morePreferenceThanLimit()112     public void shouldCollapse_morePreferenceThanLimit() {
113         when(mScreen.getPreferenceCount()).thenReturn(5);
114         mMixin.setTileLimit(3);
115 
116         assertThat(mMixin.shouldCollapse(mScreen)).isTrue();
117     }
118 
119     @Test
findPreference_prefInCollapsedList_shouldFindIt()120     public void findPreference_prefInCollapsedList_shouldFindIt() {
121         when(mScreen.findPreference(anyString())).thenReturn(null);
122         mMixin.addToCollapsedList(mPreference);
123 
124         Preference pref = mMixin.findPreference(mScreen, mPreference.getKey());
125 
126         assertThat(pref).isNotNull();
127         assertThat(pref).isSameAs(mPreference);
128     }
129 
130     @Test
findPreference_prefOnScreen_shouldFindIt()131     public void findPreference_prefOnScreen_shouldFindIt() {
132         when(mScreen.findPreference(mPreference.getKey())).thenReturn(mPreference);
133 
134         Preference pref = mMixin.findPreference(mScreen, mPreference.getKey());
135 
136         assertThat(pref).isNotNull();
137         assertThat(pref).isSameAs(mPreference);
138     }
139 
140     @Test
findPreference_prefNotInCollapsedListOrScreen_shouldNotFindIt()141     public void findPreference_prefNotInCollapsedListOrScreen_shouldNotFindIt() {
142         when(mScreen.findPreference(anyString())).thenReturn(null);
143         Preference pref = mMixin.findPreference(mScreen, mPreference.getKey());
144 
145         assertThat(pref).isNull();
146     }
147 
148     @Test
findPreference_prefRemovedFromCollapsedList_shouldNotFindIt()149     public void findPreference_prefRemovedFromCollapsedList_shouldNotFindIt() {
150         when(mScreen.findPreference(anyString())).thenReturn(null);
151         mMixin.addToCollapsedList(mPreference);
152         mMixin.removePreference(mPreferenceFragment.getPreferenceScreen(), mPreference.getKey());
153 
154         Preference pref = mMixin.findPreference(mScreen, mPreference.getKey());
155 
156         assertThat(pref).isNull();
157     }
158 
159     @Test
findPreference_nestedPrefInCollapsedList_shouldFindIt()160     public void findPreference_nestedPrefInCollapsedList_shouldFindIt() {
161         when(mScreen.findPreference(anyString())).thenReturn(null);
162         final PreferenceScreen prefGroup = spy(new PreferenceScreen(mAppContext, null));
163         when(prefGroup.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
164         final Preference preference = mock(Preference.class);
165         when(preference.getKey()).thenReturn("TestKey");
166         prefGroup.addPreference(preference);
167         mMixin.addToCollapsedList(prefGroup);
168 
169         Preference pref = mMixin.findPreference(mScreen, "TestKey");
170 
171         assertThat(pref).isNotNull();
172         assertThat(pref).isSameAs(preference);
173     }
174 
175     @Test
removePreference_shouldRemoveOnScreenPreference()176     public void removePreference_shouldRemoveOnScreenPreference() {
177         when(mScreen.findPreference(mPreference.getKey())).thenReturn(mPreference);
178 
179         mMixin.removePreference(mScreen, mPreference.getKey());
180 
181         verify(mScreen).removePreference(mPreference);
182     }
183 
184     @Test
removeLastPreference_shouldRemoveExpandButtonToo()185     public void removeLastPreference_shouldRemoveExpandButtonToo() {
186         when(mScreen.findPreference(anyString())).thenReturn(null);
187         mMixin.addToCollapsedList(mPreference);
188         // Collapsed
189         assertThat(mMixin.isCollapsed()).isTrue();
190 
191         mMixin.removePreference(mScreen, mPreference.getKey());
192 
193         // Removing expand button
194         verify(mScreen).removePreference(any(Preference.class));
195         // No longer collapsed
196         assertThat(mMixin.isCollapsed()).isFalse();
197     }
198 
199     @Test
collapse_shouldDoNothingIfNotCollapsible()200     public void collapse_shouldDoNothingIfNotCollapsible() {
201         final PreferenceScreen screen = mPreferenceFragment.getPreferenceScreen();
202         when(screen.getPreferenceCount()).thenReturn(5);
203         mMixin.setTileLimit(15);
204 
205         mMixin.collapse(screen);
206         assertThat(mMixin.isCollapsed()).isFalse();
207         verify(mExpandButton, never()).setSummary(anyString());
208         verify(screen, never()).addPreference(any(Preference.class));
209         verify(screen, never()).removePreference(any(Preference.class));
210     }
211 
212     @Test
collapse_shouldRemovePrefAndAddExpandButton()213     public void collapse_shouldRemovePrefAndAddExpandButton() {
214         final PreferenceScreen screen = mPreferenceFragment.getPreferenceScreen();
215         when(screen.getPreferenceCount()).thenReturn(5);
216         when(screen.getPreference(anyInt())).thenReturn(mPreference);
217         mMixin.setTileLimit(2);
218 
219         mMixin.collapse(screen);
220 
221         assertThat(mMixin.isCollapsed()).isTrue();
222         verify(mExpandButton, atLeastOnce()).setSummary(anyString());
223         verify(screen).addPreference(any(ExpandPreference.class));
224         verify(screen, times(3)).removePreference(any(Preference.class));
225     }
226 
227     @Test
addToCollapsedList_shouldAddInOrder()228     public void addToCollapsedList_shouldAddInOrder() {
229         final Preference pref1 = new Preference(mAppContext);
230         final Preference pref2 = new Preference(mAppContext);
231         pref1.setOrder(10);
232         pref2.setOrder(20);
233 
234         // Pref1 has lower order than pref2, but add pref2 first. The collapsed list should maintain
235         // items in increasing order.
236         mMixin.addToCollapsedList(pref2);
237         mMixin.addToCollapsedList(pref1);
238 
239         List<Preference> collapsedList = mMixin.getCollapsedPrefs();
240         assertThat(collapsedList.get(0)).isSameAs(pref1);
241         assertThat(collapsedList.get(1)).isSameAs(pref2);
242     }
243 
244     @Test
addPreferenceWhenCollapsed_noPrefOnScreen_shouldAddToList()245     public void addPreferenceWhenCollapsed_noPrefOnScreen_shouldAddToList() {
246         // Add something to collapsed list so we are in collapsed state.
247         mMixin.addToCollapsedList(new Preference(mAppContext));
248         assertThat(mMixin.getCollapsedPrefs().size()).isEqualTo(1);
249 
250         // Just 1 preference on screen: the more button
251         when(mScreen.getPreferenceCount()).thenReturn(1);
252         final Preference toBeAdded = new Preference(mAppContext);
253         toBeAdded.setOrder(100);
254         mMixin.addPreference(mScreen, toBeAdded);
255 
256         // Should have 2 prefs in collapsed list now
257         assertThat(mMixin.getCollapsedPrefs().size()).isEqualTo(2);
258         assertThat(mMixin.getCollapsedPrefs().get(0)).isSameAs(toBeAdded);
259     }
260 
261     @Test
addPreferenceWhenCollapsed_prefOrderLessThanLastOnScreen_shouldAddToScreen()262     public void addPreferenceWhenCollapsed_prefOrderLessThanLastOnScreen_shouldAddToScreen() {
263         final Preference lastPref = new Preference(mAppContext);
264         lastPref.setOrder(100);
265         // Add something to collapsed list so we are in collapsed state.
266         mMixin.addToCollapsedList(new Preference(mAppContext));
267         verify(mExpandButton).setSummary(anyString());
268         assertThat(mMixin.getCollapsedPrefs().size()).isEqualTo(1);
269 
270         // 3 prefs on screen, 2 are real and the last one is more button.
271         when(mScreen.getPreferenceCount()).thenReturn(3);
272         when(mScreen.getPreference(1)).thenReturn(lastPref);
273 
274         final Preference toBeAdded = new Preference(mAppContext);
275         toBeAdded.setOrder(50);
276         mMixin.addPreference(mScreen, toBeAdded);
277 
278         verify(mScreen).removePreference(lastPref);
279         verify(mScreen).addPreference(toBeAdded);
280         assertThat(mMixin.getCollapsedPrefs().get(0)).isSameAs(lastPref);
281     }
282 
283     @Test
addPreferenceWhenCollapsed_prefOrderMoreThanLastOnScreen_shouldAddToList()284     public void addPreferenceWhenCollapsed_prefOrderMoreThanLastOnScreen_shouldAddToList() {
285         final Preference lastPref = new Preference(mAppContext);
286         lastPref.setOrder(100);
287         // Add something to collapsed list so we are in collapsed state.
288         mMixin.addToCollapsedList(new Preference(mAppContext));
289         verify(mExpandButton).setSummary(anyString());
290         assertThat(mMixin.getCollapsedPrefs().size()).isEqualTo(1);
291 
292         // 3 prefs on screen, 2 are real and the last one is more button.
293         when(mScreen.getPreferenceCount()).thenReturn(3);
294         when(mScreen.getPreference(1)).thenReturn(lastPref);
295 
296         final Preference toBeAdded = new Preference(mAppContext);
297         toBeAdded.setOrder(200);
298         mMixin.addPreference(mScreen, toBeAdded);
299 
300         verify(mScreen, never()).removePreference(any(Preference.class));
301         verify(mScreen, never()).addPreference(any(Preference.class));
302         verify(mExpandButton, times(2)).setSummary(anyString());
303         assertThat(mMixin.getCollapsedPrefs().get(0)).isSameAs(toBeAdded);
304     }
305 
306     @Test
updateExpandSummary_noPref_noSummary()307     public void updateExpandSummary_noPref_noSummary() {
308         mMixin.updateExpandButtonSummary();
309 
310         verify(mExpandButton).setSummary(null);
311     }
312 
313     @Test
updateExpandSummary_doNotIncludeEmptyPrefTitle()314     public void updateExpandSummary_doNotIncludeEmptyPrefTitle() {
315         final Preference pref1 = new Preference(mAppContext);
316         pref1.setTitle("1");
317         final Preference pref2 = new Preference(mAppContext);
318         pref2.setTitle(null);
319         final Preference pref3 = new Preference(mAppContext);
320         pref3.setTitle("3");
321         final Preference pref4 = new Preference(mAppContext);
322         pref4.setTitle("");
323 
324         mMixin.addToCollapsedList(pref1);
325         mMixin.addToCollapsedList(pref2);
326         mMixin.addToCollapsedList(pref3);
327         mMixin.addToCollapsedList(pref4);
328 
329         verify(mExpandButton).setSummary("1, 3");
330     }
331 
332     @Test
updateExapndSummary_singlePref_expandSummarySameAsPrefTitle()333     public void updateExapndSummary_singlePref_expandSummarySameAsPrefTitle() {
334         final String TEST = "test";
335         final Preference pref = new Preference(mAppContext);
336         pref.setTitle(TEST);
337 
338         mMixin.addToCollapsedList(pref);
339         verify(mExpandButton).setSummary(TEST);
340     }
341 
342     @Test
updateExapndSummary_multiPrefs_useCombinedPrefTitleAsSummary()343     public void updateExapndSummary_multiPrefs_useCombinedPrefTitleAsSummary() {
344         final String TEST1 = "test1";
345         final String TEST2 = "test2";
346         final Preference pref1 = new Preference(mAppContext);
347         pref1.setTitle(TEST1);
348         final Preference pref2 = new Preference(mAppContext);
349         pref2.setTitle(TEST2);
350 
351         mMixin.addToCollapsedList(pref1);
352         mMixin.addToCollapsedList(pref2);
353 
354         verify(mExpandButton)
355                 .setSummary(mAppContext.getString(R.string.join_many_items_middle, TEST1, TEST2));
356     }
357 }
358