Skip to content
Open
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
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ ij_kotlin_allow_trailing_comma_on_call_site = true
ij_kotlin_name_count_to_use_star_import = 2147483647
ij_kotlin_name_count_to_use_star_import_for_members = 2147483647
ij_kotlin_packages_to_use_import_on_demand = unset
ktlint_class_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than = 1
ktlint_code_style = android_studio
ktlint_function_naming_ignore_when_annotated_with = Composable
ktlint_standard_function-expression-body = disabled
Expand Down
35 changes: 6 additions & 29 deletions AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -164,40 +164,17 @@
<!-- Settings -->
<activity
android:name=".ui.appsettings.SettingsActivity"
android:label="@string/settings_activity_title"
android:theme="@style/BugleTheme.SettingsActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
android:screenOrientation="user"
android:parentActivityName="com.android.messaging.ui.conversationlist.ConversationListActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.android.messaging.ui.conversationlist.ConversationListActivity" />
</activity>

<activity
android:name=".ui.appsettings.PerSubscriptionSettingsActivity"
android:label="@string/advanced_settings_activity_title"
android:theme="@style/BugleTheme.SettingsActivity"
android:allowEmbedded="true"
android:configChanges="orientation|screenSize|keyboardHidden"
android:screenOrientation="user"
android:parentActivityName="com.android.messaging.ui.appsettings.SettingsActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.android.messaging.ui.appsettings.SettingsActivity" />
</activity>

<activity
android:name=".ui.appsettings.ApplicationSettingsActivity"
android:exported="true"
Comment on lines 165 to 169
Copy link
Copy Markdown
Member

@inthewaves inthewaves Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically, this is removing the exported Activity .ui.appsettings.ApplicationSettingsActivity and just using .ui.appsettings.SettingsActivity now.

Since .ui.appsettings.ApplicationSettingsActivity used to be exported, for completeness, maybe an activity-alias could be added here for .ui.appsettings.ApplicationSettingsActivity with android:targetActivity=".ui.appsettings.SettingsActivity">

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will take a look, thanks

android:label="@string/general_settings_activity_title"
android:theme="@style/BugleTheme.SettingsActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
android:label="@string/settings_activity_title"
android:parentActivityName="com.android.messaging.ui.conversationlist.ConversationListActivity"
android:resizeableActivity="true"
android:screenOrientation="user"
android:parentActivityName="com.android.messaging.ui.appsettings.SettingsActivity">
android:theme="@style/Theme.Compose">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:exported="true"
android:value="com.android.messaging.ui.appsettings.SettingsActivity" />
android:value="com.android.messaging.ui.conversationlist.ConversationListActivity" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
Expand Down
5 changes: 5 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,11 @@ dependencies {

androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.compose.ui.test.junit4)
androidTestImplementation(libs.androidx.test.espresso.contrib)
androidTestImplementation(libs.androidx.test.espresso.core)
androidTestImplementation(libs.androidx.test.ext.junit)
androidTestImplementation(libs.androidx.test.rules)
androidTestImplementation(libs.androidx.test.runner)

androidTestImplementation(libs.hilt.android.testing)
kspAndroidTest(libs.hilt.compiler)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
package com.android.messaging.ui.appsettings.general.ui

import androidx.activity.ComponentActivity
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import com.android.messaging.R
import com.android.messaging.ui.appsettings.general.model.AppSettingsUiState
import com.android.messaging.ui.appsettings.screen.SettingsScreenModel
import com.android.messaging.ui.appsettings.screen.model.SettingsAction as Action
import com.android.messaging.ui.core.AppTheme
import io.mockk.mockk
import io.mockk.verify
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Rule
import org.junit.Test

