Fix when edittext only has space and cause name look like blank

fix: 335763360
Test: Manual test. see b/335763360#comment14
Test: atest passed
Change-Id: I9ebae13039d7b78b7acfea545a89d3096aa82c31
This commit is contained in:
tomhsu
2024-05-27 12:42:03 +00:00
parent 5b0211ea75
commit d5556c59e9
2 changed files with 127 additions and 30 deletions

View File

@@ -28,6 +28,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import com.android.settings.R import com.android.settings.R
import com.android.settings.network.SimOnboardingService import com.android.settings.network.SimOnboardingService
@@ -104,9 +105,9 @@ private fun LabelSimPreference(
value = titleSimName, value = titleSimName,
label = stringResource(R.string.sim_onboarding_label_sim_dialog_label), label = stringResource(R.string.sim_onboarding_label_sim_dialog_label),
placeholder = {Text(text = originalSimCarrierName)}, placeholder = {Text(text = originalSimCarrierName)},
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth().testTag("contentInput")
) { ) {
titleSimName = if (it.isEmpty()) originalSimCarrierName else it titleSimName = if (it.matches(Regex("^\\s*$"))) originalSimCarrierName else it
} }
}, },
) )

View File

@@ -19,20 +19,30 @@ package com.android.settings.spa.network
import android.content.Context import android.content.Context
import android.telephony.SubscriptionInfo import android.telephony.SubscriptionInfo
import android.telephony.SubscriptionManager import android.telephony.SubscriptionManager
import android.view.KeyEvent.ACTION_DOWN
import android.view.KeyEvent.KEYCODE_FORWARD_DEL
import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.input.key.KeyEvent
import androidx.compose.ui.input.key.NativeKeyEvent
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.semantics.SemanticsProperties
import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.hasText import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performKeyPress
import androidx.compose.ui.test.performTextClearance
import androidx.compose.ui.test.performTextInput
import androidx.lifecycle.testing.TestLifecycleOwner import androidx.lifecycle.testing.TestLifecycleOwner
import androidx.test.core.app.ApplicationProvider import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settings.R import com.android.settings.R
import com.android.settings.network.SimOnboardingService import com.android.settings.network.SimOnboardingService
import com.android.settingslib.spa.testutils.waitUntilExists import com.android.settingslib.spa.testutils.waitUntilExists
import org.junit.Assert.assertEquals
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@@ -125,22 +135,7 @@ class SimOnboardingLabelSimTest {
@Test @Test
fun simOnboardingLabelSimImpl_showItem_show3Items() { fun simOnboardingLabelSimImpl_showItem_show3Items() {
mockSimOnboardingService.stub { preSetupContent()
on { targetSubId }.doReturn(SUB_ID_1)
on { targetSubInfo }.doReturn(SUB_INFO_1)
on { availableSubInfoList }.doReturn(listOf(SUB_INFO_1, SUB_INFO_2, SUB_INFO_3))
on { activeSubInfoList }.doReturn(listOf(SUB_INFO_2, SUB_INFO_3))
on { getSelectableSubscriptionInfoList() }.doReturn(
listOf(
SUB_INFO_1,
SUB_INFO_2,
SUB_INFO_3
)
)
on { getSubscriptionInfoDisplayName(SUB_INFO_1) }.doReturn(DISPLAY_NAME_1)
on { getSubscriptionInfoDisplayName(SUB_INFO_2) }.doReturn(DISPLAY_NAME_2)
on { getSubscriptionInfoDisplayName(SUB_INFO_3) }.doReturn(DISPLAY_NAME_3)
}
composeTestRule.setContent { composeTestRule.setContent {
CompositionLocalProvider( CompositionLocalProvider(
@@ -161,6 +156,118 @@ class SimOnboardingLabelSimTest {
@Test @Test
fun simOnboardingLabelSimImpl_showDialog_checkTitle() { fun simOnboardingLabelSimImpl_showDialog_checkTitle() {
preSetupContent()
composeTestRule.setContent {
SimOnboardingLabelSimImpl(nextAction, cancelAction, mockSimOnboardingService)
}
composeTestRule.onNodeWithText(DISPLAY_NAME_1).performClick()
composeTestRule.onNodeWithText(
context.getString(R.string.sim_onboarding_label_sim_dialog_title)
).assertIsDisplayed()
}
@Test
fun showDialog_noContentInput_showOriginalDisplayName() {
preSetupContent()
composeTestRule.setContent {
SimOnboardingLabelSimImpl(nextAction, cancelAction, mockSimOnboardingService)
}
composeTestRule.onNodeWithText(DISPLAY_NAME_1).performClick()
assertEquals(
composeTestRule.onNodeWithTag(TEXT_FIELD_INPUT)
.fetchSemanticsNode()
.config[SemanticsProperties.EditableText].text, DISPLAY_NAME_1
)
}
@Test
fun showDialog_clearContent_showOriginalDisplayName() {
preSetupContent()
composeTestRule.setContent {
SimOnboardingLabelSimImpl(nextAction, cancelAction, mockSimOnboardingService)
}
composeTestRule.onNodeWithText(DISPLAY_NAME_1).performClick()
composeTestRule.onNodeWithTag(TEXT_FIELD_INPUT).performTextClearance()
assertEquals(
composeTestRule.onNodeWithTag(TEXT_FIELD_INPUT)
.fetchSemanticsNode()
.config[SemanticsProperties.EditableText].text, DISPLAY_NAME_1
)
}
@Test
fun showDialog_modifyContent_showModifiedDisplayName() {
val inputData = "input_data"
preSetupContent()
composeTestRule.setContent {
SimOnboardingLabelSimImpl(nextAction, cancelAction, mockSimOnboardingService)
}
composeTestRule.onNodeWithText(DISPLAY_NAME_1).performClick()
composeTestRule.onNodeWithTag(TEXT_FIELD_INPUT).performTextInput(inputData)
// Due to this TextField with Text and EditText, it need fetch correct node to get correct
// content.
assertEquals(
composeTestRule.onNodeWithTag(TEXT_FIELD_INPUT)
.fetchSemanticsNode()
.config[SemanticsProperties.EditableText].text, inputData + DISPLAY_NAME_1
)
// Click save button
composeTestRule.onNodeWithText(context.getString(R.string.mobile_network_sim_name_rename))
.performClick()
// Check preference's name is still DISPLAY_NAME_1
composeTestRule.onNodeWithText(inputData + DISPLAY_NAME_1).assertExists()
}
@Test
fun showDialog_onlySpaceCharContent_showAndSaveOriginalDisplayName() {
val spaceChars = " ";
preSetupContent()
composeTestRule.setContent {
SimOnboardingLabelSimImpl(nextAction, cancelAction, mockSimOnboardingService)
}
// Simulate real operation,
// 1. Click preference of DISPLAY_NAME_1
composeTestRule.onNodeWithText(DISPLAY_NAME_1).performClick()
// 2. Input space chars to EditText view
composeTestRule.onNodeWithTag(TEXT_FIELD_INPUT).performTextInput(spaceChars)
// 3. Remove the string of DISPLAY_NAME_1 from EditText view
repeat(DISPLAY_NAME_1.length) {
composeTestRule.onNodeWithTag(TEXT_FIELD_INPUT)
.performKeyPress(KeyEvent(NativeKeyEvent(ACTION_DOWN, KEYCODE_FORWARD_DEL)))
}
// Due to this TextField with Text and EditText, it need fetch correct node to get correct
// content.
assertEquals(
DISPLAY_NAME_1, composeTestRule.onNodeWithTag(TEXT_FIELD_INPUT)
.fetchSemanticsNode()
.config[SemanticsProperties.EditableText].text
)
// Click save button
composeTestRule.onNodeWithText(context.getString(R.string.mobile_network_sim_name_rename))
.performClick()
// Check preference's name is still DISPLAY_NAME_1
composeTestRule.onNodeWithText(DISPLAY_NAME_1).assertExists()
}
fun preSetupContent() {
mockSimOnboardingService.stub { mockSimOnboardingService.stub {
on { targetSubId }.doReturn(SUB_ID_1) on { targetSubId }.doReturn(SUB_ID_1)
on { targetSubInfo }.doReturn(SUB_INFO_1) on { targetSubInfo }.doReturn(SUB_INFO_1)
@@ -177,21 +284,10 @@ class SimOnboardingLabelSimTest {
on { getSubscriptionInfoDisplayName(SUB_INFO_2) }.doReturn(DISPLAY_NAME_2) on { getSubscriptionInfoDisplayName(SUB_INFO_2) }.doReturn(DISPLAY_NAME_2)
on { getSubscriptionInfoDisplayName(SUB_INFO_3) }.doReturn(DISPLAY_NAME_3) on { getSubscriptionInfoDisplayName(SUB_INFO_3) }.doReturn(DISPLAY_NAME_3)
} }
composeTestRule.setContent {
SimOnboardingLabelSimImpl(nextAction, cancelAction, mockSimOnboardingService)
}
composeTestRule.onNodeWithText(DISPLAY_NAME_1).performClick()
composeTestRule.onNodeWithText(
context.getString(R.string.sim_onboarding_label_sim_dialog_title)
)
.assertIsDisplayed()
} }
private companion object { private companion object {
const val TEXT_FIELD_INPUT = "contentInput"
const val SUB_ID_1 = 1 const val SUB_ID_1 = 1
const val SUB_ID_2 = 2 const val SUB_ID_2 = 2
const val SUB_ID_3 = 3 const val SUB_ID_3 = 3