From 9a4b059a3ad39086e8851acb5b8b84ac1115e94e Mon Sep 17 00:00:00 2001 From: Harry Andreolas Date: Thu, 11 Jul 2024 23:04:25 +0300 Subject: [PATCH] test: add deeplink tests --- .../com/andreolas/movierama/MainActivity.kt | 4 +- .../com/andreolas/movierama/MainViewModel.kt | 31 ++++--- .../com/andreolas/movierama/ui/MovieApp.kt | 2 - .../movierama/main/ui/MainViewModelRobot.kt | 17 +++- .../movierama/main/ui/MainViewModelTest.kt | 80 ++++++++++++++++- .../settings/app/SettingsScreenTest.kt | 29 ++++++ .../divinelink/core/commons/ApiConstants.kt | 1 - .../core/commons/BuildConfigProvider.kt | 11 +++ .../core/commons/util/AppSettingsUtil.kt | 18 ++++ .../extensions/StringExtensionsTest.kt | 26 ++++++ .../kotlin/com/divinelink/core/ui/TestTags.kt | 6 ++ .../settings/app/help/HelpSettingsScreen.kt | 9 +- .../app/links/LinkHandlingSettingsScreen.kt | 74 +++++++-------- .../settings/src/main/res/values/strings.xml | 1 + .../app/help/HelpSettingsScreenTest.kt | 89 +++++++++++++++++++ .../links/LinkHandlingSettingsScreenTest.kt | 37 ++++++++ 16 files changed, 375 insertions(+), 60 deletions(-) create mode 100644 core/commons/src/main/kotlin/com/divinelink/core/commons/BuildConfigProvider.kt create mode 100644 core/commons/src/main/kotlin/com/divinelink/core/commons/util/AppSettingsUtil.kt create mode 100644 core/commons/src/test/kotlin/com/divinelink/core/commons/extensions/StringExtensionsTest.kt create mode 100644 feature/settings/src/test/kotlin/com/divinelink/feature/settings/app/help/HelpSettingsScreenTest.kt create mode 100644 feature/settings/src/test/kotlin/com/divinelink/feature/settings/app/links/LinkHandlingSettingsScreenTest.kt diff --git a/app/src/main/kotlin/com/andreolas/movierama/MainActivity.kt b/app/src/main/kotlin/com/andreolas/movierama/MainActivity.kt index 2d2f26ba..db9a212f 100644 --- a/app/src/main/kotlin/com/andreolas/movierama/MainActivity.kt +++ b/app/src/main/kotlin/com/andreolas/movierama/MainActivity.kt @@ -32,7 +32,7 @@ class MainActivity : ComponentActivity() { setContent { val darkTheme = shouldUseDarkTheme( - uiState = viewModel.viewState.collectAsState().value, + uiState = viewModel.uiState.collectAsState().value, selectedTheme = viewModel.theme.collectAsState().value, ) @@ -42,7 +42,7 @@ class MainActivity : ComponentActivity() { blackBackground = viewModel.blackBackgrounds.collectAsState().value, ) { MovieApp( - uiState = viewModel.viewState.collectAsState().value, + uiState = viewModel.uiState.collectAsState().value, uiEvent = viewModel.uiEvent.collectAsState().value, onConsumeEvent = viewModel::consumeUiEvent, ) diff --git a/app/src/main/kotlin/com/andreolas/movierama/MainViewModel.kt b/app/src/main/kotlin/com/andreolas/movierama/MainViewModel.kt index ef2b5abf..aeb2b7e6 100644 --- a/app/src/main/kotlin/com/andreolas/movierama/MainViewModel.kt +++ b/app/src/main/kotlin/com/andreolas/movierama/MainViewModel.kt @@ -3,6 +3,7 @@ package com.andreolas.movierama import androidx.lifecycle.ViewModel import com.andreolas.movierama.ui.ThemedActivityDelegate import com.divinelink.core.commons.extensions.extractDetailsFromDeepLink +import com.divinelink.core.model.media.MediaType import com.divinelink.feature.details.ui.DetailsNavArguments import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow @@ -14,9 +15,9 @@ class MainViewModel @Inject constructor(themedActivityDelegate: ThemedActivityDe ViewModel(), ThemedActivityDelegate by themedActivityDelegate { - private val _viewState: MutableStateFlow = + private val _uiState: MutableStateFlow = MutableStateFlow(MainUiState.Completed) - val viewState: StateFlow = _viewState + val uiState: StateFlow = _uiState private val _uiEvent: MutableStateFlow = MutableStateFlow(MainUiEvent.None) val uiEvent: StateFlow = _uiEvent @@ -32,15 +33,19 @@ class MainViewModel @Inject constructor(themedActivityDelegate: ThemedActivityDe fun handleDeepLink(url: String?) { val (id, mediaType) = url.extractDetailsFromDeepLink() ?: return - updateUiEvent( - MainUiEvent.NavigateToDetails( - DetailsNavArguments( - id = id, - mediaType = mediaType, - isFavorite = false, + if (MediaType.from(mediaType) != MediaType.UNKNOWN) { + updateUiEvent( + MainUiEvent.NavigateToDetails( + DetailsNavArguments( + id = id, + mediaType = mediaType, + isFavorite = false, + ), ), - ), - ) + ) + } else { + updateUiEvent(MainUiEvent.None) + } } /** @@ -58,14 +63,14 @@ class MainViewModel @Inject constructor(themedActivityDelegate: ThemedActivityDe } private fun setRemoteConfig() { - _viewState.value = MainViewState.Loading + _uiState.value = MainViewState.Loading viewModelScope.launch { val result = setRemoteConfigUseCase.invoke(Unit) if (result.isSuccess) { - _viewState.value = MainViewState.Completed + _uiState.value = MainViewState.Completed } else { - _viewState.value = MainViewState.Error( + _uiState.value = MainViewState.Error( UIText.StringText("Something went wrong. Trying again..."), ) } diff --git a/app/src/main/kotlin/com/andreolas/movierama/ui/MovieApp.kt b/app/src/main/kotlin/com/andreolas/movierama/ui/MovieApp.kt index a36716ba..166d7118 100644 --- a/app/src/main/kotlin/com/andreolas/movierama/ui/MovieApp.kt +++ b/app/src/main/kotlin/com/andreolas/movierama/ui/MovieApp.kt @@ -1,6 +1,5 @@ package com.andreolas.movierama.ui -import android.annotation.SuppressLint import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material3.Icon @@ -34,7 +33,6 @@ import com.ramcosta.composedestinations.utils.navGraph import com.ramcosta.composedestinations.utils.rememberDestinationsNavigator @Composable -@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") fun MovieApp( uiState: MainUiState, uiEvent: MainUiEvent, diff --git a/app/src/test/kotlin/com/andreolas/movierama/main/ui/MainViewModelRobot.kt b/app/src/test/kotlin/com/andreolas/movierama/main/ui/MainViewModelRobot.kt index 96f59f54..70644e48 100644 --- a/app/src/test/kotlin/com/andreolas/movierama/main/ui/MainViewModelRobot.kt +++ b/app/src/test/kotlin/com/andreolas/movierama/main/ui/MainViewModelRobot.kt @@ -1,5 +1,6 @@ package com.andreolas.movierama.main.ui +import com.andreolas.movierama.MainUiEvent import com.andreolas.movierama.MainUiState import com.andreolas.movierama.MainViewModel import com.andreolas.movierama.fakes.usecase.FakeSetRemoteConfigUseCase @@ -23,8 +24,20 @@ class MainViewModelRobot { ) } - fun assertViewState(expectedViewState: MainUiState) = apply { - assertThat(viewModel.viewState.value).isEqualTo(expectedViewState) + fun onHandleDeeplink(uri: String?) = apply { + viewModel.handleDeepLink(uri) + } + + fun onConsumeUiEvent() = apply { + viewModel.consumeUiEvent() + } + + fun assertUiState(expectedUiState: MainUiState) = apply { + assertThat(viewModel.uiState.value).isEqualTo(expectedUiState) + } + + fun assertUiEvent(expectedUiEvent: MainUiEvent) = apply { + assertThat(viewModel.uiEvent.value).isEqualTo(expectedUiEvent) } fun mockSetRemoteConfigResult(result: Unit) = apply { diff --git a/app/src/test/kotlin/com/andreolas/movierama/main/ui/MainViewModelTest.kt b/app/src/test/kotlin/com/andreolas/movierama/main/ui/MainViewModelTest.kt index 821b477c..6d948c2d 100644 --- a/app/src/test/kotlin/com/andreolas/movierama/main/ui/MainViewModelTest.kt +++ b/app/src/test/kotlin/com/andreolas/movierama/main/ui/MainViewModelTest.kt @@ -1,7 +1,9 @@ package com.andreolas.movierama.main.ui +import com.andreolas.movierama.MainUiEvent import com.andreolas.movierama.MainUiState import com.divinelink.core.testing.MainDispatcherRule +import com.divinelink.feature.details.ui.DetailsNavArguments import org.junit.Rule import org.junit.Test @@ -17,11 +19,87 @@ class MainViewModelTest { robot .mockSetRemoteConfigResult(Unit) .buildViewModel() - .assertViewState( + .assertUiState( MainUiState.Completed, ) } + @Test + fun `test handleDeepLink with movie deeplink`() { + val url = "https://www.themoviedb.org/movie/693134-dune-part-two" + + robot + .buildViewModel() + .assertUiEvent(MainUiEvent.None) + .onHandleDeeplink(url) + .assertUiEvent( + MainUiEvent.NavigateToDetails( + DetailsNavArguments( + id = 693134, + mediaType = "movie", + isFavorite = false, + ), + ), + ) + .onConsumeUiEvent() + .assertUiEvent(MainUiEvent.None) + } + + @Test + fun `test handleDeepLink with tv deeplink`() { + val url = "https://www.themoviedb.org/tv/693134-dune-part-two" + + robot + .buildViewModel() + .assertUiEvent(MainUiEvent.None) + .onHandleDeeplink(url) + .assertUiEvent( + MainUiEvent.NavigateToDetails( + DetailsNavArguments( + id = 693134, + mediaType = "tv", + isFavorite = false, + ), + ), + ) + .onConsumeUiEvent() + .assertUiEvent(MainUiEvent.None) + } + + @Test + fun `test handleDeepLink with person deeplink`() { + val url = "https://www.themoviedb.org/person/693134-dune-part-two" + + robot + .buildViewModel() + .assertUiEvent(MainUiEvent.None) + .onHandleDeeplink(url) + .assertUiEvent( + MainUiEvent.NavigateToDetails( + DetailsNavArguments( + id = 693134, + mediaType = "person", + isFavorite = false, + ), + ), + ) + .onConsumeUiEvent() + .assertUiEvent(MainUiEvent.None) + } + + @Test + fun `test handleDeepLink with invalid deeplink`() { + val url = "https://www.themoviedb.org/invalid/693134-dune-part-two" + + robot + .buildViewModel() + .assertUiEvent(MainUiEvent.None) + .onHandleDeeplink(url) + .assertUiEvent(MainUiEvent.None) + .onConsumeUiEvent() + .assertUiEvent(MainUiEvent.None) + } + // @Test // fun errorTest() { // robot diff --git a/app/src/test/kotlin/com/andreolas/movierama/settings/app/SettingsScreenTest.kt b/app/src/test/kotlin/com/andreolas/movierama/settings/app/SettingsScreenTest.kt index 2f73a31b..12867fb1 100644 --- a/app/src/test/kotlin/com/andreolas/movierama/settings/app/SettingsScreenTest.kt +++ b/app/src/test/kotlin/com/andreolas/movierama/settings/app/SettingsScreenTest.kt @@ -4,12 +4,14 @@ import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import com.divinelink.core.testing.ComposeTest +import com.divinelink.core.testing.getString import com.divinelink.core.testing.navigator.FakeDestinationsNavigator import com.divinelink.feature.settings.R import com.divinelink.feature.settings.app.SettingsScreen import com.divinelink.feature.settings.screens.destinations.AccountSettingsScreenDestination import com.divinelink.feature.settings.screens.destinations.AppearanceSettingsScreenDestination import com.divinelink.feature.settings.screens.destinations.HelpSettingsScreenDestination +import com.divinelink.feature.settings.screens.destinations.LinkHandlingSettingsScreenDestination import com.divinelink.feature.settings.screens.destinations.SettingsScreenDestination import org.junit.Test import com.divinelink.core.ui.R as uiR @@ -79,6 +81,33 @@ class SettingsScreenTest : ComposeTest() { ) } + @Test + fun `test navigate to link handling screen`() { + val destinationsNavigator = FakeDestinationsNavigator() + + destinationsNavigator.navigate( + direction = SettingsScreenDestination(), + ) + + composeTestRule.setContent { + SettingsScreen( + navigator = destinationsNavigator, + ) + } + + val linkHandlingSetting = getString(R.string.feature_settings_link_handling) + + with(composeTestRule) { + onNodeWithText(linkHandlingSetting).assertExists() + + onNodeWithText(linkHandlingSetting).performClick() + } + + destinationsNavigator.verifyNavigatedToDirection( + LinkHandlingSettingsScreenDestination, + ) + } + @Test fun `test navigate to help screen`() { val destinationsNavigator = FakeDestinationsNavigator() diff --git a/core/commons/src/main/kotlin/com/divinelink/core/commons/ApiConstants.kt b/core/commons/src/main/kotlin/com/divinelink/core/commons/ApiConstants.kt index ecd623bb..aabe84be 100644 --- a/core/commons/src/main/kotlin/com/divinelink/core/commons/ApiConstants.kt +++ b/core/commons/src/main/kotlin/com/divinelink/core/commons/ApiConstants.kt @@ -1,6 +1,5 @@ package com.divinelink.core.commons object ApiConstants { - const val TMDB_URL = BuildConfig.TMDB_BASE_URL const val TMDB_IMAGE_URL = BuildConfig.TMDB_IMAGE_URL } diff --git a/core/commons/src/main/kotlin/com/divinelink/core/commons/BuildConfigProvider.kt b/core/commons/src/main/kotlin/com/divinelink/core/commons/BuildConfigProvider.kt new file mode 100644 index 00000000..a4342224 --- /dev/null +++ b/core/commons/src/main/kotlin/com/divinelink/core/commons/BuildConfigProvider.kt @@ -0,0 +1,11 @@ +package com.divinelink.core.commons + +interface BuildConfigProvider { + val isDebug: Boolean + val buildType: String +} + +object DefaultBuildConfigProvider : BuildConfigProvider { + override val isDebug: Boolean = BuildConfig.DEBUG + override val buildType: String = BuildConfig.BUILD_TYPE +} diff --git a/core/commons/src/main/kotlin/com/divinelink/core/commons/util/AppSettingsUtil.kt b/core/commons/src/main/kotlin/com/divinelink/core/commons/util/AppSettingsUtil.kt new file mode 100644 index 00000000..cd42ac4e --- /dev/null +++ b/core/commons/src/main/kotlin/com/divinelink/core/commons/util/AppSettingsUtil.kt @@ -0,0 +1,18 @@ +package com.divinelink.core.commons.util + +import android.content.Context +import android.content.Intent +import android.net.Uri +import android.provider.Settings +import androidx.core.content.ContextCompat.startActivity + +object AppSettingsUtil { + private const val PACKAGE_SCHEME = "package" + + fun openAppDetails(context: Context) { + val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { + data = Uri.fromParts(PACKAGE_SCHEME, context.packageName, null) + } + startActivity(context, intent, null) + } +} diff --git a/core/commons/src/test/kotlin/com/divinelink/core/commons/extensions/StringExtensionsTest.kt b/core/commons/src/test/kotlin/com/divinelink/core/commons/extensions/StringExtensionsTest.kt new file mode 100644 index 00000000..252be618 --- /dev/null +++ b/core/commons/src/test/kotlin/com/divinelink/core/commons/extensions/StringExtensionsTest.kt @@ -0,0 +1,26 @@ +package com.divinelink.core.commons.extensions + +import com.google.common.truth.Truth.assertThat +import org.junit.Test + +class StringExtensionsTest { + + @Test + fun `test extractDetailsFromDeeplink with valid url`() { + val url = "https://www.themoviedb.org/tv/693134-dune-part-two" + + val result = url.extractDetailsFromDeepLink() + + val expected = Pair(693134, "tv") + assertThat(expected).isEqualTo(result) + } + + @Test + fun `test extractDetailsFromDeeplink with invalid url`() { + val url = "https://www.themoviedb.org/tv/" + + val result = url.extractDetailsFromDeepLink() + + assertThat(result).isNull() + } +} diff --git a/core/ui/src/main/kotlin/com/divinelink/core/ui/TestTags.kt b/core/ui/src/main/kotlin/com/divinelink/core/ui/TestTags.kt index 986b0522..7eb7179f 100644 --- a/core/ui/src/main/kotlin/com/divinelink/core/ui/TestTags.kt +++ b/core/ui/src/main/kotlin/com/divinelink/core/ui/TestTags.kt @@ -7,6 +7,8 @@ object TestTags { const val SCROLL_TO_TOP_BUTTON = "SCROLL_TO_TOP_BUTTON_TAG" const val LOADING_PROGRESS = "Loading Progress Bar" + const val LAZY_COLUMN = "Lazy Column" + object Details { const val YOUR_RATING = "Details Your Rating" const val RATE_DIALOG = "Details Rate Dialog" @@ -53,6 +55,10 @@ object TestTags { const val JELLYSEERR_LOGIN_BUTTON = "Jellyseerr Login Button" const val JELLYSEERR_LOGOUT_BUTTON = "Jellyseerr Logout Button" } + + object LinkHandling { + const val DIRECTIONS_TEXT = "Link Handling Directions" + } } object Menu { diff --git a/feature/settings/src/main/kotlin/com/divinelink/feature/settings/app/help/HelpSettingsScreen.kt b/feature/settings/src/main/kotlin/com/divinelink/feature/settings/app/help/HelpSettingsScreen.kt index f9f2b1d8..ccc8bd47 100644 --- a/feature/settings/src/main/kotlin/com/divinelink/feature/settings/app/help/HelpSettingsScreen.kt +++ b/feature/settings/src/main/kotlin/com/divinelink/feature/settings/app/help/HelpSettingsScreen.kt @@ -4,6 +4,8 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.runtime.Composable import androidx.compose.ui.res.stringResource import com.divinelink.core.commons.BuildConfig +import com.divinelink.core.commons.BuildConfigProvider +import com.divinelink.core.commons.DefaultBuildConfigProvider import com.divinelink.core.ui.UIText import com.divinelink.core.ui.getString import com.divinelink.feature.settings.R @@ -16,7 +18,10 @@ import com.divinelink.core.commons.R as commonR @Composable @Destination -fun HelpSettingsScreen(navigator: DestinationsNavigator) { +fun HelpSettingsScreen( + navigator: DestinationsNavigator, + buildConfigProvider: BuildConfigProvider = DefaultBuildConfigProvider, +) { SettingsScaffold( title = stringResource(id = R.string.HelpSettingsFragment__help), onNavigationClick = navigator::navigateUp, @@ -24,7 +29,7 @@ fun HelpSettingsScreen(navigator: DestinationsNavigator) { val version = UIText.ResourceText(commonR.string.version_name) - val buildVersion = if (BuildConfig.DEBUG) { + val buildVersion = if (buildConfigProvider.isDebug) { UIText.StringText(version.getString() + " ${BuildConfig.BUILD_TYPE}") } else { version diff --git a/feature/settings/src/main/kotlin/com/divinelink/feature/settings/app/links/LinkHandlingSettingsScreen.kt b/feature/settings/src/main/kotlin/com/divinelink/feature/settings/app/links/LinkHandlingSettingsScreen.kt index 1a213c79..9d723f27 100644 --- a/feature/settings/src/main/kotlin/com/divinelink/feature/settings/app/links/LinkHandlingSettingsScreen.kt +++ b/feature/settings/src/main/kotlin/com/divinelink/feature/settings/app/links/LinkHandlingSettingsScreen.kt @@ -1,8 +1,5 @@ package com.divinelink.feature.settings.app.links -import android.content.Intent -import android.net.Uri -import android.provider.Settings import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.padding @@ -13,13 +10,15 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.withStyle -import androidx.core.content.ContextCompat.startActivity +import com.divinelink.core.commons.util.AppSettingsUtil import com.divinelink.core.designsystem.theme.dimensions +import com.divinelink.core.ui.TestTags import com.divinelink.feature.settings.R import com.divinelink.feature.settings.components.SettingsScaffold import com.divinelink.feature.settings.components.SettingsTextItem @@ -33,11 +32,39 @@ import com.divinelink.core.commons.R as CoreR fun LinkHandlingSettingsScreen(navigator: DestinationsNavigator) { val context = LocalContext.current + val directions = buildAnnotatedString { + append(stringResource(id = R.string.feature_settings_enable_link_handling_step_1)) + withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { + append(stringResource(id = R.string.feature_settings_enable_link_handling_step_2)) + } + withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { + append(stringResource(id = R.string.feature_settings_enable_link_handling_step_3)) + } + append(stringResource(id = R.string.feature_settings_enable_link_handling_step_4)) + withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { + append( + stringResource( + id = R.string.feature_settings_enable_link_handling_step_5, + stringResource(CoreR.string.core_commons_app_name), + ), + ) + } + append( + stringResource( + id = R.string.feature_settings_enable_link_handling_step_6, + stringResource(CoreR.string.core_commons_app_name), + ), + ) + } + SettingsScaffold( title = stringResource(id = R.string.feature_settings_link_handling), onNavigationClick = navigator::navigateUp, ) { - LazyColumn(contentPadding = it) { + LazyColumn( + modifier = Modifier.testTag(TestTags.LAZY_COLUMN), + contentPadding = it, + ) { item { SettingsTextItem( title = stringResource( @@ -52,32 +79,10 @@ fun LinkHandlingSettingsScreen(navigator: DestinationsNavigator) { } item { - val directions = buildAnnotatedString { - append(stringResource(id = R.string.feature_settings_enable_link_handling_step_1)) - withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { - append(stringResource(id = R.string.feature_settings_enable_link_handling_step_2)) - } - withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { - append(stringResource(id = R.string.feature_settings_enable_link_handling_step_3)) - } - append(stringResource(id = R.string.feature_settings_enable_link_handling_step_4)) - withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { - append( - stringResource( - id = R.string.feature_settings_enable_link_handling_step_5, - stringResource(CoreR.string.core_commons_app_name), - ), - ) - } - append( - stringResource( - id = R.string.feature_settings_enable_link_handling_step_6, - stringResource(CoreR.string.core_commons_app_name), - ), - ) - } Text( - modifier = Modifier.padding(MaterialTheme.dimensions.keyline_16), + modifier = Modifier + .testTag(TestTags.Settings.LinkHandling.DIRECTIONS_TEXT) + .padding(MaterialTheme.dimensions.keyline_16), text = directions, style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.secondary, @@ -88,14 +93,9 @@ fun LinkHandlingSettingsScreen(navigator: DestinationsNavigator) { Row { Spacer(modifier = Modifier.weight(1f)) Button( - onClick = { - val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { - data = Uri.fromParts("package", context.packageName, null) - } - startActivity(context, intent, null) - }, + onClick = { AppSettingsUtil.openAppDetails(context) }, ) { - Text("Open Settings") + Text(stringResource(id = R.string.feature_settings_open_settings)) } Spacer(modifier = Modifier.weight(1f)) } diff --git a/feature/settings/src/main/res/values/strings.xml b/feature/settings/src/main/res/values/strings.xml index c9bddfb6..8d0f4da4 100644 --- a/feature/settings/src/main/res/values/strings.xml +++ b/feature/settings/src/main/res/values/strings.xml @@ -37,6 +37,7 @@ Integrate your self-hosted apps to enable additional features like movie and TV show requests. + Open settings Allow %s to handle specific URLs? %s can open specific URLs in the app. This can be useful for opening links to movies and TV shows directly in the app. diff --git a/feature/settings/src/test/kotlin/com/divinelink/feature/settings/app/help/HelpSettingsScreenTest.kt b/feature/settings/src/test/kotlin/com/divinelink/feature/settings/app/help/HelpSettingsScreenTest.kt new file mode 100644 index 00000000..bfad41d6 --- /dev/null +++ b/feature/settings/src/test/kotlin/com/divinelink/feature/settings/app/help/HelpSettingsScreenTest.kt @@ -0,0 +1,89 @@ +package com.divinelink.feature.settings.app.help + +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.assertTextEquals +import androidx.compose.ui.test.onNodeWithTag +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.performClick +import com.divinelink.core.commons.BuildConfigProvider +import com.divinelink.core.testing.ComposeTest +import com.divinelink.core.testing.getString +import com.divinelink.core.testing.navigator.FakeDestinationsNavigator +import com.divinelink.core.testing.setContentWithTheme +import com.divinelink.core.ui.TestTags +import com.divinelink.feature.settings.R +import com.divinelink.feature.settings.app.SettingsScreen +import com.divinelink.feature.settings.screens.destinations.HelpSettingsScreenDestination +import com.divinelink.feature.settings.screens.destinations.SettingsScreenDestination +import org.junit.Test +import com.divinelink.core.commons.R as CommonR + +class HelpSettingsScreenTest : ComposeTest() { + + private val releaseBuildConfigProvider = object : BuildConfigProvider { + override val isDebug: Boolean = false + override val buildType: String = "release" + } + + private val debugBuildConfigProvider = object : BuildConfigProvider { + override val isDebug: Boolean = true + override val buildType: String = "debug" + } + + @Test + fun `test version with debug build`() { + setContentWithTheme { + HelpSettingsScreen( + navigator = FakeDestinationsNavigator(), + buildConfigProvider = debugBuildConfigProvider, + ) + } + + val version = getString(CommonR.string.version_name) + " debug" + + with(composeTestRule) { + onNodeWithText(getString(R.string.HelpSettingsFragment__help)) + .assertIsDisplayed() + .assertTextEquals("Help") + + onNodeWithText(getString(R.string.HelpSettingsFragment__version)).assertIsDisplayed() + onNodeWithText(version).assertIsDisplayed() + } + } + + @Test + fun `test version with release`() { + setContentWithTheme { + HelpSettingsScreen( + navigator = FakeDestinationsNavigator(), + buildConfigProvider = releaseBuildConfigProvider, + ) + } + + val version = getString(CommonR.string.version_name) + + with(composeTestRule) { + onNodeWithText(getString(R.string.HelpSettingsFragment__version)).assertIsDisplayed() + onNodeWithText(version).assertIsDisplayed() + } + } + + @Test + fun `test navigateUp`() { + val navigator = FakeDestinationsNavigator() + navigator.navigate(SettingsScreenDestination) + setContentWithTheme { + SettingsScreen(navigator = navigator) + } + + with(composeTestRule) { + onNodeWithText(getString(R.string.preferences__help)).performClick() + + navigator.verifyNavigatedToDirection(HelpSettingsScreenDestination) + + onNodeWithTag(TestTags.Settings.NAVIGATION_ICON).performClick().assertIsDisplayed() + } + + navigator.verifyNavigatedToDirection(SettingsScreenDestination) + } +} diff --git a/feature/settings/src/test/kotlin/com/divinelink/feature/settings/app/links/LinkHandlingSettingsScreenTest.kt b/feature/settings/src/test/kotlin/com/divinelink/feature/settings/app/links/LinkHandlingSettingsScreenTest.kt new file mode 100644 index 00000000..63d63949 --- /dev/null +++ b/feature/settings/src/test/kotlin/com/divinelink/feature/settings/app/links/LinkHandlingSettingsScreenTest.kt @@ -0,0 +1,37 @@ +package com.divinelink.feature.settings.app.links + +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.onNodeWithTag +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.performScrollTo +import androidx.compose.ui.test.performScrollToIndex +import com.divinelink.core.testing.ComposeTest +import com.divinelink.core.testing.getString +import com.divinelink.core.testing.navigator.FakeDestinationsNavigator +import com.divinelink.core.testing.setContentWithTheme +import com.divinelink.core.ui.TestTags +import com.divinelink.feature.settings.R +import org.junit.Test + +class LinkHandlingSettingsScreenTest : ComposeTest() { + + @Test + fun `test LinkHandlingSettingsScreen`() { + val navigator = FakeDestinationsNavigator() + setContentWithTheme { + LinkHandlingSettingsScreen( + navigator = navigator, + ) + } + + with(composeTestRule) { + onNodeWithText("Link handling").assertIsDisplayed() + onNodeWithText("Allow DebugRama to handle specific URLs?").assertIsDisplayed() + + onNodeWithTag(TestTags.Settings.LinkHandling.DIRECTIONS_TEXT).performScrollTo() + .assertIsDisplayed() + onNodeWithTag(TestTags.LAZY_COLUMN).performScrollToIndex(2) + onNodeWithText(getString(R.string.feature_settings_open_settings)).assertIsDisplayed() + } + } +}