diff --git a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/Lists.kt b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/Lists.kt index 88ba6ad90..20f378cfb 100644 --- a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/Lists.kt +++ b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/Lists.kt @@ -19,6 +19,10 @@ import androidx.compose.material.MaterialTheme import androidx.compose.material.Switch import androidx.compose.material.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -34,6 +38,8 @@ import com.telefonica.mistica.catalog.R import com.telefonica.mistica.compose.list.BackgroundType import com.telefonica.mistica.compose.list.ListRowIcon import com.telefonica.mistica.compose.list.ListRowItem +import com.telefonica.mistica.compose.list.ListRowItemWithCheckBox +import com.telefonica.mistica.compose.list.ListRowItemWithSwitch import com.telefonica.mistica.compose.shape.Chevron import com.telefonica.mistica.compose.tag.Tag import com.telefonica.mistica.compose.theme.MisticaTheme @@ -209,13 +215,14 @@ fun samples() = listOf( ), ListItem( headline = Tag("PROMO").withStyle(TYPE_PROMO), - title = TITLE, + title = "$TITLE clickable", subtitle = SUBTITLE, description = DESCRIPTION, action = { Chevron() }, isBadgeVisible = true, badge = "1", listRowIcon = ListRowIcon.SmallAsset(painter = painterResource(id = R.drawable.list_row_drawable)), + onClick = { println("do nothing") }, ), ListItem( headline = Tag("PROMO").withStyle(TYPE_PROMO), @@ -378,13 +385,36 @@ fun Lists() { SectionTitle("Clickable Asset") ClickableAssetSample( context = context, - onRowClick = {}, + onRowClick = null, ) ClickableAssetSample( context = context, onRowClick = { Toast.makeText(context, "Row Clicked", Toast.LENGTH_SHORT).show() }, ) } + item { + SectionTitle("Toggleables") + var switchState by remember { + mutableStateOf(false) + } + ListRowItemWithSwitch( + title = "Title", + subtitle = "Subtitle", + checked = switchState, + onCheckedChange = { switchState = it }, + listRowIcon = ListRowIcon.NormalIcon(painter = painterResource(id = R.drawable.ic_lists)), + ) + var checkBoxState by remember { + mutableStateOf(false) + } + ListRowItemWithCheckBox( + title = "Title", + subtitle = "Subtitle", + checked = checkBoxState, + onCheckedChange = { checkBoxState = it }, + listRowIcon = ListRowIcon.NormalIcon(painter = painterResource(id = R.drawable.ic_lists)), + ) + } } } @@ -451,9 +481,9 @@ private fun CustomSlot() { } @Composable -private fun ClickableAssetSample(context: Context, onRowClick: () -> Unit) { +private fun ClickableAssetSample(context: Context, onRowClick: (() -> Unit)? = null) { ListRowItem( - title = "Clickable Asset in Clickable Row", + title = if (onRowClick != null) "Clickable Asset in Clickable Row" else "Clickable Asset", subtitle = "Subtitle", description = "Description", isBadgeVisible = true, @@ -461,6 +491,7 @@ private fun ClickableAssetSample(context: Context, onRowClick: () -> Unit) { onClick = onRowClick, listRowIcon = ListRowIcon.CircleIcon( painterResource(id = R.drawable.ic_lists), + description = "Clickable asset", backgroundColor = MisticaTheme.colors.backgroundAlternative, modifier = Modifier.clickable { Toast.makeText(context, "Asset Clicked", Toast.LENGTH_SHORT).show() diff --git a/library/screenshots/check_ListRowItemWithCheckBox_Off.png b/library/screenshots/check_ListRowItemWithCheckBox_Off.png new file mode 100644 index 000000000..71bc3fb4b Binary files /dev/null and b/library/screenshots/check_ListRowItemWithCheckBox_Off.png differ diff --git a/library/screenshots/check_ListRowItemWithCheckBox_On.png b/library/screenshots/check_ListRowItemWithCheckBox_On.png new file mode 100644 index 000000000..fb87d16ba Binary files /dev/null and b/library/screenshots/check_ListRowItemWithCheckBox_On.png differ diff --git a/library/screenshots/check_ListRowItemWithSwitch_Off.png b/library/screenshots/check_ListRowItemWithSwitch_Off.png new file mode 100644 index 000000000..dcd5063af Binary files /dev/null and b/library/screenshots/check_ListRowItemWithSwitch_Off.png differ diff --git a/library/screenshots/check_ListRowItemWithSwitch_On.png b/library/screenshots/check_ListRowItemWithSwitch_On.png new file mode 100644 index 000000000..adf0891fd Binary files /dev/null and b/library/screenshots/check_ListRowItemWithSwitch_On.png differ diff --git a/library/src/main/java/com/telefonica/mistica/compose/badge/Badge.kt b/library/src/main/java/com/telefonica/mistica/compose/badge/Badge.kt index 074853b42..3a6e4fc68 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/badge/Badge.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/badge/Badge.kt @@ -6,12 +6,15 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.Badge as MaterialBadge import androidx.compose.material.Surface import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.testTag +import androidx.compose.ui.semantics.contentDescription +import androidx.compose.ui.semantics.semantics import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp @@ -24,6 +27,7 @@ fun Badge( modifier: Modifier = Modifier, textSize: TextUnit = TextUnit.Unspecified, content: String? = null, + contentDescription: String? = null, ) { if (content.isNullOrEmpty()) { Surface( @@ -39,7 +43,14 @@ fun Badge( modifier = modifier.testTag(BadgeTestTags.BADGE_NUMBER), ) { Text( - modifier = Modifier.testTag(BadgeTestTags.BADGE_NUMBER_VALUE), + modifier = Modifier + .testTag(BadgeTestTags.BADGE_NUMBER_VALUE) + .then( + if (contentDescription != null) + Modifier.semantics { this.contentDescription = contentDescription } + else + Modifier + ), text = getBadgeContent(content), fontSize = textSize, color = MisticaTheme.colors.textPrimaryInverse, diff --git a/library/src/main/java/com/telefonica/mistica/compose/input/PasswordInput.kt b/library/src/main/java/com/telefonica/mistica/compose/input/PasswordInput.kt index a0bc0ccee..81806e30a 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/input/PasswordInput.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/input/PasswordInput.kt @@ -15,6 +15,8 @@ import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.tooling.preview.Preview import com.telefonica.mistica.R +import com.telefonica.mistica.compose.theme.MisticaTheme +import com.telefonica.mistica.compose.theme.brand.MovistarBrand @Composable fun PasswordInput( @@ -86,38 +88,46 @@ private fun PasswordVisibleIcon( @Preview(showBackground = true) @Composable fun PreviewEmptyPasswordInput() { - PasswordInput( - value = "", - onValueChange = {}, - label = "empty", - ) + MisticaTheme(brand = MovistarBrand) { + PasswordInput( + value = "", + onValueChange = {}, + label = "empty", + ) + } } @Preview(showBackground = true) @Composable fun PreviewPasswordInput() { - PasswordInput( - value = "value", - onValueChange = {}, - label = "label", - ) + MisticaTheme(brand = MovistarBrand) { + PasswordInput( + value = "value", + onValueChange = {}, + label = "label", + ) + } } @Preview(showBackground = true) @Composable fun PreviewPasswordVisibleIconVisible() { - PasswordVisibleIcon( - passwordVisible = true, - onIconClicked = {}, - ) + MisticaTheme(brand = MovistarBrand) { + PasswordVisibleIcon( + passwordVisible = true, + onIconClicked = {}, + ) + } } @Preview(showBackground = true) @Composable fun PreviewPasswordVisibleIconInVisible() { - PasswordVisibleIcon( - passwordVisible = false, - onIconClicked = {}, - ) + MisticaTheme(brand = MovistarBrand) { + PasswordVisibleIcon( + passwordVisible = false, + onIconClicked = {}, + ) + } } diff --git a/library/src/main/java/com/telefonica/mistica/compose/list/ListRowItem.kt b/library/src/main/java/com/telefonica/mistica/compose/list/ListRowItem.kt index 7f604fd16..5eec1d0c9 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/list/ListRowItem.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/list/ListRowItem.kt @@ -29,9 +29,12 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.semantics.heading +import androidx.compose.ui.semantics.isTraversalGroup import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.semantics.traversalIndex import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.compose.ui.zIndex import com.telefonica.mistica.R import com.telefonica.mistica.compose.badge.Badge import com.telefonica.mistica.compose.shape.Chevron @@ -50,6 +53,7 @@ fun ListRowItem( backgroundType: BackgroundType = BackgroundType.TYPE_NORMAL, badge: String? = null, isBadgeVisible: Boolean = false, + isToggleable: Boolean = false, headline: Tag? = null, trailing: @Composable (() -> Unit)? = null, onClick: (() -> Unit)? = null, @@ -66,6 +70,7 @@ fun ListRowItem( backgroundType = backgroundType, badge = badge, isBadgeVisible = isBadgeVisible, + isToggleable = isToggleable, headline = headline, trailing = trailing, onClick = onClick, @@ -111,7 +116,7 @@ fun ListRowItem( } @Composable -private fun ListRowItemImp( +internal fun ListRowItemImp( modifier: Modifier = Modifier, icon: @Composable (() -> Unit)? = null, title: String? = null, @@ -121,6 +126,7 @@ private fun ListRowItemImp( backgroundType: BackgroundType = BackgroundType.TYPE_NORMAL, badge: String? = null, isBadgeVisible: Boolean = false, + isToggleable: Boolean = false, headline: Tag? = null, trailing: @Composable (() -> Unit)? = null, onClick: (() -> Unit)? = null, @@ -182,10 +188,14 @@ private fun ListRowItemImp( } Box( - modifier = boxModifier.testTag(ListRowItemTestTags.LIST_ROW_ITEM) + modifier = boxModifier + .testTag(ListRowItemTestTags.LIST_ROW_ITEM) + .semantics(mergeDescendants = isToggleable) { } ) { Row( - modifier = rowModifier.height(IntrinsicSize.Min) + modifier = rowModifier + .height(IntrinsicSize.Min) + .semantics { isTraversalGroup = true }, ) { if (icon != null) { Box(modifier = Modifier.testTag(ListRowItemTestTags.LIST_ROW_ITEM_ICON)) { @@ -198,10 +208,16 @@ private fun ListRowItemImp( modifier = Modifier .weight(1f) .absolutePadding(right = 16.dp) - .align(CenterVertically) + .align(CenterVertically), ) { headline?.let { - it.build() + it + .withModifier( + modifier = Modifier + .semantics { traversalIndex = 2f } + .zIndex(2f) + ) + .build() Spacer(modifier = Modifier.height(8.dp)) } title?.let { @@ -211,6 +227,8 @@ private fun ListRowItemImp( color = textColorPrimary, modifier = Modifier .testTag(ListRowItemTestTags.LIST_ROW_ITEM_TITLE) + .semantics { traversalIndex = 1f } + .zIndex(1f) .then( if (isTitleHeading) { Modifier.semantics { heading() } @@ -227,6 +245,8 @@ private fun ListRowItemImp( color = textColorPrimary, modifier = Modifier .testTag(ListRowItemTestTags.LIST_ROW_ITEM_SUBTITLE) + .semantics { traversalIndex = 3f } + .zIndex(3f) .padding(vertical = 2.dp) .defaultMinSize(minHeight = 20.dp), ) @@ -238,13 +258,21 @@ private fun ListRowItemImp( color = textColorSecondary, modifier = Modifier .testTag(ListRowItemTestTags.LIST_ROW_ITEM_DESCRIPTION) + .semantics { traversalIndex = 4f } + .zIndex(4f) .padding(vertical = 2.dp) .defaultMinSize(minHeight = 20.dp), ) } bottom?.let { Spacer(modifier = Modifier.height(2.dp)) - bottom() + Box( + modifier = Modifier + .semantics(mergeDescendants = !isToggleable) { traversalIndex = 5f } + .zIndex(5f) + ) { + bottom() + } } } @@ -252,6 +280,8 @@ private fun ListRowItemImp( val badgeModifier = Modifier .align(CenterVertically) .absolutePadding(0.dp, 0.dp, 16.dp, 0.dp) + .semantics(mergeDescendants = !isToggleable) { traversalIndex = 6f } + .zIndex(6f) Badge( modifier = badgeModifier, content = badge, @@ -259,7 +289,12 @@ private fun ListRowItemImp( } trailing?.let { - Column(modifier = Modifier.align(CenterVertically)) { + Column( + modifier = Modifier + .align(CenterVertically) + .semantics { traversalIndex = 7f } + .zIndex(7f) + ) { it() } } diff --git a/library/src/main/java/com/telefonica/mistica/compose/list/ListRowItemWithCheckBox.kt b/library/src/main/java/com/telefonica/mistica/compose/list/ListRowItemWithCheckBox.kt new file mode 100644 index 000000000..47ca2daa5 --- /dev/null +++ b/library/src/main/java/com/telefonica/mistica/compose/list/ListRowItemWithCheckBox.kt @@ -0,0 +1,86 @@ +package com.telefonica.mistica.compose.list + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.selection.toggleable +import androidx.compose.material.Checkbox +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.semantics.Role +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.telefonica.mistica.compose.tag.Tag +import com.telefonica.mistica.compose.theme.MisticaTheme +import com.telefonica.mistica.compose.theme.brand.MovistarBrand + +@Composable +fun ListRowItemWithCheckBox( + modifier: Modifier = Modifier, + listRowIcon: ListRowIcon? = null, + title: String? = null, + isTitleHeading: Boolean = false, + subtitle: String? = null, + description: String? = null, + backgroundType: BackgroundType = BackgroundType.TYPE_NORMAL, + badge: String? = null, + isBadgeVisible: Boolean = false, + headline: Tag? = null, + checked: Boolean = false, + onCheckedChange: (Boolean) -> Unit, + bottom: @Composable (() -> Unit)? = null, + contentPadding: PaddingValues = PaddingValues(horizontal = 16.dp, vertical = 8.dp), +) { + ListRowItemImp( + modifier = modifier.toggleable( + value = checked, + onValueChange = { onCheckedChange(!checked) }, + role = Role.Checkbox, + ), + icon = { listRowIcon?.Draw() }, + title = title, + isTitleHeading = isTitleHeading, + subtitle = subtitle, + description = description, + backgroundType = backgroundType, + badge = badge, + isBadgeVisible = isBadgeVisible, + isToggleable = true, + headline = headline, + trailing = { + Checkbox( + checked = checked, + onCheckedChange = null, + ) + }, + onClick = null, + bottom = bottom, + contentPadding = contentPadding + ) +} + +@Preview(showBackground = true) +@Composable +private fun PreviewListRowItemWithCheckBoxUnchecked() { + MisticaTheme(brand = MovistarBrand) { + ListRowItemWithCheckBox( + title = "Unchecked", + subtitle = "Subtitle", + description = "Description", + checked = false, + onCheckedChange = {}, + ) + } +} + +@Preview(showBackground = true) +@Composable +private fun PreviewListRowItemWithCheckBoxChecked() { + MisticaTheme(brand = MovistarBrand) { + ListRowItemWithCheckBox( + title = "Checked", + subtitle = "Subtitle", + description = "Description", + checked = true, + onCheckedChange = {}, + ) + } +} diff --git a/library/src/main/java/com/telefonica/mistica/compose/list/ListRowItemWithSwitch.kt b/library/src/main/java/com/telefonica/mistica/compose/list/ListRowItemWithSwitch.kt new file mode 100644 index 000000000..01e12b4b4 --- /dev/null +++ b/library/src/main/java/com/telefonica/mistica/compose/list/ListRowItemWithSwitch.kt @@ -0,0 +1,86 @@ +package com.telefonica.mistica.compose.list + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.selection.toggleable +import androidx.compose.material.Switch +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.semantics.Role +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.telefonica.mistica.compose.tag.Tag +import com.telefonica.mistica.compose.theme.MisticaTheme +import com.telefonica.mistica.compose.theme.brand.MovistarBrand + +@Composable +fun ListRowItemWithSwitch( + modifier: Modifier = Modifier, + listRowIcon: ListRowIcon? = null, + title: String? = null, + isTitleHeading: Boolean = false, + subtitle: String? = null, + description: String? = null, + backgroundType: BackgroundType = BackgroundType.TYPE_NORMAL, + badge: String? = null, + isBadgeVisible: Boolean = false, + headline: Tag? = null, + checked: Boolean = false, + onCheckedChange: (Boolean) -> Unit, + bottom: @Composable (() -> Unit)? = null, + contentPadding: PaddingValues = PaddingValues(horizontal = 16.dp, vertical = 8.dp), +) { + ListRowItemImp( + modifier = modifier.toggleable( + value = checked, + onValueChange = { onCheckedChange(!checked) }, + role = Role.Switch, + ), + icon = { listRowIcon?.Draw() }, + title = title, + isTitleHeading = isTitleHeading, + subtitle = subtitle, + description = description, + backgroundType = backgroundType, + badge = badge, + isBadgeVisible = isBadgeVisible, + isToggleable = true, + headline = headline, + trailing = { + Switch( + checked = checked, + onCheckedChange = null, + ) + }, + onClick = null, + bottom = bottom, + contentPadding = contentPadding + ) +} + +@Preview(showBackground = true) +@Composable +private fun PreviewListRowItemWithSwitchOff() { + MisticaTheme(brand = MovistarBrand) { + ListRowItemWithSwitch( + title = "Off", + subtitle = "Subtitle", + description = "Description", + checked = false, + onCheckedChange = {}, + ) + } +} + +@Preview(showBackground = true) +@Composable +private fun PreviewListRowItemWithSwitchOn() { + MisticaTheme(brand = MovistarBrand) { + ListRowItemWithSwitch( + title = "On", + subtitle = "Subtitle", + description = "Description", + checked = true, + onCheckedChange = {}, + ) + } +} diff --git a/library/src/main/java/com/telefonica/mistica/compose/list/README.md b/library/src/main/java/com/telefonica/mistica/compose/list/README.md index 639c953bd..88e96e61b 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/list/README.md +++ b/library/src/main/java/com/telefonica/mistica/compose/list/README.md @@ -150,3 +150,25 @@ Any `@Composable` is allowed to be used as `trailing` parameter. This will show } ) ``` + +## Toggleables +There is two new sub-components from ListRowView to handle Action Layouts with toggleable views like Switch or CheckBox components. +Take a look to the new available sub-components: +* [ListRowViewWithSwitch](ListRowItemWithSwitch.kt) +* [ListRowViewWithCheckBox](ListRowItemWithCheckBox.kt) + +This two new sub-components have been created in order to handle the main accessibility actions according to Google standards with Toggleable views. +So please, consider replacing and start using these two new sub-components if you need to use a list element with a Switch or CheckBox view. + +```kotlin +var switchState by remember { + mutableStateOf(false) +} +ListRowItemWithSwitch( + title = "Title", + subtitle = "Subtitle", + checked = switchState, + onCheckedChange = { switchState = it }, + listRowIcon = ListRowIcon.NormalIcon(painter = painterResource(id = R.drawable.ic_lists)), +) +``` diff --git a/library/src/test/java/com/telefonica/mistica/compose/list/ListRowItemWithCheckBoxTest.kt b/library/src/test/java/com/telefonica/mistica/compose/list/ListRowItemWithCheckBoxTest.kt new file mode 100644 index 000000000..5f1e24520 --- /dev/null +++ b/library/src/test/java/com/telefonica/mistica/compose/list/ListRowItemWithCheckBoxTest.kt @@ -0,0 +1,92 @@ +package com.telefonica.mistica.compose.list + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.test.assertIsOff +import androidx.compose.ui.test.assertIsOn +import androidx.compose.ui.test.isToggleable +import androidx.compose.ui.test.junit4.createComposeRule +import androidx.compose.ui.test.onRoot +import androidx.compose.ui.test.performClick +import com.telefonica.mistica.compose.tag.Tag +import com.telefonica.mistica.compose.theme.MisticaTheme +import com.telefonica.mistica.compose.theme.brand.MovistarBrand +import com.telefonica.mistica.testutils.ScreenshotsTest +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner + +@RunWith(RobolectricTestRunner::class) +internal class ListRowItemWithCheckBoxTest : ScreenshotsTest() { + + @get:Rule + val composeTestRule = createComposeRule() + + @Test + fun `check ListRowItemWithCheckBox Off`() { + `when ListRowItemWithCheckBox`(checked = false) + + `then is NOT checked`() + `then screenshot is OK`() + } + + @Test + fun `check ListRowItemWithCheckBox On`() { + `when ListRowItemWithCheckBox`(checked = true) + + `then is checked`() + `then screenshot is OK`() + } + + @Test + fun `check ListRowItemWithCheckBox state change`() { + `given ListRowItemWithCheckBox`(checked = false) + `given is NOT checked`() + + `when toggling the state`() + + `then is checked`() + } + + private fun `given ListRowItemWithCheckBox`(checked: Boolean = false) = + `when ListRowItemWithCheckBox`(checked) + + private fun `given is NOT checked`() = + `then is NOT checked`() + + private fun `when ListRowItemWithCheckBox`(checked: Boolean = false) { + composeTestRule.setContent { + var isChecked by remember { mutableStateOf(checked) } + MisticaTheme(brand = MovistarBrand) { + ListRowItemWithCheckBox( + listRowIcon = null, + headline = Tag("Promo"), + title = "title", + subtitle = "Subtitle", + description = "Description", + checked = isChecked, + onCheckedChange = { isChecked = it}, + ) + } + } + } + + private fun `when toggling the state`() { + composeTestRule.onNode(isToggleable()).performClick() + } + + private fun `then screenshot is OK`() { + compareScreenshot(composeTestRule.onRoot()) + } + + private fun `then is NOT checked`() { + composeTestRule.onNode(isToggleable()).assertIsOff() + } + + private fun `then is checked`() { + composeTestRule.onNode(isToggleable()).assertIsOn() + } +} diff --git a/library/src/test/java/com/telefonica/mistica/compose/list/ListRowItemWithSwitchTest.kt b/library/src/test/java/com/telefonica/mistica/compose/list/ListRowItemWithSwitchTest.kt new file mode 100644 index 000000000..3b4d52fed --- /dev/null +++ b/library/src/test/java/com/telefonica/mistica/compose/list/ListRowItemWithSwitchTest.kt @@ -0,0 +1,92 @@ +package com.telefonica.mistica.compose.list + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.test.assertIsOff +import androidx.compose.ui.test.assertIsOn +import androidx.compose.ui.test.isToggleable +import androidx.compose.ui.test.junit4.createComposeRule +import androidx.compose.ui.test.onRoot +import androidx.compose.ui.test.performClick +import com.telefonica.mistica.compose.tag.Tag +import com.telefonica.mistica.compose.theme.MisticaTheme +import com.telefonica.mistica.compose.theme.brand.MovistarBrand +import com.telefonica.mistica.testutils.ScreenshotsTest +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner + +@RunWith(RobolectricTestRunner::class) +internal class ListRowItemWithSwitchTest : ScreenshotsTest() { + + @get:Rule + val composeTestRule = createComposeRule() + + @Test + fun `check ListRowItemWithSwitch Off`() { + `when ListRowItemWithSwitch`(checked = false) + + `then is NOT checked`() + `then screenshot is OK`() + } + + @Test + fun `check ListRowItemWithSwitch On`() { + `when ListRowItemWithSwitch`(checked = true) + + `then is checked`() + `then screenshot is OK`() + } + + @Test + fun `check ListRowItemWithSwitch state change`() { + `given ListRowItemWithSwitch`(checked = false) + `given is NOT checked`() + + `when toggling the state`() + + `then is checked`() + } + + private fun `given ListRowItemWithSwitch`(checked: Boolean = false) = + `when ListRowItemWithSwitch`(checked) + + private fun `given is NOT checked`() = + `then is NOT checked`() + + private fun `when ListRowItemWithSwitch`(checked: Boolean = false) { + composeTestRule.setContent { + var isChecked by remember { mutableStateOf(checked) } + MisticaTheme(brand = MovistarBrand) { + ListRowItemWithSwitch( + listRowIcon = null, + headline = Tag("Promo"), + title = "title", + subtitle = "Subtitle", + description = "Description", + checked = isChecked, + onCheckedChange = { isChecked = it}, + ) + } + } + } + + private fun `when toggling the state`() { + composeTestRule.onNode(isToggleable()).performClick() + } + + private fun `then screenshot is OK`() { + compareScreenshot(composeTestRule.onRoot()) + } + + private fun `then is NOT checked`() { + composeTestRule.onNode(isToggleable()).assertIsOff() + } + + private fun `then is checked`() { + composeTestRule.onNode(isToggleable()).assertIsOn() + } +}