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 17 package com.android.documentsui.prefs; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertNull; 22 import static org.junit.Assert.fail; 23 24 import android.content.SharedPreferences; 25 import android.content.SharedPreferences.Editor; 26 import android.support.test.InstrumentationRegistry; 27 import android.support.test.filters.SmallTest; 28 import android.support.test.runner.AndroidJUnit4; 29 30 import org.junit.After; 31 import org.junit.Before; 32 import org.junit.Test; 33 import org.junit.runner.RunWith; 34 35 import java.io.IOException; 36 import java.util.Map; 37 import java.util.HashMap; 38 import java.util.HashSet; 39 import java.util.Set; 40 41 @RunWith(AndroidJUnit4.class) 42 @SmallTest 43 public class PrefsBackupHelperTest { 44 45 private static final String LOCAL_PREFERENCE_1 = "rootViewMode-validPreference1"; 46 private static final String LOCAL_PREFERENCE_2 = "rootViewMode-validPreference2"; 47 private static final String SCOPED_PREFERENCE = "includeDeviceRoot"; 48 private static final String NON_BACKUP_PREFERENCE = "notBackup-invalidPreference"; 49 50 private SharedPreferences mDefaultPrefs; 51 private SharedPreferences mBackupPrefs; 52 private PrefsBackupHelper mPrefsBackupHelper; 53 54 @Before setUp()55 public void setUp() { 56 mDefaultPrefs = InstrumentationRegistry.getContext().getSharedPreferences("prefs1", 0); 57 mBackupPrefs = InstrumentationRegistry.getContext().getSharedPreferences("prefs2", 0); 58 clearSharedPrefs(); 59 mPrefsBackupHelper = new PrefsBackupHelper(mDefaultPrefs); 60 } 61 62 @After tearDown()63 public void tearDown() { 64 clearSharedPrefs(); 65 } 66 clearSharedPrefs()67 private void clearSharedPrefs() { 68 mDefaultPrefs.edit().clear().commit(); 69 mBackupPrefs.edit().clear().commit(); 70 } 71 72 @Test testPrepareBackupFile_BackupLocalPreferences()73 public void testPrepareBackupFile_BackupLocalPreferences() { 74 mDefaultPrefs.edit().putInt(LOCAL_PREFERENCE_1, 1).commit(); 75 76 mPrefsBackupHelper.getBackupPreferences(mBackupPrefs); 77 78 assertEquals(mBackupPrefs.getInt(LOCAL_PREFERENCE_1, 0), 1); 79 } 80 81 @Test testPrepareBackupFile_BackupScopedPreferences()82 public void testPrepareBackupFile_BackupScopedPreferences() { 83 mDefaultPrefs.edit().putBoolean(SCOPED_PREFERENCE, true).commit(); 84 85 mPrefsBackupHelper.getBackupPreferences(mBackupPrefs); 86 87 assertEquals(mBackupPrefs.getBoolean(SCOPED_PREFERENCE, false), true); 88 } 89 90 @Test testPrepareBackupFile_BackupNotInterestedPreferences()91 public void testPrepareBackupFile_BackupNotInterestedPreferences() { 92 mDefaultPrefs.edit().putBoolean(NON_BACKUP_PREFERENCE, true).commit(); 93 94 mPrefsBackupHelper.getBackupPreferences(mBackupPrefs); 95 96 assertFalse(mBackupPrefs.contains(NON_BACKUP_PREFERENCE)); 97 } 98 99 @Test testPrepareBackupFile_BackupUnexpectedType()100 public void testPrepareBackupFile_BackupUnexpectedType() throws Exception { 101 // Currently only Integer and Boolean type are supported. 102 mDefaultPrefs.edit().putString(LOCAL_PREFERENCE_1, "String is not accepted").commit(); 103 104 try { 105 mPrefsBackupHelper.getBackupPreferences(mBackupPrefs); 106 fail(); 107 } catch(IllegalArgumentException e) { 108 109 } finally { 110 assertFalse(mBackupPrefs.contains(LOCAL_PREFERENCE_1)); 111 } 112 } 113 114 @Test testRestorePreferences_RestoreLocalPreferences()115 public void testRestorePreferences_RestoreLocalPreferences() { 116 mBackupPrefs.edit().putInt(LOCAL_PREFERENCE_1, 1).commit(); 117 118 mPrefsBackupHelper.putBackupPreferences(mBackupPrefs); 119 120 assertEquals(mDefaultPrefs.getInt(LOCAL_PREFERENCE_1, 0), 1); 121 } 122 123 @Test testRestorePreferences_RestoreScopedPreferences()124 public void testRestorePreferences_RestoreScopedPreferences() { 125 mBackupPrefs.edit().putBoolean(SCOPED_PREFERENCE, true).commit(); 126 127 mPrefsBackupHelper.putBackupPreferences(mBackupPrefs); 128 129 assertEquals(mDefaultPrefs.getBoolean(SCOPED_PREFERENCE, false), true); 130 } 131 132 @Test testEndToEnd()133 public void testEndToEnd() { 134 // Simulating an end to end backup & restore process. At the begining, all preferences are 135 // stored in the default shared preferences file, includes preferences that we don't want 136 // to backup. 137 // 138 // On backup, we copy all preferences that we want to backup to the backup shared 139 // preferences file, and then backup that single file. 140 // 141 // On restore, we restore the backup file first, and then copy all preferences in the backup 142 // file to the app's default shared preferences file. 143 144 SharedPreferences.Editor editor = mDefaultPrefs.edit(); 145 146 // Set preferences to the default file, includes preferences that are not backed up. 147 editor.putInt(LOCAL_PREFERENCE_1, 1); 148 editor.putInt(LOCAL_PREFERENCE_2, 2); 149 editor.putBoolean(SCOPED_PREFERENCE, true); 150 editor.putBoolean(NON_BACKUP_PREFERENCE, true); 151 editor.commit(); 152 153 // Write all backed up preferences to backup shared preferences file. 154 mPrefsBackupHelper.getBackupPreferences(mBackupPrefs); 155 156 // Assume we are doing backup to the backup file. 157 158 // Clear all preferences in default shared preferences file. 159 editor.clear().commit(); 160 161 // Assume we are doing restore to the backup file. 162 163 // Copy all backuped preferences to default shared preferences file. 164 mPrefsBackupHelper.putBackupPreferences(mBackupPrefs); 165 166 // Check all preferences are correctly restored. 167 assertEquals(mDefaultPrefs.getInt(LOCAL_PREFERENCE_1, 0), 1); 168 assertEquals(mDefaultPrefs.getInt(LOCAL_PREFERENCE_2, 0), 2); 169 assertEquals(mDefaultPrefs.getBoolean(SCOPED_PREFERENCE, false), true); 170 assertFalse(mDefaultPrefs.contains(NON_BACKUP_PREFERENCE)); 171 } 172 173 @Test testPreferenceTypesSupport()174 public void testPreferenceTypesSupport() { 175 Map<String, Object> map = new HashMap<String, Object>(); 176 map.put("int", (Integer) 1); 177 map.put("float", (Float) 0.1f); 178 map.put("long", (Long) 10000000000l); 179 map.put("boolean", true); 180 map.put("String", "String"); 181 Set<String> stringSet = new HashSet<String>(); 182 stringSet.add("string1"); 183 stringSet.add("string2"); 184 map.put("StringSet", stringSet); 185 186 // SharedPreferences accept Integer, Float, Long, Boolean, String, Set<String> types. 187 // Currently in DocumentsUI, only Integer and Boolean preferences are backed up. 188 for (Map.Entry<String, ?> entry : map.entrySet()) { 189 String key = entry.getKey(); 190 Object value = entry.getValue(); 191 Editor editor = mDefaultPrefs.edit().clear(); 192 if (value instanceof Integer) { 193 mPrefsBackupHelper.setPreference(editor, entry); 194 editor.apply(); 195 assertEquals(mDefaultPrefs.getInt("int", 0), 1); 196 } else if(value instanceof Boolean) { 197 mPrefsBackupHelper.setPreference(editor, entry); 198 editor.apply(); 199 assertEquals(mDefaultPrefs.getBoolean("boolean", false), true); 200 } else { 201 try { 202 mPrefsBackupHelper.setPreference(editor, entry); 203 fail(); 204 } catch(IllegalArgumentException e) { 205 206 } finally { 207 editor.apply(); 208 assertFalse(mDefaultPrefs.contains(key)); 209 } 210 } 211 } 212 } 213 } 214