Skip to content

Commit

Permalink
chore: update endpoint used to confirm filename conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
mavidser committed Oct 24, 2023
1 parent 5676ac3 commit d3df36b
Show file tree
Hide file tree
Showing 13 changed files with 104 additions and 110 deletions.
10 changes: 5 additions & 5 deletions src/components/AssetsDropZone/AssetsDropZone.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { courseDetails } from '../../utils/testConstants';
import { mountWithIntl } from '../../utils/i18n/enzymeHelper';

const defaultProps = {
preUploadCheck: () => {},
validateAssetsAndUpload: () => {},
uploadAssets: () => {},
uploadExceedMaxCount: () => {},
uploadExceedMaxSize: () => {},
Expand Down Expand Up @@ -71,13 +71,13 @@ describe('<AssetsDropZone />', () => {
wrapper.instance().onDrop([{}, {}], [{}]);
expect(mockUploadInvalidFileType).toBeCalled();
});
it('call preUploadCheck() for approved files', () => {
const mockPreUploadCheck = jest.fn();
it('call validateAssetsAndUpload() for approved files', () => {
const mockvalidateAssetsAndUpload = jest.fn();
wrapper.setProps({
preUploadCheck: mockPreUploadCheck,
validateAssetsAndUpload: mockvalidateAssetsAndUpload,
});
wrapper.instance().onDrop([{}, {}], []);
expect(mockPreUploadCheck).toBeCalled();
expect(mockvalidateAssetsAndUpload).toBeCalled();
});
});

Expand Down
4 changes: 2 additions & 2 deletions src/components/AssetsDropZone/container.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import { connect } from 'react-redux';

import AssetsDropZone from '.';
import {
preUploadCheck, uploadAssets, uploadExceedMaxSize, uploadExceedMaxCount, uploadInvalidFileType,
validateAssetsAndUpload, uploadAssets, uploadExceedMaxSize, uploadExceedMaxCount, uploadInvalidFileType,
} from '../../data/actions/assets';

const mapStateToProps = state => ({
courseDetails: state.studioDetails.course,
});

const mapDispatchToProps = dispatch => ({
preUploadCheck: (files, courseDetails) => dispatch(preUploadCheck(files, courseDetails)),
validateAssetsAndUpload: (files, courseDetails) => dispatch(validateAssetsAndUpload(files, courseDetails)),
uploadAssets: (files, courseDetails) => dispatch(uploadAssets(files, courseDetails)),
uploadExceedMaxCount: maxFileCount => dispatch(uploadExceedMaxCount(maxFileCount)),
uploadExceedMaxSize: maxFileSizeMB => dispatch(uploadExceedMaxSize(maxFileSizeMB)),
Expand Down
7 changes: 4 additions & 3 deletions src/components/AssetsDropZone/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import PropTypes from 'prop-types';
import { Button } from '@edx/paragon';
import FontAwesomeStyles from 'font-awesome/css/font-awesome.min.css';
import WrappedMessage from '../../utils/i18n/formattedMessageWrapper';
import MAX_FILE_UPLOAD_COUNT from '../../utils/constants';
import messages from './displayMessages';
import styles from './AssetsDropZone.scss';

Expand All @@ -28,7 +29,7 @@ export default class AssetsDropZone extends React.Component {
this.props.uploadInvalidFileType();
}
} else {
this.props.preUploadCheck(acceptedFiles, this.props.courseDetails);
this.props.validateAssetsAndUpload(acceptedFiles, this.props.courseDetails);
}
};

Expand Down Expand Up @@ -136,13 +137,13 @@ AssetsDropZone.propTypes = {
uploadExceedMaxCount: PropTypes.func.isRequired,
uploadExceedMaxSize: PropTypes.func.isRequired,
uploadInvalidFileType: PropTypes.func.isRequired,
preUploadCheck: PropTypes.func.isRequired,
validateAssetsAndUpload: PropTypes.func.isRequired,
};

AssetsDropZone.defaultProps = {
acceptedFileTypes: undefined,
buttonRef: () => {},
compactStyle: false,
maxFileCount: 1000,
maxFileCount: MAX_FILE_UPLOAD_COUNT,
maxFileSizeMB: 10,
};
26 changes: 13 additions & 13 deletions src/components/AssetsUploadConfirm/AssetsUploadConfirm.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,29 @@ import { mountWithIntl } from '../../utils/i18n/enzymeHelper';
import mockQuerySelector from '../../utils/mockQuerySelector';

const defaultProps = {
files: [],
filesToUpload: [],
uploadAssets: () => { },
clearPreUploadProps: () => {},
clearUploadConfirmProps: () => {},
courseDetails: {},
preUploadError: [],
filenameConflicts: [],
};

const modalIsClosed = (wrapper) => {
expect(wrapper.prop('preUploadError')).toEqual([]);
expect(wrapper.prop('filenameConflicts')).toEqual([]);
expect(wrapper.state('modalOpen')).toEqual(false);
expect(wrapper.find(Modal).prop('open')).toEqual(false);
};

const modalIsOpen = (wrapper) => {
expect(wrapper.prop('preUploadError')).toBeTruthy();
expect(wrapper.prop('filenameConflicts')).toBeTruthy();
expect(wrapper.state('modalOpen')).toEqual(true);
expect(wrapper.find(Modal).prop('open')).toEqual(true);
};

const errorMessageHasCorrectFiles = (wrapper, files) => {
const preUploadError = wrapper.prop('preUploadError');
const filenameConflicts = wrapper.prop('filenameConflicts');
files.forEach((file) => {
expect(preUploadError).toContain(file);
expect(filenameConflicts).toContain(file);
});
};

Expand Down Expand Up @@ -57,7 +57,7 @@ describe('AssetsUploadConfirm', () => {

it('open if there is an error message', () => {
wrapper.setProps({
preUploadError: ['asset.jpg'],
filenameConflicts: ['asset.jpg'],
});

modalIsOpen(wrapper);
Expand All @@ -67,24 +67,24 @@ describe('AssetsUploadConfirm', () => {
describe('behaves', () => {
it('Overwrite calls uploadAssets', () => {
const mockUploadAssets = jest.fn();
const files = [new File([''], 'file1')];
const filesToUpload = [new File([''], 'file1')];
const courseDetails = {
id: 'course-v1:edX+DemoX+Demo_Course',
};
wrapper.setProps({
files,
filesToUpload,
courseDetails,
uploadAssets: mockUploadAssets,
});

wrapper.find(Button).filterWhere(button => button.text() === 'Overwrite').simulate('click');
expect(mockUploadAssets).toBeCalledWith(files, courseDetails);
expect(mockUploadAssets).toBeCalledWith(filesToUpload, courseDetails);
});

it('clicking cancel button closes the status alert', () => {
wrapper.setProps({
preUploadError: ['asset.jpg'],
clearPreUploadProps: () => {
filenameConflicts: ['asset.jpg'],
clearUploadConfirmProps: () => {
wrapper.setProps({
...defaultProps,
});
Expand Down
6 changes: 3 additions & 3 deletions src/components/AssetsUploadConfirm/container.jsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { connect } from 'react-redux';

import { uploadAssets, clearPreUploadProps } from '../../data/actions/assets';
import { uploadAssets, clearUploadConfirmProps } from '../../data/actions/assets';
import AssetsUploadConfirm from '.';

const mapStateToProps = state => ({
files: state.metadata.files,
preUploadError: state.metadata.preUploadError,
filenameConflicts: state.metadata.filenameConflicts,
courseDetails: state.studioDetails.course,
});

const mapDispatchToProps = dispatch => ({
uploadAssets: (assets, courseDetails) => dispatch(uploadAssets(assets, courseDetails)),
clearPreUploadProps: () => dispatch(clearPreUploadProps()),
clearUploadConfirmProps: () => dispatch(clearUploadConfirmProps()),
});

const WrappedAssetsUploadConfirm = connect(
Expand Down
26 changes: 13 additions & 13 deletions src/components/AssetsUploadConfirm/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,32 @@ export default class AssetsUploadConfirm extends React.Component {
}

componentWillReceiveProps(nextProps) {
const { preUploadError } = nextProps;
this.updateAlertOpenState(preUploadError);
const { filenameConflicts } = nextProps;
this.updateAlertOpenState(filenameConflicts);
}

updateAlertOpenState = (preUploadError) => {
updateAlertOpenState = (filenameConflicts) => {
this.setState({
modalOpen: preUploadError.length !== 0,
modalOpen: filenameConflicts.length !== 0,
});
};

uploadFiles = () => {
this.props.uploadAssets(this.props.files, this.props.courseDetails);
this.props.uploadAssets(this.props.filesToUpload, this.props.courseDetails);
};

onClose = () => {
this.setState(defaultState);
this.props.clearPreUploadProps();
this.props.clearUploadConfirmProps();
};

render() {
const { uploadFiles } = this;
const { modalOpen } = this.state;
const { preUploadError } = this.props;
const { filenameConflicts } = this.props;
const listOfFiles = (
<ul>
{ preUploadError.sort().map(item => <li key={item}>{item}</li>) }
{ filenameConflicts.sort().map(item => <li key={item}>{item}</li>) }
</ul>
);
const content = (
Expand Down Expand Up @@ -81,9 +81,9 @@ export default class AssetsUploadConfirm extends React.Component {

AssetsUploadConfirm.propTypes = {
// eslint-disable-next-line react/forbid-prop-types
files: PropTypes.arrayOf(PropTypes.object),
filesToUpload: PropTypes.arrayOf(PropTypes.object),
uploadAssets: PropTypes.func.isRequired,
clearPreUploadProps: PropTypes.func.isRequired,
clearUploadConfirmProps: PropTypes.func.isRequired,
courseDetails: PropTypes.shape({
lang: PropTypes.string,
url_name: PropTypes.string,
Expand All @@ -94,10 +94,10 @@ AssetsUploadConfirm.propTypes = {
id: PropTypes.string,
revision: PropTypes.string,
}).isRequired,
preUploadError: PropTypes.arrayOf(PropTypes.string),
filenameConflicts: PropTypes.arrayOf(PropTypes.string),
};

AssetsUploadConfirm.defaultProps = {
files: [],
preUploadError: [],
filesToUpload: [],
filenameConflicts: [],
};
39 changes: 22 additions & 17 deletions src/data/actions/assets.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ const requestFailed = responseAction => (
responseAction && 'type' in responseAction && responseAction.type === assetActions.request.REQUEST_ASSETS_FAILURE
);

const getUploadConflicts = (filesToUpload, response) => response.json().then((json) => {
const filesFound = json.assets.map(item => item.display_name);
const conflicts = filesToUpload.filter(item => filesFound.includes(item));
return conflicts;
});

export const updateRequest = newRequest => ({
type: assetActions.request.UPDATE_REQUEST,
newRequest,
Expand Down Expand Up @@ -273,22 +279,22 @@ export const uploadAssetFailure = (asset, response) => ({
});

export const setFilesToUpload = (files) => ({
type: assetActions.files.FILES_UPDATE,
type: assetActions.uploadConfirm.FILES_TO_UPLOAD,
files,
});

export const setPreUploadError = (preUploadError) => ({
type: assetActions.files.FILES_PRE_UPLOAD_ERROR,
preUploadError,
export const setFilenameConflicts = (filenameConflicts) => ({
type: assetActions.uploadConfirm.FILENAME_CONFLICTS,
filenameConflicts,
});

export const clearPreUploadProps = () => (dispatch) => {
export const clearUploadConfirmProps = () => (dispatch) => {
dispatch(setFilesToUpload([]));
dispatch(setPreUploadError([]));
dispatch(setFilenameConflicts([]));
};

export const uploadAssets = (assets, courseDetails) => (dispatch) => {
dispatch(clearPreUploadProps());
dispatch(clearUploadConfirmProps());
dispatch(uploadingAssets(assets.length));
// gather all the promises into a single promise that can be returned
return Promise.all(assets.map(asset => (
Expand All @@ -307,18 +313,17 @@ export const uploadAssets = (assets, courseDetails) => (dispatch) => {
)));
};

export const preUploadCheck = (assets, courseDetails) => (dispatch) => {
export const validateAssetsAndUpload = (assets, courseDetails) => (dispatch) => {
const filenames = assets.map(asset => asset.name);
return clientApi.preUploadCheck(courseDetails.id, filenames)
.then((response) => {
if (response.ok) {
return dispatch(uploadAssets(assets, courseDetails));
}
return response.json().then((resp) => {
return clientApi.getAssetDetails(courseDetails.id, filenames)
.then((response) => getUploadConflicts(filenames, response)
.then((conflicts) => {
if (conflicts.length === 0) {
return dispatch(uploadAssets(assets, courseDetails));
}
dispatch(setFilesToUpload(assets));
return dispatch(setPreUploadError(resp.files));
});
});
return dispatch(setFilenameConflicts(conflicts));
}));
};

export const uploadExceedMaxCount = maxFileCount => ({
Expand Down
Loading

0 comments on commit d3df36b

Please sign in to comment.