Skip to content

Commit

Permalink
Add test for scoped object backstack survival with config change recr…
Browse files Browse the repository at this point in the history
…eation
  • Loading branch information
sebaslogen committed Sep 26, 2024
1 parent 7442dc4 commit 0a39bb8
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class KeysInScopeActivityRecreationTests : ComposeTestUtils {
Thread.sleep(COMPOSITION_RESUMED_TIMEOUT_IN_SECONDS * 2 * 1000) // Wait for the ViewModel to be cleared
composeTestRule.onNodeWithTag("LazyList").performScrollToIndex(0)

// Then the scoped ViewModel disappears
// Then the scoped ViewModel is still the same
onNodeWithTestTag("FakeScopedViewModel 1 Scoped").assertIsDisplayed().assertTextEquals(initialFakeScopedViewModelText)
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
package com.sebaslogen.resacaapp.sample

import android.content.Intent
import androidx.compose.ui.test.assert
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertTextEquals
import androidx.compose.ui.test.hasTextExactly
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.performClick
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import androidx.test.core.app.ActivityScenario
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.sebaslogen.resaca.COMPOSITION_RESUMED_TIMEOUT_IN_SECONDS
import com.sebaslogen.resacaapp.sample.ui.main.ComposeActivity
import com.sebaslogen.resacaapp.sample.ui.main.ScreensWithNavigation
import com.sebaslogen.resacaapp.sample.ui.main.rememberScopedDestination
import com.sebaslogen.resacaapp.sample.ui.main.viewModelScopedDestination
import com.sebaslogen.resacaapp.sample.utils.ComposeTestUtils
import org.junit.Rule
import org.junit.Test
Expand Down Expand Up @@ -78,4 +85,33 @@ class ComposeNavigationTests : ComposeTestUtils {
// Then the text of the NOT scoped object is different from the original one because it's a new object
onNodeWithTestTag("FakeRepo Not scoped").assertIsDisplayed().assert(hasTextExactly(initialFakeRepoText).not())
}

@Test
fun `when I navigate to nested screen, produce an activity recreation and navigate back, then the scoped objects are the same`() {
// Given the starting screen with ViewModel scoped
val launchIntent = Intent(ApplicationProvider.getApplicationContext(), ComposeActivity::class.java).apply {
putExtra(ComposeActivity.START_DESTINATION, viewModelScopedDestination)
}
ActivityScenario.launch<ComposeActivity>(launchIntent).use { scenario ->
scenario.onActivity { activity: ComposeActivity ->
// Find the scoped text fields and grab their texts
val initialFakeScopedViewModelText = retrieveTextFromNodeWithTestTag("FakeScopedViewModel Scoped")
printComposeUiTreeToLog()

// When I navigate to a second screen I apply the configuration change by recreating the Activity
onNodeWithTestTag("Navigate to rememberScoped").performClick()
printComposeUiTreeToLog()
val newScenario: ActivityScenario<ComposeActivity> = scenario.recreate()
Thread.sleep(COMPOSITION_RESUMED_TIMEOUT_IN_SECONDS * 2 * 1000) // Wait for the ViewModel to be cleared
printComposeUiTreeToLog() // Print is needed to push the main thread forward

// And then I navigate back to the first screen
newScenario.onActivity { it.onBackPressedDispatcher.onBackPressed() }
printComposeUiTreeToLog() // Print is needed to push the main thread forward

// Then the scoped ViewModel is still the same
onNodeWithTestTag("FakeScopedViewModel Scoped").assertIsDisplayed().assertTextEquals(initialFakeScopedViewModelText)
}
}
}
}

0 comments on commit 0a39bb8

Please sign in to comment.