1 /* 2 * Copyright (C) 2022 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.settingslib.spa.search 18 19 import android.content.Context 20 import android.database.Cursor 21 import android.os.Bundle 22 import android.os.Parcel 23 import androidx.test.core.app.ApplicationProvider 24 import androidx.test.ext.junit.runners.AndroidJUnit4 25 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder 26 import com.android.settingslib.spa.framework.common.SettingsPage 27 import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory 28 import com.android.settingslib.spa.framework.common.createSettingsPage 29 import com.android.settingslib.spa.tests.testutils.SpaEnvironmentForTest 30 import com.android.settingslib.spa.tests.testutils.SppForSearch 31 import com.google.common.truth.Truth 32 import org.junit.Test 33 import org.junit.runner.RunWith 34 35 @RunWith(AndroidJUnit4::class) 36 class SpaSearchProviderTest { 37 private val context: Context = ApplicationProvider.getApplicationContext() 38 private val spaEnvironment = 39 SpaEnvironmentForTest(context, listOf(SppForSearch.createSettingsPage())) 40 private val searchProvider = SpaSearchProvider() 41 private val pageOwner = spaEnvironment.createPage("SppForSearch") 42 43 @Test 44 fun testQueryColumnSetup() { 45 Truth.assertThat(QueryEnum.SEARCH_STATIC_DATA_QUERY.columnNames) 46 .containsExactlyElementsIn(QueryEnum.SEARCH_DYNAMIC_DATA_QUERY.columnNames) 47 Truth.assertThat(QueryEnum.SEARCH_MUTABLE_STATUS_DATA_QUERY.columnNames) 48 .containsExactlyElementsIn(QueryEnum.SEARCH_IMMUTABLE_STATUS_DATA_QUERY.columnNames) 49 Truth.assertThat(QueryEnum.SEARCH_STATIC_ROW_QUERY.columnNames) 50 .containsExactlyElementsIn(QueryEnum.SEARCH_DYNAMIC_ROW_QUERY.columnNames) 51 } 52 53 @Test 54 fun testQuerySearchStatusData() { 55 SpaEnvironmentFactory.reset(spaEnvironment) 56 57 val immutableStatus = searchProvider.querySearchImmutableStatusData() 58 Truth.assertThat(immutableStatus.count).isEqualTo(1) 59 immutableStatus.moveToFirst() 60 immutableStatus.checkValue( 61 QueryEnum.SEARCH_IMMUTABLE_STATUS_DATA_QUERY, 62 ColumnEnum.ENTRY_ID, 63 pageOwner.getEntryId("SearchDynamicWithImmutableStatus") 64 ) 65 immutableStatus.checkValue( 66 QueryEnum.SEARCH_IMMUTABLE_STATUS_DATA_QUERY, 67 ColumnEnum.ENTRY_LABEL, 68 pageOwner.getEntryLabel("SearchDynamicWithImmutableStatus") 69 ) 70 immutableStatus.checkValue( 71 QueryEnum.SEARCH_IMMUTABLE_STATUS_DATA_QUERY, ColumnEnum.ENTRY_DISABLED, true.toString() 72 ) 73 74 val mutableStatus = searchProvider.querySearchMutableStatusData() 75 Truth.assertThat(mutableStatus.count).isEqualTo(2) 76 mutableStatus.moveToFirst() 77 mutableStatus.checkValue( 78 QueryEnum.SEARCH_MUTABLE_STATUS_DATA_QUERY, 79 ColumnEnum.ENTRY_ID, 80 pageOwner.getEntryId("SearchStaticWithMutableStatus") 81 ) 82 mutableStatus.checkValue( 83 QueryEnum.SEARCH_MUTABLE_STATUS_DATA_QUERY, 84 ColumnEnum.ENTRY_LABEL, 85 pageOwner.getEntryLabel("SearchStaticWithMutableStatus") 86 ) 87 mutableStatus.checkValue( 88 QueryEnum.SEARCH_MUTABLE_STATUS_DATA_QUERY, ColumnEnum.ENTRY_DISABLED, false.toString() 89 ) 90 91 mutableStatus.moveToNext() 92 mutableStatus.checkValue( 93 QueryEnum.SEARCH_MUTABLE_STATUS_DATA_QUERY, 94 ColumnEnum.ENTRY_ID, 95 pageOwner.getEntryId("SearchDynamicWithMutableStatus") 96 ) 97 mutableStatus.checkValue( 98 QueryEnum.SEARCH_MUTABLE_STATUS_DATA_QUERY, 99 ColumnEnum.ENTRY_LABEL, 100 pageOwner.getEntryLabel("SearchDynamicWithMutableStatus") 101 ) 102 mutableStatus.checkValue( 103 QueryEnum.SEARCH_MUTABLE_STATUS_DATA_QUERY, ColumnEnum.ENTRY_DISABLED, true.toString() 104 ) 105 } 106 107 @Test 108 fun testQuerySearchIndexData() { 109 SpaEnvironmentFactory.reset(spaEnvironment) 110 111 val staticData = searchProvider.querySearchStaticData() 112 Truth.assertThat(staticData.count).isEqualTo(2) 113 staticData.moveToFirst() 114 staticData.checkValue( 115 QueryEnum.SEARCH_STATIC_DATA_QUERY, 116 ColumnEnum.ENTRY_ID, 117 pageOwner.getEntryId("SearchStaticWithNoStatus") 118 ) 119 staticData.checkValue( 120 QueryEnum.SEARCH_STATIC_DATA_QUERY, 121 ColumnEnum.ENTRY_LABEL, 122 pageOwner.getEntryLabel("SearchStaticWithNoStatus") 123 ) 124 staticData.checkValue( 125 QueryEnum.SEARCH_STATIC_DATA_QUERY, ColumnEnum.SEARCH_TITLE, "SearchStaticWithNoStatus" 126 ) 127 staticData.checkValue( 128 QueryEnum.SEARCH_STATIC_DATA_QUERY, ColumnEnum.SEARCH_KEYWORD, listOf("").toString() 129 ) 130 staticData.checkValue( 131 QueryEnum.SEARCH_STATIC_DATA_QUERY, 132 ColumnEnum.SEARCH_PATH, 133 listOf("SearchStaticWithNoStatus", "SppForSearch").toString() 134 ) 135 staticData.checkValue( 136 QueryEnum.SEARCH_STATIC_DATA_QUERY, 137 ColumnEnum.INTENT_TARGET_PACKAGE, 138 spaEnvironment.appContext.packageName 139 ) 140 staticData.checkValue( 141 QueryEnum.SEARCH_STATIC_DATA_QUERY, 142 ColumnEnum.INTENT_TARGET_CLASS, 143 "com.android.settingslib.spa.tests.testutils.BlankActivity" 144 ) 145 146 // Check extras in intent 147 val bundle = 148 staticData.getExtras(QueryEnum.SEARCH_STATIC_DATA_QUERY, ColumnEnum.INTENT_EXTRAS) 149 Truth.assertThat(bundle).isNotNull() 150 Truth.assertThat(bundle!!.size()).isEqualTo(3) 151 Truth.assertThat(bundle.getString("spaActivityDestination")).isEqualTo("SppForSearch") 152 Truth.assertThat(bundle.getString("highlightEntry")) 153 .isEqualTo(pageOwner.getEntryId("SearchStaticWithNoStatus")) 154 Truth.assertThat(bundle.getString("sessionSource")).isEqualTo("search") 155 156 staticData.moveToNext() 157 staticData.checkValue( 158 QueryEnum.SEARCH_STATIC_DATA_QUERY, 159 ColumnEnum.ENTRY_ID, 160 pageOwner.getEntryId("SearchStaticWithMutableStatus") 161 ) 162 staticData.checkValue( 163 QueryEnum.SEARCH_STATIC_DATA_QUERY, 164 ColumnEnum.ENTRY_LABEL, 165 pageOwner.getEntryLabel("SearchStaticWithMutableStatus") 166 ) 167 168 val dynamicData = searchProvider.querySearchDynamicData() 169 Truth.assertThat(dynamicData.count).isEqualTo(2) 170 dynamicData.moveToFirst() 171 dynamicData.checkValue( 172 QueryEnum.SEARCH_DYNAMIC_DATA_QUERY, 173 ColumnEnum.ENTRY_ID, 174 pageOwner.getEntryId("SearchDynamicWithMutableStatus") 175 ) 176 dynamicData.checkValue( 177 QueryEnum.SEARCH_DYNAMIC_DATA_QUERY, 178 ColumnEnum.ENTRY_LABEL, 179 pageOwner.getEntryLabel("SearchDynamicWithMutableStatus") 180 ) 181 182 dynamicData.moveToNext() 183 dynamicData.checkValue( 184 QueryEnum.SEARCH_DYNAMIC_DATA_QUERY, 185 ColumnEnum.ENTRY_ID, 186 pageOwner.getEntryId("SearchDynamicWithImmutableStatus") 187 ) 188 dynamicData.checkValue( 189 QueryEnum.SEARCH_DYNAMIC_DATA_QUERY, 190 ColumnEnum.ENTRY_LABEL, 191 pageOwner.getEntryLabel("SearchDynamicWithImmutableStatus") 192 ) 193 dynamicData.checkValue( 194 QueryEnum.SEARCH_DYNAMIC_DATA_QUERY, 195 ColumnEnum.SEARCH_KEYWORD, 196 listOf("kw1", "kw2").toString() 197 ) 198 } 199 200 @Test 201 fun testQuerySearchIndexRow() { 202 SpaEnvironmentFactory.reset(spaEnvironment) 203 204 val staticRow = searchProvider.querySearchStaticRow() 205 Truth.assertThat(staticRow.count).isEqualTo(1) 206 staticRow.moveToFirst() 207 staticRow.checkValue( 208 QueryEnum.SEARCH_STATIC_ROW_QUERY, 209 ColumnEnum.ENTRY_ID, 210 pageOwner.getEntryId("SearchStaticWithNoStatus") 211 ) 212 staticRow.checkValue( 213 QueryEnum.SEARCH_STATIC_ROW_QUERY, 214 ColumnEnum.ENTRY_LABEL, 215 pageOwner.getEntryLabel("SearchStaticWithNoStatus") 216 ) 217 staticRow.checkValue( 218 QueryEnum.SEARCH_STATIC_ROW_QUERY, ColumnEnum.SEARCH_TITLE, "SearchStaticWithNoStatus" 219 ) 220 staticRow.checkValue( 221 QueryEnum.SEARCH_STATIC_ROW_QUERY, ColumnEnum.SEARCH_KEYWORD, listOf("").toString() 222 ) 223 staticRow.checkValue( 224 QueryEnum.SEARCH_STATIC_ROW_QUERY, 225 ColumnEnum.SEARCH_PATH, 226 listOf("SearchStaticWithNoStatus", "SppForSearch").toString() 227 ) 228 staticRow.checkValue( 229 QueryEnum.SEARCH_STATIC_ROW_QUERY, 230 ColumnEnum.INTENT_TARGET_PACKAGE, 231 spaEnvironment.appContext.packageName 232 ) 233 staticRow.checkValue( 234 QueryEnum.SEARCH_STATIC_ROW_QUERY, 235 ColumnEnum.INTENT_TARGET_CLASS, 236 "com.android.settingslib.spa.tests.testutils.BlankActivity" 237 ) 238 239 // Check extras in intent 240 val bundle = 241 staticRow.getExtras(QueryEnum.SEARCH_STATIC_ROW_QUERY, ColumnEnum.INTENT_EXTRAS) 242 Truth.assertThat(bundle).isNotNull() 243 Truth.assertThat(bundle!!.size()).isEqualTo(3) 244 Truth.assertThat(bundle.getString("spaActivityDestination")).isEqualTo("SppForSearch") 245 Truth.assertThat(bundle.getString("highlightEntry")) 246 .isEqualTo(pageOwner.getEntryId("SearchStaticWithNoStatus")) 247 Truth.assertThat(bundle.getString("sessionSource")).isEqualTo("search") 248 249 Truth.assertThat( 250 staticRow.getString( 251 QueryEnum.SEARCH_STATIC_ROW_QUERY.columnNames.indexOf( 252 ColumnEnum.ENTRY_DISABLED 253 ) 254 ) 255 ).isNull() 256 257 val dynamicRow = searchProvider.querySearchDynamicRow() 258 Truth.assertThat(dynamicRow.count).isEqualTo(3) 259 dynamicRow.moveToFirst() 260 dynamicRow.checkValue( 261 QueryEnum.SEARCH_DYNAMIC_ROW_QUERY, 262 ColumnEnum.ENTRY_ID, 263 pageOwner.getEntryId("SearchStaticWithMutableStatus") 264 ) 265 dynamicRow.checkValue( 266 QueryEnum.SEARCH_DYNAMIC_ROW_QUERY, 267 ColumnEnum.ENTRY_LABEL, 268 pageOwner.getEntryLabel("SearchStaticWithMutableStatus") 269 ) 270 dynamicRow.checkValue( 271 QueryEnum.SEARCH_DYNAMIC_ROW_QUERY, ColumnEnum.ENTRY_DISABLED, false.toString() 272 ) 273 274 dynamicRow.moveToNext() 275 dynamicRow.checkValue( 276 QueryEnum.SEARCH_DYNAMIC_ROW_QUERY, 277 ColumnEnum.ENTRY_ID, 278 pageOwner.getEntryId("SearchDynamicWithMutableStatus") 279 ) 280 dynamicRow.checkValue( 281 QueryEnum.SEARCH_DYNAMIC_ROW_QUERY, 282 ColumnEnum.ENTRY_LABEL, 283 pageOwner.getEntryLabel("SearchDynamicWithMutableStatus") 284 ) 285 dynamicRow.checkValue( 286 QueryEnum.SEARCH_DYNAMIC_ROW_QUERY, ColumnEnum.ENTRY_DISABLED, true.toString() 287 ) 288 289 290 dynamicRow.moveToNext() 291 dynamicRow.checkValue( 292 QueryEnum.SEARCH_DYNAMIC_ROW_QUERY, 293 ColumnEnum.ENTRY_ID, 294 pageOwner.getEntryId("SearchDynamicWithImmutableStatus") 295 ) 296 dynamicRow.checkValue( 297 QueryEnum.SEARCH_DYNAMIC_ROW_QUERY, 298 ColumnEnum.ENTRY_LABEL, 299 pageOwner.getEntryLabel("SearchDynamicWithImmutableStatus") 300 ) 301 dynamicRow.checkValue( 302 QueryEnum.SEARCH_DYNAMIC_ROW_QUERY, 303 ColumnEnum.SEARCH_KEYWORD, 304 listOf("kw1", "kw2").toString() 305 ) 306 dynamicRow.checkValue( 307 QueryEnum.SEARCH_DYNAMIC_ROW_QUERY, ColumnEnum.ENTRY_DISABLED, true.toString() 308 ) 309 } 310 } 311 312 private fun Cursor.checkValue(query: QueryEnum, column: ColumnEnum, value: String) { 313 Truth.assertThat(getString(query.columnNames.indexOf(column))).isEqualTo(value) 314 } 315 316 private fun Cursor.getExtras(query: QueryEnum, column: ColumnEnum): Bundle? { 317 val extrasByte = getBlob(query.columnNames.indexOf(column)) ?: return null 318 val parcel = Parcel.obtain() 319 parcel.unmarshall(extrasByte, 0, extrasByte.size) 320 parcel.setDataPosition(0) 321 val bundle = Bundle() 322 bundle.readFromParcel(parcel) 323 return bundle 324 } 325 326 private fun SettingsPage.getEntryId(name: String): String { 327 return SettingsEntryBuilder.create(this, name).build().id 328 } 329 330 private fun SettingsPage.getEntryLabel(name: String): String { 331 return SettingsEntryBuilder.create(this, name).build().label 332 } 333