diff options
9 files changed, 701 insertions, 11 deletions
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntryRepository.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntryRepository.kt index e63e4c9d231e..14b1629e501c 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntryRepository.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntryRepository.kt @@ -30,10 +30,14 @@ data class SettingsPageWithEntry( val injectEntry: SettingsEntry, ) +private fun SettingsPage.getTitle(sppRepository: SettingsPageProviderRepository): String { + return sppRepository.getProviderOrNull(sppName)!!.getTitle(arguments) +} + /** * The repository to maintain all Settings entries */ -class SettingsEntryRepository(sppRepository: SettingsPageProviderRepository) { +class SettingsEntryRepository(private val sppRepository: SettingsPageProviderRepository) { // Map of entry unique Id to entry private val entryMap: Map<String, SettingsEntry> @@ -118,8 +122,9 @@ class SettingsEntryRepository(sppRepository: SettingsPageProviderRepository) { return entryPath.map { if (it.toPage == null) defaultTitle - else - it.toPage.getTitle()!! + else { + it.toPage.getTitle(sppRepository) + } } } } diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPage.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPage.kt index 2fa9229415c8..bb287d1b927a 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPage.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPage.kt @@ -95,11 +95,6 @@ data class SettingsPage( return false } - fun getTitle(): String? { - val sppRepository by SpaEnvironmentFactory.instance.pageProviderRepository - return sppRepository.getProviderOrNull(sppName)?.getTitle(arguments) - } - fun enterPage() { SpaEnvironmentFactory.instance.logger.event( id, diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsEntryRepositoryTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsEntryRepositoryTest.kt new file mode 100644 index 000000000000..9419161fe48d --- /dev/null +++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsEntryRepositoryTest.kt @@ -0,0 +1,146 @@ +/* + * 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.framework.common + +import android.content.Context +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.google.common.truth.Truth.assertThat +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class SettingsEntryRepositoryTest { + private val context: Context = ApplicationProvider.getApplicationContext() + private val spaEnvironment = SpaEnvironmentForTest(context) + private val entryRepository by spaEnvironment.entryRepository + + @Test + fun testGetPageWithEntry() { + val pageWithEntry = entryRepository.getAllPageWithEntry() + assertThat(pageWithEntry.size).isEqualTo(3) + assertThat( + entryRepository.getPageWithEntry(getUniquePageId("SppHome")) + ?.entries?.size + ).isEqualTo(1) + assertThat( + entryRepository.getPageWithEntry(getUniquePageId("SppLayer1")) + ?.entries?.size + ).isEqualTo(3) + assertThat( + entryRepository.getPageWithEntry(getUniquePageId("SppLayer2")) + ?.entries?.size + ).isEqualTo(2) + assertThat(entryRepository.getPageWithEntry(getUniquePageId("SppWithParam"))).isNull() + } + + @Test + fun testGetEntry() { + val entry = entryRepository.getAllEntries() + assertThat(entry.size).isEqualTo(7) + assertThat( + entryRepository.getEntry( + getUniqueEntryId( + "ROOT", + SppHome.createSettingsPage(), + SettingsPage.createNull(), + SppHome.createSettingsPage(), + ) + ) + ).isNotNull() + assertThat( + entryRepository.getEntry( + getUniqueEntryId( + "INJECT", + SppLayer1.createSettingsPage(), + SppHome.createSettingsPage(), + SppLayer1.createSettingsPage(), + ) + ) + ).isNotNull() + assertThat( + entryRepository.getEntry( + getUniqueEntryId( + "INJECT", + SppLayer2.createSettingsPage(), + SppLayer1.createSettingsPage(), + SppLayer2.createSettingsPage(), + ) + ) + ).isNotNull() + assertThat( + entryRepository.getEntry( + getUniqueEntryId("Layer1Entry1", SppLayer1.createSettingsPage()) + ) + ).isNotNull() + assertThat( + entryRepository.getEntry( + getUniqueEntryId("Layer1Entry2", SppLayer1.createSettingsPage()) + ) + ).isNotNull() + assertThat( + entryRepository.getEntry( + getUniqueEntryId("Layer2Entry1", SppLayer2.createSettingsPage()) + ) + ).isNotNull() + assertThat( + entryRepository.getEntry( + getUniqueEntryId("Layer2Entry2", SppLayer2.createSettingsPage()) + ) + ).isNotNull() + } + + @Test + fun testGetEntryPath() { + assertThat( + entryRepository.getEntryPathWithDisplayName( + getUniqueEntryId("Layer2Entry1", SppLayer2.createSettingsPage()) + ) + ).containsExactly("Layer2Entry1", "INJECT_SppLayer2", "INJECT_SppLayer1", "ROOT_SppHome") + .inOrder() + + assertThat( + entryRepository.getEntryPathWithTitle( + getUniqueEntryId("Layer2Entry2", SppLayer2.createSettingsPage()), + "entryTitle" + ) + ).containsExactly("entryTitle", "SppLayer2", "TitleLayer1", "TitleHome").inOrder() + + assertThat( + entryRepository.getEntryPathWithDisplayName( + getUniqueEntryId( + "INJECT", + SppLayer1.createSettingsPage(), + SppHome.createSettingsPage(), + SppLayer1.createSettingsPage(), + ) + ) + ).containsExactly("INJECT_SppLayer1", "ROOT_SppHome").inOrder() + + assertThat( + entryRepository.getEntryPathWithTitle( + getUniqueEntryId( + "INJECT", + SppLayer2.createSettingsPage(), + SppLayer1.createSettingsPage(), + SppLayer2.createSettingsPage(), + ), + "defaultTitle" + ) + ).containsExactly("SppLayer2", "TitleLayer1", "TitleHome").inOrder() + } +} diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsEntryTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsEntryTest.kt new file mode 100644 index 000000000000..31d2ae46fad7 --- /dev/null +++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsEntryTest.kt @@ -0,0 +1,160 @@ +/* + * 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.framework.common + +import androidx.compose.runtime.Composable +import androidx.compose.ui.test.junit4.createComposeRule +import androidx.core.os.bundleOf +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.google.common.truth.Truth.assertThat +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +const val INJECT_ENTRY_NAME = "INJECT" +const val ROOT_ENTRY_NAME = "ROOT" + +class MacroForTest(private val pageId: String, private val entryId: String) : EntryMacro { + @Composable + override fun UiLayout() { + val entryData = LocalEntryDataProvider.current + assertThat(entryData.isHighlighted).isFalse() + assertThat(entryData.pageId).isEqualTo(pageId) + assertThat(entryData.entryId).isEqualTo(entryId) + } + + override fun getSearchData(): EntrySearchData { + return EntrySearchData("myTitle") + } + + override fun getStatusData(): EntryStatusData { + return EntryStatusData(isDisabled = true, isSwitchOff = true) + } +} + +@RunWith(AndroidJUnit4::class) +class SettingsEntryTest { + @get:Rule + val composeTestRule = createComposeRule() + + @Test + fun testBuildBasic() { + val owner = SettingsPage.create("mySpp") + val entry = SettingsEntryBuilder.create(owner, "myEntry").build() + assertThat(entry.id).isEqualTo(getUniqueEntryId("myEntry", owner)) + assertThat(entry.displayName).isEqualTo("myEntry") + assertThat(entry.owner.sppName).isEqualTo("mySpp") + assertThat(entry.owner.displayName).isEqualTo("mySpp") + assertThat(entry.fromPage).isNull() + assertThat(entry.toPage).isNull() + assertThat(entry.isAllowSearch).isFalse() + assertThat(entry.isSearchDataDynamic).isFalse() + assertThat(entry.mutableStatus).isFalse() + } + + @Test + fun testBuildWithLink() { + val owner = SettingsPage.create("mySpp") + val fromPage = SettingsPage.create("fromSpp") + val toPage = SettingsPage.create("toSpp") + val entryFrom = SettingsEntryBuilder.createLinkFrom("myEntry", owner) + .setLink(toPage = toPage).build() + assertThat(entryFrom.id).isEqualTo(getUniqueEntryId("myEntry", owner, owner, toPage)) + assertThat(entryFrom.displayName).isEqualTo("myEntry") + assertThat(entryFrom.fromPage!!.sppName).isEqualTo("mySpp") + assertThat(entryFrom.toPage!!.sppName).isEqualTo("toSpp") + + val entryTo = SettingsEntryBuilder.createLinkTo("myEntry", owner) + .setLink(fromPage = fromPage).build() + assertThat(entryTo.id).isEqualTo(getUniqueEntryId("myEntry", owner, fromPage, owner)) + assertThat(entryTo.displayName).isEqualTo("myEntry") + assertThat(entryTo.fromPage!!.sppName).isEqualTo("fromSpp") + assertThat(entryTo.toPage!!.sppName).isEqualTo("mySpp") + } + + @Test + fun testBuildInject() { + val owner = SettingsPage.create("mySpp") + val entryInject = SettingsEntryBuilder.createInject(owner).build() + assertThat(entryInject.id).isEqualTo( + getUniqueEntryId( + INJECT_ENTRY_NAME, + owner, + toPage = owner + ) + ) + assertThat(entryInject.displayName).isEqualTo("${INJECT_ENTRY_NAME}_mySpp") + assertThat(entryInject.fromPage).isNull() + assertThat(entryInject.toPage).isNotNull() + } + + @Test + fun testBuildRoot() { + val owner = SettingsPage.create("mySpp") + val entryInject = SettingsEntryBuilder.createRoot(owner, "myRootEntry").build() + assertThat(entryInject.id).isEqualTo( + getUniqueEntryId( + ROOT_ENTRY_NAME, + owner, + toPage = owner + ) + ) + assertThat(entryInject.displayName).isEqualTo("myRootEntry") + assertThat(entryInject.fromPage).isNull() + assertThat(entryInject.toPage).isNotNull() + } + + @Test + fun testSetAttributes() { + val owner = SettingsPage.create("mySpp") + val entry = SettingsEntryBuilder.create(owner, "myEntry") + .setDisplayName("myEntryDisplay") + .setIsAllowSearch(true) + .setIsSearchDataDynamic(false) + .setHasMutableStatus(true) + .build() + assertThat(entry.id).isEqualTo(getUniqueEntryId("myEntry", owner)) + assertThat(entry.displayName).isEqualTo("myEntryDisplay") + assertThat(entry.fromPage).isNull() + assertThat(entry.toPage).isNull() + assertThat(entry.isAllowSearch).isTrue() + assertThat(entry.isSearchDataDynamic).isFalse() + assertThat(entry.mutableStatus).isTrue() + } + + @Test + fun testSetMarco() { + val owner = SettingsPage.create("mySpp", arguments = bundleOf("param" to "v1")) + val entry = SettingsEntryBuilder.create(owner, "myEntry") + .setMacro { + assertThat(it?.getString("param")).isEqualTo("v1") + assertThat(it?.getString("rtParam")).isEqualTo("v2") + assertThat(it?.getString("unknown")).isNull() + MacroForTest(getUniquePageId("mySpp"), getUniqueEntryId("myEntry", owner)) + } + .build() + + val rtArguments = bundleOf("rtParam" to "v2") + composeTestRule.setContent { entry.UiLayout(rtArguments) } + val searchData = entry.getSearchData(rtArguments) + val statusData = entry.getStatusData(rtArguments) + assertThat(searchData?.title).isEqualTo("myTitle") + assertThat(searchData?.keyword).isEmpty() + assertThat(statusData?.isDisabled).isTrue() + assertThat(statusData?.isSwitchOff).isTrue() + } +} diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsPageProviderRepositoryTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsPageProviderRepositoryTest.kt new file mode 100644 index 000000000000..6c0c652f5416 --- /dev/null +++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsPageProviderRepositoryTest.kt @@ -0,0 +1,62 @@ +/* + * 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.framework.common + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.google.common.truth.Truth.assertThat +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class SettingsPageProviderRepositoryTest { + @Test + fun getStartPageTest() { + val sppRepoEmpty = SettingsPageProviderRepository(emptyList(), emptyList()) + assertThat(sppRepoEmpty.getDefaultStartPage()).isEqualTo("") + assertThat(sppRepoEmpty.getAllRootPages()).isEmpty() + + val sppRepoNull = + SettingsPageProviderRepository(emptyList(), listOf(SettingsPage.createNull())) + assertThat(sppRepoNull.getDefaultStartPage()).isEqualTo("NULL") + assertThat(sppRepoNull.getAllRootPages()).contains(SettingsPage.createNull()) + + val rootPage1 = SettingsPage.create(name = "Spp1", displayName = "Spp1") + val rootPage2 = SettingsPage.create(name = "Spp2", displayName = "Spp2") + val sppRepo = SettingsPageProviderRepository(emptyList(), listOf(rootPage1, rootPage2)) + val allRoots = sppRepo.getAllRootPages() + assertThat(sppRepo.getDefaultStartPage()).isEqualTo("Spp1") + assertThat(allRoots.size).isEqualTo(2) + assertThat(allRoots).contains(rootPage1) + assertThat(allRoots).contains(rootPage2) + } + + @Test + fun getProviderTest() { + val sppRepoEmpty = SettingsPageProviderRepository(emptyList(), emptyList()) + assertThat(sppRepoEmpty.getAllProviders()).isEmpty() + assertThat(sppRepoEmpty.getProviderOrNull("Spp")).isNull() + + val sppRepo = SettingsPageProviderRepository(listOf( + object : SettingsPageProvider { + override val name = "Spp" + } + ), emptyList()) + assertThat(sppRepo.getAllProviders().size).isEqualTo(1) + assertThat(sppRepo.getProviderOrNull("Spp")).isNotNull() + assertThat(sppRepo.getProviderOrNull("SppUnknown")).isNull() + } +} diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsPageTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsPageTest.kt new file mode 100644 index 000000000000..539e56b1e134 --- /dev/null +++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsPageTest.kt @@ -0,0 +1,126 @@ +/* + * 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.framework.common + +import android.content.Context +import androidx.core.os.bundleOf +import androidx.navigation.NavType +import androidx.navigation.navArgument +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.google.common.truth.Truth.assertThat +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class SettingsPageTest { + private val context: Context = ApplicationProvider.getApplicationContext() + private val spaLogger = SpaLoggerForTest() + private val spaEnvironment = SpaEnvironmentForTest(context, logger = spaLogger) + + @Test + fun testNullPage() { + val page = SettingsPage.createNull() + assertThat(page.id).isEqualTo(getUniquePageId("NULL")) + assertThat(page.sppName).isEqualTo("NULL") + assertThat(page.displayName).isEqualTo("NULL") + assertThat(page.buildRoute()).isEqualTo("NULL") + assertThat(page.isCreateBy("NULL")).isTrue() + assertThat(page.isCreateBy("Spp")).isFalse() + assertThat(page.hasRuntimeParam()).isFalse() + assertThat(page.isBrowsable(context, MockActivity::class.java)).isFalse() + assertThat(page.createBrowseIntent(context, MockActivity::class.java)).isNull() + assertThat(page.createBrowseAdbCommand(context, MockActivity::class.java)).isNull() + } + + @Test + fun testRegularPage() { + val page = SettingsPage.create("mySpp", "SppDisplayName") + assertThat(page.id).isEqualTo(getUniquePageId("mySpp")) + assertThat(page.sppName).isEqualTo("mySpp") + assertThat(page.displayName).isEqualTo("SppDisplayName") + assertThat(page.buildRoute()).isEqualTo("mySpp") + assertThat(page.isCreateBy("NULL")).isFalse() + assertThat(page.isCreateBy("mySpp")).isTrue() + assertThat(page.hasRuntimeParam()).isFalse() + assertThat(page.isBrowsable(context, MockActivity::class.java)).isTrue() + assertThat(page.createBrowseIntent(context, MockActivity::class.java)).isNotNull() + assertThat(page.createBrowseAdbCommand(context, MockActivity::class.java)).contains( + "-e spaActivityDestination mySpp" + ) + } + + @Test + fun testParamPage() { + val arguments = bundleOf( + "string_param" to "myStr", + "int_param" to 10, + ) + val page = spaEnvironment.createPage("SppWithParam", arguments) + assertThat(page.id).isEqualTo(getUniquePageId("SppWithParam", listOf( + navArgument("string_param") { type = NavType.StringType }, + navArgument("int_param") { type = NavType.IntType }, + ), arguments)) + assertThat(page.sppName).isEqualTo("SppWithParam") + assertThat(page.displayName).isEqualTo("SppWithParam") + assertThat(page.buildRoute()).isEqualTo("SppWithParam/myStr/10") + assertThat(page.isCreateBy("SppWithParam")).isTrue() + assertThat(page.hasRuntimeParam()).isFalse() + assertThat(page.isBrowsable(context, MockActivity::class.java)).isTrue() + assertThat(page.createBrowseIntent(context, MockActivity::class.java)).isNotNull() + assertThat(page.createBrowseAdbCommand(context, MockActivity::class.java)).contains( + "-e spaActivityDestination SppWithParam/myStr/10" + ) + } + + @Test + fun testRtParamPage() { + val arguments = bundleOf( + "string_param" to "myStr", + "int_param" to 10, + "rt_param" to "rtStr", + ) + val page = spaEnvironment.createPage("SppWithRtParam", arguments) + assertThat(page.id).isEqualTo(getUniquePageId("SppWithRtParam", listOf( + navArgument("string_param") { type = NavType.StringType }, + navArgument("int_param") { type = NavType.IntType }, + navArgument("rt_param") { type = NavType.StringType }, + ), arguments)) + assertThat(page.sppName).isEqualTo("SppWithRtParam") + assertThat(page.displayName).isEqualTo("SppWithRtParam") + assertThat(page.buildRoute()).isEqualTo("SppWithRtParam/myStr/10/rtStr") + assertThat(page.isCreateBy("SppWithRtParam")).isTrue() + assertThat(page.hasRuntimeParam()).isTrue() + assertThat(page.isBrowsable(context, MockActivity::class.java)).isFalse() + assertThat(page.createBrowseIntent(context, MockActivity::class.java)).isNull() + assertThat(page.createBrowseAdbCommand(context, MockActivity::class.java)).isNull() + } + + @Test + fun testPageEvent() { + spaLogger.reset() + SpaEnvironmentFactory.reset(spaEnvironment) + val page = spaEnvironment.createPage("SppHome") + page.enterPage() + page.leavePage() + page.enterPage() + assertThat(spaLogger.getEventCount(page.id, LogEvent.PAGE_ENTER, LogCategory.FRAMEWORK)) + .isEqualTo(2) + assertThat(spaLogger.getEventCount(page.id, LogEvent.PAGE_LEAVE, LogCategory.FRAMEWORK)) + .isEqualTo(1) + } +} diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SpaEnvironmentForTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SpaEnvironmentForTest.kt new file mode 100644 index 000000000000..b8731a3019f8 --- /dev/null +++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SpaEnvironmentForTest.kt @@ -0,0 +1,147 @@ +/* + * 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.framework.common + +import android.app.Activity +import android.content.Context +import android.os.Bundle +import androidx.navigation.NavType +import androidx.navigation.navArgument +import com.android.settingslib.spa.framework.BrowseActivity + +class SpaLoggerForTest : SpaLogger { + data class MsgCountKey(val msg: String, val category: LogCategory) + data class EventCountKey(val id: String, val event: LogEvent, val category: LogCategory) + + private val messageCount: MutableMap<MsgCountKey, Int> = mutableMapOf() + private val eventCount: MutableMap<EventCountKey, Int> = mutableMapOf() + + override fun message(tag: String, msg: String, category: LogCategory) { + val key = MsgCountKey("[$tag]$msg", category) + messageCount[key] = messageCount.getOrDefault(key, 0) + 1 + } + + override fun event(id: String, event: LogEvent, category: LogCategory, details: String?) { + val key = EventCountKey(id, event, category) + eventCount[key] = eventCount.getOrDefault(key, 0) + 1 + } + + fun getMessageCount(tag: String, msg: String, category: LogCategory): Int { + val key = MsgCountKey("[$tag]$msg", category) + return messageCount.getOrDefault(key, 0) + } + + fun getEventCount(id: String, event: LogEvent, category: LogCategory): Int { + val key = EventCountKey(id, event, category) + return eventCount.getOrDefault(key, 0) + } + + fun reset() { + messageCount.clear() + eventCount.clear() + } +} + +class MockActivity : BrowseActivity() + +object SppHome : SettingsPageProvider { + override val name = "SppHome" + + override fun getTitle(arguments: Bundle?): String { + return "TitleHome" + } + + override fun buildEntry(arguments: Bundle?): List<SettingsEntry> { + val owner = this.createSettingsPage() + return listOf( + SppLayer1.buildInject().setLink(fromPage = owner).build(), + ) + } +} + +object SppLayer1 : SettingsPageProvider { + override val name = "SppLayer1" + + override fun getTitle(arguments: Bundle?): String { + return "TitleLayer1" + } + + fun buildInject(): SettingsEntryBuilder { + return SettingsEntryBuilder.createInject(this.createSettingsPage()) + } + + override fun buildEntry(arguments: Bundle?): List<SettingsEntry> { + val owner = this.createSettingsPage() + return listOf( + SettingsEntryBuilder.create(owner, "Layer1Entry1").build(), + SppLayer2.buildInject().setLink(fromPage = owner).build(), + SettingsEntryBuilder.create(owner, "Layer1Entry2").build(), + ) + } +} + +object SppLayer2 : SettingsPageProvider { + override val name = "SppLayer2" + + fun buildInject(): SettingsEntryBuilder { + return SettingsEntryBuilder.createInject(this.createSettingsPage()) + } + + override fun buildEntry(arguments: Bundle?): List<SettingsEntry> { + val owner = this.createSettingsPage() + return listOf( + SettingsEntryBuilder.create(owner, "Layer2Entry1").build(), + SettingsEntryBuilder.create(owner, "Layer2Entry2").build(), + ) + } +} + +class SpaEnvironmentForTest( + context: Context, + override val browseActivityClass: Class<out Activity>? = MockActivity::class.java, + override val logger: SpaLogger = SpaLoggerForTest() +) : SpaEnvironment(context) { + + override val pageProviderRepository = lazy { + SettingsPageProviderRepository( + listOf( + SppHome, SppLayer1, SppLayer2, + object : SettingsPageProvider { + override val name = "SppWithParam" + override val parameter = listOf( + navArgument("string_param") { type = NavType.StringType }, + navArgument("int_param") { type = NavType.IntType }, + ) + }, + object : SettingsPageProvider { + override val name = "SppWithRtParam" + override val parameter = listOf( + navArgument("string_param") { type = NavType.StringType }, + navArgument("int_param") { type = NavType.IntType }, + navArgument("rt_param") { type = NavType.StringType }, + ) + }, + ), + listOf(SettingsPage.create("SppHome")) + ) + } + + fun createPage(sppName: String, arguments: Bundle? = null): SettingsPage { + return pageProviderRepository.value + .getProviderOrNull(sppName)!!.createSettingsPage(arguments) + } +} diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/UniqueIdHelper.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/UniqueIdHelper.kt new file mode 100644 index 000000000000..93f9afe16fb6 --- /dev/null +++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/UniqueIdHelper.kt @@ -0,0 +1,46 @@ +/* + * 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.framework.common + +import android.os.Bundle +import androidx.navigation.NamedNavArgument +import com.android.settingslib.spa.framework.util.normalize + +fun getUniquePageId( + name: String, + parameter: List<NamedNavArgument> = emptyList(), + arguments: Bundle? = null +): String { + val normArguments = parameter.normalize(arguments) + return "$name:${normArguments?.toString()}".toHashId() +} + +fun getUniquePageId(page: SettingsPage): String { + return getUniquePageId(page.sppName, page.parameter, page.arguments) +} + +fun getUniqueEntryId( + name: String, + owner: SettingsPage, + fromPage: SettingsPage? = null, + toPage: SettingsPage? = null +): String { + val ownerId = getUniquePageId(owner) + val fromId = if (fromPage == null) "null" else getUniquePageId(fromPage) + val toId = if (toPage == null) "null" else getUniquePageId(toPage) + return "$name:$ownerId($fromId-$toId)".toHashId() +} diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/util/ParameterTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/util/ParameterTest.kt index 21ff08515ee6..48ebd8d8ade8 100644 --- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/util/ParameterTest.kt +++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/util/ParameterTest.kt @@ -20,9 +20,12 @@ import androidx.core.os.bundleOf import androidx.navigation.NamedNavArgument import androidx.navigation.NavType import androidx.navigation.navArgument +import androidx.test.ext.junit.runners.AndroidJUnit4 import com.google.common.truth.Truth.assertThat import org.junit.Test +import org.junit.runner.RunWith +@RunWith(AndroidJUnit4::class) class ParameterTest { @Test fun navRouteTest() { @@ -88,14 +91,14 @@ class ParameterTest { "Bundle[{rt_param=null, unset_string_param=null, unset_int_param=null}]" ) - val setParialParam = navArguments.normalize( + val setPartialParam = navArguments.normalize( bundleOf( "string_param" to "myStr", "rt_param" to "rtStr", ) ) - assertThat(setParialParam).isNotNull() - assertThat(setParialParam.toString()).isEqualTo( + assertThat(setPartialParam).isNotNull() + assertThat(setPartialParam.toString()).isEqualTo( "Bundle[{rt_param=null, string_param=myStr, unset_int_param=null}]" ) |