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