ContactEditorUtilsTest.java revision 3e435f0e724cb3e88efce15f760e59b9bc08f0d3
1/* 2 * Copyright (C) 2011 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 17package com.android.contacts.editor; 18 19import com.android.contacts.editor.ContactEditorUtils; 20import com.android.contacts.model.AccountType; 21import com.android.contacts.model.AccountWithDataSet; 22import com.android.contacts.tests.mocks.MockAccountTypeManager; 23import com.google.common.collect.Sets; 24 25import android.content.Context; 26import android.test.AndroidTestCase; 27import android.test.MoreAsserts; 28import android.test.suitebuilder.annotation.SmallTest; 29 30import java.util.Collection; 31import java.util.Set; 32 33/** 34 * Test case for {@link ContactEditorUtils}. 35 * 36 * adb shell am instrument -w -e class com.android.contacts.editor.ContactEditorUtilsTest \ 37 com.android.contacts.tests/android.test.InstrumentationTestRunner 38 */ 39@SmallTest 40public class ContactEditorUtilsTest extends AndroidTestCase { 41 private MockAccountTypeManager mAccountTypes; 42 private ContactEditorUtils mTarget; 43 44 private static final MockAccountType TYPE1 = new MockAccountType("type1", null, true); 45 private static final MockAccountType TYPE2 = new MockAccountType("type2", null, true); 46 private static final MockAccountType TYPE2EX = new MockAccountType("type2", "ext", true); 47 48 // Only type 3 is "readonly". 49 private static final MockAccountType TYPE3 = new MockAccountType("type3", null, false); 50 51 private static final AccountWithDataSet ACCOUNT_1_A = new AccountWithDataSet( 52 "a", TYPE1.accountType, TYPE1.dataSet); 53 private static final AccountWithDataSet ACCOUNT_1_B = new AccountWithDataSet( 54 "b", TYPE1.accountType, TYPE1.dataSet); 55 56 private static final AccountWithDataSet ACCOUNT_2_A = new AccountWithDataSet( 57 "a", TYPE2.accountType, TYPE2.dataSet); 58 private static final AccountWithDataSet ACCOUNT_2EX_A = new AccountWithDataSet( 59 "a", TYPE2EX.accountType, TYPE2EX.dataSet); 60 61 private static final AccountWithDataSet ACCOUNT_3_C = new AccountWithDataSet( 62 "c", TYPE3.accountType, TYPE3.dataSet); 63 64 @Override 65 protected void setUp() throws Exception { 66 // Initialize with 0 types, 0 accounts. 67 mAccountTypes = new MockAccountTypeManager(new AccountType[] {}, 68 new AccountWithDataSet[] {}); 69 mTarget = new ContactEditorUtils(getContext(), mAccountTypes); 70 71 // Clear the preferences. 72 mTarget.cleanupForTest(); 73 } 74 75 private void setAccountTypes(AccountType... types) { 76 mAccountTypes.mTypes = types; 77 } 78 79 private void setAccounts(AccountWithDataSet... accounts) { 80 mAccountTypes.mAccounts = accounts; 81 } 82 83 public void testGetWritableAccountTypeStrings() { 84 String[] types; 85 86 // 0 writable types 87 setAccountTypes(); 88 89 types = mTarget.getWritableAccountTypeStrings(); 90 MoreAsserts.assertEquals(types, new String[0]); 91 92 // 1 writable type 93 setAccountTypes(TYPE1); 94 95 types = mTarget.getWritableAccountTypeStrings(); 96 MoreAsserts.assertEquals(Sets.newHashSet(TYPE1.accountType), Sets.newHashSet(types)); 97 98 // 2 writable types 99 setAccountTypes(TYPE1, TYPE2EX); 100 101 types = mTarget.getWritableAccountTypeStrings(); 102 MoreAsserts.assertEquals(Sets.newHashSet(TYPE1.accountType, TYPE2EX.accountType), 103 Sets.newHashSet(types)); 104 105 // 3 writable types + 1 readonly type 106 setAccountTypes(TYPE1, TYPE2, TYPE2EX, TYPE3); 107 108 types = mTarget.getWritableAccountTypeStrings(); 109 MoreAsserts.assertEquals( 110 Sets.newHashSet(TYPE1.accountType, TYPE2.accountType, TYPE2EX.accountType), 111 Sets.newHashSet(types)); 112 } 113 114 /** 115 * Test for 116 * - {@link ContactEditorUtils#saveDefaultAndAllAccounts} 117 * - {@link ContactEditorUtils#getDefaultAccount} 118 * - {@link ContactEditorUtils#getSavedAccounts()} 119 */ 120 public void testSaveDefaultAndAllAccounts() { 121 // Use these account types here. 122 setAccountTypes(TYPE1, TYPE2); 123 124 // If none has been saved, it should return an empty list. 125 assertEquals(0, mTarget.getSavedAccounts().size()); 126 127 // Save 0 accounts. 128 mAccountTypes.mAccounts = new AccountWithDataSet[]{}; 129 mTarget.saveDefaultAndAllAccounts(null); 130 assertNull(mTarget.getDefaultAccount()); 131 MoreAsserts.assertEquals( 132 Sets.newHashSet(mAccountTypes.mAccounts), 133 toSet(mTarget.getSavedAccounts())); 134 135 // 1 account 136 mAccountTypes.mAccounts = new AccountWithDataSet[]{ACCOUNT_1_A}; 137 mTarget.saveDefaultAndAllAccounts(ACCOUNT_1_A); 138 assertEquals(ACCOUNT_1_A, mTarget.getDefaultAccount()); 139 MoreAsserts.assertEquals( 140 Sets.newHashSet(mAccountTypes.mAccounts), 141 toSet(mTarget.getSavedAccounts())); 142 143 // 2 accounts 144 mAccountTypes.mAccounts = new AccountWithDataSet[]{ACCOUNT_1_A, ACCOUNT_1_B}; 145 mTarget.saveDefaultAndAllAccounts(ACCOUNT_1_B); 146 assertEquals(ACCOUNT_1_B, mTarget.getDefaultAccount()); 147 MoreAsserts.assertEquals( 148 Sets.newHashSet(mAccountTypes.mAccounts), 149 toSet(mTarget.getSavedAccounts())); 150 151 // 2 accounts, and save null as the default. Even though there are accounts, the saved 152 // account list should be empty in this case. 153 mTarget.saveDefaultAndAllAccounts(null); 154 assertNull(mTarget.getDefaultAccount()); 155 assertEquals(0, mTarget.getSavedAccounts().size()); 156 } 157 158 public void testIsAccountValid() { 159 // Use these account types here. 160 setAccountTypes(TYPE1, TYPE2); 161 162 // 0 accounts 163 mAccountTypes.mAccounts = new AccountWithDataSet[]{}; 164 assertFalse(mTarget.isValidAccount(ACCOUNT_1_A)); 165 assertTrue(mTarget.isValidAccount(null)); // null is always valid 166 167 // 2 accounts 168 mAccountTypes.mAccounts = new AccountWithDataSet[]{ACCOUNT_1_A, ACCOUNT_2_A}; 169 assertTrue(mTarget.isValidAccount(ACCOUNT_1_A)); 170 assertTrue(mTarget.isValidAccount(ACCOUNT_2_A)); 171 assertFalse(mTarget.isValidAccount(ACCOUNT_2EX_A)); 172 assertTrue(mTarget.isValidAccount(null)); // null is always valid 173 } 174 175 /** 176 * Tests for {@link ContactEditorUtils#shouldShowAccountChangedNotification()}, starting with 177 * 0 accounts. 178 */ 179 public void testShouldShowAccountChangedNotification_0Accounts() { 180 // There's always at least one writable type... 181 setAccountTypes(TYPE1); 182 183 // First launch -- always true. 184 assertTrue(mTarget.shouldShowAccountChangedNotification()); 185 186 // We show the notification here, and user clicked "add account" 187 setAccounts(ACCOUNT_1_A); 188 189 // Now we open the contact editor with the new account. 190 191 // When closing the editor, we save the default account. 192 mTarget.saveDefaultAndAllAccounts(ACCOUNT_1_A); 193 194 // Next time the user creates a contact, we don't show the notification. 195 assertFalse(mTarget.shouldShowAccountChangedNotification()); 196 197 // User added a new writable account, ACCOUNT_1_B. 198 setAccounts(ACCOUNT_1_A, ACCOUNT_1_B); 199 200 // Now we show the notification again. 201 assertTrue(mTarget.shouldShowAccountChangedNotification()); 202 203 // User saved a new contact. We update the account list and the default account. 204 mTarget.saveDefaultAndAllAccounts(ACCOUNT_1_B); 205 206 // User created another contact. Now we don't show the notification. 207 assertFalse(mTarget.shouldShowAccountChangedNotification()); 208 209 // User installed a new contact sync adapter... 210 211 // Added a new account type: TYPE2, and the TYPE2EX extension. 212 setAccountTypes(TYPE1, TYPE2, TYPE2EX); 213 // Add new accounts: ACCOUNT_2_A, ACCOUNT_2EX_A. 214 setAccounts(ACCOUNT_1_A, ACCOUNT_1_B, ACCOUNT_2_A, ACCOUNT_2EX_A); 215 216 // New account means another notification. 217 assertTrue(mTarget.shouldShowAccountChangedNotification()); 218 219 // User saves a new contact, with a different default account. 220 mTarget.saveDefaultAndAllAccounts(ACCOUNT_2_A); 221 222 // Next time user creates a contact, no notification. 223 assertFalse(mTarget.shouldShowAccountChangedNotification()); 224 225 // Remove ACCOUNT_2EX_A. 226 setAccountTypes(TYPE1, TYPE2, TYPE2EX); 227 setAccounts(ACCOUNT_1_A, ACCOUNT_1_B, ACCOUNT_2_A); 228 229 // ACCOUNT_2EX_A was not default, so no notification either. 230 assertFalse(mTarget.shouldShowAccountChangedNotification()); 231 232 // Remove ACCOUNT_1_B, which is default. 233 setAccountTypes(TYPE1, TYPE2, TYPE2EX); 234 setAccounts(ACCOUNT_1_A, ACCOUNT_1_B); 235 236 // Now we show the notification. 237 assertTrue(mTarget.shouldShowAccountChangedNotification()); 238 } 239 240 /** 241 * Tests for {@link ContactEditorUtils#shouldShowAccountChangedNotification()}, starting with 242 * 1 accounts. 243 */ 244 public void testShouldShowAccountChangedNotification_1Account() { 245 setAccountTypes(TYPE1, TYPE2); 246 setAccounts(ACCOUNT_1_A); 247 248 // First launch -- always true. 249 assertTrue(mTarget.shouldShowAccountChangedNotification()); 250 251 // User saves a new contact. 252 mTarget.saveDefaultAndAllAccounts(ACCOUNT_1_A); 253 254 // Next time, no notification. 255 assertFalse(mTarget.shouldShowAccountChangedNotification()); 256 257 // The rest is the same... 258 } 259 260 /** 261 * Tests for {@link ContactEditorUtils#shouldShowAccountChangedNotification()}, starting with 262 * 0 accounts, and the user selected "local only". 263 */ 264 public void testShouldShowAccountChangedNotification_0Account_localOnly() { 265 // There's always at least one writable type... 266 setAccountTypes(TYPE1); 267 268 // First launch -- always true. 269 assertTrue(mTarget.shouldShowAccountChangedNotification()); 270 271 // We show the notification here, and user clicked "keep local" and saved an contact. 272 mTarget.saveDefaultAndAllAccounts(null); 273 274 // Now there are no accounts, and default account is null. 275 276 // The user created another contact, but this we shouldn't show the notification. 277 assertFalse(mTarget.shouldShowAccountChangedNotification()); 278 } 279 280 public void testShouldShowAccountChangedNotification_sanity_check() { 281 // Prepare 1 account and save it as the default. 282 setAccountTypes(TYPE1); 283 setAccounts(ACCOUNT_1_A); 284 285 mTarget.saveDefaultAndAllAccounts(ACCOUNT_1_A); 286 287 // Right after a save, the dialog shouldn't show up. 288 assertFalse(mTarget.shouldShowAccountChangedNotification()); 289 290 // Remove the default account to emulate broken preferences. 291 mTarget.removeDefaultAccountForTest(); 292 assertTrue(mTarget.shouldShowAccountChangedNotification()); 293 } 294 295 private static <T> Set<T> toSet(Collection<T> collection) { 296 Set<T> ret = Sets.newHashSet(); 297 ret.addAll(collection); 298 return ret; 299 } 300 301 private static class MockAccountType extends AccountType { 302 private boolean mAreContactsWritable; 303 304 public MockAccountType(String accountType, String dataSet, boolean areContactsWritable) { 305 this.accountType = accountType; 306 this.dataSet = dataSet; 307 mAreContactsWritable = areContactsWritable; 308 } 309 310 @Override 311 public boolean areContactsWritable() { 312 return mAreContactsWritable; 313 } 314 315 @Override 316 public boolean isGroupMembershipEditable() { 317 return true; 318 } 319 } 320} 321