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:
@@ -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,
|
||||
|
||||
@@ -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}`;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user