From f70d770a6fb2a56c01dfa8af82a391dc0c53330d Mon Sep 17 00:00:00 2001 From: Diana Olarte Date: Fri, 27 Dec 2024 10:48:44 +1100 Subject: [PATCH] test: add testing for request --- .../containers/ProblemEditor/index.test.tsx | 11 ++++-- src/editors/data/constants/requests.ts | 2 +- src/editors/data/redux/app/selectors.test.ts | 16 +++++++++ src/editors/data/redux/thunkActions/app.js | 3 +- .../data/redux/thunkActions/app.test.js | 36 +++++++++++++++++++ .../data/redux/thunkActions/requests.js | 5 ++- .../data/redux/thunkActions/requests.test.js | 22 +++++++++++- 7 files changed, 86 insertions(+), 9 deletions(-) diff --git a/src/editors/containers/ProblemEditor/index.test.tsx b/src/editors/containers/ProblemEditor/index.test.tsx index ab3d37095a..952b0e274e 100644 --- a/src/editors/containers/ProblemEditor/index.test.tsx +++ b/src/editors/containers/ProblemEditor/index.test.tsx @@ -27,6 +27,7 @@ jest.mock('../../data/redux', () => ({ selectors: { app: { blockValue: jest.fn(state => ({ blockValue: state })), + isCreateBlock: jest.fn(state => ({ isCreateBlock: state })), }, problem: { problemType: jest.fn(state => ({ problemType: state })), @@ -104,12 +105,18 @@ describe('ProblemEditor', () => { test('blockFinished from requests.isFinished', () => { expect( mapStateToProps(testState).blockFinished, - ).toEqual(selectors.requests.isFinished(testState, { requestKey: RequestKeys.fetchBlock })); + ).toEqual( + selectors.app.isCreateBlock(testState) + || selectors.requests.isFinished(testState, { requestKey: RequestKeys.fetchBlock }) + ); }); test('advancedSettingsFinished from requests.isFinished', () => { expect( mapStateToProps(testState).advancedSettingsFinished, - ).toEqual(selectors.requests.isFinished(testState, { requestKey: RequestKeys.fetchAdvancedSettings })); + ).toEqual( + selectors.app.isCreateBlock(testState) + || selectors.requests.isFinished(testState, { requestKey: RequestKeys.fetchAdvancedSettings }) + ); }); }); describe('mapDispatchToProps', () => { diff --git a/src/editors/data/constants/requests.ts b/src/editors/data/constants/requests.ts index 1336c7fdca..be2efcb23b 100644 --- a/src/editors/data/constants/requests.ts +++ b/src/editors/data/constants/requests.ts @@ -13,7 +13,7 @@ export const RequestKeys = StrictDict({ fetchImages: 'fetchImages', fetchUnit: 'fetchUnit', fetchStudioView: 'fetchStudioView', - creaateBlock: 'createBlock', + createBlock: 'createBlock', saveBlock: 'saveBlock', uploadVideo: 'uploadVideo', allowThumbnailUpload: 'allowThumbnailUpload', diff --git a/src/editors/data/redux/app/selectors.test.ts b/src/editors/data/redux/app/selectors.test.ts index f3ceed36e5..43a63ad94b 100644 --- a/src/editors/data/redux/app/selectors.test.ts +++ b/src/editors/data/redux/app/selectors.test.ts @@ -88,6 +88,7 @@ describe('app selectors unit tests', () => { simpleSelectors.unitUrl, simpleSelectors.blockValue, selectors.isLibrary, + selectors.isCreateBlock, ]); }); describe('for library blocks', () => { @@ -118,6 +119,16 @@ describe('app selectors unit tests', () => { ].map(([args, expected]) => expect(cb(...args)).toEqual(expected)); }); }); + describe('component creation workflow', () => { + it('returns true if is isCreateBlock is truthy', () => { + const { resultFunc: cb } = selectors.isInitialized; + + [ + [[null, null, true, true] as [any, any, any, any], true] as const, + [[null, null, true, true] as [any, any, any, any], true] as const, + ].map(([args, expected]) => expect(cb(...args)).toEqual(expected)); + }); + }); }); describe('displayTitle', () => { const title = 'tItLe'; @@ -184,4 +195,9 @@ describe('app selectors unit tests', () => { }); }); }); + describe('isCreateBlock', () => { + it('should return false if the editor is initialized with a blockId', () => { + expect(selectors.isCreateBlock.resultFunc('block-v1:', 'text')).toEqual(false); + }); + }); }); diff --git a/src/editors/data/redux/thunkActions/app.js b/src/editors/data/redux/thunkActions/app.js index 3a63b834d3..5d99027b6a 100644 --- a/src/editors/data/redux/thunkActions/app.js +++ b/src/editors/data/redux/thunkActions/app.js @@ -89,8 +89,7 @@ export const fetchCourseDetails = () => (dispatch) => { export const initialize = (data) => (dispatch) => { const editorType = data.blockType; dispatch(actions.app.initialize(data)); - - if (data.blockId === '' && data.blockType) { + if (data.blockId === '' && editorType) { dispatch(actions.app.initializeEditor()); return; } diff --git a/src/editors/data/redux/thunkActions/app.test.js b/src/editors/data/redux/thunkActions/app.test.js index 5cf52f7941..a3c098ef61 100644 --- a/src/editors/data/redux/thunkActions/app.test.js +++ b/src/editors/data/redux/thunkActions/app.test.js @@ -7,6 +7,7 @@ import * as thunkActions from './app'; jest.mock('./requests', () => ({ fetchBlock: (args) => ({ fetchBlock: args }), fetchUnit: (args) => ({ fetchUnit: args }), + createBlock: (args) => ({ createBlock: args }), saveBlock: (args) => ({ saveBlock: args }), uploadAsset: (args) => ({ uploadAsset: args }), fetchStudioView: (args) => ({ fetchStudioView: args }), @@ -196,6 +197,21 @@ describe('app thunkActions', () => { thunkActions.fetchCourseDetails = fetchCourseDetails; }); }); + describe('initialize without block id but block type defined', () => { + it('dispatches actions.app.initialize, and then fetches both block and unit', () => { + const data = { + ...testValue, + blockType: 'html', + blockId: '', + learningContextId: 'course-v1:UniversityX+PHYS+1', + }; + thunkActions.initialize(data)(dispatch); + expect(dispatch.mock.calls).toEqual([ + [actions.app.initialize(data)], + [actions.app.initializeEditor()], + ]); + }); + }); describe('initialize with block type html', () => { it('dispatches actions.app.initialize, and then fetches both block and unit', () => { const { @@ -333,6 +349,26 @@ describe('app thunkActions', () => { expect(returnToUnit).toHaveBeenCalled(); }); }); + describe('createBlock', () => { + let returnToUnit; + beforeEach(() => { + returnToUnit = jest.fn(); + thunkActions.createBlock(testValue, returnToUnit)(dispatch); + [[dispatchedAction]] = dispatch.mock.calls; + }); + it('dispatches createBlock', () => { + expect(dispatchedAction.createBlock).not.toBe(undefined); + }); + test('onSuccess: calls setBlockId and dispatches saveBlock', () => { + const { + saveBlock, + } = thunkActions; + thunkActions.saveBlock = saveBlock; + + dispatchedAction.createBlock.onSuccess({ id: 'library' }); + expect(dispatch).toHaveBeenCalledWith(actions.app.setBlockId('library')); + }); + }); describe('uploadAsset', () => { const setSelection = jest.fn(); beforeEach(() => { diff --git a/src/editors/data/redux/thunkActions/requests.js b/src/editors/data/redux/thunkActions/requests.js index cb0cd60d31..d0564996f2 100644 --- a/src/editors/data/redux/thunkActions/requests.js +++ b/src/editors/data/redux/thunkActions/requests.js @@ -126,8 +126,7 @@ export const saveBlock = ({ content, ...rest }) => (dispatch, getState) => { }; /** - * Tracked saveBlock api method. Tracked to the `saveBlock` request key. - * @param {string} content + * Tracked createBlock api method. Tracked to the `createBlock` request key. * @param {[func]} onSuccess - onSuccess method ((response) => { ... }) * @param {[func]} onFailure - onFailure method ((error) => { ... }) */ @@ -137,7 +136,7 @@ export const createBlock = ({ ...rest }) => (dispatch, getState) => { : `${uuid4()}`; dispatch(module.networkRequest({ - requestKey: RequestKeys.creaateBlock, + requestKey: RequestKeys.createBlock, promise: createLibraryBlock({ libraryId: selectors.app.learningContextId(getState()), blockType: selectors.app.blockType(getState()), diff --git a/src/editors/data/redux/thunkActions/requests.test.js b/src/editors/data/redux/thunkActions/requests.test.js index ece5411780..ebe78a6a6b 100644 --- a/src/editors/data/redux/thunkActions/requests.test.js +++ b/src/editors/data/redux/thunkActions/requests.test.js @@ -3,6 +3,7 @@ import { RequestKeys } from '../../constants/requests'; import api from '../../services/cms/api'; import * as requests from './requests'; import { actions, selectors } from '../index'; +import { createLibraryBlock } from '../../../../library-authoring/data/api'; const testState = { some: 'data', @@ -17,7 +18,7 @@ jest.mock('../app/selectors', () => ({ blockId: (state) => ({ blockId: state }), blockType: (state) => ({ blockType: state }), learningContextId: (state) => ({ learningContextId: state }), - blockTitle: (state) => ({ title: state }), + blockTitle: (state) => state.data, })); jest.mock('../../services/cms/api', () => ({ @@ -41,6 +42,10 @@ jest.mock('../../services/cms/api', () => ({ uploadVideo: (args) => args, })); +jest.mock('../../../../library-authoring/data/api', () => ({ + createLibraryBlock: ({ id, url }) => ({ id, url }), +})); + jest.mock('../../../utils', () => ({ ...jest.requireActual('../../../utils'), parseLibraryImageData: jest.fn(), @@ -349,6 +354,21 @@ describe('requests thunkActions module', () => { }, }); }); + describe('createBlock', () => { + testNetworkRequestAction({ + action: requests.createBlock, + args: { ...fetchParams }, + expectedString: 'with create promise', + expectedData: { + ...fetchParams, + requestKey: RequestKeys.createBlock, + promise: createLibraryBlock({ + libraryId: selectors.app.learningContextId(testState), + blockType: selectors.app.blockType(testState), + }), + }, + }); + }); describe('uploadAsset', () => { const asset = 'SoME iMage CoNtent As String'; let uploadAsset;