From c74f3152eb5f8034575733ef6cc22c2bf08dbb0c Mon Sep 17 00:00:00 2001 From: CD Cabrera Date: Mon, 20 Mar 2023 11:24:46 -0400 Subject: [PATCH] fix(platformServices): sw-625 restore onNavigate * authenticationContext, restore onNavigation callback * platformActions, restore onNavigation * redux, platformTypes, restore dispatch type * services, restore onNavigation --- src/components/README.md | 4 + .../__snapshots__/authentication.test.js.snap | 14 +-- .../authenticationContext.test.js.snap | 3 + .../__tests__/authentication.test.js | 27 +++++- .../__tests__/authenticationContext.test.js | 87 +++++++++++-------- .../authentication/authenticationContext.js | 17 +++- src/redux/README.md | 19 ++++ .../platformActions.test.js.snap | 4 + .../actions/__tests__/platformActions.test.js | 8 ++ src/redux/actions/platformActions.js | 19 +++- .../__snapshots__/index.test.js.snap | 4 + src/redux/types/platformTypes.js | 5 +- src/services/README.md | 19 ++++ .../__tests__/platformServices.test.js | 8 +- src/services/platform/platformServices.js | 20 ++++- tests/__snapshots__/dist.test.js.snap | 10 +-- 16 files changed, 208 insertions(+), 60 deletions(-) diff --git a/src/components/README.md b/src/components/README.md index 9cc623444..288a5cd8a 100644 --- a/src/components/README.md +++ b/src/components/README.md @@ -298,10 +298,14 @@ Initialize an app, and return a combined state store that includes authorization options.hideGlobalFilterfunction + options.onNavigationfunction + options.useChromefunction options.useDispatchfunction + options.useNavigatefunction + options.useSelectorsResponsefunction diff --git a/src/components/authentication/__tests__/__snapshots__/authentication.test.js.snap b/src/components/authentication/__tests__/__snapshots__/authentication.test.js.snap index 58dbd9365..dc264cf2a 100644 --- a/src/components/authentication/__tests__/__snapshots__/authentication.test.js.snap +++ b/src/components/authentication/__tests__/__snapshots__/authentication.test.js.snap @@ -4,9 +4,11 @@ exports[`Authentication Component should allow being disabled: disabled 1`] = ` @@ -27,9 +29,9 @@ exports[`Authentication Component should render a basic component: basic 1`] = ` diff --git a/src/components/authentication/__tests__/__snapshots__/authenticationContext.test.js.snap b/src/components/authentication/__tests__/__snapshots__/authenticationContext.test.js.snap index 16ab23006..b348ce345 100644 --- a/src/components/authentication/__tests__/__snapshots__/authenticationContext.test.js.snap +++ b/src/components/authentication/__tests__/__snapshots__/authenticationContext.test.js.snap @@ -76,6 +76,9 @@ exports[`AuthenticationContext should apply a hook for retrieving auth data from }, ], ], + [ + [Function], + ], ] `; diff --git a/src/components/authentication/__tests__/authentication.test.js b/src/components/authentication/__tests__/authentication.test.js index 8717a6b09..c45dd2788 100644 --- a/src/components/authentication/__tests__/authentication.test.js +++ b/src/components/authentication/__tests__/authentication.test.js @@ -5,8 +5,20 @@ import { rhsmConstants } from '../../../services/rhsm/rhsmConstants'; describe('Authentication Component', () => { it('should render a basic component', async () => { + const props = { + useGetAuthorization: () => ({ + error: false, + pending: false, + data: { + authorized: {}, + errorCodes: [], + errorStatus: undefined + } + }) + }; + const component = await shallowHookComponent( - + lorem ); @@ -37,7 +49,18 @@ describe('Authentication Component', () => { it('should allow being disabled', async () => { const props = { - isDisabled: true + isDisabled: true, + useGetAuthorization: () => ({ + error: false, + pending: false, + data: { + authorized: { + [helpers.UI_NAME]: true + }, + errorCodes: [], + errorStatus: undefined + } + }) }; const component = await shallowHookComponent( diff --git a/src/components/authentication/__tests__/authenticationContext.test.js b/src/components/authentication/__tests__/authenticationContext.test.js index 8881fb31b..ca82aee95 100644 --- a/src/components/authentication/__tests__/authenticationContext.test.js +++ b/src/components/authentication/__tests__/authenticationContext.test.js @@ -9,6 +9,7 @@ describe('AuthenticationContext', () => { it('should apply a hook for retrieving auth data from multiple selectors', async () => { const { result: errorResponse } = shallowHook(() => useGetAuthorization({ + useNavigate: () => jest.fn(), useSelectorsResponse: () => ({ error: true, data: { @@ -33,6 +34,7 @@ describe('AuthenticationContext', () => { const { result: successResponse } = await mountHook(() => useGetAuthorization({ useDispatch: () => mockDispatch, + useNavigate: () => jest.fn(), useSelectorsResponse: () => ({ fulfilled: true, data: { @@ -52,57 +54,66 @@ describe('AuthenticationContext', () => { expect(mockDispatch.mock.calls).toMatchSnapshot('success dispatch'); expect(successResponse).toMatchSnapshot('success response'); - const { result: mockStoreSuccessResponse } = shallowHook(() => useGetAuthorization(), { - state: { - user: { - auth: { - fulfilled: true, - data: [ - { isAdmin: true, isEntitled: true }, - { - permissions: [ - { - subscriptions: { - all: true, - resources: { - '*': { - '*': [], - loremCustom: [], - read: [] + const { result: mockStoreSuccessResponse } = shallowHook( + () => useGetAuthorization({ useNavigate: () => jest.fn() }), + { + state: { + user: { + auth: { + fulfilled: true, + data: [ + { isAdmin: true, isEntitled: true }, + { + permissions: [ + { + subscriptions: { + all: true, + resources: { + '*': { + '*': [], + loremCustom: [], + read: [] + } } } } + ], + authorized: { + subscriptions: true } - ], - authorized: { - subscriptions: true } - } - ] - }, - locale: { fulfilled: true, data: {} }, - errors: {} + ] + }, + locale: { fulfilled: true, data: {} }, + errors: {} + } } } - }); + ); expect(mockStoreSuccessResponse).toMatchSnapshot('mock store success response'); - const { result: mockStoreErrorResponse } = shallowHook(() => useGetAuthorization(), { - state: { - user: { - auth: { - error: true, - data: [] - }, - locale: { fulfilled: true, data: {} }, - errors: { - error: true, - data: ['lorem', 'ipsum'] + const { result: mockStoreErrorResponse } = shallowHook( + () => + useGetAuthorization({ + useNavigate: () => jest.fn() + }), + { + state: { + user: { + auth: { + error: true, + data: [] + }, + locale: { fulfilled: true, data: {} }, + errors: { + error: true, + data: ['lorem', 'ipsum'] + } } } } - }); + ); expect(mockStoreErrorResponse).toMatchSnapshot('mock store error response'); }); diff --git a/src/components/authentication/authenticationContext.js b/src/components/authentication/authenticationContext.js index 7361a4014..f511a6f82 100644 --- a/src/components/authentication/authenticationContext.js +++ b/src/components/authentication/authenticationContext.js @@ -1,9 +1,9 @@ -import React, { useContext } from 'react'; -import { useMount } from 'react-use'; +import React, { useContext, useState } from 'react'; +import { useMount, useUnmount } from 'react-use'; import { useChrome } from '@redhat-cloud-services/frontend-components/useChrome'; import { reduxActions, storeHooks } from '../../redux'; import { helpers } from '../../common'; -import { routerHelpers } from '../router'; +import { routerContext, routerHelpers } from '../router'; /** * @memberof Authentication @@ -33,8 +33,10 @@ const useAuthContext = () => useContext(AuthenticationContext); * @param {string} options.appName * @param {Function} options.authorizeUser * @param {Function} options.hideGlobalFilter + * @param {Function} options.onNavigation * @param {Function} options.useChrome * @param {Function} options.useDispatch + * @param {Function} options.useNavigate * @param {Function} options.useSelectorsResponse * @returns {{data: {errorCodes, errorStatus: *, locale}, pending: boolean, fulfilled: boolean, error: boolean}} */ @@ -42,10 +44,14 @@ const useGetAuthorization = ({ appName = routerHelpers.appName, authorizeUser = reduxActions.platform.authorizeUser, hideGlobalFilter = reduxActions.platform.hideGlobalFilter, + onNavigation = reduxActions.platform.onNavigation, useChrome: useAliasChrome = useChrome, useDispatch: useAliasDispatch = storeHooks.reactRedux.useDispatch, + useNavigate: useAliasNavigate = routerContext.useNavigate, useSelectorsResponse: useAliasSelectorsResponse = storeHooks.reactRedux.useSelectorsResponse } = {}) => { + const [unregister, setUnregister] = useState(() => helpers.noop); + const navigate = useAliasNavigate(); const dispatch = useAliasDispatch(); const { updateDocumentTitle = helpers.noop } = useAliasChrome(); const { data, error, fulfilled, pending, responses } = useAliasSelectorsResponse([ @@ -61,6 +67,11 @@ const useGetAuthorization = ({ await dispatch(authorizeUser()); updateDocumentTitle(appName); dispatch([hideGlobalFilter()]); + setUnregister(() => dispatch(onNavigation(event => navigate(event.navId)))); + }); + + useUnmount(() => { + unregister(); }); const [user = {}, app = {}] = (Array.isArray(data.auth) && data.auth) || []; diff --git a/src/redux/README.md b/src/redux/README.md index daf22d8e2..9f280a98a 100644 --- a/src/redux/README.md +++ b/src/redux/README.md @@ -80,6 +80,7 @@ Platform service wrappers for dispatch, state update. * [~clearNotifications()](#Actions.module_PlatformActions..clearNotifications) ⇒ \* * [~authorizeUser(appName)](#Actions.module_PlatformActions..authorizeUser) ⇒ function * [~hideGlobalFilter(isHidden)](#Actions.module_PlatformActions..hideGlobalFilter) ⇒ Object + * [~onNavigation(callback)](#Actions.module_PlatformActions..onNavigation) ⇒ function @@ -159,6 +160,24 @@ Hide platform global filter. + + +### PlatformActions~onNavigation(callback) ⇒ function +Apply platform method for updating routing history on "navigating" with the left-nav. + +**Kind**: inner method of [PlatformActions](#Actions.module_PlatformActions) + + + + + + + + + + +
ParamType
callbackfunction
+ ## RhsmActions diff --git a/src/redux/actions/__tests__/__snapshots__/platformActions.test.js.snap b/src/redux/actions/__tests__/__snapshots__/platformActions.test.js.snap index fd1e38a27..1fe44e5d4 100644 --- a/src/redux/actions/__tests__/__snapshots__/platformActions.test.js.snap +++ b/src/redux/actions/__tests__/__snapshots__/platformActions.test.js.snap @@ -6,3 +6,7 @@ exports[`PlatformActions Should return a dispatch object for the hideGlobalFilte "type": "PLATFORM_GLOBAL_FILTER_HIDE", } `; + +exports[`PlatformActions Should return a function for the onNavigation method: expected process 1`] = `"lorem ipsum"`; + +exports[`PlatformActions Should return a function for the onNavigation method: function 1`] = `[Function]`; diff --git a/src/redux/actions/__tests__/platformActions.test.js b/src/redux/actions/__tests__/platformActions.test.js index 7d2f173e2..6eeccebd4 100644 --- a/src/redux/actions/__tests__/platformActions.test.js +++ b/src/redux/actions/__tests__/platformActions.test.js @@ -28,4 +28,12 @@ describe('PlatformActions', () => { it('Should return a dispatch object for the hideGlobalFilter method', () => { expect(platformActions.hideGlobalFilter()).toMatchSnapshot('dispatch object'); }); + + it('Should return a function for the onNavigation method', () => { + expect(platformActions.onNavigation()).toMatchSnapshot('function'); + + window.insights.chrome.on = jest.fn().mockImplementation((id, value) => value('lorem')); + const dispatch = obj => obj; + expect(platformActions.onNavigation(event => `${event} ipsum`)(dispatch)).toMatchSnapshot('expected process'); + }); }); diff --git a/src/redux/actions/platformActions.js b/src/redux/actions/platformActions.js index ad184432e..978dbc1d6 100644 --- a/src/redux/actions/platformActions.js +++ b/src/redux/actions/platformActions.js @@ -59,12 +59,26 @@ const hideGlobalFilter = isHidden => ({ payload: platformServices.hideGlobalFilter(isHidden) }); +/** + * Apply platform method for updating routing history on "navigating" with the left-nav. + * + * @param {Function} callback + * @returns {Function} + */ +const onNavigation = callback => dispatch => { + dispatch({ + type: platformTypes.PLATFORM_ON_NAV + }); + return platformServices.onNavigation(callback); +}; + const platformActions = { addNotification, removeNotification, clearNotifications, authorizeUser, - hideGlobalFilter + hideGlobalFilter, + onNavigation }; export { @@ -74,5 +88,6 @@ export { removeNotification, clearNotifications, authorizeUser, - hideGlobalFilter + hideGlobalFilter, + onNavigation }; diff --git a/src/redux/types/__tests__/__snapshots__/index.test.js.snap b/src/redux/types/__tests__/__snapshots__/index.test.js.snap index 6317adb1b..77f303c42 100644 --- a/src/redux/types/__tests__/__snapshots__/index.test.js.snap +++ b/src/redux/types/__tests__/__snapshots__/index.test.js.snap @@ -24,6 +24,7 @@ exports[`ReduxTypes should have specific type properties: all redux types 1`] = "PLATFORM_ADD_NOTIFICATION": "@@INSIGHTS-CORE/NOTIFICATIONS/ADD_NOTIFICATION", "PLATFORM_CLEAR_NOTIFICATIONS": "@@INSIGHTS-CORE/NOTIFICATIONS/CLEAR_NOTIFICATIONS", "PLATFORM_GLOBAL_FILTER_HIDE": "PLATFORM_GLOBAL_FILTER_HIDE", + "PLATFORM_ON_NAV": "PLATFORM_ON_NAV", "PLATFORM_REMOVE_NOTIFICATION": "@@INSIGHTS-CORE/NOTIFICATIONS/REMOVE_NOTIFICATION", "PLATFORM_USER_AUTH": "PLATFORM_USER_AUTH", }, @@ -93,6 +94,7 @@ exports[`ReduxTypes should have specific type properties: all redux types 1`] = "PLATFORM_ADD_NOTIFICATION": "@@INSIGHTS-CORE/NOTIFICATIONS/ADD_NOTIFICATION", "PLATFORM_CLEAR_NOTIFICATIONS": "@@INSIGHTS-CORE/NOTIFICATIONS/CLEAR_NOTIFICATIONS", "PLATFORM_GLOBAL_FILTER_HIDE": "PLATFORM_GLOBAL_FILTER_HIDE", + "PLATFORM_ON_NAV": "PLATFORM_ON_NAV", "PLATFORM_REMOVE_NOTIFICATION": "@@INSIGHTS-CORE/NOTIFICATIONS/REMOVE_NOTIFICATION", "PLATFORM_USER_AUTH": "PLATFORM_USER_AUTH", }, @@ -146,6 +148,7 @@ exports[`ReduxTypes should have specific type properties: all redux types 1`] = "PLATFORM_ADD_NOTIFICATION": "@@INSIGHTS-CORE/NOTIFICATIONS/ADD_NOTIFICATION", "PLATFORM_CLEAR_NOTIFICATIONS": "@@INSIGHTS-CORE/NOTIFICATIONS/CLEAR_NOTIFICATIONS", "PLATFORM_GLOBAL_FILTER_HIDE": "PLATFORM_GLOBAL_FILTER_HIDE", + "PLATFORM_ON_NAV": "PLATFORM_ON_NAV", "PLATFORM_REMOVE_NOTIFICATION": "@@INSIGHTS-CORE/NOTIFICATIONS/REMOVE_NOTIFICATION", "PLATFORM_USER_AUTH": "PLATFORM_USER_AUTH", }, @@ -246,6 +249,7 @@ exports[`ReduxTypes should have specific type properties: specific types 1`] = ` "PLATFORM_ADD_NOTIFICATION": "@@INSIGHTS-CORE/NOTIFICATIONS/ADD_NOTIFICATION", "PLATFORM_CLEAR_NOTIFICATIONS": "@@INSIGHTS-CORE/NOTIFICATIONS/CLEAR_NOTIFICATIONS", "PLATFORM_GLOBAL_FILTER_HIDE": "PLATFORM_GLOBAL_FILTER_HIDE", + "PLATFORM_ON_NAV": "PLATFORM_ON_NAV", "PLATFORM_REMOVE_NOTIFICATION": "@@INSIGHTS-CORE/NOTIFICATIONS/REMOVE_NOTIFICATION", "PLATFORM_USER_AUTH": "PLATFORM_USER_AUTH", }, diff --git a/src/redux/types/platformTypes.js b/src/redux/types/platformTypes.js index 541883db1..b138854e2 100644 --- a/src/redux/types/platformTypes.js +++ b/src/redux/types/platformTypes.js @@ -13,19 +13,21 @@ const PLATFORM_ADD_NOTIFICATION = ADD_NOTIFICATION; const PLATFORM_REMOVE_NOTIFICATION = REMOVE_NOTIFICATION; const PLATFORM_CLEAR_NOTIFICATIONS = CLEAR_NOTIFICATIONS; const PLATFORM_GLOBAL_FILTER_HIDE = 'PLATFORM_GLOBAL_FILTER_HIDE'; +const PLATFORM_ON_NAV = 'PLATFORM_ON_NAV'; const PLATFORM_USER_AUTH = 'PLATFORM_USER_AUTH'; /** * Platform action, reducer types. * * @type {{PLATFORM_USER_AUTH: string, PLATFORM_GLOBAL_FILTER_HIDE: string, PLATFORM_CLEAR_NOTIFICATIONS: string, - * PLATFORM_ADD_NOTIFICATION: string, PLATFORM_REMOVE_NOTIFICATION: string}} + * PLATFORM_ADD_NOTIFICATION: string, PLATFORM_REMOVE_NOTIFICATION: string, PLATFORM_ON_NAV: string}} */ const platformTypes = { PLATFORM_ADD_NOTIFICATION, PLATFORM_REMOVE_NOTIFICATION, PLATFORM_CLEAR_NOTIFICATIONS, PLATFORM_GLOBAL_FILTER_HIDE, + PLATFORM_ON_NAV, PLATFORM_USER_AUTH }; @@ -36,5 +38,6 @@ export { PLATFORM_REMOVE_NOTIFICATION, PLATFORM_CLEAR_NOTIFICATIONS, PLATFORM_GLOBAL_FILTER_HIDE, + PLATFORM_ON_NAV, PLATFORM_USER_AUTH }; diff --git a/src/services/README.md b/src/services/README.md index 3236859c5..a1b94bc80 100644 --- a/src/services/README.md +++ b/src/services/README.md @@ -325,6 +325,7 @@ Emulated service calls for platform globals. * [~getUser(options)](#Platform.module_PlatformServices..getUser) ⇒ Promise.<\*> * [~getUserPermissions(appName, options)](#Platform.module_PlatformServices..getUserPermissions) ⇒ Promise.<\*> * [~hideGlobalFilter(isHidden)](#Platform.module_PlatformServices..hideGlobalFilter) ⇒ Promise.<\*> + * [~onNavigation(callback)](#Platform.module_PlatformServices..onNavigation) ⇒ function @@ -382,6 +383,24 @@ Disables the Platform's global filter display. + + +### PlatformServices~onNavigation(callback) ⇒ function +Apply on "app_navigation" event. Return an un-listener. + +**Kind**: inner method of [PlatformServices](#Platform.module_PlatformServices) + + + + + + + + + + +
ParamType
callbackfunction
+ ## PlatformTransformers diff --git a/src/services/platform/__tests__/platformServices.test.js b/src/services/platform/__tests__/platformServices.test.js index dd02c68a9..200e13b2c 100644 --- a/src/services/platform/__tests__/platformServices.test.js +++ b/src/services/platform/__tests__/platformServices.test.js @@ -15,13 +15,14 @@ describe('PlatformServices', () => { }; it('should export a specific number of methods and classes', () => { - expect(Object.keys(platformServices)).toHaveLength(3); + expect(Object.keys(platformServices)).toHaveLength(4); }); it('should have specific methods', () => { expect(platformServices.getUser).toBeDefined(); expect(platformServices.getUserPermissions).toBeDefined(); expect(platformServices.hideGlobalFilter).toBeDefined(); + expect(platformServices.onNavigation).toBeDefined(); }); /** @@ -68,4 +69,9 @@ describe('PlatformServices', () => { expect(response).toMatchSnapshot('failed hideGlobalFilter'); }); + + it('should return a failed onNavigation', () => { + window.insights.chrome.on = undefined; + expect(platformServices.onNavigation).toThrow('{ on } = insights.chrome, insights.chrome.on is not a function'); + }); }); diff --git a/src/services/platform/platformServices.js b/src/services/platform/platformServices.js index 260389981..2b9a77dce 100644 --- a/src/services/platform/platformServices.js +++ b/src/services/platform/platformServices.js @@ -108,10 +108,26 @@ const hideGlobalFilter = async (isHidden = true) => { } }; +/** + * Apply on "app_navigation" event. Return an un-listener. + * + * @param {Function} callback + * @returns {Function} + */ +const onNavigation = callback => { + const { insights } = window; + try { + return insights.chrome.on('APP_NAVIGATION', callback); + } catch (e) { + throw new Error(`{ on } = insights.chrome, ${e.message}`); + } +}; + const platformServices = { getUser, getUserPermissions, - hideGlobalFilter + hideGlobalFilter, + onNavigation }; -export { platformServices as default, platformServices, getUser, getUserPermissions, hideGlobalFilter }; +export { platformServices as default, platformServices, getUser, getUserPermissions, hideGlobalFilter, onNavigation }; diff --git a/tests/__snapshots__/dist.test.js.snap b/tests/__snapshots__/dist.test.js.snap index 4a9c98540..ac2f31693 100644 --- a/tests/__snapshots__/dist.test.js.snap +++ b/tests/__snapshots__/dist.test.js.snap @@ -289,6 +289,7 @@ exports[`Build distribution should match a specific file output 1`] = ` "./dist/js/2217*js", "./dist/js/2227*js", "./dist/js/2243*js", + "./dist/js/2293*js", "./dist/js/2622*js", "./dist/js/2701*js", "./dist/js/2738*js", @@ -299,9 +300,10 @@ exports[`Build distribution should match a specific file output 1`] = ` "./dist/js/2948*js", "./dist/js/31*js", "./dist/js/3128*js", + "./dist/js/325*js", + "./dist/js/325*txt", "./dist/js/3267*js", "./dist/js/3280*js", - "./dist/js/3385*js", "./dist/js/353*js", "./dist/js/3557*js", "./dist/js/3597*js", @@ -321,8 +323,6 @@ exports[`Build distribution should match a specific file output 1`] = ` "./dist/js/5242*js", "./dist/js/5394*js", "./dist/js/5426*js", - "./dist/js/5704*js", - "./dist/js/5704*txt", "./dist/js/5876*js", "./dist/js/5925*js", "./dist/js/5993*js", @@ -372,6 +372,7 @@ exports[`Build distribution should match a specific file output 1`] = ` "./dist/sourcemaps/2217*map", "./dist/sourcemaps/2227*map", "./dist/sourcemaps/2243*map", + "./dist/sourcemaps/2293*map", "./dist/sourcemaps/2622*map", "./dist/sourcemaps/2701*map", "./dist/sourcemaps/2738*map", @@ -382,9 +383,9 @@ exports[`Build distribution should match a specific file output 1`] = ` "./dist/sourcemaps/2948*map", "./dist/sourcemaps/31*map", "./dist/sourcemaps/3128*map", + "./dist/sourcemaps/325*map", "./dist/sourcemaps/3267*map", "./dist/sourcemaps/3280*map", - "./dist/sourcemaps/3385*map", "./dist/sourcemaps/353*map", "./dist/sourcemaps/3557*map", "./dist/sourcemaps/3597*map", @@ -401,7 +402,6 @@ exports[`Build distribution should match a specific file output 1`] = ` "./dist/sourcemaps/5242*map", "./dist/sourcemaps/5394*map", "./dist/sourcemaps/5426*map", - "./dist/sourcemaps/5704*map", "./dist/sourcemaps/5876*map", "./dist/sourcemaps/5925*map", "./dist/sourcemaps/5993*map",