• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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.accounts;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.mockito.ArgumentMatchers.any;
22 import static org.mockito.ArgumentMatchers.anyString;
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 
29 import android.accounts.Account;
30 import android.app.ActivityManager;
31 import android.content.ContentProvider;
32 import android.content.ContentResolver;
33 import android.content.Context;
34 import android.content.Intent;
35 import android.content.pm.ApplicationInfo;
36 import android.content.pm.PackageInfo;
37 import android.content.pm.ProviderInfo;
38 import android.content.pm.ResolveInfo;
39 import android.graphics.Bitmap;
40 import android.net.Uri;
41 import android.os.Bundle;
42 import android.widget.ImageView;
43 
44 import com.android.settings.homepage.SettingsHomepageActivity;
45 import com.android.settings.homepage.contextualcards.slices.BatteryFixSliceTest;
46 
47 import org.junit.Before;
48 import org.junit.Test;
49 import org.junit.runner.RunWith;
50 import org.mockito.MockitoAnnotations;
51 import org.robolectric.Robolectric;
52 import org.robolectric.RobolectricTestRunner;
53 import org.robolectric.RuntimeEnvironment;
54 import org.robolectric.android.controller.ActivityController;
55 import org.robolectric.annotation.Config;
56 import org.robolectric.annotation.Implementation;
57 import org.robolectric.annotation.Implements;
58 import org.robolectric.shadow.api.Shadow;
59 import org.robolectric.shadows.ShadowActivityManager;
60 import org.robolectric.shadows.ShadowContentResolver;
61 import org.robolectric.shadows.ShadowPackageManager;
62 
63 @RunWith(RobolectricTestRunner.class)
64 public class AvatarViewMixinTest {
65     private static final String DUMMY_ACCOUNT = "test@domain.com";
66     private static final String DUMMY_DOMAIN = "domain.com";
67     private static final String DUMMY_AUTHORITY = "authority.domain.com";
68     private static final String METHOD_GET_ACCOUNT_AVATAR = "getAccountAvatar";
69 
70     private Context mContext;
71     private ImageView mImageView;
72     private ActivityController mController;
73     private SettingsHomepageActivity mActivity;
74 
75     @Before
setUp()76     public void setUp() {
77         MockitoAnnotations.initMocks(this);
78         mContext = RuntimeEnvironment.application;
79         mImageView = new ImageView(mContext);
80         mController = Robolectric.buildActivity(SettingsHomepageActivity.class).create();
81         mActivity = (SettingsHomepageActivity) mController.get();
82     }
83 
84     @Test
hasAccount_useDefaultAccountData_returnFalse()85     public void hasAccount_useDefaultAccountData_returnFalse() {
86         final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(mActivity, mImageView);
87         assertThat(avatarViewMixin.hasAccount()).isFalse();
88     }
89 
90     @Test
91     @Config(shadows = ShadowAccountFeatureProviderImpl.class)
hasAccount_useShadowAccountData_returnTrue()92     public void hasAccount_useShadowAccountData_returnTrue() {
93         final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(mActivity, mImageView);
94         assertThat(avatarViewMixin.hasAccount()).isTrue();
95     }
96 
97     @Test
onStart_configDisabled_doNothing()98     public void onStart_configDisabled_doNothing() {
99         final AvatarViewMixin mixin = spy(new AvatarViewMixin(mActivity, mImageView));
100         mixin.onStart();
101 
102         verify(mixin, never()).hasAccount();
103     }
104 
105     @Test
onStart_lowRamDevice_doNothing()106     public void onStart_lowRamDevice_doNothing() {
107         final AvatarViewMixin mixin = spy(new AvatarViewMixin(mActivity, mImageView));
108 
109         final ShadowActivityManager activityManager =
110                 Shadow.extract(mContext.getSystemService(ActivityManager.class));
111         activityManager.setIsLowRamDevice(true);
112 
113         mixin.onStart();
114 
115         verify(mixin, never()).hasAccount();
116     }
117 
118     @Test
119     @Config(qualifiers = "mcc999",
120             shadows = {
121                     BatteryFixSliceTest.ShadowBatteryStatsHelperLoader.class,
122                     BatteryFixSliceTest.ShadowBatteryTipLoader.class
123             })
onStart_useMockAvatarViewMixin_shouldBeExecuted()124     public void onStart_useMockAvatarViewMixin_shouldBeExecuted() {
125         final AvatarViewMixin mockAvatar = spy(new AvatarViewMixin(mActivity, mImageView));
126 
127         mActivity.getLifecycle().addObserver(mockAvatar);
128         mController.start();
129 
130         verify(mockAvatar).hasAccount();
131     }
132 
133     @Test
queryProviderAuthority_useShadowPackagteManager_returnNull()134     public void queryProviderAuthority_useShadowPackagteManager_returnNull() {
135         final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(mActivity, mImageView);
136 
137         assertThat(avatarViewMixin.queryProviderAuthority()).isNull();
138     }
139 
140     @Test
queryProviderAuthority_useNewShadowPackagteManager_returnAuthority()141     public void queryProviderAuthority_useNewShadowPackagteManager_returnAuthority() {
142         final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(mActivity, mImageView);
143         ShadowPackageManager shadowPackageManager = Shadow.extract(mContext.getPackageManager());
144         final PackageInfo accountProvider = new PackageInfo();
145         accountProvider.packageName = "test.pkg";
146         accountProvider.applicationInfo = new ApplicationInfo();
147         accountProvider.applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
148         accountProvider.applicationInfo.packageName = accountProvider.packageName;
149         accountProvider.providers = new ProviderInfo[1];
150         accountProvider.providers[0] = new ProviderInfo();
151         accountProvider.providers[0].authority = DUMMY_AUTHORITY;
152         accountProvider.providers[0].packageName = accountProvider.packageName;
153         accountProvider.providers[0].name = "test.class";
154         accountProvider.providers[0].applicationInfo = accountProvider.applicationInfo;
155 
156         final ResolveInfo resolveInfo = new ResolveInfo();
157         resolveInfo.providerInfo = accountProvider.providers[0];
158         shadowPackageManager.addResolveInfoForIntent(AvatarViewMixin.INTENT_GET_ACCOUNT_DATA,
159                 resolveInfo);
160         assertThat(avatarViewMixin.queryProviderAuthority()).isEqualTo(DUMMY_AUTHORITY);
161     }
162 
163     @Test
callWithGetAccountAvatarMethod_useDummyData_shouldReturnAccountNameAndAvatar()164     public void callWithGetAccountAvatarMethod_useDummyData_shouldReturnAccountNameAndAvatar() {
165         final ContentResolver contentResolver = mContext.getContentResolver();
166         final Uri uri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(
167                 DUMMY_AUTHORITY).build();
168         final ContentProvider mockContentProvider = mock(ContentProvider.class);
169 
170         ShadowContentResolver.registerProviderInternal(DUMMY_AUTHORITY, mockContentProvider);
171 
172         final Bundle bundle = new Bundle();
173         final Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
174         bundle.putParcelable("account_avatar", bitmap);
175         bundle.putString("account_name", DUMMY_ACCOUNT);
176         doReturn(bundle).when(mockContentProvider).call(anyString(), anyString(),
177                 any(Bundle.class));
178 
179         contentResolver.call(uri, METHOD_GET_ACCOUNT_AVATAR, null /* arg */, null /* extras */);
180 
181         final Object object = bundle.getParcelable("account_avatar");
182         assertThat(object instanceof Bitmap).isTrue();
183         assertThat(bundle.getString("account_name")).isEqualTo(DUMMY_ACCOUNT);
184     }
185 
186     @Test
onClickAvatar_withEmptyUri_startActivityShouldNotBeExecuted()187     public void onClickAvatar_withEmptyUri_startActivityShouldNotBeExecuted() {
188         final SettingsHomepageActivity activity = spy((SettingsHomepageActivity) mController.get());
189         final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(activity, mImageView);
190 
191         mImageView.performClick();
192 
193         verify(activity, never()).startActivity(any(Intent.class));
194     }
195 
196     @Implements(value = AccountFeatureProviderImpl.class)
197     public static class ShadowAccountFeatureProviderImpl {
198 
199         @Implementation
getAccounts(Context context)200         protected Account[] getAccounts(Context context) {
201             return new Account[]{new Account(DUMMY_ACCOUNT, DUMMY_DOMAIN)};
202         }
203     }
204 }
205