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 package com.android.settings.accounts; 17 18 import static com.google.common.truth.Truth.assertThat; 19 import static org.mockito.Answers.RETURNS_DEEP_STUBS; 20 import static org.mockito.Matchers.any; 21 import static org.mockito.Matchers.anyInt; 22 import static org.mockito.Matchers.argThat; 23 import static org.mockito.Matchers.eq; 24 import static org.mockito.Mockito.mock; 25 import static org.mockito.Mockito.never; 26 import static org.mockito.Mockito.reset; 27 import static org.mockito.Mockito.times; 28 import static org.mockito.Mockito.verify; 29 import static org.mockito.Mockito.when; 30 31 import android.accounts.Account; 32 import android.accounts.AccountManager; 33 import android.accounts.AuthenticatorDescription; 34 import android.content.Context; 35 import android.content.pm.UserInfo; 36 import android.graphics.drawable.ColorDrawable; 37 import android.graphics.drawable.Drawable; 38 import android.os.UserHandle; 39 import android.os.UserManager; 40 import android.support.v7.preference.Preference; 41 import android.support.v7.preference.PreferenceGroup; 42 import android.support.v7.preference.PreferenceManager; 43 import android.support.v7.preference.PreferenceScreen; 44 import android.text.TextUtils; 45 46 import com.android.settings.AccessiblePreferenceCategory; 47 import com.android.settings.R; 48 import com.android.settings.SettingsPreferenceFragment; 49 import com.android.settings.search.SearchIndexableRaw; 50 import com.android.settings.testutils.SettingsRobolectricTestRunner; 51 import com.android.settings.testutils.shadow.ShadowAccountManager; 52 import com.android.settings.testutils.shadow.ShadowContentResolver; 53 import com.android.settingslib.accounts.AuthenticatorHelper; 54 55 import org.junit.Before; 56 import org.junit.Test; 57 import org.junit.runner.RunWith; 58 import org.mockito.ArgumentMatcher; 59 import org.mockito.Mock; 60 import org.mockito.MockitoAnnotations; 61 import org.robolectric.RuntimeEnvironment; 62 import org.robolectric.annotation.Config; 63 import org.robolectric.annotation.Implementation; 64 import org.robolectric.annotation.Implements; 65 import org.robolectric.shadows.ShadowApplication; 66 67 import java.util.ArrayList; 68 import java.util.List; 69 70 @RunWith(SettingsRobolectricTestRunner.class) 71 @Config(shadows = {ShadowAccountManager.class, ShadowContentResolver.class}) 72 public class AccountPreferenceControllerTest { 73 74 @Mock(answer = RETURNS_DEEP_STUBS) 75 private PreferenceScreen mScreen; 76 @Mock(answer = RETURNS_DEEP_STUBS) 77 private UserManager mUserManager; 78 @Mock(answer = RETURNS_DEEP_STUBS) 79 private SettingsPreferenceFragment mFragment; 80 @Mock(answer = RETURNS_DEEP_STUBS) 81 private AccountManager mAccountManager; 82 @Mock(answer = RETURNS_DEEP_STUBS) 83 private AccountRestrictionHelper mAccountHelper; 84 85 private Context mContext; 86 private AccountPreferenceController mController; 87 88 @Before 89 public void setUp() { 90 MockitoAnnotations.initMocks(this); 91 mContext = RuntimeEnvironment.application; 92 final ShadowApplication shadowApp = ShadowApplication.getInstance(); 93 shadowApp.setSystemService(Context.USER_SERVICE, mUserManager); 94 shadowApp.setSystemService(Context.ACCOUNT_SERVICE, mAccountManager); 95 96 when(mFragment.getPreferenceScreen()).thenReturn(mScreen); 97 when(mFragment.getPreferenceManager().getContext()).thenReturn(mContext); 98 when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())) 99 .thenReturn(new AuthenticatorDescription[0]); 100 when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[0]); 101 mController = new AccountPreferenceController(mContext, mFragment, null, mAccountHelper); 102 } 103 104 @Test 105 public void onResume_managedProfile_shouldNotAddAccountCategory() { 106 when(mUserManager.isManagedProfile()).thenReturn(true); 107 mController.onResume(); 108 109 verify(mScreen, never()).addPreference(any(Preference.class)); 110 } 111 112 @Test 113 public void onResume_linkedUser_shouldAddOneAccountCategory() { 114 final UserInfo info = new UserInfo(1, "user 1", 0); 115 when(mUserManager.isManagedProfile()).thenReturn(false); 116 when(mUserManager.isRestrictedProfile()).thenReturn(true); 117 when(mUserManager.getUserInfo(anyInt())).thenReturn(info); 118 119 mController.onResume(); 120 121 verify(mScreen, times(1)).addPreference(any(PreferenceGroup.class)); 122 } 123 124 @Test 125 public void onResume_oneProfile_shouldAddOneAccountCategory() { 126 final List<UserInfo> infos = new ArrayList<>(); 127 infos.add(new UserInfo(1, "user 1", 0)); 128 when(mUserManager.isManagedProfile()).thenReturn(false); 129 when(mUserManager.isRestrictedProfile()).thenReturn(false); 130 when(mUserManager.getProfiles(anyInt())).thenReturn(infos); 131 132 mController.onResume(); 133 134 verify(mScreen, times(1)).addPreference(any(PreferenceGroup.class)); 135 } 136 137 @Test 138 public void onResume_twoProfiles_shouldAddTwoAccountCategory() { 139 final List<UserInfo> infos = new ArrayList<>(); 140 infos.add(new UserInfo(1, "user 1", 0)); 141 infos.add(new UserInfo(2, "user 2", UserInfo.FLAG_MANAGED_PROFILE)); 142 when(mUserManager.isManagedProfile()).thenReturn(false); 143 when(mUserManager.isRestrictedProfile()).thenReturn(false); 144 when(mUserManager.getProfiles(anyInt())).thenReturn(infos); 145 146 mController.onResume(); 147 148 verify(mScreen, times(2)).addPreference(any(PreferenceGroup.class)); 149 } 150 151 @Test 152 public void onResume_noProfileChange_shouldNotAddOrRemoveAccountCategory() { 153 final List<UserInfo> infos = new ArrayList<>(); 154 infos.add(new UserInfo(1, "user 1", 0)); 155 infos.add(new UserInfo(2, "user 2", UserInfo.FLAG_MANAGED_PROFILE)); 156 when(mUserManager.isManagedProfile()).thenReturn(false); 157 when(mUserManager.isRestrictedProfile()).thenReturn(false); 158 when(mUserManager.getProfiles(anyInt())).thenReturn(infos); 159 // First time resume will build the UI 160 mController.onResume(); 161 reset(mScreen); 162 163 mController.onResume(); 164 verify(mScreen, never()).addPreference(any(PreferenceGroup.class)); 165 verify(mScreen, never()).removePreference(any(PreferenceGroup.class)); 166 } 167 168 @Test 169 public void onResume_oneNewProfile_shouldAddOneAccountCategory() { 170 final List<UserInfo> infos = new ArrayList<>(); 171 infos.add(new UserInfo(1, "user 1", 0)); 172 when(mUserManager.isManagedProfile()).thenReturn(false); 173 when(mUserManager.isRestrictedProfile()).thenReturn(false); 174 when(mUserManager.getProfiles(anyInt())).thenReturn(infos); 175 // First time resume will build the UI 176 mController.onResume(); 177 // add a new profile 178 infos.add(new UserInfo(2, "user 2", UserInfo.FLAG_MANAGED_PROFILE)); 179 reset(mScreen); 180 181 mController.onResume(); 182 verify(mScreen, times(1)).addPreference(any(PreferenceGroup.class)); 183 } 184 185 @Test 186 public void onResume_oneProfileRemoved_shouldRemoveOneAccountCategory() { 187 final List<UserInfo> infos = new ArrayList<>(); 188 infos.add(new UserInfo(1, "user 1", 0)); 189 infos.add(new UserInfo(2, "user 2", UserInfo.FLAG_MANAGED_PROFILE)); 190 when(mUserManager.isManagedProfile()).thenReturn(false); 191 when(mUserManager.isRestrictedProfile()).thenReturn(false); 192 when(mUserManager.getProfiles(anyInt())).thenReturn(infos); 193 // First time resume will build the UI 194 mController.onResume(); 195 // remove a profile 196 infos.remove(1); 197 198 mController.onResume(); 199 verify(mScreen, times(1)).removePreference(any(PreferenceGroup.class)); 200 } 201 202 @Test 203 public void onResume_oneProfile_shouldSetAccountTitleWithUserName() { 204 final List<UserInfo> infos = new ArrayList<>(); 205 infos.add(new UserInfo(1, "user 1", UserInfo.FLAG_MANAGED_PROFILE)); 206 when(mUserManager.isManagedProfile()).thenReturn(false); 207 when(mUserManager.isRestrictedProfile()).thenReturn(false); 208 when(mUserManager.getProfiles(anyInt())).thenReturn(infos); 209 AccessiblePreferenceCategory preferenceGroup = mock(AccessiblePreferenceCategory.class); 210 when(mAccountHelper.createAccessiblePreferenceCategory(any(Context.class))).thenReturn( 211 preferenceGroup); 212 213 mController.onResume(); 214 215 verify(preferenceGroup).setTitle( 216 mContext.getString(R.string.account_for_section_header, "user 1")); 217 218 } 219 220 @Test 221 public void onResume_noPreferenceScreen_shouldNotCrash() { 222 final List<UserInfo> infos = new ArrayList<>(); 223 infos.add(new UserInfo(1, "user 1", 0)); 224 when(mUserManager.isManagedProfile()).thenReturn(false); 225 when(mUserManager.isRestrictedProfile()).thenReturn(false); 226 when(mUserManager.getProfiles(anyInt())).thenReturn(infos); 227 228 AccessiblePreferenceCategory preferenceGroup = mock(AccessiblePreferenceCategory.class); 229 when(mAccountHelper.createAccessiblePreferenceCategory(any(Context.class))).thenReturn( 230 preferenceGroup); 231 232 mController.onResume(); 233 234 // Should not crash 235 } 236 237 @Test 238 public void onResume_noPreferenceManager_shouldNotCrash() { 239 when(mFragment.getPreferenceManager()).thenReturn(null); 240 final List<UserInfo> infos = new ArrayList<>(); 241 infos.add(new UserInfo(1, "user 1", 0)); 242 when(mUserManager.isManagedProfile()).thenReturn(false); 243 when(mUserManager.isRestrictedProfile()).thenReturn(false); 244 when(mUserManager.getProfiles(anyInt())).thenReturn(infos); 245 mController.onResume(); 246 247 // Should not crash 248 } 249 250 @Test 251 public void updateRawDataToIndex_ManagedProfile_shouldNotUpdate() { 252 final List<SearchIndexableRaw> data = new ArrayList<>(); 253 when(mUserManager.isManagedProfile()).thenReturn(true); 254 255 mController.updateRawDataToIndex(data); 256 257 assertThat(data).isEmpty(); 258 } 259 260 @Test 261 public void updateRawDataToIndex_DisabledUser_shouldNotUpdate() { 262 final List<SearchIndexableRaw> data = new ArrayList<>(); 263 final List<UserInfo> infos = new ArrayList<>(); 264 infos.add(new UserInfo(1, "user 1", UserInfo.FLAG_DISABLED)); 265 when(mUserManager.isManagedProfile()).thenReturn(false); 266 when(mUserManager.getProfiles(anyInt())).thenReturn(infos); 267 mController.updateRawDataToIndex(data); 268 269 assertThat(data).isEmpty(); 270 } 271 272 @Test 273 public void updateRawDataToIndex_EnabledUser_shouldAddOne() { 274 final List<SearchIndexableRaw> data = new ArrayList<>(); 275 final List<UserInfo> infos = new ArrayList<>(); 276 infos.add(new UserInfo(1, "user 1", 0)); 277 when(mUserManager.isManagedProfile()).thenReturn(false); 278 when(mUserManager.getProfiles(anyInt())).thenReturn(infos); 279 280 mController.updateRawDataToIndex(data); 281 282 assertThat(data.size()).isEqualTo(1); 283 } 284 285 @Test 286 public void updateRawDataToIndex_ManagedUser_shouldAddThree() { 287 final List<SearchIndexableRaw> data = new ArrayList<>(); 288 final List<UserInfo> infos = new ArrayList<>(); 289 infos.add(new UserInfo(1, "user 1", UserInfo.FLAG_MANAGED_PROFILE)); 290 when(mUserManager.isManagedProfile()).thenReturn(false); 291 when(mUserManager.getProfiles(anyInt())).thenReturn(infos); 292 293 mController.updateRawDataToIndex(data); 294 295 assertThat(data.size()).isEqualTo(3); 296 } 297 298 @Test 299 public void updateRawDataToIndex_DisallowRemove_shouldAddTwo() { 300 final List<SearchIndexableRaw> data = new ArrayList<>(); 301 final List<UserInfo> infos = new ArrayList<>(); 302 infos.add(new UserInfo(1, "user 1", UserInfo.FLAG_MANAGED_PROFILE)); 303 when(mUserManager.isManagedProfile()).thenReturn(false); 304 when(mUserManager.getProfiles(anyInt())).thenReturn(infos); 305 when(mAccountHelper.hasBaseUserRestriction( 306 eq(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE), anyInt())) 307 .thenReturn(true); 308 309 mController.updateRawDataToIndex(data); 310 311 assertThat(data.size()).isEqualTo(2); 312 } 313 314 @Test 315 public void updateRawDataToIndex_DisallowModify_shouldAddTwo() { 316 final List<SearchIndexableRaw> data = new ArrayList<>(); 317 final List<UserInfo> infos = new ArrayList<>(); 318 infos.add(new UserInfo(1, "user 1", UserInfo.FLAG_MANAGED_PROFILE)); 319 when(mUserManager.isManagedProfile()).thenReturn(false); 320 when(mUserManager.getProfiles(anyInt())).thenReturn(infos); 321 when(mAccountHelper.hasBaseUserRestriction( 322 eq(UserManager.DISALLOW_MODIFY_ACCOUNTS), anyInt())).thenReturn(true); 323 324 mController.updateRawDataToIndex(data); 325 326 assertThat(data.size()).isEqualTo(2); 327 } 328 329 @Test 330 public void onResume_twoAccountsOfSameType_shouldAddThreePreferences() { 331 final List<UserInfo> infos = new ArrayList<>(); 332 infos.add(new UserInfo(1, "user 1", 0)); 333 when(mUserManager.isManagedProfile()).thenReturn(false); 334 when(mUserManager.isRestrictedProfile()).thenReturn(false); 335 when(mUserManager.getProfiles(anyInt())).thenReturn(infos); 336 Account[] accounts = {new Account("Account1", "com.acct1")}; 337 when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(accounts); 338 339 Account[] accountType1 = new Account[2]; 340 accountType1[0] = new Account("Account11", "com.acct1"); 341 accountType1[1] = new Account("Account12", "com.acct1"); 342 when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class))) 343 .thenReturn(accountType1); 344 345 AuthenticatorDescription[] authDescs = { 346 new AuthenticatorDescription("com.acct1", "com.android.settings", 347 R.string.account_settings_title, 0, 0, 0, false) 348 }; 349 when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn(authDescs); 350 351 AccessiblePreferenceCategory preferenceGroup = mock(AccessiblePreferenceCategory.class); 352 when(preferenceGroup.getPreferenceManager()).thenReturn(mock(PreferenceManager.class)); 353 when(mAccountHelper.createAccessiblePreferenceCategory(any(Context.class))).thenReturn( 354 preferenceGroup); 355 356 mController.onResume(); 357 358 // should add 2 individual account and the Add account preference 359 verify(preferenceGroup, times(3)).addPreference(any(Preference.class)); 360 } 361 362 @Test 363 @Config(shadows = {ShadowAccountManager.class, ShadowContentResolver.class, 364 ShadowAuthenticatorHelper.class}) 365 public void onResume_twoAccountsOfSameName_shouldAddFivePreferences() { 366 final List<UserInfo> infos = new ArrayList<>(); 367 infos.add(new UserInfo(1, "user 1", 0)); 368 when(mUserManager.isManagedProfile()).thenReturn(false); 369 when(mUserManager.isRestrictedProfile()).thenReturn(false); 370 when(mUserManager.getProfiles(anyInt())).thenReturn(infos); 371 372 final Account[] accountType1 = new Account[2]; 373 accountType1[0] = new Account("Account1", "com.acct1"); 374 accountType1[1] = new Account("Account2", "com.acct1"); 375 final Account[] accountType2 = new Account[2]; 376 accountType2[0] = new Account("Account1", "com.acct2"); 377 accountType2[1] = new Account("Account2", "com.acct2"); 378 final Account[] allAccounts = new Account[4]; 379 allAccounts[0] = accountType1[0]; 380 allAccounts[1] = accountType1[1]; 381 allAccounts[2] = accountType2[0]; 382 allAccounts[3] = accountType2[1]; 383 final AuthenticatorDescription[] authDescs = { 384 new AuthenticatorDescription("com.acct1", "com.android.settings", 385 R.string.account_settings_title, 0, 0, 0, false), 386 new AuthenticatorDescription("com.acct2", "com.android.settings", 387 R.string.account_settings_title, 0, 0, 0, false) 388 }; 389 390 when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(allAccounts); 391 when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class))) 392 .thenReturn(accountType1); 393 when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct2"), any(UserHandle.class))) 394 .thenReturn(accountType2); 395 when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn(authDescs); 396 397 AccessiblePreferenceCategory preferenceGroup = mock(AccessiblePreferenceCategory.class); 398 when(preferenceGroup.getPreferenceManager()).thenReturn(mock(PreferenceManager.class)); 399 when(mAccountHelper.createAccessiblePreferenceCategory(any(Context.class))).thenReturn( 400 preferenceGroup); 401 402 mController.onResume(); 403 404 // should add 4 individual account and the Add account preference 405 verify(preferenceGroup, times(5)).addPreference(any(Preference.class)); 406 } 407 408 @Test 409 public void onResume_noAccountChange_shouldNotAddAccountPreference() { 410 final List<UserInfo> infos = new ArrayList<>(); 411 infos.add(new UserInfo(1, "user 1", 0)); 412 when(mUserManager.isManagedProfile()).thenReturn(false); 413 when(mUserManager.isRestrictedProfile()).thenReturn(false); 414 when(mUserManager.getProfiles(anyInt())).thenReturn(infos); 415 Account[] accounts = {new Account("Acct1", "com.acct1")}; 416 when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(accounts); 417 418 Account[] accountType1 = new Account[2]; 419 accountType1[0] = new Account("Acct11", "com.acct1"); 420 accountType1[1] = new Account("Acct12", "com.acct1"); 421 when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class))) 422 .thenReturn(accountType1); 423 424 AuthenticatorDescription[] authDescs = { 425 new AuthenticatorDescription("com.acct1", "com.android.settings", 426 R.string.account_settings_title, 0, 0, 0, false) 427 }; 428 when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn(authDescs); 429 430 AccessiblePreferenceCategory preferenceGroup = mock(AccessiblePreferenceCategory.class); 431 when(preferenceGroup.getPreferenceManager()).thenReturn(mock(PreferenceManager.class)); 432 when(mAccountHelper.createAccessiblePreferenceCategory(any(Context.class))).thenReturn( 433 preferenceGroup); 434 mController.onResume(); 435 436 mController.onResume(); 437 438 // each account should be added only once 439 verify(preferenceGroup).addPreference(argThat(titleMatches("Acct11"))); 440 verify(preferenceGroup).addPreference(argThat(titleMatches("Acct12"))); 441 } 442 443 @Test 444 public void onResume_oneNewAccount_shouldAddOneAccountPreference() { 445 final List<UserInfo> infos = new ArrayList<>(); 446 infos.add(new UserInfo(1, "user 1", 0)); 447 when(mUserManager.isManagedProfile()).thenReturn(false); 448 when(mUserManager.isRestrictedProfile()).thenReturn(false); 449 when(mUserManager.getProfiles(anyInt())).thenReturn(infos); 450 Account[] accounts = {new Account("Acct1", "com.acct1")}; 451 when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(accounts); 452 453 Account[] accountType1 = new Account[2]; 454 accountType1[0] = new Account("Acct11", "com.acct1"); 455 accountType1[1] = new Account("Acct12", "com.acct1"); 456 when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class))) 457 .thenReturn(accountType1); 458 459 AuthenticatorDescription[] authDescs = { 460 new AuthenticatorDescription("com.acct1", "com.android.settings", 461 R.string.account_settings_title, 0, 0, 0, false) 462 }; 463 when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn(authDescs); 464 465 AccessiblePreferenceCategory preferenceGroup = mock(AccessiblePreferenceCategory.class); 466 when(preferenceGroup.getPreferenceManager()).thenReturn(mock(PreferenceManager.class)); 467 when(mAccountHelper.createAccessiblePreferenceCategory(any(Context.class))).thenReturn( 468 preferenceGroup); 469 470 mController.onResume(); 471 472 // add a new account 473 accountType1 = new Account[3]; 474 accountType1[0] = new Account("Acct11", "com.acct1"); 475 accountType1[1] = new Account("Acct12", "com.acct1"); 476 accountType1[2] = new Account("Acct13", "com.acct1"); 477 when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class))) 478 .thenReturn(accountType1); 479 480 mController.onResume(); 481 482 // each account should be added only once 483 verify(preferenceGroup, times(1)).addPreference(argThat(titleMatches("Acct11"))); 484 verify(preferenceGroup, times(1)).addPreference(argThat(titleMatches("Acct12"))); 485 verify(preferenceGroup, times(1)).addPreference(argThat(titleMatches("Acct13"))); 486 } 487 488 @Test 489 public void onResume_oneNewAccountType_shouldAddOneAccountPreference() { 490 final List<UserInfo> infos = new ArrayList<>(); 491 infos.add(new UserInfo(1, "user 1", 0)); 492 infos.add(new UserInfo(2, "user 2", UserInfo.FLAG_MANAGED_PROFILE)); 493 when(mUserManager.isManagedProfile()).thenReturn(false); 494 when(mUserManager.isRestrictedProfile()).thenReturn(false); 495 when(mUserManager.getProfiles(anyInt())).thenReturn(infos); 496 497 AccessiblePreferenceCategory preferenceGroup = mock(AccessiblePreferenceCategory.class); 498 when(preferenceGroup.getPreferenceManager()).thenReturn(mock(PreferenceManager.class)); 499 when(mAccountHelper.createAccessiblePreferenceCategory(any(Context.class))).thenReturn( 500 preferenceGroup); 501 502 // First time resume will build the UI with no account 503 mController.onResume(); 504 505 // Add new account 506 Account[] accounts = {new Account("Acct1", "com.acct1")}; 507 when(mAccountManager.getAccountsAsUser(2)).thenReturn(accounts); 508 when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class))) 509 .thenReturn(accounts); 510 511 AuthenticatorDescription[] authDescs = { 512 new AuthenticatorDescription("com.acct1", "com.android.settings", 513 R.string.account_settings_title, 0, 0, 0, false) 514 }; 515 when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn(authDescs); 516 517 // Resume should show the newly added account 518 mController.onResume(); 519 520 verify(preferenceGroup).addPreference(argThat(titleMatches("Acct1"))); 521 } 522 523 @Test 524 public void onResume_oneAccountRemoved_shouldRemoveOneAccountPreference() { 525 final List<UserInfo> infos = new ArrayList<>(); 526 infos.add(new UserInfo(1, "user 1", 0)); 527 when(mUserManager.isManagedProfile()).thenReturn(false); 528 when(mUserManager.isRestrictedProfile()).thenReturn(false); 529 when(mUserManager.getProfiles(anyInt())).thenReturn(infos); 530 Account[] accounts = {new Account("Acct1", "com.acct1")}; 531 when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(accounts); 532 533 Account[] accountType1 = new Account[2]; 534 accountType1[0] = new Account("Acct11", "com.acct1"); 535 accountType1[1] = new Account("Acct12", "com.acct1"); 536 when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class))) 537 .thenReturn(accountType1); 538 539 AuthenticatorDescription[] authDescs = { 540 new AuthenticatorDescription("com.acct1", "com.android.settings", 541 R.string.account_settings_title, 0, 0, 0, false) 542 }; 543 when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn(authDescs); 544 545 AccessiblePreferenceCategory preferenceGroup = mock(AccessiblePreferenceCategory.class); 546 when(preferenceGroup.getPreferenceManager()).thenReturn(mock(PreferenceManager.class)); 547 when(mAccountHelper.createAccessiblePreferenceCategory(any(Context.class))).thenReturn( 548 preferenceGroup); 549 550 mController.onResume(); 551 552 // remove an account 553 accountType1 = new Account[1]; 554 accountType1[0] = new Account("Acct11", "com.acct1"); 555 when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class))) 556 .thenReturn(accountType1); 557 558 mController.onResume(); 559 560 verify(preferenceGroup, times(1)).addPreference(argThat(titleMatches("Acct11"))); 561 verify(preferenceGroup, times(1)).addPreference(argThat(titleMatches("Acct12"))); 562 verify(preferenceGroup, times(1)).removePreference(argThat(titleMatches("Acct12"))); 563 } 564 565 private static ArgumentMatcher<Preference> titleMatches(String expected) { 566 return preference -> TextUtils.equals(expected, preference.getTitle()); 567 } 568 569 @Implements(AuthenticatorHelper.class) 570 public static class ShadowAuthenticatorHelper { 571 @Implementation 572 public Drawable getDrawableForType(Context context, final String accountType) { 573 return new ColorDrawable(); 574 } 575 } 576 } 577