feat: connect mfe and bff
test: update unit testing chore: update requested change
This commit is contained in:
committed by
leangseu-edx
parent
7f51ac833a
commit
67d91f4f98
@@ -1,6 +1,6 @@
|
||||
const configuration = {
|
||||
// BASE_URL: process.env.BASE_URL,
|
||||
// LMS_BASE_URL: process.env.LMS_BASE_URL,
|
||||
LMS_BASE_URL: process.env.LMS_BASE_URL,
|
||||
// LOGIN_URL: process.env.LOGIN_URL,
|
||||
// LOGOUT_URL: process.env.LOGOUT_URL,
|
||||
// CSRF_TOKEN_API_PATH: process.env.CSRF_TOKEN_API_PATH,
|
||||
|
||||
@@ -28,7 +28,7 @@ exports[`ListView component component render tests snapshots snapshot: happy pat
|
||||
Object {
|
||||
"Cell": [MockFunction this.formatGrade],
|
||||
"Header": "Grade",
|
||||
"accessor": "points",
|
||||
"accessor": "score",
|
||||
"disableFilters": true,
|
||||
},
|
||||
Object {
|
||||
|
||||
@@ -114,7 +114,7 @@ export class ListView extends React.Component {
|
||||
},
|
||||
{
|
||||
Header: this.translate(messages.grade),
|
||||
accessor: 'points',
|
||||
accessor: 'score',
|
||||
Cell: this.formatGrade,
|
||||
disableFilters: true,
|
||||
},
|
||||
@@ -150,7 +150,7 @@ ListView.propTypes = {
|
||||
username: PropTypes.string,
|
||||
dateSubmitted: PropTypes.number,
|
||||
gradingStatus: PropTypes.string,
|
||||
grade: PropTypes.shape({
|
||||
score: PropTypes.shape({
|
||||
pointsEarned: PropTypes.number,
|
||||
pointsPossible: PropTypes.number,
|
||||
}),
|
||||
|
||||
@@ -148,7 +148,7 @@ describe('ListView component', () => {
|
||||
test('grade column', () => {
|
||||
expect(columns[2]).toEqual({
|
||||
Header: messages.grade.defaultMessage,
|
||||
accessor: 'points',
|
||||
accessor: 'score',
|
||||
Cell: el.instance().formatGrade,
|
||||
disableFilters: true,
|
||||
});
|
||||
|
||||
@@ -19,11 +19,6 @@ exports[`ResponseDisplay component snapshot file upload disabled without respons
|
||||
<SubmissionFiles
|
||||
files={Array []}
|
||||
/>
|
||||
<Card>
|
||||
<Card.Body>
|
||||
parsed html (sanitized ())
|
||||
</Card.Body>
|
||||
</Card>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -62,10 +57,5 @@ exports[`ResponseDisplay component snapshot file upload enable without response
|
||||
<SubmissionFiles
|
||||
files={Array []}
|
||||
/>
|
||||
<Card>
|
||||
<Card.Body>
|
||||
parsed html (sanitized ())
|
||||
</Card.Body>
|
||||
</Card>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -24,8 +24,8 @@ export class ResponseDisplay extends React.Component {
|
||||
this.purify = createDOMPurify(window);
|
||||
}
|
||||
|
||||
get textContent() {
|
||||
return parse(this.purify.sanitize(this.props.response.text));
|
||||
get textContents() {
|
||||
return this.props.response.text.map(text => parse(this.purify.sanitize(text)));
|
||||
}
|
||||
|
||||
get submittedFiles() {
|
||||
@@ -42,9 +42,14 @@ export class ResponseDisplay extends React.Component {
|
||||
return (
|
||||
<div className="response-display">
|
||||
{this.allowFileUpload && <SubmissionFiles files={this.submittedFiles} />}
|
||||
<Card>
|
||||
<Card.Body>{this.textContent}</Card.Body>
|
||||
</Card>
|
||||
{
|
||||
/* eslint-disable react/no-array-index-key */
|
||||
this.textContents.map((textContent, index) => (
|
||||
<Card key={index}>
|
||||
<Card.Body>{textContent}</Card.Body>
|
||||
</Card>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -52,14 +57,14 @@ export class ResponseDisplay extends React.Component {
|
||||
|
||||
ResponseDisplay.defaultProps = {
|
||||
response: {
|
||||
text: '',
|
||||
text: [],
|
||||
files: [],
|
||||
},
|
||||
fileUploadResponseConfig: fileUploadResponseOptions.none,
|
||||
};
|
||||
ResponseDisplay.propTypes = {
|
||||
response: PropTypes.shape({
|
||||
text: PropTypes.string,
|
||||
text: PropTypes.arrayOf(PropTypes.string),
|
||||
files: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
fileName: PropTypes.string,
|
||||
|
||||
@@ -33,7 +33,7 @@ describe('ResponseDisplay', () => {
|
||||
describe('component', () => {
|
||||
const props = {
|
||||
response: {
|
||||
text: 'some text response here',
|
||||
text: ['some text response here'],
|
||||
files: [
|
||||
{
|
||||
name: 'some file name.jpg',
|
||||
@@ -58,40 +58,45 @@ describe('ResponseDisplay', () => {
|
||||
});
|
||||
describe('snapshot', () => {
|
||||
test('file upload enable with valid response', () => {
|
||||
expect(el).toMatchSnapshot();
|
||||
expect(el.instance().render()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('file upload enable without response', () => {
|
||||
el.setProps({
|
||||
response: {
|
||||
text: '',
|
||||
text: [],
|
||||
files: [],
|
||||
},
|
||||
});
|
||||
expect(el).toMatchSnapshot();
|
||||
expect(el.instance().render()).toMatchSnapshot();
|
||||
});
|
||||
test('file upload disable with valid response', () => {
|
||||
el.setProps({
|
||||
fileUploadResponseConfig: fileUploadResponseOptions.none,
|
||||
});
|
||||
expect(el).toMatchSnapshot();
|
||||
expect(el.instance().render()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('file upload disabled without response', () => {
|
||||
el.setProps({
|
||||
response: {
|
||||
text: '',
|
||||
text: [],
|
||||
files: [],
|
||||
},
|
||||
});
|
||||
expect(el).toMatchSnapshot();
|
||||
expect(el.instance().render()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('behavior', () => {
|
||||
test('get textContent', () => {
|
||||
expect(el.instance().textContent).toEqual(
|
||||
parse(createDOMPurify(window).sanitize(props.response.text)),
|
||||
test('get textContents', () => {
|
||||
expect(el.instance().textContents.length).toEqual(
|
||||
props.response.text.length,
|
||||
);
|
||||
el.instance().textContents.forEach((text, index) => {
|
||||
expect(text).toEqual(
|
||||
parse(createDOMPurify(window).sanitize(props.response.text[index])),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('get submittedFiles', () => {
|
||||
@@ -107,7 +112,7 @@ describe('ResponseDisplay', () => {
|
||||
describe('mapStateToProps', () => {
|
||||
let mapped;
|
||||
const testState = {
|
||||
dummyText: 'text',
|
||||
dummyText: ['text'],
|
||||
dummyFiles: ['files', 'file-2'],
|
||||
};
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -165,7 +165,6 @@ const grading = createSlice({
|
||||
const current = {
|
||||
...state.current,
|
||||
lockStatus: payload.lockStatus,
|
||||
gradeStatus: payload.gradeStatus,
|
||||
};
|
||||
const gradeData = {
|
||||
...state.gradeData,
|
||||
|
||||
@@ -99,10 +99,10 @@ export const fetchSubmission = ({ submissionUUID, ...rest }) => (dispatch) => {
|
||||
* @param {[func]} onSuccess - onSuccess method ((response) => { ... })
|
||||
* @param {[func]} onFailure - onFailure method ((error) => { ... })
|
||||
*/
|
||||
export const setLock = ({ submissionUUID, value, ...rest }) => (dispatch) => {
|
||||
export const setLock = ({ submissionUUID, ...rest }) => (dispatch) => {
|
||||
dispatch(module.networkRequest({
|
||||
requestKey: RequestKeys.setLock,
|
||||
promise: api.lockSubmission({ submissionUUID, value }),
|
||||
promise: api.lockSubmission(submissionUUID),
|
||||
...rest,
|
||||
}));
|
||||
};
|
||||
|
||||
@@ -154,14 +154,13 @@ describe('requests thunkActions module', () => {
|
||||
});
|
||||
});
|
||||
describe('setLock', () => {
|
||||
const lockValue = 'test-lock-value';
|
||||
testNetworkRequestAction({
|
||||
action: requests.setLock,
|
||||
args: { submissionUUID, value: lockValue },
|
||||
args: { submissionUUID },
|
||||
expectedString: 'with setLock promise',
|
||||
expectedData: {
|
||||
requestKey: RequestKeys.setLock,
|
||||
promise: api.lockSubmission({ submissionUUID, value: lockValue }),
|
||||
promise: api.lockSubmission(submissionUUID),
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,25 +1,13 @@
|
||||
import { StrictDict } from 'utils';
|
||||
import { gradeStatuses, lockStatuses } from './constants';
|
||||
import fakeData from './fakeData';
|
||||
|
||||
// import urls from './urls';
|
||||
// import { pageSize, paramKeys } from './constants';
|
||||
// import messages from './messages';
|
||||
// import * as utils from './utils';
|
||||
// const { get, post, stringifyUrl } = utils;
|
||||
import { locationId } from 'data/constants/app';
|
||||
import { paramKeys } from './constants';
|
||||
import urls from './urls';
|
||||
import { get, post, stringifyUrl } from './utils';
|
||||
|
||||
/*********************************************************************************
|
||||
* GET Actions
|
||||
*********************************************************************************/
|
||||
|
||||
const mockSuccess = (returnValFn) => (...args) => (
|
||||
new Promise((resolve) => resolve(returnValFn(...args)))
|
||||
);
|
||||
|
||||
const mockFailure = (returnValFn) => (...args) => (
|
||||
new Promise((resolve, reject) => reject(returnValFn(...args)))
|
||||
);
|
||||
|
||||
/**
|
||||
* get('/api/initialize', { ora_location, course_id? })
|
||||
* @return {
|
||||
@@ -38,12 +26,11 @@ const mockFailure = (returnValFn) => (...args) => (
|
||||
* },
|
||||
* }
|
||||
*/
|
||||
const initializeApp = mockSuccess(() => ({
|
||||
oraMetadata: fakeData.oraMetadata,
|
||||
courseMetadata: fakeData.courseMetadata,
|
||||
submissions: fakeData.submissions,
|
||||
}));
|
||||
|
||||
const initializeApp = () => get(
|
||||
stringifyUrl(urls.oraInitializeUrl, {
|
||||
[paramKeys.oraLocation]: locationId,
|
||||
}),
|
||||
).then(response => response.data);
|
||||
/**
|
||||
* get('/api/submission', { submissionUUID })
|
||||
* @return {
|
||||
@@ -54,9 +41,12 @@ const initializeApp = mockSuccess(() => ({
|
||||
* },
|
||||
* }
|
||||
*/
|
||||
const fetchSubmission = mockSuccess((submissionUUID) => (
|
||||
fakeData.mockSubmission(submissionUUID)
|
||||
));
|
||||
const fetchSubmission = (submissionUUID) => get(
|
||||
stringifyUrl(urls.fetchSubmissionUrl, {
|
||||
[paramKeys.oraLocation]: locationId,
|
||||
[paramKeys.submissionUUID]: submissionUUID,
|
||||
}),
|
||||
).then(response => response.data);
|
||||
|
||||
/**
|
||||
* fetches the current grade, gradeStatus, and rubricResponse data for the given submission
|
||||
@@ -68,17 +58,22 @@ const fetchSubmission = mockSuccess((submissionUUID) => (
|
||||
* lockStatus,
|
||||
* }
|
||||
*/
|
||||
const fetchSubmissionStatus = mockSuccess((submissionUUID) => (
|
||||
fakeData.mockSubmissionStatus(submissionUUID)
|
||||
));
|
||||
|
||||
const fetchSubmissionStatus = (submissionUUID) => get(
|
||||
stringifyUrl(urls.fetchSubmissionStatusUrl, {
|
||||
[paramKeys.oraLocation]: locationId,
|
||||
[paramKeys.submissionUUID]: submissionUUID,
|
||||
}),
|
||||
).then(response => response.data);
|
||||
/**
|
||||
* Fetches only the learner response for a given submission. Used for pre-fetching response
|
||||
* for neighboring submissions in the queue.
|
||||
*/
|
||||
export const fetchSubmissionResponse = mockSuccess((submissionUUID) => ({
|
||||
response: fakeData.mockSubmission(submissionUUID).response,
|
||||
}));
|
||||
export const fetchSubmissionResponse = (submissionUUID) => get(
|
||||
stringifyUrl(urls.fetchSubmissionUrl, {
|
||||
[paramKeys.oraLocation]: locationId,
|
||||
[paramKeys.submissionUUID]: submissionUUID,
|
||||
}),
|
||||
).then(response => response.data);
|
||||
|
||||
/* I assume this is the "Start Grading" call, even for if a
|
||||
* submission is already graded and we are attempting re-lock.
|
||||
@@ -87,31 +82,23 @@ export const fetchSubmissionResponse = mockSuccess((submissionUUID) => ({
|
||||
* @param {bool} value - new lock value
|
||||
* @param {string} submissionUUID
|
||||
*/
|
||||
const lockSubmission = mockSuccess(({ submissionUUID, value }) => ({
|
||||
...fakeData.mockSubmissionStatus(submissionUUID),
|
||||
lockStatus: value ? lockStatuses.inProgress : lockStatuses.unlocked,
|
||||
}));
|
||||
|
||||
/*
|
||||
* Assuming we do not care who has locked it or why, as there
|
||||
* is no design around communicating that info
|
||||
* post('api/lock', { submissionUUID });
|
||||
* @param {bool} value - new lock value
|
||||
* @param {string} submissionUUID
|
||||
*/
|
||||
const lockSubmissionFail = mockFailure(() => ({
|
||||
error: 'that did not work',
|
||||
}));
|
||||
|
||||
const lockSubmission = (submissionUUID) => post(
|
||||
stringifyUrl(urls.fetchSubmissionLockUrl, {
|
||||
[paramKeys.oraLocation]: locationId,
|
||||
[paramKeys.submissionUUID]: submissionUUID,
|
||||
}),
|
||||
).then(response => response.data);
|
||||
/*
|
||||
* post('api/updateGrade', { submissionUUID, gradeData })
|
||||
* @param {object} gradeData - full grading submission data
|
||||
*/
|
||||
const updateGrade = mockSuccess((submissionUUID, gradeData) => ({
|
||||
const updateGrade = (submissionUUID, gradeData) => post(
|
||||
stringifyUrl(urls.updateSubmissioonGradeUrl, {
|
||||
[paramKeys.oraLocation]: locationId,
|
||||
[paramKeys.submissionUUID]: submissionUUID,
|
||||
}),
|
||||
gradeData,
|
||||
gradeStatus: gradeStatuses.graded,
|
||||
lockStatus: lockStatuses.unlocked,
|
||||
}));
|
||||
).then(response => response.data);
|
||||
|
||||
export default StrictDict({
|
||||
initializeApp,
|
||||
@@ -119,6 +106,5 @@ export default StrictDict({
|
||||
fetchSubmissionResponse,
|
||||
fetchSubmissionStatus,
|
||||
lockSubmission,
|
||||
lockSubmissionFail,
|
||||
updateGrade,
|
||||
});
|
||||
|
||||
@@ -29,3 +29,8 @@ export const fileUploadResponseOptions = StrictDict({
|
||||
optional: 'optional',
|
||||
none: 'none',
|
||||
});
|
||||
|
||||
export const paramKeys = StrictDict({
|
||||
oraLocation: 'oraLocation',
|
||||
submissionUUID: 'submissionUUID',
|
||||
});
|
||||
|
||||
@@ -34,7 +34,7 @@ const getFiles = (submissionUUID) => {
|
||||
// eslint-disable-next-line
|
||||
export const mockSubmission = (submissionUUID) => ({
|
||||
response: {
|
||||
text: responseText(submissionUUID),
|
||||
text: [responseText(submissionUUID)],
|
||||
files: getFiles(submissionUUID),
|
||||
},
|
||||
gradeStatus: submissionList[submissionUUID].gradeStatus,
|
||||
|
||||
@@ -22,12 +22,12 @@ const day = 86400000;
|
||||
const submissions = {};
|
||||
let lastIndex = 0;
|
||||
|
||||
const createSubmission = (points, gradeStatus, lockStatus) => {
|
||||
const createSubmission = (score, gradeStatus, lockStatus) => {
|
||||
const index = lastIndex;
|
||||
lastIndex += 1;
|
||||
const submissionUUID = ids.submissionUUID(index);
|
||||
const gradeData = points === null ? null : {
|
||||
points,
|
||||
const gradeData = score === null ? null : {
|
||||
score,
|
||||
overallFeedback: 'was okay',
|
||||
criteria: [{
|
||||
name: 'firstCriterion',
|
||||
@@ -40,7 +40,7 @@ const createSubmission = (points, gradeStatus, lockStatus) => {
|
||||
username: ids.username(index),
|
||||
// teamName: '',
|
||||
dateSubmitted: date0 + (day * index),
|
||||
points,
|
||||
score,
|
||||
gradeData,
|
||||
gradeStatus,
|
||||
lockStatus,
|
||||
|
||||
@@ -4,6 +4,14 @@ import { configuration } from 'config';
|
||||
const baseUrl = `${configuration.LMS_BASE_URL}`;
|
||||
|
||||
const api = `${baseUrl}/api/`;
|
||||
const baseEsgUrl = `${api}ora_staff_grader/mock/`;
|
||||
|
||||
const oraInitializeUrl = `${baseEsgUrl}initialize`;
|
||||
const fetchSubmissionUrl = `${baseEsgUrl}submission`;
|
||||
const fetchSubmissionStatusUrl = `${baseEsgUrl}submission/status`;
|
||||
const fetchSubmissionLockUrl = `${baseEsgUrl}submission/lock`;
|
||||
const updateSubmissioonGradeUrl = `${baseEsgUrl}submission/grade`;
|
||||
|
||||
const course = (courseId) => `${baseUrl}/courses/${courseId}`;
|
||||
|
||||
const openResponse = (courseId) => (
|
||||
@@ -13,6 +21,11 @@ const ora = (courseId, locationId) => `${course(courseId)}/jump_to/${locationId}
|
||||
|
||||
export default StrictDict({
|
||||
api,
|
||||
oraInitializeUrl,
|
||||
fetchSubmissionUrl,
|
||||
fetchSubmissionStatusUrl,
|
||||
fetchSubmissionLockUrl,
|
||||
updateSubmissioonGradeUrl,
|
||||
baseUrl,
|
||||
course,
|
||||
openResponse,
|
||||
|
||||
Reference in New Issue
Block a user