diff --git a/Flipcash/Core/Screens/Main/Currency Creation/CurrencyCreationWizardScreen.swift b/Flipcash/Core/Screens/Main/Currency Creation/CurrencyCreationWizardScreen.swift index f3d1539a8..f62073e44 100644 --- a/Flipcash/Core/Screens/Main/Currency Creation/CurrencyCreationWizardScreen.swift +++ b/Flipcash/Core/Screens/Main/Currency Creation/CurrencyCreationWizardScreen.swift @@ -261,12 +261,7 @@ struct CurrencyCreationWizardScreen: View { paymentMint: context.paymentMint ) .environment(\.dismissParentContainer, { - // Sheet dismiss unmounts the wizard, taking the - // fullScreenCover with it as a single animation. - // Nilling the cover binding here would stage a separate - // cover-dismiss before the sheet animation; the @State - // is freed automatically when the wizard unmounts. - router.dismissSheet() + Self.dismissCreationFlow(router: router) }) } } @@ -282,6 +277,17 @@ struct CurrencyCreationWizardScreen: View { } } + /// Unwinds the whole creation flow once the launch cover is done with it — + /// both the finished handoff and the failure dismissal come through here. + /// + /// The flow is pushed onto the Wallet tab's stack, so it comes off by + /// popping that stack to its root. Naming the stack rather than using + /// `popToRoot()`'s topmost lookup keeps this working while the cover is up, + /// since the tab host clears `activeTabStack` when it disappears. + static func dismissCreationFlow(router: AppRouter) { + router.popToRoot(on: AppRouter.Destination.currencyCreationWizard.owningStack) + } + // MARK: - Navigation private func advance() { diff --git a/FlipcashTests/Navigation/CurrencyCreationFlowDismissalTests.swift b/FlipcashTests/Navigation/CurrencyCreationFlowDismissalTests.swift new file mode 100644 index 000000000..3c9a8dedd --- /dev/null +++ b/FlipcashTests/Navigation/CurrencyCreationFlowDismissalTests.swift @@ -0,0 +1,43 @@ +// +// CurrencyCreationFlowDismissalTests.swift +// FlipcashTests +// + +import SwiftUI +import Testing +import FlipcashCore +@testable import Flipcash + +@MainActor +@Suite("Currency Creation Flow Dismissal") +struct CurrencyCreationFlowDismissalTests { + + /// Pushes the flow the way the Wallet tile does: summary, then wizard. + private func routerInCreationFlow() -> AppRouter { + let router = AppRouter() + router.activeTabStack = .balance + router.push(.currencyCreationSummary) + router.push(.currencyCreationWizard) + return router + } + + @Test("Finishing the launch cover pops the creation flow off the Wallet stack") + func dismissCreationFlow_popsHostStack() { + let router = routerInCreationFlow() + + CurrencyCreationWizardScreen.dismissCreationFlow(router: router) + + #expect(router[.balance].isEmpty, "the wizard must not stay mounted under the dismissed cover") + } + + @Test("Unwinds even though the cover hid the tab host and cleared the active stack") + func dismissCreationFlow_withoutActiveTabStack_popsHostStack() { + let router = routerInCreationFlow() + // `HomeTabView.onDisappear` clears this while the fullScreenCover is up. + router.activeTabStack = nil + + CurrencyCreationWizardScreen.dismissCreationFlow(router: router) + + #expect(router[.balance].isEmpty, "the unwind must not depend on the tab host still being mounted") + } +}