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
15 changes: 13 additions & 2 deletions app/src/main/java/to/bitkit/ui/ContentView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -953,8 +953,8 @@ private fun RootNavHost(
app = appViewModel,
wallet = walletViewModel,
transfer = transferViewModel,
onContinueClick = { navController.popBackStack<Routes.TransferRoot>(inclusive = true) },
onTransferUnavailable = { navController.popBackStack<Routes.TransferRoot>(inclusive = true) },
onContinueClick = { navController.navigateOnSavingsTransferExit() },
onTransferUnavailable = { navController.navigateOnSavingsTransferExit() },
Comment thread
jvsena42 marked this conversation as resolved.
)
}
deepLinkableComposable<Routes.SpendingIntro> {
Expand Down Expand Up @@ -2090,6 +2090,17 @@ fun NavController.navigateToTransferSavingsIntro() = navigateTo(Routes.SavingsIn

fun NavController.navigateToTransferSavingsAvailability() = navigateTo(Routes.SavingsAvailability)

/**
* Exits the savings transfer to home. The coop close retry job holds on to this callback for up to
* 30 minutes, so it is ignored unless the savings progress screen that owns it is still on screen.
* Matching the whole transfer graph would also pop a transfer to spending the user started since.
*/
fun NavController.navigateOnSavingsTransferExit() {
val isOnSavingsProgress = currentDestination?.hasRoute<Routes.SavingsProgress>() == true
if (!isOnSavingsProgress) return
navigateToHome()
}

fun NavController.navigateToTransferSpendingStart(hasSeenSpendingIntro: Boolean) =
navigateTo(transferSpendingStartRoute(hasSeenSpendingIntro))

Expand Down
76 changes: 76 additions & 0 deletions app/src/test/java/to/bitkit/ui/ContentViewTest.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
package to.bitkit.ui

import android.content.Context
import androidx.navigation.NavDestination.Companion.hasRoute
import androidx.navigation.NavHostController
import androidx.navigation.compose.ComposeNavigator
import androidx.navigation.compose.composable
import androidx.navigation.createGraph
import androidx.navigation.navigation
import androidx.test.core.app.ApplicationProvider
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
Expand Down Expand Up @@ -88,4 +96,72 @@ class ContentViewTest {
assertEquals(receiveSheetPresentationKey(sheet), receiveSheetPresentationKey(samePresentation))
assertFalse(receiveSheetPresentationKey(sheet) == receiveSheetPresentationKey(nextPresentation))
}

@Test
fun `savings transfer completion returns home and drops spending from back stack`() {
val navController = transferNavController()
navController.navigateTo(Routes.Spending)
navController.navigateToTransferSavingsAvailability()
navController.navigateTo(Routes.SavingsProgress)

navController.navigateOnSavingsTransferExit()

assertTrue(navController.currentDestination?.hasRoute<Routes.Home>() == true)
assertNull(navController.previousBackStackEntry)
}

@Test
fun `savings transfer exit leaves a screen opened on top of the flow alone`() {
val navController = transferNavController()
navController.navigateToTransferSavingsAvailability()
navController.navigateTo(Routes.SavingsProgress)
navController.navigateTo(Routes.Settings)

navController.navigateOnSavingsTransferExit()

assertTrue(navController.currentDestination?.hasRoute<Routes.Settings>() == true)
}

@Test
fun `savings transfer exit does nothing once the transfer flow is gone`() {
val navController = transferNavController()
navController.navigateTo(Routes.Spending)
navController.navigateToTransferSavingsAvailability()
navController.navigateTo(Routes.SavingsProgress)
navController.navigateOnSavingsTransferExit()
navController.navigateTo(Routes.Settings)

navController.navigateOnSavingsTransferExit()

assertTrue(navController.currentDestination?.hasRoute<Routes.Settings>() == true)
}

@Test
fun `savings transfer exit leaves a later transfer to spending alone`() {
val navController = transferNavController()
navController.navigateToTransferSavingsAvailability()
navController.navigateTo(Routes.SavingsProgress)
navController.navigateOnSavingsTransferExit()
navController.navigateTo(Routes.Spending)
navController.navigateTo(Routes.SpendingConfirm)

navController.navigateOnSavingsTransferExit()

assertTrue(navController.currentDestination?.hasRoute<Routes.SpendingConfirm>() == true)
}

private fun transferNavController(): NavHostController =
NavHostController(ApplicationProvider.getApplicationContext<Context>()).apply {
navigatorProvider.addNavigator(ComposeNavigator())
graph = createGraph(startDestination = Routes.Home) {
composable<Routes.Home> {}
composable<Routes.Spending> {}
composable<Routes.Settings> {}
navigation<Routes.TransferRoot>(startDestination = Routes.SavingsAvailability) {
composable<Routes.SavingsAvailability> {}
composable<Routes.SavingsProgress> {}
composable<Routes.SpendingConfirm> {}
}
}
}
}
1 change: 1 addition & 0 deletions changelog.d/next/809.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Tapping OK after moving funds from spending to savings now returns to the home screen instead of the spending wallet.
2 changes: 2 additions & 0 deletions journeys/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ fixtures, push notifications) live in each suite's README.
| [security](security) | 1 | PIN result sheet layout at a long locale and font scale; no README |
| [subscriptions](subscriptions) | 4 | Paykit subscription lifecycle across two wallets, plus the Payments tab |
| [tags](tags) | 1 | Tag input length cap on an activity; no backend, no README |
| [transfer](transfer) | 1 | Spending to Savings exit route; needs an open channel and closes it; no README |
| [transfers](transfers) | 1 | Transfer to Spending settling after the LSP closes the channel; no README |
| [widgets](widgets) | 2 | Needs no backend — the quickest way to see the loop work; no README |

