OSDN Git Service

Merge "Zen Condition text and primary click changes"
[android-x86/packages-apps-Settings.git] / tests / robotests / src / com / android / settings / dashboard / suggestions / SuggestionAdapterTest.java
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 package com.android.settings.dashboard.suggestions;
17
18 import static com.google.common.truth.Truth.assertThat;
19
20 import static org.mockito.ArgumentMatchers.any;
21 import static org.mockito.ArgumentMatchers.anyInt;
22 import static org.mockito.Mockito.mock;
23 import static org.mockito.Mockito.never;
24 import static org.mockito.Mockito.spy;
25 import static org.mockito.Mockito.verify;
26 import static org.mockito.Mockito.when;
27
28 import android.app.PendingIntent;
29 import android.content.Context;
30 import android.content.res.TypedArray;
31 import android.graphics.drawable.Drawable;
32 import android.graphics.drawable.Icon;
33 import android.service.settings.suggestions.Suggestion;
34 import android.view.LayoutInflater;
35 import android.view.View;
36 import android.widget.FrameLayout;
37 import android.widget.LinearLayout;
38
39 import com.android.internal.logging.nano.MetricsProto;
40 import com.android.settings.R;
41 import com.android.settings.SettingsActivity;
42 import com.android.settings.TestConfig;
43 import com.android.settings.dashboard.DashboardAdapter;
44 import com.android.settings.testutils.FakeFeatureFactory;
45 import com.android.settings.testutils.SettingsRobolectricTestRunner;
46 import com.android.settingslib.suggestions.SuggestionControllerMixin;
47
48 import org.junit.Before;
49 import org.junit.Test;
50 import org.junit.runner.RunWith;
51 import org.mockito.Answers;
52 import org.mockito.Mock;
53 import org.mockito.MockitoAnnotations;
54 import org.robolectric.RuntimeEnvironment;
55 import org.robolectric.annotation.Config;
56 import org.robolectric.util.ReflectionHelpers;
57
58 import java.util.ArrayList;
59 import java.util.List;
60
61 @RunWith(SettingsRobolectricTestRunner.class)
62 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
63 public class SuggestionAdapterTest {
64
65     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
66     private SettingsActivity mActivity;
67     @Mock
68     private SuggestionControllerMixin mSuggestionControllerMixin;
69     private FakeFeatureFactory mFeatureFactory;
70     private Context mContext;
71     private SuggestionAdapter mSuggestionAdapter;
72     private DashboardAdapter.DashboardItemHolder mSuggestionHolder;
73     private List<Suggestion> mOneSuggestion;
74     private List<Suggestion> mTwoSuggestions;
75
76     @Before
77     public void setUp() {
78         MockitoAnnotations.initMocks(this);
79         mContext = RuntimeEnvironment.application;
80         mFeatureFactory = FakeFeatureFactory.setupForTest();
81
82         final Suggestion suggestion1 = new Suggestion.Builder("id1")
83                 .setTitle("Test suggestion 1")
84                 .build();
85         final Suggestion suggestion2 = new Suggestion.Builder("id2")
86                 .setTitle("Test suggestion 2")
87                 .build();
88         mOneSuggestion = new ArrayList<>();
89         mOneSuggestion.add(suggestion1);
90         mTwoSuggestions = new ArrayList<>();
91         mTwoSuggestions.add(suggestion1);
92         mTwoSuggestions.add(suggestion2);
93     }
94
95     @Test
96     public void getItemCount_shouldReturnListSize() {
97         mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin,
98             null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
99         mSuggestionAdapter.setSuggestions(mOneSuggestion);
100         assertThat(mSuggestionAdapter.getItemCount()).isEqualTo(1);
101
102         mSuggestionAdapter.setSuggestions(mTwoSuggestions);
103         assertThat(mSuggestionAdapter.getItemCount()).isEqualTo(2);
104     }
105
106     @Test
107     public void getItemViewType_shouldReturnSuggestionTile() {
108         mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin,
109             null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
110         mSuggestionAdapter.setSuggestions(mOneSuggestion);
111         assertThat(mSuggestionAdapter.getItemViewType(0))
112             .isEqualTo(R.layout.suggestion_tile);
113     }
114
115     @Test
116     public void getItemType_hasButton_shouldReturnSuggestionWithButton() {
117         final List<Suggestion> suggestions = new ArrayList<>();
118         suggestions.add(new Suggestion.Builder("id")
119                 .setFlags(Suggestion.FLAG_HAS_BUTTON)
120                 .setTitle("123")
121                 .setSummary("456")
122                 .build());
123         mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin,
124             null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
125         mSuggestionAdapter.setSuggestions(suggestions);
126
127         assertThat(mSuggestionAdapter.getItemViewType(0))
128             .isEqualTo(R.layout.suggestion_tile_with_button);
129     }
130
131     @Test
132     public void onBindViewHolder_shouldLog() {
133         final View view = spy(LayoutInflater.from(mContext).inflate(
134             R.layout.suggestion_tile, new LinearLayout(mContext), true));
135         mSuggestionHolder = new DashboardAdapter.DashboardItemHolder(view);
136         mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin,
137             null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
138         mSuggestionAdapter.setSuggestions(mOneSuggestion);
139
140         // Bind twice
141         mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
142         mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
143
144         // Log once
145         verify(mFeatureFactory.metricsFeatureProvider).action(
146                 mContext, MetricsProto.MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
147                 mOneSuggestion.get(0).getId());
148     }
149
150     @Test
151     public void onBindViewHolder_itemViewShouldHandleClick()
152             throws PendingIntent.CanceledException {
153         final List<Suggestion> suggestions = makeSuggestions("pkg1");
154         setupSuggestions(mActivity, suggestions);
155
156         mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
157         mSuggestionHolder.itemView.performClick();
158
159         verify(mSuggestionControllerMixin).launchSuggestion(suggestions.get(0));
160         verify(suggestions.get(0).getPendingIntent()).send();
161     }
162
163     @Test
164     public void onBindViewHolder_hasButton_buttonShouldHandleClick()
165         throws PendingIntent.CanceledException {
166         final List<Suggestion> suggestions = new ArrayList<>();
167         final PendingIntent pendingIntent = mock(PendingIntent.class);
168         suggestions.add(new Suggestion.Builder("id")
169             .setFlags(Suggestion.FLAG_HAS_BUTTON)
170             .setTitle("123")
171             .setSummary("456")
172             .setPendingIntent(pendingIntent)
173             .build());
174         mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin,
175             null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
176         mSuggestionAdapter.setSuggestions(suggestions);
177         mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
178             new FrameLayout(RuntimeEnvironment.application),
179             mSuggestionAdapter.getItemViewType(0));
180
181         mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
182         mSuggestionHolder.itemView.findViewById(android.R.id.primary).performClick();
183
184         verify(mSuggestionControllerMixin).launchSuggestion(suggestions.get(0));
185         verify(pendingIntent).send();
186     }
187
188     @Test
189     public void getSuggestions_shouldReturnSuggestionWhenMatch() {
190         final List<Suggestion> suggestions = makeSuggestions("pkg1");
191         setupSuggestions(mActivity, suggestions);
192
193         assertThat(mSuggestionAdapter.getSuggestion(0)).isNotNull();
194     }
195
196     @Test
197     public void onBindViewHolder_closeButtonShouldHandleClick()
198         throws PendingIntent.CanceledException {
199         final List<Suggestion> suggestions = makeSuggestions("pkg1");
200         final SuggestionAdapter.Callback callback = mock(SuggestionAdapter.Callback.class);
201         mSuggestionAdapter = new SuggestionAdapter(mActivity, mSuggestionControllerMixin,
202             null /* savedInstanceState */, callback, null /* lifecycle */);
203         mSuggestionAdapter.setSuggestions(suggestions);
204         mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
205             new FrameLayout(RuntimeEnvironment.application),
206             mSuggestionAdapter.getItemViewType(0));
207
208         mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
209         mSuggestionHolder.itemView.findViewById(R.id.close_button).performClick();
210
211         final Suggestion suggestion = suggestions.get(0);
212         verify(mFeatureFactory.suggestionsFeatureProvider).dismissSuggestion(
213             mActivity, mSuggestionControllerMixin, suggestion);
214         verify(callback).onSuggestionClosed(suggestion);
215     }
216
217     @Test
218     public void onBindViewHolder_iconNotTintable_shouldNotTintIcon()
219             throws PendingIntent.CanceledException {
220         final Icon icon = mock(Icon.class);
221         final Suggestion suggestion = new Suggestion.Builder("pkg1")
222             .setPendingIntent(mock(PendingIntent.class))
223             .setIcon(icon)
224             .build();
225         final List<Suggestion> suggestions = new ArrayList<>();
226         suggestions.add(suggestion);
227         mSuggestionAdapter = new SuggestionAdapter(mActivity, mSuggestionControllerMixin,
228             null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
229         mSuggestionAdapter.setSuggestions(suggestions);
230         mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
231             new FrameLayout(RuntimeEnvironment.application),
232             mSuggestionAdapter.getItemViewType(0));
233         DashboardAdapter.IconCache cache = mock(DashboardAdapter.IconCache.class);
234         final Drawable drawable = mock(Drawable.class);
235         when(cache.getIcon(icon)).thenReturn(drawable);
236         ReflectionHelpers.setField(mSuggestionAdapter, "mCache", cache);
237
238         mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
239
240         verify(drawable, never()).setTint(anyInt());
241     }
242
243     @Test
244     public void onBindViewHolder_iconTintable_shouldTintIcon()
245             throws PendingIntent.CanceledException {
246         final Icon icon = mock(Icon.class);
247         final int FLAG_ICON_TINTABLE = 1 << 1;
248         final Suggestion suggestion = new Suggestion.Builder("pkg1")
249             .setPendingIntent(mock(PendingIntent.class))
250             .setIcon(icon)
251             .setFlags(FLAG_ICON_TINTABLE)
252             .build();
253         final List<Suggestion> suggestions = new ArrayList<>();
254         suggestions.add(suggestion);
255         mSuggestionAdapter = new SuggestionAdapter(mActivity, mSuggestionControllerMixin,
256             null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
257         mSuggestionAdapter.setSuggestions(suggestions);
258         mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
259             new FrameLayout(RuntimeEnvironment.application),
260             mSuggestionAdapter.getItemViewType(0));
261         DashboardAdapter.IconCache cache = mock(DashboardAdapter.IconCache.class);
262         final Drawable drawable = mock(Drawable.class);
263         when(cache.getIcon(icon)).thenReturn(drawable);
264         ReflectionHelpers.setField(mSuggestionAdapter, "mCache", cache);
265         TypedArray typedArray = mock(TypedArray.class);
266         final int colorAccent = 1234;
267         when(mActivity.obtainStyledAttributes(any())).thenReturn(typedArray);
268         when(typedArray.getColor(anyInt(), anyInt())).thenReturn(colorAccent);
269
270         mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
271
272         verify(drawable).setTint(colorAccent);
273     }
274
275     private void setupSuggestions(Context context, List<Suggestion> suggestions) {
276         mSuggestionAdapter = new SuggestionAdapter(context, mSuggestionControllerMixin,
277             null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
278         mSuggestionAdapter.setSuggestions(suggestions);
279         mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
280                 new FrameLayout(RuntimeEnvironment.application),
281                 mSuggestionAdapter.getItemViewType(0));
282     }
283
284     private List<Suggestion> makeSuggestions(String... pkgNames) {
285         final List<Suggestion> suggestions = new ArrayList<>();
286         for (String pkgName : pkgNames) {
287             final Suggestion suggestion = new Suggestion.Builder(pkgName)
288                     .setPendingIntent(mock(PendingIntent.class))
289                     .build();
290             suggestions.add(suggestion);
291         }
292         return suggestions;
293     }
294 }