Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ import dagger.hilt.android.testing.HiltAndroidTest
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import javax.inject.Inject
Expand Down Expand Up @@ -255,9 +254,6 @@ class NavigationTest {
}
}

// TODO decide if backStack should preserve previous stacks when navigating back to home tab (ForYou)
// https://github.com/android/nowinandroid/issues/1937
@Ignore
@Test
fun navigationBar_multipleBackStackInterests() {
composeTestRule.apply {
Expand All @@ -283,6 +279,32 @@ class NavigationTest {
}
}

@Test
fun navigationBar_backFromTabPreservesSubStack() {
composeTestRule.apply {
onNodeWithText(interests).performClick()

// Select a topic
val topic = runBlocking {
topicsRepository.getTopics().first().sortedBy(Topic::name).last()
}
onNodeWithTag(LIST_PANE_TEST_TAG).performScrollToNode(hasText(topic.name))
onNodeWithText(topic.name).performClick()

// Verify the topic is shown
onNodeWithTag("topic:${topic.id}").assertIsDisplayed()

// Switch to another tab
onNodeWithText(saved).performClick()

// Press back to return to previous tab
Espresso.pressBack()

// Verify the topic detail is still shown (sub-stack preserved)
onNodeWithTag("topic:${topic.id}").assertExists()
}
}

@Test
fun navigatingToTopicFromForYou_showsTopicDetails() {
composeTestRule.apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.google.samples.apps.nowinandroid.ui

import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.WindowInsets
Expand Down Expand Up @@ -264,8 +265,16 @@ internal fun NiaApp(
searchEntry(navigator)
}

val navigationState = appState.navigationState
BackHandler(
enabled = navigationState.currentKey == navigationState.currentTopLevelKey &&
navigationState.currentTopLevelKey != navigationState.startKey,
) {
navigator.goBack()
}

NavDisplay(
entries = appState.navigationState.toEntries(entryProvider),
entries = navigationState.toEntries(entryProvider),
sceneStrategy = listDetailStrategy,
onBack = { navigator.goBack() },
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,5 @@ fun NavigationState.toEntries(
)
}

return topLevelStack
.flatMap { decoratedEntries[it] ?: emptyList() }
.toMutableStateList()
return (decoratedEntries[currentTopLevelKey] ?: emptyList()).toMutableStateList()
}
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,32 @@ class NavigatorTest {
assertThat(navigationState.currentTopLevelKey).isEqualTo(TestFirstTopLevelKey)
}

@Test
fun testSubStackPreservedAfterTabSwitchAndBack() {
// Navigate to sub-page in first tab (ForYou → Topic)
navigator.navigate(TestKeyFirst)

assertThat(navigationState.currentKey).isEqualTo(TestKeyFirst)
assertThat(navigationState.currentTopLevelKey).isEqualTo(TestFirstTopLevelKey)

// Switch to second tab (e.g. Bookmarks)
navigator.navigate(TestSecondTopLevelKey)

assertThat(navigationState.currentKey).isEqualTo(TestSecondTopLevelKey)
assertThat(navigationState.currentTopLevelKey).isEqualTo(TestSecondTopLevelKey)

// Press back from second tab
navigator.goBack()

// Should return to first tab with sub-stack preserved
assertThat(navigationState.currentTopLevelKey).isEqualTo(TestFirstTopLevelKey)
assertThat(navigationState.currentKey).isEqualTo(TestKeyFirst)
assertThat(navigationState.currentSubStack).containsExactly(
TestFirstTopLevelKey,
TestKeyFirst,
).inOrder()
}

@Test
fun throwOnEmptyBackStack() {
assertFailsWith<IllegalStateException> {
Expand Down