scorm-again 1.7.1 → 2.1.0

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 (124) hide show
  1. package/.babelrc +18 -7
  2. package/.github/dependabot.yml +5 -0
  3. package/.github/workflows/main.yml +79 -0
  4. package/.github/workflows/stale.yml +14 -0
  5. package/.jsdoc.json +4 -5
  6. package/.mocharc.json +8 -0
  7. package/.run/{Mocha Unit Tests.run.xml → Mocha Unit Tests (watch).run.xml } +6 -3
  8. package/.run/Template Mocha.run.xml +17 -0
  9. package/CONTRIBUTING.md +1 -1
  10. package/README.md +183 -71
  11. package/dist/aicc.js +3822 -7030
  12. package/dist/aicc.js.map +1 -1
  13. package/dist/aicc.min.js +2 -40
  14. package/dist/aicc.min.js.map +1 -0
  15. package/dist/scorm-again.js +5965 -10498
  16. package/dist/scorm-again.js.map +1 -1
  17. package/dist/scorm-again.min.js +2 -52
  18. package/dist/scorm-again.min.js.map +1 -0
  19. package/dist/scorm12.js +3028 -5373
  20. package/dist/scorm12.js.map +1 -1
  21. package/dist/scorm12.min.js +2 -34
  22. package/dist/scorm12.min.js.map +1 -0
  23. package/dist/scorm2004.js +4054 -6693
  24. package/dist/scorm2004.js.map +1 -1
  25. package/dist/scorm2004.min.js +2 -40
  26. package/dist/scorm2004.min.js.map +1 -0
  27. package/eslint.config.js +21 -0
  28. package/package.json +76 -34
  29. package/results.json +34254 -0
  30. package/src/AICC.ts +72 -0
  31. package/src/BaseAPI.ts +1300 -0
  32. package/src/Scorm12API.ts +387 -0
  33. package/src/Scorm2004API.ts +688 -0
  34. package/src/cmi/aicc/attempts.ts +94 -0
  35. package/src/cmi/aicc/cmi.ts +100 -0
  36. package/src/cmi/aicc/core.ts +360 -0
  37. package/src/cmi/aicc/evaluation.ts +157 -0
  38. package/src/cmi/aicc/paths.ts +180 -0
  39. package/src/cmi/aicc/student_data.ts +86 -0
  40. package/src/cmi/aicc/student_demographics.ts +367 -0
  41. package/src/cmi/aicc/student_preferences.ts +176 -0
  42. package/src/cmi/aicc/tries.ts +116 -0
  43. package/src/cmi/aicc/validation.ts +25 -0
  44. package/src/cmi/common/array.ts +77 -0
  45. package/src/cmi/common/base_cmi.ts +46 -0
  46. package/src/cmi/common/score.ts +203 -0
  47. package/src/cmi/common/validation.ts +60 -0
  48. package/src/cmi/scorm12/cmi.ts +224 -0
  49. package/src/cmi/scorm12/interactions.ts +368 -0
  50. package/src/cmi/scorm12/nav.ts +54 -0
  51. package/src/cmi/scorm12/objectives.ts +112 -0
  52. package/src/cmi/scorm12/student_data.ts +130 -0
  53. package/src/cmi/scorm12/student_preference.ts +158 -0
  54. package/src/cmi/scorm12/validation.ts +48 -0
  55. package/src/cmi/scorm2004/adl.ts +272 -0
  56. package/src/cmi/scorm2004/cmi.ts +599 -0
  57. package/src/cmi/scorm2004/comments.ts +163 -0
  58. package/src/cmi/scorm2004/interactions.ts +466 -0
  59. package/src/cmi/scorm2004/learner_preference.ts +152 -0
  60. package/src/cmi/scorm2004/objectives.ts +212 -0
  61. package/src/cmi/scorm2004/score.ts +78 -0
  62. package/src/cmi/scorm2004/validation.ts +42 -0
  63. package/src/constants/api_constants.ts +318 -0
  64. package/src/constants/default_settings.ts +81 -0
  65. package/src/constants/enums.ts +5 -0
  66. package/src/constants/error_codes.ts +88 -0
  67. package/src/constants/language_constants.ts +394 -0
  68. package/src/constants/regex.ts +97 -0
  69. package/src/constants/{response_constants.js → response_constants.ts} +69 -62
  70. package/src/exceptions.ts +154 -0
  71. package/src/exports/aicc.js +1 -1
  72. package/src/exports/scorm-again.js +3 -3
  73. package/src/exports/scorm12.js +1 -1
  74. package/src/exports/scorm2004.js +1 -1
  75. package/src/helpers/scheduled_commit.ts +42 -0
  76. package/src/interfaces/IBaseAPI.ts +35 -0
  77. package/src/types/api_types.ts +32 -0
  78. package/src/utilities/debounce.ts +31 -0
  79. package/src/utilities.ts +338 -0
  80. package/tea.yaml +6 -0
  81. package/test/{AICC.spec.js → AICC.spec.ts} +79 -71
  82. package/test/Scorm12API.spec.ts +833 -0
  83. package/test/Scorm2004API.spec.ts +1298 -0
  84. package/test/api_helpers.ts +176 -0
  85. package/test/cmi/aicc_cmi.spec.ts +845 -0
  86. package/test/cmi/{scorm12_cmi.spec.js → scorm12_cmi.spec.ts} +253 -271
  87. package/test/cmi/scorm2004_cmi.spec.ts +1031 -0
  88. package/test/cmi_helpers.ts +207 -0
  89. package/test/exceptions.spec.ts +79 -0
  90. package/test/field_values.ts +202 -0
  91. package/test/types/api_types.spec.ts +126 -0
  92. package/test/utilities/debounce.spec.ts +56 -0
  93. package/test/utilities.spec.ts +322 -0
  94. package/tsconfig.json +18 -0
  95. package/webpack.config.js +65 -0
  96. package/.circleci/config.yml +0 -99
  97. package/.codeclimate.yml +0 -7
  98. package/.eslintrc.js +0 -36
  99. package/src/.flowconfig +0 -11
  100. package/src/AICC.js +0 -68
  101. package/src/BaseAPI.js +0 -1275
  102. package/src/Scorm12API.js +0 -308
  103. package/src/Scorm2004API.js +0 -572
  104. package/src/cmi/aicc_cmi.js +0 -1141
  105. package/src/cmi/common.js +0 -328
  106. package/src/cmi/scorm12_cmi.js +0 -1312
  107. package/src/cmi/scorm2004_cmi.js +0 -1692
  108. package/src/constants/api_constants.js +0 -218
  109. package/src/constants/error_codes.js +0 -87
  110. package/src/constants/language_constants.js +0 -76
  111. package/src/constants/regex.js +0 -84
  112. package/src/exceptions.js +0 -104
  113. package/src/utilities.js +0 -242
  114. package/test/Scorm12API.spec.js +0 -528
  115. package/test/Scorm2004API.spec.js +0 -775
  116. package/test/abstract_classes.spec.js +0 -17
  117. package/test/api_helpers.js +0 -128
  118. package/test/cmi/aicc_cmi.spec.js +0 -684
  119. package/test/cmi/scorm2004_cmi.spec.js +0 -1066
  120. package/test/cmi_helpers.js +0 -161
  121. package/test/exceptions.spec.js +0 -71
  122. package/test/field_values.js +0 -353
  123. package/test/utilities.spec.js +0 -339
  124. package/webpack.js +0 -78
