From 63eaa00ee1a695736a80a7ed598a54ea5aecb107 Mon Sep 17 00:00:00 2001 From: Ben Warzeski Date: Thu, 30 Mar 2023 10:51:30 -0400 Subject: [PATCH] Bw/fix network args (#130) --- .../AuthenticatedUserDropdown.test.jsx | 13 +++ .../AuthenticatedUserDropdown.test.jsx.snap | 14 +++- .../AuthenticatedUserDropdown.test.jsx | 13 +++ .../AuthenticatedUserDropdown.test.jsx.snap | 14 +++- src/hooks/api.js | 5 +- src/hooks/api.test.js | 84 +++++++++---------- 6 files changed, 95 insertions(+), 48 deletions(-) diff --git a/src/containers/LearnerDashboardHeader/AuthenticatedUserDropdown.test.jsx b/src/containers/LearnerDashboardHeader/AuthenticatedUserDropdown.test.jsx index 0e9fa13..9343b0a 100644 --- a/src/containers/LearnerDashboardHeader/AuthenticatedUserDropdown.test.jsx +++ b/src/containers/LearnerDashboardHeader/AuthenticatedUserDropdown.test.jsx @@ -1,9 +1,13 @@ import { shallow } from 'enzyme'; +import { getConfig } from '@edx/frontend-platform'; import { reduxHooks } from 'hooks'; import { AuthenticatedUserDropdown } from './AuthenticatedUserDropdown'; import { useIsCollapsed } from './hooks'; +jest.mock('@edx/frontend-platform', () => ({ + getConfig: jest.fn(), +})); jest.mock('@edx/frontend-platform/react', () => ({ AppContext: { authenticatedUser: { @@ -24,6 +28,15 @@ jest.mock('containers/LearnerDashboardHeader/hooks', () => ({ findCoursesNavDropdownClicked: (href) => jest.fn().mockName(`findCoursesNavDropdownClicked('${href}')`), })); +const config = { + ACCOUNT_PROFILE_URL: 'http://account-profile-url.test', + ACCOUNT_SETTINGS_URL: 'http://account-settings-url.test', + LOGOUT_URL: 'http://logout-url.test', + ORDER_HISTORY_URL: 'http://order-history-url.test', + SUPPORT_URL: 'http://localhost:18000/support', +}; +getConfig.mockReturnValue(config); + describe('AuthenticatedUserDropdown', () => { const props = { username: 'username', diff --git a/src/containers/LearnerDashboardHeader/__snapshots__/AuthenticatedUserDropdown.test.jsx.snap b/src/containers/LearnerDashboardHeader/__snapshots__/AuthenticatedUserDropdown.test.jsx.snap index 8134f10..45b28d6 100644 --- a/src/containers/LearnerDashboardHeader/__snapshots__/AuthenticatedUserDropdown.test.jsx.snap +++ b/src/containers/LearnerDashboardHeader/__snapshots__/AuthenticatedUserDropdown.test.jsx.snap @@ -61,6 +61,11 @@ exports[`AuthenticatedUserDropdown snapshots with enterprise dashboard 1`] = ` > Account + + Order History + @@ -68,7 +73,7 @@ exports[`AuthenticatedUserDropdown snapshots with enterprise dashboard 1`] = ` Sign Out @@ -117,6 +122,11 @@ exports[`AuthenticatedUserDropdown snapshots without enterprise dashboard and ex > Account + + Order History + @@ -124,7 +134,7 @@ exports[`AuthenticatedUserDropdown snapshots without enterprise dashboard and ex Sign Out diff --git a/src/containers/LearnerDashboardHeaderVariant/ExpandedHeader/AuthenticatedUserDropdown.test.jsx b/src/containers/LearnerDashboardHeaderVariant/ExpandedHeader/AuthenticatedUserDropdown.test.jsx index 49f9c6d..511880b 100644 --- a/src/containers/LearnerDashboardHeaderVariant/ExpandedHeader/AuthenticatedUserDropdown.test.jsx +++ b/src/containers/LearnerDashboardHeaderVariant/ExpandedHeader/AuthenticatedUserDropdown.test.jsx @@ -1,10 +1,14 @@ import { shallow } from 'enzyme'; import { reduxHooks } from 'hooks'; +import { getConfig } from '@edx/frontend-platform'; import { AppContext } from '@edx/frontend-platform/react'; import { AuthenticatedUserDropdown } from './AuthenticatedUserDropdown'; import { useIsCollapsed } from '../hooks'; +jest.mock('@edx/frontend-platform', () => ({ + getConfig: jest.fn(), +})); jest.mock('@edx/frontend-platform/react', () => ({ AppContext: { authenticatedUser: { @@ -26,6 +30,15 @@ jest.mock('../hooks', () => ({ findCoursesNavDropdownClicked: (href) => jest.fn().mockName(`findCoursesNavDropdownClicked('${href}')`), })); +const config = { + ACCOUNT_PROFILE_URL: 'http://account-profile-url.test', + ACCOUNT_SETTINGS_URL: 'http://account-settings-url.test', + LOGOUT_URL: 'http://logout-url.test', + ORDER_HISTORY_URL: 'http://order-history-url.test', + SUPPORT_URL: 'http://localhost:18000/support', +}; +getConfig.mockReturnValue(config); + describe('AuthenticatedUserDropdown', () => { const defaultDashboardData = { label: 'label', diff --git a/src/containers/LearnerDashboardHeaderVariant/ExpandedHeader/__snapshots__/AuthenticatedUserDropdown.test.jsx.snap b/src/containers/LearnerDashboardHeaderVariant/ExpandedHeader/__snapshots__/AuthenticatedUserDropdown.test.jsx.snap index 08f55c2..3ec3c66 100644 --- a/src/containers/LearnerDashboardHeaderVariant/ExpandedHeader/__snapshots__/AuthenticatedUserDropdown.test.jsx.snap +++ b/src/containers/LearnerDashboardHeaderVariant/ExpandedHeader/__snapshots__/AuthenticatedUserDropdown.test.jsx.snap @@ -52,9 +52,14 @@ exports[`AuthenticatedUserDropdown snapshots with enterprise dashboard 1`] = ` > Account + + Order History + Sign Out @@ -103,9 +108,14 @@ exports[`AuthenticatedUserDropdown snapshots without enterprise dashboard and ex > Account + + Order History + Sign Out diff --git a/src/hooks/api.js b/src/hooks/api.js index a603e1c..d64a118 100644 --- a/src/hooks/api.js +++ b/src/hooks/api.js @@ -14,7 +14,7 @@ const { useMakeNetworkRequest } = reduxHooks; export const useNetworkRequest = (action, args) => { const makeNetworkRequest = useMakeNetworkRequest(); return (...actionsArgs) => makeNetworkRequest({ - promise: action(actionsArgs), + promise: action(...actionsArgs), ...args, }); }; @@ -43,8 +43,9 @@ export const useNewEntitlementEnrollment = (cardId) => { export const useSwitchEntitlementEnrollment = (cardId) => { const { uuid } = reduxHooks.useCardEntitlementData(cardId); const onSuccess = module.useInitializeApp(); + const action = (selection) => api.updateEntitlementEnrollment({ uuid, courseId: selection }); return module.useNetworkRequest( - (selection) => api.updateEntitlementEnrollment({ uuid, courseId: selection }), + action, { onSuccess, requestKey: RequestKeys.switchEntitlementSession }, ); }; diff --git a/src/hooks/api.test.js b/src/hooks/api.test.js index 023f9b3..cd1a5b6 100644 --- a/src/hooks/api.test.js +++ b/src/hooks/api.test.js @@ -59,109 +59,112 @@ const testInitCardHook = (hookKey) => { const initializeApp = jest.fn(); -const testRequestKey = (requestKey) => { - test('requestKey', () => { expect(out.requestKey).toEqual(requestKey); }); -}; - describe('api hooks', () => { beforeEach(() => { jest.clearAllMocks(); }); + describe('useNetworkRequest', () => { const makeNetworkRequest = jest.fn(args => ({ networkRequest: args })); + const action = jest.fn((...actionArgs) => ({ action: actionArgs })); + const args = { some: 'test', args: 'for you' }; it('returns network request based on incoming action', () => { reduxHooks.useMakeNetworkRequest.mockReturnValue(makeNetworkRequest); - const promise = Promise.resolve(testString); - const action = () => promise; - const args = { some: 'test', args: 'for you' }; hook = apiHooks.useNetworkRequest(action, args); - expect(hook()).toEqual(makeNetworkRequest({ promise, ...args })); + expect(hook()).toEqual(makeNetworkRequest({ promise: action(), ...args })); + }); + it('forwards action arguments', () => { + reduxHooks.useMakeNetworkRequest.mockReturnValue(makeNetworkRequest); + hook = apiHooks.useNetworkRequest(action, args); + const actionArgs = [1, 2, 3]; + expect(hook(...actionArgs)).toEqual( + makeNetworkRequest({ promise: action(...actionArgs), ...args }), + ); }); }); + describe('network requests', () => { - const useNetworkRequest = (action, args) => () => ({ action, ...args }); + const mockUseNetworkRequest = jest.fn((action, args) => ({ action, args })); + const testRequestKey = (requestKey) => { + test('requestKey', () => { expect(hook.args.requestKey).toEqual(requestKey); }); + }; + beforeEach(() => { - jest.spyOn(apiHooks, moduleKeys.useNetworkRequest).mockImplementation(useNetworkRequest); + jest.spyOn(apiHooks, moduleKeys.useNetworkRequest).mockImplementation(mockUseNetworkRequest); }); + describe('useInitializeApp', () => { beforeEach(() => { hook = apiHooks.useInitializeApp(); - out = hook(); }); it('calls initialize api method', () => { - expect(out.action).toEqual(api.initializeList); + expect(hook.action).toEqual(api.initializeList); }); testRequestKey(RequestKeys.initialize); it('initializes load data hook', () => { expect(reduxHooks.useLoadData).toHaveBeenCalledWith(); }); it('calls loadData with data on success', () => { - out.onSuccess({ data: testString }); + hook.args.onSuccess({ data: testString }); expect(loadData).toHaveBeenCalledWith(testString); }); }); describe('entitlement enrollment hooks', () => { + beforeEach(() => { + jest.spyOn(apiHooks, moduleKeys.useInitializeApp).mockReturnValue(initializeApp); + }); + const testInitialization = () => { it('initializes useInitializeApp', () => { expect(apiHooks.useInitializeApp).toHaveBeenCalledWith(); }); testInitCardHook(reduxKeys.useCardEntitlementData); }; + const testArgs = (requestKey) => { testRequestKey(requestKey); it('initializes app on success', () => { - expect(out.onSuccess).toEqual(initializeApp); + expect(hook.args.onSuccess).toEqual(initializeApp); }); }; - beforeEach(() => { - jest.spyOn(apiHooks, moduleKeys.useInitializeApp).mockReturnValue(initializeApp); - }); + describe('useNewEntitlementEnrollment', () => { beforeEach(() => { hook = apiHooks.useNewEntitlementEnrollment(cardId); - out = hook(); }); testInitialization(); testArgs(RequestKeys.newEntitlementEnrollment); it('calls updateEntitlementEnrollment api method', () => { - out.action(selection); - expect(api.updateEntitlementEnrollment).toHaveBeenCalledWith({ - uuid, - courseId: selection, - }); + hook.action(selection); + expect(api.updateEntitlementEnrollment) + .toHaveBeenCalledWith({ uuid, courseId: selection }); }); }); describe('useSwitchEntitlementEnrollment', () => { beforeEach(() => { hook = apiHooks.useSwitchEntitlementEnrollment(cardId); - out = hook(); }); testInitialization(); testArgs(RequestKeys.switchEntitlementSession); it('calls updateEntitlementEnrollment api method', () => { - out.action(selection); - expect(api.updateEntitlementEnrollment).toHaveBeenCalledWith({ - uuid, - courseId: selection, - }); + hook.action(selection); + expect(api.updateEntitlementEnrollment) + .toHaveBeenCalledWith({ uuid, courseId: selection }); }); }); describe('useLeaveEntitlementSession', () => { beforeEach(() => { hook = apiHooks.useLeaveEntitlementSession(cardId); - out = hook(); }); testInitialization(); testArgs(RequestKeys.leaveEntitlementSession); it('calls updateEntitlementEnrollment api method', () => { - out.action(); - expect(api.deleteEntitlementEnrollment).toHaveBeenCalledWith({ - uuid, - isRefundable, - }); + hook.action(); + expect(api.deleteEntitlementEnrollment) + .toHaveBeenCalledWith({ uuid, isRefundable }); }); }); }); @@ -169,12 +172,11 @@ describe('api hooks', () => { describe('useUnenrollFromCourse', () => { beforeEach(() => { hook = apiHooks.useUnenrollFromCourse(cardId); - out = hook(); }); testInitCardHook(reduxKeys.useCardCourseRunData); testRequestKey(RequestKeys.unenrollFromCourse); it('calls unenrollFromCourse api method with courseId', () => { - out.action(); + hook.action(); expect(api.unenrollFromCourse).toHaveBeenCalledWith({ courseId }); }); }); @@ -182,18 +184,17 @@ describe('api hooks', () => { describe('useMasqueradeAs', () => { beforeEach(() => { hook = apiHooks.useMasqueradeAs(cardId); - out = hook(); }); it('initializes load data hook', () => { expect(reduxHooks.useLoadData).toHaveBeenCalledWith(); }); testRequestKey(RequestKeys.masquerade); it('calls initializeList api method', () => { - out.action(user); + hook.action(user); expect(api.initializeList).toHaveBeenCalledWith({ user }); }); it('loads data on success', () => { - out.onSuccess({ data: testString }); + hook.args.onSuccess({ data: testString }); expect(loadData).toHaveBeenCalledWith(testString); }); }); @@ -220,12 +221,11 @@ describe('api hooks', () => { const enable = 'test-enable'; beforeEach(() => { hook = apiHooks.useUpdateEmailSettings(cardId); - out = hook(); }); testInitCardHook(reduxKeys.useCardCourseRunData); testRequestKey(RequestKeys.updateEmailSettings); it('calls updateEmailSettings api method on call', () => { - out.action(enable); + hook.action(enable); expect(api.updateEmailSettings).toHaveBeenCalledWith({ courseId, enable }); }); });