Loading src/com/android/settings/spa/app/AllAppList.kt +13 −7 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -57,17 +60,18 @@ object AllAppListPageProvider : SettingsPageProvider { } @Composable private fun AllAppListPage() { fun AllAppListPage( appList: @Composable AppListInput<AppRecordWithSize>.() -> 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)) } } Loading @@ -75,11 +79,13 @@ data class AppRecordWithSize( override val app: ApplicationInfo, ) : AppRecord private class AllAppListModel : AppListModel<AppRecordWithSize> { class AllAppListModel( private val getSummary: @Composable ApplicationInfo.() -> State<String> = { getStorageSize() }, ) : AppListModel<AppRecordWithSize> { override fun transform(userIdFlow: Flow<Int>, appListFlow: Flow<List<ApplicationInfo>>) = appListFlow.mapItem(::AppRecordWithSize) @Composable override fun getSummary(option: Int, record: AppRecordWithSize) = record.app.getStorageSize() override fun getSummary(option: Int, record: AppRecordWithSize) = record.app.getSummary() } tests/spa_unit/src/com/android/settings/spa/app/AllAppListTest.kt 0 → 100644 +180 −0 Original line number Diff line number Diff line /* * 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<String> composeTestRule.setContent { summaryState = listModel.getSummary(option = 0, record = AppRecordWithSize(app = APP)) } assertThat(summaryState.value).isEqualTo(SUMMARY) } private fun getAppListInput(): AppListInput<AppRecordWithSize> { lateinit var input: AppListInput<AppRecordWithSize> 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 } } } tests/spa_unit/src/com/android/settings/spa/app/ResetAppPreferencesTest.kt +0 −2 Original line number Diff line number Diff line Loading @@ -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 Loading tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppLocalePreferenceTest.kt +2 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading
src/com/android/settings/spa/app/AllAppList.kt +13 −7 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -57,17 +60,18 @@ object AllAppListPageProvider : SettingsPageProvider { } @Composable private fun AllAppListPage() { fun AllAppListPage( appList: @Composable AppListInput<AppRecordWithSize>.() -> 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)) } } Loading @@ -75,11 +79,13 @@ data class AppRecordWithSize( override val app: ApplicationInfo, ) : AppRecord private class AllAppListModel : AppListModel<AppRecordWithSize> { class AllAppListModel( private val getSummary: @Composable ApplicationInfo.() -> State<String> = { getStorageSize() }, ) : AppListModel<AppRecordWithSize> { override fun transform(userIdFlow: Flow<Int>, appListFlow: Flow<List<ApplicationInfo>>) = appListFlow.mapItem(::AppRecordWithSize) @Composable override fun getSummary(option: Int, record: AppRecordWithSize) = record.app.getStorageSize() override fun getSummary(option: Int, record: AppRecordWithSize) = record.app.getSummary() }
tests/spa_unit/src/com/android/settings/spa/app/AllAppListTest.kt 0 → 100644 +180 −0 Original line number Diff line number Diff line /* * 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<String> composeTestRule.setContent { summaryState = listModel.getSummary(option = 0, record = AppRecordWithSize(app = APP)) } assertThat(summaryState.value).isEqualTo(SUMMARY) } private fun getAppListInput(): AppListInput<AppRecordWithSize> { lateinit var input: AppListInput<AppRecordWithSize> 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 } } }
tests/spa_unit/src/com/android/settings/spa/app/ResetAppPreferencesTest.kt +0 −2 Original line number Diff line number Diff line Loading @@ -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 Loading
tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppLocalePreferenceTest.kt +2 −1 Original line number Diff line number Diff line Loading @@ -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 Loading