• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.applications;
18 
19 
20 import static com.google.common.truth.Truth.assertThat;
21 import static org.mockito.Matchers.any;
22 import static org.mockito.Matchers.anyInt;
23 import static org.mockito.Matchers.eq;
24 import static org.mockito.Mockito.mock;
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.TextView;
42 
43 import com.android.settings.R;
44 import com.android.settings.SettingsRobolectricTestRunner;
45 import com.android.settings.TestConfig;
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.RuntimeEnvironment;
54 import org.robolectric.annotation.Config;
55 
56 @RunWith(SettingsRobolectricTestRunner.class)
57 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
58 public class AppHeaderControllerTest {
59 
60     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
61     private Context mContext;
62     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
63     private Activity mActivity;
64     @Mock
65     private Fragment mFragment;
66 
67     private Context mShadowContext;
68     private LayoutInflater mLayoutInflater;
69     private PackageInfo mInfo;
70     private AppHeaderController mController;
71 
72 
73     @Before
setUp()74     public void setUp() {
75         MockitoAnnotations.initMocks(this);
76         mShadowContext = RuntimeEnvironment.application;
77         when(mFragment.getContext()).thenReturn(mShadowContext);
78         mLayoutInflater = LayoutInflater.from(mShadowContext);
79         mInfo = new PackageInfo();
80         mInfo.versionName = "1234";
81     }
82 
83     @Test
testBuildView_constructedWithoutView_shouldCreateNewView()84     public void testBuildView_constructedWithoutView_shouldCreateNewView() {
85         mController = new AppHeaderController(mShadowContext, mFragment, null);
86         View view = mController.done(mActivity);
87 
88         assertThat(view).isNotNull();
89     }
90 
91     @Test
testBuildView_withContext_shouldBuildPreference()92     public void testBuildView_withContext_shouldBuildPreference() {
93         mController = new AppHeaderController(mShadowContext, mFragment, null);
94         Preference preference = mController.done(mActivity, mShadowContext);
95 
96         assertThat(preference instanceof LayoutPreference).isTrue();
97     }
98 
99     @Test
testBuildView_constructedWithView_shouldReturnSameView()100     public void testBuildView_constructedWithView_shouldReturnSameView() {
101         View inputView = mLayoutInflater.inflate(R.layout.app_details, null /* root */);
102         mController = new AppHeaderController(mShadowContext, mFragment, inputView);
103         View view = mController.done(mActivity);
104 
105         assertThat(view).isSameAs(inputView);
106     }
107 
108     @Test
bindViews_shouldBindAllData()109     public void bindViews_shouldBindAllData() {
110         final String testString = "test";
111         final View appHeader = mLayoutInflater.inflate(R.layout.app_details, null /* root */);
112         final TextView label = appHeader.findViewById(R.id.app_detail_title);
113         final TextView version = appHeader.findViewById(R.id.app_detail_summary);
114 
115         mController = new AppHeaderController(mShadowContext, mFragment, appHeader);
116         mController.setLabel(testString);
117         mController.setSummary(testString);
118         mController.setIcon(mShadowContext.getDrawable(R.drawable.ic_add));
119         mController.done(mActivity);
120 
121         assertThat(label.getText()).isEqualTo(testString);
122         assertThat(version.getText()).isEqualTo(testString);
123     }
124 
125     @Test
bindButton_hasAppPref_shouldShowButton()126     public void bindButton_hasAppPref_shouldShowButton() {
127         final ResolveInfo info = new ResolveInfo();
128         info.activityInfo = new ActivityInfo();
129         info.activityInfo.packageName = "123";
130         info.activityInfo.name = "321";
131         final View appLinks = mLayoutInflater
132                 .inflate(R.layout.app_details, null /* root */);
133         when(mContext.getPackageManager().resolveActivity(any(Intent.class), anyInt()))
134                 .thenReturn(info);
135 
136         mController = new AppHeaderController(mContext, mFragment, appLinks);
137         mController.setButtonActions(
138                 AppHeaderController.ActionType.ACTION_APP_PREFERENCE,
139                 AppHeaderController.ActionType.ACTION_NONE);
140         mController.done(mActivity);
141 
142         assertThat(appLinks.findViewById(R.id.left_button).getVisibility())
143                 .isEqualTo(View.VISIBLE);
144         assertThat(appLinks.findViewById(R.id.right_button).getVisibility())
145                 .isEqualTo(View.GONE);
146         try {
147             appLinks.findViewById(R.id.left_button).performClick();
148         } catch (Exception e) {
149             // Ignore exception because the launching intent is fake.
150         }
151         verify(mFragment).startActivity(any(Intent.class));
152     }
153 
154     @Test
bindButton_noAppPref_shouldNotShowButton()155     public void bindButton_noAppPref_shouldNotShowButton() {
156         final View appLinks = mLayoutInflater
157                 .inflate(R.layout.app_details, null /* root */);
158         when(mContext.getPackageManager().resolveActivity(any(Intent.class), anyInt()))
159                 .thenReturn(null);
160 
161         mController = new AppHeaderController(mContext, mFragment, appLinks);
162         mController.setButtonActions(
163                 AppHeaderController.ActionType.ACTION_APP_PREFERENCE,
164                 AppHeaderController.ActionType.ACTION_NONE);
165         mController.done(mActivity);
166 
167         assertThat(appLinks.findViewById(R.id.left_button).getVisibility())
168                 .isEqualTo(View.GONE);
169         assertThat(appLinks.findViewById(R.id.right_button).getVisibility())
170                 .isEqualTo(View.GONE);
171     }
172 
173     @Test
bindButton_noAppInfo_shouldNotShowButton()174     public void bindButton_noAppInfo_shouldNotShowButton() {
175         final View appLinks = mLayoutInflater
176                 .inflate(R.layout.app_details, null /* root */);
177 
178         mController = new AppHeaderController(mContext, mFragment, appLinks);
179         mController.setPackageName(null)
180                 .setButtonActions(
181                         AppHeaderController.ActionType.ACTION_APP_INFO,
182                         AppHeaderController.ActionType.ACTION_NONE);
183         mController.done(mActivity);
184 
185         assertThat(appLinks.findViewById(R.id.left_button).getVisibility())
186                 .isEqualTo(View.GONE);
187         assertThat(appLinks.findViewById(R.id.right_button).getVisibility())
188                 .isEqualTo(View.GONE);
189     }
190 
191     @Test
bindButton_hasAppInfo_shouldShowButton()192     public void bindButton_hasAppInfo_shouldShowButton() {
193         final View appLinks = mLayoutInflater
194                 .inflate(R.layout.app_details, null /* root */);
195         when(mFragment.getActivity()).thenReturn(mock(Activity.class));
196 
197         mController = new AppHeaderController(mContext, mFragment, appLinks);
198         mController.setPackageName("123")
199                 .setUid(UserHandle.USER_SYSTEM)
200                 .setButtonActions(
201                         AppHeaderController.ActionType.ACTION_APP_INFO,
202                         AppHeaderController.ActionType.ACTION_NOTIF_PREFERENCE);
203         mController.done(mActivity);
204 
205         assertThat(appLinks.findViewById(R.id.left_button).getVisibility())
206                 .isEqualTo(View.VISIBLE);
207         assertThat(appLinks.findViewById(R.id.right_button).getVisibility())
208                 .isEqualTo(View.GONE);
209     }
210 
211     @Test
bindButton_hasAppInfo_shouldHaveContentDescription()212     public void bindButton_hasAppInfo_shouldHaveContentDescription() {
213         final View appLinks = mLayoutInflater
214                 .inflate(R.layout.app_details, null /* root */);
215         when(mFragment.getActivity()).thenReturn(mock(Activity.class));
216         when(mContext.getString(eq(R.string.application_info_label))).thenReturn("App Info");
217 
218         mController = new AppHeaderController(mContext, mFragment, appLinks);
219         mController.setPackageName("123")
220                 .setUid(UserHandle.USER_SYSTEM)
221                 .setButtonActions(
222                         AppHeaderController.ActionType.ACTION_APP_INFO,
223                         AppHeaderController.ActionType.ACTION_NOTIF_PREFERENCE);
224         mController.done(mActivity);
225 
226         assertThat(appLinks.findViewById(R.id.left_button).getContentDescription())
227                 .isEqualTo("App Info");
228     }
229 
230     @Test
bindButton_hasAppNotifIntent_shouldShowButton()231     public void bindButton_hasAppNotifIntent_shouldShowButton() {
232         final View appLinks = mLayoutInflater
233                 .inflate(R.layout.app_details, null /* root */);
234 
235         mController = new AppHeaderController(mContext, mFragment, appLinks);
236         mController.setAppNotifPrefIntent(new Intent())
237                 .setButtonActions(
238                         AppHeaderController.ActionType.ACTION_NOTIF_PREFERENCE,
239                         AppHeaderController.ActionType.ACTION_NONE);
240         mController.done(mActivity);
241 
242         assertThat(appLinks.findViewById(R.id.left_button).getVisibility())
243                 .isEqualTo(View.VISIBLE);
244         assertThat(appLinks.findViewById(R.id.right_button).getVisibility())
245                 .isEqualTo(View.GONE);
246     }
247 
248     // Ensure that the instant app label does not show up when we haven't told the controller the
249     // app is instant.
250     @Test
instantApps_normalAppsDontGetLabel()251     public void instantApps_normalAppsDontGetLabel() {
252         final View appHeader = mLayoutInflater.inflate(R.layout.app_details, null /* root */);
253         mController = new AppHeaderController(mContext, mFragment, appHeader);
254         mController.done(mActivity);
255         assertThat(appHeader.findViewById(R.id.install_type).getVisibility())
256                 .isEqualTo(View.GONE);
257     }
258 
259     // Test that the "instant apps" label is present in the header when we have an instant app.
260     @Test
instantApps_expectedHeaderItem()261     public void instantApps_expectedHeaderItem() {
262         final View appHeader = mLayoutInflater.inflate(R.layout.app_details, null /* root */);
263         mController = new AppHeaderController(mContext, mFragment, appHeader);
264         mController.setIsInstantApp(true);
265         mController.done(mActivity);
266         TextView label = appHeader.findViewById(R.id.install_type);
267         assertThat(label.getVisibility()).isEqualTo(View.VISIBLE);
268         assertThat(label.getText()).isEqualTo(
269                 appHeader.getResources().getString(R.string.install_type_instant));
270         assertThat(appHeader.findViewById(R.id.app_detail_summary).getVisibility())
271                 .isEqualTo(View.GONE);
272     }
273 
274     @Test
styleActionBar_invalidObjects_shouldNotCrash()275     public void styleActionBar_invalidObjects_shouldNotCrash() {
276         mController = new AppHeaderController(mShadowContext, mFragment, null);
277         mController.styleActionBar(null);
278 
279         when(mActivity.getActionBar()).thenReturn(null);
280         mController.styleActionBar(mActivity);
281 
282         verify(mActivity).getActionBar();
283     }
284 
285     @Test
styleActionBar_setElevationAndBackground()286     public void styleActionBar_setElevationAndBackground() {
287         final ActionBar actionBar = mActivity.getActionBar();
288 
289         mController = new AppHeaderController(mShadowContext, mFragment, null);
290         mController.styleActionBar(mActivity);
291 
292         verify(actionBar).setElevation(0);
293         // Enforce a color drawable as background here, as image based drawables might not be
294         // wide enough to cover entire action bar.
295         verify(actionBar).setBackgroundDrawable(any(ColorDrawable.class));
296     }
297 
298     @Test
initAppHeaderController_appHeaderNull_useFragmentContext()299     public void initAppHeaderController_appHeaderNull_useFragmentContext() {
300         mController = new AppHeaderController(mContext, mFragment, null);
301 
302         // Fragment.getContext() is invoked to inflate the view
303         verify(mFragment).getContext();
304     }
305 }
306