diff --git a/src/editors/containers/VideoUploadEditor/VideoUploader.jsx b/src/editors/containers/VideoUploadEditor/VideoUploader.jsx index ca5298b41..d3705d8b3 100644 --- a/src/editors/containers/VideoUploadEditor/VideoUploader.jsx +++ b/src/editors/containers/VideoUploadEditor/VideoUploader.jsx @@ -26,10 +26,11 @@ const URLUploader = () => { ); }; -export const VideoUploader = ({ onUpload, setLoading }) => { - const [textInputValue, settextInputValue] = React.useState(''); +export const VideoUploader = ({ setLoading }) => { + const [textInputValue, setTextInputValue] = React.useState(''); const onURLUpload = hooks.onVideoUpload(); const intl = useIntl(); + const dispatch = useDispatch(); const handleProcessUpload = ({ fileData }) => { dispatch(thunkActions.video.uploadVideo({ @@ -53,7 +54,7 @@ export const VideoUploader = ({ onUpload, setLoading }) => { aria-label={intl.formatMessage(messages.pasteURL)} aria-describedby="basic-addon2" borderless - onChange={(event) => { settextInputValue(event.target.value); }} + onChange={(event) => { setTextInputValue(event.target.value); }} />
{ }; VideoUploader.propTypes = { - onUpload: PropTypes.func.isRequired, setLoading: PropTypes.func.isRequired, }; diff --git a/src/editors/containers/VideoUploadEditor/hooks.js b/src/editors/containers/VideoUploadEditor/hooks.js index b0571a03c..7771f2d48 100644 --- a/src/editors/containers/VideoUploadEditor/hooks.js +++ b/src/editors/containers/VideoUploadEditor/hooks.js @@ -1,6 +1,5 @@ -import React from 'react'; import * as module from './hooks'; -import { selectors } from '../../data/redux'; +import { selectors, thunkActions } from '../../data/redux'; import store from '../../data/store'; import * as appHooks from '../../hooks'; @@ -8,29 +7,6 @@ export const { navigateTo, } = appHooks; -export const state = { - // eslint-disable-next-line react-hooks/rules-of-hooks - loading: (val) => React.useState(val), - // eslint-disable-next-line react-hooks/rules-of-hooks - textInputValue: (val) => React.useState(val), -}; - -export const uploadEditor = () => { - const [loading, setLoading] = module.state.loading(false); - return { - loading, - setLoading, - }; -}; - -export const uploader = () => { - const [textInputValue, settextInputValue] = module.state.textInputValue(''); - return { - textInputValue, - settextInputValue, - }; -}; - export const postUploadRedirect = (storeState) => { const learningContextId = selectors.app.learningContextId(storeState); const blockId = selectors.app.blockId(storeState); @@ -42,9 +18,21 @@ export const onVideoUpload = () => { return module.postUploadRedirect(storeState); }; +export const useUploadVideo = async ({ + dispatch, + supportedFiles, + setLoadSpinner, + postUploadRedirectFunction, +}) => { + dispatch(thunkActions.video.uploadVideo({ + supportedFiles, + setLoadSpinner, + postUploadRedirectFunction, + })); +}; + export default { postUploadRedirect, - uploadEditor, - uploader, onVideoUpload, + useUploadVideo, }; diff --git a/src/editors/containers/VideoUploadEditor/hooks.test.js b/src/editors/containers/VideoUploadEditor/hooks.test.js deleted file mode 100644 index 3f2a5eb85..000000000 --- a/src/editors/containers/VideoUploadEditor/hooks.test.js +++ /dev/null @@ -1,27 +0,0 @@ -import * as hooks from './hooks'; -import { MockUseState } from '../../../testUtils'; - -const state = new MockUseState(hooks); - -describe('Video Upload Editor hooks', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - describe('state hooks', () => { - state.testGetter(state.keys.loading); - }); - describe('using state', () => { - beforeEach(() => { state.mock(); }); - afterEach(() => { state.restore(); }); - - describe('Hooks for Video Upload', () => { - beforeEach(() => { - hooks.uploadEditor(); - hooks.uploader(); - }); - it('initialize state with correct values', () => { - expect(state.stateVals.loading).toEqual(false); - }); - }); - }); -}); diff --git a/src/editors/containers/VideoUploadEditor/index.jsx b/src/editors/containers/VideoUploadEditor/index.jsx index 67ebde6cb..3080e9f2b 100644 --- a/src/editors/containers/VideoUploadEditor/index.jsx +++ b/src/editors/containers/VideoUploadEditor/index.jsx @@ -5,20 +5,14 @@ import { Icon, IconButton, Spinner, } from '@edx/paragon'; import { Close } from '@edx/paragon/icons'; -import { connect } from 'react-redux'; -import { thunkActions } from '../../data/redux'; import './index.scss'; -import * as hooks from './hooks'; import messages from './messages'; -import * as editorHooks from '../EditorContainer/hooks'; import { VideoUploader } from './VideoUploader'; import * as editorHooks from '../EditorContainer/hooks'; export const VideoUploadEditor = ( { onClose, - // Redux states - uploadVideo, }, ) => { const [loading, setLoading] = React.useState(false); @@ -37,7 +31,7 @@ export const VideoUploadEditor = ( onClick={handleCancel} />
- + ) : (
@@ -54,13 +48,6 @@ export const VideoUploadEditor = ( VideoUploadEditor.propTypes = { onClose: PropTypes.func.isRequired, - uploadVideo: PropTypes.func.isRequired, }; -export const mapStateToProps = () => ({}); - -export const mapDispatchToProps = { - uploadVideo: thunkActions.video.uploadVideo, -}; - -export default connect(mapStateToProps, mapDispatchToProps)(VideoUploadEditor); +export default VideoUploadEditor; diff --git a/src/editors/containers/VideoUploadEditor/index.test.jsx b/src/editors/containers/VideoUploadEditor/index.test.jsx index 6f3e0a1ff..bf032cd70 100644 --- a/src/editors/containers/VideoUploadEditor/index.test.jsx +++ b/src/editors/containers/VideoUploadEditor/index.test.jsx @@ -1,5 +1,9 @@ import React from 'react'; import { IntlProvider } from '@edx/frontend-platform/i18n'; +import { initializeMockApp } from '@edx/frontend-platform'; +import { AppProvider } from '@edx/frontend-platform/react'; +import { configureStore } from '@reduxjs/toolkit'; +import { render, fireEvent } from '@testing-library/react'; import '@testing-library/jest-dom'; import VideoUploadEditor from '.'; diff --git a/src/editors/data/redux/thunkActions/video.js b/src/editors/data/redux/thunkActions/video.js index 33d0c09e6..f42dab84f 100644 --- a/src/editors/data/redux/thunkActions/video.js +++ b/src/editors/data/redux/thunkActions/video.js @@ -11,10 +11,16 @@ export const loadVideoData = (selectedVideoId, selectedVideoUrl) => (dispatch, g const state = getState(); const blockValueData = state.app.blockValue.data; let rawVideoData = blockValueData.metadata ? blockValueData.metadata : {}; - if (selectedVideoId != null) { - const rawVideos = Object.values(selectors.app.videos(state)); - const selectedVideo = rawVideos.find(video => video.edx_video_id === selectedVideoId); - if (selectedVideo) { + const rawVideos = Object.values(selectors.app.videos(state)); + if (selectedVideoId !== undefined && selectedVideoId !== null) { + const selectedVideo = _.find(rawVideos, video => { + if (_.has(video, 'edx_video_id')) { + return video.edx_video_id === selectedVideoId; + } + return false; + }); + + if (selectedVideo !== undefined && selectedVideo !== null) { rawVideoData = { edx_video_id: selectedVideo.edx_video_id, thumbnail: selectedVideo.course_video_image_url, diff --git a/src/editors/data/redux/thunkActions/video.test.js b/src/editors/data/redux/thunkActions/video.test.js index 8563c039e..b91316661 100644 --- a/src/editors/data/redux/thunkActions/video.test.js +++ b/src/editors/data/redux/thunkActions/video.test.js @@ -88,6 +88,7 @@ const testState = { const testVideosState = { edx_video_id: mockSelectedVideoId, thumbnail: 'thumbnail', + course_video_image_url: 'course_video_image_url', duration: 60, transcripts: ['es'], transcript_urls: { es: 'url' }, @@ -262,6 +263,61 @@ describe('video thunkActions', () => { noDerivatives: true, shareAlike: false, }, + thumbnail: testVideosState.course_video_image_url, + }); + }); + it('dispatches actions.video.load with different selectedVideoId', () => { + getState = jest.fn(() => ({ + app: { + blockId: 'soMEBloCk', + studioEndpointUrl: 'soMEeNDPoiNT', + blockValue: { data: { metadata: {} } }, + courseDetails: { data: { license: null } }, + studioView: { data: { html: 'sOMeHTml' } }, + videos: testVideosState, + }, + })); + thunkActions.loadVideoData('ThisIsAVideoId2', null)(dispatch, getState); + [ + [dispatchedLoad], + [dispatchedAction1], + [dispatchedAction2], + ] = dispatch.mock.calls; + expect(dispatchedLoad.load).toEqual({ + videoSource: 'videOsOurce', + videoId: 'videOiD', + fallbackVideos: 'fALLbACKvIDeos', + allowVideoDownloads: undefined, + transcripts: testMetadata.transcripts, + selectedVideoTranscriptUrls: testMetadata.transcript_urls, + allowTranscriptDownloads: undefined, + allowVideoSharing: { + level: 'course', + value: true, + }, + showTranscriptByDefault: undefined, + duration: { + startTime: testMetadata.start_time, + stopTime: 0, + total: 0, + }, + handout: undefined, + licenseType: 'liCENSEtyPe', + licenseDetails: { + attribution: true, + noncommercial: true, + noDerivatives: true, + shareAlike: false, + }, + videoSharingEnabledForCourse: undefined, + videoSharingLearnMoreLink: undefined, + courseLicenseType: 'liCENSEtyPe', + courseLicenseDetails: { + attribution: true, + noncommercial: true, + noDerivatives: true, + shareAlike: false, + }, thumbnail: undefined, }); });