Cover all auth tests
This commit is contained in:
parent
d948d06378
commit
d9725e31e6
4 changed files with 110 additions and 13 deletions
|
|
@ -2,6 +2,7 @@ package org.fnives.test.showcase.ui
|
||||||
|
|
||||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
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.compose.ComposeActivity
|
||||||
import org.fnives.test.showcase.network.mockserver.scenario.auth.AuthScenario
|
import org.fnives.test.showcase.network.mockserver.scenario.auth.AuthScenario
|
||||||
import org.fnives.test.showcase.testutils.MockServerScenarioSetupResetingTestRule
|
import org.fnives.test.showcase.testutils.MockServerScenarioSetupResetingTestRule
|
||||||
|
|
@ -25,7 +26,7 @@ class AuthComposeInstrumentedTest : KoinTest {
|
||||||
private val mockServerScenarioSetup get() = mockServerScenarioSetupTestRule.mockServerScenarioSetup
|
private val mockServerScenarioSetup get() = mockServerScenarioSetupTestRule.mockServerScenarioSetup
|
||||||
private val mainDispatcherTestRule = ComposeMainDispatcherTestRule()
|
private val mainDispatcherTestRule = ComposeMainDispatcherTestRule()
|
||||||
private lateinit var robot: ComposeLoginRobot
|
private lateinit var robot: ComposeLoginRobot
|
||||||
private lateinit var screenRobot: ComposeScreenRobot
|
private lateinit var navigationRobot: ComposeNavigationRobot
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
@JvmField
|
@JvmField
|
||||||
|
|
@ -36,7 +37,7 @@ class AuthComposeInstrumentedTest : KoinTest {
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
robot = ComposeLoginRobot(composeTestRule)
|
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 */
|
/** 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.advanceTimeBy(500L)
|
||||||
composeTestRule.mainClock.advanceTimeUntil { anyResourceIdling() }
|
composeTestRule.mainClock.advanceTimeUntil { anyResourceIdling() }
|
||||||
screenRobot.assertAuthScreen()
|
navigationRobot.assertAuthScreen()
|
||||||
robot
|
robot.setPassword("alma")
|
||||||
.setPassword("alma")
|
|
||||||
.setUsername("banan")
|
.setUsername("banan")
|
||||||
.assertUsername("banan")
|
.assertUsername("banan")
|
||||||
.assertPassword("alma")
|
.assertPassword("alma")
|
||||||
|
|
@ -61,7 +61,93 @@ class AuthComposeInstrumentedTest : KoinTest {
|
||||||
composeTestRule.mainClock.autoAdvance = true
|
composeTestRule.mainClock.autoAdvance = true
|
||||||
|
|
||||||
composeTestRule.mainClock.advanceTimeUntil { anyResourceIdling() }
|
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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
package org.fnives.test.showcase.ui
|
package org.fnives.test.showcase.ui
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import androidx.compose.ui.test.*
|
import androidx.compose.ui.test.*
|
||||||
import androidx.compose.ui.test.junit4.ComposeTestRule
|
import androidx.compose.ui.test.junit4.ComposeTestRule
|
||||||
|
import androidx.test.core.app.ApplicationProvider
|
||||||
import org.fnives.test.showcase.compose.screen.auth.AuthScreenTag
|
import org.fnives.test.showcase.compose.screen.auth.AuthScreenTag
|
||||||
|
|
||||||
class ComposeLoginRobot(
|
class ComposeLoginRobot(
|
||||||
|
|
@ -34,4 +36,13 @@ class ComposeLoginRobot(
|
||||||
fun assertLoading(): ComposeLoginRobot = apply {
|
fun assertLoading(): ComposeLoginRobot = apply {
|
||||||
composeTestRule.onNodeWithTag(AuthScreenTag.LoadingIndicator).assertIsDisplayed()
|
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))
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,19 +1,18 @@
|
||||||
package org.fnives.test.showcase.ui
|
package org.fnives.test.showcase.ui
|
||||||
|
|
||||||
import androidx.compose.ui.test.assertIsDisplayed
|
|
||||||
import androidx.compose.ui.test.junit4.ComposeTestRule
|
import androidx.compose.ui.test.junit4.ComposeTestRule
|
||||||
import androidx.compose.ui.test.onNodeWithTag
|
import androidx.compose.ui.test.onNodeWithTag
|
||||||
import org.fnives.test.showcase.compose.screen.AppNavigationTag
|
import org.fnives.test.showcase.compose.screen.AppNavigationTag
|
||||||
|
|
||||||
class ComposeScreenRobot(
|
class ComposeNavigationRobot(
|
||||||
private val composeTestRule: ComposeTestRule,
|
private val composeTestRule: ComposeTestRule,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun assertHomeScreen(): ComposeScreenRobot = apply {
|
fun assertHomeScreen(): ComposeNavigationRobot = apply {
|
||||||
composeTestRule.onNodeWithTag(AppNavigationTag.HomeScreen).assertIsDisplayed()
|
composeTestRule.onNodeWithTag(AppNavigationTag.HomeScreen).assertExists()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun assertAuthScreen(): ComposeScreenRobot = apply {
|
fun assertAuthScreen(): ComposeNavigationRobot = apply {
|
||||||
composeTestRule.onNodeWithTag(AppNavigationTag.AuthScreen).assertIsDisplayed()
|
composeTestRule.onNodeWithTag(AppNavigationTag.AuthScreen).assertExists()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -135,7 +135,7 @@ private fun Snackbar(authScreenState: AuthScreenState, modifier: Modifier = Modi
|
||||||
val stringId = error?.stringResId()
|
val stringId = error?.stringResId()
|
||||||
if (stringId != null) {
|
if (stringId != null) {
|
||||||
Snackbar(modifier = Modifier.padding(horizontal = 16.dp)) {
|
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 PasswordInput = "AuthScreenTag.PasswordInput"
|
||||||
const val LoadingIndicator = "AuthScreenTag.LoadingIndicator"
|
const val LoadingIndicator = "AuthScreenTag.LoadingIndicator"
|
||||||
const val LoginButton = "AuthScreenTag.LoginButton"
|
const val LoginButton = "AuthScreenTag.LoginButton"
|
||||||
|
const val LoginError = "AuthScreenTag.LoginError"
|
||||||
const val PasswordVisibilityToggle = "AuthScreenTag.PasswordVisibilityToggle"
|
const val PasswordVisibilityToggle = "AuthScreenTag.PasswordVisibilityToggle"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue