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.search2; 18 19 import android.content.Context; 20 import android.content.Intent; 21 import android.content.pm.ResolveInfo; 22 import android.content.pm.UserInfo; 23 import android.os.UserManager; 24 25 import com.android.settings.R; 26 import com.android.settings.SettingsRobolectricTestRunner; 27 import com.android.settings.TestConfig; 28 import com.android.settings.applications.PackageManagerWrapper; 29 import com.android.settings.dashboard.SiteMapManager; 30 import com.android.settings.testutils.ApplicationTestUtils; 31 import com.android.settings.testutils.FakeFeatureFactory; 32 33 import org.junit.Before; 34 import org.junit.Test; 35 import org.junit.runner.RunWith; 36 import org.mockito.Answers; 37 import org.mockito.Mock; 38 import org.mockito.MockitoAnnotations; 39 import org.robolectric.annotation.Config; 40 41 import java.util.ArrayList; 42 import java.util.Arrays; 43 import java.util.List; 44 45 import static android.content.pm.ApplicationInfo.FLAG_SYSTEM; 46 import static android.content.pm.ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 47 import static com.google.common.truth.Truth.assertThat; 48 import static org.mockito.Matchers.any; 49 import static org.mockito.Matchers.anyInt; 50 import static org.mockito.Matchers.anyString; 51 import static org.mockito.Matchers.eq; 52 import static org.mockito.Mockito.mock; 53 import static org.mockito.Mockito.never; 54 import static org.mockito.Mockito.spy; 55 import static org.mockito.Mockito.verify; 56 import static org.mockito.Mockito.when; 57 58 @RunWith(SettingsRobolectricTestRunner.class) 59 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) 60 public class InstalledAppResultLoaderTest { 61 62 @Mock(answer = Answers.RETURNS_DEEP_STUBS) 63 private Context mContext; 64 @Mock(answer = Answers.RETURNS_DEEP_STUBS) 65 private PackageManagerWrapper mPackageManagerWrapper; 66 @Mock 67 private UserManager mUserManager; 68 @Mock 69 private SiteMapManager mSiteMapManager; 70 71 private InstalledAppResultLoader mLoader; 72 73 @Before setUp()74 public void setUp() { 75 MockitoAnnotations.initMocks(this); 76 FakeFeatureFactory.setupForTest(mContext); 77 FakeFeatureFactory factory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext); 78 when(factory.searchFeatureProvider.getSiteMapManager()) 79 .thenReturn(mSiteMapManager); 80 final List<UserInfo> infos = new ArrayList<>(); 81 infos.add(new UserInfo(1, "user 1", 0)); 82 when(mUserManager.getProfiles(anyInt())).thenReturn(infos); 83 when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); 84 when(mContext.getString(R.string.applications_settings)) 85 .thenReturn("app"); 86 when(mPackageManagerWrapper.getInstalledApplicationsAsUser(anyInt(), anyInt())) 87 .thenReturn(Arrays.asList( 88 ApplicationTestUtils.buildInfo(0 /* uid */, "app1", FLAG_SYSTEM, 89 0 /* targetSdkVersion */), 90 ApplicationTestUtils.buildInfo(0 /* uid */, "app2", FLAG_SYSTEM, 91 0 /* targetSdkVersion */), 92 ApplicationTestUtils.buildInfo(0 /* uid */, "app3", FLAG_SYSTEM, 93 0 /* targetSdkVersion */), 94 ApplicationTestUtils.buildInfo(0 /* uid */, "app4", 0 /* flags */, 95 0 /* targetSdkVersion */), 96 ApplicationTestUtils.buildInfo(0 /* uid */, "app", 0 /* flags */, 97 0 /* targetSdkVersion */), 98 ApplicationTestUtils.buildInfo(0 /* uid */, "appBuffer", 0 /* flags */, 99 0 /* targetSdkVersion */))); 100 } 101 102 @Test query_noMatchingQuery_shouldReturnEmptyResult()103 public void query_noMatchingQuery_shouldReturnEmptyResult() { 104 final String query = "abc"; 105 106 mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query, 107 mSiteMapManager); 108 109 assertThat(mLoader.loadInBackground()).isEmpty(); 110 } 111 112 @Test query_matchingQuery_shouldReturnNonSystemApps()113 public void query_matchingQuery_shouldReturnNonSystemApps() { 114 final String query = "app"; 115 116 mLoader = spy(new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query, 117 mSiteMapManager)); 118 when(mLoader.getContext()).thenReturn(mContext); 119 when(mSiteMapManager.buildBreadCrumb(eq(mContext), anyString(), anyString())) 120 .thenReturn(Arrays.asList(new String[]{"123"})); 121 122 assertThat(mLoader.loadInBackground().size()).isEqualTo(3); 123 verify(mSiteMapManager) 124 .buildBreadCrumb(eq(mContext), anyString(), anyString()); 125 } 126 127 @Test query_matchingQuery_shouldReturnSystemAppUpdates()128 public void query_matchingQuery_shouldReturnSystemAppUpdates() { 129 when(mPackageManagerWrapper.getInstalledApplicationsAsUser(anyInt(), anyInt())) 130 .thenReturn(Arrays.asList( 131 ApplicationTestUtils.buildInfo(0 /* uid */, "app1", FLAG_UPDATED_SYSTEM_APP, 132 0 /* targetSdkVersion */))); 133 final String query = "app"; 134 135 mLoader = spy(new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query, 136 mSiteMapManager)); 137 when(mLoader.getContext()).thenReturn(mContext); 138 139 assertThat(mLoader.loadInBackground().size()).isEqualTo(1); 140 verify(mSiteMapManager) 141 .buildBreadCrumb(eq(mContext), anyString(), anyString()); 142 } 143 144 @Test query_matchingQuery_shouldReturnSystemAppIfLaunchable()145 public void query_matchingQuery_shouldReturnSystemAppIfLaunchable() { 146 when(mPackageManagerWrapper.getInstalledApplicationsAsUser(anyInt(), anyInt())) 147 .thenReturn(Arrays.asList( 148 ApplicationTestUtils.buildInfo(0 /* uid */, "app1", FLAG_SYSTEM, 149 0 /* targetSdkVersion */))); 150 final List<ResolveInfo> list = mock(List.class); 151 when(list.size()).thenReturn(1); 152 when(mPackageManagerWrapper.queryIntentActivitiesAsUser( 153 any(Intent.class), anyInt(), anyInt())) 154 .thenReturn(list); 155 156 final String query = "app"; 157 158 mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query, 159 mSiteMapManager); 160 161 assertThat(mLoader.loadInBackground().size()).isEqualTo(1); 162 } 163 164 @Test query_matchingQuery_shouldNotReturnSystemAppIfNotLaunchable()165 public void query_matchingQuery_shouldNotReturnSystemAppIfNotLaunchable() { 166 when(mPackageManagerWrapper.getInstalledApplicationsAsUser(anyInt(), anyInt())) 167 .thenReturn(Arrays.asList( 168 ApplicationTestUtils.buildInfo(0 /* uid */, "app1", FLAG_SYSTEM, 169 0 /* targetSdkVersion */))); 170 when(mPackageManagerWrapper.queryIntentActivitiesAsUser( 171 any(Intent.class), anyInt(), anyInt())) 172 .thenReturn(null); 173 174 final String query = "app"; 175 176 mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query, 177 mSiteMapManager); 178 179 assertThat(mLoader.loadInBackground()).isEmpty(); 180 verify(mSiteMapManager, never()) 181 .buildBreadCrumb(eq(mContext), anyString(), anyString()); 182 } 183 184 @Test query_matchingQuery_shouldRankBasedOnSimilarity()185 public void query_matchingQuery_shouldRankBasedOnSimilarity() { 186 final String query = "app"; 187 188 mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query, 189 mSiteMapManager); 190 final List<? extends SearchResult> results = mLoader.loadInBackground(); 191 192 // List is sorted by rank 193 assertThat(results.get(0).rank).isAtMost(results.get(1).rank); 194 assertThat(results.get(0).title).isEqualTo("app4"); 195 assertThat(results.get(1).title).isEqualTo("app"); 196 assertThat(results.get(2).title).isEqualTo("appBuffer"); 197 } 198 199 @Test query_normalWord_MatchPrefix()200 public void query_normalWord_MatchPrefix() { 201 final String query = "ba"; 202 final String packageName = "Bananas"; 203 when(mPackageManagerWrapper.getInstalledApplicationsAsUser(anyInt(), anyInt())) 204 .thenReturn(Arrays.asList( 205 ApplicationTestUtils.buildInfo(0 /* uid */, packageName, 0 /* flags */, 206 0 /* targetSdkVersion */))); 207 mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query, 208 mSiteMapManager); 209 210 assertThat(mLoader.loadInBackground().size()).isEqualTo(1); 211 } 212 213 @Test query_CapitalCase_DoestMatchSecondWord()214 public void query_CapitalCase_DoestMatchSecondWord() { 215 final String query = "Apples"; 216 final String packageName = "BananasApples"; 217 when(mPackageManagerWrapper.getInstalledApplicationsAsUser(anyInt(), anyInt())) 218 .thenReturn(Arrays.asList( 219 ApplicationTestUtils.buildInfo(0 /* uid */, packageName, 0 /* flags */, 220 0 /* targetSdkVersion */))); 221 mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query, 222 mSiteMapManager); 223 224 assertThat(mLoader.loadInBackground().size()).isEqualTo(0); 225 } 226 227 @Test query_TwoWords_MatchesFirstWord()228 public void query_TwoWords_MatchesFirstWord() { 229 final String query = "Banana"; 230 final String packageName = "Bananas Apples"; 231 when(mPackageManagerWrapper.getInstalledApplicationsAsUser(anyInt(), anyInt())) 232 .thenReturn(Arrays.asList( 233 ApplicationTestUtils.buildInfo(0 /* uid */, packageName, 0 /* flags */, 234 0 /* targetSdkVersion */))); 235 mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query, 236 mSiteMapManager); 237 238 assertThat(mLoader.loadInBackground().size()).isEqualTo(1); 239 } 240 241 @Test query_TwoWords_MatchesSecondWord()242 public void query_TwoWords_MatchesSecondWord() { 243 final String query = "Apple"; 244 final String packageName = "Bananas Apples"; 245 when(mPackageManagerWrapper.getInstalledApplicationsAsUser(anyInt(), anyInt())) 246 .thenReturn(Arrays.asList( 247 ApplicationTestUtils.buildInfo(0 /* uid */, packageName, 0 /* flags */, 248 0 /* targetSdkVersion */))); 249 mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query, 250 mSiteMapManager); 251 252 assertThat(mLoader.loadInBackground().size()).isEqualTo(1); 253 } 254 255 @Test query_ThreeWords_MatchesThirdWord()256 public void query_ThreeWords_MatchesThirdWord() { 257 final String query = "Pear"; 258 final String packageName = "Bananas Apples Pears"; 259 when(mPackageManagerWrapper.getInstalledApplicationsAsUser(anyInt(), anyInt())) 260 .thenReturn(Arrays.asList( 261 ApplicationTestUtils.buildInfo(0 /* uid */, packageName, 0 /* flags */, 262 0 /* targetSdkVersion */))); 263 mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query, 264 mSiteMapManager); 265 266 assertThat(mLoader.loadInBackground().size()).isEqualTo(1); 267 } 268 269 @Test query_DoubleSpacedWords_MatchesSecondWord()270 public void query_DoubleSpacedWords_MatchesSecondWord() { 271 final String query = "Apple"; 272 final String packageName = "Bananas Apples"; 273 when(mPackageManagerWrapper.getInstalledApplicationsAsUser(anyInt(), anyInt())) 274 .thenReturn(Arrays.asList( 275 ApplicationTestUtils.buildInfo(0 /* uid */, packageName, 0 /* flags */, 276 0 /* targetSdkVersion */))); 277 mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query, 278 mSiteMapManager); 279 280 assertThat(mLoader.loadInBackground().size()).isEqualTo(1); 281 } 282 283 @Test query_SpecialChar_MatchesSecondWord()284 public void query_SpecialChar_MatchesSecondWord() { 285 final String query = "Apple"; 286 final String packageName = "Bananas & Apples"; 287 when(mPackageManagerWrapper.getInstalledApplicationsAsUser(anyInt(), anyInt())) 288 .thenReturn(Arrays.asList( 289 ApplicationTestUtils.buildInfo(0 /* uid */, packageName, 0 /* flags */, 290 0 /* targetSdkVersion */))); 291 mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query, 292 mSiteMapManager); 293 294 assertThat(mLoader.loadInBackground().size()).isEqualTo(1); 295 } 296 297 @Test query_TabSeparated_MatchesSecondWord()298 public void query_TabSeparated_MatchesSecondWord() { 299 final String query = "Apple"; 300 final String packageName = "Bananas\tApples"; 301 when(mPackageManagerWrapper.getInstalledApplicationsAsUser(anyInt(), anyInt())) 302 .thenReturn(Arrays.asList( 303 ApplicationTestUtils.buildInfo(0 /* uid */, packageName, 0 /* flags */, 304 0 /* targetSdkVersion */))); 305 mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query, 306 mSiteMapManager); 307 308 assertThat(mLoader.loadInBackground().size()).isEqualTo(1); 309 } 310 311 @Test query_LeadingNumber_MatchesWord()312 public void query_LeadingNumber_MatchesWord() { 313 final String query = "4"; 314 final String packageName = "4Bananas"; 315 when(mPackageManagerWrapper.getInstalledApplicationsAsUser(anyInt(), anyInt())) 316 .thenReturn(Arrays.asList( 317 ApplicationTestUtils.buildInfo(0 /* uid */, packageName, 0 /* flags */, 318 0 /* targetSdkVersion */))); 319 mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query, 320 mSiteMapManager); 321 322 assertThat(mLoader.loadInBackground().size()).isEqualTo(1); 323 } 324 325 @Test query_FirstWordPrefixOfQuery_NoMatch()326 public void query_FirstWordPrefixOfQuery_NoMatch() { 327 final String query = "Bananass"; 328 final String packageName = "Bananas Apples"; 329 when(mPackageManagerWrapper.getInstalledApplicationsAsUser(anyInt(), anyInt())) 330 .thenReturn(Arrays.asList( 331 ApplicationTestUtils.buildInfo(0 /* uid */, packageName, 0 /* flags */, 332 0 /* targetSdkVersion */))); 333 mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query, 334 mSiteMapManager); 335 336 assertThat(mLoader.loadInBackground().size()).isEqualTo(0); 337 } 338 339 @Test query_QueryLongerThanAppName_NoMatch()340 public void query_QueryLongerThanAppName_NoMatch() { 341 final String query = "BananasApples"; 342 final String packageName = "Bananas"; 343 when(mPackageManagerWrapper.getInstalledApplicationsAsUser(anyInt(), anyInt())) 344 .thenReturn(Arrays.asList( 345 ApplicationTestUtils.buildInfo(0 /* uid */, packageName, 0 /* flags */, 346 0 /* targetSdkVersion */))); 347 mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query, 348 mSiteMapManager); 349 350 assertThat(mLoader.loadInBackground().size()).isEqualTo(0); 351 } 352 } 353