From e4677c68ed9a9984943b24d3fffbd031b5b32dbe Mon Sep 17 00:00:00 2001 From: HIMANSHU Date: Mon, 8 Apr 2024 16:04:51 +0530 Subject: [PATCH 1/9] test for setting top level navogator in root component --- app/scenes/RootScreen/index.js | 8 ++++---- app/scenes/RootScreen/tests/index.test.js | 15 ++++++++++++++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/app/scenes/RootScreen/index.js b/app/scenes/RootScreen/index.js index 122c23f..4acc3ec 100644 --- a/app/scenes/RootScreen/index.js +++ b/app/scenes/RootScreen/index.js @@ -7,16 +7,15 @@ import Container from '@atoms/Container'; import { rootScreenActions } from './reducer'; import React, { useEffect } from 'react'; +const setRefForTopLevelNavigtor = navigatorRef => { + NavigationService.setTopLevelNavigator(navigatorRef); +}; const RootScreen = props => { useEffect(() => { // Run the startup function when the component mounts props.startup(); }, []); - const setRefForTopLevelNavigtor = navigatorRef => { - NavigationService.setTopLevelNavigator(navigatorRef); - }; - return ( @@ -33,3 +32,4 @@ const mapDispatchToProps = dispatch => ({ }); export default connect(null, mapDispatchToProps)(RootScreen); export { RootScreen as RootScreenTest }; +export { setRefForTopLevelNavigtor }; diff --git a/app/scenes/RootScreen/tests/index.test.js b/app/scenes/RootScreen/tests/index.test.js index a93ddc6..ba20801 100644 --- a/app/scenes/RootScreen/tests/index.test.js +++ b/app/scenes/RootScreen/tests/index.test.js @@ -6,8 +6,12 @@ import React from 'react'; import { renderWithIntl } from 'app/utils/testUtils'; -import { RootScreenTest } from '../index'; +import { RootScreenTest, setRefForTopLevelNavigtor } from '../index'; +import NavigationService from '@services/NavigationService'; export const setupJest = () => ({ submitSpy: jest.fn() }); +jest.mock('@services/NavigationService', () => ({ + setTopLevelNavigator: jest.fn() +})); describe(' container', () => { it('should render and match the snapshot', () => { const { submitSpy } = setupJest(); @@ -29,4 +33,13 @@ describe(' container', () => { expect(getByTestId('root-screen').type).toBe('View'); expect(submitSpy).toHaveBeenCalled(); }); + describe('setRefForTopLevelNavigtor', () => { + it('sets top-level navigator reference using NavigationService', () => { + const navigatorRef = { navigation: { dispatch: jest.fn() } }; // Mock navigator reference + setRefForTopLevelNavigtor(navigatorRef); + expect(NavigationService.setTopLevelNavigator).toHaveBeenCalledWith( + navigatorRef + ); + }); + }); }); From 1f90a442ef1e89229645fefdee307bcf7c28fe5d Mon Sep 17 00:00:00 2001 From: HIMANSHU Date: Mon, 8 Apr 2024 20:39:02 +0530 Subject: [PATCH 2/9] test for action.js --- app/scenes/RootScreen/index.js | 6 +----- app/scenes/RootScreen/tests/index.test.js | 12 +----------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/app/scenes/RootScreen/index.js b/app/scenes/RootScreen/index.js index 4acc3ec..7818b4a 100644 --- a/app/scenes/RootScreen/index.js +++ b/app/scenes/RootScreen/index.js @@ -1,15 +1,12 @@ import { connect } from 'react-redux'; import { PropTypes } from 'prop-types'; -import NavigationService from '@services/NavigationService'; import AppNavigator from '@navigators/AppNavigator'; import Container from '@atoms/Container'; import { rootScreenActions } from './reducer'; import React, { useEffect } from 'react'; +import setRefForTopLevelNavigtor from '@app/services/NavigationService'; -const setRefForTopLevelNavigtor = navigatorRef => { - NavigationService.setTopLevelNavigator(navigatorRef); -}; const RootScreen = props => { useEffect(() => { // Run the startup function when the component mounts @@ -32,4 +29,3 @@ const mapDispatchToProps = dispatch => ({ }); export default connect(null, mapDispatchToProps)(RootScreen); export { RootScreen as RootScreenTest }; -export { setRefForTopLevelNavigtor }; diff --git a/app/scenes/RootScreen/tests/index.test.js b/app/scenes/RootScreen/tests/index.test.js index ba20801..e81f8e8 100644 --- a/app/scenes/RootScreen/tests/index.test.js +++ b/app/scenes/RootScreen/tests/index.test.js @@ -6,8 +6,7 @@ import React from 'react'; import { renderWithIntl } from 'app/utils/testUtils'; -import { RootScreenTest, setRefForTopLevelNavigtor } from '../index'; -import NavigationService from '@services/NavigationService'; +import { RootScreenTest } from '../index'; export const setupJest = () => ({ submitSpy: jest.fn() }); jest.mock('@services/NavigationService', () => ({ setTopLevelNavigator: jest.fn() @@ -33,13 +32,4 @@ describe(' container', () => { expect(getByTestId('root-screen').type).toBe('View'); expect(submitSpy).toHaveBeenCalled(); }); - describe('setRefForTopLevelNavigtor', () => { - it('sets top-level navigator reference using NavigationService', () => { - const navigatorRef = { navigation: { dispatch: jest.fn() } }; // Mock navigator reference - setRefForTopLevelNavigtor(navigatorRef); - expect(NavigationService.setTopLevelNavigator).toHaveBeenCalledWith( - navigatorRef - ); - }); - }); }); From c62a33971f54ef478b66a199890116d13f6cfef1 Mon Sep 17 00:00:00 2001 From: HIMANSHU Date: Tue, 9 Apr 2024 13:19:34 +0530 Subject: [PATCH 3/9] removed unused code --- app/scenes/RootScreen/tests/index.test.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/scenes/RootScreen/tests/index.test.js b/app/scenes/RootScreen/tests/index.test.js index e81f8e8..a93ddc6 100644 --- a/app/scenes/RootScreen/tests/index.test.js +++ b/app/scenes/RootScreen/tests/index.test.js @@ -8,9 +8,6 @@ import React from 'react'; import { renderWithIntl } from 'app/utils/testUtils'; import { RootScreenTest } from '../index'; export const setupJest = () => ({ submitSpy: jest.fn() }); -jest.mock('@services/NavigationService', () => ({ - setTopLevelNavigator: jest.fn() -})); describe(' container', () => { it('should render and match the snapshot', () => { const { submitSpy } = setupJest(); From 8e5b9b7a3870f2c595b37a92dd6a0d154956c4e0 Mon Sep 17 00:00:00 2001 From: HIMANSHU Date: Mon, 8 Apr 2024 17:15:47 +0530 Subject: [PATCH 4/9] Added test for notification service --- app/services/NavigationService.js | 4 ++-- app/services/NavigationService.test.js | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 app/services/NavigationService.test.js diff --git a/app/services/NavigationService.js b/app/services/NavigationService.js index 467c8ac..5557975 100644 --- a/app/services/NavigationService.js +++ b/app/services/NavigationService.js @@ -6,14 +6,14 @@ import set from 'lodash/set'; * * @see https://reactnavigation.org/docs/en/navigating-without-navigation-prop.html */ -const navigatorObject = { +export const navigatorObject = { navigator: null }; /** * This function is called when the RootScreen is created to set the navigator instance to use. */ -const setTopLevelNavigator = navigatorRef => { +export const setTopLevelNavigator = navigatorRef => { set(navigatorObject, 'navigator', navigatorRef); }; diff --git a/app/services/NavigationService.test.js b/app/services/NavigationService.test.js new file mode 100644 index 0000000..da55acd --- /dev/null +++ b/app/services/NavigationService.test.js @@ -0,0 +1,20 @@ +import { setTopLevelNavigator, navigatorObject } from './NavigationService'; +import { set } from 'lodash'; +jest.mock('lodash', () => ({ + set: jest.fn() +})); + +describe('setTopLevelNavigator', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + it('sets the navigator object with the provided reference', () => { + const navigatorRef = { goBack: 'goBack' }; + setTopLevelNavigator(navigatorRef); + expect(set).toHaveBeenCalledWith( + navigatorObject, + 'navigator', + navigatorRef + ); + }); +}); From 9c9a24732cde762f28a985df1b91e3c61e227b3d Mon Sep 17 00:00:00 2001 From: HIMANSHU Date: Mon, 8 Apr 2024 19:57:41 +0530 Subject: [PATCH 5/9] navigate function tests --- app/services/NavigationService.js | 2 +- app/services/NavigationService.test.js | 47 +++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/app/services/NavigationService.js b/app/services/NavigationService.js index 5557975..37c0159 100644 --- a/app/services/NavigationService.js +++ b/app/services/NavigationService.js @@ -23,7 +23,7 @@ export const setTopLevelNavigator = navigatorRef => { * @param routeName The name of the route to navigate to. Routes are defined in RootScreen using createStackNavigator() * @param params Route parameters. */ -function navigate(routeName, params) { +export function navigate(routeName, params) { navigatorObject.navigator.dispatch( NavigationActions.navigate({ routeName, diff --git a/app/services/NavigationService.test.js b/app/services/NavigationService.test.js index da55acd..85da051 100644 --- a/app/services/NavigationService.test.js +++ b/app/services/NavigationService.test.js @@ -1,5 +1,11 @@ -import { setTopLevelNavigator, navigatorObject } from './NavigationService'; +import { + setTopLevelNavigator, + navigatorObject, + navigate +} from './NavigationService'; import { set } from 'lodash'; +import { NavigationActions } from '@react-navigation/compat'; + jest.mock('lodash', () => ({ set: jest.fn() })); @@ -18,3 +24,42 @@ describe('setTopLevelNavigator', () => { ); }); }); + +const mockDispatch = jest.fn(); + +// Mock the NavigationActions.navigate function +jest.mock('@react-navigation/compat', () => ({ + NavigationActions: { + navigate: jest.fn() + } +})); + +describe('navigate', () => { + beforeEach(() => { + // eslint-disable-next-line fp/no-mutation + navigatorObject.navigator = { dispatch: mockDispatch }; + }); + + afterEach(() => { + // Reset mocks after each test + jest.clearAllMocks(); + }); + + it('dispatches navigation action with the correct routeName and params', () => { + const routeName = '/home'; + const params = { screen: 'exampleScreen' }; + NavigationActions.navigate.mockReturnValueOnce({ + type: 'NAVIGATE_ACTION', + payload: { routeName, params } + }); + navigate(routeName, params); + expect(NavigationActions.navigate).toHaveBeenCalledWith({ + routeName, + params + }); + expect(mockDispatch).toHaveBeenCalledWith({ + type: 'NAVIGATE_ACTION', + payload: { routeName, params } + }); + }); +}); From 848e3ffc453c63109726965ebba084bf0b7c0e34 Mon Sep 17 00:00:00 2001 From: HIMANSHU Date: Mon, 8 Apr 2024 20:29:26 +0530 Subject: [PATCH 6/9] neater services tests --- app/services/NavigationService.js | 2 +- app/services/{ => tests}/UserService.test.js | 2 +- .../navigate.test.js} | 34 ++--------------- app/services/tests/navigateAndReset.test.js | 38 +++++++++++++++++++ .../tests/setTopLevelNavigation.test.js | 21 ++++++++++ 5 files changed, 64 insertions(+), 33 deletions(-) rename app/services/{ => tests}/UserService.test.js (94%) rename app/services/{NavigationService.test.js => tests/navigate.test.js} (58%) create mode 100644 app/services/tests/navigateAndReset.test.js create mode 100644 app/services/tests/setTopLevelNavigation.test.js diff --git a/app/services/NavigationService.js b/app/services/NavigationService.js index 37c0159..5dc9f43 100644 --- a/app/services/NavigationService.js +++ b/app/services/NavigationService.js @@ -41,7 +41,7 @@ export function navigate(routeName, params) { * @param routeName The name of the route to navigate to. Routes are defined in RootScreen using createStackNavigator() * @param params Route parameters. */ -function navigateAndReset(routeName, params) { +export function navigateAndReset(routeName, params) { navigatorObject.navigator.dispatch( StackActions.replace({ routeName, diff --git a/app/services/UserService.test.js b/app/services/tests/UserService.test.js similarity index 94% rename from app/services/UserService.test.js rename to app/services/tests/UserService.test.js index 53cbead..a8155f7 100644 --- a/app/services/UserService.test.js +++ b/app/services/tests/UserService.test.js @@ -1,6 +1,6 @@ import MockAdapter from 'axios-mock-adapter'; import { getApiClient } from 'app/utils/apiUtils'; -import { getUser } from './UserService'; +import { getUser } from '../UserService'; describe('UserService tests', () => { it('should make the api call to "/quotes?count=1"', async () => { diff --git a/app/services/NavigationService.test.js b/app/services/tests/navigate.test.js similarity index 58% rename from app/services/NavigationService.test.js rename to app/services/tests/navigate.test.js index 85da051..61d09fe 100644 --- a/app/services/NavigationService.test.js +++ b/app/services/tests/navigate.test.js @@ -1,43 +1,15 @@ -import { - setTopLevelNavigator, - navigatorObject, - navigate -} from './NavigationService'; +import { navigatorObject, navigate } from '../NavigationService'; import { set } from 'lodash'; import { NavigationActions } from '@react-navigation/compat'; - -jest.mock('lodash', () => ({ - set: jest.fn() -})); - -describe('setTopLevelNavigator', () => { - afterEach(() => { - jest.clearAllMocks(); - }); - it('sets the navigator object with the provided reference', () => { - const navigatorRef = { goBack: 'goBack' }; - setTopLevelNavigator(navigatorRef); - expect(set).toHaveBeenCalledWith( - navigatorObject, - 'navigator', - navigatorRef - ); - }); -}); - -const mockDispatch = jest.fn(); - -// Mock the NavigationActions.navigate function jest.mock('@react-navigation/compat', () => ({ NavigationActions: { navigate: jest.fn() } })); - +const mockDispatch = jest.fn(); describe('navigate', () => { beforeEach(() => { - // eslint-disable-next-line fp/no-mutation - navigatorObject.navigator = { dispatch: mockDispatch }; + set(navigatorObject, 'navigator', { dispatch: mockDispatch }); }); afterEach(() => { diff --git a/app/services/tests/navigateAndReset.test.js b/app/services/tests/navigateAndReset.test.js new file mode 100644 index 0000000..33aff84 --- /dev/null +++ b/app/services/tests/navigateAndReset.test.js @@ -0,0 +1,38 @@ +import { navigatorObject, navigateAndReset } from '../NavigationService'; +import { set } from 'lodash'; +import { StackActions } from '@react-navigation/compat'; + +jest.mock('@react-navigation/compat', () => ({ + StackActions: { + replace: jest.fn() + } +})); +const mockDispatch = jest.fn(); +describe('test navigateAndReset', () => { + beforeEach(() => { + set(navigatorObject, 'navigator', { dispatch: mockDispatch }); + }); + + afterEach(() => { + // Reset mocks after each test + jest.clearAllMocks(); + }); + + it('dispatches stack action with the correct routeName and params', () => { + const routeName = '/home'; + const params = { screen: 'exampleScreen' }; + StackActions.replace.mockReturnValueOnce({ + type: 'homeScreen', + payload: { routeName, params } + }); + navigateAndReset(routeName, params); + expect(StackActions.replace).toHaveBeenCalledWith({ + routeName, + params + }); + expect(mockDispatch).toHaveBeenCalledWith({ + type: 'homeScreen', + payload: { routeName, params } + }); + }); +}); diff --git a/app/services/tests/setTopLevelNavigation.test.js b/app/services/tests/setTopLevelNavigation.test.js new file mode 100644 index 0000000..fad61da --- /dev/null +++ b/app/services/tests/setTopLevelNavigation.test.js @@ -0,0 +1,21 @@ +import { setTopLevelNavigator, navigatorObject } from '../NavigationService'; +import { set } from 'lodash'; + +jest.mock('lodash', () => ({ + set: jest.fn() +})); + +describe('setTopLevelNavigator', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + it('sets the navigator object with the provided reference', () => { + const navigatorRef = { goBack: 'goBack' }; + setTopLevelNavigator(navigatorRef); + expect(set).toHaveBeenCalledWith( + navigatorObject, + 'navigator', + navigatorRef + ); + }); +}); From 40f14158f5a6eee0dcd7b6ad7af861b468b96a98 Mon Sep 17 00:00:00 2001 From: HIMANSHU Date: Tue, 9 Apr 2024 15:19:33 +0530 Subject: [PATCH 7/9] neater navigation test --- app/scenes/RootScreen/index.js | 5 ++--- app/services/NavigationService.js | 6 +++--- app/services/tests/navigate.test.js | 8 +++++--- app/services/tests/navigateAndReset.test.js | 12 +++++++----- app/services/tests/setTopLevelNavigation.test.js | 12 +++++------- 5 files changed, 22 insertions(+), 21 deletions(-) diff --git a/app/scenes/RootScreen/index.js b/app/scenes/RootScreen/index.js index 7818b4a..be51f58 100644 --- a/app/scenes/RootScreen/index.js +++ b/app/scenes/RootScreen/index.js @@ -2,10 +2,9 @@ import { connect } from 'react-redux'; import { PropTypes } from 'prop-types'; import AppNavigator from '@navigators/AppNavigator'; import Container from '@atoms/Container'; - import { rootScreenActions } from './reducer'; import React, { useEffect } from 'react'; -import setRefForTopLevelNavigtor from '@app/services/NavigationService'; +import NavigationService from '@app/services/NavigationService'; const RootScreen = props => { useEffect(() => { @@ -15,7 +14,7 @@ const RootScreen = props => { return ( - + ); }; diff --git a/app/services/NavigationService.js b/app/services/NavigationService.js index 5dc9f43..3f9446c 100644 --- a/app/services/NavigationService.js +++ b/app/services/NavigationService.js @@ -13,7 +13,7 @@ export const navigatorObject = { * This function is called when the RootScreen is created to set the navigator instance to use. */ -export const setTopLevelNavigator = navigatorRef => { +const setTopLevelNavigator = navigatorRef => { set(navigatorObject, 'navigator', navigatorRef); }; @@ -23,7 +23,7 @@ export const setTopLevelNavigator = navigatorRef => { * @param routeName The name of the route to navigate to. Routes are defined in RootScreen using createStackNavigator() * @param params Route parameters. */ -export function navigate(routeName, params) { +function navigate(routeName, params) { navigatorObject.navigator.dispatch( NavigationActions.navigate({ routeName, @@ -41,7 +41,7 @@ export function navigate(routeName, params) { * @param routeName The name of the route to navigate to. Routes are defined in RootScreen using createStackNavigator() * @param params Route parameters. */ -export function navigateAndReset(routeName, params) { +function navigateAndReset(routeName, params) { navigatorObject.navigator.dispatch( StackActions.replace({ routeName, diff --git a/app/services/tests/navigate.test.js b/app/services/tests/navigate.test.js index 61d09fe..a474add 100644 --- a/app/services/tests/navigate.test.js +++ b/app/services/tests/navigate.test.js @@ -1,4 +1,5 @@ -import { navigatorObject, navigate } from '../NavigationService'; +import { navigatorObject } from '../NavigationService'; +import NavigationService from '@app/services/NavigationService'; import { set } from 'lodash'; import { NavigationActions } from '@react-navigation/compat'; jest.mock('@react-navigation/compat', () => ({ @@ -8,6 +9,7 @@ jest.mock('@react-navigation/compat', () => ({ })); const mockDispatch = jest.fn(); describe('navigate', () => { + const { navigate } = NavigationService; beforeEach(() => { set(navigatorObject, 'navigator', { dispatch: mockDispatch }); }); @@ -18,8 +20,8 @@ describe('navigate', () => { }); it('dispatches navigation action with the correct routeName and params', () => { - const routeName = '/home'; - const params = { screen: 'exampleScreen' }; + const routeName = '/test'; + const params = { screen: 'MainScreen' }; NavigationActions.navigate.mockReturnValueOnce({ type: 'NAVIGATE_ACTION', payload: { routeName, params } diff --git a/app/services/tests/navigateAndReset.test.js b/app/services/tests/navigateAndReset.test.js index 33aff84..e517606 100644 --- a/app/services/tests/navigateAndReset.test.js +++ b/app/services/tests/navigateAndReset.test.js @@ -1,4 +1,5 @@ -import { navigatorObject, navigateAndReset } from '../NavigationService'; +import { navigatorObject } from '../NavigationService'; +import NavigationService from '@app/services/NavigationService'; import { set } from 'lodash'; import { StackActions } from '@react-navigation/compat'; @@ -9,6 +10,7 @@ jest.mock('@react-navigation/compat', () => ({ })); const mockDispatch = jest.fn(); describe('test navigateAndReset', () => { + const { navigateAndReset } = NavigationService; beforeEach(() => { set(navigatorObject, 'navigator', { dispatch: mockDispatch }); }); @@ -19,10 +21,10 @@ describe('test navigateAndReset', () => { }); it('dispatches stack action with the correct routeName and params', () => { - const routeName = '/home'; - const params = { screen: 'exampleScreen' }; + const routeName = '/test'; + const params = { screen: 'MainScreen' }; StackActions.replace.mockReturnValueOnce({ - type: 'homeScreen', + type: 'NAVIGATE_ACTION', payload: { routeName, params } }); navigateAndReset(routeName, params); @@ -31,7 +33,7 @@ describe('test navigateAndReset', () => { params }); expect(mockDispatch).toHaveBeenCalledWith({ - type: 'homeScreen', + type: 'NAVIGATE_ACTION', payload: { routeName, params } }); }); diff --git a/app/services/tests/setTopLevelNavigation.test.js b/app/services/tests/setTopLevelNavigation.test.js index fad61da..7477f81 100644 --- a/app/services/tests/setTopLevelNavigation.test.js +++ b/app/services/tests/setTopLevelNavigation.test.js @@ -1,11 +1,9 @@ -import { setTopLevelNavigator, navigatorObject } from '../NavigationService'; -import { set } from 'lodash'; - -jest.mock('lodash', () => ({ - set: jest.fn() -})); - +import { navigatorObject } from '../NavigationService'; +import set from 'lodash/set'; +import NavigationService from '@app/services/NavigationService'; +jest.mock('lodash/set', () => jest.fn()); describe('setTopLevelNavigator', () => { + const { setTopLevelNavigator } = NavigationService; afterEach(() => { jest.clearAllMocks(); }); From 4d5476ee569ee37b3083f06f771c9cf4b5d6c8db Mon Sep 17 00:00:00 2001 From: HIMANSHU Date: Tue, 9 Apr 2024 17:37:50 +0530 Subject: [PATCH 8/9] feat: interim --- app/services/NavigationService.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/NavigationService.js b/app/services/NavigationService.js index 3f9446c..467c8ac 100644 --- a/app/services/NavigationService.js +++ b/app/services/NavigationService.js @@ -6,7 +6,7 @@ import set from 'lodash/set'; * * @see https://reactnavigation.org/docs/en/navigating-without-navigation-prop.html */ -export const navigatorObject = { +const navigatorObject = { navigator: null }; /** From 1f1cc25b1b50879be644d4cd159fb8d9c83951c4 Mon Sep 17 00:00:00 2001 From: HIMANSHU Date: Tue, 9 Apr 2024 20:52:13 +0530 Subject: [PATCH 9/9] neater tests --- app/navigators/AppNavigator.js | 4 ++-- app/scenes/RootScreen/index.js | 4 ++-- app/scenes/RootScreen/saga.js | 4 ++-- app/scenes/RootScreen/tests/saga.test.js | 22 ++++++++++++------- app/services/NavigationService.js | 6 +---- app/services/tests/navigate.test.js | 15 ++++--------- app/services/tests/navigateAndReset.test.js | 14 ++++-------- .../tests/setTopLevelNavigation.test.js | 7 +++--- 8 files changed, 33 insertions(+), 43 deletions(-) diff --git a/app/navigators/AppNavigator.js b/app/navigators/AppNavigator.js index d3baa1c..b03dff6 100644 --- a/app/navigators/AppNavigator.js +++ b/app/navigators/AppNavigator.js @@ -3,7 +3,7 @@ import { createStackNavigator } from '@react-navigation/stack'; import SplashScreen from '@scenes/SplashScreen/'; import ExampleScreen from '@scenes/ExampleScreen'; import { NavigationContainer } from '@react-navigation/native'; -import NavigationService from '../services/NavigationService'; +import { setTopLevelNavigator } from '../services/NavigationService'; const Stack = createStackNavigator(); /** * The root screen contains the application's navigation. @@ -12,7 +12,7 @@ const Stack = createStackNavigator(); */ export default function AppNavigator() { return ( - + diff --git a/app/scenes/RootScreen/index.js b/app/scenes/RootScreen/index.js index be51f58..93f16f3 100644 --- a/app/scenes/RootScreen/index.js +++ b/app/scenes/RootScreen/index.js @@ -4,7 +4,7 @@ import AppNavigator from '@navigators/AppNavigator'; import Container from '@atoms/Container'; import { rootScreenActions } from './reducer'; import React, { useEffect } from 'react'; -import NavigationService from '@app/services/NavigationService'; +import { setRefForTopLevelNavigtor } from '@app/services/NavigationService'; const RootScreen = props => { useEffect(() => { @@ -14,7 +14,7 @@ const RootScreen = props => { return ( - + ); }; diff --git a/app/scenes/RootScreen/saga.js b/app/scenes/RootScreen/saga.js index 098f16e..a988d24 100644 --- a/app/scenes/RootScreen/saga.js +++ b/app/scenes/RootScreen/saga.js @@ -1,12 +1,12 @@ import { takeLatest } from 'redux-saga/effects'; -import NavigationService from '@app/services/NavigationService'; +import { navigateAndReset } from '@app/services/NavigationService'; import { rootScreenTypes } from './reducer'; /** * The startup saga is the place to define behavior to execute when the application starts. */ export function* startup() { - setTimeout(() => NavigationService.navigateAndReset('MainScreen'), 1000); + setTimeout(() => navigateAndReset('MainScreen'), 1000); } /** diff --git a/app/scenes/RootScreen/tests/saga.test.js b/app/scenes/RootScreen/tests/saga.test.js index f8ce417..c743c43 100644 --- a/app/scenes/RootScreen/tests/saga.test.js +++ b/app/scenes/RootScreen/tests/saga.test.js @@ -1,3 +1,4 @@ +/* eslint-disable sonarjs/no-duplicate-string */ /** * Test sagas */ @@ -5,12 +6,22 @@ /* eslint-disable redux-saga/yield-effects */ import { takeLatest } from 'redux-saga/effects'; -import NavigationService from 'app/services/NavigationService'; +// import NavigationService from 'app/services/NavigationService'; +import { navigateAndReset } from '@app/services/NavigationService'; import { timeout } from 'app/utils/testUtils'; import rootScreenSaga, { startup } from '../saga'; import { rootScreenTypes } from '../reducer'; import set from 'lodash/set'; + +const NavigationService = '@app/services/NavigationService'; +jest.mock('@app/services/NavigationService', () => ({ + ...jest.requireActual('@app/services/NavigationService'), + navigateAndReset: jest.fn() +})); describe('Tests for RootScreen sagas', () => { + afterEach(() => { + jest.clearAllMocks(); + }); const setupTests = () => ({ generator: rootScreenSaga(), submitSpy: jest.fn() @@ -25,15 +36,10 @@ describe('Tests for RootScreen sagas', () => { it('should ensure that the navigation service is called after waiting for 1000ms', async () => { const method = startup(); - NavigationService.setTopLevelNavigator({ dispatch: () => {} }); - const navigateAndResetSpy = jest.spyOn( - NavigationService, - 'navigateAndReset' - ); method.next(); await timeout(1000); - expect(navigateAndResetSpy).toHaveBeenCalled(); - expect(navigateAndResetSpy).toHaveBeenCalledWith('MainScreen'); + expect(navigateAndReset).toHaveBeenCalled(); + expect(navigateAndReset).toHaveBeenCalledWith('MainScreen'); }); it('should ensure that the navigation service is called after waiting for 1000ms', async () => { diff --git a/app/services/NavigationService.js b/app/services/NavigationService.js index 467c8ac..7b5ae4b 100644 --- a/app/services/NavigationService.js +++ b/app/services/NavigationService.js @@ -50,8 +50,4 @@ function navigateAndReset(routeName, params) { ); } -export default { - navigate, - navigateAndReset, - setTopLevelNavigator -}; +export { navigate, navigateAndReset, setTopLevelNavigator }; diff --git a/app/services/tests/navigate.test.js b/app/services/tests/navigate.test.js index a474add..fea5a93 100644 --- a/app/services/tests/navigate.test.js +++ b/app/services/tests/navigate.test.js @@ -1,21 +1,14 @@ -import { navigatorObject } from '../NavigationService'; -import NavigationService from '@app/services/NavigationService'; -import { set } from 'lodash'; +import { navigate, setTopLevelNavigator } from '../NavigationService'; import { NavigationActions } from '@react-navigation/compat'; jest.mock('@react-navigation/compat', () => ({ NavigationActions: { navigate: jest.fn() } })); -const mockDispatch = jest.fn(); +const navigatorRef = { goBack: 'goBack', dispatch: jest.fn() }; +setTopLevelNavigator(navigatorRef); describe('navigate', () => { - const { navigate } = NavigationService; - beforeEach(() => { - set(navigatorObject, 'navigator', { dispatch: mockDispatch }); - }); - afterEach(() => { - // Reset mocks after each test jest.clearAllMocks(); }); @@ -31,7 +24,7 @@ describe('navigate', () => { routeName, params }); - expect(mockDispatch).toHaveBeenCalledWith({ + expect(navigatorRef.dispatch).toHaveBeenCalledWith({ type: 'NAVIGATE_ACTION', payload: { routeName, params } }); diff --git a/app/services/tests/navigateAndReset.test.js b/app/services/tests/navigateAndReset.test.js index e517606..0a0df12 100644 --- a/app/services/tests/navigateAndReset.test.js +++ b/app/services/tests/navigateAndReset.test.js @@ -1,6 +1,4 @@ -import { navigatorObject } from '../NavigationService'; -import NavigationService from '@app/services/NavigationService'; -import { set } from 'lodash'; +import { setTopLevelNavigator, navigateAndReset } from '../NavigationService'; import { StackActions } from '@react-navigation/compat'; jest.mock('@react-navigation/compat', () => ({ @@ -8,13 +6,9 @@ jest.mock('@react-navigation/compat', () => ({ replace: jest.fn() } })); -const mockDispatch = jest.fn(); +const navigatorRef = { goBack: 'goBack', dispatch: jest.fn() }; +setTopLevelNavigator(navigatorRef); describe('test navigateAndReset', () => { - const { navigateAndReset } = NavigationService; - beforeEach(() => { - set(navigatorObject, 'navigator', { dispatch: mockDispatch }); - }); - afterEach(() => { // Reset mocks after each test jest.clearAllMocks(); @@ -32,7 +26,7 @@ describe('test navigateAndReset', () => { routeName, params }); - expect(mockDispatch).toHaveBeenCalledWith({ + expect(navigatorRef.dispatch).toHaveBeenCalledWith({ type: 'NAVIGATE_ACTION', payload: { routeName, params } }); diff --git a/app/services/tests/setTopLevelNavigation.test.js b/app/services/tests/setTopLevelNavigation.test.js index 7477f81..dcf2aa1 100644 --- a/app/services/tests/setTopLevelNavigation.test.js +++ b/app/services/tests/setTopLevelNavigation.test.js @@ -1,13 +1,14 @@ -import { navigatorObject } from '../NavigationService'; import set from 'lodash/set'; -import NavigationService from '@app/services/NavigationService'; +import { setTopLevelNavigator } from '../NavigationService'; jest.mock('lodash/set', () => jest.fn()); describe('setTopLevelNavigator', () => { - const { setTopLevelNavigator } = NavigationService; afterEach(() => { jest.clearAllMocks(); }); it('sets the navigator object with the provided reference', () => { + const navigatorObject = { + navigator: null + }; const navigatorRef = { goBack: 'goBack' }; setTopLevelNavigator(navigatorRef); expect(set).toHaveBeenCalledWith(