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