Merge "Fix popWithTransition in TestNavigatorState" into androidx-main
diff --git a/navigation/navigation-testing/src/androidTest/java/androidx/navigation/testing/TestNavigatorStateTest.kt b/navigation/navigation-testing/src/androidTest/java/androidx/navigation/testing/TestNavigatorStateTest.kt
index 95ca300..0685776 100644
--- a/navigation/navigation-testing/src/androidTest/java/androidx/navigation/testing/TestNavigatorStateTest.kt
+++ b/navigation/navigation-testing/src/androidTest/java/androidx/navigation/testing/TestNavigatorStateTest.kt
@@ -119,9 +119,14 @@
             .isEqualTo(Lifecycle.State.RESUMED)
 
         navigator.popBackStack(secondEntry, false)
+        assertThat(secondEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.CREATED)
+        assertThat(firstEntry.lifecycle.currentState)
+            .isEqualTo(Lifecycle.State.STARTED)
+
+        state.transitionsInProgress.value[firstEntry]?.onTransitionComplete()
         assertThat(firstEntry.lifecycle.currentState)
             .isEqualTo(Lifecycle.State.RESUMED)
-
         state.transitionsInProgress.value[secondEntry]?.onTransitionComplete()
         assertThat(secondEntry.lifecycle.currentState)
             .isEqualTo(Lifecycle.State.DESTROYED)
diff --git a/navigation/navigation-testing/src/main/java/androidx/navigation/testing/TestNavigatorState.kt b/navigation/navigation-testing/src/main/java/androidx/navigation/testing/TestNavigatorState.kt
index c317091..eef9c77 100644
--- a/navigation/navigation-testing/src/main/java/androidx/navigation/testing/TestNavigatorState.kt
+++ b/navigation/navigation-testing/src/main/java/androidx/navigation/testing/TestNavigatorState.kt
@@ -120,10 +120,27 @@
         popUpTo: NavBackStackEntry,
         saveState: Boolean
     ): OnTransitionCompleteListener {
+        // Get the entry that will be incoming after we have popped all the way up to the desired
+        // entry.
+        // We need to do this before we call popWithTransition because for the TestNavigatorState
+        // pop is called immediately, which would cause the entry to immediately go to RESUMED.
+        val incomingEntry = backStack.value.lastOrNull { entry ->
+            entry != popUpTo &&
+                backStack.value.lastIndexOf(entry) < backStack.value.lastIndexOf(popUpTo)
+        }
+        // When popping, we need to mark the incoming entry as transitioning so we keep it
+        // STARTED until the transition completes at which point we can move it to RESUMED
+        if (incomingEntry != null) {
+            addInProgressTransition(incomingEntry) {
+                removeInProgressTransition(incomingEntry)
+                updateMaxLifecycle()
+            }
+        }
+        addInProgressTransition(popUpTo) { }
         val innerListener = super.popWithTransition(popUpTo, saveState)
         val listener = OnTransitionCompleteListener {
             innerListener.onTransitionComplete()
-            updateMaxLifecycle()
+            updateMaxLifecycle(listOf(popUpTo))
         }
         addInProgressTransition(popUpTo, listener)
         updateMaxLifecycle()