From b427943036b9ce12e16a0ec2a3220c4cae7554b0 Mon Sep 17 00:00:00 2001 From: Jonathan Putney Date: Tue, 12 Nov 2019 14:59:01 -0500 Subject: [PATCH] More test cases --- src/cmi/common.js | 13 +- src/cmi/scorm2004_cmi.js | 3 +- test/cmi/aicc_cmi.spec.js | 24 --- test/cmi/scorm12_cmi.spec.js | 25 --- test/cmi/scorm2004_cmi.spec.js | 314 ++++++++++++++++++++++++++++++++- test/helpers.js | 3 +- 6 files changed, 326 insertions(+), 56 deletions(-) diff --git a/src/cmi/common.js b/src/cmi/common.js index 6fdda4a..d1d3c70 100644 --- a/src/cmi/common.js +++ b/src/cmi/common.js @@ -2,6 +2,7 @@ import {scorm12_constants} from '../constants/api_constants'; import {scorm12_error_codes} from '../constants/error_codes'; import {ValidationError} from '../exceptions'; +import {scorm12_regex} from '../regex'; /** * Check if the value matches the proper format. If not, throw proper error code. @@ -78,6 +79,7 @@ export class CMIScore extends BaseCMI { * @param {number} invalidErrorCode * @param {number} invalidTypeCode * @param {number} invalidRangeCode + * @param {string} decimalRegex */ constructor( { @@ -87,6 +89,7 @@ export class CMIScore extends BaseCMI { invalidErrorCode, invalidTypeCode, invalidRangeCode, + decimalRegex, }) { super(); @@ -104,6 +107,9 @@ export class CMIScore extends BaseCMI { this.#_invalid_range_code = invalidRangeCode ? invalidRangeCode : scorm12_error_codes.VALUE_OUT_OF_RANGE; + this.#_decimal_regex = decimalRegex ? + decimalRegex : + scorm12_regex.CMIDecimal; } #_children; @@ -111,6 +117,7 @@ export class CMIScore extends BaseCMI { #_invalid_error_code; #_invalid_type_code; #_invalid_range_code; + #_decimal_regex; #raw = ''; #min = ''; #max; @@ -146,7 +153,7 @@ export class CMIScore extends BaseCMI { * @param {string} raw */ set raw(raw) { - if (checkValidFormat(raw, scorm12_constants.CMIDecimal, + if (checkValidFormat(raw, this.#_decimal_regex, this.#_invalid_type_code) && (!this.#_score_range || checkValidRange(raw, this.#_score_range, @@ -168,7 +175,7 @@ export class CMIScore extends BaseCMI { * @param {string} min */ set min(min) { - if (checkValidFormat(min, scorm12_constants.CMIDecimal, + if (checkValidFormat(min, this.#_decimal_regex, this.#_invalid_type_code) && (!this.#_score_range || checkValidRange(min, this.#_score_range, @@ -190,7 +197,7 @@ export class CMIScore extends BaseCMI { * @param {string} max */ set max(max) { - if (checkValidFormat(max, scorm12_constants.CMIDecimal, + if (checkValidFormat(max, this.#_decimal_regex, this.#_invalid_type_code) && (!this.#_score_range || checkValidRange(max, this.#_score_range, diff --git a/src/cmi/scorm2004_cmi.js b/src/cmi/scorm2004_cmi.js index 210147a..814114e 100644 --- a/src/cmi/scorm2004_cmi.js +++ b/src/cmi/scorm2004_cmi.js @@ -671,7 +671,7 @@ class CMIInteractions extends CMIArray { */ constructor() { super({ - children: constants.objectives_children, + children: constants.interactions_children, errorCode: scorm2004_error_codes.READ_ONLY_ELEMENT, }); } @@ -1147,6 +1147,7 @@ class Scorm2004CMIScore extends CMIScore { invalidErrorCode: scorm2004_error_codes.INVALID_SET_VALUE, invalidTypeCode: scorm2004_error_codes.TYPE_MISMATCH, invalidRangeCode: scorm2004_error_codes.VALUE_OUT_OF_RANGE, + decimalRegex: scorm2004_regex.CMIDecimal, }); } diff --git a/test/cmi/aicc_cmi.spec.js b/test/cmi/aicc_cmi.spec.js index f91c9d5..e6a2c24 100644 --- a/test/cmi/aicc_cmi.spec.js +++ b/test/cmi/aicc_cmi.spec.js @@ -86,7 +86,6 @@ describe('AICC CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.core.lesson_status', - expectedError: type_mismatch, validValues: [ 'passed', 'completed', @@ -125,7 +124,6 @@ describe('AICC CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.core.exit', - expectedError: type_mismatch, validValues: [ 'time-out', 'suspend', @@ -145,7 +143,6 @@ describe('AICC CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.core.session_time', - expectedError: type_mismatch, validValues: [ '10:06:57', '00:00:01.56', @@ -172,7 +169,6 @@ describe('AICC CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.core.score.raw', - expectedError: invalid_range, validValues: [ '0', '25.1', @@ -188,7 +184,6 @@ describe('AICC CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.core.score.min', - expectedError: invalid_range, validValues: [ '0', '25.1', @@ -204,7 +199,6 @@ describe('AICC CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.core.score.max', - expectedError: invalid_range, validValues: [ '0', '25.1', @@ -271,7 +265,6 @@ describe('AICC CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.student_preference.audio', - expectedError: type_mismatch, validValues: [ '1', '-1', @@ -286,7 +279,6 @@ describe('AICC CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.student_preference.audio', - expectedError: invalid_range, validValues: [], invalidValues: [ '101', @@ -303,7 +295,6 @@ describe('AICC CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.student_preference.speed', - expectedError: type_mismatch, validValues: [ '1', '-100', @@ -318,7 +309,6 @@ describe('AICC CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.student_preference.speed', - expectedError: invalid_range, validValues: [], invalidValues: [ '101', @@ -330,7 +320,6 @@ describe('AICC CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.student_preference.text', - expectedError: type_mismatch, validValues: [ '1', '-1', @@ -343,7 +332,6 @@ describe('AICC CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.student_preference.text', - expectedError: invalid_range, validValues: [], invalidValues: [ '2', @@ -447,7 +435,6 @@ describe('AICC CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.core.lesson_status', - expectedError: type_mismatch, validValues: [ 'passed', 'completed', @@ -489,7 +476,6 @@ describe('AICC CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.core.exit', - expectedError: type_mismatch, validValues: [ 'time-out', 'suspend', @@ -508,7 +494,6 @@ describe('AICC CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.core.session_time', - expectedError: type_mismatch, validValues: [ '10:06:57', '00:00:01.56', @@ -534,7 +519,6 @@ describe('AICC CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.core.score.raw', - expectedError: invalid_range, validValues: [ '0', '25.1', @@ -550,7 +534,6 @@ describe('AICC CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.core.score.min', - expectedError: invalid_range, validValues: [ '0', '25.1', @@ -566,7 +549,6 @@ describe('AICC CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.core.score.max', - expectedError: invalid_range, validValues: [ '0', '25.1', @@ -637,7 +619,6 @@ describe('AICC CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.student_preference.audio', - expectedError: type_mismatch, validValues: [ '1', '-1', @@ -652,7 +633,6 @@ describe('AICC CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.student_preference.audio', - expectedError: invalid_range, validValues: [], invalidValues: [ '101', @@ -669,7 +649,6 @@ describe('AICC CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.student_preference.speed', - expectedError: type_mismatch, validValues: [ '1', '-100', @@ -684,7 +663,6 @@ describe('AICC CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.student_preference.speed', - expectedError: invalid_range, validValues: [], invalidValues: [ '101', @@ -696,7 +674,6 @@ describe('AICC CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.student_preference.text', - expectedError: type_mismatch, validValues: [ '1', '-1', @@ -709,7 +686,6 @@ describe('AICC CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.student_preference.text', - expectedError: invalid_range, validValues: [], invalidValues: [ '2', diff --git a/test/cmi/scorm12_cmi.spec.js b/test/cmi/scorm12_cmi.spec.js index 3140073..4fa0dfc 100644 --- a/test/cmi/scorm12_cmi.spec.js +++ b/test/cmi/scorm12_cmi.spec.js @@ -8,7 +8,6 @@ const invalid_set = scorm12_error_codes.INVALID_SET_VALUE; const type_mismatch = scorm12_error_codes.TYPE_MISMATCH; const write_only = scorm12_error_codes.WRITE_ONLY_ELEMENT; const read_only = scorm12_error_codes.READ_ONLY_ELEMENT; -const invalid_range = scorm12_error_codes.VALUE_OUT_OF_RANGE; describe('SCORM 1.2 CMI Tests', () => { describe('CMI Spec Tests', () => { @@ -87,7 +86,6 @@ describe('SCORM 1.2 CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.core.lesson_status', - expectedError: type_mismatch, validValues: [ 'passed', 'completed', @@ -126,7 +124,6 @@ describe('SCORM 1.2 CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.core.exit', - expectedError: type_mismatch, validValues: [ 'time-out', 'suspend', @@ -145,7 +142,6 @@ describe('SCORM 1.2 CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.core.session_time', - expectedError: type_mismatch, validValues: [ '10:06:57', '00:00:01.56', @@ -171,7 +167,6 @@ describe('SCORM 1.2 CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.core.score.raw', - expectedError: invalid_range, validValues: [ '0', '25.1', @@ -187,7 +182,6 @@ describe('SCORM 1.2 CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.core.score.min', - expectedError: invalid_range, validValues: [ '0', '25.1', @@ -203,7 +197,6 @@ describe('SCORM 1.2 CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.core.score.max', - expectedError: invalid_range, validValues: [ '0', '25.1', @@ -267,7 +260,6 @@ describe('SCORM 1.2 CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.student_preference.audio', - expectedError: type_mismatch, validValues: [ '1', '-1', @@ -282,7 +274,6 @@ describe('SCORM 1.2 CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.student_preference.audio', - expectedError: invalid_range, validValues: [], invalidValues: [ '101', @@ -299,7 +290,6 @@ describe('SCORM 1.2 CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.student_preference.speed', - expectedError: type_mismatch, validValues: [ '1', '-100', @@ -314,7 +304,6 @@ describe('SCORM 1.2 CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.student_preference.speed', - expectedError: invalid_range, validValues: [], invalidValues: [ '101', @@ -326,7 +315,6 @@ describe('SCORM 1.2 CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.student_preference.text', - expectedError: type_mismatch, validValues: [ '1', '-1', @@ -339,7 +327,6 @@ describe('SCORM 1.2 CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.student_preference.text', - expectedError: invalid_range, validValues: [], invalidValues: [ '2', @@ -446,7 +433,6 @@ describe('SCORM 1.2 CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.core.lesson_status', - expectedError: type_mismatch, validValues: [ 'passed', 'completed', @@ -488,7 +474,6 @@ describe('SCORM 1.2 CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.core.exit', - expectedError: type_mismatch, validValues: [ 'time-out', 'suspend', @@ -507,7 +492,6 @@ describe('SCORM 1.2 CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.core.session_time', - expectedError: type_mismatch, validValues: [ '10:06:57', '00:00:01.56', @@ -533,7 +517,6 @@ describe('SCORM 1.2 CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.core.score.raw', - expectedError: invalid_range, validValues: [ '0', '25.1', @@ -549,7 +532,6 @@ describe('SCORM 1.2 CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.core.score.min', - expectedError: invalid_range, validValues: [ '0', '25.1', @@ -565,7 +547,6 @@ describe('SCORM 1.2 CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.core.score.max', - expectedError: invalid_range, validValues: [ '0', '25.1', @@ -632,7 +613,6 @@ describe('SCORM 1.2 CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.student_preference.audio', - expectedError: type_mismatch, validValues: [ '1', '-1', @@ -647,7 +627,6 @@ describe('SCORM 1.2 CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.student_preference.audio', - expectedError: invalid_range, validValues: [], invalidValues: [ '101', @@ -664,7 +643,6 @@ describe('SCORM 1.2 CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.student_preference.speed', - expectedError: type_mismatch, validValues: [ '1', '-100', @@ -679,7 +657,6 @@ describe('SCORM 1.2 CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.student_preference.speed', - expectedError: invalid_range, validValues: [], invalidValues: [ '101', @@ -691,7 +668,6 @@ describe('SCORM 1.2 CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.student_preference.text', - expectedError: type_mismatch, validValues: [ '1', '-1', @@ -704,7 +680,6 @@ describe('SCORM 1.2 CMI Tests', () => { h.checkValidValues({ cmi: cmi(), fieldName: 'cmi.student_preference.text', - expectedError: invalid_range, validValues: [], invalidValues: [ '2', diff --git a/test/cmi/scorm2004_cmi.spec.js b/test/cmi/scorm2004_cmi.spec.js index e52a134..f3a54a3 100644 --- a/test/cmi/scorm2004_cmi.spec.js +++ b/test/cmi/scorm2004_cmi.spec.js @@ -7,7 +7,6 @@ import * as h from '../helpers'; const read_only = scorm2004_error_codes.READ_ONLY_ELEMENT; const write_only = scorm2004_error_codes.WRITE_ONLY_ELEMENT; const invalid_set = scorm2004_error_codes.INVALID_SET_VALUE; -const invalid_range = scorm2004_error_codes.VALUE_OUT_OF_RANGE; const type_mismatch = scorm2004_error_codes.TYPE_MISMATCH; describe('SCORM 2004 CMI Tests', () => { @@ -48,6 +47,319 @@ describe('SCORM 2004 CMI Tests', () => { 'failed', ], }); + h.checkReadAndWrite({ + cmi: cmi(), + fieldName: 'cmi.completion_threshold', + }); + h.checkReadAndWrite({ + cmi: cmi(), + fieldName: 'cmi.credit', + expectedValue: 'credit', + }); + h.checkReadAndWrite({ + cmi: cmi(), + fieldName: 'cmi.entry', + }); + h.checkWriteOnly({ + cmi: cmi(), + fieldName: 'cmi.exit', + expectedError: write_only, + valueToTest: 'time-out', + }); + h.checkValidValues({ + cmi: cmi(), + fieldName: 'cmi.exit', + validValues: [ + 'time-out', + 'suspend', + 'logout', + 'normal', + ], + invalidValues: [ + 'close', + 'exit', + 'crash', + ], + }); + h.checkReadAndWrite({ + cmi: cmi(), + fieldName: 'cmi.launch_data', + }); + h.checkReadAndWrite({ + cmi: cmi(), + fieldName: 'cmi.learner_id', + }); + h.checkReadAndWrite({ + cmi: cmi(), + fieldName: 'cmi.learner_name', + }); + h.checkFieldConstraintSize({ + cmi: cmi(), + fieldName: 'cmi.location', + limit: 1000, + expectedError: type_mismatch, + }); + h.checkReadAndWrite({ + cmi: cmi(), + fieldName: 'cmi.max_time_allowed', + }); + h.checkReadAndWrite({ + cmi: cmi(), + fieldName: 'cmi.mode', + expectedValue: 'normal', + }); + h.checkReadAndWrite({ + cmi: cmi(), + fieldName: 'cmi.max_time_allowed', + }); + h.checkValidValues({ + cmi: cmi(), + fieldName: 'cmi.progress_measure', + validValues: [ + '0.0', + '0.25', + '0.5', + '1.0', + ], + invalidValues: [ + '-1', + '-0.1', + '1.1', + '.25', + ], + }); + h.checkReadAndWrite({ + cmi: cmi(), + fieldName: 'cmi.scaled_passing_score', + }); + h.checkWriteOnly({ + cmi: cmi(), + fieldName: 'cmi.session_time', + valueToTest: 'P0S', + expectedError: write_only, + }); + h.checkValidValues({ + cmi: cmi(), + fieldName: 'cmi.session_time', + validValues: [ + 'P1Y34DT23H45M15S', + 'PT1M45S', + 'P0S', + 'PT75M', + ], + invalidValues: [ + '00:08:45', + '-P1H', + '1y45D', + '0', + ], + }); + h.checkRead({ + cmi: cmi(), + fieldName: 'cmi.success_status', + expectedValue: 'unknown', + }); + h.checkValidValues({ + cmi: cmi(), + fieldName: 'cmi.success_status', + validValues: [ + 'passed', + 'failed', + 'unknown', + ], + invalidValues: [ + 'complete', + 'incomplete', + 'P', + 'f', + ], + }); + h.checkFieldConstraintSize({ + cmi: cmi(), + fieldName: 'cmi.suspend_data', + limit: 64000, + expectedError: type_mismatch, + }); + h.checkReadAndWrite({ + cmi: cmi(), + fieldName: 'cmi.time_limit_action', + expectedValue: 'continue,no message', + }); + h.checkReadAndWrite({ + cmi: cmi(), + fieldName: 'cmi.total_time', + expectedValue: '0', + }); + + /** + * cmi.interactions Properties + */ + h.checkReadOnly({ + cmi: cmi(), + fieldName: 'cmi.interactions._children', + expectedValue: scorm2004_constants.interactions_children, + expectedError: read_only, + }); + h.checkReadOnly({ + cmi: cmi(), + fieldName: 'cmi.interactions._count', + expectedValue: 0, + expectedError: read_only, + }); + + /** + * cmi.learner_preference Properties + */ + h.checkInvalidSet({ + cmi: cmi(), + fieldName: 'cmi.learner_preference._children', + expectedValue: scorm2004_constants.student_preference_children, + expectedError: read_only, + }); + h.checkValidValues({ + cmi: cmi(), + fieldName: 'cmi.learner_preference.audio_level', + validValues: [ + '1', + '50', + '100', + ], + invalidValues: [ + 'invalid', + 'a100', + '-1', + ], + }); + h.checkValidValues({ + cmi: cmi(), + fieldName: 'cmi.learner_preference.language', + validValues: [ + 'en', + 'fr', + 'ru', + 'es', + ], + invalidValues: [ + 'invalid', + 'a100', + ], + }); + h.checkValidValues({ + cmi: cmi(), + fieldName: 'cmi.learner_preference.delivery_speed', + validValues: [ + '1', + '50', + '100', + ], + invalidValues: [ + 'invalid', + 'a100', + ], + }); + h.checkValidValues({ + cmi: cmi(), + fieldName: 'cmi.learner_preference.audio_captioning', + validValues: [ + '1', + '-1', + ], + invalidValues: [ + 'invalid', + 'a100', + '2', + '-2', + ], + }); + + /** + * cmi.objectives Properties + */ + h.checkReadOnly({ + cmi: cmi(), + fieldName: 'cmi.objectives._children', + expectedValue: scorm2004_constants.objectives_children, + expectedError: read_only, + }); + h.checkReadOnly({ + cmi: cmi(), + fieldName: 'cmi.objectives._count', + expectedValue: 0, + expectedError: read_only, + }); + + /** + * cmi.score Properties + */ + h.checkInvalidSet({ + cmi: cmi(), + fieldName: 'cmi.score._children', + expectedValue: scorm2004_constants.score_children, + expectedError: invalid_set, + }); + h.checkValidValues({ + cmi: cmi(), + fieldName: 'cmi.score.scaled', + validValues: [ + '1', + '0.5', + '0', + '-0.5', + '-1', + ], + invalidValues: [ + '-101', + '25.1', + '50.5', + '75', + '100', + ], + }); + h.checkValidValues({ + cmi: cmi(), + fieldName: 'cmi.score.raw', + validValues: [ + '0', + '25.1', + '50.5', + '75', + '100', + ], + invalidValues: [ + 'a100', + 'invalid', + ], + }); + h.checkValidValues({ + cmi: cmi(), + fieldName: 'cmi.score.min', + validValues: [ + '0', + '25.1', + '50.5', + '75', + '100', + ], + invalidValues: [ + 'a100', + 'invalid', + ], + }); + h.checkValidValues({ + cmi: cmi(), + fieldName: 'cmi.score.max', + validValues: [ + '0', + '25.1', + '50.5', + '75', + '100', + ], + invalidValues: [ + 'a100', + 'invalid', + ], + }); }); }); }); diff --git a/test/helpers.js b/test/helpers.js index c190b71..c63a378 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -134,7 +134,6 @@ export const checkValidValues = ( { cmi, fieldName, - expectedError, validValues, invalidValues, }) => { @@ -154,7 +153,7 @@ export const checkValidValues = ( it(`Should fail to write '${invalidValues[idx]}' to ${fieldName}`, () => { expect(() => eval(`${fieldName} = '${invalidValues[idx]}'`)). - to.throw(expectedError + ''); + to.throw(); }); } }