@coorpacademy/progression-engine
Version:
474 lines (473 loc) • 11.8 kB
JavaScript
"use strict";
var _concat2 = _interopRequireDefault(require("lodash/fp/concat"));
var _filter2 = _interopRequireDefault(require("lodash/fp/filter"));
var _ava = _interopRequireDefault(require("ava"));
var _config2 = require("../../config");
var _computeNextStep = require("../compute-next-step");
var _slides = _interopRequireDefault(require("./fixtures/slides"));
var _states = require("./fixtures/states");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const config = (0, _config2.getConfig)({
ref: 'learner',
version: '1'
});
const availableContent = [{
ref: '1.A1',
slides: (0, _filter2.default)({
chapter_id: '1.A1'
}, _slides.default),
rules: null
}];
(0, _ava.default)('should return a success ExitNode if there is no available content with one chapter', t => {
const availableContenta = [{
ref: '1.A1',
slides: (0, _concat2.default)((0, _filter2.default)({
_id: '1.A1.1'
}, _slides.default), (0, _filter2.default)({
_id: '1.A1.2'
}, _slides.default)),
rules: null
}];
const state = Object.freeze(_states.stateBeforeGettingNextContent);
// $FlowFixMe
const action = (0, _computeNextStep.computeNextStep)(config, state, availableContenta, {
type: 'answer',
payload: {
answer: [],
content: {
ref: '1.A1.2',
type: 'slide'
},
godMode: false,
isCorrect: true
}
});
// $FlowFixMe
t.deepEqual(action.nextContent, {
type: 'success',
ref: 'successExitNode'
});
});
(0, _ava.default)('should return a success ExitNode if there is no available content with any empty chapters', t => {
const availableContenta = [{
ref: '1.A1',
slides: (0, _concat2.default)((0, _filter2.default)({
_id: '1.A1.1'
}, _slides.default), (0, _filter2.default)({
_id: '1.A1.2'
}, _slides.default)),
rules: null
}, {
ref: '2.A1',
slides: [],
rules: null
}, {
ref: '3.A1',
slides: [],
rules: null
}];
const state = Object.freeze(_states.stateBeforeGettingNextContent);
// $FlowFixMe
const action = (0, _computeNextStep.computeNextStep)(config, state, availableContenta, {
type: 'answer',
payload: {
answer: [],
content: {
ref: '1.A1.2',
type: 'slide'
},
godMode: false,
isCorrect: true
}
});
// $FlowFixMe
t.deepEqual(action.nextContent, {
type: 'success',
ref: 'successExitNode'
});
});
(0, _ava.default)('should return next slide if there is no available content in current chapter', t => {
const availableContenta = [{
ref: '1.A1',
slides: (0, _concat2.default)((0, _filter2.default)({
_id: '1.A1.1'
}, _slides.default), (0, _filter2.default)({
_id: '1.A1.2'
}, _slides.default)),
rules: null
}, {
ref: '2.A1',
slides: (0, _filter2.default)({
chapter_id: '2.A1'
}, _slides.default),
rules: null
}];
const state = Object.freeze(_states.stateBeforeGettingNextContent);
// $FlowFixMe
const action = (0, _computeNextStep.computeNextStep)(config, state, availableContenta, {
type: 'answer',
payload: {
answer: [],
content: {
ref: '1.A1.2',
type: 'slide'
},
godMode: false,
isCorrect: true
}
});
// $FlowFixMe
t.regex(action.nextContent.ref, /^2\.A1\.[1-9]+$/);
});
(0, _ava.default)('should return next slide if there is available content in current chapter', t => {
const availableContentbb = [{
ref: '1.A1',
slides: [...(0, _filter2.default)({
_id: '1.A1.1'
}, _slides.default), ...(0, _filter2.default)({
_id: '1.A1.2'
}, _slides.default), ...(0, _filter2.default)({
_id: '1.A1.3'
}, _slides.default), ...(0, _filter2.default)({
_id: '1.A1.4'
}, _slides.default)],
rules: null
}];
const state = Object.freeze(_states.lastStepProgressionState);
// $FlowFixMe
const action = (0, _computeNextStep.computeNextStep)(config, state, availableContentbb, {
type: 'answer',
payload: {
answer: [],
content: {
ref: '1.A1.3',
type: 'slide'
},
godMode: false,
isCorrect: true
}
});
// $FlowFixMe
t.is(action.nextContent.ref, '1.A1.4');
});
(0, _ava.default)('should return null if there is no available content', t => {
const state = Object.freeze(_states.stateBeforeGettingNextContent);
// $FlowFixMe
const action = (0, _computeNextStep.computeNextStep)(config, state, availableContent, {
type: 'foo'
});
// $FlowFixMe
t.regex(action.nextContent.ref, /^1\.A1\.[1-9]+$/);
});
(0, _ava.default)('nextSlidePool --> should handle next chapter when no present within availableContent', t => {
const state = Object.freeze({
nextContent: {
ref: '1.A2',
type: 'chapter'
},
lives: 1,
livesDisabled: false,
stars: 0,
slides: [],
requestedClues: [],
viewedResources: [],
step: {
current: 0
},
isCorrect: null,
remainingLifeRequests: 1,
hasViewedAResourceAtThisStep: false,
allAnswers: [],
variables: {},
pendingSlides: []
});
const result = (0, _computeNextStep.nextSlidePool)(config, availableContent, state);
t.deepEqual(result, {
currentChapterContent: null,
nextChapterContent: null,
temporaryNextContent: {
type: 'slide',
ref: ''
}
});
});
(0, _ava.default)('prepareStateToSwitchChapters --> should return null when state is null', t => {
// $FlowFixMe
t.is((0, _computeNextStep.prepareStateToSwitchChapters)({}, null), null);
});
(0, _ava.default)('computeNextStepForNewChapter --> should return null when computeNextStep returns null', t => {
const state = Object.freeze({
nextContent: {
ref: '1.A2',
type: 'chapter'
},
lives: 1,
livesDisabled: false,
stars: 0,
slides: [],
requestedClues: [],
viewedResources: [],
step: {
current: 0
},
isCorrect: null,
remainingLifeRequests: 1,
hasViewedAResourceAtThisStep: false,
allAnswers: [],
variables: {},
pendingSlides: []
});
const chapterRule = {
source: {
type: 'slide',
ref: '1.A1.7'
},
destination: {
type: 'chapter',
ref: '2.A1'
},
instructions: [{
field: 'bar',
type: 'set',
value: 'I was in 1.A1.7'
}],
conditions: [],
priority: 10
};
const result = (0, _computeNextStep.computeNextStepForNewChapter)(config, state, chapterRule, false, availableContent);
t.is(result, null);
});
(0, _ava.default)('computeNextStepForReview --> should return the next slide for an init state', t => {
const _config = (0, _config2.getConfig)({
ref: 'review',
version: '1'
});
const _availableContent = [{
ref: 'skill_ref',
slides: [_slides.default[3],
// _id: '1.A1.5'
_slides.default[4] // _id: '1.A1.4'
],
rules: null
}];
const result = (0, _computeNextStep.computeNextStepForReview)(_config, null, _availableContent, null);
t.deepEqual(result, {
nextContent: {
type: 'slide',
ref: '1.A1.5'
},
instructions: null,
isCorrect: false
});
});
(0, _ava.default)('computeNextStepForReview --> should return the next slide', t => {
const state = Object.freeze({
livesDisabled: true,
isCorrect: false,
slides: ['1.A1.1', '1.A1.2'],
lives: 0,
step: {
current: 3
},
stars: 0,
requestedClues: [],
viewedResources: [],
remainingLifeRequests: 0,
hasViewedAResourceAtThisStep: false,
content: {
ref: '1.A1.2',
type: 'slide'
},
nextContent: {
ref: '1.A1.3',
type: 'slide'
},
allAnswers: [{
slideRef: '1.A1.1',
isCorrect: true,
answer: ['d']
}, {
slideRef: '1.A1.2',
isCorrect: true,
answer: ['d']
}],
pendingSlides: [],
variables: {}
});
const _config = (0, _config2.getConfig)({
ref: 'review',
version: '1'
});
const _availableContent = [{
ref: 'skill_ref',
slides: [_slides.default[3],
// _id: '1.A1.5'
_slides.default[4] // _id: '1.A1.4'
],
rules: null
}];
const result = (0, _computeNextStep.computeNextStepForReview)(_config, state, _availableContent, {
type: 'answer',
payload: {
answer: ['answer'],
content: {
ref: '1.A1.3',
type: 'slide'
},
godMode: false,
isCorrect: false
}
});
t.deepEqual(result, {
nextContent: {
type: 'slide',
ref: '1.A1.5'
},
instructions: null,
isCorrect: false
});
});
(0, _ava.default)('computeNextStepForReview --> should return the same slide if you fail the last question', t => {
const state = Object.freeze({
livesDisabled: true,
isCorrect: true,
slides: ['1.A1.1', '1.A1.2', '1.A1.3', '1.A1.4'],
lives: 0,
step: {
current: 5
},
stars: 32,
requestedClues: [],
viewedResources: [],
remainingLifeRequests: 0,
hasViewedAResourceAtThisStep: false,
content: {
ref: '1.A1.4',
type: 'slide'
},
nextContent: {
ref: '1.A1.5',
type: 'slide'
},
allAnswers: [{
slideRef: '1.A1.1',
isCorrect: true,
answer: ['d']
}, {
slideRef: '1.A1.2',
isCorrect: true,
answer: ['d']
}, {
slideRef: '1.A1.3',
isCorrect: true,
answer: ['d']
}, {
slideRef: '1.A1.4',
isCorrect: true,
answer: ['d']
}],
pendingSlides: [],
variables: {}
});
const _config = (0, _config2.getConfig)({
ref: 'review',
version: '1'
});
const _availableContent = [{
ref: 'skill_ref',
slides: [],
rules: null
}];
const result = (0, _computeNextStep.computeNextStepForReview)(_config, state, _availableContent, {
type: 'answer',
payload: {
answer: ['answer'],
content: {
ref: '1.A1.5',
type: 'slide'
},
godMode: false,
isCorrect: false
}
});
t.deepEqual(result, {
nextContent: {
type: 'slide',
ref: '1.A1.5'
},
instructions: null,
isCorrect: false
});
});
(0, _ava.default)('computeNextStepForReview --> should avoid to return the already answered slide if there are lag on review lambda and available content are not updated', t => {
const state = Object.freeze({
livesDisabled: true,
isCorrect: false,
slides: ['1.A1.1', '1.A1.2'],
lives: 0,
step: {
current: 3
},
stars: 0,
requestedClues: [],
viewedResources: [],
remainingLifeRequests: 0,
hasViewedAResourceAtThisStep: false,
content: {
ref: '1.A1.2',
type: 'slide'
},
nextContent: {
ref: '1.A1.3',
type: 'slide'
},
allAnswers: [{
slideRef: '1.A1.1',
isCorrect: true,
answer: ['d']
}, {
slideRef: '1.A1.2',
isCorrect: true,
answer: ['d']
}],
pendingSlides: [],
variables: {}
});
const _config = (0, _config2.getConfig)({
ref: 'review',
version: '1'
});
const _availableContent = [{
ref: 'skill_ref',
slides: [_slides.default[1],
// _id: '1.A1.2'
_slides.default[2],
// _id: '1.A1.3'
_slides.default[3],
// _id: '1.A1.5'
_slides.default[4] // _id: '1.A1.4'
],
rules: null
}];
const result = (0, _computeNextStep.computeNextStepForReview)(_config, state, _availableContent, {
type: 'answer',
payload: {
answer: ['answer'],
content: {
ref: '1.A1.3',
type: 'slide'
},
godMode: false,
isCorrect: false
}
});
t.deepEqual(result, {
nextContent: {
type: 'slide',
ref: '1.A1.5'
},
instructions: null,
isCorrect: false
});
});
//# sourceMappingURL=compute-next-step.js.map