OSDN Git Service

daa42b4a5d82b6821460bd08f76a286c1437e926
[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_noAppPref_shouldNotShowButton() {
169         final View appLinks = mLayoutInflater
170                 .inflate(R.layout.settings_entity_header, null /* root */);
171         when(mContext.getPackageManager().resolveActivity(any(Intent.class), anyInt()))
172                 .thenReturn(null);
173
174         mController = EntityHeaderController.newInstance(mActivity, mFragment, appLinks);
175         mController.setButtonActions(
176                 EntityHeaderController.ActionType.ACTION_APP_PREFERENCE,
177                 EntityHeaderController.ActionType.ACTION_NONE);
178         mController.done(mActivity);
179
180         final ImageButton button1 = appLinks.findViewById(android.R.id.button1);
181         assertThat(button1.getVisibility()).isEqualTo(View.GONE);
182         assertThat(button1.getDrawable()).isNull();
183         assertThat(appLinks.findViewById(android.R.id.button2).getVisibility())
184                 .isEqualTo(View.GONE);
185     }
186
187     @Test
188     public void bindButton_noAppInfo_shouldNotAttachClickListener() {
189         final View appLinks = mLayoutInflater
190                 .inflate(R.layout.settings_entity_header, null /* root */);
191         final Activity activity = mock(Activity.class);
192         when(mFragment.getActivity()).thenReturn(activity);
193
194         mController = EntityHeaderController.newInstance(mActivity, mFragment, appLinks);
195         mController.setPackageName(null)
196                 .setHasAppInfoLink(true)
197                 .setButtonActions(
198                         EntityHeaderController.ActionType.ACTION_NONE,
199                         EntityHeaderController.ActionType.ACTION_NONE);
200         mController.done(mActivity);
201
202         assertThat(appLinks.findViewById(android.R.id.button1).getVisibility())
203                 .isEqualTo(View.GONE);
204         assertThat(appLinks.findViewById(android.R.id.button2).getVisibility())
205                 .isEqualTo(View.GONE);
206
207         appLinks.findViewById(R.id.entity_header_content).performClick();
208         verify(mFragment, never()).getActivity();
209         verify(activity, never()).startActivity(any(Intent.class));
210     }
211
212     @Test
213     public void bindButton_hasAppInfo_shouldAttachClickListener() {
214         final View appLinks = mLayoutInflater
215                 .inflate(R.layout.settings_entity_header, null /* root */);
216         final Activity activity = mock(Activity.class);
217         when(mFragment.getActivity()).thenReturn(activity);
218         when(mContext.getString(eq(R.string.application_info_label))).thenReturn("App Info");
219
220         mController = EntityHeaderController.newInstance(mActivity, mFragment, appLinks);
221         mController.setPackageName("123")
222                 .setUid(UserHandle.USER_SYSTEM)
223                 .setHasAppInfoLink(true)
224                 .setButtonActions(
225                         EntityHeaderController.ActionType.ACTION_NOTIF_PREFERENCE,
226                         EntityHeaderController.ActionType.ACTION_NONE);
227         mController.done(mActivity);
228
229         appLinks.findViewById(R.id.entity_header_content).performClick();
230         verify(activity).startActivityForResultAsUser(
231                 any(Intent.class), anyInt(), any(UserHandle.class));
232     }
233
234     @Test
235     public void iconContentDescription_shouldWorkWithSetIcon() {
236         final View view = mLayoutInflater
237                 .inflate(R.layout.settings_entity_header, null /* root */);
238         when(mFragment.getActivity()).thenReturn(mock(Activity.class));
239         mController = EntityHeaderController.newInstance(mActivity, mFragment, view);
240         String description = "Fake Description";
241         mController.setIcon(mShadowContext.getDrawable(R.drawable.ic_add));
242         mController.setIconContentDescription(description);
243         mController.done(mActivity);
244         assertThat(view.findViewById(R.id.entity_header_icon).getContentDescription().toString())
245                 .isEqualTo(description);
246     }
247
248     @Test
249     public void iconContentDescription_shouldWorkWithoutSetIcon() {
250         final View view = mLayoutInflater
251                 .inflate(R.layout.settings_entity_header, null /* root */);
252         when(mFragment.getActivity()).thenReturn(mock(Activity.class));
253         mController = EntityHeaderController.newInstance(mActivity, mFragment, view);
254         String description = "Fake Description";
255         mController.setIconContentDescription(description);
256         mController.done(mActivity);
257         assertThat(view.findViewById(R.id.entity_header_icon).getContentDescription().toString())
258                 .isEqualTo(description);
259     }
260
261     @Test
262     public void bindButton_hasAppNotifIntent_shouldShowButton() {
263         final View appLinks = mLayoutInflater
264                 .inflate(R.layout.settings_entity_header, null /* root */);
265
266         mController = EntityHeaderController.newInstance(mActivity, mFragment, appLinks);
267         mController.setAppNotifPrefIntent(new Intent())
268                 .setButtonActions(
269                         EntityHeaderController.ActionType.ACTION_NOTIF_PREFERENCE,
270                         EntityHeaderController.ActionType.ACTION_NONE);
271         mController.done(mActivity);
272
273         assertThat(appLinks.findViewById(android.R.id.button1).getVisibility())
274                 .isEqualTo(View.VISIBLE);
275         assertThat(appLinks.findViewById(android.R.id.button2).getVisibility())
276                 .isEqualTo(View.GONE);
277     }
278
279     // Ensure that the instant app label does not show up when we haven't told the controller the
280     // app is instant.
281     @Test
282     public void instantApps_normalAppsDontGetLabel() {
283         final View header = mLayoutInflater.inflate(
284                 R.layout.settings_entity_header, null /* root */);
285         mController = EntityHeaderController.newInstance(mActivity, mFragment, header);
286         mController.done(mActivity);
287
288         assertThat(header.findViewById(R.id.install_type).getVisibility())
289                 .isEqualTo(View.GONE);
290     }
291
292     // Test that the "instant apps" label is present in the header when we have an instant app.
293     @Test
294     public void instantApps_expectedHeaderItem() {
295         final View header = mLayoutInflater.inflate(
296                 R.layout.settings_entity_header, null /* root */);
297         mController = EntityHeaderController.newInstance(mActivity, mFragment, header);
298         mController.setIsInstantApp(true);
299         mController.done(mActivity);
300         TextView label = header.findViewById(R.id.install_type);
301
302         assertThat(label.getVisibility()).isEqualTo(View.VISIBLE);
303         assertThat(label.getText()).isEqualTo(
304                 header.getResources().getString(R.string.install_type_instant));
305         assertThat(header.findViewById(R.id.entity_header_summary).getVisibility())
306                 .isEqualTo(View.GONE);
307     }
308
309     @Test
310     public void styleActionBar_invalidObjects_shouldNotCrash() {
311         mController = EntityHeaderController.newInstance(mActivity, mFragment, null);
312         mController.styleActionBar(null);
313
314         when(mActivity.getActionBar()).thenReturn(null);
315         mController.styleActionBar(mActivity);
316
317         verify(mActivity).getActionBar();
318     }
319
320     @Test
321     public void styleActionBar_setElevationAndBackground() {
322         final ActionBar actionBar = mActivity.getActionBar();
323
324         mController = EntityHeaderController.newInstance(mActivity, mFragment, null);
325         mController.styleActionBar(mActivity);
326
327         verify(actionBar).setElevation(0);
328         // Enforce a color drawable as background here, as image based drawables might not be
329         // wide enough to cover entire action bar.
330         verify(actionBar).setBackgroundDrawable(any(ColorDrawable.class));
331     }
332
333     @Test
334     public void initAppHeaderController_appHeaderNull_useFragmentContext() {
335         mController = EntityHeaderController.newInstance(mActivity, mFragment, null);
336
337         // Fragment.getContext() is invoked to inflate the view
338         verify(mFragment).getContext();
339     }
340 }