• 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 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
setUp()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
onResume_managedProfile_shouldNotAddAccountCategory()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
onResume_linkedUser_shouldAddOneAccountCategory()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
onResume_oneProfile_shouldAddOneAccountCategory()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
onResume_twoProfiles_shouldAddTwoAccountCategory()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
onResume_noProfileChange_shouldNotAddOrRemoveAccountCategory()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
onResume_oneNewProfile_shouldAddOneAccountCategory()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
onResume_oneProfileRemoved_shouldRemoveOneAccountCategory()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
onResume_oneProfile_shouldSetAccountTitleWithUserName()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
onResume_noPreferenceScreen_shouldNotCrash()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
onResume_noPreferenceManager_shouldNotCrash()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
updateRawDataToIndex_ManagedProfile_shouldNotUpdate()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
updateRawDataToIndex_DisabledUser_shouldNotUpdate()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
updateRawDataToIndex_EnabledUser_shouldAddOne()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
updateRawDataToIndex_ManagedUser_shouldAddThree()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
updateRawDataToIndex_DisallowRemove_shouldAddTwo()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
updateRawDataToIndex_DisallowModify_shouldAddTwo()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
onResume_twoAccountsOfSameType_shouldAddThreePreferences()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})
onResume_twoAccountsOfSameName_shouldAddFivePreferences()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
onResume_noAccountChange_shouldNotAddAccountPreference()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
onResume_oneNewAccount_shouldAddOneAccountPreference()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
onResume_oneNewAccountType_shouldAddOneAccountPreference()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
onResume_oneAccountRemoved_shouldRemoveOneAccountPreference()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 
titleMatches(String expected)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
getDrawableForType(Context context, final String accountType)572         public Drawable getDrawableForType(Context context, final String accountType) {
573             return new ColorDrawable();
574         }
575     }
576 }
577