Make AppListPage testable
Users could now overwrite AppListPage's appList param to replace the
real implementation with fake for testing.
Bug: 260660819
Test: Unit test
Change-Id: Ia25fecf6d98f7ed18de020f855b9cd31a7199217
diff --git a/packages/SettingsLib/Spa/testutils/Android.bp b/packages/SettingsLib/Spa/testutils/Android.bp
index de87dde..2c1e1c2 100644
--- a/packages/SettingsLib/Spa/testutils/Android.bp
+++ b/packages/SettingsLib/Spa/testutils/Android.bp
@@ -24,7 +24,9 @@
srcs: ["src/**/*.kt"],
static_libs: [
+ "SpaLib",
"androidx.arch.core_core-testing",
+ "androidx.compose.runtime_runtime",
"androidx.compose.ui_ui-test-junit4",
"androidx.compose.ui_ui-test-manifest",
"mockito",
diff --git a/packages/SettingsLib/Spa/testutils/build.gradle b/packages/SettingsLib/Spa/testutils/build.gradle
index 81e54c1..e31eb02 100644
--- a/packages/SettingsLib/Spa/testutils/build.gradle
+++ b/packages/SettingsLib/Spa/testutils/build.gradle
@@ -44,9 +44,17 @@
jvmTarget = '1.8'
freeCompilerArgs = ["-Xjvm-default=all"]
}
+ buildFeatures {
+ compose true
+ }
+ composeOptions {
+ kotlinCompilerExtensionVersion jetpack_compose_compiler_version
+ }
}
dependencies {
+ api project(":SpaLib")
+
api "androidx.arch.core:core-testing:2.1.0"
api "androidx.compose.ui:ui-test-junit4:$jetpack_compose_version"
api "com.google.truth:truth:1.1.3"
diff --git a/packages/SettingsLib/Spa/testutils/src/com/android/settingslib/spa/testutils/FakeNavControllerWrapper.kt b/packages/SettingsLib/Spa/testutils/src/com/android/settingslib/spa/testutils/FakeNavControllerWrapper.kt
new file mode 100644
index 0000000..5a3044d
--- /dev/null
+++ b/packages/SettingsLib/Spa/testutils/src/com/android/settingslib/spa/testutils/FakeNavControllerWrapper.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.spa.testutils
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import com.android.settingslib.spa.framework.compose.LocalNavController
+import com.android.settingslib.spa.framework.compose.NavControllerWrapper
+
+class FakeNavControllerWrapper : NavControllerWrapper {
+ var navigateCalledWith: String? = null
+ var navigateBackIsCalled = false
+
+ override fun navigate(route: String) {
+ navigateCalledWith = route
+ }
+
+ override fun navigateBack() {
+ navigateBackIsCalled = true
+ }
+
+ @Composable
+ fun Wrapper(content: @Composable () -> Unit) {
+ CompositionLocalProvider(LocalNavController provides this) {
+ content()
+ }
+ }
+}
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListRepository.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListRepository.kt
index 487dbcb..4c144b2 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListRepository.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListRepository.kt
@@ -29,7 +29,7 @@
/**
* The config used to load the App List.
*/
-internal data class AppListConfig(
+data class AppListConfig(
val userId: Int,
val showInstantApps: Boolean,
)
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppList.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppList.kt
index 15766e1..2e0d853 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppList.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppList.kt
@@ -49,13 +49,13 @@
private const val TAG = "AppList"
private const val CONTENT_TYPE_HEADER = "header"
-internal data class AppListState(
+data class AppListState(
val showSystem: State<Boolean>,
val option: State<Int>,
val searchQuery: State<String>,
)
-internal data class AppListInput<T : AppRecord>(
+data class AppListInput<T : AppRecord>(
val config: AppListConfig,
val listModel: AppListModel<T>,
val state: AppListState,
@@ -70,10 +70,13 @@
* This UI element will take the remaining space on the screen to show the App List.
*/
@Composable
-internal fun <T : AppRecord> AppListInput<T>.AppList(
- appListDataSupplier: @Composable () -> State<AppListData<T>?> = {
- loadAppListData(config, listModel, state)
- },
+fun <T : AppRecord> AppListInput<T>.AppList() {
+ AppListImpl { loadAppListData(config, listModel, state) }
+}
+
+@Composable
+internal fun <T : AppRecord> AppListInput<T>.AppListImpl(
+ appListDataSupplier: @Composable () -> State<AppListData<T>?>,
) {
LogCompositions(TAG, config.userId.toString())
val appListData = appListDataSupplier()
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppListItem.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppListItem.kt
index 28bf832..6d0d7d6 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppListItem.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppListItem.kt
@@ -28,7 +28,7 @@
import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spaprivileged.model.app.AppRecord
-class AppListItemModel<T : AppRecord>(
+data class AppListItemModel<T : AppRecord>(
val record: T,
val label: String,
val summary: State<String>,
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppListPage.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppListPage.kt
index d452c74..cb35fb0 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppListPage.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppListPage.kt
@@ -47,24 +47,9 @@
primaryUserOnly: Boolean = false,
moreOptions: @Composable MoreOptionsScope.() -> Unit = {},
header: @Composable () -> Unit = {},
+ appList: @Composable AppListInput<T>.() -> Unit = { AppList() },
appItem: @Composable AppListItemModel<T>.() -> Unit,
) {
- AppListPageImpl(
- title, listModel, showInstantApps, primaryUserOnly, moreOptions, header, appItem,
- ) { it.AppList() }
-}
-
-@Composable
-internal fun <T : AppRecord> AppListPageImpl(
- title: String,
- listModel: AppListModel<T>,
- showInstantApps: Boolean = false,
- primaryUserOnly: Boolean = false,
- moreOptions: @Composable MoreOptionsScope.() -> Unit = {},
- header: @Composable () -> Unit = {},
- appItem: @Composable AppListItemModel<T>.() -> Unit,
- appList: @Composable (input: AppListInput<T>) -> Unit,
-) {
val showSystem = rememberSaveable { mutableStateOf(false) }
SearchScaffold(
title = title,
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListPageTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListPageTest.kt
index 946dc2a..f2267f6 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListPageTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListPageTest.kt
@@ -118,12 +118,12 @@
): State<AppListInput<TestAppRecord>?> {
val appListState = mutableStateOf<AppListInput<TestAppRecord>?>(null)
composeTestRule.setContent {
- AppListPageImpl(
+ AppListPage(
title = TITLE,
listModel = TestAppListModel(options),
header = header,
appItem = { AppListItem {} },
- appList = { appListState.value = it },
+ appList = { appListState.value = this },
)
}
return appListState
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListTest.kt
index 945bd51..2677669 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListTest.kt
@@ -102,7 +102,7 @@
appItem = { AppListItem {} },
bottomPadding = 0.dp,
)
- appListInput.AppList { stateOf(AppListData(appEntries, option = 0)) }
+ appListInput.AppListImpl { stateOf(AppListData(appEntries, option = 0)) }
}
}