Cover all auth tests

This commit is contained in:
Alex Gabor 2022-04-01 16:06:35 +03:00
parent d948d06378
commit d9725e31e6
4 changed files with 110 additions and 13 deletions

View file

@ -2,6 +2,7 @@ package org.fnives.test.showcase.ui
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.fnives.test.showcase.R
import org.fnives.test.showcase.compose.ComposeActivity
import org.fnives.test.showcase.network.mockserver.scenario.auth.AuthScenario
import org.fnives.test.showcase.testutils.MockServerScenarioSetupResetingTestRule
@ -25,7 +26,7 @@ class AuthComposeInstrumentedTest : KoinTest {
private val mockServerScenarioSetup get() = mockServerScenarioSetupTestRule.mockServerScenarioSetup
private val mainDispatcherTestRule = ComposeMainDispatcherTestRule()
private lateinit var robot: ComposeLoginRobot
private lateinit var screenRobot: ComposeScreenRobot
private lateinit var navigationRobot: ComposeNavigationRobot
@Rule
@JvmField
@ -36,7 +37,7 @@ class AuthComposeInstrumentedTest : KoinTest {
@Before
fun setup() {
robot = ComposeLoginRobot(composeTestRule)
screenRobot = ComposeScreenRobot(composeTestRule)
navigationRobot = ComposeNavigationRobot(composeTestRule)
}
/** GIVEN non empty password and username and successful response WHEN signIn THEN no error is shown and navigating to home */
@ -47,9 +48,8 @@ class AuthComposeInstrumentedTest : KoinTest {
)
composeTestRule.mainClock.advanceTimeBy(500L)
composeTestRule.mainClock.advanceTimeUntil { anyResourceIdling() }
screenRobot.assertAuthScreen()
robot
.setPassword("alma")
navigationRobot.assertAuthScreen()
robot.setPassword("alma")
.setUsername("banan")
.assertUsername("banan")
.assertPassword("alma")
@ -61,7 +61,93 @@ class AuthComposeInstrumentedTest : KoinTest {
composeTestRule.mainClock.autoAdvance = true
composeTestRule.mainClock.advanceTimeUntil { anyResourceIdling() }
screenRobot.assertHomeScreen()
navigationRobot.assertHomeScreen()
}
/** GIVEN empty password and username WHEN signIn THEN error password is shown */
@Test
fun emptyPasswordShowsProperErrorMessage() {
composeTestRule.mainClock.advanceTimeBy(500L)
composeTestRule.mainClock.advanceTimeUntil { anyResourceIdling() }
navigationRobot.assertAuthScreen()
robot.setUsername("banan")
.assertUsername("banan")
.clickOnLogin()
composeTestRule.mainClock.advanceTimeUntil { anyResourceIdling() }
robot.assertErrorIsShown(R.string.password_is_invalid)
.assertNotLoading()
navigationRobot.assertAuthScreen()
}
/** GIVEN password and empty username WHEN signIn THEN error username is shown */
@Test
fun emptyUserNameShowsProperErrorMessage() {
composeTestRule.mainClock.advanceTimeBy(500L)
composeTestRule.mainClock.advanceTimeUntil { anyResourceIdling() }
navigationRobot.assertAuthScreen()
robot
.setPassword("banan")
.assertPassword("banan")
.clickOnLogin()
composeTestRule.mainClock.advanceTimeUntil { anyResourceIdling() }
robot.assertErrorIsShown(R.string.username_is_invalid)
.assertNotLoading()
navigationRobot.assertAuthScreen()
}
/** GIVEN password and username and invalid credentials response WHEN signIn THEN error invalid credentials is shown */
@Test
fun invalidCredentialsGivenShowsProperErrorMessage() {
mockServerScenarioSetup.setScenario(
AuthScenario.InvalidCredentials(password = "alma", username = "banan")
)
composeTestRule.mainClock.advanceTimeBy(500L)
composeTestRule.mainClock.advanceTimeUntil { anyResourceIdling() }
navigationRobot.assertAuthScreen()
robot.setUsername("alma")
.setPassword("banan")
.assertUsername("alma")
.assertPassword("banan")
composeTestRule.mainClock.autoAdvance = false
robot.clickOnLogin()
composeTestRule.mainClock.advanceTimeByFrame()
robot.assertLoading()
composeTestRule.mainClock.autoAdvance = true
composeTestRule.mainClock.advanceTimeUntil { anyResourceIdling() }
robot.assertErrorIsShown(R.string.credentials_invalid)
.assertNotLoading()
navigationRobot.assertAuthScreen()
}
/** GIVEN password and username and error response WHEN signIn THEN error invalid credentials is shown */
@Test
fun networkErrorShowsProperErrorMessage() {
mockServerScenarioSetup.setScenario(
AuthScenario.GenericError(username = "alma", password = "banan")
)
composeTestRule.mainClock.advanceTimeBy(500L)
composeTestRule.mainClock.advanceTimeUntil { anyResourceIdling() }
navigationRobot.assertAuthScreen()
robot.setUsername("alma")
.setPassword("banan")
.assertUsername("alma")
.assertPassword("banan")
composeTestRule.mainClock.autoAdvance = false
robot.clickOnLogin()
composeTestRule.mainClock.advanceTimeByFrame()
robot.assertLoading()
composeTestRule.mainClock.autoAdvance = true
composeTestRule.mainClock.advanceTimeUntil { anyResourceIdling() }
robot.assertErrorIsShown(R.string.something_went_wrong)
.assertNotLoading()
navigationRobot.assertAuthScreen()
}
}

View file

@ -1,7 +1,9 @@
package org.fnives.test.showcase.ui
import android.content.Context
import androidx.compose.ui.test.*
import androidx.compose.ui.test.junit4.ComposeTestRule
import androidx.test.core.app.ApplicationProvider
import org.fnives.test.showcase.compose.screen.auth.AuthScreenTag
class ComposeLoginRobot(
@ -34,4 +36,13 @@ class ComposeLoginRobot(
fun assertLoading(): ComposeLoginRobot = apply {
composeTestRule.onNodeWithTag(AuthScreenTag.LoadingIndicator).assertIsDisplayed()
}
fun assertNotLoading(): ComposeLoginRobot = apply {
composeTestRule.onAllNodesWithTag(AuthScreenTag.LoadingIndicator).assertCountEquals(0)
}
fun assertErrorIsShown(stringId: Int): ComposeLoginRobot = apply {
composeTestRule.onNodeWithTag(AuthScreenTag.LoginError)
.assertTextContains(ApplicationProvider.getApplicationContext<Context>().resources.getString(stringId))
}
}

View file

@ -1,19 +1,18 @@
package org.fnives.test.showcase.ui
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.ComposeTestRule
import androidx.compose.ui.test.onNodeWithTag
import org.fnives.test.showcase.compose.screen.AppNavigationTag
class ComposeScreenRobot(
class ComposeNavigationRobot(
private val composeTestRule: ComposeTestRule,
) {
fun assertHomeScreen(): ComposeScreenRobot = apply {
composeTestRule.onNodeWithTag(AppNavigationTag.HomeScreen).assertIsDisplayed()
fun assertHomeScreen(): ComposeNavigationRobot = apply {
composeTestRule.onNodeWithTag(AppNavigationTag.HomeScreen).assertExists()
}
fun assertAuthScreen(): ComposeScreenRobot = apply {
composeTestRule.onNodeWithTag(AppNavigationTag.AuthScreen).assertIsDisplayed()
fun assertAuthScreen(): ComposeNavigationRobot = apply {
composeTestRule.onNodeWithTag(AppNavigationTag.AuthScreen).assertExists()
}
}

View file

@ -135,7 +135,7 @@ private fun Snackbar(authScreenState: AuthScreenState, modifier: Modifier = Modi
val stringId = error?.stringResId()
if (stringId != null) {
Snackbar(modifier = Modifier.padding(horizontal = 16.dp)) {
Text(text = stringResource(stringId))
Text(text = stringResource(stringId), Modifier.testTag(AuthScreenTag.LoginError))
}
}
}
@ -176,5 +176,6 @@ object AuthScreenTag {
const val PasswordInput = "AuthScreenTag.PasswordInput"
const val LoadingIndicator = "AuthScreenTag.LoadingIndicator"
const val LoginButton = "AuthScreenTag.LoginButton"
const val LoginError = "AuthScreenTag.LoginError"
const val PasswordVisibilityToggle = "AuthScreenTag.PasswordVisibilityToggle"
}