Expand Down Expand Up @@ -155,6 +156,7 @@ Known differences in the corpus, as of the iOS port (synonymdev/bitkit-ios#691):
| `home/pull-to-refresh-rates.xml` | not ported — iOS does not refresh exchange rates on pull to refresh |
| `security/pin-result-long-label.xml` | not ported — the toggle exists on the iOS security success screen, but the overlap check is a follow-up |
| `tags/activity-tag-length-cap.xml` | not ported — iOS has no 20-character cap on tag input |
| `transfer/transfer-to-savings-returns-home.xml` | not ported — iOS already resets navigation to home on the same OK, so the journey has no iOS counterpart yet |
| — | `hardware-wallet/transfer-to-spending-over-max.xml` exists only on iOS |

### Running one on iOS
Expand Down
28 changes: 28 additions & 0 deletions journeys/transfer/transfer-to-savings-returns-home.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<journey name="transfer to savings returns home">
<description>
Verifies that confirming a Spending to Savings transfer and tapping OK on the success screen
lands on the wallet home screen, not on the Spending wallet screen the flow was started from,
and that system back from there does not reopen the Spending screen or the transfer flow
(synonymdev/bitkit-android#809). iOS resets navigation to home on the same OK.

Precondition: onboarded dev wallet with an open, usable channel to the LSP and a POSITIVE
Spending balance. The transfer closes that channel, so reopen one (Blocktank order through the
lsp helper, then mine blocks) afterwards if later work needs a Spending balance. Start on the
wallet home screen.
</description>
<actions>
<action>Verify the Spending balance card (testTag "ActivitySpending") shows a positive amount</action>
<action>Tap the Spending balance card (testTag "ActivitySpending")</action>
<action>Tap "Transfer To Savings" (testTag "TransferToSavings")</action>
<action>If the transfer to savings intro appears, tap "Get Started" (testTag "SavingsIntro-button")</action>
<action>Tap "Continue" (testTag "AvailabilityContinue") on the funds availability screen</action>
<action>On the confirm screen, swipe the "Swipe To Transfer" handle (testTag "GRAB") fully to the right</action>
<action>Wait up to 60 seconds for the "Transfer Successful" screen (testTag "TransferSuccess") with the OK button (testTag "TransferSuccess-button")</action>
<action>Tap OK (testTag "TransferSuccess-button")</action>
<action>Verify the home screen is visible with the Savings and Spending cards (testTags "ActivitySavings" and "ActivitySpending")</action>
<action>Verify there is no back button (testTag "NavigationBack") and no "Transfer To Savings" button (testTag "TransferToSavings")</action>
<action>Verify the Spending balance card (testTag "ActivitySpending") shows 0</action>
<action>Press the system back button once</action>
<action>Verify the app is backgrounded to the launcher, and neither the Spending screen nor any transfer screen is shown</action>
</actions>
</journey>
Loading