diff --git a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/VideoSourceWidget/hooks.jsx b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/VideoSourceWidget/hooks.jsx index d68d1cde2..90a8fce8c 100644 --- a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/VideoSourceWidget/hooks.jsx +++ b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/VideoSourceWidget/hooks.jsx @@ -1,70 +1,19 @@ import { actions } from '../../../../../../data/redux'; -import { isEdxVideo } from '../../../../../../data/services/cms/api'; -/** - * updateVideoId({ dispatch })({e, source}) - * updateVideoId takes the current onBlur event, the current object of the video - * source, and dispatch method, and updates the redux value for all the fields to - * their default values except videoId, fallbackVideos, and handouts. - * @param {event} e - object for onBlur event - * @param {func} dispatch - redux dispatch method - * @param {object} source - object for the Video Source field functions and values - */ -export const updateVideoId = ({ dispatch }) => ({ e, source }) => { - if (source.local !== '') { - if (source.formValue !== e.target.value) { - source.onBlur(e); - let videoId; - let videoSource; - if (isEdxVideo(source.local)) { - videoId = source.local; - videoSource = ''; - } else if (source.local.includes('youtu.be') || source.local.includes('youtube')) { - videoId = ''; - videoSource = source.local; - } else { - videoId = ''; - videoSource = source.local; - } - dispatch(actions.video.updateField({ - videoId, - videoSource, - allowVideoDownloads: false, - thumbnail: null, - transcripts: [], - allowTranscriptDownloads: false, - showTranscriptByDefault: false, - duration: { - startTime: '00:00:00', - stopTime: '00:00:00', - total: '00:00:00', - }, - licenseType: null, - })); - } - } +export const sourceHooks = ({ dispatch }) => ({ + updateVideoURL: (e) => dispatch(actions.video.updateField({ videoSource: e.target.value })), + updateVideoId: (e) => dispatch(actions.video.updateField({ videoId: e.target.value })), +}); + +export const fallbackHooks = ({ fallbackVideos, dispatch }) => ({ + addFallbackVideo: () => dispatch(actions.video.updateField({ fallbackVideos: [...fallbackVideos, ''] })), + deleteFallbackVideo: (videoUrl) => { + const updatedFallbackVideos = fallbackVideos.splice(fallbackVideos.indexOf(videoUrl), 1); + dispatch(actions.video.updateField({ fallbackVideos: updatedFallbackVideos })); + }, +}); + +export default { + sourceHooks, + fallbackHooks, }; - -/** - * deleteFallbackVideo({ fallbackVideos, dispatch })(videoUrl) - * deleteFallbackVideo takes the current array of fallback videos, string of - * deleted video URL and dispatch method, and updates the redux value for - * fallbackVideos. - * @param {array} fallbackVideos - array of current fallback videos - * @param {func} dispatch - redux dispatch method - * @param {string} videoUrl - string of the video URL for the fallabck video that needs to be deleted - */ -export const deleteFallbackVideo = ({ fallbackVideos, dispatch }) => (videoUrl) => { - const updatedFallbackVideos = []; - let firstOccurence = true; - fallbackVideos.forEach(item => { - if (item === videoUrl && firstOccurence) { - firstOccurence = false; - } else { - updatedFallbackVideos.push(item); - } - }); - dispatch(actions.video.updateField({ fallbackVideos: updatedFallbackVideos })); -}; - -export default { deleteFallbackVideo }; diff --git a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/VideoSourceWidget/hooks.test.jsx b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/VideoSourceWidget/hooks.test.jsx index 4f21f183e..34181e523 100644 --- a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/VideoSourceWidget/hooks.test.jsx +++ b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/VideoSourceWidget/hooks.test.jsx @@ -6,6 +6,7 @@ jest.mock('react-redux', () => { const dispatchFn = jest.fn(); return { ...jest.requireActual('react-redux'), + useSelector: jest.fn(), dispatch: dispatchFn, useDispatch: jest.fn(() => dispatchFn), }; @@ -20,78 +21,61 @@ jest.mock('../../../../../../data/redux', () => ({ })); describe('VideoEditorHandout hooks', () => { - describe('updateVideoId', () => { - const sourceEdxVideo = { - onBlur: jest.fn(), - local: '06b15030-7df0-4e70-b979-326e02dbcbe0', - }; - const sourceYouTube = { - onBlur: jest.fn(), - local: 'youtu.be', - }; - const sourceHtml5Source = { - onBlur: jest.fn(), - local: 'sOMEranDomfILe.mp4', - }; - const mockState = { - videoId: '', - videoSource: '', - allowVideoDownloads: false, - thumbnail: null, - transcripts: [], - allowTranscriptDownloads: false, - showTranscriptByDefault: false, - duration: { - startTime: '00:00:00', - stopTime: '00:00:00', - total: '00:00:00', - }, - licenseType: null, - }; - it('returns dispatches updateField action with default state and edxVideo Id', () => { - hooks.updateVideoId({ dispatch })({ e: { target: { value: sourceEdxVideo.local } }, source: sourceEdxVideo }); - expect(dispatch).toHaveBeenCalledWith( - actions.video.updateField({ - ...mockState, - videoId: sourceEdxVideo.local, - }), - ); + let hook; + + describe('sourceHooks', () => { + const e = { target: { value: 'soMEvALuE' } }; + beforeEach(() => { + hook = hooks.sourceHooks({ dispatch }); }); - it('returns dispatches updateField action with default state and YouTube video', () => { - hooks.updateVideoId({ dispatch })({ - e: { target: { value: sourceYouTube.local } }, - source: sourceYouTube, + describe('updateVideoURL', () => { + it('dispatches updateField action with new videoSource', () => { + hook.updateVideoURL(e); + expect(dispatch).toHaveBeenCalledWith( + actions.video.updateField({ + videoSource: e.target.value, + }), + ); }); - expect(dispatch).toHaveBeenCalledWith( - actions.video.updateField({ - ...mockState, - }), - ); }); - it('returns dispatches updateField action with default state and html5source video', () => { - hooks.updateVideoId({ dispatch })({ - e: { target: { value: sourceHtml5Source.local } }, - source: sourceHtml5Source, + describe('updateVideoId', () => { + it('dispatches updateField action with new videoId', () => { + hook.updateVideoId(e); + expect(dispatch).toHaveBeenCalledWith( + actions.video.updateField({ + videoId: e.target.value, + }), + ); }); - expect(dispatch).toHaveBeenCalledWith( - actions.video.updateField({ - ...mockState, - }), - ); }); }); - describe('deleteFallbackVideo', () => { + describe('fallbackHooks', () => { const videoUrl = 'sOmERAndoMuRl1'; const fallbackVideos = ['sOmERAndoMuRl1', 'sOmERAndoMuRl2', 'sOmERAndoMuRl1', '']; - const updatedFallbackVideos = ['sOmERAndoMuRl2', 'sOmERAndoMuRl1', '']; - it('returns dispatches updateField action with updatedFallbackVideos', () => { - hooks.deleteFallbackVideo({ fallbackVideos, dispatch })(videoUrl); - expect(dispatch).toHaveBeenCalledWith( - actions.video.updateField({ - fallbackVideos: updatedFallbackVideos, - }), - ); + beforeEach(() => { + hook = hooks.fallbackHooks({ fallbackVideos, dispatch }); + }); + describe('addFallbackVideo', () => { + it('dispatches updateField action with updated array appended by a new empty element', () => { + hook.addFallbackVideo(); + expect(dispatch).toHaveBeenCalledWith( + actions.video.updateField({ + fallbackVideos: [...fallbackVideos, ''], + }), + ); + }); + }); + describe('deleteFallbackVideo', () => { + it('dispatches updateField action with updated array with videoUrl removed', () => { + const updatedFallbackVideos = ['sOmERAndoMuRl2', 'sOmERAndoMuRl1', '']; + hook.deleteFallbackVideo(videoUrl); + expect(dispatch).toHaveBeenCalledWith( + actions.video.updateField({ + fallbackVideos: updatedFallbackVideos, + }), + ); + }); }); }); }); diff --git a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/VideoSourceWidget/index.jsx b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/VideoSourceWidget/index.jsx index 7dc2762d5..915f4281e 100644 --- a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/VideoSourceWidget/index.jsx +++ b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/VideoSourceWidget/index.jsx @@ -1,6 +1,5 @@ import React from 'react'; -import { connect, useDispatch } from 'react-redux'; -import PropTypes from 'prop-types'; +import { useDispatch } from 'react-redux'; import { Form, @@ -20,9 +19,8 @@ import { } from '@edx/frontend-platform/i18n'; import * as widgetHooks from '../hooks'; -import * as module from './hooks'; +import * as hooks from './hooks'; import messages from './messages'; -import { actions } from '../../../../../../data/redux'; import CollapsibleFormWidget from '../CollapsibleFormWidget'; @@ -32,8 +30,6 @@ import CollapsibleFormWidget from '../CollapsibleFormWidget'; export const VideoSourceWidget = ({ // injected intl, - // redux - updateField, }) => { const dispatch = useDispatch(); const { @@ -50,8 +46,11 @@ export const VideoSourceWidget = ({ [widgetHooks.selectorKeys.allowVideoDownloads]: widgetHooks.genericWidget, }, }); - const deleteFallbackVideo = module.deleteFallbackVideo({ fallbackVideos: fallbackVideos.formValue, dispatch }); - const updateVideoId = module.updateVideoId({ dispatch }); + const { updateVideoId, updateVideoURL } = hooks.sourceHooks({ dispatch }); + const { + addFallbackVideo, + deleteFallbackVideo, + } = hooks.fallbackHooks({ fallbackVideos: fallbackVideos.formValue, dispatch }); return ( updateVideoId({ e, source: videoId })} + onBlur={updateVideoId} value={videoId.local} /> @@ -72,7 +71,7 @@ export const VideoSourceWidget = ({ updateVideoId({ e, source })} + onBlur={updateVideoURL} value={source.local} /> @@ -134,7 +133,7 @@ export const VideoSourceWidget = ({ size="sm" iconBefore={Add} variant="link" - onClick={() => updateField({ fallbackVideos: [...fallbackVideos.formValue, ''] })} + onClick={() => addFallbackVideo()} > @@ -144,12 +143,6 @@ export const VideoSourceWidget = ({ VideoSourceWidget.propTypes = { // injected intl: intlShape.isRequired, - // redux - updateField: PropTypes.func.isRequired, }; -export const mapStateToProps = () => ({}); -export const mapDispatchToProps = (dispatch) => ({ - updateField: (stateUpdate) => dispatch(actions.video.updateField(stateUpdate)), -}); -export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(VideoSourceWidget)); +export default injectIntl(VideoSourceWidget); diff --git a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/VideoSourceWidget/index.test.jsx b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/VideoSourceWidget/index.test.jsx index fcc48d57a..88d5825db 100644 --- a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/VideoSourceWidget/index.test.jsx +++ b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/VideoSourceWidget/index.test.jsx @@ -1,25 +1,19 @@ import React from 'react'; +import { dispatch } from 'react-redux'; import { shallow } from 'enzyme'; import { formatMessage } from '../../../../../../../testUtils'; -import { actions } from '../../../../../../data/redux'; -import { VideoSourceWidget, mapDispatchToProps } from '.'; +import { VideoSourceWidget } from '.'; +import * as hooks from './hooks'; -jest.mock('../../../../../../data/redux', () => ({ - actions: { - video: { - updateField: jest.fn().mockName('actions.video.updateField'), - }, - }, - selectors: { - video: { - videoSource: jest.fn(state => ({ videoSource: state })), - videoId: jest.fn(state => ({ videoId: state })), - fallbackVideos: jest.fn(state => ({ fallbackVideos: state })), - allowVideoDownloads: jest.fn(state => ({ allowVideoDownloads: state })), - }, - }, -})); +jest.mock('react-redux', () => { + const dispatchFn = jest.fn(); + return { + ...jest.requireActual('react-redux'), + dispatch: dispatchFn, + useDispatch: jest.fn(() => dispatchFn), + }; +}); jest.mock('../hooks', () => ({ selectorKeys: ['soMEkEy'], @@ -36,14 +30,21 @@ jest.mock('../hooks', () => ({ }), })); +jest.mock('./hooks', () => ({ + sourceHooks: jest.fn().mockReturnValue({ + updateVideoId: (args) => ({ updateVideoId: args }), + updateVideoURL: (args) => ({ updateVideoURL: args }), + }), + fallbackHooks: jest.fn().mockReturnValue({ + addFallbackVideo: jest.fn().mockName('addFallbackVideo'), + deleteFallbackVideo: jest.fn().mockName('deleteFallbackVideo'), + }), +})); + describe('VideoSourceWidget', () => { const props = { - error: {}, - title: 'tiTLE', // inject intl: { formatMessage }, - // redux - updateField: jest.fn().mockName('args.updateField'), }; describe('snapshots', () => { @@ -53,10 +54,27 @@ describe('VideoSourceWidget', () => { ).toMatchSnapshot(); }); }); - describe('mapDispatchToProps', () => { - const dispatch = jest.fn(); - test('updateField from actions.video.updateField', () => { - expect(mapDispatchToProps.updateField).toEqual(dispatch(actions.video.updateField)); + + describe('behavior inspection', () => { + let el; + let hook; + beforeEach(() => { + el = shallow(); + hook = hooks.sourceHooks({ dispatch }); + }); + test('updateVideoId is tied to id field onBlur', () => { + const expected = hook.updateVideoId; + expect(el + // eslint-disable-next-line + .children().at(0).children().at(0).children().at(0) + .props().onBlur).toEqual(expected); + }); + test('updateVideoURL is tied to url field onBlur', () => { + const expected = hook.updateVideoURL; + expect(el + // eslint-disable-next-line + .children().at(0).children().at(0).children().at(2) + .props().onBlur).toEqual(expected); }); }); }); diff --git a/src/editors/data/redux/thunkActions/video.js b/src/editors/data/redux/thunkActions/video.js index f36ecd86d..4b3d628a3 100644 --- a/src/editors/data/redux/thunkActions/video.js +++ b/src/editors/data/redux/thunkActions/video.js @@ -11,10 +11,10 @@ export const loadVideoData = () => (dispatch, getState) => { const courseLicenseData = state.app.courseDetails.data ? state.app.courseDetails.data : {}; const studioView = state.app.studioView?.data?.html; const { - videoSource, videoId, + videoUrl, fallbackVideos, - } = module.determineVideoSource({ + } = module.determineVideoSources({ edxVideoId: rawVideoData.edx_video_id, youtubeId: rawVideoData.youtube_id_1_0, html5Sources: rawVideoData.html5_sources, @@ -27,7 +27,7 @@ export const loadVideoData = () => (dispatch, getState) => { }); dispatch(actions.video.load({ - videoSource, + videoSource: videoUrl, videoId, fallbackVideos, allowVideoDownloads: rawVideoData.download_video, @@ -61,7 +61,7 @@ export const loadVideoData = () => (dispatch, getState) => { allowThumbnailUpload: response.data.allowThumbnailUpload, })), })); - const youTubeId = parseYoutubeId(videoSource); + const youTubeId = parseYoutubeId(videoUrl); if (youTubeId) { dispatch(requests.checkTranscriptsForImport({ videoId, @@ -77,33 +77,23 @@ export const loadVideoData = () => (dispatch, getState) => { } }; -export const determineVideoSource = ({ +export const determineVideoSources = ({ edxVideoId, youtubeId, html5Sources, }) => { - // videoSource should be the edx_video_id, the youtube url or the first fallback url in that order. - // If we are falling back to the first fallback url, remove it from the list of fallback urls for display. const youtubeUrl = `https://youtu.be/${youtubeId}`; - const videoId = edxVideoId || ''; - let videoSource = ''; - let fallbackVideos = []; + let videoUrl; + let fallbackVideos; if (youtubeId) { - // videoSource = youtubeUrl; - // fallbackVideos = html5Sources; - [videoSource, fallbackVideos] = [youtubeUrl, html5Sources]; - } else if (edxVideoId) { - // fallbackVideos = html5Sources; - fallbackVideos = html5Sources; + [videoUrl, fallbackVideos] = [youtubeUrl, html5Sources]; } else if (Array.isArray(html5Sources) && html5Sources[0]) { - // videoSource = html5Sources[0]; - // fallbackVideos = html5Sources.slice(1); - [videoSource, fallbackVideos] = [html5Sources[0], html5Sources.slice(1)]; + [videoUrl, fallbackVideos] = [html5Sources[0], html5Sources.slice(1)]; } return { - videoSource, - videoId, - fallbackVideos, + videoId: edxVideoId, + videoUrl: videoUrl || '', + fallbackVideos: fallbackVideos || [], }; }; @@ -343,7 +333,7 @@ export const replaceTranscript = ({ newFile, newFilename, language }) => (dispat export default { loadVideoData, - determineVideoSource, + determineVideoSources, parseLicense, saveVideoData, uploadThumbnail, diff --git a/src/editors/data/redux/thunkActions/video.test.js b/src/editors/data/redux/thunkActions/video.test.js index 895d4f425..cb90ecde4 100644 --- a/src/editors/data/redux/thunkActions/video.test.js +++ b/src/editors/data/redux/thunkActions/video.test.js @@ -99,8 +99,8 @@ describe('video thunkActions', () => { let dispatchedAction1; let dispatchedAction2; beforeEach(() => { - jest.spyOn(thunkActions, thunkActionsKeys.determineVideoSource).mockReturnValue({ - videoSource: 'videOsOurce', + jest.spyOn(thunkActions, thunkActionsKeys.determineVideoSources).mockReturnValue({ + videoUrl: 'videOsOurce', videoId: 'videOiD', fallbackVideos: 'fALLbACKvIDeos', }); @@ -176,69 +176,69 @@ describe('video thunkActions', () => { })); }); }); - describe('determineVideoSource', () => { + describe('determineVideoSources', () => { const edxVideoId = 'EDxviDEoiD'; const youtubeId = 'yOuTuBEiD'; const youtubeUrl = `https://youtu.be/${youtubeId}`; const html5Sources = ['htmLOne', 'hTMlTwo', 'htMLthrEE']; describe('when there is an edx video id, youtube id and html5 sources', () => { - it('returns the youtube id for video source and html5 sources for fallback videos', () => { - expect(thunkActions.determineVideoSource({ + it('returns all three with the youtube id wrapped in url', () => { + expect(thunkActions.determineVideoSources({ edxVideoId, youtubeId, html5Sources, })).toEqual({ - videoSource: youtubeUrl, + videoUrl: youtubeUrl, videoId: edxVideoId, fallbackVideos: html5Sources, }); }); }); - describe('when there is an edx video id', () => { + describe('when there is only an edx video id', () => { it('returns the edx video id for video source', () => { - expect(thunkActions.determineVideoSource({ + expect(thunkActions.determineVideoSources({ edxVideoId, youtubeId: '', html5Sources: '', })).toEqual({ - videoSource: '', + videoUrl: '', videoId: edxVideoId, - fallbackVideos: '', + fallbackVideos: [], }); }); }); describe('when there is no edx video id', () => { it('returns the youtube url for video source and html5 sources for fallback videos', () => { - expect(thunkActions.determineVideoSource({ + expect(thunkActions.determineVideoSources({ edxVideoId: '', youtubeId, html5Sources, })).toEqual({ - videoSource: youtubeUrl, + videoUrl: youtubeUrl, videoId: '', fallbackVideos: html5Sources, }); }); }); describe('when there is no edx video id and no youtube id', () => { - it('returns the first html5 source for video source and the rest for fallback videos', () => { - expect(thunkActions.determineVideoSource({ + it('returns the first html5 source for video url and the rest for fallback videos', () => { + expect(thunkActions.determineVideoSources({ edxVideoId: '', youtubeId: '', html5Sources, })).toEqual({ - videoSource: 'htmLOne', + videoUrl: 'htmLOne', videoId: '', fallbackVideos: ['hTMlTwo', 'htMLthrEE'], }); }); it('returns the html5 source for video source and an array with 2 empty values for fallback videos', () => { - expect(thunkActions.determineVideoSource({ + expect(thunkActions.determineVideoSources({ edxVideoId: '', youtubeId: '', html5Sources: ['htmlOne'], })).toEqual({ - videoSource: 'htmlOne', + videoUrl: 'htmlOne', videoId: '', fallbackVideos: [], }); @@ -246,12 +246,12 @@ describe('video thunkActions', () => { }); describe('when there is no edx video id, no youtube id and no html5 sources', () => { it('returns an empty string for video source and an array with 2 empty values for fallback videos', () => { - expect(thunkActions.determineVideoSource({ + expect(thunkActions.determineVideoSources({ edxVideoId: '', youtubeId: '', html5Sources: [], })).toEqual({ - videoSource: '', + videoUrl: '', videoId: '', fallbackVideos: [], }); diff --git a/src/editors/data/services/cms/api.js b/src/editors/data/services/cms/api.js index 434df60f5..66183e99a 100644 --- a/src/editors/data/services/cms/api.js +++ b/src/editors/data/services/cms/api.js @@ -157,7 +157,7 @@ export const apiMethods = { youtubeId, } = module.processVideoIds({ videoId: content.videoId, - videoSource: content.videoSource, + videoUrl: content.videoSource, fallbackVideos: content.fallbackVideos, }); response = { @@ -217,21 +217,18 @@ export const loadImages = (rawImages) => camelizeKeys(rawImages).reduce( export const processVideoIds = ({ videoId, - videoSource, + videoUrl, fallbackVideos, - edxVideoId, }) => { - let newEdxVideoId = edxVideoId; let youtubeId = ''; const html5Sources = []; - // overwrite videoId if source is changed. - if (module.isEdxVideo(videoId)) { - newEdxVideoId = videoId; - } else if (module.parseYoutubeId(videoSource)) { - youtubeId = module.parseYoutubeId(videoSource); - } else if (videoSource) { - html5Sources.push(videoSource); + if (videoUrl) { + if (module.parseYoutubeId(videoUrl)) { + youtubeId = module.parseYoutubeId(videoUrl); + } else { + html5Sources.push(videoUrl); + } } if (fallbackVideos) { @@ -239,7 +236,7 @@ export const processVideoIds = ({ } return { - edxVideoId: newEdxVideoId, + edxVideoId: videoId, html5Sources, youtubeId, }; diff --git a/src/editors/data/services/cms/api.test.js b/src/editors/data/services/cms/api.test.js index 6426f93d5..004f660dc 100644 --- a/src/editors/data/services/cms/api.test.js +++ b/src/editors/data/services/cms/api.test.js @@ -333,7 +333,8 @@ describe('cms api', () => { }); describe('processVideoIds', () => { const edxVideoId = 'eDXviDEoid'; - const youtubeId = 'yOuTuBeID'; + const youtubeId = 'yOuTuBeUrL'; + const youtubeUrl = `https://youtu.be/${youtubeId}`; const html5Sources = [ 'sOuRce1', 'sourCE2', @@ -341,15 +342,14 @@ describe('cms api', () => { afterEach(() => { jest.restoreAllMocks(); }); - describe('if the videoSource is an edx video id', () => { + describe('if there is a video id', () => { beforeEach(() => { jest.spyOn(api, 'isEdxVideo').mockReturnValue(true); - jest.spyOn(api, 'parseYoutubeId').mockReturnValue(null); + jest.spyOn(api, 'parseYoutubeId').mockReturnValue(youtubeId); }); it('returns edxVideoId when there are no fallbackVideos', () => { expect(api.processVideoIds({ - edxVideoId, - videoSource: '', + videoUrl: '', fallbackVideos: [], videoId: edxVideoId, })).toEqual({ @@ -360,42 +360,39 @@ describe('cms api', () => { }); it('returns edxVideoId and html5Sources when there are fallbackVideos', () => { expect(api.processVideoIds({ - edxVideoId, - videoSource: 'edxVideoId', + videoUrl: youtubeUrl, fallbackVideos: html5Sources, videoId: edxVideoId, })).toEqual({ edxVideoId, html5Sources, - youtubeId: '', + youtubeId, }); }); }); - describe('if the videoSource is a youtube url', () => { + describe('if there is a youtube url', () => { beforeEach(() => { jest.spyOn(api, 'isEdxVideo').mockReturnValue(false); jest.spyOn(api, 'parseYoutubeId').mockReturnValue(youtubeId); }); it('returns youtubeId when there are no fallbackVideos', () => { expect(api.processVideoIds({ - edxVideoId, - videoSource: edxVideoId, + videoUrl: youtubeUrl, fallbackVideos: [], videoId: '', })).toEqual({ - edxVideoId, + edxVideoId: '', html5Sources: [], youtubeId, }); }); it('returns youtubeId and html5Sources when there are fallbackVideos', () => { expect(api.processVideoIds({ - edxVideoId, - videoSource: edxVideoId, + videoUrl: youtubeUrl, fallbackVideos: html5Sources, videoId: '', })).toEqual({ - edxVideoId, + edxVideoId: '', html5Sources, youtubeId, }); @@ -408,24 +405,22 @@ describe('cms api', () => { }); it('returns html5Sources when there are no fallbackVideos', () => { expect(api.processVideoIds({ - edxVideoId, - videoSource: html5Sources[0], + videoUrl: html5Sources[0], fallbackVideos: [], videoId: '', })).toEqual({ - edxVideoId, + edxVideoId: '', html5Sources: [html5Sources[0]], youtubeId: '', }); }); it('returns html5Sources when there are fallbackVideos', () => { expect(api.processVideoIds({ - edxVideoId, - videoSource: html5Sources[0], + videoUrl: html5Sources[0], fallbackVideos: [html5Sources[1]], videoId: '', })).toEqual({ - edxVideoId, + edxVideoId: '', html5Sources, youtubeId: '', }); diff --git a/src/editors/data/services/cms/mockApi.js b/src/editors/data/services/cms/mockApi.js index ac17d7ff5..68dea813d 100644 --- a/src/editors/data/services/cms/mockApi.js +++ b/src/editors/data/services/cms/mockApi.js @@ -287,3 +287,7 @@ export const fetchStudioView = ({ blockId, studioEndpointUrl }) => { }, }); }; + +export const checkTranscriptsForImport = () => mockPromise({}); + +export const uploadTranscript = () => mockPromise({});