Allowing the creation of ValidationErrors with just error codes, but setting the proper message for debugging

This commit is contained in:
Jonathan Putney
2021-05-27 10:56:17 -04:00
parent fe2e53d858
commit 338d5b107d
10 changed files with 653 additions and 291 deletions

448
dist/scorm-again.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -202,7 +202,7 @@ export default class Scorm12API extends BaseAPI {
* Returns the message that corresponds to errorNumber.
*
* @param {*} errorNumber
* @param {boolean }detail
* @param {boolean} detail
* @return {string}
*/
getLmsErrorMessageDetails(errorNumber, detail) {
@@ -278,8 +278,7 @@ export default class Scorm12API extends BaseAPI {
if (this.settings.mastery_override &&
this.cmi.student_data.mastery_score !== '' &&
this.cmi.core.score.raw !== '') {
if (parseFloat(this.cmi.core.score.raw) >=
parseFloat(this.cmi.student_data.mastery_score)) {
if (parseFloat(this.cmi.core.score.raw) >= parseFloat(this.cmi.student_data.mastery_score)) {
this.cmi.core.lesson_status = 'passed';
} else {
this.cmi.core.lesson_status = 'failed';
@@ -287,8 +286,7 @@ export default class Scorm12API extends BaseAPI {
}
}
} else if (this.cmi.core.lesson_mode === 'browse') {
if ((this.startingData?.cmi?.core?.lesson_status || '') === '' &&
originalStatus === 'not attempted') {
if ((this.startingData?.cmi?.core?.lesson_status || '') === '' && originalStatus === 'not attempted') {
this.cmi.core.lesson_status = 'browsed';
}
}
@@ -299,15 +297,13 @@ export default class Scorm12API extends BaseAPI {
if (this.settings.lmsCommitUrl) {
if (this.apiLogLevel === global_constants.LOG_LEVEL_DEBUG) {
console.debug('Commit (terminated: ' +
(terminateCommit ? 'yes' : 'no') + '): ');
console.debug('Commit (terminated: ' + (terminateCommit ? 'yes' : 'no') + '): ');
console.debug(commitObject);
}
return this.processHttpRequest(this.settings.lmsCommitUrl, commitObject,
terminateCommit);
} else {
console.log('Commit (terminated: ' +
(terminateCommit ? 'yes' : 'no') + '): ');
console.log('Commit (terminated: ' + (terminateCommit ? 'yes' : 'no') + '): ');
console.log(commitObject);
return global_constants.SCORM_TRUE;
}

View File

@@ -1,17 +1,40 @@
import * as Scorm12CMI from './scorm12_cmi';
import {BaseCMI, CMIArray, CMIScore} from './common';
import {BaseCMI, checkValidFormat, CMIArray, CMIScore} from './common';
import APIConstants from '../constants/api_constants';
import Regex from '../constants/regex';
import ErrorCodes from '../constants/error_codes';
import {
check12ValidFormat,
throwReadOnlyError,
} from './scorm12_cmi';
import {AICCValidationError} from '../exceptions';
const aicc_constants = APIConstants.aicc;
const scorm12_constants = APIConstants.scorm12;
const aicc_regex = Regex.aicc;
const scorm12_error_codes = ErrorCodes.scorm12;
const aicc_error_codes = ErrorCodes.scorm12;
/**
* Helper method for throwing Read Only error
*/
function throwReadOnlyError() {
throw new AICCValidationError(aicc_error_codes.READ_ONLY_ELEMENT);
}
/**
* Helper method, no reason to have to pass the same error codes every time
* @param {*} value
* @param {string} regexPattern
* @param {boolean} allowEmptyString
* @return {boolean}
*/
function checkAICCValidFormat(
value: String,
regexPattern: String,
allowEmptyString?: boolean) {
return checkValidFormat(
value,
regexPattern,
aicc_error_codes.TYPE_MISMATCH,
AICCValidationError,
allowEmptyString
);
}
/**
* CMI Class for AICC
@@ -129,8 +152,8 @@ class CMIEvaluationComments extends CMIArray {
constructor() {
super({
children: aicc_constants.comments_children,
errorCode: scorm12_error_codes.INVALID_SET_VALUE,
errorMessage: scorm12_constants.error_descriptions[scorm12_error_codes.INVALID_SET_VALUE].detailMessage,
errorCode: aicc_error_codes.INVALID_SET_VALUE,
errorClass: AICCValidationError,
});
}
}
@@ -146,8 +169,8 @@ class AICCStudentPreferences extends Scorm12CMI.CMIStudentPreference {
super(aicc_constants.student_preference_children);
this.windows = new CMIArray({
errorCode: scorm12_error_codes.INVALID_SET_VALUE,
errorMessage: scorm12_constants.error_descriptions[scorm12_error_codes.INVALID_SET_VALUE].detailMessage,
errorCode: aicc_error_codes.INVALID_SET_VALUE,
errorClass: AICCValidationError,
children: '',
});
}
@@ -179,7 +202,7 @@ class AICCStudentPreferences extends Scorm12CMI.CMIStudentPreference {
* @param {string} lesson_type
*/
set lesson_type(lesson_type: string) {
if (check12ValidFormat(lesson_type, aicc_regex.CMIString256)) {
if (checkAICCValidFormat(lesson_type, aicc_regex.CMIString256)) {
this.#lesson_type = lesson_type;
}
}
@@ -197,7 +220,7 @@ class AICCStudentPreferences extends Scorm12CMI.CMIStudentPreference {
* @param {string} text_color
*/
set text_color(text_color: string) {
if (check12ValidFormat(text_color, aicc_regex.CMIString256)) {
if (checkAICCValidFormat(text_color, aicc_regex.CMIString256)) {
this.#text_color = text_color;
}
}
@@ -215,7 +238,7 @@ class AICCStudentPreferences extends Scorm12CMI.CMIStudentPreference {
* @param {string} text_location
*/
set text_location(text_location: string) {
if (check12ValidFormat(text_location, aicc_regex.CMIString256)) {
if (checkAICCValidFormat(text_location, aicc_regex.CMIString256)) {
this.#text_location = text_location;
}
}
@@ -233,7 +256,7 @@ class AICCStudentPreferences extends Scorm12CMI.CMIStudentPreference {
* @param {string} text_size
*/
set text_size(text_size: string) {
if (check12ValidFormat(text_size, aicc_regex.CMIString256)) {
if (checkAICCValidFormat(text_size, aicc_regex.CMIString256)) {
this.#text_size = text_size;
}
}
@@ -251,7 +274,7 @@ class AICCStudentPreferences extends Scorm12CMI.CMIStudentPreference {
* @param {string} video
*/
set video(video: string) {
if (check12ValidFormat(video, aicc_regex.CMIString256)) {
if (checkAICCValidFormat(video, aicc_regex.CMIString256)) {
this.#video = video;
}
}
@@ -379,6 +402,14 @@ export class CMIStudentDemographics extends BaseCMI {
#telephone = '';
#years_experience = '';
/**
* Getter for _children
* @return {string}
*/
get _children() {
return this.#_children;
}
/**
* Getter for city
* @return {string}
@@ -711,7 +742,7 @@ export class CMIPathsObject extends BaseCMI {
* @param {string} location_id
*/
set location_id(location_id) {
if (check12ValidFormat(location_id, aicc_regex.CMIString256)) {
if (checkAICCValidFormat(location_id, aicc_regex.CMIString256)) {
this.#location_id = location_id;
}
}
@@ -729,7 +760,7 @@ export class CMIPathsObject extends BaseCMI {
* @param {string} date
*/
set date(date) {
if (check12ValidFormat(date, aicc_regex.CMIString256)) {
if (checkAICCValidFormat(date, aicc_regex.CMIString256)) {
this.#date = date;
}
}
@@ -747,7 +778,7 @@ export class CMIPathsObject extends BaseCMI {
* @param {string} time
*/
set time(time) {
if (check12ValidFormat(time, aicc_regex.CMITime)) {
if (checkAICCValidFormat(time, aicc_regex.CMITime)) {
this.#time = time;
}
}
@@ -765,7 +796,7 @@ export class CMIPathsObject extends BaseCMI {
* @param {string} status
*/
set status(status) {
if (check12ValidFormat(status, aicc_regex.CMIStatus2)) {
if (checkAICCValidFormat(status, aicc_regex.CMIStatus2)) {
this.#status = status;
}
}
@@ -783,7 +814,7 @@ export class CMIPathsObject extends BaseCMI {
* @param {string} why_left
*/
set why_left(why_left) {
if (check12ValidFormat(why_left, aicc_regex.CMIString256)) {
if (checkAICCValidFormat(why_left, aicc_regex.CMIString256)) {
this.#why_left = why_left;
}
}
@@ -801,7 +832,7 @@ export class CMIPathsObject extends BaseCMI {
* @param {string} time_in_element
*/
set time_in_element(time_in_element) {
if (check12ValidFormat(time_in_element, aicc_regex.CMITime)) {
if (checkAICCValidFormat(time_in_element, aicc_regex.CMITime)) {
this.#time_in_element = time_in_element;
}
}
@@ -860,12 +891,10 @@ export class CMITriesObject extends BaseCMI {
{
score_children: aicc_constants.score_children,
score_range: aicc_regex.score_range,
invalidErrorCode: scorm12_error_codes.INVALID_SET_VALUE,
invalidErrorMessage: scorm12_constants.error_descriptions[scorm12_error_codes.INVALID_SET_VALUE].detailMessage,
invalidTypeCode: scorm12_error_codes.TYPE_MISMATCH,
invalidTypeMessage: scorm12_constants.error_descriptions[scorm12_error_codes.TYPE_MISMATCH].detailMessage,
invalidRangeCode: scorm12_error_codes.VALUE_OUT_OF_RANGE,
invalidRangeMessage: scorm12_constants.error_descriptions[scorm12_error_codes.VALUE_OUT_OF_RANGE].detailMessage,
invalidErrorCode: aicc_error_codes.INVALID_SET_VALUE,
invalidTypeCode: aicc_error_codes.TYPE_MISMATCH,
invalidRangeCode: aicc_error_codes.VALUE_OUT_OF_RANGE,
errorClass: AICCValidationError,
});
}
@@ -893,7 +922,7 @@ export class CMITriesObject extends BaseCMI {
* @param {string} status
*/
set status(status) {
if (check12ValidFormat(status, aicc_regex.CMIStatus2)) {
if (checkAICCValidFormat(status, aicc_regex.CMIStatus2)) {
this.#status = status;
}
}
@@ -911,7 +940,7 @@ export class CMITriesObject extends BaseCMI {
* @param {string} time
*/
set time(time) {
if (check12ValidFormat(time, aicc_regex.CMITime)) {
if (checkAICCValidFormat(time, aicc_regex.CMITime)) {
this.#time = time;
}
}
@@ -964,12 +993,10 @@ export class CMIAttemptRecordsObject extends BaseCMI {
{
score_children: aicc_constants.score_children,
score_range: aicc_regex.score_range,
invalidErrorCode: scorm12_error_codes.INVALID_SET_VALUE,
invalidErrorMessage: scorm12_constants.error_descriptions[scorm12_error_codes.INVALID_SET_VALUE].detailMessage,
invalidTypeCode: scorm12_error_codes.TYPE_MISMATCH,
invalidTypeMessage: scorm12_constants.error_descriptions[scorm12_error_codes.TYPE_MISMATCH].detailMessage,
invalidRangeCode: scorm12_error_codes.VALUE_OUT_OF_RANGE,
invalidRangeMessage: scorm12_constants.error_descriptions[scorm12_error_codes.VALUE_OUT_OF_RANGE].detailMessage,
invalidErrorCode: aicc_error_codes.INVALID_SET_VALUE,
invalidTypeCode: aicc_error_codes.TYPE_MISMATCH,
invalidRangeCode: aicc_error_codes.VALUE_OUT_OF_RANGE,
errorClass: AICCValidationError,
});
}
@@ -996,7 +1023,7 @@ export class CMIAttemptRecordsObject extends BaseCMI {
* @param {string} lesson_status
*/
set lesson_status(lesson_status) {
if (check12ValidFormat(lesson_status, aicc_regex.CMIStatus2)) {
if (checkAICCValidFormat(lesson_status, aicc_regex.CMIStatus2)) {
this.#lesson_status = lesson_status;
}
}
@@ -1050,7 +1077,7 @@ export class CMIEvaluationCommentsObject extends BaseCMI {
* @param {string} content
*/
set content(content) {
if (check12ValidFormat(content, aicc_regex.CMIString256)) {
if (checkAICCValidFormat(content, aicc_regex.CMIString256)) {
this.#content = content;
}
}
@@ -1068,7 +1095,7 @@ export class CMIEvaluationCommentsObject extends BaseCMI {
* @param {string} location
*/
set location(location) {
if (check12ValidFormat(location, aicc_regex.CMIString256)) {
if (checkAICCValidFormat(location, aicc_regex.CMIString256)) {
this.#location = location;
}
}
@@ -1086,7 +1113,7 @@ export class CMIEvaluationCommentsObject extends BaseCMI {
* @param {string} time
*/
set time(time) {
if (check12ValidFormat(time, aicc_regex.CMITime)) {
if (checkAICCValidFormat(time, aicc_regex.CMITime)) {
this.#time = time;
}
}

View File

@@ -1,7 +1,6 @@
// @flow
import APIConstants from '../constants/api_constants';
import ErrorCodes from '../constants/error_codes';
import {ValidationError} from '../exceptions';
import Regex from '../constants/regex';
const scorm12_constants = APIConstants.scorm12;
@@ -14,7 +13,7 @@ const scorm12_error_codes = ErrorCodes.scorm12;
* @param {string} value
* @param {string} regexPattern
* @param {number} errorCode
* @param {string} errorMessage
* @param {class} errorClass
* @param {boolean} allowEmptyString
* @return {boolean}
*/
@@ -22,7 +21,7 @@ export function checkValidFormat(
value: String,
regexPattern: String,
errorCode: number,
errorMessage: String,
errorClass: function,
allowEmptyString?: boolean) {
const formatRegex = new RegExp(regexPattern);
const matches = value.match(formatRegex);
@@ -30,7 +29,7 @@ export function checkValidFormat(
return true;
}
if (value === undefined || !matches || matches[0] === '') {
throw new ValidationError(errorCode, errorMessage);
throw new errorClass.prototype.constructor(errorCode);
}
return true;
}
@@ -41,21 +40,24 @@ export function checkValidFormat(
* @param {*} value
* @param {string} rangePattern
* @param {number} errorCode
* @param {string} errorMessage
* @param {class} errorClass
* @return {boolean}
*/
export function checkValidRange(
value: any, rangePattern: String, errorCode: number, errorMessage: String) {
value: any,
rangePattern: String,
errorCode: number,
errorClass: function) {
const ranges = rangePattern.split('#');
value = value * 1.0;
if (value >= ranges[0]) {
if ((ranges[1] === '*') || (value <= ranges[1])) {
return true;
} else {
throw new ValidationError(errorCode, errorMessage);
throw new errorClass.prototype.constructor(errorCode);
}
} else {
throw new ValidationError(errorCode, errorMessage);
throw new errorClass.prototype.constructor(errorCode);
}
}
@@ -118,12 +120,10 @@ export class CMIScore extends BaseCMI {
* @param {string} score_range
* @param {string} max
* @param {number} invalidErrorCode
* @param {string} invalidErrorMessage
* @param {number} invalidTypeCode
* @param {string} invalidTypeMessage
* @param {number} invalidRangeCode
* @param {string} invalidRangeMessage
* @param {string} decimalRegex
* @param {class} errorClass
*/
constructor(
{
@@ -131,12 +131,10 @@ export class CMIScore extends BaseCMI {
score_range,
max,
invalidErrorCode,
invalidErrorMessage,
invalidTypeCode,
invalidTypeMessage,
invalidRangeCode,
invalidRangeMessage,
decimalRegex,
errorClass,
}) {
super();
@@ -146,29 +144,22 @@ export class CMIScore extends BaseCMI {
this.#max = (max || max === '') ? max : '100';
this.#_invalid_error_code = invalidErrorCode ||
scorm12_error_codes.INVALID_SET_VALUE;
this.#_invalid_error_message = invalidErrorMessage ||
scorm12_constants.error_descriptions[scorm12_error_codes.INVALID_SET_VALUE].detailMessage;
this.#_invalid_type_code = invalidTypeCode ||
scorm12_error_codes.TYPE_MISMATCH;
this.#_invalid_type_message = invalidTypeMessage ||
scorm12_constants.error_descriptions[scorm12_error_codes.TYPE_MISMATCH].detailMessage;
this.#_invalid_range_code = invalidRangeCode ||
scorm12_error_codes.VALUE_OUT_OF_RANGE;
this.#_invalid_range_message = invalidRangeMessage ||
scorm12_constants.error_descriptions[scorm12_error_codes.VALUE_OUT_OF_RANGE].detailMessage;
this.#_decimal_regex = decimalRegex ||
scorm12_regex.CMIDecimal;
this.#_error_class = errorClass;
}
#_children;
#_score_range;
#_invalid_error_code;
#_invalid_error_message;
#_invalid_type_code;
#_invalid_type_message;
#_invalid_range_code;
#_invalid_range_message;
#_decimal_regex;
#_error_class;
#raw = '';
#min = '';
#max;
@@ -188,7 +179,7 @@ export class CMIScore extends BaseCMI {
* @private
*/
set _children(_children) {
throw new ValidationError(this.#_invalid_error_code, this.#_invalid_error_message);
throw new this.#_error_class.prototype.constructor(this.#_invalid_error_code);
}
/**
@@ -204,11 +195,9 @@ export class CMIScore extends BaseCMI {
* @param {string} raw
*/
set raw(raw) {
if (checkValidFormat(raw, this.#_decimal_regex,
this.#_invalid_type_code, this.#_invalid_type_message) &&
if (checkValidFormat(raw, this.#_decimal_regex, this.#_invalid_type_code, this.#_error_class) &&
(!this.#_score_range ||
checkValidRange(raw, this.#_score_range,
this.#_invalid_range_code, this.#_invalid_range_message))) {
checkValidRange(raw, this.#_score_range, this.#_invalid_range_code, this.#_error_class))) {
this.#raw = raw;
}
}
@@ -226,11 +215,9 @@ export class CMIScore extends BaseCMI {
* @param {string} min
*/
set min(min) {
if (checkValidFormat(min, this.#_decimal_regex,
this.#_invalid_type_code, this.#_invalid_type_message) &&
if (checkValidFormat(min, this.#_decimal_regex, this.#_invalid_type_code, this.#_error_class) &&
(!this.#_score_range ||
checkValidRange(min, this.#_score_range,
this.#_invalid_range_code, this.#_invalid_range_message))) {
checkValidRange(min, this.#_score_range, this.#_invalid_range_code, this.#_error_class))) {
this.#min = min;
}
}
@@ -248,11 +235,9 @@ export class CMIScore extends BaseCMI {
* @param {string} max
*/
set max(max) {
if (checkValidFormat(max, this.#_decimal_regex,
this.#_invalid_type_code, this.#_invalid_type_message) &&
if (checkValidFormat(max, this.#_decimal_regex, this.#_invalid_type_code, this.#_error_class) &&
(!this.#_score_range ||
checkValidRange(max, this.#_score_range,
this.#_invalid_range_code, this.#_invalid_range_message))) {
checkValidRange(max, this.#_score_range, this.#_invalid_range_code, this.#_error_class))) {
this.#max = max;
}
}
@@ -281,18 +266,18 @@ export class CMIArray extends BaseCMI {
* Constructor cmi *.n arrays
* @param {string} children
* @param {number} errorCode
* @param {string} errorMessage
* @param {class} errorClass
*/
constructor({children, errorCode, errorMessage}) {
constructor({children, errorCode, errorClass}) {
super();
this.#_children = children;
this.#errorCode = errorCode;
this.#errorMessage = errorMessage;
this.#errorClass = errorClass;
this.childArray = [];
}
#errorCode;
#errorMessage;
#errorClass;
#_children;
/**
@@ -308,7 +293,7 @@ export class CMIArray extends BaseCMI {
* @param {string} _children
*/
set _children(_children) {
throw new ValidationError(this.#errorCode, this.#errorMessage);
throw new this.#errorClass.prototype.constructor(this.#errorCode);
}
/**
@@ -324,7 +309,7 @@ export class CMIArray extends BaseCMI {
* @param {number} _count
*/
set _count(_count) {
throw new ValidationError(this.#errorCode, this.#errorMessage);
throw new this.#errorClass.prototype.constructor(this.#errorCode);
}
/**

View File

@@ -9,7 +9,7 @@ import {
import APIConstants from '../constants/api_constants';
import ErrorCodes from '../constants/error_codes';
import Regex from '../constants/regex';
import {ValidationError} from '../exceptions';
import {Scorm12ValidationError} from '../exceptions';
import * as Utilities from '../utilities';
import * as Util from '../utilities';
@@ -21,30 +21,21 @@ const scorm12_error_codes = ErrorCodes.scorm12;
* Helper method for throwing Read Only error
*/
export function throwReadOnlyError() {
throw new ValidationError(
scorm12_error_codes.READ_ONLY_ELEMENT,
scorm12_constants.error_descriptions[scorm12_error_codes.READ_ONLY_ELEMENT].detailMessage
);
throw new Scorm12ValidationError(scorm12_error_codes.READ_ONLY_ELEMENT);
}
/**
* Helper method for throwing Write Only error
*/
export function throwWriteOnlyError() {
throw new ValidationError(
scorm12_error_codes.WRITE_ONLY_ELEMENT,
scorm12_constants.error_descriptions[scorm12_error_codes.WRITE_ONLY_ELEMENT].detailMessage
);
throw new Scorm12ValidationError(scorm12_error_codes.WRITE_ONLY_ELEMENT);
}
/**
* Helper method for throwing Invalid Set error
*/
function throwInvalidValueError() {
throw new ValidationError(
scorm12_error_codes.INVALID_SET_VALUE,
scorm12_constants.error_descriptions[scorm12_error_codes.INVALID_SET_VALUE].detailMessage
);
throw new Scorm12ValidationError(scorm12_error_codes.INVALID_SET_VALUE);
}
/**
@@ -58,10 +49,13 @@ export function check12ValidFormat(
value: String,
regexPattern: String,
allowEmptyString?: boolean) {
return checkValidFormat(value, regexPattern,
return checkValidFormat(
value,
regexPattern,
scorm12_error_codes.TYPE_MISMATCH,
scorm12_constants.error_descriptions[scorm12_error_codes.TYPE_MISMATCH].detailMessage,
allowEmptyString);
Scorm12ValidationError,
allowEmptyString
);
}
/**
@@ -75,10 +69,13 @@ export function check12ValidRange(
value: any,
rangePattern: String,
allowEmptyString?: boolean) {
return checkValidRange(value, rangePattern,
return checkValidRange(
value,
rangePattern,
scorm12_error_codes.VALUE_OUT_OF_RANGE,
scorm12_constants.error_descriptions[scorm12_error_codes.VALUE_OUT_OF_RANGE].detailMessage,
allowEmptyString);
Scorm12ValidationError,
allowEmptyString
);
}
/**
@@ -288,11 +285,9 @@ class CMICore extends BaseCMI {
score_children: scorm12_constants.score_children,
score_range: scorm12_regex.score_range,
invalidErrorCode: scorm12_error_codes.INVALID_SET_VALUE,
invalidErrorMessage: scorm12_constants.error_descriptions[scorm12_error_codes.INVALID_SET_VALUE].detailMessage,
invalidTypeCode: scorm12_error_codes.TYPE_MISMATCH,
invalidTypeMessage: scorm12_constants.error_descriptions[scorm12_error_codes.TYPE_MISMATCH].detailMessage,
invalidRangeCode: scorm12_error_codes.VALUE_OUT_OF_RANGE,
invalidRangeMessage: scorm12_constants.error_descriptions[scorm12_error_codes.VALUE_OUT_OF_RANGE].detailMessage,
errorClass: Scorm12ValidationError,
});
}
@@ -599,7 +594,7 @@ class CMIObjectives extends CMIArray {
super({
children: scorm12_constants.objectives_children,
errorCode: scorm12_error_codes.INVALID_SET_VALUE,
errorMessage: scorm12_constants.error_descriptions[scorm12_error_codes.INVALID_SET_VALUE].detailMessage,
errorClass: Scorm12ValidationError,
});
}
}
@@ -875,7 +870,7 @@ class CMIInteractions extends CMIArray {
super({
children: scorm12_constants.interactions_children,
errorCode: scorm12_error_codes.INVALID_SET_VALUE,
errorMessage: scorm12_constants.error_descriptions[scorm12_error_codes.INVALID_SET_VALUE].detailMessage,
errorClass: Scorm12ValidationError,
});
}
}
@@ -893,12 +888,12 @@ export class CMIInteractionsObject extends BaseCMI {
this.objectives = new CMIArray({
errorCode: scorm12_error_codes.INVALID_SET_VALUE,
errorMessage: scorm12_constants.error_descriptions[scorm12_error_codes.INVALID_SET_VALUE].detailMessage,
errorClass: Scorm12ValidationError,
children: scorm12_constants.objectives_children,
});
this.correct_responses = new CMIArray({
errorCode: scorm12_error_codes.INVALID_SET_VALUE,
errorMessage: scorm12_constants.error_descriptions[scorm12_error_codes.INVALID_SET_VALUE].detailMessage,
errorClass: Scorm12ValidationError,
children: scorm12_constants.correct_responses_children,
});
}
@@ -1100,11 +1095,9 @@ export class CMIObjectivesObject extends BaseCMI {
score_children: scorm12_constants.score_children,
score_range: scorm12_regex.score_range,
invalidErrorCode: scorm12_error_codes.INVALID_SET_VALUE,
invalidErrorMessage: scorm12_constants.error_descriptions[scorm12_error_codes.INVALID_SET_VALUE].detailMessage,
invalidTypeCode: scorm12_error_codes.TYPE_MISMATCH,
invalidTypeMessage: scorm12_constants.error_descriptions[scorm12_error_codes.TYPE_MISMATCH].detailMessage,
invalidRangeCode: scorm12_error_codes.VALUE_OUT_OF_RANGE,
invalidRangeMessage: scorm12_constants.error_descriptions[scorm12_error_codes.VALUE_OUT_OF_RANGE].detailMessage,
errorClass: Scorm12ValidationError,
});
}

View File

@@ -10,7 +10,7 @@ import APIConstants from '../constants/api_constants';
import Regex from '../constants/regex';
import ErrorCodes from '../constants/error_codes';
import Responses from '../constants/response_constants';
import {ValidationError} from '../exceptions';
import {Scorm2004ValidationError} from '../exceptions';
import * as Util from '../utilities';
const scorm2004_constants = APIConstants.scorm2004;
@@ -23,50 +23,35 @@ const scorm2004_regex = Regex.scorm2004;
* Helper method for throwing Read Only error
*/
function throwReadOnlyError() {
throw new ValidationError(
scorm2004_error_codes.READ_ONLY_ELEMENT,
scorm2004_constants.error_descriptions[scorm2004_error_codes.READ_ONLY_ELEMENT].detailMessage
);
throw new Scorm2004ValidationError(scorm2004_error_codes.READ_ONLY_ELEMENT);
}
/**
* Helper method for throwing Write Only error
*/
function throwWriteOnlyError() {
throw new ValidationError(
scorm2004_error_codes.WRITE_ONLY_ELEMENT,
scorm2004_constants.error_descriptions[scorm2004_error_codes.WRITE_ONLY_ELEMENT].detailMessage
);
throw new Scorm2004ValidationError(scorm2004_error_codes.WRITE_ONLY_ELEMENT);
}
/**
* Helper method for throwing Type Mismatch error
*/
function throwTypeMismatchError() {
throw new ValidationError(
scorm2004_error_codes.TYPE_MISMATCH,
scorm2004_constants.error_descriptions[scorm2004_error_codes.TYPE_MISMATCH].detailMessage
);
throw new Scorm2004ValidationError(scorm2004_error_codes.TYPE_MISMATCH);
}
/**
* Helper method for throwing Dependency Not Established error
*/
function throwDependencyNotEstablishedError() {
throw new ValidationError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED,
scorm2004_constants.error_descriptions[scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED].detailMessage
);
throw new Scorm2004ValidationError(scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
}
/**
* Helper method for throwing Dependency Not Established error
*/
function throwGeneralSetError() {
throw new ValidationError(
scorm2004_error_codes.GENERAL_SET_FAILURE,
scorm2004_constants.error_descriptions[scorm2004_error_codes.GENERAL_SET_FAILURE].detailMessage
);
throw new Scorm2004ValidationError(scorm2004_error_codes.GENERAL_SET_FAILURE);
}
/**
@@ -80,10 +65,13 @@ function check2004ValidFormat(
value: String,
regexPattern: String,
allowEmptyString?: boolean) {
return checkValidFormat(value, regexPattern,
return checkValidFormat(
value,
regexPattern,
scorm2004_error_codes.TYPE_MISMATCH,
scorm2004_constants.error_descriptions[scorm2004_error_codes.TYPE_MISMATCH].detailMessage,
allowEmptyString);
Scorm2004ValidationError,
allowEmptyString,
);
}
/**
@@ -93,9 +81,12 @@ function check2004ValidFormat(
* @return {boolean}
*/
function check2004ValidRange(value: any, rangePattern: String) {
return checkValidRange(value, rangePattern,
return checkValidRange(
value,
rangePattern,
scorm2004_error_codes.VALUE_OUT_OF_RANGE,
scorm2004_constants.error_descriptions[scorm2004_error_codes.VALUE_OUT_OF_RANGE].detailMessage);
Scorm2004ValidationError,
);
}
/**
@@ -221,8 +212,8 @@ export class CMI extends BaseCMI {
*/
set completion_threshold(completion_threshold) {
!this.initialized ?
this.#completion_threshold = completion_threshold :
throwReadOnlyError();
this.#completion_threshold = completion_threshold :
throwReadOnlyError();
}
/**
@@ -321,8 +312,8 @@ export class CMI extends BaseCMI {
*/
set learner_name(learner_name) {
!this.initialized ?
this.#learner_name = learner_name :
throwReadOnlyError();
this.#learner_name = learner_name :
throwReadOnlyError();
}
/**
@@ -357,8 +348,8 @@ export class CMI extends BaseCMI {
*/
set max_time_allowed(max_time_allowed) {
!this.initialized ?
this.#max_time_allowed = max_time_allowed :
throwReadOnlyError();
this.#max_time_allowed = max_time_allowed :
throwReadOnlyError();
}
/**
@@ -391,7 +382,7 @@ export class CMI extends BaseCMI {
*/
set progress_measure(progress_measure) {
if (check2004ValidFormat(progress_measure, scorm2004_regex.CMIDecimal) &&
check2004ValidRange(progress_measure, scorm2004_regex.progress_range)) {
check2004ValidRange(progress_measure, scorm2004_regex.progress_range)) {
this.#progress_measure = progress_measure;
}
}
@@ -410,8 +401,8 @@ export class CMI extends BaseCMI {
*/
set scaled_passing_score(scaled_passing_score) {
!this.initialized ?
this.#scaled_passing_score = scaled_passing_score :
throwReadOnlyError();
this.#scaled_passing_score = scaled_passing_score :
throwReadOnlyError();
}
/**
@@ -483,8 +474,8 @@ export class CMI extends BaseCMI {
*/
set time_limit_action(time_limit_action) {
!this.initialized ?
this.#time_limit_action = time_limit_action :
throwReadOnlyError();
this.#time_limit_action = time_limit_action :
throwReadOnlyError();
}
/**
@@ -636,7 +627,7 @@ class CMILearnerPreference extends BaseCMI {
*/
set audio_level(audio_level) {
if (check2004ValidFormat(audio_level, scorm2004_regex.CMIDecimal) &&
check2004ValidRange(audio_level, scorm2004_regex.audio_range)) {
check2004ValidRange(audio_level, scorm2004_regex.audio_range)) {
this.#audio_level = audio_level;
}
}
@@ -673,7 +664,7 @@ class CMILearnerPreference extends BaseCMI {
*/
set delivery_speed(delivery_speed) {
if (check2004ValidFormat(delivery_speed, scorm2004_regex.CMIDecimal) &&
check2004ValidRange(delivery_speed, scorm2004_regex.speed_range)) {
check2004ValidRange(delivery_speed, scorm2004_regex.speed_range)) {
this.#delivery_speed = delivery_speed;
}
}
@@ -692,7 +683,7 @@ class CMILearnerPreference extends BaseCMI {
*/
set audio_captioning(audio_captioning) {
if (check2004ValidFormat(audio_captioning, scorm2004_regex.CMISInteger) &&
check2004ValidRange(audio_captioning, scorm2004_regex.text_range)) {
check2004ValidRange(audio_captioning, scorm2004_regex.text_range)) {
this.#audio_captioning = audio_captioning;
}
}
@@ -733,7 +724,7 @@ class CMIInteractions extends CMIArray {
super({
children: scorm2004_constants.interactions_children,
errorCode: scorm2004_error_codes.READ_ONLY_ELEMENT,
errorMessage: scorm2004_constants.error_descriptions[scorm2004_error_codes.READ_ONLY_ELEMENT].detailMessage,
errorClass: Scorm2004ValidationError,
});
}
}
@@ -749,7 +740,7 @@ class CMIObjectives extends CMIArray {
super({
children: scorm2004_constants.objectives_children,
errorCode: scorm2004_error_codes.READ_ONLY_ELEMENT,
errorMessage: scorm2004_constants.error_descriptions[scorm2004_error_codes.READ_ONLY_ELEMENT].detailMessage,
errorClass: Scorm2004ValidationError,
});
}
}
@@ -765,7 +756,7 @@ class CMICommentsFromLMS extends CMIArray {
super({
children: scorm2004_constants.comments_children,
errorCode: scorm2004_error_codes.READ_ONLY_ELEMENT,
errorMessage: scorm2004_constants.error_descriptions[scorm2004_error_codes.READ_ONLY_ELEMENT].detailMessage,
errorClass: Scorm2004ValidationError,
});
}
}
@@ -781,7 +772,7 @@ class CMICommentsFromLearner extends CMIArray {
super({
children: scorm2004_constants.comments_children,
errorCode: scorm2004_error_codes.READ_ONLY_ELEMENT,
errorMessage: scorm2004_constants.error_descriptions[scorm2004_error_codes.READ_ONLY_ELEMENT].detailMessage,
errorClass: Scorm2004ValidationError,
});
}
}
@@ -807,12 +798,12 @@ export class CMIInteractionsObject extends BaseCMI {
this.objectives = new CMIArray({
errorCode: scorm2004_error_codes.READ_ONLY_ELEMENT,
errorMessage: scorm2004_constants.error_descriptions[scorm2004_error_codes.INVALID_SET_VALUE].detailMessage,
errorClass: Scorm2004ValidationError,
children: scorm2004_constants.objectives_children,
});
this.correct_responses = new CMIArray({
errorCode: scorm2004_error_codes.READ_ONLY_ELEMENT,
errorMessage: scorm2004_constants.error_descriptions[scorm2004_error_codes.INVALID_SET_VALUE].detailMessage,
errorClass: Scorm2004ValidationError,
children: scorm2004_constants.correct_responses_children,
});
}
@@ -1183,8 +1174,8 @@ export class CMIObjectivesObject extends BaseCMI {
throwDependencyNotEstablishedError();
} else {
if (check2004ValidFormat(progress_measure, scorm2004_regex.CMIDecimal) &&
check2004ValidRange(progress_measure,
scorm2004_regex.progress_range)) {
check2004ValidRange(progress_measure,
scorm2004_regex.progress_range)) {
this.#progress_measure = progress_measure;
}
}
@@ -1257,12 +1248,10 @@ class Scorm2004CMIScore extends CMIScore {
score_children: scorm2004_constants.score_children,
max: '',
invalidErrorCode: scorm2004_error_codes.READ_ONLY_ELEMENT,
invalidErrorMessage: scorm2004_constants.error_descriptions[scorm2004_error_codes.READ_ONLY_ELEMENT].detailMessage,
invalidTypeCode: scorm2004_error_codes.TYPE_MISMATCH,
invalidTypeMessage: scorm2004_constants.error_descriptions[scorm2004_error_codes.TYPE_MISMATCH].detailMessage,
invalidRangeCode: scorm2004_error_codes.VALUE_OUT_OF_RANGE,
invalidRangeMessage: scorm2004_constants.error_descriptions[scorm2004_error_codes.VALUE_OUT_OF_RANGE].detailMessage,
decimalRegex: scorm2004_regex.CMIDecimal,
errorClass: Scorm2004ValidationError,
});
}
@@ -1280,7 +1269,7 @@ class Scorm2004CMIScore extends CMIScore {
*/
set scaled(scaled) {
if (check2004ValidFormat(scaled, scorm2004_regex.CMIDecimal) &&
check2004ValidRange(scaled, scorm2004_regex.scaled_range)) {
check2004ValidRange(scaled, scorm2004_regex.scaled_range)) {
this.#scaled = scaled;
}
}

View File

@@ -1,19 +1,31 @@
// @flow
import APIConstants from './constants/api_constants';
const scorm12_errors = APIConstants.scorm12.error_descriptions;
const aicc_errors = APIConstants.aicc.error_descriptions;
const scorm2004_errors = APIConstants.scorm2004.error_descriptions;
/**
* Data Validation Exception
* Base Validation Exception
*/
export class ValidationError extends Error {
/**
* Constructor to take in an error message and code
* @param {number} errorCode
* @param {string} errorMessage
* @param {string} detailedMessage
*/
constructor(errorCode: number, ...rest) {
super(...rest);
constructor(errorCode: number, errorMessage: String, detailedMessage: String) {
super(errorMessage);
this.#errorCode = errorCode;
this.#errorMessage = errorMessage;
this.#detailedMessage = detailedMessage;
}
#errorCode;
#errorMessage;
#detailedMessage;
/**
* Getter for #errorCode
@@ -22,4 +34,71 @@ export class ValidationError extends Error {
get errorCode() {
return this.#errorCode;
}
/**
* Getter for #errorMessage
* @return {string}
*/
get errorMessage() {
return this.#errorMessage;
}
/**
* Getter for #detailedMessage
* @return {string}
*/
get detailedMessage() {
return this.#detailedMessage;
}
}
/**
* SCORM 1.2 Validation Error
*/
export class Scorm12ValidationError extends ValidationError {
/**
* Constructor to take in an error code
* @param {number} errorCode
*/
constructor(errorCode: number) {
if ({}.hasOwnProperty.call(scorm12_errors, String(errorCode))) {
super(errorCode, scorm12_errors[String(errorCode)].basicMessage, scorm12_errors[String(errorCode)].detailMessage);
} else {
super(101, scorm12_errors['101'].basicMessage, scorm12_errors['101'].detailMessage);
}
}
}
/**
* AICC Validation Error
*/
export class AICCValidationError extends ValidationError {
/**
* Constructor to take in an error code
* @param {number} errorCode
*/
constructor(errorCode: number) {
if ({}.hasOwnProperty.call(aicc_errors, String(errorCode))) {
super(errorCode, aicc_errors[String(errorCode)].basicMessage, aicc_errors[String(errorCode)].detailMessage);
} else {
super(101, aicc_errors['101'].basicMessage, aicc_errors['101'].detailMessage);
}
}
}
/**
* SCORM 2004 Validation Error
*/
export class Scorm2004ValidationError extends ValidationError {
/**
* Constructor to take in an error code
* @param {number} errorCode
*/
constructor(errorCode: number) {
if ({}.hasOwnProperty.call(scorm2004_errors, String(errorCode))) {
super(errorCode, scorm2004_errors[String(errorCode)].basicMessage, scorm2004_errors[String(errorCode)].detailMessage);
} else {
super(101, scorm2004_errors['101'].basicMessage, scorm2004_errors['101'].detailMessage);
}
}
}

View File

@@ -1,6 +1,46 @@
import {describe, it} from 'mocha';
import {expect} from 'chai';
import {ValidationError} from '../src/exceptions';
import {ValidationError, AICCValidationError, Scorm12ValidationError, Scorm2004ValidationError} from '../src/exceptions';
import APIConstants from '../src/constants/api_constants';
const scorm12_errors = APIConstants.scorm12.error_descriptions;
const aicc_errors = APIConstants.aicc.error_descriptions;
const scorm2004_errors = APIConstants.scorm2004.error_descriptions;
const checkValidationMessage = (
{
errorClass,
errorCodes,
error_messages,
}
) => {
describe(`ValidationError: ${typeof errorClass}`, () => {
it(`${typeof errorClass} should return general errorCode number when not recognized`, () => {
expect(
new errorClass.prototype.constructor(53).errorCode,
).to.equal(101);
});
it(`${typeof errorClass} should return general message when not recognized`, () => {
expect(
new errorClass.prototype.constructor(53).message,
).to.equal(error_messages['101'].basicMessage);
});
for (let i = 0; i < errorCodes.length; i++) {
const errorCode = errorCodes[i];
it(`${typeof errorClass} should return proper errorCode number when recognized`, () => {
expect(
new errorClass.prototype.constructor(errorCode).errorCode,
).to.equal(errorCode);
});
it(`${typeof errorClass} should return proper ${errorCode} message`, () => {
expect(
new errorClass.prototype.constructor(errorCode).message,
).to.equal(error_messages[String(errorCode)].basicMessage);
});
}
});
};
describe('Exception Tests', () => {
it('ValidationException should return message string', () => {
@@ -13,4 +53,19 @@ describe('Exception Tests', () => {
new ValidationError(0, 'Error Message').errorCode,
).to.equal(0);
});
checkValidationMessage({
errorClass: AICCValidationError,
errorCodes: [101, 201, 202, 203, 301, 401, 402, 403, 404, 405, 407, 408],
error_messages: aicc_errors,
});
checkValidationMessage({
errorClass: Scorm12ValidationError,
errorCodes: [101, 201, 202, 203, 301, 401, 402, 403, 404, 405, 407, 408],
error_messages: scorm12_errors,
});
checkValidationMessage({
errorClass: Scorm2004ValidationError,
errorCodes: [0, 101, 102, 103, 104, 111, 112, 113, 122, 123, 132, 133, 142, 143, 201, 301, 351, 391, 401, 402, 403, 404, 405, 406, 407, 408],
error_messages: scorm2004_errors,
});
});