feat: separate video id and url fields into two (#164)

This commit is contained in:
Kristin Aoki
2022-12-12 10:55:32 -05:00
committed by GitHub
parent bcb3c3f7fb
commit 07202c0518
16 changed files with 158 additions and 110 deletions

View File

@@ -42,7 +42,7 @@ exports[`ThumbnailWidget snapshots snapshots: renders as expected where thumbnai
</injectIntl(ShimmedIntlComponent)>
`;
exports[`ThumbnailWidget snapshots snapshots: renders as expected where videoType equals edxVideo 1`] = `
exports[`ThumbnailWidget snapshots snapshots: renders as expected where videoId is valid 1`] = `
<injectIntl(ShimmedIntlComponent)
fontSize="x-small"
isError={true}
@@ -81,7 +81,7 @@ exports[`ThumbnailWidget snapshots snapshots: renders as expected where videoTyp
</injectIntl(ShimmedIntlComponent)>
`;
exports[`ThumbnailWidget snapshots snapshots: renders as expected where videoType equals edxVideo and no thumbnail 1`] = `
exports[`ThumbnailWidget snapshots snapshots: renders as expected where videoId is valid and no thumbnail 1`] = `
<injectIntl(ShimmedIntlComponent)
fontSize="x-small"
isError={true}

View File

@@ -17,6 +17,8 @@ import {
import { Delete, FileUpload } from '@edx/paragon/icons';
import { selectors } from '../../../../../../data/redux';
import { isEdxVideo } from '../../../../../../data/services/cms/api';
import { acceptedImgKeys } from './constants';
import * as hooks from './hooks';
import messages from './messages';
@@ -36,7 +38,7 @@ export const ThumbnailWidget = ({
isLibrary,
allowThumbnailUpload,
thumbnail,
videoType,
videoId,
}) => {
const dispatch = useDispatch();
const [error] = React.useContext(ErrorContext).thumbnail;
@@ -48,10 +50,10 @@ export const ThumbnailWidget = ({
imgRef,
fileSizeError,
});
const edxVideo = isEdxVideo(videoId);
const deleteThumbnail = hooks.deleteThumbnail({ dispatch });
const isEdxVideo = videoType === 'edxVideo';
const getSubtitle = () => {
if (isEdxVideo) {
if (edxVideo) {
if (thumbnail) {
return intl.formatMessage(messages.yesSubtitle);
}
@@ -73,7 +75,7 @@ export const ThumbnailWidget = ({
>
<FormattedMessage {...messages.fileSizeError} />
</ErrorAlert>
{isEdxVideo ? null : (
{edxVideo ? null : (
<Alert variant="light">
<FormattedMessage {...messages.unavailableMessage} />
</Alert>
@@ -88,7 +90,7 @@ export const ThumbnailWidget = ({
src={thumbnailSrc || thumbnail}
alt={intl.formatMessage(messages.thumbnailAltText)}
/>
{ (allowThumbnailUpload && isEdxVideo) ? (
{ (allowThumbnailUpload && edxVideo) ? (
<IconButtonWithTooltip
tooltipPlacement="top"
tooltipContent={intl.formatMessage(messages.deleteThumbnail)}
@@ -113,7 +115,7 @@ export const ThumbnailWidget = ({
iconBefore={FileUpload}
onClick={fileInput.click}
variant="link"
disabled={!isEdxVideo}
disabled={!edxVideo}
>
<FormattedMessage {...messages.uploadButtonLabel} />
</Button>
@@ -130,13 +132,13 @@ ThumbnailWidget.propTypes = {
isLibrary: PropTypes.bool.isRequired,
allowThumbnailUpload: PropTypes.bool.isRequired,
thumbnail: PropTypes.string.isRequired,
videoType: PropTypes.string.isRequired,
videoId: PropTypes.string.isRequired,
};
export const mapStateToProps = (state) => ({
isLibrary: selectors.app.isLibrary(state),
allowThumbnailUpload: selectors.video.allowThumbnailUpload(state),
thumbnail: selectors.video.thumbnail(state),
videoType: selectors.video.videoType(state),
videoId: selectors.video.videoId(state),
});
export const mapDispatchToProps = {};

View File

@@ -19,7 +19,7 @@ jest.mock('../../../../../../data/redux', () => ({
video: {
allowThumbnailUpload: jest.fn(state => ({ allowThumbnailUpload: state })),
thumbnail: jest.fn(state => ({ thumbnail: state })),
videoType: jest.fn(state => ({ videoType: state })),
videoId: jest.fn(state => ({ videoId: state })),
},
app: {
isLibrary: jest.fn(state => ({ isLibrary: state })),
@@ -27,6 +27,10 @@ jest.mock('../../../../../../data/redux', () => ({
},
}));
jest.mock('../../../../../../data/services/cms/api', () => ({
isEdxVideo: (args) => (args),
}));
describe('ThumbnailWidget', () => {
const props = {
error: {},
@@ -35,10 +39,9 @@ describe('ThumbnailWidget', () => {
isLibrary: false,
allowThumbnailUpload: false,
thumbnail: null,
videoType: '',
videoId: '',
updateField: jest.fn().mockName('args.updateField'),
};
describe('snapshots', () => {
test('snapshots: renders as expected with default props', () => {
expect(
@@ -52,7 +55,7 @@ describe('ThumbnailWidget', () => {
});
test('snapshots: renders as expected with a thumbnail provided', () => {
expect(
shallow(<ThumbnailWidget {...props} thumbnail="sOMeUrl" videoType="edxVideo" />),
shallow(<ThumbnailWidget {...props} thumbnail="sOMeUrl" videoId="sOMeViDEoID" />),
).toMatchSnapshot();
});
test('snapshots: renders as expected where thumbnail uploads are allowed', () => {
@@ -60,14 +63,14 @@ describe('ThumbnailWidget', () => {
shallow(<ThumbnailWidget {...props} thumbnail="sOMeUrl" allowThumbnailUpload />),
).toMatchSnapshot();
});
test('snapshots: renders as expected where videoType equals edxVideo', () => {
test('snapshots: renders as expected where videoId is valid', () => {
expect(
shallow(<ThumbnailWidget {...props} thumbnail="sOMeUrl" allowThumbnailUpload videoType="edxVideo" />),
shallow(<ThumbnailWidget {...props} thumbnail="sOMeUrl" allowThumbnailUpload videoId="sOMeViDEoID" />),
).toMatchSnapshot();
});
test('snapshots: renders as expected where videoType equals edxVideo and no thumbnail', () => {
test('snapshots: renders as expected where videoId is valid and no thumbnail', () => {
expect(
shallow(<ThumbnailWidget {...props} allowThumbnailUpload videoType="edxVideo" />),
shallow(<ThumbnailWidget {...props} allowThumbnailUpload videoId="sOMeViDEoID" />),
).toMatchSnapshot();
});
});
@@ -88,10 +91,10 @@ describe('ThumbnailWidget', () => {
mapStateToProps(testState).thumbnail,
).toEqual(selectors.video.thumbnail(testState));
});
test('videoType from video.videoType', () => {
test('videoId from video.videoId', () => {
expect(
mapStateToProps(testState).videoType,
).toEqual(selectors.video.videoType(testState));
mapStateToProps(testState).videoId,
).toEqual(selectors.video.videoId(testState));
});
});
describe('mapDispatchToProps', () => {

View File

@@ -10,14 +10,39 @@ exports[`VideoSourceWidget snapshots snapshots: renders as expected with default
className="border-primary-100 border-bottom pb-4"
>
<Form.Control
floatingLabel="Video ID or URL"
floatingLabel="Video ID"
onBlur={[Function]}
onChange={[MockFunction]}
value=""
/>
<Component
className="text-primary-300 mb-4"
>
<FormattedMessage
defaultMessage="If you were assigned a video ID by edX, enter the ID here."
description="Feedback for video ID field"
id="authoring.videoeditor.videoSource.videoId.feedback"
/>
</Component>
<Form.Control
floatingLabel="Video URL"
onBlur={[Function]}
onChange={[MockFunction]}
value=""
/>
<Component
className="text-primary-300"
>
<FormattedMessage
defaultMessage="The URL for your video. This can be a YouTube URL, or a link
to an .mp4, .ogg, or .webm video file hosted elsewhere on the internet."
description="Feedback for video URL field"
id="authoring.videoeditor.videoSource.videoUrl.feedback"
/>
</Component>
</div>
<div
className="mt-3"
className="mt-4"
>
<FormattedMessage
defaultMessage="Fallback videos"

View File

@@ -2,43 +2,45 @@ import { actions } from '../../../../../../data/redux';
import { isEdxVideo } from '../../../../../../data/services/cms/api';
/**
* updateVideoType({ dispatch })({e, source})
* updateVideoType takes the current onBlur event, the current object of the video
* 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, videoType, and handouts.
* 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 updateVideoType = ({ dispatch }) => ({ e, source }) => {
source.onBlur(e);
let videoType;
let videoId;
if (isEdxVideo(source.local)) {
videoType = 'edxVideo';
videoId = source.local;
} else if (source.local.includes('youtu.be')) {
videoType = 'youtube';
videoId = '';
} else {
videoType = 'html5source';
videoId = '';
export const updateVideoId = ({ dispatch }) => ({ e, source }) => {
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,
}));
}
dispatch(actions.video.updateField({
videoId,
videoType,
allowVideoDownloads: false,
thumbnail: null,
transcripts: [],
allowTranscriptDownloads: false,
showTranscriptByDefault: false,
duration: {
startTime: '00:00:00',
stopTime: '00:00:00',
total: '00:00:00',
},
licenseType: null,
}));
};
/**

View File

@@ -20,10 +20,10 @@ jest.mock('../../../../../../data/redux', () => ({
}));
describe('VideoEditorHandout hooks', () => {
describe('updateVideoType', () => {
describe('updateVideoId', () => {
const sourceEdxVideo = {
onBlur: jest.fn(),
local: '06b1503a-7df4-4e72-b970-326e02dbcbe4',
local: '06b15030-7df0-4e70-b979-326e02dbcbe0',
};
const sourceYouTube = {
onBlur: jest.fn(),
@@ -35,7 +35,7 @@ describe('VideoEditorHandout hooks', () => {
};
const mockState = {
videoId: '',
videoType: '',
videoSource: '',
allowVideoDownloads: false,
thumbnail: null,
transcripts: [],
@@ -49,36 +49,33 @@ describe('VideoEditorHandout hooks', () => {
licenseType: null,
};
it('returns dispatches updateField action with default state and edxVideo Id', () => {
hooks.updateVideoType({ dispatch })({ e: { target: { value: sourceEdxVideo.local } }, source: sourceEdxVideo });
hooks.updateVideoId({ dispatch })({ e: { target: { value: sourceEdxVideo.local } }, source: sourceEdxVideo });
expect(dispatch).toHaveBeenCalledWith(
actions.video.updateField({
...mockState,
videoId: sourceEdxVideo.local,
videoType: 'edxVideo',
}),
);
});
it('returns dispatches updateField action with default state and YouTube video', () => {
hooks.updateVideoType({ dispatch })({
hooks.updateVideoId({ dispatch })({
e: { target: { value: sourceYouTube.local } },
source: sourceYouTube,
});
expect(dispatch).toHaveBeenCalledWith(
actions.video.updateField({
...mockState,
videoId: sourceYouTube.local,
}),
);
});
it('returns dispatches updateField action with default state and html5source video', () => {
hooks.updateVideoType({ dispatch })({
hooks.updateVideoId({ dispatch })({
e: { target: { value: sourceHtml5Source.local } },
source: sourceHtml5Source,
});
expect(dispatch).toHaveBeenCalledWith(
actions.video.updateField({
...mockState,
videoId: sourceHtml5Source.local,
}),
);
});

View File

@@ -10,6 +10,7 @@ import {
Button,
Tooltip,
OverlayTrigger,
FormControlFeedback,
} from '@edx/paragon';
import { Delete, Info, Add } from '@edx/paragon/icons';
import {
@@ -36,6 +37,7 @@ export const VideoSourceWidget = ({
}) => {
const dispatch = useDispatch();
const {
videoId,
videoSource: source,
fallbackVideos,
allowVideoDownloads: allowDownload,
@@ -43,12 +45,13 @@ export const VideoSourceWidget = ({
dispatch,
fields: {
[widgetHooks.selectorKeys.videoSource]: widgetHooks.genericWidget,
[widgetHooks.selectorKeys.videoId]: widgetHooks.genericWidget,
[widgetHooks.selectorKeys.fallbackVideos]: widgetHooks.arrayWidget,
[widgetHooks.selectorKeys.allowVideoDownloads]: widgetHooks.genericWidget,
},
});
const deleteFallbackVideo = module.deleteFallbackVideo({ fallbackVideos: fallbackVideos.formValue, dispatch });
const updateVideoType = module.updateVideoType({ dispatch });
const updateVideoId = module.updateVideoId({ dispatch });
return (
<CollapsibleFormWidget
@@ -58,19 +61,31 @@ export const VideoSourceWidget = ({
<Form.Group>
<div className="border-primary-100 border-bottom pb-4">
<Form.Control
floatingLabel={intl.formatMessage(messages.videoIdOrUrlLabel)}
floatingLabel={intl.formatMessage(messages.videoIdLabel)}
onChange={videoId.onChange}
onBlur={(e) => updateVideoId({ e, source: videoId })}
value={videoId.local}
/>
<FormControlFeedback className="text-primary-300 mb-4">
<FormattedMessage {...messages.videoIdFeedback} />
</FormControlFeedback>
<Form.Control
floatingLabel={intl.formatMessage(messages.videoUrlLabel)}
onChange={source.onChange}
onBlur={(e) => updateVideoType({ e, source })}
onBlur={(e) => updateVideoId({ e, source })}
value={source.local}
/>
<FormControlFeedback className="text-primary-300">
<FormattedMessage {...messages.videoUrlFeedback} />
</FormControlFeedback>
</div>
<div className="mt-3">
<div className="mt-4">
<FormattedMessage {...messages.fallbackVideoTitle} />
</div>
<div>
<FormattedMessage {...messages.fallbackVideoMessage} />
</div>
{fallbackVideos.formValue.map((videoUrl, index) => (
{fallbackVideos.formValue.length > 0 ? fallbackVideos.formValue.map((videoUrl, index) => (
<Form.Row className="mt-4 flex-nowrap">
<Form.Control
floatingLabel={intl.formatMessage(messages.fallbackVideoLabel)}
@@ -88,7 +103,7 @@ export const VideoSourceWidget = ({
onClick={() => deleteFallbackVideo(videoUrl)}
/>
</Form.Row>
))}
)) : null}
<ActionRow className="mt-4">
<Form.Checkbox
checked={allowDownload.local}

View File

@@ -14,6 +14,7 @@ jest.mock('../../../../../../data/redux', () => ({
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 })),
},
@@ -23,6 +24,7 @@ jest.mock('../../../../../../data/redux', () => ({
jest.mock('../hooks', () => ({
selectorKeys: ['soMEkEy'],
widgetValues: jest.fn().mockReturnValue({
videoId: { onChange: jest.fn(), onBlur: jest.fn(), local: '' },
videoSource: { onChange: jest.fn(), onBlur: jest.fn(), local: '' },
fallbackVideos: {
formValue: ['somEUrL'],

View File

@@ -4,16 +4,26 @@ export const messages = {
defaultMessage: 'Video source',
description: 'Title for the video source widget',
},
videoIdOrUrlLabel: {
id: 'authoring.videoeditor.videoSource.videoIdOrUrl.label',
defaultMessage: 'Video ID or URL',
description: 'Label for video ID or URL field',
videoIdLabel: {
id: 'authoring.videoeditor.videoSource.videoId.label',
defaultMessage: 'Video ID',
description: 'Label for video ID field',
},
videoIdOrUrlFeedback: {
id: 'authoring.videoeditor.videoSource.videoIdOrUrl.feedback',
defaultMessage: `Your video ID, YouTube URL, or a link to an .mp4, .ogg, or
.webm video file hosted elsewhere on the Internet`,
description: 'Feedback for video ID or URL field',
videoIdFeedback: {
id: 'authoring.videoeditor.videoSource.videoId.feedback',
defaultMessage: 'If you were assigned a video ID by edX, enter the ID here.',
description: 'Feedback for video ID field',
},
videoUrlLabel: {
id: 'authoring.videoeditor.videoSource.videoUrl.label',
defaultMessage: 'Video URL',
description: 'Label for video URL field',
},
videoUrlFeedback: {
id: 'authoring.videoeditor.videoSource.videoUrl.feedback',
defaultMessage: `The URL for your video. This can be a YouTube URL, or a link
to an .mp4, .ogg, or .webm video file hosted elsewhere on the internet.`,
description: 'Feedback for video URL field',
},
fallbackVideoTitle: {
id: 'authoring.videoeditor.videoSource.fallbackVideo.title',

View File

@@ -30,6 +30,7 @@ export const selectorKeys = keyStore(selectors.video);
export const state = StrictDict(
[
selectorKeys.videoSource,
selectorKeys.videoId,
selectorKeys.fallbackVideos,
selectorKeys.allowVideoDownloads,

View File

@@ -11,7 +11,6 @@ export const loadVideoData = () => (dispatch, getState) => {
const studioView = state.app.studioView?.data?.html;
const {
videoSource,
videoType,
videoId,
fallbackVideos,
} = module.determineVideoSource({
@@ -28,7 +27,6 @@ export const loadVideoData = () => (dispatch, getState) => {
dispatch(actions.video.load({
videoSource,
videoType,
videoId,
fallbackVideos,
allowVideoDownloads: rawVideoData.download_video,
@@ -74,30 +72,21 @@ export const determineVideoSource = ({
const youtubeUrl = `https://youtu.be/${youtubeId}`;
const videoId = edxVideoId || '';
let videoSource = '';
let videoType = '';
let fallbackVideos = [];
if (youtubeId) {
// videoSource = youtubeUrl;
// fallbackVideos = html5Sources;
[videoSource, fallbackVideos] = [youtubeUrl, html5Sources];
videoType = 'youtube';
} else if (edxVideoId) {
// videoSource = edxVideoId;
// fallbackVideos = html5Sources;
[videoSource, fallbackVideos] = [edxVideoId, html5Sources];
videoType = 'edxVideo';
fallbackVideos = html5Sources;
} else if (Array.isArray(html5Sources) && html5Sources[0]) {
// videoSource = html5Sources[0];
// fallbackVideos = html5Sources.slice(1);
[videoSource, fallbackVideos] = [html5Sources[0], html5Sources.slice(1)];
videoType = 'html5source';
}
if (!fallbackVideos || fallbackVideos.length === 0) {
fallbackVideos = ['', ''];
}
return {
videoSource,
videoType,
videoId,
fallbackVideos,
};

View File

@@ -94,7 +94,6 @@ describe('video thunkActions', () => {
videoSource: 'videOsOurce',
videoId: 'videOiD',
fallbackVideos: 'fALLbACKvIDeos',
videoType: 'viDEOtyPE',
});
jest.spyOn(thunkActions, thunkActionsKeys.parseLicense).mockReturnValue([
'liCENSEtyPe',
@@ -123,7 +122,6 @@ describe('video thunkActions', () => {
videoSource: 'videOsOurce',
videoId: 'videOiD',
fallbackVideos: 'fALLbACKvIDeos',
videoType: 'viDEOtyPE',
allowVideoDownloads: testMetadata.download_video,
transcripts: testMetadata.transcripts,
allowTranscriptDownloads: testMetadata.download_track,
@@ -173,7 +171,6 @@ describe('video thunkActions', () => {
})).toEqual({
videoSource: youtubeUrl,
videoId: edxVideoId,
videoType: 'youtube',
fallbackVideos: html5Sources,
});
});
@@ -185,10 +182,9 @@ describe('video thunkActions', () => {
youtubeId: '',
html5Sources: '',
})).toEqual({
videoSource: edxVideoId,
videoSource: '',
videoId: edxVideoId,
videoType: 'edxVideo',
fallbackVideos: ['', ''],
fallbackVideos: '',
});
});
});
@@ -201,7 +197,6 @@ describe('video thunkActions', () => {
})).toEqual({
videoSource: youtubeUrl,
videoId: '',
videoType: 'youtube',
fallbackVideos: html5Sources,
});
});
@@ -215,7 +210,6 @@ describe('video thunkActions', () => {
})).toEqual({
videoSource: 'htmLOne',
videoId: '',
videoType: 'html5source',
fallbackVideos: ['hTMlTwo', 'htMLthrEE'],
});
});
@@ -227,8 +221,7 @@ describe('video thunkActions', () => {
})).toEqual({
videoSource: 'htmlOne',
videoId: '',
fallbackVideos: ['', ''],
videoType: 'html5source',
fallbackVideos: [],
});
});
});
@@ -241,8 +234,7 @@ describe('video thunkActions', () => {
})).toEqual({
videoSource: '',
videoId: '',
fallbackVideos: ['', ''],
videoType: '',
fallbackVideos: [],
});
});
});

View File

@@ -4,7 +4,6 @@ import { StrictDict } from '../../../utils';
const initialState = {
videoSource: '',
videoType: '',
videoId: '',
fallbackVideos: [
'',

View File

@@ -28,7 +28,6 @@ export const simpleSelectors = [
stateKeys.courseLicenseType,
stateKeys.courseLicenseDetails,
stateKeys.allowThumbnailUpload,
stateKeys.videoType,
].reduce((obj, key) => ({ ...obj, [key]: state => state.video[key] }), {});
export const openLanguages = createSelector(

View File

@@ -117,6 +117,7 @@ export const apiMethods = {
edxVideoId,
youtubeId,
} = module.processVideoIds({
videoId: content.videoId,
videoSource: content.videoSource,
fallbackVideos: content.fallbackVideos,
});
@@ -173,14 +174,19 @@ export const loadImages = (rawImages) => camelizeKeys(rawImages).reduce(
{},
);
export const processVideoIds = ({ videoSource, fallbackVideos, edxVideoId }) => {
export const processVideoIds = ({
videoId,
videoSource,
fallbackVideos,
edxVideoId,
}) => {
let newEdxVideoId = edxVideoId;
let youtubeId = '';
const html5Sources = [];
// overwrite videoId if source is changed.
if (module.isEdxVideo(videoSource)) {
newEdxVideoId = videoSource;
if (module.isEdxVideo(videoId)) {
newEdxVideoId = videoId;
} else if (module.parseYoutubeId(videoSource)) {
youtubeId = module.parseYoutubeId(videoSource);
} else if (videoSource) {
@@ -200,7 +206,7 @@ export const processVideoIds = ({ videoSource, fallbackVideos, edxVideoId }) =>
export const isEdxVideo = (src) => {
const uuid4Regex = new RegExp(/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/);
if (src.match(uuid4Regex)) {
if (src && src.match(uuid4Regex)) {
return true;
}
return false;

View File

@@ -321,8 +321,9 @@ describe('cms api', () => {
it('returns edxVideoId when there are no fallbackVideos', () => {
expect(api.processVideoIds({
edxVideoId,
videoSource: edxVideoId,
videoSource: '',
fallbackVideos: [],
videoId: edxVideoId,
})).toEqual({
edxVideoId,
html5Sources: [],
@@ -332,8 +333,9 @@ describe('cms api', () => {
it('returns edxVideoId and html5Sources when there are fallbackVideos', () => {
expect(api.processVideoIds({
edxVideoId,
videoSource: edxVideoId,
videoSource: 'edxVideoId',
fallbackVideos: html5Sources,
videoId: edxVideoId,
})).toEqual({
edxVideoId,
html5Sources,
@@ -351,6 +353,7 @@ describe('cms api', () => {
edxVideoId,
videoSource: edxVideoId,
fallbackVideos: [],
videoId: '',
})).toEqual({
edxVideoId,
html5Sources: [],
@@ -362,6 +365,7 @@ describe('cms api', () => {
edxVideoId,
videoSource: edxVideoId,
fallbackVideos: html5Sources,
videoId: '',
})).toEqual({
edxVideoId,
html5Sources,
@@ -379,6 +383,7 @@ describe('cms api', () => {
edxVideoId,
videoSource: html5Sources[0],
fallbackVideos: [],
videoId: '',
})).toEqual({
edxVideoId,
html5Sources: [html5Sources[0]],
@@ -390,6 +395,7 @@ describe('cms api', () => {
edxVideoId,
videoSource: html5Sources[0],
fallbackVideos: [html5Sources[1]],
videoId: '',
})).toEqual({
edxVideoId,
html5Sources,