Home | History | Annotate | Download | only in cts
      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 android.preference2.cts;
     18 
     19 import static org.junit.Assert.assertEquals;
     20 import static org.junit.Assert.assertNotNull;
     21 import static org.junit.Assert.assertNull;
     22 import static org.junit.Assert.assertTrue;
     23 import static org.mockito.AdditionalMatchers.or;
     24 import static org.mockito.Matchers.any;
     25 import static org.mockito.Matchers.anyBoolean;
     26 import static org.mockito.Matchers.anyFloat;
     27 import static org.mockito.Matchers.anyInt;
     28 import static org.mockito.Matchers.anyLong;
     29 import static org.mockito.Matchers.anyString;
     30 import static org.mockito.Matchers.eq;
     31 import static org.mockito.Matchers.isNull;
     32 import static org.mockito.Matchers.nullable;
     33 import static org.mockito.Mockito.atLeast;
     34 import static org.mockito.Mockito.atLeastOnce;
     35 import static org.mockito.Mockito.mock;
     36 import static org.mockito.Mockito.verify;
     37 import static org.mockito.Mockito.verifyNoMoreInteractions;
     38 import static org.mockito.Mockito.verifyZeroInteractions;
     39 import static org.mockito.Mockito.when;
     40 
     41 import android.content.Context;
     42 import android.content.SharedPreferences;
     43 import android.preference.CheckBoxPreference;
     44 import android.preference.Preference;
     45 import android.preference.PreferenceDataStore;
     46 import android.preference.PreferenceManager;
     47 import android.preference.PreferenceScreen;
     48 import android.support.test.filters.SmallTest;
     49 import android.support.test.rule.ActivityTestRule;
     50 import android.support.test.runner.AndroidJUnit4;
     51 
     52 import org.junit.Before;
     53 import org.junit.Rule;
     54 import org.junit.Test;
     55 import org.junit.runner.RunWith;
     56 
     57 import java.util.HashSet;
     58 import java.util.Set;
     59 
     60 @SmallTest
     61 @RunWith(AndroidJUnit4.class)
     62 public class PreferenceDataStoreTest {
     63 
     64     private PreferenceFragmentActivity mActivity;
     65     private PreferenceWrapper mPreference;
     66     private PreferenceDataStore mDataStore;
     67     private PreferenceScreen mScreen;
     68     private PreferenceManager mManager;
     69     private SharedPreferences mSharedPref;
     70 
     71     private static final String KEY = "TestPrefKey";
     72     private static final String TEST_STR = "Test";
     73     private static final String TEST_DEFAULT_STR = "TestDefault";
     74     private static final String TEST_WRONG_STR = "TestFromSharedPref";
     75 
     76     @Rule
     77     public ActivityTestRule<PreferenceFragmentActivity> mActivityRule =
     78             new ActivityTestRule<>(PreferenceFragmentActivity.class);
     79 
     80 
     81     @Before
     82     public void setup() {
     83         mActivity = mActivityRule.getActivity();
     84         mPreference = new PreferenceWrapper(mActivity);
     85         mPreference.setKey(KEY);
     86 
     87         // Assign the Preference to the PreferenceFragment.
     88         mScreen = mActivity.prefFragment.getPreferenceManager().createPreferenceScreen(mActivity);
     89         mManager = mScreen.getPreferenceManager();
     90         mSharedPref = mManager.getSharedPreferences();
     91 
     92         mDataStore = mock(PreferenceDataStore.class);
     93 
     94         // Make sure that the key is not present in SharedPreferences to ensure test correctness.
     95         mManager.getSharedPreferences().edit().remove(KEY).commit();
     96     }
     97 
     98     @Test
     99     public void testThatDataStoreIsNullByDefault() {
    100         Preference preference = new Preference(mActivity);
    101         mScreen.addPreference(preference);
    102 
    103         assertNull(preference.getPreferenceDataStore());
    104         assertNotNull(preference.getSharedPreferences());
    105 
    106         assertNull(mManager.getPreferenceDataStore());
    107         assertNotNull(mManager.getSharedPreferences());
    108     }
    109 
    110     @Test
    111     public void testSetGetOnPreference() {
    112         Preference preference = new Preference(mActivity);
    113         preference.setPreferenceDataStore(mDataStore);
    114 
    115         assertEquals(mDataStore, preference.getPreferenceDataStore());
    116         assertNull(preference.getSharedPreferences());
    117     }
    118 
    119     @Test
    120     public void testSetGetOnPreferenceManager() {
    121         mManager.setPreferenceDataStore(mDataStore);
    122 
    123         assertEquals(mDataStore, mManager.getPreferenceDataStore());
    124         assertNull(mManager.getSharedPreferences());
    125     }
    126 
    127     @Test
    128     public void testSetOnPreferenceManagerGetOnPreference() {
    129         Preference preference = new Preference(mActivity);
    130         mScreen.addPreference(preference);
    131         mManager.setPreferenceDataStore(mDataStore);
    132 
    133         assertEquals(mDataStore, preference.getPreferenceDataStore());
    134         assertNull(preference.getSharedPreferences());
    135     }
    136 
    137     @Test
    138     public void testDataStoresHierarchy() {
    139         mPreference.setPreferenceDataStore(mDataStore);
    140         PreferenceDataStore secondaryDataStore = mock(PreferenceDataStore.class);
    141         mScreen.addPreference(mPreference);
    142         mManager.setPreferenceDataStore(secondaryDataStore);
    143         mPreference.putString(TEST_STR);
    144 
    145         // Check that the Preference returns the correct data store.
    146         assertEquals(mDataStore, mPreference.getPreferenceDataStore());
    147 
    148         // Check that the secondary data store assigned to the manager was NOT used.
    149         verifyZeroInteractions(secondaryDataStore);
    150 
    151         // Check that the primary data store assigned directly to the preference was used.
    152         verify(mDataStore, atLeastOnce()).getString(eq(KEY), any());
    153     }
    154 
    155     @Test
    156     public void testPutStringWithDataStoreOnPref() {
    157         mPreference.setPreferenceDataStore(mDataStore);
    158         mScreen.addPreference(mPreference);
    159         putStringTestCommon();
    160     }
    161 
    162     @Test
    163     public void testPutStringWithDataStoreOnMgr() {
    164         mManager.setPreferenceDataStore(mDataStore);
    165         mScreen.addPreference(mPreference);
    166         putStringTestCommon();
    167     }
    168 
    169     private void putStringTestCommon() {
    170         mPreference.putString(TEST_STR);
    171 
    172         verify(mDataStore, atLeast(0)).getString(eq(KEY), nullable(String.class));
    173         verify(mDataStore, atLeastOnce()).putString(eq(KEY), anyString());
    174         verifyNoMoreInteractions(mDataStore);
    175 
    176         // Test that the value was NOT propagated to SharedPreferences.
    177         assertNull(mSharedPref.getString(KEY, null));
    178     }
    179 
    180     @Test
    181     public void testGetStringWithDataStoreOnPref() {
    182         mPreference.setPreferenceDataStore(mDataStore);
    183         mScreen.addPreference(mPreference);
    184         mPreference.getString(TEST_STR);
    185         verify(mDataStore, atLeastOnce()).getString(eq(KEY), eq(TEST_STR));
    186     }
    187 
    188     @Test
    189     public void testGetStringWithDataStoreOnMgr() {
    190         mManager.setPreferenceDataStore(mDataStore);
    191         mScreen.addPreference(mPreference);
    192         mPreference.getString(TEST_STR);
    193         verify(mDataStore, atLeastOnce()).getString(eq(KEY), eq(TEST_STR));
    194     }
    195 
    196     /**
    197      * This test makes sure that when a default value is set to a preference that has a data store
    198      * assigned that the default value is correctly propagated to
    199      * {@link Preference#onSetInitialValue(boolean, Object)} instead of passing a value from
    200      * {@link android.content.SharedPreferences}. We have this test only for String because the
    201      * implementation is not dependent on value type so this coverage should be fine.
    202      */
    203     @Test
    204     public void testDefaultStringValue() {
    205         mPreference.setPreferenceDataStore(mDataStore);
    206         mPreference.setDefaultValue(TEST_DEFAULT_STR);
    207         mSharedPref.edit().putString(KEY, TEST_WRONG_STR).commit();
    208         mScreen.addPreference(mPreference);
    209         mSharedPref.edit().remove(KEY).commit();
    210         assertEquals(TEST_DEFAULT_STR, mPreference.defaultValue);
    211     }
    212 
    213     /**
    214      * Test that the initial value is taken from the data store (before the preference gets assigned
    215      * to the preference hierarchy).
    216      */
    217     @Test
    218     public void testInitialValueIsFromDataStoreOnPreference() {
    219         when(mDataStore.getBoolean(anyString(), anyBoolean())).thenReturn(true);
    220 
    221         CheckBoxPreference pref = new CheckBoxPreference(mActivityRule.getActivity());
    222         pref.setKey("CheckboxTestPref");
    223         pref.setPreferenceDataStore(mDataStore);
    224 
    225         mScreen.addPreference(pref);
    226 
    227         assertTrue(pref.isChecked());
    228     }
    229 
    230     /**
    231      * Test that the initial value is taken from the data store (before the preference gets assigned
    232      * to the preference hierarchy).
    233      */
    234     @Test
    235     public void testInitialValueIsFromDataStoreOnPreferenceManager() {
    236         when(mDataStore.getBoolean(anyString(), anyBoolean())).thenReturn(true);
    237         mManager.setPreferenceDataStore(mDataStore);
    238 
    239         CheckBoxPreference pref = new CheckBoxPreference(mActivityRule.getActivity());
    240         pref.setKey("CheckboxTestPref");
    241 
    242         mScreen.addPreference(pref);
    243 
    244         assertTrue(pref.isChecked());
    245     }
    246 
    247     @Test
    248     public void testPutStringSetWithDataStoreOnPref() {
    249         mPreference.setPreferenceDataStore(mDataStore);
    250         mScreen.addPreference(mPreference);
    251         putStringSetTestCommon();
    252     }
    253 
    254     @Test
    255     public void testPutStringSetWithDataStoreOnMgr() {
    256         mManager.setPreferenceDataStore(mDataStore);
    257         mScreen.addPreference(mPreference);
    258         putStringSetTestCommon();
    259     }
    260 
    261     private void putStringSetTestCommon() {
    262         Set<String> testSet = new HashSet<>();
    263         testSet.add(TEST_STR);
    264         mPreference.putStringSet(testSet);
    265 
    266         verify(mDataStore, atLeast(0)).getStringSet(eq(KEY), or(isNull(Set.class), any()));
    267         verify(mDataStore, atLeastOnce()).putStringSet(eq(KEY), or(isNull(Set.class), any()));
    268         verifyNoMoreInteractions(mDataStore);
    269 
    270         // Test that the value was NOT propagated to SharedPreferences.
    271         assertNull(mSharedPref.getStringSet(KEY, null));
    272     }
    273 
    274     @Test
    275     public void testGetStringSetWithDataStoreOnPref() {
    276         mPreference.setPreferenceDataStore(mDataStore);
    277         mScreen.addPreference(mPreference);
    278         Set<String> testSet = new HashSet<>();
    279         mPreference.getStringSet(testSet);
    280         verify(mDataStore, atLeastOnce()).getStringSet(eq(KEY), eq(testSet));
    281     }
    282 
    283     @Test
    284     public void testGetStringSetWithDataStoreOnMgr() {
    285         mManager.setPreferenceDataStore(mDataStore);
    286         mScreen.addPreference(mPreference);
    287         Set<String> testSet = new HashSet<>();
    288         mPreference.getStringSet(testSet);
    289         verify(mDataStore, atLeastOnce()).getStringSet(eq(KEY), eq(testSet));
    290     }
    291 
    292     @Test
    293     public void testPutIntWithDataStoreOnPref() {
    294         mPreference.setPreferenceDataStore(mDataStore);
    295         mScreen.addPreference(mPreference);
    296         putIntTestCommon();
    297     }
    298 
    299     @Test
    300     public void testPutIntWithDataStoreOnMgr() {
    301         mManager.setPreferenceDataStore(mDataStore);
    302         mScreen.addPreference(mPreference);
    303         putIntTestCommon();
    304     }
    305 
    306     private void putIntTestCommon() {
    307         mPreference.putInt(1);
    308 
    309         verify(mDataStore, atLeast(0)).getInt(eq(KEY), anyInt());
    310         verify(mDataStore, atLeastOnce()).putInt(eq(KEY), anyInt());
    311         verifyNoMoreInteractions(mDataStore);
    312 
    313         // Test that the value was NOT propagated to SharedPreferences.
    314         assertEquals(-1, mSharedPref.getInt(KEY, -1));
    315     }
    316 
    317     @Test
    318     public void testGetIntWithDataStoreOnPref() {
    319         mPreference.setPreferenceDataStore(mDataStore);
    320         mScreen.addPreference(mPreference);
    321         mPreference.getInt(1);
    322         verify(mDataStore, atLeastOnce()).getInt(eq(KEY), eq(1));
    323     }
    324 
    325     @Test
    326     public void testGetIntWithDataStoreOnMgr() {
    327         mManager.setPreferenceDataStore(mDataStore);
    328         mScreen.addPreference(mPreference);
    329         mPreference.getInt(1);
    330         verify(mDataStore, atLeastOnce()).getInt(eq(KEY), eq(1));
    331     }
    332 
    333     @Test
    334     public void testPutLongWithDataStoreOnPref() {
    335         mPreference.setPreferenceDataStore(mDataStore);
    336         mScreen.addPreference(mPreference);
    337         putLongTestCommon();
    338     }
    339 
    340     @Test
    341     public void testPutLongWithDataStoreOnMgr() {
    342         mManager.setPreferenceDataStore(mDataStore);
    343         mScreen.addPreference(mPreference);
    344         putLongTestCommon();
    345     }
    346 
    347     private void putLongTestCommon() {
    348         mPreference.putLong(1L);
    349 
    350         verify(mDataStore, atLeast(0)).getLong(eq(KEY), anyLong());
    351         verify(mDataStore, atLeastOnce()).putLong(eq(KEY), anyLong());
    352         verifyNoMoreInteractions(mDataStore);
    353 
    354         // Test that the value was NOT propagated to SharedPreferences.
    355         assertEquals(-1, mSharedPref.getLong(KEY, -1L));
    356     }
    357 
    358     @Test
    359     public void testGetLongWithDataStoreOnPref() {
    360         mPreference.setPreferenceDataStore(mDataStore);
    361         mScreen.addPreference(mPreference);
    362         mPreference.getLong(1L);
    363         verify(mDataStore, atLeastOnce()).getLong(eq(KEY), eq(1L));
    364     }
    365 
    366     @Test
    367     public void testGetLongWithDataStoreOnMgr() {
    368         mManager.setPreferenceDataStore(mDataStore);
    369         mScreen.addPreference(mPreference);
    370         mPreference.getLong(1L);
    371         verify(mDataStore, atLeastOnce()).getLong(eq(KEY), eq(1L));
    372     }
    373 
    374     @Test
    375     public void testPutFloatWithDataStoreOnPref() {
    376         mPreference.setPreferenceDataStore(mDataStore);
    377         mScreen.addPreference(mPreference);
    378         putFloatTestCommon();
    379     }
    380 
    381     @Test
    382     public void testPutFloatWithDataStoreOnMgr() {
    383         mManager.setPreferenceDataStore(mDataStore);
    384         mScreen.addPreference(mPreference);
    385         putFloatTestCommon();
    386     }
    387 
    388     private void putFloatTestCommon() {
    389         mPreference.putFloat(1f);
    390 
    391         verify(mDataStore, atLeast(0)).getFloat(eq(KEY), anyFloat());
    392         verify(mDataStore, atLeastOnce()).putFloat(eq(KEY), anyFloat());
    393         verifyNoMoreInteractions(mDataStore);
    394 
    395         // Test that the value was NOT propagated to SharedPreferences.
    396         assertEquals(-1, mSharedPref.getFloat(KEY, -1f), 0.1f /* epsilon */);
    397     }
    398 
    399     @Test
    400     public void testGetFloatWithDataStoreOnPref() {
    401         mPreference.setPreferenceDataStore(mDataStore);
    402         mScreen.addPreference(mPreference);
    403         mPreference.getFloat(1f);
    404         verify(mDataStore, atLeastOnce()).getFloat(eq(KEY), eq(1f));
    405     }
    406 
    407     @Test
    408     public void testGetFloatWithDataStoreOnMgr() {
    409         mManager.setPreferenceDataStore(mDataStore);
    410         mScreen.addPreference(mPreference);
    411         mPreference.getFloat(1f);
    412         verify(mDataStore, atLeastOnce()).getFloat(eq(KEY), eq(1f));
    413     }
    414 
    415     @Test
    416     public void testPutBooleanWithDataStoreOnPref() {
    417         mPreference.setPreferenceDataStore(mDataStore);
    418         mScreen.addPreference(mPreference);
    419         putBooleanTestCommon();
    420     }
    421 
    422     @Test
    423     public void testPutBooleanWithDataStoreOnMgr() {
    424         mManager.setPreferenceDataStore(mDataStore);
    425         mScreen.addPreference(mPreference);
    426         putBooleanTestCommon();
    427     }
    428 
    429     private void putBooleanTestCommon() {
    430         mPreference.putBoolean(true);
    431 
    432         verify(mDataStore, atLeast(0)).getBoolean(eq(KEY), anyBoolean());
    433         verify(mDataStore, atLeastOnce()).putBoolean(eq(KEY), anyBoolean());
    434         verifyNoMoreInteractions(mDataStore);
    435 
    436         // Test that the value was NOT propagated to SharedPreferences.
    437         assertEquals(false, mSharedPref.getBoolean(KEY, false));
    438     }
    439 
    440     @Test
    441     public void testGetBooleanWithDataStoreOnPref() {
    442         mPreference.setPreferenceDataStore(mDataStore);
    443         mScreen.addPreference(mPreference);
    444         mPreference.getBoolean(true);
    445         verify(mDataStore, atLeastOnce()).getBoolean(eq(KEY), eq(true));
    446     }
    447 
    448     @Test
    449     public void testGetBooleanWithDataStoreOnMgr() {
    450         mManager.setPreferenceDataStore(mDataStore);
    451         mScreen.addPreference(mPreference);
    452         mPreference.getBoolean(true);
    453         verify(mDataStore, atLeastOnce()).getBoolean(eq(KEY), eq(true));
    454     }
    455 
    456     /**
    457      * When {@link PreferenceDataStore} is NOT assigned, the getter for SharedPreferences should not
    458      * return null.
    459      */
    460     @Test
    461     public void testSharedPrefNotNullIfNoDS() {
    462         mScreen.addPreference(mPreference);
    463         assertNotNull(mPreference.getSharedPreferences());
    464         assertNotNull(mPreference.getEditor());
    465     }
    466 
    467     /**
    468      * When {@link PreferenceDataStore} is NOT assigned, the getter for SharedPreferences must not
    469      * return null for PreferenceManager.
    470      */
    471     @Test
    472     public void testSharedPrefNotNullIfNoDSMgr() {
    473         assertNotNull(mManager.getSharedPreferences());
    474     }
    475 
    476     /**
    477      * When {@link PreferenceDataStore} is assigned, the getter for SharedPreferences has to return
    478      * null.
    479      */
    480     @Test
    481     public void testSharedPrefNullIfWithDS() {
    482         mScreen.addPreference(mPreference);
    483         mPreference.setPreferenceDataStore(mDataStore);
    484         assertNull(mPreference.getSharedPreferences());
    485         assertNull(mPreference.getEditor());
    486     }
    487 
    488     /**
    489      * When {@link PreferenceDataStore} is assigned, the getter for SharedPreferences has to return
    490      * null for PreferenceManager.
    491      */
    492     @Test
    493     public void testSharedPrefNullIfWithDSMgr() {
    494         mManager.setPreferenceDataStore(mDataStore);
    495         assertNull(mManager.getSharedPreferences());
    496     }
    497 
    498     /**
    499      * Wrapper to allow to easily call protected methods.
    500      */
    501     private static class PreferenceWrapper extends Preference {
    502 
    503         Object defaultValue;
    504 
    505         PreferenceWrapper(Context context) {
    506             super(context);
    507         }
    508 
    509         void putString(String value) {
    510             persistString(value);
    511         }
    512 
    513         String getString(String defaultValue) {
    514             return getPersistedString(defaultValue);
    515         }
    516 
    517         void putStringSet(Set<String> values) {
    518             persistStringSet(values);
    519         }
    520 
    521         Set<String> getStringSet(Set<String> defaultValues) {
    522             return getPersistedStringSet(defaultValues);
    523         }
    524 
    525         void putInt(int value) {
    526             persistInt(value);
    527         }
    528 
    529         int getInt(int defaultValue) {
    530             return getPersistedInt(defaultValue);
    531         }
    532 
    533         void putLong(long value) {
    534             persistLong(value);
    535         }
    536 
    537         long getLong(long defaultValue) {
    538             return getPersistedLong(defaultValue);
    539         }
    540 
    541         void putFloat(float value) {
    542             persistFloat(value);
    543         }
    544 
    545         float getFloat(float defaultValue) {
    546             return getPersistedFloat(defaultValue);
    547         }
    548 
    549         void putBoolean(boolean value) {
    550             persistBoolean(value);
    551         }
    552 
    553         boolean getBoolean(boolean defaultValue) {
    554             return getPersistedBoolean(defaultValue);
    555         }
    556 
    557         @Override
    558         protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
    559             this.defaultValue = defaultValue;
    560             super.onSetInitialValue(restorePersistedValue, defaultValue);
    561         }
    562     }
    563 
    564 }
    565