From 040f454568a2ff9b8b8cbd7eb3708c26c426f2b1 Mon Sep 17 00:00:00 2001 From: Ida Delphine Date: Fri, 9 Oct 2026 03:31:26 -0700 Subject: [PATCH] add debug settings test --- .../newpipe/settings/ComposeDebugActions.kt | 7 -- .../net/newpipe/app/platform/DebugActions.kt | 3 +- .../app/composable/PreferenceRowTest.kt | 13 +++ .../settings/DebugSettingsScreenTest.kt | 96 +++++++++++++++++++ 4 files changed, 111 insertions(+), 8 deletions(-) create mode 100644 shared/src/commonTest/kotlin/net/newpipe/app/screen/settings/DebugSettingsScreenTest.kt diff --git a/app/src/main/java/org/schabi/newpipe/settings/ComposeDebugActions.kt b/app/src/main/java/org/schabi/newpipe/settings/ComposeDebugActions.kt index 7c415e4ef..14177e67a 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ComposeDebugActions.kt +++ b/app/src/main/java/org/schabi/newpipe/settings/ComposeDebugActions.kt @@ -34,13 +34,6 @@ class ComposeDebugActions(private val context: Context) : DebugActions { private fun dummyErrorInfo() = ErrorInfo(RuntimeException(DUMMY), UserAction.UI_ERROR, DUMMY) - /** - * LeakCanary only ships in debug builds, so it is reached through the build-variant dependent - * bridge the legacy debug settings fragment already defines. - * - * TODO: move [DebugSettingsFragment.DebugSettingsBVDLeakCanaryAPI] out of the fragment when - * the legacy debug settings fragment is deleted. - */ private fun loadLeakCanary(): DebugSettingsFragment.DebugSettingsBVDLeakCanaryAPI? = runCatching { Class.forName(DebugSettingsFragment.DebugSettingsBVDLeakCanaryAPI.IMPL_CLASS) .getDeclaredConstructor() diff --git a/shared/src/commonMain/kotlin/net/newpipe/app/platform/DebugActions.kt b/shared/src/commonMain/kotlin/net/newpipe/app/platform/DebugActions.kt index 8f4e01739..1c3fcec52 100644 --- a/shared/src/commonMain/kotlin/net/newpipe/app/platform/DebugActions.kt +++ b/shared/src/commonMain/kotlin/net/newpipe/app/platform/DebugActions.kt @@ -43,5 +43,6 @@ internal object NoOpDebugActions : DebugActions { override fun reportDummyError() = logUnsupported("reportDummyError") - private fun logUnsupported(action: String) = Logger.w(messageString = "Debug action '$action' is unsupported on this platform") + private fun logUnsupported(action: String) = + Logger.w(messageString = "Debug action '$action' is unsupported on this platform") } diff --git a/shared/src/commonTest/kotlin/net/newpipe/app/composable/PreferenceRowTest.kt b/shared/src/commonTest/kotlin/net/newpipe/app/composable/PreferenceRowTest.kt index 0746d7ad6..930545fe9 100644 --- a/shared/src/commonTest/kotlin/net/newpipe/app/composable/PreferenceRowTest.kt +++ b/shared/src/commonTest/kotlin/net/newpipe/app/composable/PreferenceRowTest.kt @@ -11,6 +11,7 @@ import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.compose.ui.test.v2.runComposeUiTest import kotlin.test.Test +import kotlin.test.assertFalse import kotlin.test.assertTrue @OptIn(ExperimentalTestApi::class) @@ -45,4 +46,16 @@ class PreferenceRowTest { onNodeWithText(title).assertIsDisplayed() onNodeWithText(summary).assertIsDisplayed() } + + @Test + fun disabledRowDoesNotFire() = runComposeUiTest { + val title = "Test title" + var fired = false + setContent { + PreferenceRow(title = title, enabled = false, onClick = { fired = true }) + } + + onNodeWithText(title).performClick() + assertFalse(fired) + } } diff --git a/shared/src/commonTest/kotlin/net/newpipe/app/screen/settings/DebugSettingsScreenTest.kt b/shared/src/commonTest/kotlin/net/newpipe/app/screen/settings/DebugSettingsScreenTest.kt new file mode 100644 index 000000000..5cf313f79 --- /dev/null +++ b/shared/src/commonTest/kotlin/net/newpipe/app/screen/settings/DebugSettingsScreenTest.kt @@ -0,0 +1,96 @@ +/* + * SPDX-FileCopyrightText: 2026 NewPipe e.V. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package net.newpipe.app.screen.settings + +import androidx.compose.ui.test.ExperimentalTestApi +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.performClick +import androidx.compose.ui.test.performScrollTo +import androidx.compose.ui.test.v2.runComposeUiTest +import com.russhwolf.settings.MapSettings +import com.russhwolf.settings.Settings +import kotlin.test.Test +import kotlin.test.assertFalse +import kotlin.test.assertTrue +import net.newpipe.app.extensions.withKoin +import newpipe.shared.generated.resources.Res +import newpipe.shared.generated.resources.check_new_streams +import newpipe.shared.generated.resources.enable_leak_canary_summary +import newpipe.shared.generated.resources.leak_canary_not_available +import newpipe.shared.generated.resources.leakcanary +import newpipe.shared.generated.resources.settings_category_debug_title +import newpipe.shared.generated.resources.show_memory_leaks +import org.jetbrains.compose.resources.getString +import org.koin.dsl.module + +@OptIn(ExperimentalTestApi::class) +class DebugSettingsScreenTest { + + private val emptySettings = module { + single { MapSettings() } + } + + @Test + fun rendersTitleAndLeakCanaryRow() = runComposeUiTest { + withKoin( + modules = listOf(emptySettings), + content = { DebugSettingsScreenContent() }, + onContent = { + onNodeWithText(getString(Res.string.settings_category_debug_title)) + .assertIsDisplayed() + onNodeWithText(getString(Res.string.leakcanary)).assertIsDisplayed() + } + ) + } + + @Test + fun leakCanaryRowsExplainWhyTheyAreDisabled() = runComposeUiTest { + withKoin( + modules = listOf(emptySettings), + content = { DebugSettingsScreenContent(leakCanaryAvailable = false) }, + onContent = { + onNodeWithText(getString(Res.string.leak_canary_not_available)) + .assertIsDisplayed() + onNodeWithText(getString(Res.string.enable_leak_canary_summary)) + .assertDoesNotExist() + } + ) + } + + @Test + fun memoryLeaksRowDoesNotFireWhenLeakCanaryIsMissing() = runComposeUiTest { + var clicked = false + withKoin( + modules = listOf(emptySettings), + content = { + DebugSettingsScreenContent( + leakCanaryAvailable = false, + onShowMemoryLeaks = { clicked = true } + ) + }, + onContent = { + onNodeWithText(getString(Res.string.show_memory_leaks)).performClick() + assertFalse(clicked) + } + ) + } + + @Test + fun checkNewStreamsRowFiresItsAction() = runComposeUiTest { + var clicked = false + withKoin( + modules = listOf(emptySettings), + content = { DebugSettingsScreenContent(onCheckNewStreams = { clicked = true }) }, + onContent = { + onNodeWithText(getString(Res.string.check_new_streams)) + .performScrollTo() + .performClick() + assertTrue(clicked) + } + ) + } +}