Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nav tests #156

Merged
merged 12 commits into from
Jan 10, 2025
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module.exports = {
`<rootDir>/tests/ui/**/*.${testFileExtension}`,
`<rootDir>/tests/unit/**/*.${testFileExtension}`,
`<rootDir>/tests/actions/**/*.${testFileExtension}`,
`<rootDir>/tests/navigation/**/*.${testFileExtension}`,
`<rootDir>/?(*.)+(spec|test).${testFileExtension}`,
],
transform: {
Expand Down
16 changes: 16 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {sub as dateSubtract} from 'date-fns/sub';
import Config from 'react-native-config';
import * as KeyCommand from 'react-native-key-command';
import type {ValueOf} from 'type-fest';
import type ResponsiveLayoutResult from './hooks/useResponsiveLayout/types';
import type {Video} from './libs/actions/Report';
import type {MileageRate} from './libs/DistanceRequestUtils';
import BankAccount from './libs/models/BankAccount';
Expand Down Expand Up @@ -6494,6 +6495,21 @@ const CONST = {
GLOBAL_CREATE_TOOLTIP: 'globalCreateTooltip',
},
SMART_BANNER_HEIGHT: 152,

NAVIGATION_TESTS: {
DEFAULT_PARENT_ROUTE: {key: 'parentRouteKey', name: 'ParentNavigator'},
DEFAULT_USE_RESPONSIVE_LAYOUT_VALUE: {
shouldUseNarrowLayout: true,
isSmallScreenWidth: true,
isInNarrowPaneModal: false,
isExtraSmallScreenHeight: false,
isMediumScreenWidth: false,
isLargeScreenWidth: false,
isExtraSmallScreenWidth: false,
isSmallScreen: false,
onboardingIsMediumOrLargerScreenWidth: false,
} as ResponsiveLayoutResult,
},
} as const;

type Country = keyof typeof CONST.ALL_COUNTRIES;
Expand Down
439 changes: 439 additions & 0 deletions tests/navigation/GoBackTests.tsx

Large diffs are not rendered by default.

184 changes: 184 additions & 0 deletions tests/navigation/NavigateTests.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
import {act, render} from '@testing-library/react-native';
import React from 'react';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import getIsNarrowLayout from '@libs/getIsNarrowLayout';
import Navigation from '@libs/Navigation/Navigation';
import navigationRef from '@libs/Navigation/navigationRef';
import CONST from '@src/CONST';
import NAVIGATORS from '@src/NAVIGATORS';
import ROUTES from '@src/ROUTES';
import SCREENS from '@src/SCREENS';
import TestNavigationContainer from '../utils/TestNavigationContainer';

jest.mock('@hooks/useResponsiveLayout', () => jest.fn());
jest.mock('@libs/getIsNarrowLayout', () => jest.fn());

jest.mock('@pages/home/sidebar/BottomTabAvatar');

const mockedGetIsNarrowLayout = getIsNarrowLayout as jest.MockedFunction<typeof getIsNarrowLayout>;
const mockedUseResponsiveLayout = useResponsiveLayout as jest.MockedFunction<typeof useResponsiveLayout>;

