diff --git a/src/BaseAPI.js b/src/BaseAPI.js index 4ff5d9f..61c8e95 100644 --- a/src/BaseAPI.js +++ b/src/BaseAPI.js @@ -106,6 +106,8 @@ export default class BaseAPI { if (this.checkState(checkTerminated, this.#error_codes.TERMINATION_BEFORE_INIT, this.#error_codes.MULTIPLE_TERMINATION)) { + this.currentState = global_constants.STATE_TERMINATED; + const result = this.storeData(true); if (result.errorCode && result.errorCode > 0) { this.throwSCORMError(result.errorCode); @@ -114,7 +116,7 @@ export default class BaseAPI { result.result : global_constants.SCORM_FALSE; if (checkTerminated) this.lastErrorCode = 0; - this.currentState = global_constants.STATE_TERMINATED; + returnValue = global_constants.SCORM_TRUE; this.processListeners(callbackName); } @@ -906,7 +908,8 @@ export default class BaseAPI { */ scheduleCommit(when: number) { this.#timeout = new ScheduledCommit(this, when); - this.apiLog('scheduleCommit', '', 'scheduled', global_constants.LOG_LEVEL_DEBUG); + this.apiLog('scheduleCommit', '', 'scheduled', + global_constants.LOG_LEVEL_DEBUG); } /** diff --git a/src/Scorm2004API.js b/src/Scorm2004API.js index 1524cf2..78e83c0 100644 --- a/src/Scorm2004API.js +++ b/src/Scorm2004API.js @@ -473,10 +473,6 @@ export default class Scorm2004API extends BaseAPI { renderCommitCMI(terminateCommit: boolean) { const cmiExport = this.renderCMIToJSONObject(); - if (terminateCommit) { - cmiExport.cmi.total_time = this.cmi.getCurrentTotalTime(); - } - const result = []; const flattened = Utilities.flatten(cmiExport); switch (this.settings.dataCommitFormat) { diff --git a/src/cmi/scorm12_cmi.js b/src/cmi/scorm12_cmi.js index b237170..e636dd1 100644 --- a/src/cmi/scorm12_cmi.js +++ b/src/cmi/scorm12_cmi.js @@ -526,7 +526,7 @@ class CMICore extends BaseCMI { 'credit': this.credit, 'lesson_status': this.lesson_status, 'entry': this.entry, - 'total_time': this.total_time, + 'total_time': this.getCurrentTotalTime(), 'lesson_mode': this.lesson_mode, 'exit': this.exit, 'session_time': this.session_time, diff --git a/src/cmi/scorm2004_cmi.js b/src/cmi/scorm2004_cmi.js index 9325a91..227874f 100644 --- a/src/cmi/scorm2004_cmi.js +++ b/src/cmi/scorm2004_cmi.js @@ -103,7 +103,7 @@ export class CMI extends BaseCMI { #success_status = 'unknown'; #suspend_data = ''; #time_limit_action = 'continue,no message'; - #total_time = '0'; + #total_time = ''; /** * Called when the API has been initialized after the CMI has been created @@ -538,7 +538,7 @@ export class CMI extends BaseCMI { 'success_status': this.success_status, 'suspend_data': this.suspend_data, 'time_limit_action': this.time_limit_action, - 'total_time': this.total_time, + 'total_time': this.getCurrentTotalTime(), }; delete this.jsonString; return result; diff --git a/src/constants/regex.js b/src/constants/regex.js index 3a0e7ed..6570979 100644 --- a/src/constants/regex.js +++ b/src/constants/regex.js @@ -1,7 +1,5 @@ // @flow -import {scorm12_values, scorm2004_values} from './field_values'; - export const scorm12_regex = { CMIString256: '^.{0,255}$', CMIString4096: '^.{0,4096}$', @@ -15,11 +13,11 @@ export const scorm12_regex = { CMIIndex: '[._](\\d+).', // Vocabulary Data Type Definition - CMIStatus: '^(' + scorm12_values.validLessonStatus.join('|') + ')$', - CMIStatus2: '^(' + scorm12_values.validLessonStatus.join('|') + '|not attempted)$', - CMIExit: '^(' + scorm12_values.validExit.join('|') + '|)$', - CMIType: '^(' + scorm12_values.validType.join('|') + ')$', - CMIResult: '^(' + scorm12_values.validResult.join('|') + '|([0-9]{0,3})?(\\.[0-9]*)?)$', // eslint-disable-line + CMIStatus: '^(passed|completed|failed|incomplete|browsed)$', + CMIStatus2: '^(passed|completed|failed|incomplete|browsed|not attempted)$', + CMIExit: '^(time-out|suspend|logout|)$', + CMIType: '^(true-false|choice|fill-in|matching|performance|sequencing|likert|numeric)$', + CMIResult: '^(correct|wrong|unanticipated|neutral|([0-9]{0,3})?(\\.[0-9]*)?)$', // eslint-disable-line NAVEvent: '^(previous|continue)$', // Data ranges @@ -60,12 +58,12 @@ export const scorm2004_regex = { CMIIndexStore: '.N(\\d+).', // Vocabulary Data Type Definition - CMICStatus: '^(' + scorm2004_values.validCStatus.join('|') + ')$', - CMISStatus: '^(' + scorm2004_values.validSStatus.join('|') + ')$', - CMIExit: '^(' + scorm2004_values.validExit.join('|') + ')$', - CMIType: '^(' + scorm2004_values.validType.join('|') + ')$', - CMIResult: '^(' + scorm2004_values.validResult.join('|') + '|-?([0-9]{1,4})(\\.[0-9]{1,18})?)$', - NAVEvent: '^(' + scorm2004_values.validNavRequest.join('|') + '|\{target=\\S{0,200}[a-zA-Z0-9]\}choice|jump)$', // eslint-disable-line + CMICStatus: '^(completed|incomplete|not attempted|unknown)$', + CMISStatus: '^(passed|failed|unknown)$', + CMIExit: '^(time-out|suspend|logout|normal)$', + CMIType: '^(true-false|choice|fill-in|long-fill-in|matching|performance|sequencing|likert|numeric|other)$', + CMIResult: '^(correct|wrong|unanticipated|neutral|-?([0-9]{1,4})(\\.[0-9]{1,18})?)$', + NAVEvent: '^(previous|continue|exit|exitAll|abandon|abandonAll|suspendAll|\{target=\\S{0,200}[a-zA-Z0-9]\}choice|jump)$', // eslint-disable-line NAVBoolean: '^(unknown|true|false$)', NAVTarget: '^(previous|continue|choice.{target=\\S{0,200}[a-zA-Z0-9]})$', diff --git a/test/Scorm2004API.spec.js b/test/Scorm2004API.spec.js index 14ee28f..af6d7f4 100644 --- a/test/Scorm2004API.spec.js +++ b/test/Scorm2004API.spec.js @@ -3,7 +3,7 @@ import {describe, it} from 'mocha'; import * as h from './api_helpers'; import {scorm2004_error_codes} from '../src/constants/error_codes'; import Scorm2004API from '../src/Scorm2004API'; -import {scorm2004_values} from '../src/constants/field_values'; +import {scorm2004_values} from './field_values'; const api = () => { const API = new Scorm2004API(); diff --git a/test/cmi/aicc_cmi.spec.js b/test/cmi/aicc_cmi.spec.js index fdb9175..c737a1a 100644 --- a/test/cmi/aicc_cmi.spec.js +++ b/test/cmi/aicc_cmi.spec.js @@ -13,7 +13,7 @@ import { NAV, } from '../../src/cmi/scorm12_cmi'; import {expect} from 'chai'; -import {scorm12_values} from '../../src/constants/field_values'; +import {scorm12_values} from '../field_values'; const invalid_set = scorm12_error_codes.INVALID_SET_VALUE; const type_mismatch = scorm12_error_codes.TYPE_MISMATCH; @@ -520,7 +520,7 @@ describe('AICC CMI Tests', () => { ). to. equal( - '{"suspend_data":"","launch_data":"","comments":"","comments_from_lms":"","core":{"student_id":"","student_name":"","lesson_location":"","credit":"","lesson_status":"not attempted","entry":"","total_time":"","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"}}}},"student_preference":{"audio":"","language":"","speed":"","text":""},"interactions":{"0":{"id":"","time":"","type":"","weighting":"","student_response":"","result":"","latency":"","objectives":{},"correct_responses":{}}},"evaluation":{"comments":{"0":{"content":"","location":"","time":""}}}}'); + '{"suspend_data":"","launch_data":"","comments":"","comments_from_lms":"","core":{"student_id":"","student_name":"","lesson_location":"","credit":"","lesson_status":"not attempted","entry":"","total_time":"00:00:00","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"}}}},"student_preference":{"audio":"","language":"","speed":"","text":""},"interactions":{"0":{"id":"","time":"","type":"","weighting":"","student_response":"","result":"","latency":"","objectives":{},"correct_responses":{}}},"evaluation":{"comments":{"0":{"content":"","location":"","time":""}}}}'); }); }); diff --git a/test/cmi/scorm12_cmi.spec.js b/test/cmi/scorm12_cmi.spec.js index 978556f..97c68d0 100644 --- a/test/cmi/scorm12_cmi.spec.js +++ b/test/cmi/scorm12_cmi.spec.js @@ -10,7 +10,7 @@ import { CMIObjectivesObject, } from '../../src/cmi/scorm12_cmi'; import * as h from '../cmi_helpers'; -import {scorm12_values} from '../../src/constants/field_values'; +import {scorm12_values} from '../field_values'; const invalid_set = scorm12_error_codes.INVALID_SET_VALUE; const type_mismatch = scorm12_error_codes.TYPE_MISMATCH; @@ -592,7 +592,7 @@ describe('SCORM 1.2 CMI Tests', () => { ). to. equal( - '{"suspend_data":"","launch_data":"","comments":"","comments_from_lms":"","core":{"student_id":"","student_name":"","lesson_location":"","credit":"","lesson_status":"not attempted","entry":"","total_time":"","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":""},"student_preference":{"audio":"","language":"","speed":"","text":""},"interactions":{"0":{"id":"","time":"","type":"","weighting":"","student_response":"","result":"","latency":"","objectives":{},"correct_responses":{}}}}'); + '{"suspend_data":"","launch_data":"","comments":"","comments_from_lms":"","core":{"student_id":"","student_name":"","lesson_location":"","credit":"","lesson_status":"not attempted","entry":"","total_time":"00:00:00","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":""},"student_preference":{"audio":"","language":"","speed":"","text":""},"interactions":{"0":{"id":"","time":"","type":"","weighting":"","student_response":"","result":"","latency":"","objectives":{},"correct_responses":{}}}}'); }); }); diff --git a/test/cmi/scorm2004_cmi.spec.js b/test/cmi/scorm2004_cmi.spec.js index 4b72410..1e1ea8f 100644 --- a/test/cmi/scorm2004_cmi.spec.js +++ b/test/cmi/scorm2004_cmi.spec.js @@ -12,7 +12,7 @@ import { } from '../../src/cmi/scorm2004_cmi'; import * as h from '../cmi_helpers'; import {expect} from 'chai'; -import {scorm2004_values} from '../../src/constants/field_values'; +import {scorm2004_values} from '../field_values'; const read_only = scorm2004_error_codes.READ_ONLY_ELEMENT; const write_only = scorm2004_error_codes.WRITE_ONLY_ELEMENT; @@ -234,7 +234,7 @@ describe('SCORM 2004 CMI Tests', () => { h.checkReadAndWrite({ cmi: cmi(), fieldName: 'cmi.total_time', - expectedValue: '0', + expectedValue: '', }); /** @@ -402,7 +402,7 @@ describe('SCORM 2004 CMI Tests', () => { ). to. equal( - '{"comments_from_learner":{},"comments_from_lms":{},"completion_status":"unknown","completion_threshold":"","credit":"credit","entry":"","exit":"","interactions":{"0":{"id":"","type":"","objectives":{},"timestamp":"","weighting":"","learner_response":"","result":"","latency":"","description":"","correct_responses":{}}},"launch_data":"","learner_id":"","learner_name":"","learner_preference":{"audio_level":"1","language":"","delivery_speed":"1","audio_captioning":"0"},"location":"","max_time_allowed":"","mode":"normal","objectives":{"0":{"id":"","success_status":"unknown","completion_status":"unknown","progress_measure":"","description":"","score":{"scaled":"","raw":"","min":"","max":""}}},"progress_measure":"","scaled_passing_score":"","score":{"scaled":"","raw":"","min":"","max":""},"session_time":"PT0H0M0S","success_status":"unknown","suspend_data":"","time_limit_action":"continue,no message","total_time":"0"}'); + '{"comments_from_learner":{},"comments_from_lms":{},"completion_status":"unknown","completion_threshold":"","credit":"credit","entry":"","exit":"","interactions":{"0":{"id":"","type":"","objectives":{},"timestamp":"","weighting":"","learner_response":"","result":"","latency":"","description":"","correct_responses":{}}},"launch_data":"","learner_id":"","learner_name":"","learner_preference":{"audio_level":"1","language":"","delivery_speed":"1","audio_captioning":"0"},"location":"","max_time_allowed":"","mode":"normal","objectives":{"0":{"id":"","success_status":"unknown","completion_status":"unknown","progress_measure":"","description":"","score":{"scaled":"","raw":"","min":"","max":""}}},"progress_measure":"","scaled_passing_score":"","score":{"scaled":"","raw":"","min":"","max":""},"session_time":"PT0H0M0S","success_status":"unknown","suspend_data":"","time_limit_action":"continue,no message","total_time":"PT0S"}'); }); }); @@ -543,7 +543,7 @@ describe('SCORM 2004 CMI Tests', () => { h.checkReadOnly({ cmi: cmiInitialized(), fieldName: 'cmi.total_time', - expectedValue: '0', + expectedValue: '', expectedError: read_only, }); @@ -712,7 +712,7 @@ describe('SCORM 2004 CMI Tests', () => { ). to. equal( - '{"comments_from_learner":{},"comments_from_lms":{},"completion_status":"unknown","completion_threshold":"","credit":"credit","entry":"","exit":"","interactions":{"0":{"id":"","type":"","objectives":{},"timestamp":"","weighting":"","learner_response":"","result":"","latency":"","description":"","correct_responses":{}}},"launch_data":"","learner_id":"","learner_name":"","learner_preference":{"audio_level":"1","language":"","delivery_speed":"1","audio_captioning":"0"},"location":"","max_time_allowed":"","mode":"normal","objectives":{"0":{"id":"","success_status":"unknown","completion_status":"unknown","progress_measure":"","description":"","score":{"scaled":"","raw":"","min":"","max":""}}},"progress_measure":"","scaled_passing_score":"","score":{"scaled":"","raw":"","min":"","max":""},"session_time":"PT0H0M0S","success_status":"unknown","suspend_data":"","time_limit_action":"continue,no message","total_time":"0"}'); + '{"comments_from_learner":{},"comments_from_lms":{},"completion_status":"unknown","completion_threshold":"","credit":"credit","entry":"","exit":"","interactions":{"0":{"id":"","type":"","objectives":{},"timestamp":"","weighting":"","learner_response":"","result":"","latency":"","description":"","correct_responses":{}}},"launch_data":"","learner_id":"","learner_name":"","learner_preference":{"audio_level":"1","language":"","delivery_speed":"1","audio_captioning":"0"},"location":"","max_time_allowed":"","mode":"normal","objectives":{"0":{"id":"","success_status":"unknown","completion_status":"unknown","progress_measure":"","description":"","score":{"scaled":"","raw":"","min":"","max":""}}},"progress_measure":"","scaled_passing_score":"","score":{"scaled":"","raw":"","min":"","max":""},"session_time":"PT0H0M0S","success_status":"unknown","suspend_data":"","time_limit_action":"continue,no message","total_time":"PT0S"}'); }); }); diff --git a/src/constants/field_values.js b/test/field_values.js similarity index 100% rename from src/constants/field_values.js rename to test/field_values.js