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
testQueryColumnSetupnull44     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
testQuerySearchStatusDatanull54     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
testQuerySearchIndexDatanull108     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
testQuerySearchIndexRownull201     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 
checkValuenull312 private fun Cursor.checkValue(query: QueryEnum, column: ColumnEnum, value: String) {
313     Truth.assertThat(getString(query.columnNames.indexOf(column))).isEqualTo(value)
314 }
315 
getExtrasnull316 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 
SettingsPagenull326 private fun SettingsPage.getEntryId(name: String): String {
327     return SettingsEntryBuilder.create(this, name).build().id
328 }
329 
SettingsPagenull330 private fun SettingsPage.getEntryLabel(name: String): String {
331     return SettingsEntryBuilder.create(this, name).build().label
332 }
333