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:
@@ -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
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user