1 /* 2 * Copyright (C) 2017 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 17 package com.android.settings.dashboard; 18 19 import static com.google.common.truth.Truth.assertThat; 20 import static org.mockito.ArgumentMatchers.nullable; 21 import static org.mockito.Mockito.any; 22 import static org.mockito.Mockito.doNothing; 23 import static org.mockito.Mockito.doReturn; 24 import static org.mockito.Mockito.mock; 25 import static org.mockito.Mockito.never; 26 import static org.mockito.Mockito.spy; 27 import static org.mockito.Mockito.verify; 28 import static org.mockito.Mockito.when; 29 30 import android.app.Activity; 31 import android.content.Context; 32 import android.support.v7.widget.LinearLayoutManager; 33 34 import com.android.settings.dashboard.conditional.ConditionManager; 35 import com.android.settings.dashboard.conditional.FocusRecyclerView; 36 import com.android.settings.testutils.FakeFeatureFactory; 37 import com.android.settings.testutils.SettingsRobolectricTestRunner; 38 import com.android.settingslib.drawer.CategoryKey; 39 import com.android.settingslib.drawer.DashboardCategory; 40 import com.android.settingslib.suggestions.SuggestionControllerMixin; 41 42 import org.junit.Before; 43 import org.junit.Test; 44 import org.junit.runner.RunWith; 45 import org.mockito.Mock; 46 import org.mockito.MockitoAnnotations; 47 import org.robolectric.RuntimeEnvironment; 48 import org.robolectric.util.ReflectionHelpers; 49 50 @RunWith(SettingsRobolectricTestRunner.class) 51 public class DashboardSummaryTest { 52 53 @Mock 54 private DashboardAdapter mAdapter; 55 @Mock 56 private DashboardFeatureProvider mDashboardFeatureProvider; 57 @Mock 58 private FocusRecyclerView mDashboard; 59 @Mock 60 private LinearLayoutManager mLayoutManager; 61 @Mock 62 private ConditionManager mConditionManager; 63 @Mock 64 private SummaryLoader mSummaryLoader; 65 @Mock 66 private SuggestionControllerMixin mSuggestionControllerMixin; 67 68 private Context mContext; 69 private DashboardSummary mSummary; 70 private FakeFeatureFactory mFeatureFactory; 71 72 @Before setUp()73 public void setUp() { 74 MockitoAnnotations.initMocks(this); 75 mFeatureFactory = FakeFeatureFactory.setupForTest(); 76 mContext = RuntimeEnvironment.application; 77 mSummary = spy(new DashboardSummary()); 78 ReflectionHelpers.setField(mSummary, "mAdapter", mAdapter); 79 ReflectionHelpers.setField(mSummary, "mDashboardFeatureProvider", 80 mDashboardFeatureProvider); 81 ReflectionHelpers.setField(mSummary, "mDashboard", mDashboard); 82 ReflectionHelpers.setField(mSummary, "mLayoutManager", mLayoutManager); 83 ReflectionHelpers.setField(mSummary, "mConditionManager", mConditionManager); 84 ReflectionHelpers.setField(mSummary, "mSummaryLoader", mSummaryLoader); 85 } 86 87 @Test onAttach_suggestionDisabled_shouldNotStartSuggestionControllerMixin()88 public void onAttach_suggestionDisabled_shouldNotStartSuggestionControllerMixin() { 89 when(mFeatureFactory.suggestionsFeatureProvider.isSuggestionEnabled(any(Context.class))) 90 .thenReturn(false); 91 92 mSummary.onAttach(mContext); 93 final SuggestionControllerMixin mixin = ReflectionHelpers 94 .getField(mSummary, "mSuggestionControllerMixin"); 95 assertThat(mixin).isNull(); 96 } 97 98 @Test onAttach_suggestionEnabled_shouldStartSuggestionControllerMixin()99 public void onAttach_suggestionEnabled_shouldStartSuggestionControllerMixin() { 100 when(mFeatureFactory.suggestionsFeatureProvider.isSuggestionEnabled(any(Context.class))) 101 .thenReturn(true); 102 103 mSummary.onAttach(mContext); 104 final SuggestionControllerMixin mixin = ReflectionHelpers 105 .getField(mSummary, "mSuggestionControllerMixin"); 106 assertThat(mixin).isNotNull(); 107 } 108 109 @Test updateCategory_shouldGetCategoryFromFeatureProvider()110 public void updateCategory_shouldGetCategoryFromFeatureProvider() { 111 ReflectionHelpers.setField(mSummary, "mSuggestionControllerMixin", 112 mSuggestionControllerMixin); 113 114 when(mSuggestionControllerMixin.isSuggestionLoaded()).thenReturn(true); 115 doReturn(mock(Activity.class)).when(mSummary).getActivity(); 116 mSummary.onAttach(mContext); 117 mSummary.updateCategory(); 118 119 verify(mSummaryLoader).updateSummaryToCache(nullable(DashboardCategory.class)); 120 verify(mDashboardFeatureProvider).getTilesForCategory(CategoryKey.CATEGORY_HOMEPAGE); 121 verify(mAdapter).setCategory(any()); 122 } 123 124 @Test updateCategory_shouldGetCategoryFromFeatureProvider_evenIfSuggestionDisabled()125 public void updateCategory_shouldGetCategoryFromFeatureProvider_evenIfSuggestionDisabled() { 126 when(mFeatureFactory.suggestionsFeatureProvider.isSuggestionEnabled(any(Context.class))) 127 .thenReturn(false); 128 129 doReturn(mock(Activity.class)).when(mSummary).getActivity(); 130 mSummary.onAttach(mContext); 131 mSummary.updateCategory(); 132 133 verify(mSummaryLoader).updateSummaryToCache(nullable(DashboardCategory.class)); 134 verify(mDashboardFeatureProvider).getTilesForCategory(CategoryKey.CATEGORY_HOMEPAGE); 135 verify(mAdapter).setCategory(any()); 136 } 137 138 @Test onConditionChanged_PositionAtTop_ScrollToTop()139 public void onConditionChanged_PositionAtTop_ScrollToTop() { 140 when(mLayoutManager.findFirstCompletelyVisibleItemPosition()).thenReturn(1); 141 mSummary.onConditionsChanged(); 142 mSummary.onConditionsChanged(); 143 verify(mDashboard).scrollToPosition(0); 144 } 145 146 @Test onConditionChanged_PositionNotTop_RemainPosition()147 public void onConditionChanged_PositionNotTop_RemainPosition() { 148 when(mLayoutManager.findFirstCompletelyVisibleItemPosition()).thenReturn(2); 149 mSummary.onConditionsChanged(); 150 mSummary.onConditionsChanged(); 151 verify(mDashboard, never()).scrollToPosition(0); 152 } 153 154 @Test onConditionChanged_firstCall_shouldIgnore()155 public void onConditionChanged_firstCall_shouldIgnore() { 156 mSummary.onConditionsChanged(); 157 verify(mAdapter, never()).setConditions(any()); 158 } 159 160 @Test onConditionChanged_secondCall_shouldSetConditionsOnAdapter()161 public void onConditionChanged_secondCall_shouldSetConditionsOnAdapter() { 162 mSummary.onConditionsChanged(); 163 mSummary.onConditionsChanged(); 164 verify(mAdapter).setConditions(any()); 165 } 166 167 @Test onCategoryChanged_noRebuildOnFirstCall()168 public void onCategoryChanged_noRebuildOnFirstCall() { 169 doReturn(mock(Activity.class)).when(mSummary).getActivity(); 170 doNothing().when(mSummary).rebuildUI(); 171 mSummary.onCategoriesChanged(); 172 verify(mSummary, never()).rebuildUI(); 173 } 174 175 @Test onCategoryChanged_rebuildOnSecondCall()176 public void onCategoryChanged_rebuildOnSecondCall() { 177 doReturn(mock(Activity.class)).when(mSummary).getActivity(); 178 doNothing().when(mSummary).rebuildUI(); 179 mSummary.onCategoriesChanged(); 180 mSummary.onCategoriesChanged(); 181 verify(mSummary).rebuildUI(); 182 } 183 }