Home | History | Annotate | Download | only in dashboard
      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
     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
     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
     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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    307     public void updateExpandSummary_noPref_noSummary() {
    308         mMixin.updateExpandButtonSummary();
    309 
    310         verify(mExpandButton).setSummary(null);
    311     }
    312 
    313     @Test
    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
    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
    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