From 07fc7f104403f656a38c8163c452a504509ddd72 Mon Sep 17 00:00:00 2001 From: Chaohui Wang Date: Mon, 5 Dec 2022 20:10:04 +0800 Subject: [PATCH] Add unit test for AllAppList Bug: 260660819 Test: Unit test Change-Id: I15e294d8b90d385e932adc3bf0d61e6923941542 --- .../android/settings/spa/app/AllAppList.kt | 20 +- .../settings/spa/app/AllAppListTest.kt | 180 ++++++++++++++++++ .../spa/app/ResetAppPreferencesTest.kt | 2 - .../app/appinfo/AppLocalePreferenceTest.kt | 3 +- 4 files changed, 195 insertions(+), 10 deletions(-) create mode 100644 tests/spa_unit/src/com/android/settings/spa/app/AllAppListTest.kt diff --git a/src/com/android/settings/spa/app/AllAppList.kt b/src/com/android/settings/spa/app/AllAppList.kt index 75b5cd21963..cd116c17729 100644 --- a/src/com/android/settings/spa/app/AllAppList.kt +++ b/src/com/android/settings/spa/app/AllAppList.kt @@ -19,6 +19,7 @@ package com.android.settings.spa.app import android.content.pm.ApplicationInfo import android.os.Bundle import androidx.compose.runtime.Composable +import androidx.compose.runtime.State import androidx.compose.runtime.remember import androidx.compose.ui.res.stringResource import com.android.settings.R @@ -32,6 +33,8 @@ import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spaprivileged.model.app.AppListModel import com.android.settingslib.spaprivileged.model.app.AppRecord +import com.android.settingslib.spaprivileged.template.app.AppList +import com.android.settingslib.spaprivileged.template.app.AppListInput import com.android.settingslib.spaprivileged.template.app.AppListItem import com.android.settingslib.spaprivileged.template.app.AppListPage import com.android.settingslib.spaprivileged.template.app.getStorageSize @@ -57,17 +60,18 @@ object AllAppListPageProvider : SettingsPageProvider { } @Composable -private fun AllAppListPage() { +fun AllAppListPage( + appList: @Composable AppListInput.() -> Unit = { AppList() }, +) { val resetAppDialogPresenter = rememberResetAppDialogPresenter() AppListPage( title = stringResource(R.string.all_apps), listModel = remember { AllAppListModel() }, showInstantApps = true, - moreOptions = { ResetAppPreferences(resetAppDialogPresenter::open) } + moreOptions = { ResetAppPreferences(resetAppDialogPresenter::open) }, + appList = appList, ) { - AppListItem( - onClick = AppInfoSettingsProvider.navigator(app = record.app), - ) + AppListItem(onClick = AppInfoSettingsProvider.navigator(app = record.app)) } } @@ -75,11 +79,13 @@ data class AppRecordWithSize( override val app: ApplicationInfo, ) : AppRecord -private class AllAppListModel : AppListModel { +class AllAppListModel( + private val getSummary: @Composable ApplicationInfo.() -> State = { getStorageSize() }, +) : AppListModel { override fun transform(userIdFlow: Flow, appListFlow: Flow>) = appListFlow.mapItem(::AppRecordWithSize) @Composable - override fun getSummary(option: Int, record: AppRecordWithSize) = record.app.getStorageSize() + override fun getSummary(option: Int, record: AppRecordWithSize) = record.app.getSummary() } diff --git a/tests/spa_unit/src/com/android/settings/spa/app/AllAppListTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/AllAppListTest.kt new file mode 100644 index 00000000000..1a5f3ab36a6 --- /dev/null +++ b/tests/spa_unit/src/com/android/settings/spa/app/AllAppListTest.kt @@ -0,0 +1,180 @@ +/* + * 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.settings.spa.app + +import android.content.Context +import android.content.pm.ApplicationInfo +import androidx.compose.runtime.SideEffect +import androidx.compose.runtime.State +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.junit4.createComposeRule +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.performClick +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.settings.R +import com.android.settingslib.spa.framework.compose.stateOf +import com.android.settingslib.spa.testutils.FakeNavControllerWrapper +import com.android.settingslib.spa.testutils.firstWithTimeoutOrNull +import com.android.settingslib.spaprivileged.template.app.AppListInput +import com.android.settingslib.spaprivileged.template.app.AppListItemModel +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.test.runTest +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class AllAppListTest { + @get:Rule + val composeTestRule = createComposeRule() + + private val context: Context = ApplicationProvider.getApplicationContext() + + private val fakeNavControllerWrapper = FakeNavControllerWrapper() + + @Test + fun allAppListPageProvider_name() { + assertThat(AllAppListPageProvider.name).isEqualTo("AllAppList") + } + + @Test + fun injectEntry_title() { + setInjectEntry() + + composeTestRule.onNodeWithText(context.getString(R.string.all_apps)).assertIsDisplayed() + } + + @Test + fun injectEntry_onClick_navigate() { + setInjectEntry() + + composeTestRule.onNodeWithText(context.getString(R.string.all_apps)).performClick() + + assertThat(fakeNavControllerWrapper.navigateCalledWith).isEqualTo("AllAppList") + } + + private fun setInjectEntry() { + composeTestRule.setContent { + fakeNavControllerWrapper.Wrapper { + AllAppListPageProvider.buildInjectEntry().build().UiLayout() + } + } + } + + @Test + fun title_displayed() { + composeTestRule.setContent { + AllAppListPage {} + } + + composeTestRule.onNodeWithText(context.getString(R.string.all_apps)).assertIsDisplayed() + } + + @Test + fun showInstantApps_isTrue() { + val input = getAppListInput() + + assertThat(input.config.showInstantApps).isTrue() + } + + @Test + fun item_labelDisplayed() { + setItemContent() + + composeTestRule.onNodeWithText(LABEL).assertIsDisplayed() + } + + @Test + fun item_summaryDisplayed() { + setItemContent() + + composeTestRule.onNodeWithText(SUMMARY).assertIsDisplayed() + } + + @Test + fun item_onClick_navigate() { + setItemContent() + + composeTestRule.onNodeWithText(LABEL).performClick() + + assertThat(fakeNavControllerWrapper.navigateCalledWith) + .isEqualTo("AppInfoSettings/package.name/0") + } + + @OptIn(ExperimentalCoroutinesApi::class) + @Test + fun allAppListModel_transform() = runTest { + val listModel = AllAppListModel { stateOf(SUMMARY) } + + val recordListFlow = listModel.transform(flowOf(USER_ID), flowOf(listOf(APP))) + + val recordList = recordListFlow.firstWithTimeoutOrNull()!! + assertThat(recordList).hasSize(1) + assertThat(recordList[0].app).isSameInstanceAs(APP) + } + + @Test + fun allAppListModel_getSummary() { + val listModel = AllAppListModel { stateOf(SUMMARY) } + + lateinit var summaryState: State + composeTestRule.setContent { + summaryState = listModel.getSummary(option = 0, record = AppRecordWithSize(app = APP)) + } + + assertThat(summaryState.value).isEqualTo(SUMMARY) + } + + private fun getAppListInput(): AppListInput { + lateinit var input: AppListInput + composeTestRule.setContent { + AllAppListPage { + SideEffect { + input = this + } + } + } + return input + } + + private fun setItemContent() { + composeTestRule.setContent { + AllAppListPage { + fakeNavControllerWrapper.Wrapper { + AppListItemModel( + record = AppRecordWithSize(app = APP), + label = LABEL, + summary = stateOf(SUMMARY), + ).appItem() + } + } + } + } + + private companion object { + const val USER_ID = 0 + const val PACKAGE_NAME = "package.name" + const val LABEL = "Label" + const val SUMMARY = "Summary" + val APP = ApplicationInfo().apply { + packageName = PACKAGE_NAME + } + } +} diff --git a/tests/spa_unit/src/com/android/settings/spa/app/ResetAppPreferencesTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/ResetAppPreferencesTest.kt index b144ad6eecf..ffd58313f1b 100644 --- a/tests/spa_unit/src/com/android/settings/spa/app/ResetAppPreferencesTest.kt +++ b/tests/spa_unit/src/com/android/settings/spa/app/ResetAppPreferencesTest.kt @@ -28,14 +28,12 @@ import com.android.settingslib.spa.widget.scaffold.MoreOptionsScope import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.mockito.Spy @RunWith(AndroidJUnit4::class) class ResetAppPreferencesTest { @get:Rule val composeTestRule = createComposeRule() - @Spy private val context: Context = ApplicationProvider.getApplicationContext() @Test diff --git a/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppLocalePreferenceTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppLocalePreferenceTest.kt index 39524df7c16..b4545d46361 100644 --- a/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppLocalePreferenceTest.kt +++ b/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppLocalePreferenceTest.kt @@ -131,10 +131,11 @@ class AppLocalePreferenceTest { AppLocalePreference(APP) } } + composeTestRule.delay() } private companion object { - const val PACKAGE_NAME = "packageName" + const val PACKAGE_NAME = "package.name" const val UID = 123 val APP = ApplicationInfo().apply { packageName = PACKAGE_NAME