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.dashboard; 17 18 import static com.google.common.truth.Truth.assertThat; 19 import static org.mockito.ArgumentMatchers.nullable; 20 import static org.mockito.Mockito.mock; 21 import static org.mockito.Mockito.never; 22 import static org.mockito.Mockito.spy; 23 import static org.mockito.Mockito.times; 24 import static org.mockito.Mockito.verify; 25 import static org.mockito.Mockito.when; 26 27 import android.content.ComponentName; 28 import android.content.Context; 29 import android.content.Intent; 30 import android.graphics.drawable.Icon; 31 import android.os.Bundle; 32 import android.support.v7.preference.Preference; 33 import android.support.v7.preference.PreferenceManager; 34 import android.support.v7.preference.PreferenceScreen; 35 36 import com.android.settings.core.PreferenceControllerMixin; 37 import com.android.settings.testutils.FakeFeatureFactory; 38 import com.android.settings.testutils.SettingsRobolectricTestRunner; 39 import com.android.settingslib.core.AbstractPreferenceController; 40 import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin; 41 import com.android.settingslib.drawer.DashboardCategory; 42 import com.android.settingslib.drawer.Tile; 43 import com.android.settingslib.drawer.TileUtils; 44 45 import org.junit.Before; 46 import org.junit.Test; 47 import org.junit.runner.RunWith; 48 import org.mockito.Mock; 49 import org.mockito.MockitoAnnotations; 50 import org.robolectric.RuntimeEnvironment; 51 import org.robolectric.util.ReflectionHelpers; 52 53 import java.util.ArrayList; 54 import java.util.List; 55 56 @RunWith(SettingsRobolectricTestRunner.class) 57 public class DashboardFragmentTest { 58 59 @Mock 60 private FakeFeatureFactory mFakeFeatureFactory; 61 private DashboardCategory mDashboardCategory; 62 private Context mContext; 63 private TestFragment mTestFragment; 64 65 @Before setUp()66 public void setUp() { 67 MockitoAnnotations.initMocks(this); 68 mContext = spy(RuntimeEnvironment.application); 69 mFakeFeatureFactory = FakeFeatureFactory.setupForTest(); 70 mDashboardCategory = new DashboardCategory(); 71 mDashboardCategory.addTile(new Tile()); 72 mTestFragment = new TestFragment(RuntimeEnvironment.application); 73 when(mFakeFeatureFactory.dashboardFeatureProvider 74 .getTilesForCategory(nullable(String.class))) 75 .thenReturn(mDashboardCategory); 76 mTestFragment.onAttach(RuntimeEnvironment.application); 77 when(mContext.getPackageName()).thenReturn("TestPackage"); 78 } 79 80 @Test testPreferenceControllerGetterSetter_shouldAddAndGetProperly()81 public void testPreferenceControllerGetterSetter_shouldAddAndGetProperly() { 82 final TestPreferenceController controller = new TestPreferenceController(mContext); 83 mTestFragment.addPreferenceController(controller); 84 85 final TestPreferenceController retrievedController = mTestFragment.use 86 (TestPreferenceController.class); 87 88 assertThat(controller).isSameAs(retrievedController); 89 } 90 91 @Test testPreferenceControllerSetter_shouldAddAndNotReplace()92 public void testPreferenceControllerSetter_shouldAddAndNotReplace() { 93 final TestPreferenceController controller1 = new TestPreferenceController(mContext); 94 mTestFragment.addPreferenceController(controller1); 95 final TestPreferenceController controller2 = new TestPreferenceController(mContext); 96 mTestFragment.addPreferenceController(controller2); 97 98 final TestPreferenceController retrievedController = mTestFragment.use 99 (TestPreferenceController.class); 100 101 assertThat(controller1).isSameAs(retrievedController); 102 } 103 104 @Test displayTilesAsPreference_shouldAddTilesWithIntent()105 public void displayTilesAsPreference_shouldAddTilesWithIntent() { 106 when(mFakeFeatureFactory.dashboardFeatureProvider 107 .getTilesForCategory(nullable(String.class))) 108 .thenReturn(mDashboardCategory); 109 when(mFakeFeatureFactory.dashboardFeatureProvider 110 .getDashboardKeyForTile(nullable(Tile.class))) 111 .thenReturn("test_key"); 112 mTestFragment.onCreatePreferences(new Bundle(), "rootKey"); 113 114 verify(mTestFragment.mScreen).addPreference(nullable(Preference.class)); 115 } 116 117 @Test displayTilesAsPreference_shouldNotAddTilesWithoutIntent()118 public void displayTilesAsPreference_shouldNotAddTilesWithoutIntent() { 119 mTestFragment.onCreatePreferences(new Bundle(), "rootKey"); 120 121 verify(mTestFragment.mScreen, never()).addPreference(nullable(Preference.class)); 122 } 123 124 @Test displayTilesAsPreference_withEmptyCategory_shouldNotAddTiles()125 public void displayTilesAsPreference_withEmptyCategory_shouldNotAddTiles() { 126 mDashboardCategory.removeTile(0); 127 mTestFragment.onCreatePreferences(new Bundle(), "rootKey"); 128 129 verify(mTestFragment.mScreen, never()).addPreference(nullable(Preference.class)); 130 } 131 132 @Test onAttach_shouldCreatePlaceholderPreferenceController()133 public void onAttach_shouldCreatePlaceholderPreferenceController() { 134 final AbstractPreferenceController controller = mTestFragment.use( 135 DashboardTilePlaceholderPreferenceController.class); 136 137 assertThat(controller).isNotNull(); 138 } 139 140 @Test updateState_skipUnavailablePrefs()141 public void updateState_skipUnavailablePrefs() { 142 final List<AbstractPreferenceController> preferenceControllers = mTestFragment.mControllers; 143 final AbstractPreferenceController mockController1 = 144 mock(AbstractPreferenceController.class); 145 final AbstractPreferenceController mockController2 = 146 mock(AbstractPreferenceController.class); 147 when(mockController1.getPreferenceKey()).thenReturn("key1"); 148 when(mockController2.getPreferenceKey()).thenReturn("key2"); 149 preferenceControllers.add(mockController1); 150 preferenceControllers.add(mockController2); 151 when(mockController1.isAvailable()).thenReturn(false); 152 when(mockController2.isAvailable()).thenReturn(true); 153 mTestFragment.onAttach(RuntimeEnvironment.application); 154 mTestFragment.onResume(); 155 156 verify(mockController1).getPreferenceKey(); 157 verify(mockController2, times(2)).getPreferenceKey(); 158 } 159 160 @Test updateState_doesNotSkipControllersOfSameClass()161 public void updateState_doesNotSkipControllersOfSameClass() { 162 final AbstractPreferenceController mockController1 = 163 mock(AbstractPreferenceController.class); 164 final AbstractPreferenceController mockController2 = 165 mock(AbstractPreferenceController.class); 166 mTestFragment.addPreferenceController(mockController1); 167 mTestFragment.addPreferenceController(mockController2); 168 when(mockController1.isAvailable()).thenReturn(true); 169 when(mockController2.isAvailable()).thenReturn(true); 170 171 mTestFragment.updatePreferenceStates(); 172 173 verify(mockController1).getPreferenceKey(); 174 verify(mockController2).getPreferenceKey(); 175 } 176 177 @Test tintTileIcon_hasMetadata_shouldReturnIconTintableMetadata()178 public void tintTileIcon_hasMetadata_shouldReturnIconTintableMetadata() { 179 final Tile tile = new Tile(); 180 tile.icon = mock(Icon.class); 181 final Bundle metaData = new Bundle(); 182 tile.metaData = metaData; 183 184 metaData.putBoolean(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE, false); 185 assertThat(mTestFragment.tintTileIcon(tile)).isFalse(); 186 187 metaData.putBoolean(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE, true); 188 assertThat(mTestFragment.tintTileIcon(tile)).isTrue(); 189 } 190 191 @Test tintTileIcon_noIcon_shouldReturnFalse()192 public void tintTileIcon_noIcon_shouldReturnFalse() { 193 final Tile tile = new Tile(); 194 tile.metaData = new Bundle(); 195 196 assertThat(mTestFragment.tintTileIcon(tile)).isFalse(); 197 } 198 199 @Test tintTileIcon_noMetadata_shouldReturnPackageNameCheck()200 public void tintTileIcon_noMetadata_shouldReturnPackageNameCheck() { 201 final Tile tile = new Tile(); 202 tile.icon = mock(Icon.class); 203 final Intent intent = new Intent(); 204 tile.intent = intent; 205 intent.setComponent( 206 new ComponentName(RuntimeEnvironment.application.getPackageName(), "TestClass")); 207 assertThat(mTestFragment.tintTileIcon(tile)).isFalse(); 208 209 intent.setComponent(new ComponentName("OtherPackage", "TestClass")); 210 assertThat(mTestFragment.tintTileIcon(tile)).isTrue(); 211 } 212 213 public static class TestPreferenceController extends AbstractPreferenceController 214 implements PreferenceControllerMixin { 215 TestPreferenceController(Context context)216 private TestPreferenceController(Context context) { 217 super(context); 218 } 219 220 @Override handlePreferenceTreeClick(Preference preference)221 public boolean handlePreferenceTreeClick(Preference preference) { 222 return false; 223 } 224 225 @Override isAvailable()226 public boolean isAvailable() { 227 return false; 228 } 229 230 @Override getPreferenceKey()231 public String getPreferenceKey() { 232 return null; 233 } 234 235 @Override updateNonIndexableKeys(List<String> keys)236 public void updateNonIndexableKeys(List<String> keys) { 237 } 238 } 239 240 public static class TestFragment extends DashboardFragment { 241 242 private final PreferenceManager mPreferenceManager; 243 private final Context mContext; 244 private final List<AbstractPreferenceController> mControllers; 245 246 public final PreferenceScreen mScreen; 247 TestFragment(Context context)248 public TestFragment(Context context) { 249 mContext = context; 250 mPreferenceManager = mock(PreferenceManager.class); 251 mScreen = mock(PreferenceScreen.class); 252 mControllers = new ArrayList<>(); 253 254 when(mPreferenceManager.getContext()).thenReturn(mContext); 255 ReflectionHelpers.setField( 256 this, "mVisibilityLoggerMixin", mock(VisibilityLoggerMixin.class)); 257 } 258 259 @Override getContext()260 public Context getContext() { 261 return mContext; 262 } 263 264 @Override getMetricsCategory()265 public int getMetricsCategory() { 266 return 0; 267 } 268 269 @Override getPreferenceScreen()270 public PreferenceScreen getPreferenceScreen() { 271 return mScreen; 272 } 273 274 @Override getLogTag()275 protected String getLogTag() { 276 return "TEST_FRAG"; 277 } 278 279 @Override getPreferenceScreenResId()280 protected int getPreferenceScreenResId() { 281 return 0; 282 } 283 284 @Override createPreferenceControllers(Context context)285 protected List<AbstractPreferenceController> createPreferenceControllers(Context context) { 286 return mControllers; 287 } 288 289 @Override getPreferenceManager()290 public PreferenceManager getPreferenceManager() { 291 return mPreferenceManager; 292 } 293 } 294 } 295