UNPKG

scorm-again

Version:

A modern SCORM JavaScript run-time library for AICC, SCORM 1.2, and SCORM 2004

843 lines (805 loc) 24.9 kB
import { describe, it } from "mocha"; import { aicc_constants } from "../../src/constants/api_constants"; import { scorm12_errors } from "../../src/constants/error_codes"; import { CMI } from "../../src/cmi/aicc/cmi"; import * as h from "../cmi_helpers"; import { expect } from "expect"; import { scorm12Values } from "../field_values"; import { CMITriesObject } from "../../src/cmi/aicc/tries"; import { CMIEvaluationCommentsObject } from "../../src/cmi/aicc/evaluation"; import { CMIObjectivesObject } from "../../src/cmi/scorm12/objectives"; import { CMIInteractionsObject } from "../../src/cmi/scorm12/interactions"; import { NAV } from "../../src/cmi/scorm12/nav"; import { CMIPathsObject } from "../../src/cmi/aicc/paths"; import { CMIStudentDemographics } from "../../src/cmi/aicc/student_demographics"; const invalid_set = scorm12_errors.INVALID_SET_VALUE; const type_mismatch = scorm12_errors.TYPE_MISMATCH; const write_only = scorm12_errors.WRITE_ONLY_ELEMENT; const read_only = scorm12_errors.READ_ONLY_ELEMENT; describe("AICC CMI Tests", () => { describe("CMI Spec Tests", () => { describe("Pre-Initialize Tests", () => { const cmi = () => { return new CMI(); }; /** * Base CMI Properties */ h.checkReadOnly({ cmi: cmi(), fieldName: "cmi._version", expectedValue: "3.4", expectedError: invalid_set, }); h.checkReadOnly({ cmi: cmi(), fieldName: "cmi._children", expectedValue: aicc_constants.cmi_children, expectedError: invalid_set, }); h.checkFieldConstraintSize({ cmi: cmi(), fieldName: "cmi.suspend_data", limit: 4096, expectedError: type_mismatch, }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.launch_data", }); h.checkFieldConstraintSize({ cmi: cmi(), fieldName: "cmi.comments", limit: 4096, expectedError: type_mismatch, }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.comments_from_lms", }); /** * cmi.core Properties */ h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.core._children", expectedValue: aicc_constants.core_children, expectedError: invalid_set, }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.core.student_id", }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.core.student_name", }); h.checkFieldConstraintSize({ cmi: cmi(), fieldName: "cmi.core.lesson_location", limit: 255, expectedError: type_mismatch, }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.core.credit", }); h.checkRead({ cmi: cmi(), fieldName: "cmi.core.lesson_status", expectedValue: "not attempted", }); h.checkValidValues({ cmi: cmi(), fieldName: "cmi.core.lesson_status", validValues: scorm12Values.validLessonStatus, invalidValues: scorm12Values.invalidLessonStatus, }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.core.entry", }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.core.total_time", }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.core.lesson_mode", expectedValue: "normal", }); h.checkWrite({ cmi: cmi(), fieldName: "cmi.core.exit", valueToTest: "suspend", }); h.checkValidValues({ cmi: cmi(), fieldName: "cmi.core.exit", validValues: scorm12Values.validExit, invalidValues: scorm12Values.invalidExit, }); h.checkWriteOnly({ cmi: cmi(), fieldName: "cmi.core.session_time", valueToTest: "00:00:00", expectedError: write_only, }); h.checkValidValues({ cmi: cmi(), fieldName: "cmi.core.session_time", validValues: scorm12Values.validTimespan, invalidValues: scorm12Values.invalidTimespan, }); /** * cmi.core.score Properties */ h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.core.score._children", expectedValue: aicc_constants.score_children, expectedError: invalid_set, }); h.checkValidValues({ cmi: cmi(), fieldName: "cmi.core.score.raw", validValues: scorm12Values.validScoreRange, invalidValues: scorm12Values.invalidScoreRange, }); h.checkValidValues({ cmi: cmi(), fieldName: "cmi.core.score.min", validValues: scorm12Values.validScoreRange, invalidValues: scorm12Values.invalidScoreRange, }); h.checkValidValues({ cmi: cmi(), fieldName: "cmi.core.score.max", validValues: scorm12Values.validScoreRange, invalidValues: scorm12Values.invalidScoreRange, }); /** * cmi.objectives Properties */ h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.objectives._children", expectedValue: aicc_constants.objectives_children, expectedError: invalid_set, }); h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.objectives._count", expectedValue: 0, expectedError: invalid_set, }); /** * cmi.student_data Properties */ h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.student_data._children", expectedValue: aicc_constants.student_data_children, expectedError: invalid_set, }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.student_data.mastery_score", }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.student_data.max_time_allowed", }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.student_data.time_limit_action", }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.student_data.tries_during_lesson", }); /** * cmi.student_preference Properties */ h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.student_preference._children", expectedValue: aicc_constants.student_preference_children, expectedError: invalid_set, }); h.checkValidValues({ cmi: cmi(), fieldName: "cmi.student_preference.audio", validValues: scorm12Values.valid0To100Range.concat(["-1"]), invalidValues: scorm12Values.invalid0To100Range, }); h.checkFieldConstraintSize({ cmi: cmi(), fieldName: "cmi.student_preference.language", limit: 255, expectedError: type_mismatch, }); h.checkValidValues({ cmi: cmi(), fieldName: "cmi.student_preference.speed", validValues: scorm12Values.validSpeedRange, invalidValues: scorm12Values.invalidSpeedRange, }); h.checkValidValues({ cmi: cmi(), fieldName: "cmi.student_preference.text", validValues: scorm12Values.validIntegerScaledRange, invalidValues: scorm12Values.invalidIntegerScaledRange, }); /** * cmi.interactions Properties */ h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.interactions._children", expectedValue: aicc_constants.interactions_children, expectedError: invalid_set, }); h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.interactions._count", expectedValue: 0, expectedError: invalid_set, }); }); describe("Post-Initialize Tests", () => { const cmi = () => { const obj = new CMI(); obj.initialize(); return obj; }; /** * Base CMI Properties */ h.checkReadOnly({ cmi: cmi(), fieldName: "cmi._version", expectedValue: "3.4", expectedError: invalid_set, }); h.checkReadOnly({ cmi: cmi(), fieldName: "cmi._children", expectedValue: aicc_constants.cmi_children, expectedError: invalid_set, }); h.checkFieldConstraintSize({ cmi: cmi(), fieldName: "cmi.suspend_data", limit: 4096, expectedError: type_mismatch, }); h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.launch_data", expectedError: read_only, }); h.checkFieldConstraintSize({ cmi: cmi(), fieldName: "cmi.comments", limit: 4096, expectedError: type_mismatch, }); h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.comments_from_lms", expectedError: read_only, }); /** * cmi.core Properties */ h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.core._children", expectedValue: aicc_constants.core_children, expectedError: invalid_set, }); h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.core.student_id", expectedError: read_only, }); h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.core.student_name", expectedError: read_only, }); h.checkFieldConstraintSize({ cmi: cmi(), fieldName: "cmi.core.lesson_location", limit: 255, expectedError: type_mismatch, }); h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.core.credit", expectedError: read_only, }); h.checkRead({ cmi: cmi(), fieldName: "cmi.core.lesson_status", expectedValue: "not attempted", }); h.checkValidValues({ cmi: cmi(), fieldName: "cmi.core.lesson_status", validValues: scorm12Values.validLessonStatus, invalidValues: scorm12Values.invalidLessonStatus, }); h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.core.entry", expectedError: read_only, }); h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.core.total_time", expectedError: read_only, }); h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.core.lesson_mode", expectedValue: "normal", expectedError: read_only, }); h.checkWrite({ cmi: cmi(), fieldName: "cmi.core.exit", valueToTest: "suspend", }); h.checkValidValues({ cmi: cmi(), fieldName: "cmi.core.exit", validValues: scorm12Values.validExit, invalidValues: scorm12Values.invalidExit, }); h.checkWriteOnly({ cmi: cmi(), fieldName: "cmi.core.session_time", valueToTest: "00:00:00", expectedError: write_only, }); h.checkValidValues({ cmi: cmi(), fieldName: "cmi.core.session_time", validValues: scorm12Values.validTimespan, invalidValues: scorm12Values.invalidTimespan, }); /** * cmi.core.score Properties */ h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.core.score._children", expectedValue: aicc_constants.score_children, expectedError: invalid_set, }); h.checkValidValues({ cmi: cmi(), fieldName: "cmi.core.score.raw", validValues: scorm12Values.validScoreRange, invalidValues: scorm12Values.invalidScoreRange, }); h.checkValidValues({ cmi: cmi(), fieldName: "cmi.core.score.min", validValues: scorm12Values.validScoreRange, invalidValues: scorm12Values.invalidScoreRange, }); h.checkValidValues({ cmi: cmi(), fieldName: "cmi.core.score.max", validValues: scorm12Values.validScoreRange, invalidValues: scorm12Values.invalidScoreRange, }); /** * cmi.objectives Properties */ h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.objectives._children", expectedValue: aicc_constants.objectives_children, expectedError: invalid_set, }); h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.objectives._count", expectedValue: 0, expectedError: invalid_set, }); /** * cmi.student_data Properties */ h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.student_data._children", expectedValue: aicc_constants.student_data_children, expectedError: invalid_set, }); h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.student_data.mastery_score", expectedError: read_only, }); h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.student_data.max_time_allowed", expectedError: read_only, }); h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.student_data.time_limit_action", expectedError: read_only, }); h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.student_data.tries_during_lesson", expectedError: read_only, }); /** * cmi.student_preference Properties */ h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.student_preference._children", expectedValue: aicc_constants.student_preference_children, expectedError: invalid_set, }); h.checkValidValues({ cmi: cmi(), fieldName: "cmi.student_preference.audio", validValues: scorm12Values.valid0To100Range.concat(["-1"]), invalidValues: scorm12Values.invalid0To100Range, }); h.checkFieldConstraintSize({ cmi: cmi(), fieldName: "cmi.student_preference.language", limit: 255, expectedError: type_mismatch, }); h.checkValidValues({ cmi: cmi(), fieldName: "cmi.student_preference.speed", validValues: scorm12Values.validSpeedRange, invalidValues: scorm12Values.invalidSpeedRange, }); h.checkValidValues({ cmi: cmi(), fieldName: "cmi.student_preference.text", validValues: scorm12Values.validIntegerScaledRange, invalidValues: scorm12Values.invalidIntegerScaledRange, }); /** * cmi.interactions Properties */ h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.interactions._children", expectedValue: aicc_constants.interactions_children, expectedError: invalid_set, }); h.checkReadOnly({ cmi: cmi(), fieldName: "cmi.interactions._count", expectedValue: 0, expectedError: invalid_set, }); it("should export JSON", () => { const cmiObj = cmi(); cmiObj.objectives.childArray.push(new CMIObjectivesObject()); cmiObj.interactions.childArray.push(new CMIInteractionsObject()); cmiObj.evaluation.comments.childArray.push( new CMIEvaluationCommentsObject(), ); cmiObj.student_data.tries.childArray.push(new CMITriesObject()); expect(JSON.stringify(cmiObj)).toEqual( '{"suspend_data":"","launch_data":"","comments":"","comments_from_lms":"","core":{"student_id":"","student_name":"","lesson_location":"","credit":"","lesson_status":"not attempted","entry":"","lesson_mode":"normal","exit":"","session_time":"00:00:00","score":{"raw":"","min":"","max":"100"}},"objectives":{"0":{"id":"","status":"","score":{"raw":"","min":"","max":"100"}}},"student_data":{"mastery_score":"","max_time_allowed":"","time_limit_action":"","tries":{"0":{"status":"","time":"","score":{"raw":"","min":"","max":"100"}}},"attempt_records":{}},"student_preference":{"audio":"","language":"","lesson_type":"","speed":"","text":"","text_color":"","text_location":"","text_size":"","video":"","windows":{}},"student_demographics":{"city":"","class":"","company":"","country":"","experience":"","familiar_name":"","instructor_name":"","title":"","native_language":"","state":"","street_address":"","telephone":"","years_experience":""},"interactions":{"0":{"id":"","time":"","type":"","weighting":"","student_response":"","result":"","latency":"","objectives":{},"correct_responses":{}}},"evaluation":{"comments":{"0":{"content":"","location":"","time":""}}},"paths":{}}', ); }); }); describe("CMITriesObject Tests", () => { const triesObject = () => { return new CMITriesObject(); }; const triesInitialized = () => { const cmi = new CMITriesObject(); cmi.initialize(); return cmi; }; /** * cmi.interactions.n.objectives.n object */ h.checkRead({ cmi: triesObject(), fieldName: "cmi.status", }); h.checkRead({ cmi: triesInitialized(), fieldName: "cmi.status", }); h.checkValidValues({ cmi: triesObject(), fieldName: "cmi.status", validValues: scorm12Values.validLessonStatus.concat(["not attempted"]), invalidValues: scorm12Values.invalidLessonStatus, }); h.checkReadAndWrite({ cmi: triesObject(), fieldName: "cmi.time", valueToTest: "23:59:59", }); h.checkValidValues({ cmi: triesObject(), fieldName: "cmi.time", validValues: scorm12Values.validTime, invalidValues: scorm12Values.invalidTime, }); /** * cmi.student_data.tries.n.score Properties */ h.checkReadOnly({ cmi: triesObject(), fieldName: "cmi.score._children", expectedValue: aicc_constants.score_children, expectedError: invalid_set, }); h.checkValidValues({ cmi: triesObject(), fieldName: "cmi.score.raw", validValues: scorm12Values.validScoreRange, invalidValues: scorm12Values.invalidScoreRange, }); h.checkValidValues({ cmi: triesObject(), fieldName: "cmi.score.min", validValues: scorm12Values.validScoreRange, invalidValues: scorm12Values.invalidScoreRange, }); h.checkValidValues({ cmi: triesObject(), fieldName: "cmi.score.max", validValues: scorm12Values.validScoreRange, invalidValues: scorm12Values.invalidScoreRange, }); it("should export JSON", () => { const cmi = triesObject(); expect(JSON.stringify(cmi)).toEqual( '{"status":"","time":"","score":{"raw":"","min":"","max":"100"}}', ); }); }); describe("CMIPathsObject Tests", () => { const paths = () => { return new CMIPathsObject(); }; h.checkFieldConstraintSize({ cmi: paths(), fieldName: "cmi.location_id", expectedError: type_mismatch, limit: 255, }); h.checkReadAndWrite({ cmi: paths(), fieldName: "cmi.date", valueToTest: "2021-01-01", }); h.checkValidValues({ cmi: paths(), fieldName: "cmi.time", validValues: scorm12Values.validTime, invalidValues: scorm12Values.invalidTime, }); h.checkValidValues({ cmi: paths(), fieldName: "cmi.status", validValues: scorm12Values.validLessonStatus, invalidValues: scorm12Values.invalidLessonStatus, }); h.checkFieldConstraintSize({ cmi: paths(), fieldName: "cmi.why_left", expectedError: type_mismatch, limit: 255, }); h.checkValidValues({ cmi: paths(), fieldName: "cmi.time_in_element", validValues: scorm12Values.validTime, invalidValues: scorm12Values.invalidTime, }); it("should export JSON", () => { const cmi = paths(); expect(JSON.stringify(cmi)).toEqual( '{"location_id":"","date":"","time":"","status":"","why_left":"","time_in_element":""}', ); }); }); describe("CMIStudentDemographicsObject Tests", () => { const cmiInit = () => { const cmiStudentDemographics = new CMIStudentDemographics(); cmiStudentDemographics.initialize(); return cmiStudentDemographics; }; const cmi = () => { return new CMIStudentDemographics(); }; h.checkReadOnly({ cmi: cmiInit(), fieldName: "cmi.city", expectedError: read_only, }); h.checkReadOnly({ cmi: cmiInit(), fieldName: "cmi.class", expectedError: read_only, }); h.checkReadOnly({ cmi: cmiInit(), fieldName: "cmi.company", expectedError: read_only, }); h.checkReadOnly({ cmi: cmiInit(), fieldName: "cmi.country", expectedError: read_only, }); h.checkReadOnly({ cmi: cmiInit(), fieldName: "cmi.experience", expectedError: read_only, }); h.checkReadOnly({ cmi: cmiInit(), fieldName: "cmi.familiar_name", expectedError: read_only, }); h.checkReadOnly({ cmi: cmiInit(), fieldName: "cmi.instructor_name", expectedError: read_only, }); h.checkReadOnly({ cmi: cmiInit(), fieldName: "cmi.title", expectedError: read_only, }); h.checkReadOnly({ cmi: cmiInit(), fieldName: "cmi.native_language", expectedError: read_only, }); h.checkReadOnly({ cmi: cmiInit(), fieldName: "cmi.state", expectedError: read_only, }); h.checkReadOnly({ cmi: cmiInit(), fieldName: "cmi.street_address", expectedError: read_only, }); h.checkReadOnly({ cmi: cmiInit(), fieldName: "cmi.telephone", expectedError: read_only, }); h.checkReadOnly({ cmi: cmiInit(), fieldName: "cmi.years_experience", expectedError: read_only, }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.city", }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.class", }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.company", }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.country", }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.experience", }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.familiar_name", }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.instructor_name", }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.title", }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.native_language", }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.state", }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.street_address", }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.telephone", }); h.checkReadAndWrite({ cmi: cmi(), fieldName: "cmi.years_experience", }); }); describe("CMIEvaluationCommentsObject Tests", () => { const evaluationComment = () => { return new CMIEvaluationCommentsObject(); }; /** * cmi.evaluation.comments.n object */ h.checkFieldConstraintSize({ cmi: evaluationComment(), fieldName: "cmi.content", expectedError: type_mismatch, limit: 255, }); h.checkFieldConstraintSize({ cmi: evaluationComment(), fieldName: "cmi.location", expectedError: type_mismatch, limit: 255, }); h.checkReadAndWrite({ cmi: evaluationComment(), fieldName: "cmi.time", valueToTest: "23:59:59", }); h.checkValidValues({ cmi: evaluationComment(), fieldName: "cmi.time", validValues: scorm12Values.validTime, invalidValues: scorm12Values.invalidTime, }); it("should export JSON", () => { const cmi = evaluationComment(); expect(JSON.stringify(cmi)).toEqual( '{"content":"","location":"","time":""}', ); }); }); describe("NAV Tests", () => { const nav = () => { return new NAV(); }; /** * cmi.interactions.n.correct_responses.n object */ h.checkValidValues({ cmi: nav(), fieldName: "cmi.event", validValues: ["previous", "continue"], invalidValues: ["P", "f", "complete", "started", "in progress"], }); it("should export JSON", () => { const cmi = nav(); expect(JSON.stringify(cmi)).toEqual('{"event":""}'); }); }); }); });