• 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.dashboard.DashboardFragment;
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 DashboardFragment 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_noManagedProfile_shouldContainAddAccount()257     public void updateRawDataToIndex_noManagedProfile_shouldContainAddAccount() {
258         final List<SearchIndexableRaw> data = new ArrayList<>();
259         when(mUserManager.isManagedProfile()).thenReturn(false);
260 
261         mController.updateRawDataToIndex(data);
262 
263         assertThat(data).hasSize(1);
264         assertThat(data.get(0).key).isEqualTo("add_account");
265     }
266 
267 
268     @Test
updateRawDataToIndex_ManagedProfile_shouldContainAddAccount()269     public void updateRawDataToIndex_ManagedProfile_shouldContainAddAccount() {
270         final List<SearchIndexableRaw> data = new ArrayList<>();
271         when(mUserManager.isManagedProfile()).thenReturn(true);
272 
273         mController.updateRawDataToIndex(data);
274 
275         assertThat(data).hasSize(1);
276         assertThat(data.get(0).key).isEqualTo("add_account");
277     }
278 
279     @Test
updateDynamicRawDataToIndex_enabledUser_notManagedUser_shouldNotUpdate()280     public void updateDynamicRawDataToIndex_enabledUser_notManagedUser_shouldNotUpdate() {
281         final List<SearchIndexableRaw> data = new ArrayList<>();
282         final List<UserInfo> infos = new ArrayList<>();
283         infos.add(new UserInfo(1, "user 1", 0));
284         when(mUserManager.isManagedProfile()).thenReturn(false);
285         when(mUserManager.getProfiles(anyInt())).thenReturn(infos);
286 
287         mController.updateDynamicRawDataToIndex(data);
288 
289         assertThat(data.size()).isEqualTo(0);
290     }
291 
292     @Test
updateDynamicRawDataToIndex_managedUser_shouldAddTwo()293     public void updateDynamicRawDataToIndex_managedUser_shouldAddTwo() {
294         final List<SearchIndexableRaw> data = new ArrayList<>();
295         final List<UserInfo> infos = new ArrayList<>();
296         infos.add(new UserInfo(1, "user 1", UserInfo.FLAG_MANAGED_PROFILE));
297         when(mUserManager.isManagedProfile()).thenReturn(false);
298         when(mUserManager.getProfiles(anyInt())).thenReturn(infos);
299 
300         mController.updateDynamicRawDataToIndex(data);
301 
302         assertThat(data.size()).isEqualTo(2);
303     }
304 
305     @Test
updateDynamicRawDataToIndex_disallowRemove_shouldAddOne()306     public void updateDynamicRawDataToIndex_disallowRemove_shouldAddOne() {
307         final List<SearchIndexableRaw> data = new ArrayList<>();
308         final List<UserInfo> infos = new ArrayList<>();
309         infos.add(new UserInfo(1, "user 1", UserInfo.FLAG_MANAGED_PROFILE));
310         when(mUserManager.isManagedProfile()).thenReturn(false);
311         when(mUserManager.getProfiles(anyInt())).thenReturn(infos);
312         when(mAccountHelper.hasBaseUserRestriction(
313                 eq(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE), anyInt()))
314                 .thenReturn(true);
315 
316         mController.updateDynamicRawDataToIndex(data);
317 
318         assertThat(data.size()).isEqualTo(1);
319     }
320 
321     @Test
updateDynamicRawDataToIndex_disallowModify_shouldAddTwo()322     public void updateDynamicRawDataToIndex_disallowModify_shouldAddTwo() {
323         final List<SearchIndexableRaw> data = new ArrayList<>();
324         final List<UserInfo> infos = new ArrayList<>();
325         infos.add(new UserInfo(1, "user 1", UserInfo.FLAG_MANAGED_PROFILE));
326         when(mUserManager.isManagedProfile()).thenReturn(false);
327         when(mUserManager.getProfiles(anyInt())).thenReturn(infos);
328         when(mAccountHelper.hasBaseUserRestriction(
329                 eq(UserManager.DISALLOW_MODIFY_ACCOUNTS), anyInt())).thenReturn(true);
330 
331         mController.updateDynamicRawDataToIndex(data);
332 
333         assertThat(data.size()).isEqualTo(2);
334     }
335 
336     @Test
onResume_twoAccountsOfSameType_shouldAddThreePreferences()337     public void onResume_twoAccountsOfSameType_shouldAddThreePreferences() {
338         final List<UserInfo> infos = new ArrayList<>();
339         infos.add(new UserInfo(1, "user 1", 0));
340         when(mUserManager.isManagedProfile()).thenReturn(false);
341         when(mUserManager.isRestrictedProfile()).thenReturn(false);
342         when(mUserManager.getProfiles(anyInt())).thenReturn(infos);
343         Account[] accounts = {new Account("Account1", "com.acct1")};
344         when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(accounts);
345 
346         Account[] accountType1 = {
347                 new Account("Account11", "com.acct1"),
348                 new Account("Account12", "com.acct1")
349         };
350         when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class)))
351                 .thenReturn(accountType1);
352 
353         AuthenticatorDescription[] authDescs = {
354                 new AuthenticatorDescription("com.acct1", "com.android.settings",
355                         R.string.account_settings_title, 0, 0, 0, false)
356         };
357         when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn(authDescs);
358 
359         AccessiblePreferenceCategory preferenceGroup = mock(AccessiblePreferenceCategory.class);
360         when(preferenceGroup.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
361         when(mAccountHelper.createAccessiblePreferenceCategory(any(Context.class))).thenReturn(
362                 preferenceGroup);
363 
364         mController.onResume();
365 
366         // should add 2 individual account and the Add account preference
367         verify(preferenceGroup, times(3)).addPreference(any(Preference.class));
368     }
369 
370     @Test
371     @Config(shadows = {ShadowAccountManager.class, ShadowContentResolver.class})
onResume_twoAccountsOfSameName_shouldAddFivePreferences()372     public void onResume_twoAccountsOfSameName_shouldAddFivePreferences() {
373         final List<UserInfo> infos = new ArrayList<>();
374         infos.add(new UserInfo(1, "user 1", 0));
375         when(mUserManager.isManagedProfile()).thenReturn(false);
376         when(mUserManager.isRestrictedProfile()).thenReturn(false);
377         when(mUserManager.getProfiles(anyInt())).thenReturn(infos);
378 
379         final Account[] accountType1 = new Account[2];
380         accountType1[0] = new Account("Account1", "com.acct1");
381         accountType1[1] = new Account("Account2", "com.acct1");
382         final Account[] accountType2 = new Account[2];
383         accountType2[0] = new Account("Account1", "com.acct2");
384         accountType2[1] = new Account("Account2", "com.acct2");
385         final Account[] allAccounts = new Account[4];
386         allAccounts[0] = accountType1[0];
387         allAccounts[1] = accountType1[1];
388         allAccounts[2] = accountType2[0];
389         allAccounts[3] = accountType2[1];
390         final AuthenticatorDescription[] authDescs = {
391                 new AuthenticatorDescription("com.acct1", "com.android.settings",
392                         R.string.account_settings_title, 0, 0, 0, false),
393                 new AuthenticatorDescription("com.acct2", "com.android.settings",
394                         R.string.account_settings_title, 0, 0, 0, false)
395         };
396 
397         when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(allAccounts);
398         when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class)))
399                 .thenReturn(accountType1);
400         when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct2"), any(UserHandle.class)))
401                 .thenReturn(accountType2);
402         when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn(authDescs);
403 
404         AccessiblePreferenceCategory preferenceGroup = mock(AccessiblePreferenceCategory.class);
405         when(preferenceGroup.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
406         when(mAccountHelper.createAccessiblePreferenceCategory(any(Context.class))).thenReturn(
407                 preferenceGroup);
408 
409         mController.onResume();
410 
411         // should add 4 individual account and the Add account preference
412         verify(preferenceGroup, times(5)).addPreference(any(Preference.class));
413     }
414 
415     @Test
onResume_noAccountChange_shouldNotAddAccountPreference()416     public void onResume_noAccountChange_shouldNotAddAccountPreference() {
417         final List<UserInfo> infos = new ArrayList<>();
418         infos.add(new UserInfo(1, "user 1", 0));
419         when(mUserManager.isManagedProfile()).thenReturn(false);
420         when(mUserManager.isRestrictedProfile()).thenReturn(false);
421         when(mUserManager.getProfiles(anyInt())).thenReturn(infos);
422         Account[] accounts = {new Account("Acct1", "com.acct1")};
423         when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(accounts);
424 
425         Account[] accountType1 = new Account[2];
426         accountType1[0] = new Account("Acct11", "com.acct1");
427         accountType1[1] = new Account("Acct12", "com.acct1");
428         when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class)))
429                 .thenReturn(accountType1);
430 
431         AuthenticatorDescription[] authDescs = {
432                 new AuthenticatorDescription("com.acct1", "com.android.settings",
433                         R.string.account_settings_title, 0, 0, 0, false)
434         };
435         when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn(authDescs);
436 
437         AccessiblePreferenceCategory preferenceGroup = mock(AccessiblePreferenceCategory.class);
438         when(preferenceGroup.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
439         when(mAccountHelper.createAccessiblePreferenceCategory(any(Context.class))).thenReturn(
440                 preferenceGroup);
441         mController.onResume();
442 
443         mController.onResume();
444 
445         // each account should be added only once
446         verify(preferenceGroup).addPreference(argThat(titleMatches("Acct11")));
447         verify(preferenceGroup).addPreference(argThat(titleMatches("Acct12")));
448     }
449 
450     @Test
onResume_oneNewAccount_shouldAddOneAccountPreference()451     public void onResume_oneNewAccount_shouldAddOneAccountPreference() {
452         final List<UserInfo> infos = new ArrayList<>();
453         infos.add(new UserInfo(1, "user 1", 0));
454         when(mUserManager.isManagedProfile()).thenReturn(false);
455         when(mUserManager.isRestrictedProfile()).thenReturn(false);
456         when(mUserManager.getProfiles(anyInt())).thenReturn(infos);
457         Account[] accounts = {new Account("Acct1", "com.acct1")};
458         when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(accounts);
459 
460         Account[] accountType1 = new Account[2];
461         accountType1[0] = new Account("Acct11", "com.acct1");
462         accountType1[1] = new Account("Acct12", "com.acct1");
463         when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class)))
464                 .thenReturn(accountType1);
465 
466         AuthenticatorDescription[] authDescs = {
467                 new AuthenticatorDescription("com.acct1", "com.android.settings",
468                         R.string.account_settings_title, 0, 0, 0, false)
469         };
470         when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn(authDescs);
471 
472         AccessiblePreferenceCategory preferenceGroup = mock(AccessiblePreferenceCategory.class);
473         when(preferenceGroup.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
474         when(mAccountHelper.createAccessiblePreferenceCategory(any(Context.class))).thenReturn(
475                 preferenceGroup);
476 
477         mController.onResume();
478 
479         // add a new account
480         accountType1 = new Account[3];
481         accountType1[0] = new Account("Acct11", "com.acct1");
482         accountType1[1] = new Account("Acct12", "com.acct1");
483         accountType1[2] = new Account("Acct13", "com.acct1");
484         when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class)))
485                 .thenReturn(accountType1);
486 
487         mController.onResume();
488 
489         // each account should be added only once
490         verify(preferenceGroup, times(1)).addPreference(argThat(titleMatches("Acct11")));
491         verify(preferenceGroup, times(1)).addPreference(argThat(titleMatches("Acct12")));
492         verify(preferenceGroup, times(1)).addPreference(argThat(titleMatches("Acct13")));
493     }
494 
495     @Test
onResume_oneNewAccountType_shouldAddOneAccountPreference()496     public void onResume_oneNewAccountType_shouldAddOneAccountPreference() {
497         final List<UserInfo> infos = new ArrayList<>();
498         infos.add(new UserInfo(1, "user 1", 0));
499         infos.add(new UserInfo(2, "user 2", UserInfo.FLAG_MANAGED_PROFILE));
500         when(mUserManager.isManagedProfile()).thenReturn(false);
501         when(mUserManager.isRestrictedProfile()).thenReturn(false);
502         when(mUserManager.getProfiles(anyInt())).thenReturn(infos);
503 
504         AccessiblePreferenceCategory preferenceGroup = mock(AccessiblePreferenceCategory.class);
505         when(preferenceGroup.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
506         when(mAccountHelper.createAccessiblePreferenceCategory(any(Context.class))).thenReturn(
507                 preferenceGroup);
508 
509         // First time resume will build the UI with no account
510         mController.onResume();
511 
512         // Add new account
513         Account[] accounts = {new Account("Acct1", "com.acct1")};
514         when(mAccountManager.getAccountsAsUser(2)).thenReturn(accounts);
515         when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class)))
516                 .thenReturn(accounts);
517 
518         AuthenticatorDescription[] authDescs = {
519                 new AuthenticatorDescription("com.acct1", "com.android.settings",
520                         R.string.account_settings_title, 0, 0, 0, false)
521         };
522         when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn(authDescs);
523 
524         // Resume should show the newly added account
525         mController.onResume();
526 
527         verify(preferenceGroup).addPreference(argThat(titleMatches("Acct1")));
528     }
529 
530     @Test
onResume_oneAccountRemoved_shouldRemoveOneAccountPreference()531     public void onResume_oneAccountRemoved_shouldRemoveOneAccountPreference() {
532         final List<UserInfo> infos = new ArrayList<>();
533         infos.add(new UserInfo(1, "user 1", 0));
534         when(mUserManager.isManagedProfile()).thenReturn(false);
535         when(mUserManager.isRestrictedProfile()).thenReturn(false);
536         when(mUserManager.getProfiles(anyInt())).thenReturn(infos);
537         Account[] accounts = {new Account("Acct1", "com.acct1")};
538         when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(accounts);
539 
540         Account[] accountType1 = {
541                 new Account("Acct11", "com.acct1"),
542                 new Account("Acct12", "com.acct1")
543         };
544         when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class)))
545                 .thenReturn(accountType1);
546 
547         AuthenticatorDescription[] authDescs = {
548                 new AuthenticatorDescription("com.acct1", "com.android.settings",
549                         R.string.account_settings_title, 0, 0, 0, false)
550         };
551         when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn(authDescs);
552 
553         AccessiblePreferenceCategory preferenceGroup = mock(AccessiblePreferenceCategory.class);
554         when(preferenceGroup.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
555         when(mAccountHelper.createAccessiblePreferenceCategory(any(Context.class))).thenReturn(
556                 preferenceGroup);
557 
558         mController.onResume();
559 
560         // remove an account
561         accountType1 = new Account[]{new Account("Acct11", "com.acct1")};
562         when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class)))
563                 .thenReturn(accountType1);
564 
565         mController.onResume();
566 
567         verify(preferenceGroup, times(1)).addPreference(argThat(titleMatches("Acct11")));
568         verify(preferenceGroup, times(1)).addPreference(argThat(titleMatches("Acct12")));
569         verify(preferenceGroup, times(1)).removePreference(argThat(titleMatches("Acct12")));
570     }
571 
572     @Test
onResume_userReEnabled_shouldAddOneAccountPreference()573     public void onResume_userReEnabled_shouldAddOneAccountPreference() {
574         final List<UserInfo> infos = new ArrayList<>();
575         infos.add(new UserInfo(1, "user 1", UserInfo.FLAG_DISABLED));
576         when(mUserManager.isManagedProfile()).thenReturn(false);
577         when(mUserManager.isRestrictedProfile()).thenReturn(false);
578         when(mUserManager.getProfiles(anyInt())).thenReturn(infos);
579 
580         Account[] accounts = {new Account("Acct1", "com.acct1")};
581         when(mAccountManager.getAccountsAsUser(1)).thenReturn(accounts);
582         when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class)))
583                 .thenReturn(accounts);
584 
585         AuthenticatorDescription[] authDescs = {
586                 new AuthenticatorDescription("com.acct1", "com.android.settings",
587                         R.string.account_settings_title, 0 /* iconId */, 0 /* smallIconId */,
588                         0 /* prefId */, false /* customTokens */)
589         };
590         when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn(authDescs);
591 
592         AccessiblePreferenceCategory preferenceGroup = mock(AccessiblePreferenceCategory.class);
593         when(preferenceGroup.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
594         when(mAccountHelper.createAccessiblePreferenceCategory(any(Context.class)))
595                 .thenReturn(preferenceGroup);
596 
597         // First time resume will build the UI with no account
598         mController.onResume();
599         verify(preferenceGroup, never()).addPreference(argThat(titleMatches("Acct1")));
600 
601         // Enable the user
602         infos.remove(0 /* index */);
603         infos.add(new UserInfo(1, "user 1", 0 /* flags */));
604 
605         // Resume should show the account for the user
606         mController.onResume();
607 
608         verify(preferenceGroup).addPreference(argThat(titleMatches("Acct1")));
609     }
610 
titleMatches(String expected)611     private static ArgumentMatcher<Preference> titleMatches(String expected) {
612         return preference -> TextUtils.equals(expected, preference.getTitle());
613     }
614 }
615