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