From ff636837cf55c8add135cfe07b799919a2c21fdf Mon Sep 17 00:00:00 2001 From: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com> Date: Wed, 14 Sep 2022 11:07:20 -0400 Subject: [PATCH] feat: transcript parent widget component --- .../components/ImageSettingsModal/index.jsx | 2 +- .../__snapshots__/index.test.jsx.snap | 42 +- .../components/SelectImageModal/index.jsx | 15 +- .../SelectImageModal/index.test.jsx | 10 +- .../components/SelectImageModal/messages.js | 5 - .../__snapshots__/index.test.jsx.snap | 407 ++++++++++++++++++ .../components/TranscriptWidget/hooks.js | 29 ++ .../components/TranscriptWidget/index.jsx | 148 +++++++ .../TranscriptWidget/index.test.jsx | 83 ++++ .../components/TranscriptWidget/messages.js | 44 ++ .../components/TranscriptsWidget.jsx | 53 --- .../components/VideoSettingsModal/index.jsx | 4 +- .../ErrorAlerts/ErrorAlert.jsx | 2 +- .../ErrorAlerts/ErrorAlert.test.jsx | 2 +- .../ErrorAlerts/FetchErrorAlert.jsx | 14 +- .../ErrorAlerts/FetchErrorAlert.test.jsx | 6 +- .../ErrorAlerts/UploadErrorAlert.jsx | 13 +- .../ErrorAlerts/UploadErrorAlert.test.jsx | 6 +- .../__snapshots__/ErrorAlert.test.jsx.snap | 0 .../FetchErrorAlert.test.jsx.snap | 6 +- .../UploadErrorAlert.test.jsx.snap | 6 +- .../sharedComponents/ErrorAlerts/messages.js | 9 + .../__snapshots__/index.test.jsx.snap} | 3 +- .../FileInput/index.jsx} | 7 +- .../FileInput/index.test.jsx} | 9 +- 25 files changed, 811 insertions(+), 114 deletions(-) create mode 100644 src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/__snapshots__/index.test.jsx.snap create mode 100644 src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/hooks.js create mode 100644 src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/index.jsx create mode 100644 src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/index.test.jsx create mode 100644 src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/messages.js delete mode 100644 src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptsWidget.jsx rename src/editors/{containers/TextEditor/components => sharedComponents}/ErrorAlerts/ErrorAlert.jsx (96%) rename src/editors/{containers/TextEditor/components => sharedComponents}/ErrorAlerts/ErrorAlert.test.jsx (98%) rename src/editors/{containers/TextEditor/components => sharedComponents}/ErrorAlerts/FetchErrorAlert.jsx (71%) rename src/editors/{containers/TextEditor/components => sharedComponents}/ErrorAlerts/FetchErrorAlert.test.jsx (83%) rename src/editors/{containers/TextEditor/components => sharedComponents}/ErrorAlerts/UploadErrorAlert.jsx (72%) rename src/editors/{containers/TextEditor/components => sharedComponents}/ErrorAlerts/UploadErrorAlert.test.jsx (83%) rename src/editors/{containers/TextEditor/components => sharedComponents}/ErrorAlerts/__snapshots__/ErrorAlert.test.jsx.snap (100%) rename src/editors/{containers/TextEditor/components => sharedComponents}/ErrorAlerts/__snapshots__/FetchErrorAlert.test.jsx.snap (50%) rename src/editors/{containers/TextEditor/components => sharedComponents}/ErrorAlerts/__snapshots__/UploadErrorAlert.test.jsx.snap (50%) create mode 100644 src/editors/sharedComponents/ErrorAlerts/messages.js rename src/editors/{containers/TextEditor/components/SelectImageModal/__snapshots__/FileInput.test.jsx.snap => sharedComponents/FileInput/__snapshots__/index.test.jsx.snap} (87%) rename src/editors/{containers/TextEditor/components/SelectImageModal/FileInput.jsx => sharedComponents/FileInput/index.jsx} (79%) rename src/editors/{containers/TextEditor/components/SelectImageModal/FileInput.test.jsx => sharedComponents/FileInput/index.test.jsx} (80%) diff --git a/src/editors/containers/TextEditor/components/ImageSettingsModal/index.jsx b/src/editors/containers/TextEditor/components/ImageSettingsModal/index.jsx index 559cd127d..00c42e799 100644 --- a/src/editors/containers/TextEditor/components/ImageSettingsModal/index.jsx +++ b/src/editors/containers/TextEditor/components/ImageSettingsModal/index.jsx @@ -11,7 +11,7 @@ import messages from './messages'; import BaseModal from '../BaseModal'; import AltTextControls from './AltTextControls'; import DimensionControls from './DimensionControls'; -import ErrorAlert from '../ErrorAlerts/ErrorAlert'; +import ErrorAlert from '../../../../sharedComponents/ErrorAlerts/ErrorAlert'; /** * Modal display wrapping the dimension and alt-text controls for image tags diff --git a/src/editors/containers/TextEditor/components/SelectImageModal/__snapshots__/index.test.jsx.snap b/src/editors/containers/TextEditor/components/SelectImageModal/__snapshots__/index.test.jsx.snap index 40ffea994..797f148e3 100644 --- a/src/editors/containers/TextEditor/components/SelectImageModal/__snapshots__/index.test.jsx.snap +++ b/src/editors/containers/TextEditor/components/SelectImageModal/__snapshots__/index.test.jsx.snap @@ -30,8 +30,24 @@ exports[`SelectImageModal component snapshot 1`] = ` isOpen={true} title="Add an image" > - - + + - - + + {/* Error Alerts */} - - + + )} - + ); diff --git a/src/editors/containers/TextEditor/components/SelectImageModal/index.test.jsx b/src/editors/containers/TextEditor/components/SelectImageModal/index.test.jsx index 807189495..1780fc255 100644 --- a/src/editors/containers/TextEditor/components/SelectImageModal/index.test.jsx +++ b/src/editors/containers/TextEditor/components/SelectImageModal/index.test.jsx @@ -5,19 +5,19 @@ import { formatMessage } from '../../../../../testUtils'; import { RequestKeys } from '../../../../data/constants/requests'; import { selectors } from '../../../../data/redux'; import BaseModal from '../BaseModal'; -import FileInput from './FileInput'; +import FileInput from '../../../../sharedComponents/FileInput'; import Gallery from './Gallery'; import SearchSort from './SearchSort'; import hooks from './hooks'; import { SelectImageModal, mapStateToProps, mapDispatchToProps } from '.'; jest.mock('../BaseModal', () => 'BaseModal'); -jest.mock('./FileInput', () => 'FileInput'); +jest.mock('../../../../sharedComponents/FileInput', () => 'FileInput'); jest.mock('./Gallery', () => 'Gallery'); jest.mock('./SearchSort', () => 'SearchSort'); -jest.mock('../ErrorAlerts/FetchErrorAlert', () => 'FetchErrorAlert'); -jest.mock('../ErrorAlerts/UploadErrorAlert', () => 'UploadErrorAlert'); -jest.mock('../ErrorAlerts/ErrorAlert', () => 'ErrorAlert'); +jest.mock('../../../../sharedComponents/ErrorAlerts/FetchErrorAlert', () => 'FetchErrorAlert'); +jest.mock('../../../../sharedComponents/ErrorAlerts/UploadErrorAlert', () => 'UploadErrorAlert'); +jest.mock('../../../../sharedComponents/ErrorAlerts/ErrorAlert', () => 'ErrorAlert'); jest.mock('./hooks', () => ({ imgHooks: jest.fn(() => ({ diff --git a/src/editors/containers/TextEditor/components/SelectImageModal/messages.js b/src/editors/containers/TextEditor/components/SelectImageModal/messages.js index 88532fe96..d2fa7c311 100644 --- a/src/editors/containers/TextEditor/components/SelectImageModal/messages.js +++ b/src/editors/containers/TextEditor/components/SelectImageModal/messages.js @@ -66,11 +66,6 @@ export const messages = { }, // Errors - errorTitle: { - id: 'authoring.texteditor.selectimagemodal.error.errorTitle', - defaultMessage: 'Error', - description: 'Title of message presented to user when something goes wrong', - }, uploadImageError: { id: 'authoring.texteditor.selectimagemodal.error.uploadImageError', defaultMessage: 'Failed to upload image. Please try again.', diff --git a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/__snapshots__/index.test.jsx.snap b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/__snapshots__/index.test.jsx.snap new file mode 100644 index 000000000..83fe094dd --- /dev/null +++ b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/__snapshots__/index.test.jsx.snap @@ -0,0 +1,407 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`TranscriptWidget snapshots snapshots: renders as expected with allowTranscriptDownloads true 1`] = ` + + + + + + + + + + + Transcript widget: + +
+ + + + + + + + + } + placement="right" + > + + +
+ + + + + +
+ + +
+
+`; + +exports[`TranscriptWidget snapshots snapshots: renders as expected with default props 1`] = ` + + + + + + + + + + Only SRT files can be uploaded. Please select a file ending in .srt to upload. + + + + + + +`; + +exports[`TranscriptWidget snapshots snapshots: renders as expected with showTranscriptByDefault true 1`] = ` + + + + + + + + + + + Transcript widget: + +
+ + + + + + + + + } + placement="right" + > + + +
+ + + + + +
+ + +
+
+`; + +exports[`TranscriptWidget snapshots snapshots: renders as expected with transcripts 1`] = ` + + + + + + + + + + + Transcript widget: + +
+ + + + + + + + + } + placement="right" + > + + +
+ + + + + +
+ + +
+
+`; diff --git a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/hooks.js b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/hooks.js new file mode 100644 index 000000000..b15ca7d69 --- /dev/null +++ b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/hooks.js @@ -0,0 +1,29 @@ +import React from 'react'; + +export const transcriptLanguages = (transcripts) => { + const languages = []; + if (transcripts) { + Object.keys(transcripts).forEach(transcript => { + languages.push(transcript); + }); + return languages.join(', '); + } + return 'None'; +}; + +export const fileInput = () => { + const ref = React.useRef(); + const click = () => ref.current.click(); + const addFile = (e) => { + const selectedFile = e.target.files[0]; + console.log(selectedFile); + }; + + return { + click, + addFile, + ref, + }; +}; + +export default { transcriptLanguages, fileInput }; diff --git a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/index.jsx b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/index.jsx new file mode 100644 index 000000000..3e2775440 --- /dev/null +++ b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/index.jsx @@ -0,0 +1,148 @@ +import React from 'react'; +import { connect } from 'react-redux'; +import PropTypes from 'prop-types'; + +import { + Form, + Button, + Stack, + Icon, + OverlayTrigger, + Tooltip, + Alert, +} from '@edx/paragon'; +import { FileUpload, Info } from '@edx/paragon/icons'; +import { + FormattedMessage, + injectIntl, +} from '@edx/frontend-platform/i18n'; + +import { actions, selectors } from '../../../../../../data/redux'; +import * as hooks from './hooks'; +import messages from './messages'; + +import FileInput from '../../../../../../sharedComponents/FileInput'; +import ErrorAlert from '../../../../../../sharedComponents/ErrorAlerts/ErrorAlert'; +import CollapsibleFormWidget from '../CollapsibleFormWidget'; + +/** + * Collapsible Form widget controlling video transcripts + */ +export const TranscriptWidget = ({ + error, + // redux + transcripts, + allowTranscriptDownloads, + showTranscriptByDefault, + updateField, +}) => { + const languagesArr = hooks.transcriptLanguages(transcripts); + const fileInput = hooks.fileInput(); + const input = { + error: { + dismiss: () => { console.log('dismiss'); }, + show: true, + }, + }; + const upload = { + error: { + dismiss: () => { console.log('dismiss'); }, + show: true, + }, + }; + + return ( + + + + + + + + + {transcripts ? ( + + Transcript widget: +
+ updateField({ allowTranscriptDownloads: e.target.checked })} + > + + + + + + + + )} + > + + +
+ updateField({ showTranscriptByDefault: e.target.checked })} + > + + + + +
+ ) : ( + <> + + Only SRT files can be uploaded. Please select a file ending in .srt to upload. + + + + )} + + +
+
+ ); +}; + +TranscriptWidget.defaultProps = { + error: {}, +}; +TranscriptWidget.propTypes = { + error: PropTypes.node, + // redux + transcripts: PropTypes.shape({}).isRequired, + allowTranscriptDownloads: PropTypes.bool.isRequired, + showTranscriptByDefault: PropTypes.bool.isRequired, + updateField: PropTypes.func.isRequired, +}; +export const mapStateToProps = (state) => ({ + transcripts: selectors.video.transcripts(state), + allowTranscriptDownloads: selectors.video.allowTranscriptDownloads(state), + showTranscriptByDefault: selectors.video.showTranscriptByDefault(state), +}); + +export const mapDispatchToProps = (dispatch) => ({ + updateField: (stateUpdate) => dispatch(actions.video.updateField(stateUpdate)), +}); + +export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(TranscriptWidget)); diff --git a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/index.test.jsx b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/index.test.jsx new file mode 100644 index 000000000..227b4fae5 --- /dev/null +++ b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/index.test.jsx @@ -0,0 +1,83 @@ +import React from 'react'; +import { shallow } from 'enzyme'; + +import { formatMessage } from '../../../../../../../testUtils'; +import { actions, selectors } from '../../../../../../data/redux'; +import { TranscriptWidget, mapStateToProps, mapDispatchToProps } from '.'; + +jest.mock('../../../../../../data/redux', () => ({ + actions: { + video: { + updateField: jest.fn().mockName('actions.video.updateField'), + }, + }, + selectors: { + video: { + transcripts: jest.fn(state => ({ transcripts: state })), + allowTranscriptDownloads: jest.fn(state => ({ allowTranscriptDownloads: state })), + showTranscriptByDefault: jest.fn(state => ({ showTranscriptByDefault: state })), + }, + }, +})); + +describe('TranscriptWidget', () => { + const props = { + error: {}, + subtitle: 'SuBTItle', + title: 'tiTLE', + // inject + intl: { formatMessage }, + // redux + transcripts: null, + allowTranscriptDownloads: false, + showTranscriptByDefault: false, + updateField: jest.fn().mockName('args.updateField'), + }; + + describe('snapshots', () => { + test('snapshots: renders as expected with default props', () => { + expect( + shallow(), + ).toMatchSnapshot(); + }); + test('snapshots: renders as expected with transcripts', () => { + expect( + shallow(), + ).toMatchSnapshot(); + }); + test('snapshots: renders as expected with allowTranscriptDownloads true', () => { + expect( + shallow(), + ).toMatchSnapshot(); + }); + test('snapshots: renders as expected with showTranscriptByDefault true', () => { + expect( + shallow(), + ).toMatchSnapshot(); + }); + }); + describe('mapStateToProps', () => { + const testState = { A: 'pple', B: 'anana', C: 'ucumber' }; + test('transcripts from video.transcript', () => { + expect( + mapStateToProps(testState).transcripts, + ).toEqual(selectors.video.transcripts(testState)); + }); + test('allowTranscriptDownloads from video.allowTranscriptDownloads', () => { + expect( + mapStateToProps(testState).allowTranscriptDownloads, + ).toEqual(selectors.video.allowTranscriptDownloads(testState)); + }); + test('showTranscriptByDefault from video.showTranscriptByDefault', () => { + expect( + mapStateToProps(testState).showTranscriptByDefault, + ).toEqual(selectors.video.showTranscriptByDefault(testState)); + }); + }); + describe('mapDispatchToProps', () => { + const dispatch = jest.fn(); + test('updateField from actions.video.updateField', () => { + expect(mapDispatchToProps.updateField).toEqual(dispatch(actions.video.updateField)); + }); + }); +}); diff --git a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/messages.js b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/messages.js new file mode 100644 index 000000000..a7fd486d3 --- /dev/null +++ b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/messages.js @@ -0,0 +1,44 @@ +export const messages = { + uploadButtonLabel: { + id: 'authoring.videoeditor.transcripts.upload.label', + defaultMessage: 'Upload Transcript', + description: 'Label for upload button', + }, + addFirstTranscript: { + id: 'authoring.videoeditor.transcripts.upload.firstTranscriptMessage', + defaultMessage: 'Add video transcripts for improved accessibility.', + description: 'Message for adding first transcript', + }, + allowDownloadCheckboxLabel: { + id: 'authoring.videoeditor.transcripts.allowDownloadCheckboxLabel', + defaultMessage: 'Allow transcript downloads', + description: 'Label for allow transcript downloads checkbox', + }, + showByDefaultCheckboxLabel: { + id: 'authoring.videoeditor.transcripts.upload.showByDefaultCheckboxLabel', + defaultMessage: 'Show transcript in the video player by default', + description: 'Label for show by default checkbox', + }, + tooltipMessage: { + id: 'authoring.videoeditor.transcripts.upload.allowDownloadTooltipMessage', + defaultMessage: 'Learners will see a link to download the transcript below the video.', + description: 'Message for show by default checkbox', + }, + transcriptTypeError: { + id: 'authoring.videoeditor.transcript.error.transcriptTypeError', + defaultMessage: 'Only SRT file can be uploaded', + description: 'Message presented to user when image fails to upload', + }, + uploadTranscriptError: { + id: 'authoring.videoeditor.transcript.error.uploadTranscriptError', + defaultMessage: 'Failed to upload transcript. Please try again.', + description: 'Message presented to user when transcript fails to upload', + }, + fileSizeError: { + id: 'authoring.videoeditor.transcript.error.fileSizeError', + defaultMessage: 'Transcript file size exeeds the maximum. Please try again.', + description: 'Message presented to user when transcript file size is too large', + }, +}; + +export default messages; diff --git a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptsWidget.jsx b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptsWidget.jsx deleted file mode 100644 index c893335c4..000000000 --- a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptsWidget.jsx +++ /dev/null @@ -1,53 +0,0 @@ -import React from 'react'; -import { useDispatch } from 'react-redux'; -import PropTypes from 'prop-types'; - -import hooks from './hooks'; -import CollapsibleFormWidget from './CollapsibleFormWidget'; - -/** - * Collapsible Form widget controlling video transcripts - */ -export const TranscriptWidget = ({ - error, -}) => { - const dispatch = useDispatch(); - const values = hooks.widgetValues({ - dispatch, - fields: { - [hooks.selectorKeys.transcripts]: hooks.objectWidget, - [hooks.selectorKeys.allowTranscriptDownloads]: hooks.genericWidget, - [hooks.selectorKeys.showTranscriptByDefault]: hooks.genericWidget, - }, - }); - const { - transcripts, - allowTranscriptDownloads: allowDownload, - showTranscriptByDefault: showByDefault, - } = values; - - // TODO: replace the following sample subtitle input with one managed by hook logic - const sampleSubtitle =
{transcripts.formValue.english}
; - - return ( - - Transcripts -

English: {transcripts.formValue.english}

-

Allow downloads: {allowDownload.formValue ? 'True' : 'False' }

-

Show by default: {showByDefault.formValue ? 'True' : 'False' }

-
- ); -}; - -TranscriptWidget.defaultProps = { - error: {}, -}; -TranscriptWidget.propTypes = { - error: PropTypes.node, -}; - -export default TranscriptWidget; diff --git a/src/editors/containers/VideoEditor/components/VideoSettingsModal/index.jsx b/src/editors/containers/VideoEditor/components/VideoSettingsModal/index.jsx index 70c3db680..9ca375366 100644 --- a/src/editors/containers/VideoEditor/components/VideoSettingsModal/index.jsx +++ b/src/editors/containers/VideoEditor/components/VideoSettingsModal/index.jsx @@ -8,7 +8,7 @@ import DurationWidget from './components/DurationWidget'; import HandoutWidget from './components/HandoutWidget'; import LicenseWidget from './components/LicenseWidget'; import ThumbnailWidget from './components/ThumbnailWidget'; -import TranscriptsWidget from './components/TranscriptsWidget'; +import TranscriptWidget from './components/TranscriptWidget'; import VideoSourceWidget from './components/VideoSourceWidget'; import './index.scss'; @@ -33,7 +33,7 @@ export const VideoSettingsModal = ({

Settings

- + diff --git a/src/editors/containers/TextEditor/components/ErrorAlerts/ErrorAlert.jsx b/src/editors/sharedComponents/ErrorAlerts/ErrorAlert.jsx similarity index 96% rename from src/editors/containers/TextEditor/components/ErrorAlerts/ErrorAlert.jsx rename to src/editors/sharedComponents/ErrorAlerts/ErrorAlert.jsx index 9b9dfc40d..00ffd9245 100644 --- a/src/editors/containers/TextEditor/components/ErrorAlerts/ErrorAlert.jsx +++ b/src/editors/sharedComponents/ErrorAlerts/ErrorAlert.jsx @@ -5,7 +5,7 @@ import { Alert } from '@edx/paragon'; import { Info } from '@edx/paragon/icons'; import { FormattedMessage } from '@edx/frontend-platform/i18n'; -import messages from '../SelectImageModal/messages'; +import messages from './messages'; export const hooks = { state: { diff --git a/src/editors/containers/TextEditor/components/ErrorAlerts/ErrorAlert.test.jsx b/src/editors/sharedComponents/ErrorAlerts/ErrorAlert.test.jsx similarity index 98% rename from src/editors/containers/TextEditor/components/ErrorAlerts/ErrorAlert.test.jsx rename to src/editors/sharedComponents/ErrorAlerts/ErrorAlert.test.jsx index abeb6a5d3..f06941ba9 100644 --- a/src/editors/containers/TextEditor/components/ErrorAlerts/ErrorAlert.test.jsx +++ b/src/editors/sharedComponents/ErrorAlerts/ErrorAlert.test.jsx @@ -1,7 +1,7 @@ import React from 'react'; import { shallow } from 'enzyme'; import * as module from './ErrorAlert'; -import { MockUseState } from '../../../../../testUtils'; +import { MockUseState } from '../../../testUtils'; const { ErrorAlert } = module; diff --git a/src/editors/containers/TextEditor/components/ErrorAlerts/FetchErrorAlert.jsx b/src/editors/sharedComponents/ErrorAlerts/FetchErrorAlert.jsx similarity index 71% rename from src/editors/containers/TextEditor/components/ErrorAlerts/FetchErrorAlert.jsx rename to src/editors/sharedComponents/ErrorAlerts/FetchErrorAlert.jsx index 5c9754057..df9542c24 100644 --- a/src/editors/containers/TextEditor/components/ErrorAlerts/FetchErrorAlert.jsx +++ b/src/editors/sharedComponents/ErrorAlerts/FetchErrorAlert.jsx @@ -3,12 +3,12 @@ import { connect } from 'react-redux'; import PropTypes from 'prop-types'; import { FormattedMessage } from '@edx/frontend-platform/i18n'; -import messages from '../SelectImageModal/messages'; import ErrorAlert from './ErrorAlert'; -import { selectors } from '../../../../data/redux'; -import { RequestKeys } from '../../../../data/constants/requests'; +import { selectors } from '../../data/redux'; +import { RequestKeys } from '../../data/constants/requests'; export const FetchErrorAlert = ({ + message, // redux isFetchError, // inject @@ -17,14 +17,20 @@ export const FetchErrorAlert = ({ isError={isFetchError} >
); FetchErrorAlert.propTypes = { + message: PropTypes.shape({ + id: PropTypes.string, + defaultMessage: PropTypes.string, + description: PropTypes.string, + }).isRequired, // redux isFetchError: PropTypes.bool.isRequired, + }; export const mapStateToProps = (state) => ({ isFetchError: selectors.requests.isFailed(state, { requestKey: RequestKeys.fetchImages }), diff --git a/src/editors/containers/TextEditor/components/ErrorAlerts/FetchErrorAlert.test.jsx b/src/editors/sharedComponents/ErrorAlerts/FetchErrorAlert.test.jsx similarity index 83% rename from src/editors/containers/TextEditor/components/ErrorAlerts/FetchErrorAlert.test.jsx rename to src/editors/sharedComponents/ErrorAlerts/FetchErrorAlert.test.jsx index ee652aef6..ccb3c16ac 100644 --- a/src/editors/containers/TextEditor/components/ErrorAlerts/FetchErrorAlert.test.jsx +++ b/src/editors/sharedComponents/ErrorAlerts/FetchErrorAlert.test.jsx @@ -1,10 +1,10 @@ import React from 'react'; import { shallow } from 'enzyme'; import { FetchErrorAlert, mapStateToProps } from './FetchErrorAlert'; -import { selectors } from '../../../../data/redux'; -import { RequestKeys } from '../../../../data/constants/requests'; +import { selectors } from '../../data/redux'; +import { RequestKeys } from '../../data/constants/requests'; -jest.mock('../../../../data/redux', () => ({ +jest.mock('../../data/redux', () => ({ selectors: { requests: { isFailed: jest.fn((state, params) => ({ isFailed: { state, params } })), diff --git a/src/editors/containers/TextEditor/components/ErrorAlerts/UploadErrorAlert.jsx b/src/editors/sharedComponents/ErrorAlerts/UploadErrorAlert.jsx similarity index 72% rename from src/editors/containers/TextEditor/components/ErrorAlerts/UploadErrorAlert.jsx rename to src/editors/sharedComponents/ErrorAlerts/UploadErrorAlert.jsx index 4e7d690f1..fd2552f17 100644 --- a/src/editors/containers/TextEditor/components/ErrorAlerts/UploadErrorAlert.jsx +++ b/src/editors/sharedComponents/ErrorAlerts/UploadErrorAlert.jsx @@ -3,12 +3,12 @@ import { connect } from 'react-redux'; import PropTypes from 'prop-types'; import { FormattedMessage } from '@edx/frontend-platform/i18n'; -import messages from '../SelectImageModal/messages'; import ErrorAlert from './ErrorAlert'; -import { selectors } from '../../../../data/redux'; -import { RequestKeys } from '../../../../data/constants/requests'; +import { selectors } from '../../data/redux'; +import { RequestKeys } from '../../data/constants/requests'; export const UploadErrorAlert = ({ + message, // redux isUploadError, // inject @@ -17,12 +17,17 @@ export const UploadErrorAlert = ({ isError={isUploadError} >
); UploadErrorAlert.propTypes = { + message: PropTypes.shape({ + id: PropTypes.string, + defaultMessage: PropTypes.string, + description: PropTypes.string, + }).isRequired, // redux isUploadError: PropTypes.bool.isRequired, }; diff --git a/src/editors/containers/TextEditor/components/ErrorAlerts/UploadErrorAlert.test.jsx b/src/editors/sharedComponents/ErrorAlerts/UploadErrorAlert.test.jsx similarity index 83% rename from src/editors/containers/TextEditor/components/ErrorAlerts/UploadErrorAlert.test.jsx rename to src/editors/sharedComponents/ErrorAlerts/UploadErrorAlert.test.jsx index ac20accd6..1ddf44b28 100644 --- a/src/editors/containers/TextEditor/components/ErrorAlerts/UploadErrorAlert.test.jsx +++ b/src/editors/sharedComponents/ErrorAlerts/UploadErrorAlert.test.jsx @@ -1,10 +1,10 @@ import React from 'react'; import { shallow } from 'enzyme'; import { UploadErrorAlert, mapStateToProps } from './UploadErrorAlert'; -import { selectors } from '../../../../data/redux'; -import { RequestKeys } from '../../../../data/constants/requests'; +import { selectors } from '../../data/redux'; +import { RequestKeys } from '../../data/constants/requests'; -jest.mock('../../../../data/redux', () => ({ +jest.mock('../../data/redux', () => ({ selectors: { requests: { isFailed: jest.fn((state, params) => ({ isFailed: { state, params } })), diff --git a/src/editors/containers/TextEditor/components/ErrorAlerts/__snapshots__/ErrorAlert.test.jsx.snap b/src/editors/sharedComponents/ErrorAlerts/__snapshots__/ErrorAlert.test.jsx.snap similarity index 100% rename from src/editors/containers/TextEditor/components/ErrorAlerts/__snapshots__/ErrorAlert.test.jsx.snap rename to src/editors/sharedComponents/ErrorAlerts/__snapshots__/ErrorAlert.test.jsx.snap diff --git a/src/editors/containers/TextEditor/components/ErrorAlerts/__snapshots__/FetchErrorAlert.test.jsx.snap b/src/editors/sharedComponents/ErrorAlerts/__snapshots__/FetchErrorAlert.test.jsx.snap similarity index 50% rename from src/editors/containers/TextEditor/components/ErrorAlerts/__snapshots__/FetchErrorAlert.test.jsx.snap rename to src/editors/sharedComponents/ErrorAlerts/__snapshots__/FetchErrorAlert.test.jsx.snap index 7874b5a9f..bc4615752 100644 --- a/src/editors/containers/TextEditor/components/ErrorAlerts/__snapshots__/FetchErrorAlert.test.jsx.snap +++ b/src/editors/sharedComponents/ErrorAlerts/__snapshots__/FetchErrorAlert.test.jsx.snap @@ -6,10 +6,6 @@ exports[`FetchErrorAlert Snapshots snapshot: is ErrorAlert with Message error ( hideHeading={false} isError={true} > - +
`; diff --git a/src/editors/containers/TextEditor/components/ErrorAlerts/__snapshots__/UploadErrorAlert.test.jsx.snap b/src/editors/sharedComponents/ErrorAlerts/__snapshots__/UploadErrorAlert.test.jsx.snap similarity index 50% rename from src/editors/containers/TextEditor/components/ErrorAlerts/__snapshots__/UploadErrorAlert.test.jsx.snap rename to src/editors/sharedComponents/ErrorAlerts/__snapshots__/UploadErrorAlert.test.jsx.snap index f50cb4443..68f5d8b3d 100644 --- a/src/editors/containers/TextEditor/components/ErrorAlerts/__snapshots__/UploadErrorAlert.test.jsx.snap +++ b/src/editors/sharedComponents/ErrorAlerts/__snapshots__/UploadErrorAlert.test.jsx.snap @@ -6,10 +6,6 @@ exports[`UploadErrorAlert Snapshots snapshot: is ErrorAlert with Message error hideHeading={false} isError={true} > - + `; diff --git a/src/editors/sharedComponents/ErrorAlerts/messages.js b/src/editors/sharedComponents/ErrorAlerts/messages.js new file mode 100644 index 000000000..0f8b80fc9 --- /dev/null +++ b/src/editors/sharedComponents/ErrorAlerts/messages.js @@ -0,0 +1,9 @@ +export const messages = { + errorTitle: { + id: 'authoring.texteditor.selectimagemodal.error.errorTitle', + defaultMessage: 'Error', + description: 'Title of message presented to user when something goes wrong', + }, +}; + +export default messages; diff --git a/src/editors/containers/TextEditor/components/SelectImageModal/__snapshots__/FileInput.test.jsx.snap b/src/editors/sharedComponents/FileInput/__snapshots__/index.test.jsx.snap similarity index 87% rename from src/editors/containers/TextEditor/components/SelectImageModal/__snapshots__/FileInput.test.jsx.snap rename to src/editors/sharedComponents/FileInput/__snapshots__/index.test.jsx.snap index 45d41a313..4c4fd68dc 100644 --- a/src/editors/containers/TextEditor/components/SelectImageModal/__snapshots__/FileInput.test.jsx.snap +++ b/src/editors/sharedComponents/FileInput/__snapshots__/index.test.jsx.snap @@ -2,6 +2,7 @@ exports[`FileInput component snapshot 1`] = ` ( +export const FileInput = ({ fileInput, acceptedFiles }) => ( ( ); FileInput.propTypes = { + acceptedFiles: PropTypes.string.isRequired, fileInput: PropTypes.shape({ addFile: PropTypes.func, ref: PropTypes.oneOfType([ diff --git a/src/editors/containers/TextEditor/components/SelectImageModal/FileInput.test.jsx b/src/editors/sharedComponents/FileInput/index.test.jsx similarity index 80% rename from src/editors/containers/TextEditor/components/SelectImageModal/FileInput.test.jsx rename to src/editors/sharedComponents/FileInput/index.test.jsx index 721e18d2c..45a043b41 100644 --- a/src/editors/containers/TextEditor/components/SelectImageModal/FileInput.test.jsx +++ b/src/editors/sharedComponents/FileInput/index.test.jsx @@ -1,9 +1,7 @@ import React from 'react'; import { mount } from 'enzyme'; -import { acceptedImgKeys } from './utils'; - -import { FileInput } from './FileInput'; +import { FileInput } from '.'; describe('FileInput component', () => { let el; @@ -12,6 +10,7 @@ describe('FileInput component', () => { beforeEach(() => { container = {}; props = { + acceptedFiles: '.srt', fileInput: { addFile: jest.fn().mockName('props.fileInput.addFile'), ref: (input) => { container.ref = input; }, @@ -23,9 +22,7 @@ describe('FileInput component', () => { expect(el).toMatchSnapshot(); }); test('only accepts allowed file types', () => { - expect(el.find('input').props().accept).toEqual( - Object.values(acceptedImgKeys).join(), - ); + expect(el.find('input').props().accept).toEqual('.srt'); }); test('calls fileInput.addFile onChange', () => { expect(el.find('input').props().onChange).toEqual(props.fileInput.addFile);