• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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