From b61ff38f7cd4a9acd01941deef2ecae8bbac7b39 Mon Sep 17 00:00:00 2001 From: Amanda Bullington <35536439+albullington@users.noreply.github.com> Date: Thu, 25 Jul 2024 09:58:54 -0700 Subject: [PATCH] Reset stack when user navigates from AddObsModal (#1858) * Reset navigation stack when user navigates from AddObsModal; closes #1857 * Fix AddObs nav test --- .../SharedComponents/Buttons/AddObsButton.js | 30 ++++++++++++---- .../navigation/AddObsButton.test.js | 35 +++++++++++++------ 2 files changed, 49 insertions(+), 16 deletions(-) diff --git a/src/components/SharedComponents/Buttons/AddObsButton.js b/src/components/SharedComponents/Buttons/AddObsButton.js index b619a0692..41875b48f 100644 --- a/src/components/SharedComponents/Buttons/AddObsButton.js +++ b/src/components/SharedComponents/Buttons/AddObsButton.js @@ -1,6 +1,6 @@ // @flow -import { useNavigation } from "@react-navigation/native"; +import { CommonActions, useNavigation } from "@react-navigation/native"; import AddObsModal from "components/AddObsModal"; import { Modal } from "components/SharedComponents"; import GradientButton from "components/SharedComponents/Buttons/GradientButton.tsx"; @@ -30,11 +30,29 @@ const AddObsButton = (): React.Node => { if ( screen !== "ObsEdit" ) { resetObservationFlowSlice( ); } - // access nested screen - navigation.navigate( "NoBottomTabStackNavigator", { - screen, - params: { ...params, previousScreen: currentRoute } - } ); + + // we need to reset the navigation stack whenever a user navigates from the AddObs wheel, + // otherwise the user can end up closing out to a previous place in the stack, #1857 + navigation.dispatch( + CommonActions.reset( { + index: 0, + routes: [ + { + name: "NoBottomTabStackNavigator", + state: { + index: 0, + routes: [ + { + name: screen, + params: { ...params, previousScreen: currentRoute } + } + ] + } + } + ] + } ) + ); + closeModal( ); }; const navToARCamera = ( ) => { navAndCloseModal( "Camera", { camera: "AI" } ); }; diff --git a/tests/integration/navigation/AddObsButton.test.js b/tests/integration/navigation/AddObsButton.test.js index cf05f962a..13b8e84dc 100644 --- a/tests/integration/navigation/AddObsButton.test.js +++ b/tests/integration/navigation/AddObsButton.test.js @@ -7,17 +7,34 @@ import { renderComponent } from "tests/helpers/render"; const actor = userEvent.setup(); -const mockNavigate = jest.fn(); +const mockDispatch = jest.fn(); jest.mock( "@react-navigation/native", () => { const actualNav = jest.requireActual( "@react-navigation/native" ); return { ...actualNav, useNavigation: () => ( { - navigate: mockNavigate + dispatch: mockDispatch } ) }; } ); +const resetNavigation = ( name, params ) => ( { + payload: { + index: 0, + routes: [{ + name: "NoBottomTabStackNavigator", + state: { + index: 0, + routes: [{ + name, + params + }] + } + }] + }, + type: "RESET" +} ); + beforeAll( ( ) => { jest.useFakeTimers( ); } ); @@ -32,10 +49,9 @@ describe( "AddObsButton", ( ) => { expect( addObsButton ).toBeTruthy( ); await actor.press( addObsButton ); - expect( mockNavigate ).toHaveBeenCalledWith( "NoBottomTabStackNavigator", { - screen: "Camera", - params: { camera: "AI", previousScreen: null } - } ); + expect( mockDispatch ).toHaveBeenCalledWith( + resetNavigation( "Camera", { camera: "AI", previousScreen: null } ) + ); } ); } ); @@ -74,9 +90,8 @@ describe( "with advanced user layout", ( ) => { expect( noEvidenceButton ).toBeTruthy( ); await actor.press( noEvidenceButton ); - expect( mockNavigate ).toHaveBeenCalledWith( "NoBottomTabStackNavigator", { - screen: "ObsEdit", - params: { previousScreen: null } - } ); + expect( mockDispatch ).toHaveBeenCalledWith( + resetNavigation( "ObsEdit", { previousScreen: null } ) + ); } ); } );