Add quota error handling to RCS sidebar
closes CORE-1239 Test Plan: - Set a course's usage quota to 10mb (or anything low) - Attempt to upload a file bigger than that through the RCS sidebar - Notice an error shows up - Upload a file less than the quota - Notice the error goes away Change-Id: I2b8cab2fb76d3ec3520fff5eee337892d34d56d1 Reviewed-on: https://gerrit.instructure.com/150085 Tested-by: Jenkins Reviewed-by: Ryan Shaw <ryan@instructure.com> QA-Review: Rohan Cheeniyil <rcheeniyil@instructure.com> Product-Review: Clay Diffrient <cdiffrient@instructure.com>
This commit is contained in:
parent
ebbfde74ef
commit
0a9226051e
|
@ -28,6 +28,7 @@ export const FAIL_FILE_UPLOAD = "FAIL_FILE_UPLOAD";
|
|||
export const COMPLETE_FILE_UPLOAD = "COMPLETE_FILE_UPLOAD";
|
||||
export const TOGGLE_UPLOAD_FORM = "TOGGLE_UPLOAD_FORM";
|
||||
export const PROCESSED_FOLDER_BATCH = "PROCESSED_FOLDER_BATCH";
|
||||
export const QUOTA_EXCEEDED_UPLOAD = "QUOTA_EXCEEDED_UPLOAD";
|
||||
|
||||
export function receiveFolder({ id, name, parentId }) {
|
||||
return { type: RECEIVE_FOLDER, id, name, parentId };
|
||||
|
@ -45,6 +46,10 @@ export function failUpload(error) {
|
|||
return { type: FAIL_FILE_UPLOAD, error };
|
||||
}
|
||||
|
||||
export function quotaExceeded(error) {
|
||||
return { type: QUOTA_EXCEEDED_UPLOAD, error };
|
||||
}
|
||||
|
||||
export function completeUpload(results) {
|
||||
return { type: COMPLETE_FILE_UPLOAD, results };
|
||||
}
|
||||
|
@ -174,6 +179,19 @@ export function setAltText(altText, results) {
|
|||
return results;
|
||||
}
|
||||
|
||||
export function handleFailures(error, dispatch) {
|
||||
return error.response
|
||||
.json()
|
||||
.then(resp => {
|
||||
if (resp.message === "file size exceeds quota") {
|
||||
dispatch(quotaExceeded(error));
|
||||
} else {
|
||||
dispatch(failUpload(error));
|
||||
}
|
||||
})
|
||||
.catch(error => dispatch(failUpload(error)))
|
||||
}
|
||||
|
||||
export function uploadPreflight(tabContext, fileMetaProps) {
|
||||
return (dispatch, getState) => {
|
||||
const { source, jwt, host, contextId, contextType } = getState();
|
||||
|
@ -202,6 +220,6 @@ export function uploadPreflight(tabContext, fileMetaProps) {
|
|||
.then(results => {
|
||||
dispatch(allUploadCompleteActions(results, fileMetaProps));
|
||||
})
|
||||
.catch(error => dispatch(failUpload(error)));
|
||||
.catch(err => handleFailures(err, dispatch));
|
||||
};
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import formatMessage from "../../format-message";
|
|||
import ScreenReaderContent from "@instructure/ui-core/lib/components/ScreenReaderContent";
|
||||
import Select from "@instructure/ui-core/lib/components/Select";
|
||||
import Button from "@instructure/ui-core/lib/components/Button";
|
||||
import Alert from "@instructure/ui-alerts/lib/components/Alert";
|
||||
import IconAddSolid from "instructure-icons/lib/Solid/IconAddSolid";
|
||||
import IconMinimizeSolid from "instructure-icons/lib/Solid/IconMinimizeSolid";
|
||||
import Loading from "../../common/components/Loading";
|
||||
|
@ -234,6 +235,13 @@ class UploadForm extends Component {
|
|||
renderForm() {
|
||||
if (this.props.upload.formExpanded) {
|
||||
let screenreaderMessage = formatMessage("Select a file");
|
||||
let errorMessage =
|
||||
this.props.upload.error &&
|
||||
this.props.upload.error.type === "QUOTA_EXCEEDED_UPLOAD"
|
||||
? formatMessage(
|
||||
"This upload exceeds the file storage quota. Please speak to your system administrator."
|
||||
)
|
||||
: null;
|
||||
return (
|
||||
<form
|
||||
onSubmit={this.handleUpload.bind(this)}
|
||||
|
@ -245,6 +253,7 @@ class UploadForm extends Component {
|
|||
<label htmlFor="upload-form-file-input">
|
||||
<ScreenReaderContent>{screenreaderMessage}</ScreenReaderContent>
|
||||
</label>
|
||||
{errorMessage && <Alert variant="error">{errorMessage}</Alert>}
|
||||
<input
|
||||
className={css(styles.uploadedData)}
|
||||
type="file"
|
||||
|
@ -308,7 +317,10 @@ UploadForm.propTypes = {
|
|||
uploading: PropTypes.bool.isRequired,
|
||||
formExpanded: PropTypes.bool.isRequired,
|
||||
rootFolderId: PropTypes.number,
|
||||
folderTree: PropTypes.object.isRequired
|
||||
folderTree: PropTypes.object.isRequired,
|
||||
error: PropTypes.shape({
|
||||
type: PropTypes.string
|
||||
})
|
||||
}).isRequired,
|
||||
toggleUploadForm: PropTypes.func.isRequired,
|
||||
fetchFolders: PropTypes.func.isRequired,
|
||||
|
|
|
@ -23,7 +23,8 @@ import {
|
|||
COMPLETE_FILE_UPLOAD,
|
||||
RECEIVE_FOLDER,
|
||||
FAIL_FOLDERS_LOAD,
|
||||
PROCESSED_FOLDER_BATCH
|
||||
PROCESSED_FOLDER_BATCH,
|
||||
QUOTA_EXCEEDED_UPLOAD
|
||||
} from "../actions/upload";
|
||||
import { combineReducers } from "redux";
|
||||
|
||||
|
@ -33,12 +34,27 @@ function uploading(state = false, action) {
|
|||
return true;
|
||||
case FAIL_FILE_UPLOAD:
|
||||
case COMPLETE_FILE_UPLOAD:
|
||||
case QUOTA_EXCEEDED_UPLOAD:
|
||||
return false;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
function error(state = {}, action) {
|
||||
switch (action.type) {
|
||||
case COMPLETE_FILE_UPLOAD:
|
||||
return {};
|
||||
case QUOTA_EXCEEDED_UPLOAD:
|
||||
return {
|
||||
...state,
|
||||
type: action.type
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
function formExpanded(state = false, action) {
|
||||
switch (action.type) {
|
||||
case COMPLETE_FILE_UPLOAD:
|
||||
|
@ -116,5 +132,6 @@ export default combineReducers({
|
|||
formExpanded,
|
||||
folders,
|
||||
rootFolderId,
|
||||
folderTree
|
||||
folderTree,
|
||||
error
|
||||
});
|
||||
|
|
|
@ -499,4 +499,36 @@ describe("Upload data actions", () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('handleFailures', () => {
|
||||
it('calls quota exceeded when the file size exceeds the quota', () => {
|
||||
const fakeDispatch = sinon.spy();
|
||||
const error = {
|
||||
response: new Response('{ "message": "file size exceeds quota" }', { status: 400})
|
||||
}
|
||||
return actions.handleFailures(error, fakeDispatch).then(() => {
|
||||
sinon.assert.calledWith(fakeDispatch,
|
||||
sinon.match({
|
||||
type: 'QUOTA_EXCEEDED_UPLOAD',
|
||||
error
|
||||
})
|
||||
);
|
||||
})
|
||||
|
||||
});
|
||||
it('calls failUpload for other errors', () => {
|
||||
const fakeDispatch = sinon.spy();
|
||||
const error = {
|
||||
response: new Response('{ "message": "we don\'t like you " }', { status: 400})
|
||||
}
|
||||
return actions.handleFailures(error, fakeDispatch).then(() => {
|
||||
sinon.assert.calledWith(fakeDispatch,
|
||||
sinon.match({
|
||||
type: 'FAIL_FILE_UPLOAD',
|
||||
error
|
||||
})
|
||||
);
|
||||
})
|
||||
})
|
||||
})
|
||||
});
|
||||
|
|
|
@ -30,7 +30,8 @@ describe("Upload reducer", () => {
|
|||
formExpanded: false,
|
||||
folders: {},
|
||||
rootFolderId: null,
|
||||
folderTree: {}
|
||||
folderTree: {},
|
||||
error: {}
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -67,6 +68,11 @@ describe("Upload reducer", () => {
|
|||
state.formExpanded = true;
|
||||
assert.equal(false, upload(state, action).formExpanded);
|
||||
});
|
||||
|
||||
it('resets the error state', () => {
|
||||
state.error = { type: 'SOME_ERROR'}
|
||||
assert.deepEqual({}, upload(state, action).error);
|
||||
})
|
||||
});
|
||||
|
||||
describe("FAIL_FILE_UPLOAD", () => {
|
||||
|
@ -83,6 +89,20 @@ describe("Upload reducer", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('QUOTA_EXCEEDED_UPLOAD', () => {
|
||||
beforeEach(() => {
|
||||
action = { type: actions.QUOTA_EXCEEDED_UPLOAD };
|
||||
});
|
||||
|
||||
it('sets the error state type to QUOTA_EXCEEDED_UPLOAD', () => {
|
||||
assert.equal(upload(state, action).error.type, 'QUOTA_EXCEEDED_UPLOAD');
|
||||
});
|
||||
|
||||
it('sets the uploading state the false', () => {
|
||||
assert.equal(false, upload(state, action).uploading);
|
||||
})
|
||||
});
|
||||
|
||||
describe("RECEIVE_FOLDER", () => {
|
||||
beforeEach(() => {
|
||||
action = {
|
||||
|
|
Loading…
Reference in New Issue