Files
ShadowrunCharSheet/sharedUI/src/commonTest/kotlin/org/shahondin1624/EditDialogValidationTest.kt
T

275 lines
9.5 KiB
Kotlin

package org.shahondin1624
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.assertIsEnabled
import androidx.compose.ui.test.assertIsNotEnabled
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performTextClearance
import androidx.compose.ui.test.performTextInput
import androidx.compose.ui.test.runComposeUiTest
import org.shahondin1624.lib.components.TestTags
import org.shahondin1624.lib.components.charactermodel.CharacterDataEditDialog
import org.shahondin1624.lib.components.charactermodel.attributespage.AttributeEditDialog
import org.shahondin1624.model.attributes.Attribute
import org.shahondin1624.model.attributes.AttributeType
import org.shahondin1624.model.characterdata.CharacterData
import org.shahondin1624.model.characterdata.Metatype
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue
/**
* UI tests for edit dialog validation behavior:
* - AttributeEditDialog value bounds checking
* - CharacterDataEditDialog field validation
*/
@OptIn(ExperimentalTestApi::class)
class EditDialogValidationTest {
private val testAttribute = Attribute(AttributeType.Body, 3)
private val testCharacterData = CharacterData(
concept = "Test",
nuyen = 1000,
essence = 6.0f,
name = "Test Character",
metatype = Metatype.Human,
age = 25,
gender = "Female",
streetCred = 0,
notoriety = 0,
publicAwareness = 0,
totalKarma = 20,
currentKarma = 10
)
// ---- AttributeEditDialog validation ----
@Test
fun attributeEditDialogConfirmEnabledForValidValue() = runComposeUiTest {
setContent {
AttributeEditDialog(
attribute = testAttribute,
maxValue = 10,
onConfirm = {},
onDismiss = {}
)
}
// Default value (3) should be valid
onNodeWithTag(TestTags.ATTRIBUTE_EDIT_CONFIRM).assertIsEnabled()
}
@Test
fun attributeEditDialogConfirmDisabledWhenEmpty() = runComposeUiTest {
setContent {
AttributeEditDialog(
attribute = testAttribute,
maxValue = 10,
onConfirm = {},
onDismiss = {}
)
}
onNodeWithTag(TestTags.ATTRIBUTE_EDIT_INPUT).performTextClearance()
onNodeWithTag(TestTags.ATTRIBUTE_EDIT_CONFIRM).assertIsNotEnabled()
}
@Test
fun attributeEditDialogConfirmDisabledForZero() = runComposeUiTest {
setContent {
AttributeEditDialog(
attribute = testAttribute,
maxValue = 10,
onConfirm = {},
onDismiss = {}
)
}
onNodeWithTag(TestTags.ATTRIBUTE_EDIT_INPUT).performTextClearance()
onNodeWithTag(TestTags.ATTRIBUTE_EDIT_INPUT).performTextInput("0")
onNodeWithTag(TestTags.ATTRIBUTE_EDIT_CONFIRM).assertIsNotEnabled()
}
@Test
fun attributeEditDialogConfirmDisabledForValueExceedingMax() = runComposeUiTest {
setContent {
AttributeEditDialog(
attribute = testAttribute,
maxValue = 10,
onConfirm = {},
onDismiss = {}
)
}
onNodeWithTag(TestTags.ATTRIBUTE_EDIT_INPUT).performTextClearance()
onNodeWithTag(TestTags.ATTRIBUTE_EDIT_INPUT).performTextInput("15")
onNodeWithTag(TestTags.ATTRIBUTE_EDIT_CONFIRM).assertIsNotEnabled()
}
@Test
fun attributeEditDialogAcceptsMaxBoundaryValue() = runComposeUiTest {
setContent {
AttributeEditDialog(
attribute = testAttribute,
maxValue = 10,
onConfirm = {},
onDismiss = {}
)
}
onNodeWithTag(TestTags.ATTRIBUTE_EDIT_INPUT).performTextClearance()
onNodeWithTag(TestTags.ATTRIBUTE_EDIT_INPUT).performTextInput("10")
onNodeWithTag(TestTags.ATTRIBUTE_EDIT_CONFIRM).assertIsEnabled()
}
@Test
fun attributeEditDialogAcceptsMinBoundaryValue() = runComposeUiTest {
setContent {
AttributeEditDialog(
attribute = testAttribute,
maxValue = 10,
onConfirm = {},
onDismiss = {}
)
}
onNodeWithTag(TestTags.ATTRIBUTE_EDIT_INPUT).performTextClearance()
onNodeWithTag(TestTags.ATTRIBUTE_EDIT_INPUT).performTextInput("1")
onNodeWithTag(TestTags.ATTRIBUTE_EDIT_CONFIRM).assertIsEnabled()
}
// ---- CharacterDataEditDialog validation ----
@Test
fun characterDataEditConfirmEnabledForValidData() = runComposeUiTest {
setContent {
CharacterDataEditDialog(
characterData = testCharacterData,
onConfirm = {},
onDismiss = {}
)
}
// Default valid data should enable confirm
onNodeWithTag(TestTags.CHARACTER_DATA_EDIT_CONFIRM).assertIsEnabled()
}
@Test
fun characterDataEditConfirmDisabledWhenNameEmpty() = runComposeUiTest {
setContent {
CharacterDataEditDialog(
characterData = testCharacterData,
onConfirm = {},
onDismiss = {}
)
}
onNodeWithTag(TestTags.CHARACTER_DATA_EDIT_NAME).performTextClearance()
onNodeWithTag(TestTags.CHARACTER_DATA_EDIT_CONFIRM).assertIsNotEnabled()
}
@Test
fun characterDataEditConfirmDisabledWhenAgeEmpty() = runComposeUiTest {
setContent {
CharacterDataEditDialog(
characterData = testCharacterData,
onConfirm = {},
onDismiss = {}
)
}
onNodeWithTag(TestTags.CHARACTER_DATA_EDIT_AGE).performTextClearance()
onNodeWithTag(TestTags.CHARACTER_DATA_EDIT_CONFIRM).assertIsNotEnabled()
}
@Test
fun characterDataEditConfirmDisabledWhenNuyenEmpty() = runComposeUiTest {
setContent {
CharacterDataEditDialog(
characterData = testCharacterData,
onConfirm = {},
onDismiss = {}
)
}
onNodeWithTag(TestTags.CHARACTER_DATA_EDIT_NUYEN).performTextClearance()
onNodeWithTag(TestTags.CHARACTER_DATA_EDIT_CONFIRM).assertIsNotEnabled()
}
@Test
fun characterDataEditConfirmDisabledWhenEssenceEmpty() = runComposeUiTest {
setContent {
CharacterDataEditDialog(
characterData = testCharacterData,
onConfirm = {},
onDismiss = {}
)
}
onNodeWithTag(TestTags.CHARACTER_DATA_EDIT_ESSENCE).performTextClearance()
onNodeWithTag(TestTags.CHARACTER_DATA_EDIT_CONFIRM).assertIsNotEnabled()
}
@Test
fun characterDataEditConfirmDisabledWhenCurrentKarmaExceedsTotalKarma() = runComposeUiTest {
setContent {
CharacterDataEditDialog(
characterData = testCharacterData.copy(totalKarma = 10, currentKarma = 5),
onConfirm = {},
onDismiss = {}
)
}
// Set current karma higher than total karma
onNodeWithTag(TestTags.CHARACTER_DATA_EDIT_CURRENT_KARMA).performTextClearance()
onNodeWithTag(TestTags.CHARACTER_DATA_EDIT_CURRENT_KARMA).performTextInput("15")
onNodeWithTag(TestTags.CHARACTER_DATA_EDIT_CONFIRM).assertIsNotEnabled()
}
// ---- Validation logic unit tests (non-UI) ----
@Test
fun characterDataValidationNameNotBlank() {
val valid = testCharacterData.copy(name = "Valid Name")
assertTrue(valid.name.isNotBlank(), "Name should be valid when not blank")
val invalid = testCharacterData.copy(name = "")
assertFalse(invalid.name.isNotBlank(), "Empty name should be invalid")
val whitespace = testCharacterData.copy(name = " ")
assertFalse(whitespace.name.isNotBlank(), "Whitespace-only name should be invalid")
}
@Test
fun characterDataValidationEssenceRange() {
// Valid range: 0.0 to 6.0
assertTrue(0.0f in 0.0f..6.0f, "0.0 should be valid")
assertTrue(6.0f in 0.0f..6.0f, "6.0 should be valid")
assertTrue(3.5f in 0.0f..6.0f, "3.5 should be valid")
assertFalse(-0.1f in 0.0f..6.0f, "Negative essence should be invalid")
assertFalse(6.1f in 0.0f..6.0f, "Essence > 6.0 should be invalid")
}
@Test
fun characterDataValidationKarmaConstraint() {
// currentKarma must be <= totalKarma
val valid = testCharacterData.copy(totalKarma = 50, currentKarma = 30)
assertTrue(valid.currentKarma <= valid.totalKarma, "Current <= total should be valid")
val equal = testCharacterData.copy(totalKarma = 50, currentKarma = 50)
assertTrue(equal.currentKarma <= equal.totalKarma, "Current == total should be valid")
val invalid = testCharacterData.copy(totalKarma = 50, currentKarma = 51)
assertFalse(invalid.currentKarma <= invalid.totalKarma, "Current > total should be invalid")
}
@Test
fun characterDataValidationNonNegativeFields() {
assertTrue(testCharacterData.age >= 0, "Age should be non-negative")
assertTrue(testCharacterData.nuyen >= 0, "Nuyen should be non-negative")
assertTrue(testCharacterData.totalKarma >= 0, "Total karma should be non-negative")
assertTrue(testCharacterData.currentKarma >= 0, "Current karma should be non-negative")
}
}