Compare commits

...

10 Commits

Author SHA1 Message Date
Simon Chen
7e9ef204a7 Merge pull request #22 from edx/schen/fix_search
fix(functionality): Fix search so results are rendered with proper heading
2018-11-27 15:02:07 -05:00
Simon Chen
f779e7fd35 fix(functionality): Fix search so results are rendered with proper heading 2018-11-27 14:47:57 -05:00
Richard I Reilly
a5a62922b5 Merge pull request #13 from edx/schen/clean
Clean up not needed example code
2018-11-26 14:41:00 -05:00
Richard I Reilly
2c6aa96f8e Merge pull request #20 from edx/rir/fix-sorting
Fix column sorting in the grade table
2018-11-26 14:29:48 -05:00
Rick Reilly
30e866128f Fix column sorting in the grade table 2018-11-26 14:25:11 -05:00
Simon Chen
ec81eb47d9 Merge pull request #18 from edx/aed/edit-modal
feat(editing): display a status alert after grades have updated.
2018-11-14 21:03:12 -05:00
Alex Dusenbery
cd2a5ae903 feat(editing): display a status alert after grades have updated. 2018-11-14 20:36:41 -05:00
Richard I Reilly
7a02330e9e Merge pull request #17 from edx/rir/frontend-auth-1-1
Return the frontend-auth npm package to 1.1.0
2018-11-14 16:45:51 -05:00
Rick Reilly
a929194a29 Return the frontend-auth npm package to 1.1.0 2018-11-14 16:16:47 -05:00
Simon Chen
1687a6ca1a Clean up not needed example code 2018-11-14 14:02:53 -05:00
16 changed files with 126 additions and 1356 deletions

25
package-lock.json generated
View File

@@ -3075,9 +3075,9 @@
}
},
"@edx/paragon": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-3.7.1.tgz",
"integrity": "sha512-HmcWcCL6ocz0yoTajeSEt62a/CPM+Jz/Ch+RzxZhvUrlced6u7bSrjM0CdK7rlz4sZKI5oPQzZe199x1KHXk6Q==",
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-3.7.2.tgz",
"integrity": "sha512-M1l/0yVc2291jqyVpOHZkaq3Hz3A2ua87P7WrxM4vk6I8HAqNJyWRasa8rPYEGJ6hz0wAhA2Eemuq7YlMHaBVA==",
"requires": {
"@edx/edx-bootstrap": "^1.0.0",
"@sambego/storybook-styles": "^1.0.0",
@@ -3098,7 +3098,7 @@
"dependencies": {
"@edx/edx-bootstrap": {
"version": "1.0.0",
"resolved": "http://registry.npmjs.org/@edx/edx-bootstrap/-/edx-bootstrap-1.0.0.tgz",
"resolved": "https://registry.npmjs.org/@edx/edx-bootstrap/-/edx-bootstrap-1.0.0.tgz",
"integrity": "sha512-ZVoGAqWo9NtPKoNRgOgiW+Qr83TyZ+CWiKFpTmqaG3fm0qBgysnYYRooh1pyaJPedgFw2ljGrAAHYpn94R3pfw==",
"requires": {
"bootstrap": "4.0.0",
@@ -3132,15 +3132,6 @@
}
}
}
},
"scheduler": {
"version": "0.11.2",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.11.2.tgz",
"integrity": "sha512-+WCP3s3wOaW4S7C1tl3TEXp4l9lJn0ZK8G3W3WKRWmw77Z2cIFUW2MiNTMHn5sCjxN+t7N43HAOOgMjyAg5hlg==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1"
}
}
}
},
@@ -3554,7 +3545,7 @@
},
"@types/object-assign": {
"version": "4.0.30",
"resolved": "http://registry.npmjs.org/@types/object-assign/-/object-assign-4.0.30.tgz",
"resolved": "https://registry.npmjs.org/@types/object-assign/-/object-assign-4.0.30.tgz",
"integrity": "sha1-iUk3HVqZ9Dge4PHfCpt6GH4H5lI="
},
"@types/tapable": {
@@ -20515,9 +20506,9 @@
"dev": true
},
"scheduler": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.11.0.tgz",
"integrity": "sha512-MAYbBfmiEHxF0W+c4CxMpEqMYK+rYF584VP/qMKSiHM6lTkBKKYOJaDiSILpJHla6hBOsVd6GucPL46o2Uq3sg==",
"version": "0.11.2",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.11.2.tgz",
"integrity": "sha512-+WCP3s3wOaW4S7C1tl3TEXp4l9lJn0ZK8G3W3WKRWmw77Z2cIFUW2MiNTMHn5sCjxN+t7N43HAOOgMjyAg5hlg==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1"

