OSDN Git Service

Zen automatic rule page ui changes
[android-x86/packages-apps-Settings.git] / tests / robotests / src / com / android / settings / widget / EntityHeaderControllerTest.java
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
17 package com.android.settings.widget;
18
19 import static com.google.common.truth.Truth.assertThat;
20 import static org.mockito.Matchers.any;
21 import static org.mockito.Matchers.anyInt;
22 import static org.mockito.Matchers.eq;
23 import static org.mockito.Mockito.mock;
24 import static org.mockito.Mockito.never;
25 import static org.mockito.Mockito.verify;
26 import static org.mockito.Mockito.when;
27
28 import android.app.ActionBar;
29 import android.app.Activity;
30 import android.app.Fragment;
31 import android.content.Context;
32 import android.content.Intent;
33 import android.content.pm.ActivityInfo;
34 import android.content.pm.PackageInfo;
35 import android.content.pm.ResolveInfo;
36 import android.graphics.drawable.ColorDrawable;
37 import android.os.UserHandle;
38 import android.support.v7.preference.Preference;
39 import android.view.LayoutInflater;
40 import android.view.View;
41 import android.widget.ImageButton;
42 import android.widget.TextView;
43
44 import com.android.internal.logging.nano.MetricsProto;
45 import com.android.settings.R;
46 import com.android.settings.TestConfig;
47 import com.android.settings.applications.LayoutPreference;
48 import com.android.settings.testutils.FakeFeatureFactory;
49 import com.android.settings.testutils.SettingsRobolectricTestRunner;
50
51 import org.junit.Before;
52 import org.junit.Test;
53 import org.junit.runner.RunWith;
54 import org.mockito.Answers;
55 import org.mockito.Mock;
56 import org.mockito.MockitoAnnotations;
57 import org.robolectric.RuntimeEnvironment;
58 import org.robolectric.annotation.Config;
59
60 @RunWith(SettingsRobolectricTestRunner.class)
61 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
62 public class EntityHeaderControllerTest {
63
64     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
65     private Context mContext;
66     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
67     private Activity mActivity;
68     @Mock
69     private Fragment mFragment;
70
71     private Context mShadowContext;
72     private LayoutInflater mLayoutInflater;
73     private PackageInfo mInfo;
74     private EntityHeaderController mController;
75     private FakeFeatureFactory mFeatureFactory;
76
77     @Before
78     public void setUp() {
79         MockitoAnnotations.initMocks(this);
80         mFeatureFactory = FakeFeatureFactory.setupForTest();
81         mShadowContext = RuntimeEnvironment.application;
82         when(mActivity.getApplicationContext()).thenReturn(mShadowContext);
83         when(mContext.getApplicationContext()).thenReturn(mContext);
84         when(mFragment.getContext()).thenReturn(mShadowContext);
85         mLayoutInflater = LayoutInflater.from(mShadowContext);
86         mInfo = new PackageInfo();
87         mInfo.versionName = "1234";
88     }
89
90     @Test
91     public void testBuildView_constructedWithoutView_shouldCreateNewView() {
92         mController = EntityHeaderController.newInstance(mActivity, mFragment, null);
93         View view = mController.done(mActivity);
94
95         assertThat(view).isNotNull();
96     }
97
98     @Test
99     public void testBuildView_withContext_shouldBuildPreference() {
100         mController = EntityHeaderController.newInstance(mActivity, mFragment, null);
101         Preference preference = mController.done(mActivity, mShadowContext);
102
103         assertThat(preference instanceof LayoutPreference).isTrue();
104     }
105
106     @Test
107     public void testBuildView_constructedWithView_shouldReturnSameView() {
108         View inputView = mLayoutInflater.inflate(R.layout.settings_entity_header, null /* root */);
109         mController = EntityHeaderController.newInstance(mActivity, mFragment, inputView);
110         View view = mController.done(mActivity);
111
112         assertThat(view).isSameAs(inputView);
113     }
114
115     @Test
116     public void bindViews_shouldBindAllData() {
117         final String testString = "test";
118         final View header = mLayoutInflater.inflate(
119                 R.layout.settings_entity_header, null /* root */);
120         final TextView label = header.findViewById(R.id.entity_header_title);
121         final TextView version = header.findViewById(R.id.entity_header_summary);
122
123         mController = EntityHeaderController.newInstance(mActivity, mFragment, header);
124         mController.setLabel(testString);
125         mController.setSummary(testString);
126         mController.setIcon(mShadowContext.getDrawable(R.drawable.ic_add));
127         mController.done(mActivity);
128
129         assertThat(label.getText()).isEqualTo(testString);
130         assertThat(version.getText()).isEqualTo(testString);
131     }
132
133     @Test
134     public void bindButton_hasAppPref_shouldShowButton() {
135         final ResolveInfo info = new ResolveInfo();
136         info.activityInfo = new ActivityInfo();
137         info.activityInfo.packageName = "123";
138         info.activityInfo.name = "321";
139         final View appLinks = mLayoutInflater
140                 .inflate(R.layout.settings_entity_header, null /* root */);
141         when(mActivity.getApplicationContext()).thenReturn(mContext);
142         when(mContext.getPackageManager().resolveActivity(any(Intent.class), anyInt()))
143                 .thenReturn(info);
144
145         mController = EntityHeaderController.newInstance(mActivity, mFragment, appLinks);
146         mController.setButtonActions(
147                 EntityHeaderController.ActionType.ACTION_APP_PREFERENCE,
148                 EntityHeaderController.ActionType.ACTION_NONE);
149         mController.done(mActivity);
150
151         final ImageButton button1 = appLinks.findViewById(android.R.id.button1);
152         assertThat(button1.getVisibility()).isEqualTo(View.VISIBLE);
153         assertThat(button1.getDrawable()).isNotNull();
154         assertThat(appLinks.findViewById(android.R.id.button2).getVisibility())
155                 .isEqualTo(View.GONE);
156         try {
157             appLinks.findViewById(android.R.id.button1).performClick();
158         } catch (Exception e) {
159             // Ignore exception because the launching intent is fake.
160         }
161         verify(mFeatureFactory.metricsFeatureProvider).actionWithSource(mContext,
162                 MetricsProto.MetricsEvent.VIEW_UNKNOWN,
163                 MetricsProto.MetricsEvent.ACTION_OPEN_APP_SETTING);
164         verify(mFragment).startActivity(any(Intent.class));
165     }
166
167     @Test
168     public void bindButton_hasEditRuleNameClickListener_shouldShowButton() {
169         final ResolveInfo info = new ResolveInfo();
170         info.activityInfo = new ActivityInfo();
171         info.activityInfo.packageName = "123";
172         info.activityInfo.name = "321";
173         final View view = mLayoutInflater
174                 .inflate(R.layout.settings_entity_header, null /* root */);
175         when(mActivity.getApplicationContext()).thenReturn(mContext);
176
177         mController = EntityHeaderController.newInstance(mActivity, mFragment, view);
178         mController.setEditZenRuleNameListener(new View.OnClickListener() {
179             public void onClick(View v) {
180                 // do nothing
181             }
182         });
183         mController.setButtonActions(
184                 EntityHeaderController.ActionType.ACTION_DND_RULE_PREFERENCE,
185                 EntityHeaderController.ActionType.ACTION_NONE);
186         mController.done(mActivity);
187
188         final ImageButton button1 = view.findViewById(android.R.id.button1);
189         assertThat(button1.getVisibility()).isEqualTo(View.VISIBLE);
190         assertThat(button1.getDrawable()).isNotNull();
191         assertThat(view.findViewById(android.R.id.button2).getVisibility())
192                 .isEqualTo(View.GONE);
193     }
194
195     @Test
196     public void bindButton_noEditRuleNameClickListener_shouldNotShowButton() {
197         final ResolveInfo info = new ResolveInfo();
198         info.activityInfo = new ActivityInfo();
199         info.activityInfo.packageName = "123";
200         info.activityInfo.name = "321";
201         final View view = mLayoutInflater
202                 .inflate(R.layout.settings_entity_header, null /* root */);
203         when(mActivity.getApplicationContext()).thenReturn(mContext);
204
205         mController = EntityHeaderController.newInstance(mActivity, mFragment, view);
206         mController.setButtonActions(
207                 EntityHeaderController.ActionType.ACTION_DND_RULE_PREFERENCE,
208                 EntityHeaderController.ActionType.ACTION_NONE);
209         mController.done(mActivity);
210
211         assertThat(view.findViewById(android.R.id.button1).getVisibility())
212                 .isEqualTo(View.GONE);
213         assertThat(view.findViewById(android.R.id.button2).getVisibility())
214                 .isEqualTo(View.GONE);
215     }
216
217
218     @Test
219     public void bindButton_noAppPref_shouldNotShowButton() {
220         final View appLinks = mLayoutInflater
221                 .inflate(R.layout.settings_entity_header, null /* root */);
222         when(mContext.getPackageManager().resolveActivity(any(Intent.class), anyInt()))
223                 .thenReturn(null);
224
225         mController = EntityHeaderController.newInstance(mActivity, mFragment, appLinks);
226         mController.setButtonActions(
227                 EntityHeaderController.ActionType.ACTION_APP_PREFERENCE,
228                 EntityHeaderController.ActionType.ACTION_NONE);
229         mController.done(mActivity);
230
231         final ImageButton button1 = appLinks.findViewById(android.R.id.button1);
232         assertThat(button1.getVisibility()).isEqualTo(View.GONE);
233         assertThat(button1.getDrawable()).isNull();
234         assertThat(appLinks.findViewById(android.R.id.button2).getVisibility())
235                 .isEqualTo(View.GONE);
236     }
237
238     @Test
239     public void bindButton_noAppInfo_shouldNotAttachClickListener() {
240         final View appLinks = mLayoutInflater
241                 .inflate(R.layout.settings_entity_header, null /* root */);
242         final Activity activity = mock(Activity.class);
243         when(mFragment.getActivity()).thenReturn(activity);
244
245         mController = EntityHeaderController.newInstance(mActivity, mFragment, appLinks);
246         mController.setPackageName(null)
247                 .setHasAppInfoLink(true)
248                 .setButtonActions(
249                         EntityHeaderController.ActionType.ACTION_NONE,
250                         EntityHeaderController.ActionType.ACTION_NONE);
251         mController.done(mActivity);
252
253         assertThat(appLinks.findViewById(android.R.id.button1).getVisibility())
254                 .isEqualTo(View.GONE);
255         assertThat(appLinks.findViewById(android.R.id.button2).getVisibility())
256                 .isEqualTo(View.GONE);
257
258         appLinks.findViewById(R.id.entity_header_content).performClick();
259         verify(mFragment, never()).getActivity();
260         verify(activity, never()).startActivity(any(Intent.class));
261     }
262
263     @Test
264     public void bindButton_hasAppInfo_shouldAttachClickListener() {
265         final View appLinks = mLayoutInflater
266                 .inflate(R.layout.settings_entity_header, null /* root */);
267         final Activity activity = mock(Activity.class);
268         when(mFragment.getActivity()).thenReturn(activity);
269         when(mContext.getString(eq(R.string.application_info_label))).thenReturn("App Info");
270
271         mController = EntityHeaderController.newInstance(mActivity, mFragment, appLinks);
272         mController.setPackageName("123")
273                 .setUid(UserHandle.USER_SYSTEM)
274                 .setHasAppInfoLink(true)
275                 .setButtonActions(
276                         EntityHeaderController.ActionType.ACTION_NOTIF_PREFERENCE,
277                         EntityHeaderController.ActionType.ACTION_NONE);
278         mController.done(mActivity);
279
280         appLinks.findViewById(R.id.entity_header_content).performClick();
281         verify(activity).startActivityForResultAsUser(
282                 any(Intent.class), anyInt(), any(UserHandle.class));
283     }
284
285     @Test
286     public void iconContentDescription_shouldWorkWithSetIcon() {
287         final View view = mLayoutInflater
288                 .inflate(R.layout.settings_entity_header, null /* root */);
289         when(mFragment.getActivity()).thenReturn(mock(Activity.class));
290         mController = EntityHeaderController.newInstance(mActivity, mFragment, view);
291         String description = "Fake Description";
292         mController.setIcon(mShadowContext.getDrawable(R.drawable.ic_add));
293         mController.setIconContentDescription(description);
294         mController.done(mActivity);
295         assertThat(view.findViewById(R.id.entity_header_icon).getContentDescription().toString())
296                 .isEqualTo(description);
297     }
298
299     @Test
300     public void iconContentDescription_shouldWorkWithoutSetIcon() {
301         final View view = mLayoutInflater
302                 .inflate(R.layout.settings_entity_header, null /* root */);
303         when(mFragment.getActivity()).thenReturn(mock(Activity.class));
304         mController = EntityHeaderController.newInstance(mActivity, mFragment, view);
305         String description = "Fake Description";
306         mController.setIconContentDescription(description);
307         mController.done(mActivity);
308         assertThat(view.findViewById(R.id.entity_header_icon).getContentDescription().toString())
309                 .isEqualTo(description);
310     }
311
312     @Test
313     public void bindButton_hasAppNotifIntent_shouldShowButton() {
314         final View appLinks = mLayoutInflater
315                 .inflate(R.layout.settings_entity_header, null /* root */);
316
317         mController = EntityHeaderController.newInstance(mActivity, mFragment, appLinks);
318         mController.setAppNotifPrefIntent(new Intent())
319                 .setButtonActions(
320                         EntityHeaderController.ActionType.ACTION_NOTIF_PREFERENCE,
321                         EntityHeaderController.ActionType.ACTION_NONE);
322         mController.done(mActivity);
323
324         assertThat(appLinks.findViewById(android.R.id.button1).getVisibility())
325                 .isEqualTo(View.VISIBLE);
326         assertThat(appLinks.findViewById(android.R.id.button2).getVisibility())
327                 .isEqualTo(View.GONE);
328     }
329
330     // Ensure that the instant app label does not show up when we haven't told the controller the
331     // app is instant.
332     @Test
333     public void instantApps_normalAppsDontGetLabel() {
334         final View header = mLayoutInflater.inflate(
335                 R.layout.settings_entity_header, null /* root */);
336         mController = EntityHeaderController.newInstance(mActivity, mFragment, header);
337         mController.done(mActivity);
338
339         assertThat(header.findViewById(R.id.install_type).getVisibility())
340                 .isEqualTo(View.GONE);
341     }
342
343     // Test that the "instant apps" label is present in the header when we have an instant app.
344     @Test
345     public void instantApps_expectedHeaderItem() {
346         final View header = mLayoutInflater.inflate(
347                 R.layout.settings_entity_header, null /* root */);
348         mController = EntityHeaderController.newInstance(mActivity, mFragment, header);
349         mController.setIsInstantApp(true);
350         mController.done(mActivity);
351         TextView label = header.findViewById(R.id.install_type);
352
353         assertThat(label.getVisibility()).isEqualTo(View.VISIBLE);
354         assertThat(label.getText()).isEqualTo(
355                 header.getResources().getString(R.string.install_type_instant));
356         assertThat(header.findViewById(R.id.entity_header_summary).getVisibility())
357                 .isEqualTo(View.GONE);
358     }
359
360     @Test
361     public void styleActionBar_invalidObjects_shouldNotCrash() {
362         mController = EntityHeaderController.newInstance(mActivity, mFragment, null);
363         mController.styleActionBar(null);
364
365         when(mActivity.getActionBar()).thenReturn(null);
366         mController.styleActionBar(mActivity);
367
368         verify(mActivity).getActionBar();
369     }
370
371     @Test
372     public void styleActionBar_setElevationAndBackground() {
373         final ActionBar actionBar = mActivity.getActionBar();
374
375         mController = EntityHeaderController.newInstance(mActivity, mFragment, null);
376         mController.styleActionBar(mActivity);
377
378         verify(actionBar).setElevation(0);
379         // Enforce a color drawable as background here, as image based drawables might not be
380         // wide enough to cover entire action bar.
381         verify(actionBar).setBackgroundDrawable(any(ColorDrawable.class));
382     }
383
384     @Test
385     public void initAppHeaderController_appHeaderNull_useFragmentContext() {
386         mController = EntityHeaderController.newInstance(mActivity, mFragment, null);
387
388         // Fragment.getContext() is invoked to inflate the view
389         verify(mFragment).getContext();
390     }
391 }