feat: connect mfe and bff

test: update unit testing

chore: update requested change
This commit is contained in:
Leangseu Kim
2021-11-23 12:21:07 -05:00
committed by leangseu-edx
parent 7f51ac833a
commit 67d91f4f98
15 changed files with 99 additions and 97 deletions

View File

@@ -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,

View File

@@ -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 {

View File

@@ -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,
}),

View File

@@ -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,
});

View File

@@ -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>
`;

View File

@@ -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,

View File

@@ -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(() => {

View File

@@ -165,7 +165,6 @@ const grading = createSlice({
const current = {
...state.current,
lockStatus: payload.lockStatus,
gradeStatus: payload.gradeStatus,
};
const gradeData = {
...state.gradeData,

View File

@@ -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,
}));
};

View File

@@ -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),
},
});
});

View File

@@ -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,
});

View File

@@ -29,3 +29,8 @@ export const fileUploadResponseOptions = StrictDict({
optional: 'optional',
none: 'none',
});
export const paramKeys = StrictDict({
oraLocation: 'oraLocation',
submissionUUID: 'submissionUUID',
});

View File

@@ -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,

View File

@@ -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,

View File

@@ -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,