scorm-again 2.6.2 → 2.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/aicc.js +41 -25
  2. package/dist/aicc.js.map +1 -1
  3. package/dist/aicc.min.js +1 -1
  4. package/dist/aicc.min.js.map +1 -1
  5. package/dist/esm/aicc.js +41 -25
  6. package/dist/esm/aicc.js.map +1 -1
  7. package/dist/esm/aicc.min.js +1 -1
  8. package/dist/esm/aicc.min.js.map +1 -1
  9. package/dist/esm/scorm-again.js +70 -45
  10. package/dist/esm/scorm-again.js.map +1 -1
  11. package/dist/esm/scorm-again.min.js +1 -1
  12. package/dist/esm/scorm-again.min.js.map +1 -1
  13. package/dist/esm/scorm12.js +38 -23
  14. package/dist/esm/scorm12.js.map +1 -1
  15. package/dist/esm/scorm12.min.js +1 -1
  16. package/dist/esm/scorm12.min.js.map +1 -1
  17. package/dist/esm/scorm2004.js +60 -39
  18. package/dist/esm/scorm2004.js.map +1 -1
  19. package/dist/esm/scorm2004.min.js +1 -1
  20. package/dist/esm/scorm2004.min.js.map +1 -1
  21. package/dist/scorm-again.js +70 -45
  22. package/dist/scorm-again.js.map +1 -1
  23. package/dist/scorm-again.min.js +1 -1
  24. package/dist/scorm-again.min.js.map +1 -1
  25. package/dist/scorm12.js +38 -23
  26. package/dist/scorm12.js.map +1 -1
  27. package/dist/scorm12.min.js +1 -1
  28. package/dist/scorm12.min.js.map +1 -1
  29. package/dist/scorm2004.js +60 -39
  30. package/dist/scorm2004.js.map +1 -1
  31. package/dist/scorm2004.min.js +1 -1
  32. package/dist/scorm2004.min.js.map +1 -1
  33. package/index.d.ts +24 -3
  34. package/package.json +1 -1
  35. package/src/BaseAPI.ts +57 -35
  36. package/src/Scorm12API.ts +3 -2
  37. package/src/Scorm2004API.ts +31 -24
  38. package/src/cmi/aicc/attempts.ts +3 -3
  39. package/src/cmi/aicc/core.ts +30 -12
  40. package/src/cmi/aicc/evaluation.ts +1 -1
  41. package/src/cmi/aicc/student_data.ts +1 -1
  42. package/src/cmi/aicc/student_demographics.ts +13 -13
  43. package/src/cmi/aicc/student_preferences.ts +1 -1
  44. package/src/cmi/aicc/tries.ts +3 -3
  45. package/src/cmi/aicc/validation.ts +1 -1
  46. package/src/cmi/common/array.ts +1 -1
  47. package/src/cmi/common/score.ts +3 -3
  48. package/src/cmi/common/validation.ts +2 -2
  49. package/src/cmi/scorm12/cmi.ts +12 -4
  50. package/src/cmi/scorm12/interactions.ts +27 -11
  51. package/src/cmi/scorm12/objectives.ts +4 -4
  52. package/src/cmi/scorm12/student_data.ts +12 -4
  53. package/src/cmi/scorm12/student_preference.ts +3 -1
  54. package/src/cmi/scorm12/validation.ts +5 -3
  55. package/src/cmi/scorm2004/adl.ts +21 -7
  56. package/src/cmi/scorm2004/cmi.ts +45 -15
  57. package/src/cmi/scorm2004/comments.ts +11 -5
  58. package/src/cmi/scorm2004/interactions.ts +25 -23
  59. package/src/cmi/scorm2004/learner_preference.ts +3 -1
  60. package/src/cmi/scorm2004/objectives.ts +5 -5
  61. package/src/cmi/scorm2004/score.ts +3 -3
  62. package/src/cmi/scorm2004/validation.ts +2 -2
  63. package/src/constants/regex.ts +8 -1
  64. package/src/exceptions/aicc_exceptions.ts +4 -4
  65. package/src/exceptions/scorm12_exceptions.ts +4 -4
  66. package/src/exceptions/scorm2004_exceptions.ts +4 -4
  67. package/src/utilities.ts +3 -3
  68. package/test/Scorm12API.spec.ts +45 -0
  69. package/test/Scorm2004API.spec.ts +43 -0
  70. package/tsconfig.json +1 -0