describe('Navigate', () => {
beforeEach(() => {
mockedGetIsNarrowLayout.mockReturnValue(true);
mockedUseResponsiveLayout.mockReturnValue({...CONST.NAVIGATION_TESTS.DEFAULT_USE_RESPONSIVE_LAYOUT_VALUE, shouldUseNarrowLayout: true});
});

describe('on the narrow layout', () => {
it('to the page within the same navigator', () => {
// Given the initialized navigation on the narrow layout with the settings split navigator
render(
<TestNavigationContainer
initialState={{
index: 0,
routes: [
{
name: NAVIGATORS.SETTINGS_SPLIT_NAVIGATOR,
state: {
index: 0,
routes: [
{
name: SCREENS.SETTINGS.ROOT,
},
],
},
},
],
}}
/>,
);

const settingsSplitBeforeGoBack = navigationRef.current?.getRootState().routes.at(0);
expect(settingsSplitBeforeGoBack?.state?.index).toBe(0);
expect(settingsSplitBeforeGoBack?.state?.routes.at(-1)?.name).toBe(SCREENS.SETTINGS.ROOT);

// When navigate to the page from the same split navigator
act(() => {
Navigation.navigate(ROUTES.SETTINGS_PROFILE);
});

// Then push a new page to the current split navigator
const settingsSplitAfterGoBack = navigationRef.current?.getRootState().routes.at(0);
expect(settingsSplitAfterGoBack?.state?.index).toBe(1);
expect(settingsSplitAfterGoBack?.state?.routes.at(-1)?.name).toBe(SCREENS.SETTINGS.PROFILE.ROOT);
});

it('to the page within the same navigator using replace action', () => {
// Given the initialized navigation on the narrow layout with the settings split navigator
render(
<TestNavigationContainer
initialState={{
index: 0,
routes: [
{
name: NAVIGATORS.SETTINGS_SPLIT_NAVIGATOR,
state: {
index: 1,
routes: [
{
name: SCREENS.SETTINGS.ROOT,
},
{
name: SCREENS.SETTINGS.PROFILE.ROOT,
},
],
},
},
],
}}
/>,
);

const settingsSplitBeforeGoBack = navigationRef.current?.getRootState().routes.at(0);
expect(settingsSplitBeforeGoBack?.state?.index).toBe(1);
expect(settingsSplitBeforeGoBack?.state?.routes.at(-1)?.name).toBe(SCREENS.SETTINGS.PROFILE.ROOT);

// When navigate to the page from the same split navigator using replace action
act(() => {
Navigation.navigate(ROUTES.SETTINGS_ABOUT, CONST.NAVIGATION.ACTION_TYPE.REPLACE);
});

// Then replace the current page with the page passed to the navigate function
const settingsSplitAfterGoBack = navigationRef.current?.getRootState().routes.at(0);
expect(settingsSplitAfterGoBack?.state?.index).toBe(1);
expect(settingsSplitAfterGoBack?.state?.routes.at(-1)?.name).toBe(SCREENS.SETTINGS.ABOUT);
});

it('to the page from the different split navigator', () => {
// Given the initialized navigation on the narrow layout with the settings split navigator
render(
<TestNavigationContainer
initialState={{
index: 0,
routes: [
{
name: NAVIGATORS.SETTINGS_SPLIT_NAVIGATOR,
state: {
index: 0,
routes: [
{
name: SCREENS.SETTINGS.ROOT,
},
],
},
},
],
}}
/>,
);

const rootStateBeforeNavigate = navigationRef.current?.getRootState();
const lastSplitBeforeNavigate = rootStateBeforeNavigate?.routes.at(-1);
expect(rootStateBeforeNavigate?.index).toBe(0);
expect(lastSplitBeforeNavigate?.name).toBe(NAVIGATORS.SETTINGS_SPLIT_NAVIGATOR);
expect(lastSplitBeforeNavigate?.state?.routes.at(-1)?.name).toBe(SCREENS.SETTINGS.ROOT);

// When navigate to the page from the different split navigator
act(() => {
Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute('1'));
});

// Then push a new split navigator to the navigation state
const rootStateAfterNavigate = navigationRef.current?.getRootState();
const lastSplitAfterNavigate = rootStateAfterNavigate?.routes.at(-1);
expect(rootStateAfterNavigate?.index).toBe(1);
expect(lastSplitAfterNavigate?.name).toBe(NAVIGATORS.REPORTS_SPLIT_NAVIGATOR);
});

it('to the report split from the search page passing the active workspace id', () => {
// Given the initialized navigation on the narrow layout with the search page with the active workspace id
render(
<TestNavigationContainer
initialState={{
index: 0,
routes: [
{
name: SCREENS.SEARCH.ROOT,
params: {
q: 'type:expense status:all sortBy:date sortOrder:desc policyID:1',
},
},
],
}}
/>,
);

const rootStateBeforeNavigate = navigationRef.current?.getRootState();
const lastSplitBeforeNavigate = rootStateBeforeNavigate?.routes.at(-1);
expect(rootStateBeforeNavigate?.index).toBe(0);
expect(lastSplitBeforeNavigate?.name).toBe(SCREENS.SEARCH.ROOT);

// When navigate to the Home page when the active workspace is set
act(() => {
Navigation.navigate(ROUTES.HOME);
});

// Then push a new report split navigator with policyID in params
const rootStateAfterNavigate = navigationRef.current?.getRootState();
const lastSplitAfterNavigate = rootStateAfterNavigate?.routes.at(-1);
expect(rootStateAfterNavigate?.index).toBe(1);
expect(lastSplitAfterNavigate?.name).toBe(NAVIGATORS.REPORTS_SPLIT_NAVIGATOR);
expect(lastSplitAfterNavigate?.params).toMatchObject({policyID: '1'});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {NavigationContainer} from '@react-navigation/native';
import {render, renderHook} from '@testing-library/react-native';
import React from 'react';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import type ResponsiveLayoutResult from '@hooks/useResponsiveLayout/types';
import getIsNarrowLayout from '@libs/getIsNarrowLayout';
import createSplitNavigator from '@libs/Navigation/AppNavigator/createSplitNavigator';
import useNavigationResetOnLayoutChange from '@libs/Navigation/AppNavigator/useNavigationResetOnLayoutChange';
Expand All @@ -12,6 +11,7 @@ import type {CustomEffectsHookProps} from '@libs/Navigation/PlatformStackNavigat
import type {SettingsSplitNavigatorParamList} from '@libs/Navigation/types';
import InitialSettingsPage from '@pages/settings/InitialSettingsPage';
import ProfilePage from '@pages/settings/Profile/ProfilePage';
import CONST from '@src/CONST';
import SCREENS from '@src/SCREENS';

const Split = createSplitNavigator<SettingsSplitNavigatorParamList>();
Expand All @@ -22,18 +22,6 @@ jest.mock('@libs/getIsNarrowLayout', () => jest.fn());
jest.mock('@pages/settings/InitialSettingsPage');
jest.mock('@pages/settings/Profile/ProfilePage');

const DEFAULT_USE_RESPONSIVE_LAYOUT_VALUE: ResponsiveLayoutResult = {
shouldUseNarrowLayout: true,
isSmallScreenWidth: true,
isInNarrowPaneModal: false,
isExtraSmallScreenHeight: false,
isMediumScreenWidth: false,
isLargeScreenWidth: false,
isExtraSmallScreenWidth: false,
isSmallScreen: false,
onboardingIsMediumOrLargerScreenWidth: false,
};

const INITIAL_STATE = {
index: 0,
routes: [
Expand All @@ -43,16 +31,14 @@ const INITIAL_STATE = {
],
};

const PARENT_ROUTE = {key: 'parentRouteKey', name: 'ParentNavigator'};

const mockedGetIsNarrowLayout = getIsNarrowLayout as jest.MockedFunction<typeof getIsNarrowLayout>;
const mockedUseResponsiveLayout = useResponsiveLayout as jest.MockedFunction<typeof useResponsiveLayout>;

describe('Resize screen', () => {
it('Should display the settings profile after resizing the screen with the settings page opened to the wide layout', () => {
// Given the initialized navigation on the narrow layout with the settings screen
mockedGetIsNarrowLayout.mockReturnValue(true);
mockedUseResponsiveLayout.mockReturnValue({...DEFAULT_USE_RESPONSIVE_LAYOUT_VALUE, shouldUseNarrowLayout: true});
mockedUseResponsiveLayout.mockReturnValue({...CONST.NAVIGATION_TESTS.DEFAULT_USE_RESPONSIVE_LAYOUT_VALUE, shouldUseNarrowLayout: true});

render(
<NavigationContainer
Expand All @@ -62,7 +48,7 @@ describe('Resize screen', () => {
<Split.Navigator
sidebarScreen={SCREENS.SETTINGS.ROOT}
defaultCentralScreen={SCREENS.SETTINGS.PROFILE.ROOT}
parentRoute={PARENT_ROUTE}
parentRoute={CONST.NAVIGATION_TESTS.DEFAULT_PARENT_ROUTE}
>
<Split.Screen
name={SCREENS.SETTINGS.ROOT}
Expand Down Expand Up @@ -93,7 +79,7 @@ describe('Resize screen', () => {

// When resizing the screen to the wide layout
mockedGetIsNarrowLayout.mockReturnValue(false);
mockedUseResponsiveLayout.mockReturnValue({...DEFAULT_USE_RESPONSIVE_LAYOUT_VALUE, shouldUseNarrowLayout: false});
mockedUseResponsiveLayout.mockReturnValue({...CONST.NAVIGATION_TESTS.DEFAULT_USE_RESPONSIVE_LAYOUT_VALUE, shouldUseNarrowLayout: false});
rerender({});

const rootStateAfterResize = navigationRef.current?.getRootState();
Expand Down
Loading
Loading