View File

@@ -25,8 +25,8 @@
},
"dependencies": {
"@edx/edx-bootstrap": "^0.4.3",
"@edx/frontend-auth": "^1.1.0",
"@edx/paragon": "^3.7.1",
"@edx/frontend-auth": "1.1.0",
"@edx/paragon": "^3.7.2",
"babel-polyfill": "^6.26.0",
"classnames": "^2.2.5",
"email-prop-type": "^1.1.5",

View File

@@ -1,5 +1,5 @@
import React from 'react';
import { Button, Modal, SearchField, Table, InputSelect } from '@edx/paragon';
import { Button, InputSelect, Modal, SearchField, StatusAlert, Table } from '@edx/paragon';
import queryString from 'query-string';
import { configuration } from '../../config';
@@ -7,10 +7,7 @@ export default class Gradebook extends React.Component {
constructor(props) {
super(props);
this.state = {
grades: [], // this.mapUserEntriesPercent(this.props.grades).sort(this.sortAlphaDesc),
headings: [], // this.mapHeadings(this.props.grades[0]),
filterValue: '',
modalContent: (<h1>Hello, World!</h1>),
modalOpen: false,
modalModel: [{}],
updateVal: 0,
@@ -62,7 +59,15 @@ export default class Gradebook extends React.Component {
},
},
]);
this.setState({
modalModel: [{}],
modalOpen: false,
updateModuleId: null,
updateUserId: null,
});
}
updateQueryParams = (queryKey, queryValue) => {
const parsed = queryString.parse(this.props.location.search);
parsed[queryKey] = queryValue;
@@ -250,7 +255,7 @@ export default class Gradebook extends React.Component {
className="ml-2 mr-1"
onClick={() => this.props.filterColumns('exam', this.props.grades[0])}
/>
<label htmlFor="Exam">
<label htmlFor="category-exam">
Exam
</label>
</span>
@@ -292,11 +297,18 @@ export default class Gradebook extends React.Component {
</div>
</div>
<br />
<StatusAlert
alertType="success"
dialog="The grade has been successfully edited."
onClose={() => this.props.updateBanner(false)}
open={this.props.showSuccess}
/>
<div className="gbook">
<Table
columns={this.props.headings}
data={this.formatter[this.props.format](this.props.grades)}
defaultSortDirection="desc"
tableSortable
defaultSortDirection="asc"
defaultSortedColumn="username"
/>
</div>
@@ -309,9 +321,6 @@ export default class Gradebook extends React.Component {
<Table
columns={[{ label: 'Username', key: 'username' }, { label: 'Current grade', key: 'currentGrade' }, { label: 'Adjusted grade', key: 'adjustedGrade' }]}
data={this.state.modalModel}
tableSortable
defaultSortDirection="desc"
defaultSortedColumn="username"
/>
</div>
)}

View File

@@ -7,6 +7,7 @@ import {
updateGrades,
toggleGradeFormat,
filterColumns,
updateBanner,
} from '../../data/actions/grades';
import { fetchCohorts } from '../../data/actions/cohorts';
import { fetchTracks } from '../../data/actions/tracks';
@@ -20,6 +21,7 @@ const mapStateToProps = state => (
selectedTrack: state.grades.selectedTrack,
selectedCohort: state.grades.selectedCohort,
format: state.grades.gradeFormat,
showSuccess: state.grades.showSuccess,
}
);
@@ -46,6 +48,9 @@ const mapDispatchToProps = dispatch => (
filterColumns: (filterType, exampleUser) => {
dispatch(filterColumns(filterType, exampleUser));
},
updateBanner: (showSuccess) => {
dispatch(updateBanner(showSuccess));
},
}
);

View File

