feat: add check to sanitize answer ranges (#298)
This commit is contained in:
@@ -38,6 +38,9 @@ class ReactStateOLXParser {
|
||||
addHints() {
|
||||
const hintsArray = [];
|
||||
const { hints } = this.editorObject;
|
||||
if (hints.length < 1) {
|
||||
return {};
|
||||
}
|
||||
hints.forEach(hint => {
|
||||
if (hint.length > 0) {
|
||||
const parsedHint = this.parser.parse(hint);
|
||||
@@ -312,6 +315,44 @@ class ReactStateOLXParser {
|
||||
answers.forEach((answer) => {
|
||||
const correcthint = this.getAnswerHints(selectedFeedback?.[answer.id]);
|
||||
if (this.hasAttributeWithValue(answer, 'title')) {
|
||||
let { title } = answer;
|
||||
if (title.startsWith('(') || title.startsWith('[')) {
|
||||
const parsedRange = title.split(',');
|
||||
const [rawLowerBound, rawUpperBound] = parsedRange;
|
||||
let lowerBoundInt;
|
||||
let lowerBoundFraction;
|
||||
let upperBoundInt;
|
||||
let upperBoundFraction;
|
||||
if (rawLowerBound.includes('/')) {
|
||||
lowerBoundFraction = rawLowerBound.replace(/[^0-9-/]/gm, '');
|
||||
const [numerator, denominator] = lowerBoundFraction.split('/');
|
||||
const lowerBoundFloat = Number(numerator) / Number(denominator);
|
||||
lowerBoundInt = lowerBoundFloat;
|
||||
} else {
|
||||
// these regex replaces remove everything that is not a decimal or positive/negative numer
|
||||
lowerBoundInt = Number(rawLowerBound.replace(/[^0-9-.]/gm, ''));
|
||||
}
|
||||
if (rawUpperBound.includes('/')) {
|
||||
upperBoundFraction = rawUpperBound.replace(/[^0-9-/]/gm, '');
|
||||
const [numerator, denominator] = upperBoundFraction.split('/');
|
||||
const upperBoundFloat = Number(numerator) / Number(denominator);
|
||||
upperBoundInt = upperBoundFloat;
|
||||
} else {
|
||||
// these regex replaces remove everything that is not a decimal or positive/negative numer
|
||||
upperBoundInt = Number(rawUpperBound.replace(/[^0-9-.]/gm, ''));
|
||||
}
|
||||
if (lowerBoundInt > upperBoundInt) {
|
||||
const lowerBoundChar = rawUpperBound[rawUpperBound.length - 1] === ']' ? '[' : '(';
|
||||
const upperBoundChar = rawLowerBound[0] === '[' ? ']' : ')';
|
||||
if (lowerBoundFraction) {
|
||||
lowerBoundInt = lowerBoundFraction;
|
||||
}
|
||||
if (upperBoundFraction) {
|
||||
upperBoundInt = upperBoundFraction;
|
||||
}
|
||||
title = `${lowerBoundChar}${upperBoundInt},${lowerBoundInt}${upperBoundChar}`;
|
||||
}
|
||||
}
|
||||
if (answer.correct && !firstCorrectAnswerParsed) {
|
||||
firstCorrectAnswerParsed = true;
|
||||
let responseParam = {};
|
||||
@@ -324,13 +365,13 @@ class ReactStateOLXParser {
|
||||
};
|
||||
}
|
||||
answerObject = {
|
||||
'@_answer': answer.title,
|
||||
'@_answer': title,
|
||||
...responseParam,
|
||||
...correcthint,
|
||||
};
|
||||
} else if (answer.correct && firstCorrectAnswerParsed) {
|
||||
additionalAnswers.push({
|
||||
'@_answer': answer.title,
|
||||
'@_answer': title,
|
||||
...correcthint,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
checkboxesOLXWithFeedbackAndHintsOLX,
|
||||
dropdownOLXWithFeedbackAndHintsOLX,
|
||||
numericInputWithFeedbackAndHintsOLX,
|
||||
numericInputWithAnswerRangeOLX,
|
||||
textInputWithFeedbackAndHintsOLX,
|
||||
multipleChoiceWithFeedbackAndHintsOLX,
|
||||
textInputWithFeedbackAndHintsOLXWithMultipleAnswers,
|
||||
@@ -13,6 +14,7 @@ import {
|
||||
textInputWithFeedbackAndHints,
|
||||
multipleChoiceWithFeedbackAndHints,
|
||||
numericInputWithFeedbackAndHints,
|
||||
numericInputWithAnswerRange,
|
||||
textInputWithFeedbackAndHintsWithMultipleAnswers,
|
||||
} from './mockData/editorTestData';
|
||||
import ReactStateOLXParser from './ReactStateOLXParser';
|
||||
@@ -68,6 +70,17 @@ describe('Check React Sate OLXParser problem', () => {
|
||||
const buildOLX = stateParser.buildOLX();
|
||||
expect(buildOLX.replace(/\s/g, '')).toEqual(numericInputWithFeedbackAndHintsOLX.buildOLX.replace(/\s/g, ''));
|
||||
});
|
||||
|
||||
test('Test numerical response with isAnswerRange true', () => {
|
||||
const olxparser = new OLXParser(numericInputWithAnswerRangeOLX.rawOLX);
|
||||
const problem = olxparser.getParsedOLXData();
|
||||
const stateParser = new ReactStateOLXParser({
|
||||
problem,
|
||||
editorObject: numericInputWithAnswerRange,
|
||||
});
|
||||
const buildOLX = stateParser.buildOLX();
|
||||
expect(buildOLX.replace(/\s/g, '')).toEqual(numericInputWithAnswerRangeOLX.buildOLX.replace(/\s/g, ''));
|
||||
});
|
||||
test('Test string response with feedback and hints, multiple answers', () => {
|
||||
const olxparser = new OLXParser(textInputWithFeedbackAndHintsOLXWithMultipleAnswers.rawOLX);
|
||||
const problem = olxparser.getParsedOLXData();
|
||||
|
||||
@@ -82,6 +82,12 @@ export const numericInputWithFeedbackAndHints = {
|
||||
question: '<p>You can use this template as a guide to the simple editor markdown and OLX markup to use for numerical input with hints and feedback problems. Edit this component to replace this template with your own assessment.</p><label>Add the question text, or prompt, here. This text is required.</label><em>You can add an optional tip or note related to the prompt like this.</em>',
|
||||
};
|
||||
|
||||
export const numericInputWithAnswerRange = {
|
||||
solution: '',
|
||||
hints: [],
|
||||
question: '<p>You can use this template as a guide to the simple editor markdown and OLX markup to use for numerical input with hints and feedback problems. Edit this component to replace this template with your own assessment.</p><label>Add the question text, or prompt, here. This text is required.</label><em>You can add an optional tip or note related to the prompt like this.</em>',
|
||||
};
|
||||
|
||||
export const textInputWithFeedbackAndHints = {
|
||||
solution: '',
|
||||
selectedFeedback: {
|
||||
|
||||
@@ -384,6 +384,38 @@ export const numericInputWithFeedbackAndHintsOLX = {
|
||||
`,
|
||||
};
|
||||
|
||||
export const numericInputWithAnswerRangeOLX = {
|
||||
rawOLX: `<problem>
|
||||
<numericalresponse answer="[3/2,-1.3)">
|
||||
<p>You can use this template as a guide to the simple editor markdown and OLX markup to use for numerical input with hints and feedback problems. Edit this component to replace this template with your own assessment.</p>
|
||||
<label>Add the question text, or prompt, here. This text is required.</label>
|
||||
<description>You can add an optional tip or note related to the prompt like this. </description>
|
||||
<formulaequationinput/>\
|
||||
</numericalresponse>
|
||||
</problem>`,
|
||||
data: {
|
||||
answers: [
|
||||
{
|
||||
id: 'A',
|
||||
title: '[32,-1.3)',
|
||||
correct: true,
|
||||
selectedFeedback: '<p>You can specify optional feedback like this, which appears after this answer is submitted.</p>',
|
||||
isAnswerRange: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
question: '<p>You can use this template as a guide to the simple editor markdown and OLX markup to use for numerical input with hints and feedback problems. Edit this component to replace this template with your own assessment.</p><label>Add the question text, or prompt, here. This text is required.</label><em>You can add an optional tip or note related to the prompt like this.</em>',
|
||||
buildOLX: `<problem>
|
||||
<p>You can use this template as a guide to the simple editor markdown and OLX markup to use for numerical input with hints and feedback problems. Edit this component to replace this template with your own assessment.</p>
|
||||
<label>Add the question text, or prompt, here. This text is required.</label>
|
||||
<em>You can add an optional tip or note related to the prompt like this.</em>
|
||||
<numericalresponse answer="(-1.3,3/2]">
|
||||
<formulaequationinput></formulaequationinput>
|
||||
</numericalresponse>
|
||||
</problem>
|
||||
`,
|
||||
};
|
||||
|
||||
export const textInputWithFeedbackAndHintsOLX = {
|
||||
rawOLX: `<problem>
|
||||
<stringresponse answer="the correct answer" type="ci">
|
||||
|
||||
Reference in New Issue
Block a user