class AppSettingsScreenTest {

@get:Rule
val composeTestRule = createAndroidComposeRule<ComponentActivity>()

private lateinit var screenModel: SettingsScreenModel

@Before
fun setup() {
screenModel = mockk(relaxed = true)
}

@Test
fun defaultSmsAppItem_displaysLabel() {
val appSettings = AppSettingsUiState(
isDefaultSmsApp = true,
defaultSmsAppLabel = "Messaging",
)

setContent(appSettings = appSettings)

composeTestRule.onNodeWithText("Messaging").assertIsDisplayed()
}

@Test
fun defaultSmsAppClick_delegatesToScreenModel() {
val appSettings = AppSettingsUiState(
isDefaultSmsApp = true,
defaultSmsAppLabel = "Messaging",
)

setContent(appSettings = appSettings)

val title = composeTestRule.activity.getString(R.string.sms_disabled_pref_title)
composeTestRule.onNodeWithText(title).performClick()

verify(exactly = 1) {
screenModel.onAction(Action.DefaultSmsAppClicked(true))
}
}

@Test
fun notificationsClick_delegatesToScreenModel() {
setContent()

val title = composeTestRule.activity.getString(
R.string.notifications_enabled_conversation_pref_title,
)
composeTestRule.onNodeWithText(title).performClick()

verify(exactly = 1) {
screenModel.onAction(Action.NotificationsClicked)
}
}

@Test
fun sendSoundToggle_delegatesToScreenModel() {
val appSettings = AppSettingsUiState(sendSoundEnabled = true)

setContent(appSettings = appSettings)

val title = composeTestRule.activity.getString(R.string.send_sound_pref_title)
composeTestRule.onNodeWithText(title).performClick()

verify(exactly = 1) {
screenModel.onAction(Action.SendSoundChanged(false))
}
}

@Test
fun debugSection_hiddenWhenDebugDisabled() {
val appSettings = AppSettingsUiState(isDebugEnabled = false)

setContent(appSettings = appSettings)

val debugTitle = composeTestRule.activity.getString(R.string.debug_category_pref_title)
composeTestRule.onNodeWithText(debugTitle).assertDoesNotExist()

val dumpSmsTitle = composeTestRule.activity.getString(R.string.dump_sms_pref_title)
composeTestRule.onNodeWithText(dumpSmsTitle).assertDoesNotExist()
}

@Test
fun debugSection_shownWhenDebugEnabled() {
val appSettings = AppSettingsUiState(
isDebugEnabled = true,
dumpSmsEnabled = false,
dumpMmsEnabled = false,
)

setContent(appSettings = appSettings)

val debugTitle = composeTestRule.activity.getString(R.string.debug_category_pref_title)
composeTestRule.onNodeWithText(debugTitle).assertIsDisplayed()

val dumpSmsTitle = composeTestRule.activity.getString(R.string.dump_sms_pref_title)
composeTestRule.onNodeWithText(dumpSmsTitle).assertIsDisplayed()

val dumpMmsTitle = composeTestRule.activity.getString(R.string.dump_mms_pref_title)
composeTestRule.onNodeWithText(dumpMmsTitle).assertIsDisplayed()
}

@Test
fun dumpSmsToggle_delegatesToScreenModel() {
val appSettings = AppSettingsUiState(
isDebugEnabled = true,
dumpSmsEnabled = false,
)

setContent(appSettings = appSettings)

val title = composeTestRule.activity.getString(R.string.dump_sms_pref_title)
composeTestRule.onNodeWithText(title).performClick()

verify(exactly = 1) {
screenModel.onAction(Action.DumpSmsChanged(true))
}
}

@Test
fun dumpMmsToggle_delegatesToScreenModel() {
val appSettings = AppSettingsUiState(
isDebugEnabled = true,
dumpMmsEnabled = false,
)

setContent(appSettings = appSettings)

val title = composeTestRule.activity.getString(R.string.dump_mms_pref_title)
composeTestRule.onNodeWithText(title).performClick()

verify(exactly = 1) {
screenModel.onAction(Action.DumpMmsChanged(true))
}
}

@Test
fun licensesClick_delegatesToScreenModel() {
setContent()

val title = composeTestRule.activity.getString(R.string.menu_license)
composeTestRule.onNodeWithText(title).performClick()

verify(exactly = 1) {
screenModel.onAction(Action.LicensesClicked)
}
}

@Test
fun advancedSettings_shownWhenTopLevel() {
var advancedClicks = 0

composeTestRule.setContent {
AppTheme {
AppSettingsScreen(
appSettings = AppSettingsUiState(),
screenModel = screenModel,
onNavigateBack = {},
isTopLevel = true,
onAdvancedClick = { advancedClicks += 1 },
)
}
}

val advancedTitle = composeTestRule.activity.getString(R.string.advanced_settings)
composeTestRule.onNodeWithText(advancedTitle).assertIsDisplayed()
composeTestRule.onNodeWithText(advancedTitle).performClick()

composeTestRule.runOnIdle {
assertEquals(1, advancedClicks)
}
}

@Test
fun advancedSettings_hiddenWhenNotTopLevel() {
composeTestRule.setContent {
AppTheme {
AppSettingsScreen(
appSettings = AppSettingsUiState(),
screenModel = screenModel,
onNavigateBack = {},
isTopLevel = false,
onAdvancedClick = null,
)
}
}

val advancedTitle = composeTestRule.activity.getString(R.string.advanced_settings)
composeTestRule.onNodeWithText(advancedTitle).assertDoesNotExist()
}

private fun setContent(
appSettings: AppSettingsUiState = AppSettingsUiState(),
) {
composeTestRule.setContent {
AppTheme {
AppSettingsScreen(
appSettings = appSettings,
screenModel = screenModel,
onNavigateBack = {},
)
}
}
}
}
Loading