@@ -1,38 +0,0 @@
import 'whatwg-fetch';
import {
STARTED_FETCHING_COMMENT,
FINISHED_FETCHING_COMMENT,
ERROR_FETCHING_COMMENT,
GET_COMMENT,
} from '../constants/actionTypes/comment';
const startedFetchingComment = () => ({ type: STARTED_FETCHING_COMMENT });
const finishedFetchingComment = () => ({ type: FINISHED_FETCHING_COMMENT });
const errorFetchingComment = () => ({ type: ERROR_FETCHING_COMMENT });
const getComment = comment => ({ type: GET_COMMENT, comment });
const fetchComment = commentId => (
(dispatch) => {
dispatch(startedFetchingComment());
return fetch(`https://jsonplaceholder.typicode.com/comments/${commentId}`)
.then((response) => {
if (response.ok) {
return response.json();
}
throw new Error();
})
.then((data) => {
dispatch(getComment(data));
dispatch(finishedFetchingComment());
})
.catch(() => dispatch(errorFetchingComment()));
}
);
export {
startedFetchingComment,
finishedFetchingComment,
errorFetchingComment,
getComment,
fetchComment,
};

View File

@@ -9,9 +9,23 @@ import {
TOGGLE_GRADE_FORMAT,
SORT_GRADES,
FILTER_COLUMNS,
UPDATE_BANNER,
} from '../constants/actionTypes/grades';
import LmsApiService from '../services/LmsApiService';
import { headingMapper } from './utils';
import store from '../store';
import { headingMapper, gradeSortMap, sortAlphaAsc } from './utils';
const sortGrades = (columnName, direction) => {
const sortFn = gradeSortMap(columnName, direction);
const { results } = store.getState().grades;
results.sort(sortFn);
/* have to make a copy of results or React wont know there was
* a change and wont trigger a re-render
*/
return ({ type: SORT_GRADES, results: [...results] });
};
const startedFetchingGrades = () => ({ type: STARTED_FETCHING_GRADES });
const finishedFetchingGrades = () => ({ type: FINISHED_FETCHING_GRADES });
@@ -36,21 +50,29 @@ const gradeUpdateFailure = error => ({
const toggleGradeFormat = formatType => ({ type: TOGGLE_GRADE_FORMAT, formatType });
const sortGrades = (columnName, direction) => ({ type: SORT_GRADES, columnName, direction });
const filterColumns = (filterType, exampleUser) => ({
type: FILTER_COLUMNS,
headings: headingMapper[filterType](exampleUser)
});
const filterColumns = (filterType, exampleUser) => (
dispatch => ({
type: FILTER_COLUMNS,
headings: headingMapper[filterType](dispatch, exampleUser),
}));
const fetchGrades = (courseId, cohort, track) => (
const updateBanner = showSuccess => ({ type: UPDATE_BANNER, showSuccess });
const fetchGrades = (courseId, cohort, track, showSuccess) => (
(dispatch) => {
dispatch(startedFetchingGrades());
return LmsApiService.fetchGradebookData(courseId, null, cohort, track)
.then(response => response.data)
.then((data) => {
dispatch(gotGrades(data.results, cohort, track, headingMapper.all(data.results[0])));
dispatch(gotGrades(
data.results.sort(sortAlphaAsc),
cohort,
track,
headingMapper.all(dispatch, data.results[0]),
));
dispatch(finishedFetchingGrades());
dispatch(updateBanner(!!showSuccess));
})
.catch(() => {
dispatch(errorFetchingGrades());
@@ -64,7 +86,12 @@ const fetchMatchingUserGrades = (courseId, searchText, cohort, track) => (
return LmsApiService.fetchGradebookData(courseId, searchText, cohort, track)
.then(response => response.data)
.then((data) => {
dispatch(gotGrades(data.results, cohort, track));
dispatch(gotGrades(
data.results.sort(sortAlphaAsc),
cohort,
track,
headingMapper.all(dispatch, data.results[0]),
));
dispatch(finishedFetchingGrades());
})
.catch(() => {
@@ -80,6 +107,7 @@ const updateGrades = (courseId, updateData) => (
.then(response => response.data)
.then((data) => {
dispatch(gradeUpdateSuccess(data));
dispatch(fetchGrades(courseId, null, null, true));
})
.catch((error) => {
dispatch(gradeUpdateFailure(error));
@@ -101,4 +129,5 @@ export {
toggleGradeFormat,
sortGrades,
filterColumns,
updateBanner,
};

View File

@@ -1,46 +0,0 @@
import 'whatwg-fetch';
import {
STARTED_FETCHING_POSTS,
FINISHED_FETCHING_POSTS,
GET_POSTS,
} from '../constants/actionTypes/posts';
const startedFetchingPosts = () => (
{
type: STARTED_FETCHING_POSTS,
}
);
const finishedFetchingPosts = () => (
{
type: FINISHED_FETCHING_POSTS,
}
);
const getPosts = posts => (
{
type: GET_POSTS,
posts,
}
);
const fetchPosts = () => (
(dispatch) => {
dispatch(startedFetchingPosts());
return fetch('https://jsonplaceholder.typicode.com/posts')
// TODO: handle response error
.then(response => response.json())
.then((data) => {
dispatch(getPosts(data));
dispatch(finishedFetchingPosts());
});
}
);
export {
startedFetchingPosts,
finishedFetchingPosts,
getPosts,
fetchPosts,
};

View File

@@ -1,65 +0,0 @@
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import fetchMock from 'fetch-mock';
import {
startedFetchingPosts,
finishedFetchingPosts,
getPosts,
fetchPosts,
} from './posts';
import {
STARTED_FETCHING_POSTS,
GET_POSTS,
FINISHED_FETCHING_POSTS,
} from '../constants/actionTypes/posts';
const mockStore = configureMockStore([thunk]);
describe('actions', () => {
afterEach(() => {
fetchMock.reset();
fetchMock.restore();
});
it('sends started fetching post action', () => {
const expected = { type: STARTED_FETCHING_POSTS };
expect(startedFetchingPosts()).toEqual(expected);
});
it('sends finished fetching posts', () => {
const expected = { type: FINISHED_FETCHING_POSTS };
expect(finishedFetchingPosts()).toEqual(expected);
});
it('sends posts', () => {
const data = 'data';
const expected = { type: GET_POSTS, posts: data };
expect(getPosts(data)).toEqual(expected);
});
it('fetches posts', () => {
const posts = [
{
id: 1,
title: 'title',
body: 'body',
},
];
fetchMock.getOnce('https://jsonplaceholder.typicode.com/posts', {
body: JSON.stringify({ posts }),
headers: { 'content-type': 'application/json' },
});
const store = mockStore({ posts: [] });
const expectedActions = [
{ type: STARTED_FETCHING_POSTS },
{ type: GET_POSTS, posts: { posts } },
{ type: FINISHED_FETCHING_POSTS },
];
return store.dispatch(fetchPosts()).then(() => {
expect(store.getActions()).toEqual(expectedActions);
});
});
});

View File

@@ -1,5 +1,6 @@
import { sortGrades } from './grades';
const sortAlphaDesc = (gradeRowA, gradeRowB) => {
const sortAlphaAsc = (gradeRowA, gradeRowB) => {
const a = gradeRowA.username.toUpperCase();
const b = gradeRowB.username.toUpperCase();
if (a < b) {
@@ -11,7 +12,7 @@ const sortAlphaDesc = (gradeRowA, gradeRowB) => {
return 0;
};
const sortAlphaAsc = (gradeRowA, gradeRowB) => {
const sortAlphaDesc = (gradeRowA, gradeRowB) => {
const a = gradeRowA.username.toUpperCase();
const b = gradeRowB.username.toUpperCase();
if (a < b) {
@@ -24,40 +25,49 @@ const sortAlphaAsc = (gradeRowA, gradeRowB) => {
};
const sortNumerically = (colKey, direction) => {
function getPercents(gradeRowA, gradeRowB) {
if (colKey !== 'total') {
return {
a: gradeRowA.section_breakdown.find(x => x.label === colKey).percent,
b: gradeRowB.section_breakdown.find(x => x.label === colKey).percent,
};
}
return {
a: gradeRowA.percent,
b: gradeRowB.percent,
};
}
function sortNumAsc(gradeRowA, gradeRowB) {
if (gradeRowA[colKey] < gradeRowB[colKey]) {
return -1;
}
if (gradeRowA[colKey] > gradeRowB[colKey]) {
return 1;
}
return 0;
const { a, b } = getPercents(gradeRowA, gradeRowB);
return a - b;
}
function sortNumDesc(gradeRowA, gradeRowB) {
if (gradeRowA[colKey] < gradeRowB[colKey]) {
return 1;
}
if (gradeRowA[colKey] > gradeRowB[colKey]) {
return -1;
}
return 0;
const { a, b } = getPercents(gradeRowA, gradeRowB);
return b - a;
}
this.setState({ grades: [...this.state.grades].sort(direction === 'desc' ? sortNumDesc : sortNumAsc) });
return direction === 'desc' ? sortNumDesc : sortNumAsc;
};
function gradeSortMap(columnName, direction) {
if (columnName === 'username' && direction === 'desc') {
return sortAlphaDesc;
} else if (columnName === 'username') {
return sortAlphaAsc;
}
return sortNumerically(columnName, direction);
}
const headingMapper = {
all: (entry) => {
all: (dispatch, entry) => {
if (entry) {
const results = [{
label: 'Username',
key: 'username',
columnSortable: true,
onSort: (direction) => {
this.setState({
grades: [...this.state.grades].sort(direction === 'desc' ? this.sortAlphaDesc : this.sortAlphaAsc),
});
},
onSort: (direction) => { dispatch(sortGrades('username', direction)); },
}];
const assignmentHeadings = entry.section_breakdown
@@ -66,21 +76,21 @@ const headingMapper = {
label: s.label,
key: s.label,
columnSortable: true,
onSort: (direction) => { this.sortNumerically(s.label, direction); },
onSort: direction => dispatch(sortGrades(s.label, direction)),
}));
const totals = [{
label: 'Total',
key: 'total',
columnSortable: true,
onSort: (direction) => { this.sortNumerically('total', direction); },
onSort: direction => dispatch(sortGrades('total', direction)),
}];
return results.concat(assignmentHeadings).concat(totals);
}
return [];
},
hw: (entry) => {
hw: (dispatch, entry) => {
const results = [{
label: 'Username',
key: 'username',
@@ -103,7 +113,7 @@ const headingMapper = {
return results.concat(assignmentHeadings);
},
exam: (entry) => {
exam: (dispatch, entry) => {
const results = [{
label: 'Username',
key: 'username',
@@ -128,4 +138,5 @@ const headingMapper = {
},
};
export { headingMapper };
export { headingMapper, gradeSortMap, sortAlphaAsc };

View File

@@ -1,11 +0,0 @@
const STARTED_FETCHING_COMMENT = 'STARTED_FETCHING_COMMENT';
const FINISHED_FETCHING_COMMENT = 'FINISHED_FETCHING_COMMENT';
const ERROR_FETCHING_COMMENT = 'ERROR_FETCHING_COMMENT';
const GET_COMMENT = 'GET_COMMENT';
export {
STARTED_FETCHING_COMMENT,
FINISHED_FETCHING_COMMENT,
ERROR_FETCHING_COMMENT,
GET_COMMENT,
};

View File

@@ -10,6 +10,7 @@ const GRADE_UPDATE_FAILURE = 'GRADE_UPDATE_FAILURE';
const TOGGLE_GRADE_FORMAT = 'TOGGLE_GRADE_FORMAT';
const SORT_GRADES = 'SORT_GRADES';
const FILTER_COLUMNS = 'FILTER_COLUMNS';
const UPDATE_BANNER = 'UPDATE_BANNER';
export {
STARTED_FETCHING_GRADES,
@@ -22,4 +23,5 @@ export {
TOGGLE_GRADE_FORMAT,
SORT_GRADES,
FILTER_COLUMNS,
UPDATE_BANNER,
};

View File

@@ -1,9 +0,0 @@
const STARTED_FETCHING_POSTS = 'STARTED_FETCHING_POSTS';
const GET_POSTS = 'GET_POSTS';
const FINISHED_FETCHING_POSTS = 'FINISHED_FETCHING_POSTS';
export {
STARTED_FETCHING_POSTS,
GET_POSTS,
FINISHED_FETCHING_POSTS,
};

View File

@@ -1,46 +0,0 @@
import {
STARTED_FETCHING_COMMENT,
ERROR_FETCHING_COMMENT,
GET_COMMENT,
} from '../constants/actionTypes/comment';
const initialState = {
details: {
id: null,
postId: null,
name: '',
email: 'example@example.com',
body: '',
},
startedFetching: false,
finishedFetching: false,
errorFetching: false,
};
const comment = (state = initialState, action) => {
switch (action.type) {
case GET_COMMENT:
return {
...state,
details: { ...action.comment },
finishedFetching: true,
errorFetching: false,
};
case STARTED_FETCHING_COMMENT:
return {
...state,
startedFetching: true,
finishedFetching: false,
};
case ERROR_FETCHING_COMMENT:
return {
...state,
finishedFetching: true,
errorFetching: true,
};
default:
return state;
}
};
export default comment;

View File

@@ -4,6 +4,9 @@ import {
GOT_GRADES,
TOGGLE_GRADE_FORMAT,
FILTER_COLUMNS,
GRADE_UPDATE_SUCCESS,
UPDATE_BANNER,
SORT_GRADES,
} from '../constants/actionTypes/grades';
const initialState = {
@@ -13,6 +16,7 @@ const initialState = {
finishedFetching: false,
errorFetching: false,
gradeFormat: 'percent',
showSuccess: false,
};
const grades = (state = initialState, action) => {
@@ -49,1009 +53,19 @@ const grades = (state = initialState, action) => {
...state,
headings: action.headings,
};
case UPDATE_BANNER:
return {
...state,
showSuccess: action.showSuccess,
};
case SORT_GRADES:
return {
...state,
results: action.results,
};
default:
return state;
}
};
export default grades;
// Gradebook.defaultProps = {
// "results": [
// {
// "course_id": "course-v1:edX+DemoX+Demo_Course",
// "email": "honor@example.com",
// "user_id": 6,
// "username": "honor",
// "full_name": "",
// "passed": false,
// "percent": 0,
// "letter_grade": null,
// "progress_page_url": "/courses/course-v1:edX+DemoX+Demo_Course/progress/6/",
// "section_breakdown": [
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Introduction",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@edx_introduction",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@d8a6192ade314473a78242dfeedfbf5b",
// "subsection_name": "Demo Course Overview"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 1: Getting Started",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/3.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@19a30717eff543078a5d94ae9d6c18a5",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 3,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations",
// "subsection_name": "Lesson 1 - Getting Started"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": "Homework",
// "chapter_name": "Example Week 1: Getting Started",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": true,
// "grade_description": "(0.00/11.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": "Ex 01",
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 11,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations",
// "subsection_name": "Homework - Question Styles"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 2: Get Interactive",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@simulations",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
// "subsection_name": "Lesson 2 - Let's Get Interactive!"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": "Homework",
// "chapter_name": "Example Week 2: Get Interactive",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": true,
// "grade_description": "(0.00/5.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": "Ex 02",
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@graded_simulations",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 5,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
// "subsection_name": "Homework - Labs and Demos"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 2: Get Interactive",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/19.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@175e76c4951144a29d46211361266e0e",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 19,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
// "subsection_name": "Homework - Essays"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 3: Be Social",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@48ecb924d7fe4b66a230137626bfa93e",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
// "subsection_name": "Lesson 3 - Be Social"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 3: Be Social",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@dbe8fc027bcb4fe9afb744d2e8415855",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
// "subsection_name": "Homework - Find Your Study Buddy"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 3: Be Social",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@6ab9c442501d472c8ed200e367b4edfa",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
// "subsection_name": "More Ways to Connect"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": "Exam",
// "chapter_name": "About Exams and Certificates",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": true,
// "grade_description": "(0.00/6.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@workflow",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 6,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@1414ffd5143b4b508f739b563ab468b7",
// "subsection_name": "edX Exams"
// }
// ],
// "aggregates": {
// "Exam": {
// "score_possible": 6,
// "score_earned": 0
// },
// "Homework": {
// "score_possible": 16,
// "score_earned": 0
// }
// }
// },
// {
// "course_id": "course-v1:edX+DemoX+Demo_Course",
// "email": "audit@example.com",
// "user_id": 7,
// "username": "audit",
// "full_name": "",
// "passed": false,
// "percent": 0.17,
// "letter_grade": null,
// "progress_page_url": "/courses/course-v1:edX+DemoX+Demo_Course/progress/7/",
// "section_breakdown": [
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Introduction",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@edx_introduction",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@d8a6192ade314473a78242dfeedfbf5b",
// "subsection_name": "Demo Course Overview"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 1: Getting Started",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/3.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@19a30717eff543078a5d94ae9d6c18a5",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 3,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations",
// "subsection_name": "Lesson 1 - Getting Started"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": "Homework",
// "chapter_name": "Example Week 1: Getting Started",
// "comment": "",
// "detail": "",
// "displayed_value": "0.45",
// "is_graded": true,
// "grade_description": "(5.00/11.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": "Ex 01",
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions",
// "percent": 0.45,
// "score_earned": 5,
// "score_possible": 11,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations",
// "subsection_name": "Homework - Question Styles"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 2: Get Interactive",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@simulations",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
// "subsection_name": "Lesson 2 - Let's Get Interactive!"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": "Homework",
// "chapter_name": "Example Week 2: Get Interactive",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": true,
// "grade_description": "(0.00/5.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": "Ex 02",
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@graded_simulations",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 5,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
// "subsection_name": "Homework - Labs and Demos"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 2: Get Interactive",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/19.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@175e76c4951144a29d46211361266e0e",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 19,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
// "subsection_name": "Homework - Essays"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 3: Be Social",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@48ecb924d7fe4b66a230137626bfa93e",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
// "subsection_name": "Lesson 3 - Be Social"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 3: Be Social",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@dbe8fc027bcb4fe9afb744d2e8415855",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
// "subsection_name": "Homework - Find Your Study Buddy"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 3: Be Social",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@6ab9c442501d472c8ed200e367b4edfa",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
// "subsection_name": "More Ways to Connect"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": "Exam",
// "chapter_name": "About Exams and Certificates",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": true,
// "grade_description": "(0.00/6.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@workflow",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 6,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@1414ffd5143b4b508f739b563ab468b7",
// "subsection_name": "edX Exams"
// }
// ],
// "aggregates": {
// "Exam": {
// "score_possible": 6,
// "score_earned": 0
// },
// "Homework": {
// "score_possible": 16,
// "score_earned": 5
// }
// }
// },
// {
// "course_id": "course-v1:edX+DemoX+Demo_Course",
// "email": "verified@example.com",
// "user_id": 8,
// "username": "verified",
// "full_name": "",
// "passed": false,
// "percent": 0,
// "letter_grade": null,
// "progress_page_url": "/courses/course-v1:edX+DemoX+Demo_Course/progress/8/",
// "section_breakdown": [
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Introduction",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@edx_introduction",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@d8a6192ade314473a78242dfeedfbf5b",
// "subsection_name": "Demo Course Overview"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 1: Getting Started",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/3.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@19a30717eff543078a5d94ae9d6c18a5",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 3,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations",
// "subsection_name": "Lesson 1 - Getting Started"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": "Homework",
// "chapter_name": "Example Week 1: Getting Started",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": true,
// "grade_description": "(0.00/11.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": "Ex 01",
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 11,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations",
// "subsection_name": "Homework - Question Styles"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 2: Get Interactive",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@simulations",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
// "subsection_name": "Lesson 2 - Let's Get Interactive!"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": "Homework",
// "chapter_name": "Example Week 2: Get Interactive",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": true,
// "grade_description": "(0.00/5.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": "Ex 02",
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@graded_simulations",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 5,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
// "subsection_name": "Homework - Labs and Demos"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 2: Get Interactive",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/19.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@175e76c4951144a29d46211361266e0e",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 19,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
// "subsection_name": "Homework - Essays"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 3: Be Social",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@48ecb924d7fe4b66a230137626bfa93e",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
// "subsection_name": "Lesson 3 - Be Social"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 3: Be Social",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@dbe8fc027bcb4fe9afb744d2e8415855",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
// "subsection_name": "Homework - Find Your Study Buddy"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 3: Be Social",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@6ab9c442501d472c8ed200e367b4edfa",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
// "subsection_name": "More Ways to Connect"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": "Exam",
// "chapter_name": "About Exams and Certificates",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": true,
// "grade_description": "(0.00/6.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@workflow",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 6,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@1414ffd5143b4b508f739b563ab468b7",
// "subsection_name": "edX Exams"
// }
// ],
// "aggregates": {
// "Exam": {
// "score_possible": 6,
// "score_earned": 0
// },
// "Homework": {
// "score_possible": 16,
// "score_earned": 0
// }
// }
// },
// {
// "course_id": "course-v1:edX+DemoX+Demo_Course",
// "email": "staff@example.com",
// "user_id": 9,
// "username": "staff",
// "full_name": "",
// "passed": false,
// "percent": 0,
// "letter_grade": null,
// "progress_page_url": "/courses/course-v1:edX+DemoX+Demo_Course/progress/9/",
// "section_breakdown": [
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Introduction",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@edx_introduction",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@d8a6192ade314473a78242dfeedfbf5b",
// "subsection_name": "Demo Course Overview"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 1: Getting Started",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/3.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@19a30717eff543078a5d94ae9d6c18a5",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 3,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations",
// "subsection_name": "Lesson 1 - Getting Started"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": "Homework",
// "chapter_name": "Example Week 1: Getting Started",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": true,
// "grade_description": "(0.00/11.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": "Ex 01",
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 11,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations",
// "subsection_name": "Homework - Question Styles"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 2: Get Interactive",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@simulations",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
// "subsection_name": "Lesson 2 - Let's Get Interactive!"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": "Homework",
// "chapter_name": "Example Week 2: Get Interactive",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": true,
// "grade_description": "(0.00/5.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": "Ex 02",
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@graded_simulations",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 5,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
// "subsection_name": "Homework - Labs and Demos"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 2: Get Interactive",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/19.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@175e76c4951144a29d46211361266e0e",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 19,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
// "subsection_name": "Homework - Essays"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 3: Be Social",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@48ecb924d7fe4b66a230137626bfa93e",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
// "subsection_name": "Lesson 3 - Be Social"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 3: Be Social",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@dbe8fc027bcb4fe9afb744d2e8415855",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
// "subsection_name": "Homework - Find Your Study Buddy"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 3: Be Social",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@6ab9c442501d472c8ed200e367b4edfa",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
// "subsection_name": "More Ways to Connect"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": "Exam",
// "chapter_name": "About Exams and Certificates",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": true,
// "grade_description": "(0.00/6.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@workflow",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 6,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@1414ffd5143b4b508f739b563ab468b7",
// "subsection_name": "edX Exams"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "holding section",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@07bc32474380492cb34f76e5f9d9a135",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@9fca584977d04885bc911ea76a9ef29e",
// "subsection_name": "New Subsection"
// }
// ],
// "aggregates": {
// "Exam": {
// "score_possible": 6,
// "score_earned": 0
// },
// "Homework": {
// "score_possible": 16,
// "score_earned": 0
// }
// }
// }
// ]
// };

View File

@@ -1,31 +0,0 @@
import {
GET_POSTS,
STARTED_FETCHING_POSTS,
FINISHED_FETCHING_POSTS,
} from '../constants/actionTypes/posts';
const posts = (state = { posts: [], startedFetching: false, finishedFetching: false }, action) => {
switch (action.type) {
case GET_POSTS:
return {
...state,
posts: action.posts,
};
case STARTED_FETCHING_POSTS:
return {
...state,
startedFetching: true,
finishedFetching: false,
};
case FINISHED_FETCHING_POSTS:
return {
...state,
startedFetching: false,
finishedFetching: true,
};
default:
return state;
}
};
export default posts;

View File

@@ -1,45 +0,0 @@
import posts from './posts';
import {
GET_POSTS,
STARTED_FETCHING_POSTS,
FINISHED_FETCHING_POSTS,
} from '../constants/actionTypes/posts';
const initialState = {
posts: [],
startedFetching: false,
finishedFetching: false,
};
describe('posts reducer', () => {
it('has initial state', () => {
expect(posts(undefined, {})).toEqual(initialState);
});
it('adds posts', () => {
const fetchedPosts = [1, 2, 3];
const expected = {
...initialState,
posts: fetchedPosts,
};
expect(posts(undefined, { type: GET_POSTS, posts: fetchedPosts })).toEqual(expected);
});
it('updates started fetching posts state', () => {
const expected = {
...initialState,
startedFetching: true,
finishedFetching: false,
};
expect(posts(undefined, { type: STARTED_FETCHING_POSTS })).toEqual(expected);
});
it('updates finished fetching posts state', () => {
const expected = {
...initialState,
startedFetching: false,
finishedFetching: true,
};
expect(posts(undefined, { type: FINISHED_FETCHING_POSTS })).toEqual(expected);
});
});