From a18c45f0db883753df399684766db6cfa3f086ff Mon Sep 17 00:00:00 2001 From: Raymond Zhou <56318341+rayzhou-bit@users.noreply.github.com> Date: Thu, 10 Aug 2023 12:58:14 -0400 Subject: [PATCH] feat: call failRequest on fetch failure (#373) --- src/editors/data/redux/thunkActions/app.js | 30 +++++- .../data/redux/thunkActions/app.test.js | 99 ++++++++++++++----- 2 files changed, 99 insertions(+), 30 deletions(-) diff --git a/src/editors/data/redux/thunkActions/app.js b/src/editors/data/redux/thunkActions/app.js index a10cf1db4..9c4e4aea6 100644 --- a/src/editors/data/redux/thunkActions/app.js +++ b/src/editors/data/redux/thunkActions/app.js @@ -3,45 +3,65 @@ import { StrictDict, camelizeKeys } from '../../../utils'; import { actions } from '..'; import * as requests from './requests'; import * as module from './app'; +import { RequestKeys } from '../../constants/requests'; export const fetchBlock = () => (dispatch) => { dispatch(requests.fetchBlock({ onSuccess: (response) => dispatch(actions.app.setBlockValue(response)), - // eslint-disable-next-line - onFailure: (e) => console.log({ fetchFailure: e }), + onFailure: (error) => dispatch(actions.requests.failRequest({ + requestKey: RequestKeys.fetchBlock, + error, + })), })); }; export const fetchStudioView = () => (dispatch) => { dispatch(requests.fetchStudioView({ onSuccess: (response) => dispatch(actions.app.setStudioView(response)), - onFailure: (e) => dispatch(actions.app.setStudioView(e)), + onFailure: (error) => dispatch(actions.requests.failRequest({ + requestKey: RequestKeys.fetchStudioView, + error, + })), })); }; export const fetchUnit = () => (dispatch) => { dispatch(requests.fetchUnit({ onSuccess: (response) => dispatch(actions.app.setUnitUrl(response)), - onFailure: (e) => dispatch(actions.app.setUnitUrl(e)), + onFailure: (error) => dispatch(actions.requests.failRequest({ + requestKey: RequestKeys.fetchUnit, + error, + })), })); }; export const fetchAssets = () => (dispatch) => { dispatch(requests.fetchAssets({ onSuccess: (response) => dispatch(actions.app.setAssets(response)), + onFailure: (error) => dispatch(actions.requests.failRequest({ + requestKey: RequestKeys.fetchAssets, + error, + })), })); }; export const fetchVideos = () => (dispatch) => { dispatch(requests.fetchVideos({ onSuccess: (response) => dispatch(actions.app.setVideos(response.data.videos)), + onFailure: (error) => dispatch(actions.requests.failRequest({ + requestKey: RequestKeys.fetchVideos, + error, + })), })); }; export const fetchCourseDetails = () => (dispatch) => { dispatch(requests.fetchCourseDetails({ onSuccess: (response) => dispatch(actions.app.setCourseDetails(response)), - onFailure: (e) => dispatch(actions.app.setCourseDetails(e)), + onFailure: (error) => dispatch(actions.requests.failRequest({ + requestKey: RequestKeys.fetchCourseDetails, + error, + })), })); }; diff --git a/src/editors/data/redux/thunkActions/app.test.js b/src/editors/data/redux/thunkActions/app.test.js index 289d0210a..dce0a212d 100644 --- a/src/editors/data/redux/thunkActions/app.test.js +++ b/src/editors/data/redux/thunkActions/app.test.js @@ -1,6 +1,7 @@ /* eslint-disable no-import-assign */ import { actions } from '..'; import { camelizeKeys } from '../../../utils'; +import { RequestKeys } from '../../constants/requests'; import * as thunkActions from './app'; jest.mock('./requests', () => ({ @@ -19,7 +20,12 @@ jest.mock('../../../utils', () => ({ ...jest.requireActual('../../../utils'), })); -const testValue = { data: { assets: 'test VALUE' } }; +const testValue = { + data: { + assets: 'test VALUE', + videos: 'vIDeO vALUe', + }, +}; describe('app thunkActions', () => { let dispatch; @@ -40,6 +46,14 @@ describe('app thunkActions', () => { dispatchedAction.fetchBlock.onSuccess(testValue); expect(dispatch).toHaveBeenCalledWith(actions.app.setBlockValue(testValue)); }); + it('dispatches failRequest with fetchBlock requestKey on failure', () => { + dispatch.mockClear(); + dispatchedAction.fetchBlock.onFailure(testValue); + expect(dispatch).toHaveBeenCalledWith(actions.requests.failRequest({ + requestKey: RequestKeys.fetchBlock, + error: testValue, + })); + }); }); describe('fetchStudioView', () => { @@ -55,10 +69,13 @@ describe('app thunkActions', () => { dispatchedAction.fetchStudioView.onSuccess(testValue); expect(dispatch).toHaveBeenCalledWith(actions.app.setStudioView(testValue)); }); - it('dispatches setStudioView on failure', () => { + it('dispatches failRequest with fetchStudioView requestKey on failure', () => { dispatch.mockClear(); dispatchedAction.fetchStudioView.onFailure(testValue); - expect(dispatch).toHaveBeenCalledWith(actions.app.setStudioView(testValue)); + expect(dispatch).toHaveBeenCalledWith(actions.requests.failRequest({ + requestKey: RequestKeys.fetchStudioView, + error: testValue, + })); }); }); @@ -75,10 +92,57 @@ describe('app thunkActions', () => { dispatchedAction.fetchUnit.onSuccess(testValue); expect(dispatch).toHaveBeenCalledWith(actions.app.setUnitUrl(testValue)); }); - it('dispatches actions.app.setUnitUrl on failure', () => { + it('dispatches failRequest with fetchUnit requestKey on failure', () => { dispatch.mockClear(); dispatchedAction.fetchUnit.onFailure(testValue); - expect(dispatch).toHaveBeenCalledWith(actions.app.setUnitUrl(testValue)); + expect(dispatch).toHaveBeenCalledWith(actions.requests.failRequest({ + requestKey: RequestKeys.fetchUnit, + error: testValue, + })); + }); + }); + describe('fetchAssets', () => { + beforeEach(() => { + thunkActions.fetchAssets()(dispatch); + [[dispatchedAction]] = dispatch.mock.calls; + }); + it('dispatches fetchAssets action', () => { + expect(dispatchedAction.fetchAssets).not.toEqual(undefined); + }); + it('dispatches actions.app.setAssets on success', () => { + dispatch.mockClear(); + dispatchedAction.fetchAssets.onSuccess(testValue); + expect(dispatch).toHaveBeenCalledWith(actions.app.setAssets(testValue)); + }); + it('dispatches failRequest with fetchAssets requestKey on failure', () => { + dispatch.mockClear(); + dispatchedAction.fetchAssets.onFailure(testValue); + expect(dispatch).toHaveBeenCalledWith(actions.requests.failRequest({ + requestKey: RequestKeys.fetchAssets, + error: testValue, + })); + }); + }); + describe('fetchVideos', () => { + beforeEach(() => { + thunkActions.fetchVideos()(dispatch); + [[dispatchedAction]] = dispatch.mock.calls; + }); + it('dispatches fetchAssets action', () => { + expect(dispatchedAction.fetchVideos).not.toEqual(undefined); + }); + it('dispatches actions.app.setVideos on success', () => { + dispatch.mockClear(); + dispatchedAction.fetchVideos.onSuccess(testValue); + expect(dispatch).toHaveBeenCalledWith(actions.app.setVideos(testValue.data.videos)); + }); + it('dispatches failRequest with fetchVideos requestKey on failure', () => { + dispatch.mockClear(); + dispatchedAction.fetchVideos.onFailure(testValue); + expect(dispatch).toHaveBeenCalledWith(actions.requests.failRequest({ + requestKey: RequestKeys.fetchVideos, + error: testValue, + })); }); }); describe('fetchCourseDetails', () => { @@ -94,10 +158,13 @@ describe('app thunkActions', () => { dispatchedAction.fetchCourseDetails.onSuccess(testValue); expect(dispatch).toHaveBeenCalledWith(actions.app.setCourseDetails(testValue)); }); - it('dispatches actions.app.setUnitUrl on failure', () => { + it('dispatches failRequest with fetchCourseDetails requestKey on failure', () => { dispatch.mockClear(); dispatchedAction.fetchCourseDetails.onFailure(testValue); - expect(dispatch).toHaveBeenCalledWith(actions.app.setCourseDetails(testValue)); + expect(dispatch).toHaveBeenCalledWith(actions.requests.failRequest({ + requestKey: RequestKeys.fetchCourseDetails, + error: testValue, + })); }); }); describe('initialize', () => { @@ -158,24 +225,6 @@ describe('app thunkActions', () => { expect(returnToUnit).toHaveBeenCalled(); }); }); - describe('fetchAssets', () => { - it('dispatches fetchAssets action with setAssets for onSuccess param', () => { - const response = { data: { assets: 'testRESPONSE' } }; - thunkActions.fetchAssets()(dispatch); - const [[dispatchCall]] = dispatch.mock.calls; - dispatchCall.fetchAssets.onSuccess(response); - expect(dispatch).toHaveBeenCalledWith(actions.app.setAssets(response)); - }); - }); - describe('fetchVideos', () => { - it('dispatches fetchVideos action with setVideos for onSuccess param', () => { - const response = { data: { videos: 'testRESPONSE' } }; - thunkActions.fetchVideos()(dispatch); - const [[dispatchCall]] = dispatch.mock.calls; - dispatchCall.fetchVideos.onSuccess(response); - expect(dispatch).toHaveBeenCalledWith(actions.app.setVideos(response.data.videos)); - }); - }); describe('uploadImage', () => { const setSelection = jest.fn(); beforeEach(() => {