Fixes saving unit position and unit redirection bugs (#128)

* Bumping axios-mock-adapter version

Thought there was a feature in 1.18.2 that I needed - turns out the feature hasn’t been released yet.  Still fine to bump the dependency, though.

* Hiding some warnings about console logging.

* Fixes bugs in CoursewareContainer

Fixes a few bugs in the courseware container:

- Position was not being saved because we weren’t reading “saveUnitPosition” correctly.
- We weren’t calling checkContentRedirect with the right arguments - it was using a non-existent unitId instead of the routeUnitId, meaning we would redirect to the active unit even if a unit was specified in the URL.

Adds tests in CoursewareContainer for various URL and data states.

Now explicitly tests:
- Exam redirects
- The resume block method when it has, and doesn’t have, a block to resume.
- The content redirect when a unit isn’t present on the URL (uses sequence.position)
- Loading a specific unit (not the first of a sequence!) by URL.

Updated some of the factories to be more flexible/allow multiple units.
This commit is contained in:
David Joy
2020-07-29 14:24:39 -04:00
committed by GitHub
parent 71482f1ec7
commit b048ca8187
8 changed files with 257 additions and 106 deletions

View File

@@ -4,50 +4,44 @@ import './block.factory';
Factory.define('courseBlocks')
.option('courseId', 'course-v1:edX+DemoX+Demo_Course')
.option('unit', ['courseId'], courseId => Factory.build(
'block',
{ type: 'vertical' },
{ courseId },
))
.option('sequence', ['courseId', 'unit'], (courseId, child) => Factory.build(
'block',
{ type: 'sequential', children: [child.id] },
{ courseId },
))
.option('section', ['courseId', 'sequence'], (courseId, child) => Factory.build(
'block',
{ type: 'chapter', children: [child.id] },
{ courseId },
))
.option('course', ['courseId', 'section'], (courseId, child) => Factory.build(
'block',
{ type: 'course', children: [child.id] },
{ courseId },
))
.option('units')
.option('sequence')
.option('section')
.option('course')
.attr(
'blocks',
['course', 'section', 'sequence', 'unit'],
(course, section, sequence, unit) => ({
[course.id]: course,
[section.id]: section,
[sequence.id]: sequence,
[unit.id]: unit,
}),
['course', 'section', 'sequence', 'units'],
(course, section, sequence, units) => {
const unitsObj = {};
units.forEach(unit => {
unitsObj[unit.id] = unit;
});
return {
[course.id]: course,
[section.id]: section,
[sequence.id]: sequence,
...unitsObj,
};
},
)
.attr('root', ['course'], course => course.id);
/**
* Builds a course with a single chapter, sequence, and unit.
*/
export default function buildSimpleCourseBlocks(courseId, title) {
const unitBlock = Factory.build(
'block',
{ type: 'vertical' },
{ courseId },
);
export default function buildSimpleCourseBlocks(courseId, title, numUnits = 1) {
const unitBlocks = [];
for (let i = 0; i < numUnits; i++) {
const unitBlock = Factory.build(
'block',
{ type: 'vertical' },
{ courseId },
);
unitBlocks.push(unitBlock);
}
const sequenceBlock = Factory.build(
'block',
{ type: 'sequential', children: [unitBlock.id] },
{ type: 'sequential', children: unitBlocks.map(unitBlock => unitBlock.id) },
{ courseId },
);
const sectionBlock = Factory.build(
@@ -65,13 +59,13 @@ export default function buildSimpleCourseBlocks(courseId, title) {
'courseBlocks',
{ courseId },
{
unit: unitBlock,
units: unitBlocks,
sequence: sequenceBlock,
section: sectionBlock,
course: courseBlock,
},
),
unitBlock,
unitBlocks,
sequenceBlock,
sectionBlock,
courseBlock,

View File

@@ -25,16 +25,17 @@ describe('Data layer integration tests', () => {
// building minimum set of api responses to test all thunks
const courseMetadata = Factory.build('courseMetadata');
const courseId = courseMetadata.id;
const { courseBlocks, unitBlock, sequenceBlock } = buildSimpleCourseBlocks(courseId);
const { courseBlocks, unitBlocks, sequenceBlock } = buildSimpleCourseBlocks(courseId);
const sequenceMetadata = Factory.build(
'sequenceMetadata',
{},
{ courseId, unitBlocks: [unitBlock], sequenceBlock },
{ courseId, unitBlocks, sequenceBlock },
);
const courseUrl = `${courseBaseUrl}/${courseId}`;
const sequenceUrl = `${sequenceBaseUrl}/${sequenceMetadata.item_id}`;
const sequenceId = sequenceBlock.id;
const unitBlock = unitBlocks[0];
const unitId = unitBlock.id;
let store;
@@ -66,9 +67,7 @@ describe('Data layer integration tests', () => {
has_access: false,
},
});
const forbiddenCourseBlocks = Factory.build('courseBlocks', {
courseId: forbiddenCourseMetadata.id,
});
const { courseBlocks: forbiddenCourseBlocks } = buildSimpleCourseBlocks(forbiddenCourseMetadata.id, null);
const forbiddenCourseUrl = `${courseBaseUrl}/${forbiddenCourseMetadata.id}`;