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 18 package com.android.settings.search; 19 20 import android.app.Activity; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.graphics.drawable.Drawable; 24 import android.view.ViewGroup; 25 import android.widget.FrameLayout; 26 27 import com.android.settings.R; 28 import com.android.settings.SettingsRobolectricTestRunner; 29 import com.android.settings.TestConfig; 30 import com.android.settings.search2.AppSearchResult; 31 import com.android.settings.search2.DatabaseResultLoader; 32 import com.android.settings.search2.InlineSwitchViewHolder; 33 import com.android.settings.search2.InstalledAppResultLoader; 34 import com.android.settings.search2.IntentPayload; 35 import com.android.settings.search2.IntentSearchViewHolder; 36 import com.android.settings.search2.ResultPayload; 37 import com.android.settings.search2.SearchFragment; 38 import com.android.settings.search2.SearchResult; 39 import com.android.settings.search2.SearchResult.Builder; 40 import com.android.settings.search2.SearchResultsAdapter; 41 import com.android.settings.search2.SearchViewHolder; 42 43 import org.junit.Before; 44 import org.junit.Test; 45 import org.junit.runner.RunWith; 46 import org.mockito.Mock; 47 import org.mockito.MockitoAnnotations; 48 import org.robolectric.Robolectric; 49 import org.robolectric.annotation.Config; 50 51 import java.util.ArrayList; 52 import java.util.List; 53 54 import static com.google.common.truth.Truth.assertThat; 55 56 @RunWith(SettingsRobolectricTestRunner.class) 57 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) 58 public class SearchResultsAdapterTest { 59 60 @Mock 61 private SearchFragment mFragment; 62 private SearchResultsAdapter mAdapter; 63 private Context mContext; 64 private String mLoaderClassName; 65 66 private String[] TITLES = {"alpha", "bravo", "charlie", "appAlpha", "appBravo", "appCharlie"}; 67 68 @Before setUp()69 public void setUp() { 70 MockitoAnnotations.initMocks(this); 71 mContext = Robolectric.buildActivity(Activity.class).get(); 72 mAdapter = new SearchResultsAdapter(mFragment); 73 mLoaderClassName = DatabaseResultLoader.class.getName(); 74 } 75 76 @Test testNoResultsAdded_emptyListReturned()77 public void testNoResultsAdded_emptyListReturned() { 78 List<SearchResult> updatedResults = mAdapter.getSearchResults(); 79 assertThat(updatedResults).isEmpty(); 80 } 81 82 @Test testSingleSourceMerge_exactCopyReturned()83 public void testSingleSourceMerge_exactCopyReturned() { 84 ArrayList<SearchResult> intentResults = getIntentSampleResults(); 85 mAdapter.addSearchResults(intentResults, mLoaderClassName); 86 mAdapter.displaySearchResults(); 87 88 List<SearchResult> updatedResults = mAdapter.getSearchResults(); 89 assertThat(updatedResults).containsAllIn(intentResults); 90 } 91 92 @Test testCreateViewHolder_returnsIntentResult()93 public void testCreateViewHolder_returnsIntentResult() { 94 ViewGroup group = new FrameLayout(mContext); 95 SearchViewHolder view = mAdapter.onCreateViewHolder(group, 96 ResultPayload.PayloadType.INTENT); 97 assertThat(view).isInstanceOf(IntentSearchViewHolder.class); 98 } 99 100 @Test testCreateViewHolder_returnsInlineSwitchResult()101 public void testCreateViewHolder_returnsInlineSwitchResult() { 102 ViewGroup group = new FrameLayout(mContext); 103 SearchViewHolder view = mAdapter.onCreateViewHolder(group, 104 ResultPayload.PayloadType.INLINE_SWITCH); 105 assertThat(view).isInstanceOf(InlineSwitchViewHolder.class); 106 } 107 108 @Test testEndToEndSearch_properResultsMerged_correctOrder()109 public void testEndToEndSearch_properResultsMerged_correctOrder() { 110 mAdapter.addSearchResults(getDummyAppResults(), InstalledAppResultLoader.class.getName()); 111 mAdapter.addSearchResults(getDummyDbResults(), DatabaseResultLoader.class.getName()); 112 mAdapter.displaySearchResults(); 113 114 List<SearchResult> results = mAdapter.getSearchResults(); 115 List<SearchResult> sortedDummyResults = getSortedDummyResults(); 116 117 assertThat(results).containsExactlyElementsIn(sortedDummyResults).inOrder(); 118 } 119 120 @Test testEndToEndSearch_addResults_resultsAddedInOrder()121 public void testEndToEndSearch_addResults_resultsAddedInOrder() { 122 List<AppSearchResult> appResults = getDummyAppResults(); 123 List<SearchResult> dbResults = getDummyDbResults(); 124 // Add two individual items 125 mAdapter.addSearchResults(appResults.subList(0,1), 126 InstalledAppResultLoader.class.getName()); 127 mAdapter.addSearchResults(dbResults.subList(0,1), DatabaseResultLoader.class.getName()); 128 mAdapter.displaySearchResults(); 129 // Add super-set of items 130 mAdapter.addSearchResults(appResults, InstalledAppResultLoader.class.getName()); 131 mAdapter.addSearchResults(dbResults, DatabaseResultLoader.class.getName()); 132 mAdapter.displaySearchResults(); 133 134 List<SearchResult> results = mAdapter.getSearchResults(); 135 List<SearchResult> sortedDummyResults = getSortedDummyResults(); 136 assertThat(results).containsExactlyElementsIn(sortedDummyResults).inOrder(); 137 } 138 139 @Test testEndToEndSearch_removeResults_resultsAdded()140 public void testEndToEndSearch_removeResults_resultsAdded() { 141 List<AppSearchResult> appResults = getDummyAppResults(); 142 List<SearchResult> dbResults = getDummyDbResults(); 143 // Add list of items 144 mAdapter.addSearchResults(appResults, InstalledAppResultLoader.class.getName()); 145 mAdapter.addSearchResults(dbResults, DatabaseResultLoader.class.getName()); 146 mAdapter.displaySearchResults(); 147 // Add subset of items 148 mAdapter.addSearchResults(appResults.subList(0,1), 149 InstalledAppResultLoader.class.getName()); 150 mAdapter.addSearchResults(dbResults.subList(0,1), DatabaseResultLoader.class.getName()); 151 int count = mAdapter.displaySearchResults(); 152 153 List<SearchResult> results = mAdapter.getSearchResults(); 154 assertThat(results.get(0).title).isEqualTo(TITLES[0]); 155 assertThat(results.get(1).title).isEqualTo(TITLES[3]); 156 assertThat(count).isEqualTo(2); 157 } 158 getDummyDbResults()159 private List<SearchResult> getDummyDbResults() { 160 List<SearchResult> results = new ArrayList<>(); 161 IntentPayload payload = new IntentPayload(new Intent()); 162 SearchResult.Builder builder = new SearchResult.Builder(); 163 builder.addPayload(payload); 164 165 builder.addTitle(TITLES[0]) 166 .addRank(1); 167 results.add(builder.build()); 168 169 builder.addTitle(TITLES[1]) 170 .addRank(3); 171 results.add(builder.build()); 172 173 builder.addTitle(TITLES[2]) 174 .addRank(6); 175 results.add(builder.build()); 176 177 return results; 178 } 179 getDummyAppResults()180 private List<AppSearchResult> getDummyAppResults() { 181 List<AppSearchResult> results = new ArrayList<>(); 182 IntentPayload payload = new IntentPayload(new Intent()); 183 AppSearchResult.Builder builder = new AppSearchResult.Builder(); 184 builder.addPayload(payload); 185 186 builder.addTitle(TITLES[3]) 187 .addRank(1); 188 results.add(builder.build()); 189 190 builder.addTitle(TITLES[4]) 191 .addRank(2); 192 results.add(builder.build()); 193 194 builder.addTitle(TITLES[5]) 195 .addRank(4); 196 results.add(builder.build()); 197 198 return results; 199 } 200 getSortedDummyResults()201 private List<SearchResult> getSortedDummyResults() { 202 List<AppSearchResult> appResults = getDummyAppResults(); 203 List<SearchResult> dbResults = getDummyDbResults(); 204 List<SearchResult> sortedResults = new ArrayList<>(appResults.size() + dbResults.size()); 205 sortedResults.add(dbResults.get(0)); // alpha 206 sortedResults.add(appResults.get(0)); // appAlpha 207 sortedResults.add(appResults.get(1)); // appBravo 208 sortedResults.add(dbResults.get(1)); // bravo 209 sortedResults.add(appResults.get(2)); // appCharlie 210 sortedResults.add(dbResults.get(2)); // Charlie 211 212 return sortedResults; 213 } 214 getIntentSampleResults()215 private ArrayList<SearchResult> getIntentSampleResults() { 216 ArrayList<SearchResult> sampleResults = new ArrayList<>(); 217 ArrayList<String> breadcrumbs = new ArrayList<>(); 218 final Drawable icon = mContext.getDrawable(R.drawable.ic_search_history); 219 final ResultPayload payload = new IntentPayload(null); 220 final SearchResult.Builder builder = new Builder(); 221 builder.addTitle("title") 222 .addSummary("summary") 223 .addRank(1) 224 .addBreadcrumbs(breadcrumbs) 225 .addIcon(icon) 226 .addPayload(payload); 227 sampleResults.add(builder.build()); 228 229 builder.addRank(2); 230 sampleResults.add(builder.build()); 231 232 builder.addRank(3); 233 sampleResults.add(builder.build()); 234 return sampleResults; 235 } 236 }