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