@@ -0,0 +1,1031 @@
1
+ import { describe, it } from "mocha";
2
+ import ErrorCodes from "../../src/constants/error_codes";
3
+ import APIConstants from "../../src/constants/api_constants";
4
+ import { CMI } from "../../src/cmi/scorm2004/cmi";
5
+ import * as h from "../cmi_helpers";
6
+ import { expect } from "expect";
7
+ import { scorm2004Values } from "../field_values";
8
+ import {
9
+ CMIInteractionsCorrectResponsesObject,
10
+ CMIInteractionsObject,
11
+ CMIInteractionsObjectivesObject,
12
+ } from "../../src/cmi/scorm2004/interactions";
13
+ import { CMICommentsObject } from "../../src/cmi/scorm2004/comments";
14
+ import { CMIObjectivesObject } from "../../src/cmi/scorm2004/objectives";
15
+ import { ADL } from "../../src/cmi/scorm2004/adl";
16
+
17
+ const scorm2004_constants = APIConstants.scorm2004;
18
+ const scorm2004_error_codes = ErrorCodes.scorm2004;
19
+
20
+ const read_only = scorm2004_error_codes.READ_ONLY_ELEMENT;
21
+ const write_only = scorm2004_error_codes.WRITE_ONLY_ELEMENT;
22
+ const type_mismatch = scorm2004_error_codes.TYPE_MISMATCH;
23
+
24
+ const cmi = () => {
25
+ return new CMI();
26
+ };
27
+ const cmiInitialized = () => {
28
+ const cmiObj = new CMI();
29
+ cmiObj.initialize();
30
+ return cmiObj;
31
+ };
32
+ const comments = () => {
33
+ return new CMICommentsObject();
34
+ };
35
+ const lmsComments = () => {
36
+ return new CMICommentsObject(true);
37
+ };
38
+ const lmsCommentsInitialized = () => {
39
+ const cmi = lmsComments();
40
+ cmi.initialize();
41
+ return cmi;
42
+ };
43
+ const interaction = () => {
44
+ return new CMIInteractionsObject();
45
+ };
46
+ const interactionInitialized = () => {
47
+ const cmi = new CMIInteractionsObject();
48
+ cmi.initialize();
49
+ return cmi;
50
+ };
51
+ const objective = () => {
52
+ return new CMIObjectivesObject();
53
+ };
54
+ const objectiveInitialized = () => {
55
+ const cmi = new CMIObjectivesObject();
56
+ cmi.initialize();
57
+ return cmi;
58
+ };
59
+ const interactionObjective = () => {
60
+ return new CMIInteractionsObjectivesObject();
61
+ };
62
+ const correctResponse = () => {
63
+ return new CMIInteractionsCorrectResponsesObject();
64
+ };
65
+ const adl = () => {
66
+ return new ADL();
67
+ };
68
+
69
+ describe("SCORM 2004 CMI Tests", () => {
70
+ describe("getCurrentTotalTime()", () => {
71
+ h.checkGetCurrentTotalTime({
72
+ cmi: cmi(),
73
+ startingTotal: "PT0S",
74
+ sessionTime: "PT15M45S",
75
+ expectedTotal: "PT15M45S",
76
+ totalFieldName: "cmi.total_time",
77
+ sessionFieldName: "cmi.session_time",
78
+ });
79
+ h.checkGetCurrentTotalTime({
80
+ cmi: cmi(),
81
+ startingTotal: "PT60S",
82
+ sessionTime: "PT15M45S",
83
+ expectedTotal: "PT16M45S",
84
+ totalFieldName: "cmi.total_time",
85
+ sessionFieldName: "cmi.session_time",
86
+ });
87
+ h.checkGetCurrentTotalTime({
88
+ cmi: cmi(),
89
+ startingTotal: "PT60S",
90
+ sessionTime: "PT0S",
91
+ expectedTotal: "PT1M",
92
+ totalFieldName: "cmi.total_time",
93
+ sessionFieldName: "cmi.session_time",
94
+ });
95
+ h.checkGetCurrentTotalTime({
96
+ cmi: cmi(),
97
+ startingTotal: "PT25H1M0S",
98
+ sessionTime: "PT13H",
99
+ expectedTotal: "P1DT14H1M",
100
+ totalFieldName: "cmi.total_time",
101
+ sessionFieldName: "cmi.session_time",
102
+ });
103
+ h.checkGetCurrentTotalTime({
104
+ cmi: cmi(),
105
+ startingTotal: "PT48H1M45S",
106
+ sessionTime: "PT13H16S",
107
+ expectedTotal: "P2DT13H2M1S",
108
+ totalFieldName: "cmi.total_time",
109
+ sessionFieldName: "cmi.session_time",
110
+ });
111
+ });
112
+
113
+ describe("CMI Spec Tests", () => {
114
+ describe("Pre-Initialize Tests", () => {
115
+ /**
116
+ * Base CMI Properties
117
+ */
118
+ h.checkReadOnly({
119
+ cmi: cmi(),
120
+ fieldName: "cmi._version",
121
+ expectedValue: "1.0",
122
+ expectedError: read_only,
123
+ });
124
+ h.checkReadOnly({
125
+ cmi: cmi(),
126
+ fieldName: "cmi._children",
127
+ expectedValue: scorm2004_constants.cmi_children,
128
+ expectedError: read_only,
129
+ });
130
+ h.checkValidValues({
131
+ cmi: cmi(),
132
+ fieldName: "cmi.completion_status",
133
+ validValues: scorm2004Values.validCStatus,
134
+ invalidValues: scorm2004Values.invalidCStatus,
135
+ });
136
+ h.checkReadAndWrite({
137
+ cmi: cmi(),
138
+ fieldName: "cmi.completion_threshold",
139
+ });
140
+ h.checkReadAndWrite({
141
+ cmi: cmi(),
142
+ fieldName: "cmi.credit",
143
+ expectedValue: "credit",
144
+ });
145
+ h.checkReadAndWrite({
146
+ cmi: cmi(),
147
+ fieldName: "cmi.entry",
148
+ });
149
+ h.checkWriteOnly({
150
+ cmi: cmi(),
151
+ fieldName: "cmi.exit",
152
+ expectedError: write_only,
153
+ valueToTest: "time-out",
154
+ });
155
+ h.checkValidValues({
156
+ cmi: cmi(),
157
+ fieldName: "cmi.exit",
158
+ validValues: scorm2004Values.validExit,
159
+ invalidValues: scorm2004Values.invalidExit,
160
+ });
161
+ h.checkReadAndWrite({
162
+ cmi: cmi(),
163
+ fieldName: "cmi.launch_data",
164
+ });
165
+ h.checkReadAndWrite({
166
+ cmi: cmi(),
167
+ fieldName: "cmi.learner_id",
168
+ });
169
+ h.checkReadAndWrite({
170
+ cmi: cmi(),
171
+ fieldName: "cmi.learner_name",
172
+ });
173
+ h.checkFieldConstraintSize({
174
+ cmi: cmi(),
175
+ fieldName: "cmi.location",
176
+ limit: 1000,
177
+ expectedError: type_mismatch,
178
+ });
179
+ h.checkReadAndWrite({
180
+ cmi: cmi(),
181
+ fieldName: "cmi.max_time_allowed",
182
+ });
183
+ h.checkReadAndWrite({
184
+ cmi: cmi(),
185
+ fieldName: "cmi.mode",
186
+ expectedValue: "normal",
187
+ });
188
+ h.checkReadAndWrite({
189
+ cmi: cmi(),
190
+ fieldName: "cmi.max_time_allowed",
191
+ });
192
+ h.checkValidValues({
193
+ cmi: cmi(),
194
+ fieldName: "cmi.progress_measure",
195
+ validValues: scorm2004Values.valid0To1Range,
196
+ invalidValues: scorm2004Values.invalid0To1Range,
197
+ });
198
+ h.checkReadAndWrite({
199
+ cmi: cmi(),
200
+ fieldName: "cmi.scaled_passing_score",
201
+ });
202
+ h.checkWriteOnly({
203
+ cmi: cmi(),
204
+ fieldName: "cmi.session_time",
205
+ valueToTest: "P0S",
206
+ expectedError: write_only,
207
+ });
208
+ h.checkValidValues({
209
+ cmi: cmi(),
210
+ fieldName: "cmi.session_time",
211
+ validValues: scorm2004Values.validISO8601Durations,
212
+ invalidValues: scorm2004Values.invalidISO8601Durations,
213
+ });
214
+ h.checkRead({
215
+ cmi: cmi(),
216
+ fieldName: "cmi.success_status",
217
+ expectedValue: "unknown",
218
+ });
219
+ h.checkValidValues({
220
+ cmi: cmi(),
221
+ fieldName: "cmi.success_status",
222
+ validValues: scorm2004Values.validSStatus,
223
+ invalidValues: scorm2004Values.invalidSStatus,
224
+ });
225
+ h.checkFieldConstraintSize({
226
+ cmi: cmi(),
227
+ fieldName: "cmi.suspend_data",
228
+ limit: 64000,
229
+ expectedError: type_mismatch,
230
+ });
231
+ h.checkReadAndWrite({
232
+ cmi: cmi(),
233
+ fieldName: "cmi.time_limit_action",
234
+ expectedValue: "continue,no message",
235
+ });
236
+ h.checkReadAndWrite({
237
+ cmi: cmi(),
238
+ fieldName: "cmi.total_time",
239
+ expectedValue: "",
240
+ });
241
+
242
+ /**
243
+ * cmi.learner_preference Properties
244
+ */
245
+ h.checkReadOnly({
246
+ cmi: cmi(),
247
+ fieldName: "cmi.learner_preference._children",
248
+ expectedValue: scorm2004_constants.student_preference_children,
249
+ expectedError: read_only,
250
+ });
251
+ h.checkValidValues({
252
+ cmi: cmi(),
253
+ fieldName: "cmi.learner_preference.audio_level",
254
+ validValues: scorm2004Values.valid0To100Range,
255
+ invalidValues: scorm2004Values.invalid0To100Range,
256
+ });
257
+ h.checkValidValues({
258
+ cmi: cmi(),
259
+ fieldName: "cmi.learner_preference.language",
260
+ validValues: ["en", "fr", "ru", "es"],
261
+ invalidValues: ["invalid", "a100"],
262
+ });
263
+ h.checkValidValues({
264
+ cmi: cmi(),
265
+ fieldName: "cmi.learner_preference.delivery_speed",
266
+ validValues: scorm2004Values.valid0To100Range,
267
+ invalidValues: scorm2004Values.invalid0To100Range,
268
+ });
269
+ h.checkValidValues({
270
+ cmi: cmi(),
271
+ fieldName: "cmi.learner_preference.audio_captioning",
272
+ validValues: scorm2004Values.validIntegerScaledRange,
273
+ invalidValues: scorm2004Values.invalidIntegerScaledRange,
274
+ });
275
+
276
+ /**
277
+ * cmi.objectives Properties
278
+ */
279
+ h.checkReadOnly({
280
+ cmi: cmi(),
281
+ fieldName: "cmi.objectives._children",
282
+ expectedValue: scorm2004_constants.objectives_children,
283
+ expectedError: read_only,
284
+ });
285
+ h.checkReadOnly({
286
+ cmi: cmi(),
287
+ fieldName: "cmi.objectives._count",
288
+ expectedValue: 0,
289
+ expectedError: read_only,
290
+ });
291
+
292
+ /**
293
+ * cmi.score Properties
294
+ */
295
+ h.checkReadOnly({
296
+ cmi: cmi(),
297
+ fieldName: "cmi.score._children",
298
+ expectedValue: scorm2004_constants.score_children,
299
+ expectedError: read_only,
300
+ });
301
+ h.checkValidValues({
302
+ cmi: cmi(),
303
+ fieldName: "cmi.score.scaled",
304
+ validValues: scorm2004Values.validScaledRange,
305
+ invalidValues: scorm2004Values.invalidScaledRange,
306
+ });
307
+ h.checkValidValues({
308
+ cmi: cmi(),
309
+ fieldName: "cmi.score.raw",
310
+ validValues: scorm2004Values.validScoreRange,
311
+ invalidValues: scorm2004Values.invalidScoreRange,
312
+ });
313
+ h.checkValidValues({
314
+ cmi: cmi(),
315
+ fieldName: "cmi.score.min",
316
+ validValues: scorm2004Values.validScoreRange,
317
+ invalidValues: scorm2004Values.invalidScoreRange,
318
+ });
319
+ h.checkValidValues({
320
+ cmi: cmi(),
321
+ fieldName: "cmi.score.max",
322
+ validValues: scorm2004Values.validScoreRange,
323
+ invalidValues: scorm2004Values.invalidScoreRange,
324
+ });
325
+
326
+ /**
327
+ * cmi.comments_from_learner Properties
328
+ */
329
+ h.checkReadOnly({
330
+ cmi: cmi(),
331
+ fieldName: "cmi.comments_from_learner._children",
332
+ expectedValue: scorm2004_constants.comments_children,
333
+ expectedError: read_only,
334
+ });
335
+ h.checkReadOnly({
336
+ cmi: cmi(),
337
+ fieldName: "cmi.comments_from_learner._count",
338
+ expectedValue: 0,
339
+ expectedError: read_only,
340
+ });
341
+
342
+ /**
343
+ * cmi.comments_from_lms Properties
344
+ */
345
+ h.checkReadOnly({
346
+ cmi: cmi(),
347
+ fieldName: "cmi.comments_from_lms._children",
348
+ expectedValue: scorm2004_constants.comments_children,
349
+ expectedError: read_only,
350
+ });
351
+ h.checkReadOnly({
352
+ cmi: cmi(),
353
+ fieldName: "cmi.comments_from_lms._count",
354
+ expectedValue: 0,
355
+ expectedError: read_only,
356
+ });
357
+
358
+ /**
359
+ * cmi.interactions Properties
360
+ */
361
+ h.checkReadOnly({
362
+ cmi: cmi(),
363
+ fieldName: "cmi.interactions._children",
364
+ expectedValue: scorm2004_constants.interactions_children,
365
+ expectedError: read_only,
366
+ });
367
+ h.checkReadOnly({
368
+ cmi: cmi(),
369
+ fieldName: "cmi.interactions._count",
370
+ expectedValue: 0,
371
+ expectedError: read_only,
372
+ });
373
+
374
+ /**
375
+ * cmi.objectives Properties
376
+ */
377
+ h.checkReadOnly({
378
+ cmi: cmi(),
379
+ fieldName: "cmi.objectives._children",
380
+ expectedValue: scorm2004_constants.objectives_children,
381
+ expectedError: read_only,
382
+ });
383
+ h.checkReadOnly({
384
+ cmi: cmi(),
385
+ fieldName: "cmi.objectives._count",
386
+ expectedValue: 0,
387
+ expectedError: read_only,
388
+ });
389
+
390
+ it("should export JSON", () => {
391
+ const cmiObj = cmi();
392
+ cmiObj.objectives.childArray.push(new CMIObjectivesObject());
393
+ cmiObj.interactions.childArray.push(new CMIInteractionsObject());
394
+ expect(JSON.stringify(cmiObj)).toEqual(
395
+ '{"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"}',
396
+ );
397
+ });
398
+ });
399
+
400
+ describe("Post-Initialize Tests", () => {
401
+ /**
402
+ * Base CMI Properties
403
+ */
404
+ h.checkReadOnly({
405
+ cmi: cmiInitialized(),
406
+ fieldName: "cmi._version",
407
+ expectedValue: "1.0",
408
+ expectedError: read_only,
409
+ });
410
+ h.checkReadOnly({
411
+ cmi: cmiInitialized(),
412
+ fieldName: "cmi._children",
413
+ expectedValue: scorm2004_constants.cmi_children,
414
+ expectedError: read_only,
415
+ });
416
+ h.checkValidValues({
417
+ cmi: cmiInitialized(),
418
+ fieldName: "cmi.completion_status",
419
+ validValues: scorm2004Values.validCStatus,
420
+ invalidValues: scorm2004Values.invalidCStatus,
421
+ });
422
+ h.checkReadOnly({
423
+ cmi: cmiInitialized(),
424
+ fieldName: "cmi.completion_threshold",
425
+ expectedError: read_only,
426
+ });
427
+ h.checkReadOnly({
428
+ cmi: cmiInitialized(),
429
+ fieldName: "cmi.credit",
430
+ expectedValue: "credit",
431
+ expectedError: read_only,
432
+ });
433
+ h.checkReadOnly({
434
+ cmi: cmiInitialized(),
435
+ fieldName: "cmi.entry",
436
+ expectedError: read_only,
437
+ });
438
+ h.checkWriteOnly({
439
+ cmi: cmiInitialized(),
440
+ fieldName: "cmi.exit",
441
+ expectedError: write_only,
442
+ valueToTest: "time-out",
443
+ });
444
+ h.checkValidValues({
445
+ cmi: cmiInitialized(),
446
+ fieldName: "cmi.exit",
447
+ validValues: scorm2004Values.validExit,
448
+ invalidValues: scorm2004Values.invalidExit,
449
+ });
450
+ h.checkReadOnly({
451
+ cmi: cmiInitialized(),
452
+ fieldName: "cmi.launch_data",
453
+ expectedError: read_only,
454
+ });
455
+ h.checkReadOnly({
456
+ cmi: cmiInitialized(),
457
+ fieldName: "cmi.learner_id",
458
+ expectedError: read_only,
459
+ });
460
+ h.checkReadOnly({
461
+ cmi: cmiInitialized(),
462
+ fieldName: "cmi.learner_name",
463
+ expectedError: read_only,
464
+ });
465
+ h.checkFieldConstraintSize({
466
+ cmi: cmiInitialized(),
467
+ fieldName: "cmi.location",
468
+ limit: 1000,
469
+ expectedError: type_mismatch,
470
+ });
471
+ h.checkReadOnly({
472
+ cmi: cmiInitialized(),
473
+ fieldName: "cmi.max_time_allowed",
474
+ expectedError: read_only,
475
+ });
476
+ h.checkReadOnly({
477
+ cmi: cmiInitialized(),
478
+ fieldName: "cmi.mode",
479
+ expectedValue: "normal",
480
+ expectedError: read_only,
481
+ });
482
+ h.checkReadOnly({
483
+ cmi: cmiInitialized(),
484
+ fieldName: "cmi.max_time_allowed",
485
+ expectedError: read_only,
486
+ });
487
+ h.checkValidValues({
488
+ cmi: cmiInitialized(),
489
+ fieldName: "cmi.progress_measure",
490
+ validValues: scorm2004Values.valid0To1Range,
491
+ invalidValues: scorm2004Values.invalid0To1Range,
492
+ });
493
+ h.checkReadOnly({
494
+ cmi: cmiInitialized(),
495
+ fieldName: "cmi.scaled_passing_score",
496
+ expectedError: read_only,
497
+ });
498
+ h.checkWriteOnly({
499
+ cmi: cmiInitialized(),
500
+ fieldName: "cmi.session_time",
501
+ valueToTest: "P0S",
502
+ expectedError: write_only,
503
+ });
504
+ h.checkValidValues({
505
+ cmi: cmiInitialized(),
506
+ fieldName: "cmi.session_time",
507
+ validValues: scorm2004Values.validISO8601Durations,
508
+ invalidValues: scorm2004Values.invalidISO8601Durations,
509
+ });
510
+ h.checkRead({
511
+ cmi: cmiInitialized(),
512
+ fieldName: "cmi.success_status",
513
+ expectedValue: "unknown",
514
+ });
515
+ h.checkValidValues({
516
+ cmi: cmiInitialized(),
517
+ fieldName: "cmi.success_status",
518
+ validValues: scorm2004Values.validSStatus,
519
+ invalidValues: scorm2004Values.invalidSStatus,
520
+ });
521
+ h.checkFieldConstraintSize({
522
+ cmi: cmiInitialized(),
523
+ fieldName: "cmi.suspend_data",
524
+ limit: 64000,
525
+ expectedError: type_mismatch,
526
+ });
527
+ h.checkReadOnly({
528
+ cmi: cmiInitialized(),
529
+ fieldName: "cmi.time_limit_action",
530
+ expectedValue: "continue,no message",
531
+ expectedError: read_only,
532
+ });
533
+ h.checkReadOnly({
534
+ cmi: cmiInitialized(),
535
+ fieldName: "cmi.total_time",
536
+ expectedValue: "",
537
+ expectedError: read_only,
538
+ });
539
+
540
+ /**
541
+ * cmi.learner_preference Properties
542
+ */
543
+ h.checkReadOnly({
544
+ cmi: cmiInitialized(),
545
+ fieldName: "cmi.learner_preference._children",
546
+ expectedValue: scorm2004_constants.student_preference_children,
547
+ expectedError: read_only,
548
+ });
549
+ h.checkValidValues({
550
+ cmi: cmiInitialized(),
551
+ fieldName: "cmi.learner_preference.audio_level",
552
+ validValues: scorm2004Values.valid0To100Range,
553
+ invalidValues: scorm2004Values.invalid0To100Range,
554
+ });
555
+ h.checkValidValues({
556
+ cmi: cmiInitialized(),
557
+ fieldName: "cmi.learner_preference.language",
558
+ validValues: ["en", "fr", "ru", "es"],
559
+ invalidValues: ["invalid", "a100"],
560
+ });
561
+ h.checkValidValues({
562
+ cmi: cmiInitialized(),
563
+ fieldName: "cmi.learner_preference.delivery_speed",
564
+ validValues: scorm2004Values.valid0To100Range,
565
+ invalidValues: scorm2004Values.invalid0To100Range,
566
+ });
567
+ h.checkValidValues({
568
+ cmi: cmiInitialized(),
569
+ fieldName: "cmi.learner_preference.audio_captioning",
570
+ validValues: scorm2004Values.validIntegerScaledRange,
571
+ invalidValues: scorm2004Values.invalidIntegerScaledRange,
572
+ });
573
+
574
+ /**
575
+ * cmi.objectives Properties
576
+ */
577
+ h.checkReadOnly({
578
+ cmi: cmiInitialized(),
579
+ fieldName: "cmi.objectives._children",
580
+ expectedValue: scorm2004_constants.objectives_children,
581
+ expectedError: read_only,
582
+ });
583
+ h.checkReadOnly({
584
+ cmi: cmiInitialized(),
585
+ fieldName: "cmi.objectives._count",
586
+ expectedValue: 0,
587
+ expectedError: read_only,
588
+ });
589
+
590
+ /**
591
+ * cmi.score Properties
592
+ */
593
+ h.checkReadOnly({
594
+ cmi: cmiInitialized(),
595
+ fieldName: "cmi.score._children",
596
+ expectedValue: scorm2004_constants.score_children,
597
+ expectedError: read_only,
598
+ });
599
+ h.checkValidValues({
600
+ cmi: cmiInitialized(),
601
+ fieldName: "cmi.score.scaled",
602
+ validValues: scorm2004Values.validScaledRange,
603
+ invalidValues: scorm2004Values.invalidScaledRange,
604
+ });
605
+ h.checkValidValues({
606
+ cmi: cmiInitialized(),
607
+ fieldName: "cmi.score.raw",
608
+ validValues: scorm2004Values.validScoreRange,
609
+ invalidValues: scorm2004Values.invalidScoreRange,
610
+ });
611
+ h.checkValidValues({
612
+ cmi: cmiInitialized(),
613
+ fieldName: "cmi.score.min",
614
+ validValues: scorm2004Values.validScoreRange,
615
+ invalidValues: scorm2004Values.invalidScoreRange,
616
+ });
617
+ h.checkValidValues({
618
+ cmi: cmiInitialized(),
619
+ fieldName: "cmi.score.max",
620
+ validValues: scorm2004Values.validScoreRange,
621
+ invalidValues: scorm2004Values.invalidScoreRange,
622
+ });
623
+
624
+ /**
625
+ * cmi.comments_from_learner Properties
626
+ */
627
+ h.checkReadOnly({
628
+ cmi: cmiInitialized(),
629
+ fieldName: "cmi.comments_from_learner._children",
630
+ expectedValue: scorm2004_constants.comments_children,
631
+ expectedError: read_only,
632
+ });
633
+ h.checkReadOnly({
634
+ cmi: cmiInitialized(),
635
+ fieldName: "cmi.comments_from_learner._count",
636
+ expectedValue: 0,
637
+ expectedError: read_only,
638
+ });
639
+
640
+ /**
641
+ * cmi.comments_from_lms Properties
642
+ */
643
+ h.checkReadOnly({
644
+ cmi: cmiInitialized(),
645
+ fieldName: "cmi.comments_from_lms._children",
646
+ expectedValue: scorm2004_constants.comments_children,
647
+ expectedError: read_only,
648
+ });
649
+ h.checkReadOnly({
650
+ cmi: cmiInitialized(),
651
+ fieldName: "cmi.comments_from_lms._count",
652
+ expectedValue: 0,
653
+ expectedError: read_only,
654
+ });
655
+
656
+ /**
657
+ * cmi.interactions Properties
658
+ */
659
+ h.checkReadOnly({
660
+ cmi: cmiInitialized(),
661
+ fieldName: "cmi.interactions._children",
662
+ expectedValue: scorm2004_constants.interactions_children,
663
+ expectedError: read_only,
664
+ });
665
+ h.checkReadOnly({
666
+ cmi: cmiInitialized(),
667
+ fieldName: "cmi.interactions._count",
668
+ expectedValue: 0,
669
+ expectedError: read_only,
670
+ });
671
+
672
+ /**
673
+ * cmi.objectives Properties
674
+ */
675
+ h.checkReadOnly({
676
+ cmi: cmiInitialized(),
677
+ fieldName: "cmi.objectives._children",
678
+ expectedValue: scorm2004_constants.objectives_children,
679
+ expectedError: read_only,
680
+ });
681
+ h.checkReadOnly({
682
+ cmi: cmiInitialized(),
683
+ fieldName: "cmi.objectives._count",
684
+ expectedValue: 0,
685
+ expectedError: read_only,
686
+ });
687
+
688
+ it("should export JSON", () => {
689
+ const cmiObj = cmiInitialized();
690
+ cmiObj.objectives.childArray.push(new CMIObjectivesObject());
691
+ cmiObj.interactions.childArray.push(new CMIInteractionsObject());
692
+ expect(JSON.stringify(cmiObj)).toEqual(
693
+ '{"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"}',
694
+ );
695
+ });
696
+ });
697
+
698
+ describe("CMICommentsObject Tests", () => {
699
+ /**
700
+ * cmi.comments_from_learner.n object
701
+ */
702
+ h.checkValidValues({
703
+ cmi: comments(),
704
+ fieldName: "cmi.comment",
705
+ validValues: scorm2004Values.validComment,
706
+ invalidValues: scorm2004Values.invalidComment,
707
+ });
708
+
709
+ h.checkFieldConstraintSize({
710
+ cmi: comments(),
711
+ fieldName: "cmi.location",
712
+ expectedError: type_mismatch,
713
+ limit: 250,
714
+ });
715
+
716
+ h.checkReadAndWrite({
717
+ cmi: comments(),
718
+ fieldName: "cmi.timestamp",
719
+ valueToTest: "2019-06-25T02:30:00",
720
+ });
721
+ h.checkValidValues({
722
+ cmi: comments(),
723
+ fieldName: "cmi.timestamp",
724
+ validValues: scorm2004Values.validTimestamps,
725
+ invalidValues: scorm2004Values.invalidTimestamps,
726
+ });
727
+
728
+ it("should export JSON", () => {
729
+ const cmi = comments();
730
+ expect(JSON.stringify(cmi)).toEqual(
731
+ '{"comment":"","location":"","timestamp":""}',
732
+ );
733
+ });
734
+ });
735
+
736
+ describe("CMICommentsFromLMSObject Tests", () => {
737
+ /**
738
+ * cmi.comments_from_lms.n object
739
+ */
740
+ h.checkValidValues({
741
+ cmi: lmsComments(),
742
+ fieldName: "cmi.comment",
743
+ validValues: scorm2004Values.validComment,
744
+ invalidValues: scorm2004Values.invalidComment,
745
+ });
746
+
747
+ h.checkFieldConstraintSize({
748
+ cmi: lmsComments(),
749
+ fieldName: "cmi.location",
750
+ expectedError: type_mismatch,
751
+ limit: 250,
752
+ });
753
+
754
+ h.checkReadAndWrite({
755
+ cmi: lmsComments(),
756
+ fieldName: "cmi.timestamp",
757
+ valueToTest: scorm2004Values.validTimestamps[0],
758
+ });
759
+ h.checkValidValues({
760
+ cmi: lmsComments(),
761
+ fieldName: "cmi.timestamp",
762
+ validValues: scorm2004Values.validTimestamps,
763
+ invalidValues: scorm2004Values.invalidTimestamps,
764
+ });
765
+
766
+ h.checkReadOnly({
767
+ cmi: lmsCommentsInitialized(),
768
+ fieldName: "cmi.comment",
769
+ expectedError: read_only,
770
+ });
771
+ h.checkReadOnly({
772
+ cmi: lmsCommentsInitialized(),
773
+ fieldName: "cmi.location",
774
+ expectedError: read_only,
775
+ });
776
+ h.checkReadOnly({
777
+ cmi: lmsCommentsInitialized(),
778
+ fieldName: "cmi.timestamp",
779
+ expectedError: read_only,
780
+ });
781
+
782
+ it("should export JSON", () => {
783
+ const cmi = lmsComments();
784
+ expect(JSON.stringify(cmi)).toEqual(
785
+ '{"comment":"","location":"","timestamp":""}',
786
+ );
787
+ });
788
+ });
789
+
790
+ describe("CMIInteractionsObject Tests", () => {
791
+ /**
792
+ * cmi.interactions.n object
793
+ */
794
+ h.checkReadAndWrite({
795
+ cmi: interaction(),
796
+ fieldName: "cmi.id",
797
+ });
798
+ h.checkReadAndWrite({
799
+ cmi: interactionInitialized(),
800
+ fieldName: "cmi.id",
801
+ });
802
+
803
+ h.checkValidValues({
804
+ cmi: interaction(),
805
+ fieldName: "cmi.timestamp",
806
+ validValues: scorm2004Values.validTimestamps,
807
+ invalidValues: scorm2004Values.invalidTimestamps,
808
+ });
809
+ h.checkValidValues({
810
+ cmi: interaction(),
811
+ fieldName: "cmi.type",
812
+ validValues: scorm2004Values.validType,
813
+ invalidValues: scorm2004Values.invalidType,
814
+ });
815
+ h.checkReadOnly({
816
+ cmi: interaction(),
817
+ fieldName: "cmi.objectives._count",
818
+ expectedValue: 0,
819
+ expectedError: read_only,
820
+ });
821
+ h.checkReadOnly({
822
+ cmi: interaction(),
823
+ fieldName: "cmi.correct_responses._count",
824
+ expectedValue: 0,
825
+ expectedError: read_only,
826
+ });
827
+ h.checkWrite({
828
+ cmi: interaction(),
829
+ fieldName: "cmi.weighting",
830
+ valueToTest: "0",
831
+ });
832
+ h.checkValidValues({
833
+ cmi: interaction(),
834
+ fieldName: "cmi.weighting",
835
+ validValues: scorm2004Values.validScoreRange,
836
+ invalidValues: scorm2004Values.invalidScoreRange,
837
+ });
838
+
839
+ /**
840
+ * TODO: Learner Response depends on first setting Type, so need to build out lots of test cases
841
+ */
842
+
843
+ h.checkRead({
844
+ cmi: interaction(),
845
+ fieldName: "cmi.result",
846
+ });
847
+ h.checkValidValues({
848
+ cmi: interaction(),
849
+ fieldName: "cmi.result",
850
+ validValues: scorm2004Values.validResult.concat([
851
+ "1",
852
+ "999",
853
+ "999.99999",
854
+ ]),
855
+ invalidValues: scorm2004Values.invalidResult,
856
+ });
857
+ h.checkRead({
858
+ cmi: interaction(),
859
+ fieldName: "cmi.latency",
860
+ });
861
+ h.checkValidValues({
862
+ cmi: interaction(),
863
+ fieldName: "cmi.latency",
864
+ validValues: scorm2004Values.validISO8601Durations,
865
+ invalidValues: scorm2004Values.invalidISO8601Durations,
866
+ });
867
+
868
+ h.checkValidValues({
869
+ cmi: interaction(),
870
+ fieldName: "cmi.description",
871
+ validValues: scorm2004Values.validDescription,
872
+ invalidValues: scorm2004Values.invalidDescription,
873
+ });
874
+
875
+ it("should export JSON", () => {
876
+ const cmi = interaction();
877
+ cmi.objectives.childArray.push(new CMIInteractionsObjectivesObject());
878
+ cmi.correct_responses.childArray.push(
879
+ new CMIInteractionsCorrectResponsesObject(),
880
+ );
881
+ expect(JSON.stringify(cmi)).toEqual(
882
+ '{"id":"","type":"","objectives":{"0":{"id":""}},"timestamp":"","weighting":"","learner_response":"","result":"","latency":"","description":"","correct_responses":{"0":{"pattern":""}}}',
883
+ );
884
+ });
885
+ });
886
+
887
+ describe("CMIObjectivesObject Tests", () => {
888
+ /**
889
+ * cmi.objectives.n object
890
+ */
891
+ h.checkReadAndWrite({
892
+ cmi: objective(),
893
+ fieldName: "cmi.id",
894
+ });
895
+ h.checkReadAndWrite({
896
+ cmi: objectiveInitialized(),
897
+ fieldName: "cmi.id",
898
+ });
899
+ h.checkRead({
900
+ cmi: objective(),
901
+ fieldName: "cmi.success_status",
902
+ expectedValue: "unknown",
903
+ });
904
+ h.checkValidValues({
905
+ cmi: objective(),
906
+ fieldName: "cmi.success_status",
907
+ validValues: scorm2004Values.validSStatus,
908
+ invalidValues: scorm2004Values.invalidSStatus,
909
+ });
910
+ h.checkRead({
911
+ cmi: objective(),
912
+ fieldName: "cmi.completion_status",
913
+ expectedValue: "unknown",
914
+ });
915
+ h.checkValidValues({
916
+ cmi: objective(),
917
+ fieldName: "cmi.completion_status",
918
+ validValues: scorm2004Values.validCStatus,
919
+ invalidValues: scorm2004Values.invalidCStatus,
920
+ });
921
+ h.checkValidValues({
922
+ cmi: objective(),
923
+ fieldName: "cmi.progress_measure",
924
+ validValues: scorm2004Values.valid0To1Range,
925
+ invalidValues: scorm2004Values.invalid0To1Range,
926
+ });
927
+ h.checkValidValues({
928
+ cmi: objective(),
929
+ fieldName: "cmi.description",
930
+ validValues: scorm2004Values.validDescription,
931
+ invalidValues: scorm2004Values.invalidDescription,
932
+ });
933
+
934
+ /**
935
+ * cmi.objectives.n.score Properties
936
+ */
937
+ h.checkReadOnly({
938
+ cmi: objective(),
939
+ fieldName: "cmi.score._children",
940
+ expectedValue: scorm2004_constants.score_children,
941
+ expectedError: read_only,
942
+ });
943
+ h.checkValidValues({
944
+ cmi: objective(),
945
+ fieldName: "cmi.score.scaled",
946
+ validValues: scorm2004Values.validScaledRange,
947
+ invalidValues: scorm2004Values.invalidScaledRange,
948
+ });
949
+ h.checkValidValues({
950
+ cmi: objective(),
951
+ fieldName: "cmi.score.raw",
952
+ validValues: scorm2004Values.validScoreRange,
953
+ invalidValues: scorm2004Values.invalidScoreRange,
954
+ });
955
+ h.checkValidValues({
956
+ cmi: objective(),
957
+ fieldName: "cmi.score.min",
958
+ validValues: scorm2004Values.validScoreRange,
959
+ invalidValues: scorm2004Values.invalidScoreRange,
960
+ });
961
+ h.checkValidValues({
962
+ cmi: objective(),
963
+ fieldName: "cmi.score.max",
964
+ validValues: scorm2004Values.validScoreRange,
965
+ invalidValues: scorm2004Values.invalidScoreRange,
966
+ });
967
+
968
+ it("should export JSON", () => {
969
+ const cmi = objective();
970
+ expect(JSON.stringify(cmi)).toEqual(
971
+ '{"id":"","success_status":"unknown","completion_status":"unknown","progress_measure":"","description":"","score":{"scaled":"","raw":"","min":"","max":""}}',
972
+ );
973
+ });
974
+ });
975
+
976
+ describe("CMIInteractionsObjectivesObject Tests", () => {
977
+ /**
978
+ * cmi.interactions.n.objectives.n object
979
+ */
980
+ h.checkReadAndWrite({
981
+ cmi: interactionObjective(),
982
+ fieldName: "cmi.id",
983
+ });
984
+
985
+ it("should export JSON", () => {
986
+ const cmi = interactionObjective();
987
+ expect(JSON.stringify(cmi)).toEqual('{"id":""}');
988
+ });
989
+ });
990
+
991
+ describe("CMIInteractionsCorrectResponsesObject Tests", () => {
992
+ /**
993
+ * cmi.interactions.n.correct_responses.n object
994
+ */
995
+ h.checkReadAndWrite({
996
+ cmi: correctResponse(),
997
+ fieldName: "cmi.pattern",
998
+ });
999
+
1000
+ it("should export JSON", () => {
1001
+ const cmi = correctResponse();
1002
+ expect(JSON.stringify(cmi)).toEqual('{"pattern":""}');
1003
+ });
1004
+ });
1005
+
1006
+ describe("ADL Tests", () => {
1007
+ describe("ADLNav Tests", () => {
1008
+ /**
1009
+ * cmi.interactions.n.correct_responses.n object
1010
+ */
1011
+ h.checkRead({
1012
+ cmi: adl(),
1013
+ fieldName: "cmi.nav.request",
1014
+ expectedValue: "_none_",
1015
+ });
1016
+
1017
+ h.checkValidValues({
1018
+ cmi: adl(),
1019
+ fieldName: "cmi.nav.request",
1020
+ validValues: scorm2004Values.validNavRequest,
1021
+ invalidValues: scorm2004Values.invalidNavRequest,
1022
+ });
1023
+
1024
+ it("should export JSON", () => {
1025
+ const cmi = adl();
1026
+ expect(JSON.stringify(cmi)).toEqual('{"nav":{"request":"_none_"}}');
1027
+ });
1028
+ });
1029
+ });
1030
+ });
1031
+ });