Add a test for restoring compose content
This commit is contained in:
parent
2e97716b48
commit
47037d4bcd
3 changed files with 73 additions and 3 deletions
|
|
@ -1,5 +1,6 @@
|
|||
package org.fnives.test.showcase.ui
|
||||
|
||||
import androidx.compose.ui.test.junit4.StateRestorationTester
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import org.fnives.test.showcase.R
|
||||
|
|
@ -22,6 +23,7 @@ class AuthComposeInstrumentedTest : KoinTest {
|
|||
|
||||
@get:Rule
|
||||
val composeTestRule = createComposeRule()
|
||||
private val stateRestorationTester = StateRestorationTester(composeTestRule)
|
||||
|
||||
private val mockServerScenarioSetupTestRule = MockServerScenarioSetupResetingTestRule()
|
||||
private val mockServerScenarioSetup get() = mockServerScenarioSetupTestRule.mockServerScenarioSetup
|
||||
|
|
@ -37,7 +39,7 @@ class AuthComposeInstrumentedTest : KoinTest {
|
|||
|
||||
@Before
|
||||
fun setup() {
|
||||
composeTestRule.setContent {
|
||||
stateRestorationTester.setContent {
|
||||
AppNavigation(isUserLogeInUseCase = IsUserLoggedInUseCase(FakeUserDataLocalStorage()))
|
||||
}
|
||||
robot = ComposeLoginRobot(composeTestRule)
|
||||
|
|
@ -152,4 +154,21 @@ class AuthComposeInstrumentedTest : KoinTest {
|
|||
.assertNotLoading()
|
||||
navigationRobot.assertAuthScreen()
|
||||
}
|
||||
|
||||
/** GIVEN username and password WHEN restoring THEN username and password fields contain the same text */
|
||||
@Test
|
||||
fun restoringContentShowPreviousCredentials() {
|
||||
composeTestRule.mainClock.advanceTimeUntil { anyResourceIdling() }
|
||||
navigationRobot.assertAuthScreen()
|
||||
robot.setUsername("alma")
|
||||
.setPassword("banan")
|
||||
.assertUsername("alma")
|
||||
.assertPassword("banan")
|
||||
|
||||
stateRestorationTester.emulateSavedInstanceStateRestore()
|
||||
|
||||
navigationRobot.assertAuthScreen()
|
||||
robot.assertUsername("alma")
|
||||
.assertPassword("banan")
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
package org.fnives.test.showcase.compose.screen.auth
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.platform.AndroidUiDispatcher
|
||||
import androidx.compose.runtime.saveable.Saver
|
||||
import androidx.compose.runtime.saveable.mapSaver
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -17,7 +19,9 @@ fun rememberAuthScreenState(
|
|||
loginUseCase: LoginUseCase = get(),
|
||||
onLoginSuccess: () -> Unit = {},
|
||||
): AuthScreenState {
|
||||
return remember { AuthScreenState(stateScope, loginUseCase, onLoginSuccess) }
|
||||
return rememberSaveable(saver = AuthScreenState.getSaver(stateScope, loginUseCase, onLoginSuccess)) {
|
||||
AuthScreenState(stateScope, loginUseCase, onLoginSuccess)
|
||||
}
|
||||
}
|
||||
|
||||
class AuthScreenState(
|
||||
|
|
@ -80,4 +84,23 @@ class AuthScreenState(
|
|||
UNSUPPORTED_USERNAME,
|
||||
UNSUPPORTED_PASSWORD
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val USERNAME = "USERNAME"
|
||||
private const val PASSWORD = "PASSWORD"
|
||||
|
||||
fun getSaver(
|
||||
stateScope: CoroutineScope,
|
||||
loginUseCase: LoginUseCase,
|
||||
onLoginSuccess: () -> Unit,
|
||||
): Saver<AuthScreenState, *> = mapSaver(
|
||||
save = { mapOf(USERNAME to it.username, PASSWORD to it.password) },
|
||||
restore = {
|
||||
AuthScreenState(stateScope, loginUseCase, onLoginSuccess).apply {
|
||||
onUsernameChanged(it.getOrElse(USERNAME) { "" } as String)
|
||||
onPasswordChanged(it.getOrElse(PASSWORD) { "" } as String)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -324,3 +324,31 @@ robot.assertErrorIsShown(R.string.something_went_wrong)
|
|||
.assertNotLoading()
|
||||
navigationRobot.assertAuthScreen()
|
||||
```
|
||||
|
||||
### 6. `restoringContentShowPreviousCredentials`
|
||||
|
||||
Since we're writing apps for Android, we must handle state restoration so let's write a test for it.
|
||||
|
||||
For simulating the recreation of the UI, we first need a `StateRestorationTester`:
|
||||
```kotlin
|
||||
private val stateRestorationTester = StateRestorationTester(composeTestRule)
|
||||
```
|
||||
|
||||
Then in `setup()`, we need to `setContent` on `stateRestorationTester` instead of on `composeTestRule`.
|
||||
|
||||
Now for the actual test, we first setup the content then we trigger restoration by calling `stateRestorationTester.emulateSavedInstanceStateRestore()`, afterwards we can verify that the content is recreated in the correct way:
|
||||
|
||||
```kotlin
|
||||
composeTestRule.mainClock.advanceTimeUntil { anyResourceIdling() }
|
||||
navigationRobot.assertAuthScreen()
|
||||
robot.setUsername("alma")
|
||||
.setPassword("banan")
|
||||
.assertUsername("alma")
|
||||
.assertPassword("banan")
|
||||
|
||||
stateRestorationTester.emulateSavedInstanceStateRestore()
|
||||
|
||||
navigationRobot.assertAuthScreen()
|
||||
robot.assertUsername("alma")
|
||||
.assertPassword("banan")
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue