Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ dependencies {
// Compose
def composeBom = platform(libs.androidx.compose.bom)
implementation(composeBom)
testImplementation(composeBom)

// Material Design 3
implementation libs.androidx.material3
Expand All @@ -167,6 +168,9 @@ dependencies {
// Android Studio Preview support
implementation libs.androidx.ui.tooling.preview
debugImplementation libs.androidx.ui.tooling
// UI tests, run as Robolectric unit tests
testImplementation libs.androidx.ui.test.junit4
debugImplementation libs.androidx.ui.test.manifest
// Optional - Add full set of material icons
implementation libs.androidx.material.icons.extended
// Optional - Integration with activities
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalResources
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.intl.Locale
import androidx.compose.ui.text.toUpperCase
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.core.graphics.createBitmap
Expand Down Expand Up @@ -66,7 +64,7 @@ fun AddAppSignaturePackageFilterDialog(

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun AddAppSignaturePackageFilterDialog(
internal fun AddAppSignaturePackageFilterDialog(
viewState: ViewState,
closeDialog: () -> Unit = {},
appSelected: (AppInfo) -> Unit = {},
Expand Down Expand Up @@ -111,7 +109,7 @@ private fun AddAppSignaturePackageFilterDialog(
modifier = Modifier
.align(Alignment.End), onClick = closeDialog
) {
Text(text = stringResource(id = R.string.cancel).toUpperCase(Locale.current))
Text(text = stringResource(id = R.string.cancel))
}
}
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.intl.Locale
import androidx.compose.ui.text.toUpperCase
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
Expand Down Expand Up @@ -58,7 +56,7 @@ fun AddPackageNamePackageFilterDialog(
}

@Composable
private fun AddPackageNamePackageFilterDialog(
internal fun AddPackageNamePackageFilterDialog(
viewState: AddPackageNamePackageFilterDialogViewModel.ViewState,
closeDialog: () -> Unit = {},
addFilter: (String) -> Unit = {}
Expand Down Expand Up @@ -98,10 +96,10 @@ private fun AddPackageNamePackageFilterDialog(
Spacer(modifier = Modifier.size(8.dp))
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {
TextButton(onClick = closeDialog) {
Text(text = stringResource(id = R.string.cancel).toUpperCase(Locale.current))
Text(text = stringResource(id = R.string.cancel))
}
TextButton(onClick = { addFilter(text) }, enabled = text.isNotBlank()) {
Text(text = stringResource(id = R.string.add).toUpperCase(Locale.current))
Text(text = stringResource(id = R.string.add))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.intl.Locale
import androidx.compose.ui.text.toUpperCase
import de.psdev.devdrawer.R

@Composable
Expand All @@ -21,12 +19,12 @@ fun DeletePackageFilterDialog(
},
dismissButton = {
TextButton(onClick = onDismiss) {
Text(text = stringResource(id = R.string.cancel).toUpperCase(Locale.current))
Text(text = stringResource(id = R.string.cancel))
}
},
confirmButton = {
TextButton(onClick = onConfirm) {
Text(text = stringResource(id = R.string.yes).toUpperCase(Locale.current))
Text(text = stringResource(id = R.string.yes))
}
}
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.intl.Locale
import androidx.compose.ui.text.toUpperCase
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import de.psdev.devdrawer.R
Expand Down Expand Up @@ -65,7 +63,7 @@ fun PackageFilterInfoDialog(
modifier = Modifier.align(Alignment.End),
onClick = onDismiss
) {
Text(text = stringResource(id = R.string.close).toUpperCase(Locale.current))
Text(text = stringResource(id = R.string.close))
}
}
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.intl.Locale
import androidx.compose.ui.text.toUpperCase
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.core.content.res.ResourcesCompat
Expand Down Expand Up @@ -49,7 +47,7 @@ fun PackageFilterPreviewDialog(
}

@Composable
private fun PackageFilterPreviewDialog(
internal fun PackageFilterPreviewDialog(
viewState: PackageFilterPreviewDialogViewModel.ViewState,
closeDialog: () -> Unit = {}
) {
Expand All @@ -67,7 +65,7 @@ private fun PackageFilterPreviewDialog(
},
bottomContent = {
TextButton(modifier = Modifier.align(Alignment.End), onClick = closeDialog) {
Text(text = stringResource(id = R.string.close).toUpperCase(Locale.current))
Text(text = stringResource(id = R.string.close))
}
}
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.intl.Locale
import androidx.compose.ui.text.toUpperCase
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
Expand Down Expand Up @@ -223,7 +221,7 @@ private sealed class WidgetProfileEditorDialogs {

@OptIn(ExperimentalAnimationApi::class)
@Composable
private fun WidgetProfileEditor(
internal fun WidgetProfileEditor(
viewState: WidgetProfileEditorViewState,
modifier: Modifier = Modifier,
onNameChange: (String) -> Unit = {},
Expand Down Expand Up @@ -266,7 +264,7 @@ private fun WidgetProfileEditor(
contentDescription = stringResource(id = R.string.add_package_name)
)
Spacer(Modifier.size(ButtonDefaults.IconSpacing))
Text(text = stringResource(id = R.string.add_package_name).toUpperCase(Locale.current))
Text(text = stringResource(id = R.string.add_package_name))
}
Button(
modifier = Modifier.weight(1f),
Expand All @@ -278,7 +276,7 @@ private fun WidgetProfileEditor(
contentDescription = stringResource(id = R.string.add_app_signature)
)
Spacer(Modifier.size(ButtonDefaults.IconSpacing))
Text(text = stringResource(id = R.string.add_app_signature).toUpperCase(Locale.current))
Text(text = stringResource(id = R.string.add_app_signature))
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
<string name="uninstall">Uninstall</string>
<string name="app_details">App details</string>
<string name="add_app_signature">App signature</string>
<string name="add_package_name">package name</string>
<string name="add_package_name">Package name</string>
<string name="app_icon">App icon</string>
<string name="enter_package_name_filter">Enter package name filter</string>
<string name="select_signature_from_app">Select signature from app</string>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package de.psdev.devdrawer.profiles.ui.editor

import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText
import de.psdev.devdrawer.database.FilterType
import de.psdev.devdrawer.database.PackageFilter
import de.psdev.devdrawer.ui.theme.DevDrawerTheme
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config

/**
* Dialog buttons use the string resources' sentence case ("Cancel"), not upper-cased labels ("CANCEL").
*/
@RunWith(RobolectricTestRunner::class)
// SDK 36 requires Java 21; use SDK 33 which is compatible with the project's Java 17 toolchain.
@Config(sdk = [33])
class DialogButtonLabelTest {

@get:Rule
val composeTestRule = createComposeRule()

private val packageFilter = PackageFilter(
type = FilterType.SIGNATURE,
filter = "4f8d2c9e",
description = "Example App",
profileId = "profile"
)

@Test
fun `given the delete filter dialog, when shown, then its buttons are in sentence case`() {
// Given / When
composeTestRule.setContent {
DevDrawerTheme { DeletePackageFilterDialog(onDismiss = {}, onConfirm = {}) }
}

// Then
assertSentenceCase("Cancel", "Yes")
}

@Test
fun `given the add package name filter dialog, when loaded, then its buttons are in sentence case`() {
// Given / When
composeTestRule.setContent {
DevDrawerTheme {
AddPackageNamePackageFilterDialog(
viewState = AddPackageNamePackageFilterDialogViewModel.ViewState.Loaded(listOf("com.example.app"))
)
}
}

// Then
assertSentenceCase("Cancel", "Add")
}

@Test
fun `given the add app signature filter dialog, when shown, then its button is in sentence case`() {
// Given / When
composeTestRule.setContent {
DevDrawerTheme {
AddAppSignaturePackageFilterDialog(
viewState = AddAppSignaturePackageFilterDialogViewModel.ViewState.Loaded(
data = emptyList(),
showSystemApps = false
)
)
}
}

// Then
assertSentenceCase("Cancel")
}

@Test
fun `given the filter info dialog, when shown, then its button is in sentence case`() {
// Given / When
composeTestRule.setContent {
DevDrawerTheme { PackageFilterInfoDialog(packageFilter = packageFilter, onDismiss = {}) }
}

// Then
assertSentenceCase("Close")
}

@Test
fun `given the filter preview dialog, when loaded, then its button is in sentence case`() {
// Given / When
composeTestRule.setContent {
DevDrawerTheme {
PackageFilterPreviewDialog(
viewState = PackageFilterPreviewDialogViewModel.ViewState.Loaded(emptyList())
)
}
}

// Then
assertSentenceCase("Close")
}

private fun assertSentenceCase(vararg labels: String) {
labels.forEach { label ->
composeTestRule.onNodeWithText(label).assertExists()
composeTestRule.onNodeWithText(label.uppercase()).assertDoesNotExist()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package de.psdev.devdrawer.profiles.ui.editor

import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText
import de.psdev.devdrawer.database.FilterType
import de.psdev.devdrawer.database.PackageFilter
import de.psdev.devdrawer.database.WidgetProfile
import de.psdev.devdrawer.ui.theme.DevDrawerTheme
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config

/**
* The filter type labels ("Package name", "App signature") are shown in sentence case,
* neither upper-cased ("PACKAGE NAME") nor lower-cased ("package name").
*/
@RunWith(RobolectricTestRunner::class)
// SDK 36 requires Java 21; use SDK 33 which is compatible with the project's Java 17 toolchain.
@Config(sdk = [33])
class FilterTypeLabelTest {

@get:Rule
val composeTestRule = createComposeRule()

@Test
fun `given the profile editor, when loaded, then the add filter buttons are in sentence case`() {
// Given
val widgetProfile = WidgetProfile(name = "Test profile")

// When
composeTestRule.setContent {
DevDrawerTheme {
WidgetProfileEditor(
viewState = WidgetProfileEditorViewState(
widgetProfile = widgetProfile,
widgetName = widgetProfile.name
)
)
}
}

// Then
assertSentenceCase("Package name", "App signature")
}

@Test
fun `given a package name filter, when showing its info, then the title is in sentence case`() {
// Given
val packageFilter = PackageFilter(
type = FilterType.PACKAGE_NAME,
filter = "com.example.*",
profileId = "profile"
)

// When
composeTestRule.setContent {
DevDrawerTheme { PackageFilterInfoDialog(packageFilter = packageFilter, onDismiss = {}) }
}

// Then
assertSentenceCase("Package name")
}

private fun assertSentenceCase(vararg labels: String) {
labels.forEach { label ->
composeTestRule.onNodeWithText(label).assertExists()
composeTestRule.onNodeWithText(label.uppercase()).assertDoesNotExist()
composeTestRule.onNodeWithText(label.lowercase()).assertDoesNotExist()
}
}
}
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref =
androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "androidx-room" }
androidx-ui-tooling = { module = "androidx.compose.ui:ui-tooling" }
androidx-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview" }
androidx-ui-test-junit4 = { module = "androidx.compose.ui:ui-test-junit4" }
androidx-ui-test-manifest = { module = "androidx.compose.ui:ui-test-manifest" }
androidx-work-runtime-ktx = { module = "androidx.work:work-runtime-ktx", version.ref = "androidx-work" }
app-update-ktx = { module = "com.google.android.play:app-update-ktx", version.ref = "playUpdate" }
androidx-navigation3-runtime = { module = "androidx.navigation3:navigation3-runtime", version.ref = "nav3" }
Expand Down
Loading