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 android.content.Intent.EXTRA_USER; 19 20 import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_KEYHINT; 21 import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE; 22 23 import static com.google.common.truth.Truth.assertThat; 24 25 import static org.mockito.ArgumentMatchers.any; 26 import static org.mockito.ArgumentMatchers.anyInt; 27 import static org.mockito.Mockito.mock; 28 import static org.mockito.Mockito.never; 29 import static org.mockito.Mockito.spy; 30 import static org.mockito.Mockito.verify; 31 import static org.mockito.Mockito.when; 32 33 import android.accounts.Account; 34 import android.content.Context; 35 import android.content.Intent; 36 import android.content.pm.ActivityInfo; 37 import android.content.pm.PackageManager; 38 import android.content.pm.ResolveInfo; 39 import android.os.Bundle; 40 import android.os.UserHandle; 41 import android.os.UserManager; 42 43 import androidx.fragment.app.FragmentActivity; 44 import androidx.preference.Preference; 45 46 import com.android.settings.dashboard.DashboardFeatureProviderImpl; 47 import com.android.settings.testutils.shadow.ShadowAccountManager; 48 import com.android.settings.testutils.shadow.ShadowUserManager; 49 import com.android.settingslib.drawer.ActivityTile; 50 import com.android.settingslib.drawer.CategoryKey; 51 import com.android.settingslib.drawer.Tile; 52 53 import org.junit.After; 54 import org.junit.Before; 55 import org.junit.Test; 56 import org.junit.runner.RunWith; 57 import org.robolectric.Robolectric; 58 import org.robolectric.RobolectricTestRunner; 59 import org.robolectric.RuntimeEnvironment; 60 import org.robolectric.Shadows; 61 import org.robolectric.annotation.Config; 62 import org.robolectric.shadow.api.Shadow; 63 import org.robolectric.util.ReflectionHelpers; 64 65 @RunWith(RobolectricTestRunner.class) 66 @Config(shadows = {ShadowAccountManager.class, ShadowUserManager.class}) 67 public class AccountDetailDashboardFragmentTest { 68 69 private static final String METADATA_CATEGORY = "com.android.settings.category"; 70 private static final String METADATA_ACCOUNT_TYPE = "com.android.settings.ia.account"; 71 private static final String METADATA_USER_HANDLE = "user_handle"; 72 73 private AccountDetailDashboardFragment mFragment; 74 private Context mContext; 75 private ActivityInfo mActivityInfo; 76 77 @Before setUp()78 public void setUp() { 79 mContext = RuntimeEnvironment.application; 80 mActivityInfo = new ActivityInfo(); 81 mActivityInfo.packageName = mContext.getPackageName(); 82 mActivityInfo.name = "clazz"; 83 mActivityInfo.metaData = new Bundle(); 84 85 final Bundle args = new Bundle(); 86 args.putParcelable(METADATA_USER_HANDLE, UserHandle.CURRENT); 87 88 mFragment = spy(new AccountDetailDashboardFragment()); 89 mFragment.setArguments(args); 90 mFragment.mAccountType = "com.abc"; 91 mFragment.mAccount = new Account("name1@abc.com", "com.abc"); 92 when(mFragment.getContext()).thenReturn(mContext); 93 } 94 95 @After tearDown()96 public void tearDown() { 97 ShadowAccountManager.reset(); 98 } 99 100 @Test testCategory_isAccountDetail()101 public void testCategory_isAccountDetail() { 102 assertThat(new AccountDetailDashboardFragment().getCategoryKey()) 103 .isEqualTo(CategoryKey.CATEGORY_ACCOUNT_DETAIL); 104 } 105 106 @Test refreshDashboardTiles_HasAccountType_shouldDisplay()107 public void refreshDashboardTiles_HasAccountType_shouldDisplay() { 108 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_ACCOUNT_DETAIL); 109 mActivityInfo.metaData.putString(METADATA_CATEGORY, CategoryKey.CATEGORY_ACCOUNT_DETAIL); 110 mActivityInfo.metaData.putString(METADATA_ACCOUNT_TYPE, "com.abc"); 111 112 assertThat(mFragment.displayTile(tile)).isTrue(); 113 } 114 115 @Test refreshDashboardTiles_NoAccountType_shouldNotDisplay()116 public void refreshDashboardTiles_NoAccountType_shouldNotDisplay() { 117 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_ACCOUNT_DETAIL); 118 mActivityInfo.metaData.putString(METADATA_CATEGORY, CategoryKey.CATEGORY_ACCOUNT_DETAIL); 119 120 assertThat(mFragment.displayTile(tile)).isFalse(); 121 } 122 123 @Test refreshDashboardTiles_OtherAccountType_shouldNotDisplay()124 public void refreshDashboardTiles_OtherAccountType_shouldNotDisplay() { 125 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_ACCOUNT_DETAIL); 126 mActivityInfo.metaData.putString(METADATA_CATEGORY, CategoryKey.CATEGORY_ACCOUNT_DETAIL); 127 mActivityInfo.metaData.putString(METADATA_ACCOUNT_TYPE, "com.other"); 128 129 assertThat(mFragment.displayTile(tile)).isFalse(); 130 } 131 132 @Test refreshDashboardTiles_HasAccountType_shouldAddAccountNameToIntent()133 public void refreshDashboardTiles_HasAccountType_shouldAddAccountNameToIntent() { 134 final DashboardFeatureProviderImpl dashboardFeatureProvider = 135 new DashboardFeatureProviderImpl(mContext); 136 final PackageManager packageManager = mock(PackageManager.class); 137 ReflectionHelpers.setField(dashboardFeatureProvider, "mPackageManager", packageManager); 138 when(packageManager.resolveActivity(any(Intent.class), anyInt())) 139 .thenReturn(mock(ResolveInfo.class)); 140 141 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_ACCOUNT_DETAIL); 142 mActivityInfo.metaData.putString(META_DATA_PREFERENCE_KEYHINT, "key"); 143 mActivityInfo.metaData.putString(METADATA_CATEGORY, CategoryKey.CATEGORY_ACCOUNT); 144 mActivityInfo.metaData.putString(METADATA_ACCOUNT_TYPE, "com.abc"); 145 mActivityInfo.metaData.putString(META_DATA_PREFERENCE_TITLE, "summary"); 146 mActivityInfo.metaData.putString("com.android.settings.intent.action", 147 Intent.ACTION_ASSIST); 148 tile.userHandle = null; 149 mFragment.displayTile(tile); 150 151 final FragmentActivity activity = Robolectric.setupActivity(FragmentActivity.class); 152 final Preference preference = new Preference(mContext); 153 dashboardFeatureProvider.bindPreferenceToTileAndGetObservers(activity, mFragment, 154 false /* forceRoundedIcon */, preference, tile, null /* key */, 155 Preference.DEFAULT_ORDER); 156 157 assertThat(preference.getKey()).isEqualTo(tile.getKey(mContext)); 158 preference.performClick(); 159 160 final Intent intent = Shadows.shadowOf(activity).getNextStartedActivityForResult().intent; 161 162 assertThat(intent.getStringExtra("extra.accountName")).isEqualTo("name1@abc.com"); 163 } 164 165 @Test displayTile_shouldAddUserHandleToTileIntent()166 public void displayTile_shouldAddUserHandleToTileIntent() { 167 mFragment.mUserHandle = new UserHandle(1); 168 169 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_ACCOUNT_DETAIL); 170 mActivityInfo.metaData.putString(METADATA_CATEGORY, CategoryKey.CATEGORY_ACCOUNT); 171 mActivityInfo.metaData.putString(METADATA_ACCOUNT_TYPE, "com.abc"); 172 173 mFragment.displayTile(tile); 174 175 final UserHandle userHandle = tile.getIntent().getParcelableExtra(EXTRA_USER); 176 assertThat(userHandle.getIdentifier()).isEqualTo(1); 177 } 178 179 @Test onResume_accountMissing_shouldFinish()180 public void onResume_accountMissing_shouldFinish() { 181 ShadowUserManager userManager = 182 Shadow.extract(mContext.getSystemService(UserManager.class)); 183 184 userManager.addUserProfile(new UserHandle(1)); 185 ShadowAccountManager.addAccountForUser(1, new Account("test@test.com", "com.test")); 186 187 mFragment.finishIfAccountMissing(); 188 verify(mFragment).finish(); 189 } 190 191 @Test onResume_accountPresentOneProfile_shouldNotFinish()192 public void onResume_accountPresentOneProfile_shouldNotFinish() { 193 ShadowUserManager userManager = 194 Shadow.extract(mContext.getSystemService(UserManager.class)); 195 196 userManager.addUserProfile(new UserHandle(1)); 197 ShadowAccountManager.addAccountForUser(1, mFragment.mAccount); 198 199 mFragment.finishIfAccountMissing(); 200 verify(mFragment, never()).finish(); 201 } 202 203 @Test onResume_accountPresentTwoProfiles_shouldNotFinish()204 public void onResume_accountPresentTwoProfiles_shouldNotFinish() { 205 ShadowUserManager userManager = 206 Shadow.extract(mContext.getSystemService(UserManager.class)); 207 208 userManager.addUserProfile(new UserHandle(1)); 209 userManager.addUserProfile(new UserHandle(2)); 210 ShadowAccountManager.addAccountForUser(1, new Account("test@test.com", "com.test")); 211 ShadowAccountManager.addAccountForUser(2, mFragment.mAccount); 212 213 mFragment.finishIfAccountMissing(); 214 verify(mFragment, never()).finish(); 215 } 216 } 217