@@ -17,7 +17,7 @@ export class CMICommentsFromLMS extends CMIArray {
17
17
  constructor() {
18
18
  super({
19
19
  children: scorm2004_constants.comments_children,
20
- errorCode: scorm2004_errors.READ_ONLY_ELEMENT,
20
+ errorCode: scorm2004_errors.READ_ONLY_ELEMENT as number,
21
21
  errorClass: Scorm2004ValidationError,
22
22
  });
23
23
  }
@@ -34,7 +34,7 @@ export class CMICommentsFromLearner extends CMIArray {
34
34
  constructor() {
35
35
  super({
36
36
  children: scorm2004_constants.comments_children,
37
- errorCode: scorm2004_errors.READ_ONLY_ELEMENT,
37
+ errorCode: scorm2004_errors.READ_ONLY_ELEMENT as number,
38
38
  errorClass: Scorm2004ValidationError,
39
39
  });
40
40
  }
@@ -83,7 +83,9 @@ export class CMICommentsObject extends BaseCMI {
83
83
  */
84
84
  set comment(comment: string) {
85
85
  if (this.initialized && this._readOnlyAfterInit) {
86
- throw new Scorm2004ValidationError(scorm2004_errors.READ_ONLY_ELEMENT);
86
+ throw new Scorm2004ValidationError(
87
+ scorm2004_errors.READ_ONLY_ELEMENT as number,
88
+ );
87
89
  } else {
88
90
  if (
89
91
  check2004ValidFormat(comment, scorm2004_regex.CMILangString4000, true)
@@ -107,7 +109,9 @@ export class CMICommentsObject extends BaseCMI {
107
109
  */
108
110
  set location(location: string) {
109
111
  if (this.initialized && this._readOnlyAfterInit) {
110
- throw new Scorm2004ValidationError(scorm2004_errors.READ_ONLY_ELEMENT);
112
+ throw new Scorm2004ValidationError(
113
+ scorm2004_errors.READ_ONLY_ELEMENT as number,
114
+ );
111
115
  } else {
112
116
  if (check2004ValidFormat(location, scorm2004_regex.CMIString250)) {
113
117
  this._location = location;
@@ -129,7 +133,9 @@ export class CMICommentsObject extends BaseCMI {
129
133
  */
130
134
  set timestamp(timestamp: string) {
131
135
  if (this.initialized && this._readOnlyAfterInit) {
132
- throw new Scorm2004ValidationError(scorm2004_errors.READ_ONLY_ELEMENT);
136
+ throw new Scorm2004ValidationError(
137
+ scorm2004_errors.READ_ONLY_ELEMENT as number,
138
+ );
133
139
  } else {
134
140
  if (check2004ValidFormat(timestamp, scorm2004_regex.CMITime)) {
135
141
  this._timestamp = timestamp;
@@ -17,7 +17,7 @@ export class CMIInteractions extends CMIArray {
17
17
  constructor() {
18
18
  super({
19
19
  children: scorm2004_constants.interactions_children,
20
- errorCode: scorm2004_errors.READ_ONLY_ELEMENT,
20
+ errorCode: scorm2004_errors.READ_ONLY_ELEMENT as number,
21
21
  errorClass: Scorm2004ValidationError,
22
22
  });
23
23
  }
@@ -43,12 +43,12 @@ export class CMIInteractionsObject extends BaseCMI {
43
43
  constructor() {
44
44
  super();
45
45
  this.objectives = new CMIArray({
46
- errorCode: scorm2004_errors.READ_ONLY_ELEMENT,
46
+ errorCode: scorm2004_errors.READ_ONLY_ELEMENT as number,
47
47
  errorClass: Scorm2004ValidationError,
48
48
  children: scorm2004_constants.objectives_children,
49
49
  });
50
50
  this.correct_responses = new CMIArray({
51
- errorCode: scorm2004_errors.READ_ONLY_ELEMENT,
51
+ errorCode: scorm2004_errors.READ_ONLY_ELEMENT as number,
52
52
  errorClass: Scorm2004ValidationError,
53
53
  children: scorm2004_constants.correct_responses_children,
54
54
  });
@@ -80,12 +80,12 @@ export class CMIInteractionsObject extends BaseCMI {
80
80
  this._latency = "";
81
81
  this._description = "";
82
82
  this.objectives = new CMIArray({
83
- errorCode: scorm2004_errors.READ_ONLY_ELEMENT,
83
+ errorCode: scorm2004_errors.READ_ONLY_ELEMENT as number,
84
84
  errorClass: Scorm2004ValidationError,
85
85
  children: scorm2004_constants.objectives_children,
86
86
  });
87
87
  this.correct_responses = new CMIArray({
88
- errorCode: scorm2004_errors.READ_ONLY_ELEMENT,
88
+ errorCode: scorm2004_errors.READ_ONLY_ELEMENT as number,
89
89
  errorClass: Scorm2004ValidationError,
90
90
  children: scorm2004_constants.correct_responses_children,
91
91
  });
@@ -124,7 +124,7 @@ export class CMIInteractionsObject extends BaseCMI {
124
124
  set type(type: string) {
125
125
  if (this.initialized && this._id === "") {
126
126
  throw new Scorm2004ValidationError(
127
- scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED,
127
+ scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED as number,
128
128
  );
129
129
  } else {
130
130
  if (check2004ValidFormat(type, scorm2004_regex.CMIType)) {
@@ -148,7 +148,7 @@ export class CMIInteractionsObject extends BaseCMI {
148
148
  set timestamp(timestamp: string) {
149
149
  if (this.initialized && this._id === "") {
150
150
  throw new Scorm2004ValidationError(
151
- scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED,
151
+ scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED as number,
152
152
  );
153
153
  } else {
154
154
  if (check2004ValidFormat(timestamp, scorm2004_regex.CMITime)) {
@@ -172,7 +172,7 @@ export class CMIInteractionsObject extends BaseCMI {
172
172
  set weighting(weighting: string) {
173
173
  if (this.initialized && this._id === "") {
174
174
  throw new Scorm2004ValidationError(
175
- scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED,
175
+ scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED as number,
176
176
  );
177
177
  } else {
178
178
  if (check2004ValidFormat(weighting, scorm2004_regex.CMIDecimal)) {
@@ -197,7 +197,7 @@ export class CMIInteractionsObject extends BaseCMI {
197
197
  set learner_response(learner_response: string) {
198
198
  if (this.initialized && (this._type === "" || this._id === "")) {
199
199
  throw new Scorm2004ValidationError(
200
- scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED,
200
+ scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED as number,
201
201
  );
202
202
  } else {
203
203
  let nodes = [];
@@ -215,39 +215,39 @@ export class CMIInteractionsObject extends BaseCMI {
215
215
 
216
216
  for (let i = 0; i < nodes.length; i++) {
217
217
  if (response_type?.delimiter2) {
218
- const values = nodes[i].split(response_type.delimiter2);
218
+ const values = nodes[i]?.split(response_type.delimiter2);
219
219
 
220
- if (values.length === 2) {
221
- if (!values[0].match(formatRegex)) {
220
+ if (values?.length === 2) {
221
+ if (!values[0]?.match(formatRegex)) {
222
222
  throw new Scorm2004ValidationError(
223
- scorm2004_errors.TYPE_MISMATCH,
223
+ scorm2004_errors.TYPE_MISMATCH as number,
224
224
  );
225
225
  } else {
226
226
  if (
227
227
  !response_type.format2 ||
228
- !values[1].match(new RegExp(response_type.format2))
228
+ !values[1]?.match(new RegExp(response_type.format2))
229
229
  ) {
230
230
  throw new Scorm2004ValidationError(
231
- scorm2004_errors.TYPE_MISMATCH,
231
+ scorm2004_errors.TYPE_MISMATCH as number,
232
232
  );
233
233
  }
234
234
  }
235
235
  } else {
236
236
  throw new Scorm2004ValidationError(
237
- scorm2004_errors.TYPE_MISMATCH,
237
+ scorm2004_errors.TYPE_MISMATCH as number,
238
238
  );
239
239
  }
240
240
  } else {
241
- if (!nodes[i].match(formatRegex)) {
241
+ if (!nodes[i]?.match(formatRegex)) {
242
242
  throw new Scorm2004ValidationError(
243
- scorm2004_errors.TYPE_MISMATCH,
243
+ scorm2004_errors.TYPE_MISMATCH as number,
244
244
  );
245
245
  } else {
246
246
  if (nodes[i] !== "" && response_type.unique) {
247
247
  for (let j = 0; j < i; j++) {
248
248
  if (nodes[i] === nodes[j]) {
249
249
  throw new Scorm2004ValidationError(
250
- scorm2004_errors.TYPE_MISMATCH,
250
+ scorm2004_errors.TYPE_MISMATCH as number,
251
251
  );
252
252
  }
253
253
  }
@@ -257,13 +257,15 @@ export class CMIInteractionsObject extends BaseCMI {
257
257
  }
258
258
  } else {
259
259
  throw new Scorm2004ValidationError(
260
- scorm2004_errors.GENERAL_SET_FAILURE,
260
+ scorm2004_errors.GENERAL_SET_FAILURE as number,
261
261
  );
262
262
  }
263
263
 
264
264
  this._learner_response = learner_response;
265
265
  } else {
266
- throw new Scorm2004ValidationError(scorm2004_errors.TYPE_MISMATCH);
266
+ throw new Scorm2004ValidationError(
267
+ scorm2004_errors.TYPE_MISMATCH as number,
268
+ );
267
269
  }
268
270
  }
269
271
  }
@@ -301,7 +303,7 @@ export class CMIInteractionsObject extends BaseCMI {
301
303
  set latency(latency: string) {
302
304
  if (this.initialized && this._id === "") {
303
305
  throw new Scorm2004ValidationError(
304
- scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED,
306
+ scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED as number,
305
307
  );
306
308
  } else {
307
309
  if (check2004ValidFormat(latency, scorm2004_regex.CMITimespan)) {
@@ -325,7 +327,7 @@ export class CMIInteractionsObject extends BaseCMI {
325
327
  set description(description: string) {
326
328
  if (this.initialized && this._id === "") {
327
329
  throw new Scorm2004ValidationError(
328
- scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED,
330
+ scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED as number,
329
331
  );
330
332
  } else {
331
333
  if (
@@ -44,7 +44,9 @@ export class CMILearnerPreference extends BaseCMI {
44
44
  * @private
45
45
  */
46
46
  set _children(_children: string) {
47
- throw new Scorm2004ValidationError(scorm2004_errors.READ_ONLY_ELEMENT);
47
+ throw new Scorm2004ValidationError(
48
+ scorm2004_errors.READ_ONLY_ELEMENT as number,
49
+ );
48
50
  }
49
51
 
50
52
  /**
@@ -18,7 +18,7 @@ export class CMIObjectives extends CMIArray {
18
18
  constructor() {
19
19
  super({
20
20
  children: scorm2004_constants.objectives_children,
21
- errorCode: scorm2004_errors.READ_ONLY_ELEMENT,
21
+ errorCode: scorm2004_errors.READ_ONLY_ELEMENT as number,
22
22
  errorClass: Scorm2004ValidationError,
23
23
  });
24
24
  }
@@ -110,7 +110,7 @@ export class CMIObjectivesObject extends BaseCMI {
110
110
  set success_status(success_status: string) {
111
111
  if (this.initialized && this._id === "") {
112
112
  throw new Scorm2004ValidationError(
113
- scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED,
113
+ scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED as number,
114
114
  );
115
115
  } else {
116
116
  if (check2004ValidFormat(success_status, scorm2004_regex.CMISStatus)) {
@@ -134,7 +134,7 @@ export class CMIObjectivesObject extends BaseCMI {
134
134
  set completion_status(completion_status: string) {
135
135
  if (this.initialized && this._id === "") {
136
136
  throw new Scorm2004ValidationError(
137
- scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED,
137
+ scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED as number,
138
138
  );
139
139
  } else {
140
140
  if (check2004ValidFormat(completion_status, scorm2004_regex.CMICStatus)) {
@@ -158,7 +158,7 @@ export class CMIObjectivesObject extends BaseCMI {
158
158
  set progress_measure(progress_measure: string) {
159
159
  if (this.initialized && this._id === "") {
160
160
  throw new Scorm2004ValidationError(
161
- scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED,
161
+ scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED as number,
162
162
  );
163
163
  } else {
164
164
  if (
@@ -185,7 +185,7 @@ export class CMIObjectivesObject extends BaseCMI {
185
185
  set description(description: string) {
186
186
  if (this.initialized && this._id === "") {
187
187
  throw new Scorm2004ValidationError(
188
- scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED,
188
+ scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED as number,
189
189
  );
190
190
  } else {
191
191
  if (
@@ -18,9 +18,9 @@ export class Scorm2004CMIScore extends CMIScore {
18
18
  super({
19
19
  score_children: scorm2004_constants.score_children,
20
20
  max: "",
21
- invalidErrorCode: scorm2004_errors.READ_ONLY_ELEMENT,
22
- invalidTypeCode: scorm2004_errors.TYPE_MISMATCH,
23
- invalidRangeCode: scorm2004_errors.VALUE_OUT_OF_RANGE,
21
+ invalidErrorCode: scorm2004_errors.READ_ONLY_ELEMENT as number,
22
+ invalidTypeCode: scorm2004_errors.TYPE_MISMATCH as number,
23
+ invalidRangeCode: scorm2004_errors.VALUE_OUT_OF_RANGE as number,
24
24
  decimalRegex: scorm2004_regex.CMIDecimal,
25
25
  errorClass: Scorm2004ValidationError,
26
26
  });
@@ -17,7 +17,7 @@ export function check2004ValidFormat(
17
17
  return checkValidFormat(
18
18
  value,
19
19
  regexPattern,
20
- scorm2004_errors.TYPE_MISMATCH,
20
+ scorm2004_errors.TYPE_MISMATCH as number,
21
21
  Scorm2004ValidationError,
22
22
  allowEmptyString,
23
23
  );
@@ -36,7 +36,7 @@ export function check2004ValidRange(
36
36
  return checkValidRange(
37
37
  value,
38
38
  rangePattern,
39
- scorm2004_errors.VALUE_OUT_OF_RANGE,
39
+ scorm2004_errors.VALUE_OUT_OF_RANGE as number,
40
40
  Scorm2004ValidationError,
41
41
  );
42
42
  }
@@ -9,7 +9,14 @@ export const scorm12_regex = {
9
9
  CMIDecimal: "^-?([0-9]{0,3})(.[0-9]*)?$",
10
10
 
11
11
  CMIIdentifier: "^[\\u0021-\\u007E\\s]{0,255}$",
12
- CMIFeedback: "^.{0,255}$",
12
+ // Allow storing larger responses for interactions
13
+ // Some content packages may exceed the 255 character limit
14
+ // defined in the SCORM 1.2 specification. The previous
15
+ // expression truncated these values which resulted in
16
+ // a "101: General Exception" being thrown when long
17
+ // answers were supplied. To support these packages we
18
+ // relax the limitation and accept any length string.
19
+ CMIFeedback: "^.*$",
13
20
  // This must be redefined
14
21
  CMIIndex: "[._](\\d+).",
15
22
  // Vocabulary Data Type Definition
@@ -15,14 +15,14 @@ export class AICCValidationError extends ValidationError {
15
15
  if ({}.hasOwnProperty.call(aicc_errors, String(errorCode))) {
16
16
  super(
17
17
  errorCode,
18
- aicc_errors[String(errorCode)].basicMessage,
19
- aicc_errors[String(errorCode)].detailMessage,
18
+ aicc_errors[String(errorCode)]?.basicMessage || "Unknown rror",
19
+ aicc_errors[String(errorCode)]?.detailMessage,
20
20
  );
21
21
  } else {
22
22
  super(
23
23
  101,
24
- aicc_errors["101"].basicMessage,
25
- aicc_errors["101"].detailMessage,
24
+ aicc_errors["101"]?.basicMessage || "General error",
25
+ aicc_errors["101"]?.detailMessage,
26
26
  );
27
27
  }
28
28
  }
@@ -15,14 +15,14 @@ export class Scorm12ValidationError extends ValidationError {
15
15
  if ({}.hasOwnProperty.call(scorm12_errors, String(errorCode))) {
16
16
  super(
17
17
  errorCode,
18
- scorm12_errors[String(errorCode)].basicMessage,
19
- scorm12_errors[String(errorCode)].detailMessage,
18
+ scorm12_errors[String(errorCode)]?.basicMessage || "Unknown error",
19
+ scorm12_errors[String(errorCode)]?.detailMessage,
20
20
  );
21
21
  } else {
22
22
  super(
23
23
  101,
24
- scorm12_errors["101"].basicMessage,
25
- scorm12_errors["101"].detailMessage,
24
+ scorm12_errors["101"]?.basicMessage ?? "General error",
25
+ scorm12_errors["101"]?.detailMessage,
26
26
  );
27
27
  }
28
28
  }
@@ -15,14 +15,14 @@ export class Scorm2004ValidationError extends ValidationError {
15
15
  if ({}.hasOwnProperty.call(scorm2004_errors, String(errorCode))) {
16
16
  super(
17
17
  errorCode,
18
- scorm2004_errors[String(errorCode)].basicMessage,
19
- scorm2004_errors[String(errorCode)].detailMessage,
18
+ scorm2004_errors[String(errorCode)]?.basicMessage || "Unknown error",
19
+ scorm2004_errors[String(errorCode)]?.detailMessage,
20
20
  );
21
21
  } else {
22
22
  super(
23
23
  101,
24
- scorm2004_errors["101"].basicMessage,
25
- scorm2004_errors["101"].detailMessage,
24
+ scorm2004_errors["101"]?.basicMessage || "General error",
25
+ scorm2004_errors["101"]?.detailMessage,
26
26
  );
27
27
  }
28
28
  }
package/src/utilities.ts CHANGED
@@ -68,7 +68,7 @@ export function getSecondsAsISODuration(seconds: number | null): string {
68
68
  let duration = "P";
69
69
  let remainder = seconds;
70
70
  for (const designationsKey in designations) {
71
- const current_seconds = designations[designationsKey];
71
+ const current_seconds = designations[designationsKey] || 1;
72
72
  let value = Math.floor(remainder / current_seconds);
73
73
  remainder = remainder % current_seconds;
74
74
 
@@ -259,7 +259,7 @@ export function unflatten(data: StringKeyMap): object {
259
259
 
260
260
  while (m) {
261
261
  cur = cur[prop] || (cur[prop] = m[2] ? [] : {});
262
- prop = m[2] || m[1];
262
+ prop = m[2] || m[1] || "";
263
263
  m = regex.exec(p);
264
264
  }
265
265
 
@@ -278,7 +278,7 @@ export function unflatten(data: StringKeyMap): object {
278
278
  export function countDecimals(num: number): number {
279
279
  if (Math.floor(num) === num || String(num).indexOf(".") < 0) return 0;
280
280
  const parts = num.toString().split(".")[1];
281
- return parts.length || 0;
281
+ return parts?.length || 0;
282
282
  }
283
283
 
284
284
  /**
@@ -841,6 +841,51 @@ describe("SCORM 1.2 API Tests", () => {
841
841
  expect(callback3.calledTwice).toBe(true);
842
842
  expect(callback4.calledTwice).toBe(true);
843
843
  });
844
+
845
+ it("Should handle multiple events in one listener string", async () => {
846
+ const scorm12API = api({
847
+ ...DefaultSettings,
848
+ ...{
849
+ lmsCommitUrl: "/scorm12",
850
+ autocommit: true,
851
+ autocommitSeconds: 1,
852
+ },
853
+ });
854
+ scorm12API.lmsInitialize();
855
+
856
+ const callback = sinon.spy();
857
+ scorm12API.on("LMSSetValue.cmi.core.session_time CommitSuccess", callback);
858
+
859
+ scorm12API.lmsSetValue("cmi.core.session_time", "00:01:00");
860
+ clock.tick(2000);
861
+
862
+ await clock.runAllAsync();
863
+
864
+ expect(callback.calledTwice).toBe(true);
865
+ });
866
+
867
+ it("Should detach multiple events using off()", async () => {
868
+ const scorm12API = api({
869
+ ...DefaultSettings,
870
+ ...{
871
+ lmsCommitUrl: "/scorm12",
872
+ autocommit: true,
873
+ autocommitSeconds: 1,
874
+ },
875
+ });
876
+ scorm12API.lmsInitialize();
877
+
878
+ const callback = sinon.spy();
879
+ scorm12API.on("LMSSetValue.cmi.core.session_time CommitSuccess", callback);
880
+ scorm12API.off("LMSSetValue.cmi.core.session_time CommitSuccess", callback);
881
+
882
+ scorm12API.lmsSetValue("cmi.core.session_time", "00:01:00");
883
+ clock.tick(2000);
884
+
885
+ await clock.runAllAsync();
886
+
887
+ expect(callback.called).toBe(false);
888
+ });
844
889
  it("Should handle CommitError event", async () => {
845
890
  const scorm12API = api({
846
891
  ...DefaultSettings,
@@ -1356,6 +1356,49 @@ describe("SCORM 2004 API Tests", () => {
1356
1356
  expect(callback3.calledTwice).toBe(true);
1357
1357
  expect(callback4.calledTwice).toBe(true);
1358
1358
  });
1359
+
1360
+ it("Should handle multiple events in one listener string", async () => {
1361
+ const scorm2004API = api({
1362
+ ...DefaultSettings,
1363
+ ...{
1364
+ lmsCommitUrl: "/scorm2004",
1365
+ autocommit: true,
1366
+ autocommitSeconds: 1,
1367
+ },
1368
+ });
1369
+ scorm2004API.lmsInitialize();
1370
+
1371
+ const callback = sinon.spy();
1372
+ scorm2004API.on("SetValue.cmi.learner_id CommitSuccess", callback);
1373
+
1374
+ scorm2004API.lmsSetValue("cmi.learner_id", "@jcputney");
1375
+ scorm2004API.lmsCommit();
1376
+ await clock.runAllAsync();
1377
+
1378
+ expect(callback.calledTwice).toBe(true);
1379
+ });
1380
+
1381
+ it("Should detach multiple events using off()", async () => {
1382
+ const scorm2004API = api({
1383
+ ...DefaultSettings,
1384
+ ...{
1385
+ lmsCommitUrl: "/scorm2004",
1386
+ autocommit: true,
1387
+ autocommitSeconds: 1,
1388
+ },
1389
+ });
1390
+ scorm2004API.lmsInitialize();
1391
+
1392
+ const callback = sinon.spy();
1393
+ scorm2004API.on("SetValue.cmi.learner_id CommitSuccess", callback);
1394
+ scorm2004API.off("SetValue.cmi.learner_id CommitSuccess", callback);
1395
+
1396
+ scorm2004API.lmsSetValue("cmi.learner_id", "@jcputney");
1397
+ scorm2004API.lmsCommit();
1398
+ await clock.runAllAsync();
1399
+
1400
+ expect(callback.called).toBe(false);
1401
+ });
1359
1402
  it("Should handle CommitError event", async () => {
1360
1403
  const scorm2004API = api({
1361
1404
  ...DefaultSettings,
package/tsconfig.json CHANGED
@@ -3,6 +3,7 @@
3
3
  "sourceMap": true,
4
4
  "noImplicitAny": true,
5
5
  "noImplicitOverride": true,
6
+ "noUncheckedIndexedAccess": true,
6
7
  "declaration": false,
7
8
  "module": "es2020",
8
9
  "moduleResolution": "Node",