scorm-again 2.1.0 → 2.3.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.
- package/README.md +32 -23
- package/dist/aicc.js +72 -2
- package/dist/aicc.js.map +1 -1
- package/dist/aicc.min.js +1 -1
- package/dist/aicc.min.js.map +1 -1
- package/dist/scorm-again.js +120 -4
- package/dist/scorm-again.js.map +1 -1
- package/dist/scorm-again.min.js +1 -1
- package/dist/scorm-again.min.js.map +1 -1
- package/dist/scorm12.js +72 -2
- package/dist/scorm12.js.map +1 -1
- package/dist/scorm12.min.js +1 -1
- package/dist/scorm12.min.js.map +1 -1
- package/dist/scorm2004.js +69 -2
- package/dist/scorm2004.js.map +1 -1
- package/dist/scorm2004.min.js +1 -1
- package/dist/scorm2004.min.js.map +1 -1
- package/index.d.ts +5 -0
- package/package.json +13 -14
- package/src/BaseAPI.ts +16 -4
- package/src/Scorm12API.ts +70 -5
- package/src/Scorm2004API.ts +74 -4
- package/src/constants/default_settings.ts +1 -0
- package/src/constants/enums.ts +12 -0
- package/src/types/api_types.ts +18 -0
- package/test/Scorm12API.spec.ts +110 -0
- package/test/Scorm2004API.spec.ts +70 -0
package/index.d.ts
ADDED
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "scorm-again",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "A modern SCORM JavaScript run-time library for AICC, SCORM 1.2, and SCORM 2004",
|
|
5
|
-
"main": "
|
|
5
|
+
"main": "index.d.ts",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"browser": {
|
|
8
8
|
"electron": false
|
|
@@ -20,17 +20,16 @@
|
|
|
20
20
|
"test": "test"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@babel/cli": "^7.25.
|
|
24
|
-
"@babel/core": "^7.25.
|
|
25
|
-
"@babel/eslint-parser": "^7.25.
|
|
26
|
-
"@babel/node": "^7.25.
|
|
27
|
-
"@babel/preset-env": "^7.25.
|
|
28
|
-
"@babel/preset-typescript": "^7.25.
|
|
23
|
+
"@babel/cli": "^7.25.9",
|
|
24
|
+
"@babel/core": "^7.25.9",
|
|
25
|
+
"@babel/eslint-parser": "^7.25.9",
|
|
26
|
+
"@babel/node": "^7.25.9",
|
|
27
|
+
"@babel/preset-env": "^7.25.9",
|
|
28
|
+
"@babel/preset-typescript": "^7.25.9",
|
|
29
29
|
"@eslint/eslintrc": "^3.1.0",
|
|
30
|
-
"@eslint/js": "^9.
|
|
30
|
+
"@eslint/js": "^9.13.0",
|
|
31
31
|
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
|
32
32
|
"@types/eslint__js": "^8.42.3",
|
|
33
|
-
"@types/expect": "^24.3.0",
|
|
34
33
|
"@types/mocha": "^10.0.9",
|
|
35
34
|
"@types/sinon": "^17.0.3",
|
|
36
35
|
"babel-eslint": "^11.0.0-beta.2",
|
|
@@ -39,15 +38,15 @@
|
|
|
39
38
|
"browserify": "^17.0.1",
|
|
40
39
|
"c8": "^10.1.2",
|
|
41
40
|
"c8-as-nyc": "^1.1.11",
|
|
42
|
-
"eslint": "^9.
|
|
41
|
+
"eslint": "^9.13.0",
|
|
43
42
|
"eslint-formatter-junit": "^8.40.0",
|
|
44
43
|
"eslint-plugin-import": "^2.31.0",
|
|
45
|
-
"eslint-plugin-jsdoc": "^50.3
|
|
44
|
+
"eslint-plugin-jsdoc": "^50.4.3",
|
|
46
45
|
"eslint-webpack-plugin": "^4.2.0",
|
|
47
46
|
"expect": "^29.7.0",
|
|
48
47
|
"fetch-pretender": "https://github.com/jcputney/fetch-pretender#master",
|
|
49
48
|
"globals": "^15.11.0",
|
|
50
|
-
"jsdoc": "^4.0.
|
|
49
|
+
"jsdoc": "^4.0.4",
|
|
51
50
|
"jsdoc-babel": "^0.5.0",
|
|
52
51
|
"minimist": "^1.2.8",
|
|
53
52
|
"miragejs": "^0.2.0-alpha.3",
|
|
@@ -60,7 +59,7 @@
|
|
|
60
59
|
"ts-loader": "^9.5.1",
|
|
61
60
|
"tsx": "^4.19.1",
|
|
62
61
|
"typescript": "^5.6.3",
|
|
63
|
-
"typescript-eslint": "^8.
|
|
62
|
+
"typescript-eslint": "^8.11.0",
|
|
64
63
|
"webpack": "^5.91.0",
|
|
65
64
|
"webpack-cli": "^5.1.4"
|
|
66
65
|
},
|
package/src/BaseAPI.ts
CHANGED
|
@@ -5,7 +5,12 @@ import APIConstants from "./constants/api_constants";
|
|
|
5
5
|
import { formatMessage, stringMatches, unflatten } from "./utilities";
|
|
6
6
|
import { BaseCMI } from "./cmi/common/base_cmi";
|
|
7
7
|
import { debounce } from "./utilities/debounce";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
RefObject,
|
|
10
|
+
CommitObject,
|
|
11
|
+
ResultObject,
|
|
12
|
+
Settings,
|
|
13
|
+
} from "./types/api_types";
|
|
9
14
|
import { DefaultSettings } from "./constants/default_settings";
|
|
10
15
|
import { IBaseAPI } from "./interfaces/IBaseAPI";
|
|
11
16
|
import { ScheduledCommit } from "./helpers/scheduled_commit";
|
|
@@ -165,6 +170,13 @@ export default abstract class BaseAPI implements IBaseAPI {
|
|
|
165
170
|
*/
|
|
166
171
|
abstract renderCommitCMI(_terminateCommit: boolean): RefObject | Array<any>;
|
|
167
172
|
|
|
173
|
+
/**
|
|
174
|
+
* Render the commit object to the shortened format for LMS commit
|
|
175
|
+
* @param {boolean} _terminateCommit
|
|
176
|
+
* @return {CommitObject}
|
|
177
|
+
*/
|
|
178
|
+
abstract renderCommitObject(_terminateCommit: boolean): CommitObject;
|
|
179
|
+
|
|
168
180
|
/**
|
|
169
181
|
* Logging for all SCORM actions
|
|
170
182
|
*
|
|
@@ -1114,13 +1126,13 @@ export default abstract class BaseAPI implements IBaseAPI {
|
|
|
1114
1126
|
/**
|
|
1115
1127
|
* Send the request to the LMS
|
|
1116
1128
|
* @param {string} url
|
|
1117
|
-
* @param {RefObject|Array} params
|
|
1129
|
+
* @param {CommitObject|RefObject|Array} params
|
|
1118
1130
|
* @param {boolean} immediate
|
|
1119
1131
|
* @return {ResultObject}
|
|
1120
1132
|
*/
|
|
1121
1133
|
async processHttpRequest(
|
|
1122
1134
|
url: string,
|
|
1123
|
-
params: RefObject | Array<any>,
|
|
1135
|
+
params: CommitObject | RefObject | Array<any>,
|
|
1124
1136
|
immediate: boolean = false,
|
|
1125
1137
|
): Promise<ResultObject> {
|
|
1126
1138
|
const api = this;
|
|
@@ -1143,7 +1155,7 @@ export default abstract class BaseAPI implements IBaseAPI {
|
|
|
1143
1155
|
|
|
1144
1156
|
const process = async (
|
|
1145
1157
|
url: string,
|
|
1146
|
-
params: RefObject | Array<any>,
|
|
1158
|
+
params: CommitObject | RefObject | Array<any>,
|
|
1147
1159
|
settings: Settings,
|
|
1148
1160
|
): Promise<ResultObject> => {
|
|
1149
1161
|
try {
|
package/src/Scorm12API.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import BaseAPI from "./BaseAPI";
|
|
2
2
|
import { CMI } from "./cmi/scorm12/cmi";
|
|
3
3
|
import * as Utilities from "./utilities";
|
|
4
|
+
import { stringMatches } from "./utilities";
|
|
4
5
|
import APIConstants from "./constants/api_constants";
|
|
5
6
|
import ErrorCodes from "./constants/error_codes";
|
|
6
7
|
|
|
@@ -12,8 +13,15 @@ import {
|
|
|
12
13
|
CMIInteractionsObjectivesObject,
|
|
13
14
|
} from "./cmi/scorm12/interactions";
|
|
14
15
|
import { NAV } from "./cmi/scorm12/nav";
|
|
15
|
-
import {
|
|
16
|
-
|
|
16
|
+
import {
|
|
17
|
+
CommitObject,
|
|
18
|
+
RefObject,
|
|
19
|
+
ResultObject,
|
|
20
|
+
ScoreObject,
|
|
21
|
+
Settings,
|
|
22
|
+
} from "./types/api_types";
|
|
23
|
+
import Regex from "./constants/regex";
|
|
24
|
+
import { CompletionStatus, SuccessStatus } from "./constants/enums";
|
|
17
25
|
|
|
18
26
|
/**
|
|
19
27
|
* API class for SCORM 1.2
|
|
@@ -320,6 +328,61 @@ export default class Scorm12API extends BaseAPI {
|
|
|
320
328
|
}
|
|
321
329
|
}
|
|
322
330
|
|
|
331
|
+
/**
|
|
332
|
+
* Render the cmi object to the proper format for LMS commit
|
|
333
|
+
* @param {boolean} terminateCommit
|
|
334
|
+
* @return {CommitObject}
|
|
335
|
+
*/
|
|
336
|
+
renderCommitObject(terminateCommit: boolean): CommitObject {
|
|
337
|
+
const cmiExport = this.renderCommitCMI(terminateCommit);
|
|
338
|
+
const totalTimeHHMMSS = this.cmi.getCurrentTotalTime();
|
|
339
|
+
const totalTimeSeconds = Utilities.getTimeAsSeconds(
|
|
340
|
+
totalTimeHHMMSS,
|
|
341
|
+
Regex.scorm12.CMITimespan,
|
|
342
|
+
);
|
|
343
|
+
const lessonStatus = this.cmi.core.lesson_status;
|
|
344
|
+
let completionStatus = CompletionStatus.unknown;
|
|
345
|
+
let successStatus = SuccessStatus.unknown;
|
|
346
|
+
if (lessonStatus) {
|
|
347
|
+
completionStatus =
|
|
348
|
+
lessonStatus === "completed" || lessonStatus === "passed"
|
|
349
|
+
? CompletionStatus.completed
|
|
350
|
+
: CompletionStatus.incomplete;
|
|
351
|
+
if (lessonStatus === "passed") {
|
|
352
|
+
successStatus = SuccessStatus.passed;
|
|
353
|
+
} else if (lessonStatus === "failed") {
|
|
354
|
+
successStatus = SuccessStatus.failed;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
const score = this.cmi.core.score;
|
|
359
|
+
let scoreObject: ScoreObject = null;
|
|
360
|
+
if (score) {
|
|
361
|
+
scoreObject = {};
|
|
362
|
+
|
|
363
|
+
if (!Number.isNaN(Number.parseFloat(score.raw))) {
|
|
364
|
+
scoreObject.raw = Number.parseFloat(score.raw);
|
|
365
|
+
}
|
|
366
|
+
if (!Number.isNaN(Number.parseFloat(score.min))) {
|
|
367
|
+
scoreObject.min = Number.parseFloat(score.min);
|
|
368
|
+
}
|
|
369
|
+
if (!Number.isNaN(Number.parseFloat(score.max))) {
|
|
370
|
+
scoreObject.max = Number.parseFloat(score.max);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
const commitObject: CommitObject = {
|
|
375
|
+
successStatus: successStatus,
|
|
376
|
+
completionStatus: completionStatus,
|
|
377
|
+
runtimeData: cmiExport,
|
|
378
|
+
totalTimeSeconds: totalTimeSeconds,
|
|
379
|
+
};
|
|
380
|
+
if (scoreObject) {
|
|
381
|
+
commitObject.score = scoreObject;
|
|
382
|
+
}
|
|
383
|
+
return commitObject;
|
|
384
|
+
}
|
|
385
|
+
|
|
323
386
|
/**
|
|
324
387
|
* Attempts to store the data to the LMS
|
|
325
388
|
*
|
|
@@ -361,9 +424,11 @@ export default class Scorm12API extends BaseAPI {
|
|
|
361
424
|
}
|
|
362
425
|
}
|
|
363
426
|
|
|
364
|
-
const
|
|
365
|
-
terminateCommit || this.settings.alwaysSendTotalTime
|
|
366
|
-
|
|
427
|
+
const shouldTerminateCommit =
|
|
428
|
+
terminateCommit || this.settings.alwaysSendTotalTime;
|
|
429
|
+
const commitObject = this.settings.renderCommonCommitFields
|
|
430
|
+
? this.renderCommitObject(shouldTerminateCommit)
|
|
431
|
+
: this.renderCommitCMI(shouldTerminateCommit);
|
|
367
432
|
|
|
368
433
|
if (this.apiLogLevel === APIConstants.global.LOG_LEVEL_DEBUG) {
|
|
369
434
|
console.debug(
|
package/src/Scorm2004API.ts
CHANGED
|
@@ -18,7 +18,14 @@ import {
|
|
|
18
18
|
import { CMICommentsObject } from "./cmi/scorm2004/comments";
|
|
19
19
|
import { CMIObjectivesObject } from "./cmi/scorm2004/objectives";
|
|
20
20
|
import { ADL } from "./cmi/scorm2004/adl";
|
|
21
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
CommitObject,
|
|
23
|
+
RefObject,
|
|
24
|
+
ResultObject,
|
|
25
|
+
ScoreObject,
|
|
26
|
+
Settings,
|
|
27
|
+
} from "./types/api_types";
|
|
28
|
+
import { CompletionStatus, SuccessStatus } from "./constants/enums";
|
|
22
29
|
|
|
23
30
|
/**
|
|
24
31
|
* API class for SCORM 2004
|
|
@@ -613,6 +620,67 @@ export default class Scorm2004API extends BaseAPI {
|
|
|
613
620
|
}
|
|
614
621
|
}
|
|
615
622
|
|
|
623
|
+
/**
|
|
624
|
+
* Render the cmi object to the proper format for LMS commit
|
|
625
|
+
* @param {boolean} terminateCommit
|
|
626
|
+
* @return {CommitObject}
|
|
627
|
+
*/
|
|
628
|
+
renderCommitObject(terminateCommit: boolean): CommitObject {
|
|
629
|
+
const cmiExport = this.renderCommitCMI(terminateCommit);
|
|
630
|
+
const totalTimeDuration = this.cmi.getCurrentTotalTime();
|
|
631
|
+
const totalTimeSeconds = Utilities.getDurationAsSeconds(
|
|
632
|
+
totalTimeDuration,
|
|
633
|
+
Regex.scorm2004.CMITimespan,
|
|
634
|
+
);
|
|
635
|
+
|
|
636
|
+
let completionStatus = CompletionStatus.unknown;
|
|
637
|
+
let successStatus = SuccessStatus.unknown;
|
|
638
|
+
if (this.cmi.completion_status) {
|
|
639
|
+
if (this.cmi.completion_status === "completed") {
|
|
640
|
+
completionStatus = CompletionStatus.completed;
|
|
641
|
+
} else if (this.cmi.completion_status === "incomplete") {
|
|
642
|
+
completionStatus = CompletionStatus.incomplete;
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
if (this.cmi.success_status) {
|
|
646
|
+
if (this.cmi.success_status === "passed") {
|
|
647
|
+
successStatus = SuccessStatus.passed;
|
|
648
|
+
} else if (this.cmi.success_status === "failed") {
|
|
649
|
+
successStatus = SuccessStatus.failed;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
const score = this.cmi.score;
|
|
654
|
+
let scoreObject: ScoreObject = null;
|
|
655
|
+
if (score) {
|
|
656
|
+
scoreObject = {};
|
|
657
|
+
|
|
658
|
+
if (!Number.isNaN(Number.parseFloat(score.raw))) {
|
|
659
|
+
scoreObject.raw = Number.parseFloat(score.raw);
|
|
660
|
+
}
|
|
661
|
+
if (!Number.isNaN(Number.parseFloat(score.min))) {
|
|
662
|
+
scoreObject.min = Number.parseFloat(score.min);
|
|
663
|
+
}
|
|
664
|
+
if (!Number.isNaN(Number.parseFloat(score.max))) {
|
|
665
|
+
scoreObject.max = Number.parseFloat(score.max);
|
|
666
|
+
}
|
|
667
|
+
if (!Number.isNaN(Number.parseFloat(score.scaled))) {
|
|
668
|
+
scoreObject.scaled = Number.parseFloat(score.scaled);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
const commitObject: CommitObject = {
|
|
673
|
+
completionStatus: completionStatus,
|
|
674
|
+
successStatus: successStatus,
|
|
675
|
+
totalTimeSeconds: totalTimeSeconds,
|
|
676
|
+
runtimeData: cmiExport,
|
|
677
|
+
};
|
|
678
|
+
if (scoreObject) {
|
|
679
|
+
commitObject.score = scoreObject;
|
|
680
|
+
}
|
|
681
|
+
return commitObject;
|
|
682
|
+
}
|
|
683
|
+
|
|
616
684
|
/**
|
|
617
685
|
* Attempts to store the data to the LMS
|
|
618
686
|
*
|
|
@@ -650,9 +718,11 @@ export default class Scorm2004API extends BaseAPI {
|
|
|
650
718
|
navRequest = true;
|
|
651
719
|
}
|
|
652
720
|
|
|
653
|
-
const
|
|
654
|
-
terminateCommit || this.settings.alwaysSendTotalTime
|
|
655
|
-
|
|
721
|
+
const shouldTerminateCommit =
|
|
722
|
+
terminateCommit || this.settings.alwaysSendTotalTime;
|
|
723
|
+
const commitObject = this.settings.renderCommonCommitFields
|
|
724
|
+
? this.renderCommitObject(shouldTerminateCommit)
|
|
725
|
+
: this.renderCommitCMI(shouldTerminateCommit);
|
|
656
726
|
|
|
657
727
|
if (this.apiLogLevel === APIConstants.global.LOG_LEVEL_DEBUG) {
|
|
658
728
|
console.debug(
|
|
@@ -16,6 +16,7 @@ export const DefaultSettings: Settings = {
|
|
|
16
16
|
logLevel: APIConstants.global.LOG_LEVEL_ERROR,
|
|
17
17
|
selfReportSessionTime: false,
|
|
18
18
|
alwaysSendTotalTime: false,
|
|
19
|
+
renderCommonCommitFields: false,
|
|
19
20
|
strict_errors: true,
|
|
20
21
|
xhrHeaders: {},
|
|
21
22
|
xhrWithCredentials: false,
|
package/src/constants/enums.ts
CHANGED
|
@@ -3,3 +3,15 @@ export enum NAVBoolean {
|
|
|
3
3
|
true = "true",
|
|
4
4
|
false = "false",
|
|
5
5
|
}
|
|
6
|
+
|
|
7
|
+
export enum SuccessStatus {
|
|
8
|
+
passed = "passed",
|
|
9
|
+
failed = "failed",
|
|
10
|
+
unknown = "unknown",
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export enum CompletionStatus {
|
|
14
|
+
completed = "completed",
|
|
15
|
+
incomplete = "incomplete",
|
|
16
|
+
unknown = "unknown",
|
|
17
|
+
}
|
package/src/types/api_types.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { CompletionStatus, SuccessStatus } from "../constants/enums";
|
|
2
|
+
|
|
1
3
|
export type Settings = {
|
|
2
4
|
autocommit?: boolean;
|
|
3
5
|
autocommitSeconds?: number;
|
|
@@ -19,6 +21,7 @@ export type Settings = {
|
|
|
19
21
|
scoItemIds?: string[];
|
|
20
22
|
scoItemIdValidator?: false | ((scoItemId: string) => boolean);
|
|
21
23
|
mastery_override?: boolean;
|
|
24
|
+
renderCommonCommitFields?: boolean;
|
|
22
25
|
};
|
|
23
26
|
|
|
24
27
|
export type RefObject = {
|
|
@@ -30,3 +33,18 @@ export type ResultObject = {
|
|
|
30
33
|
errorCode: number;
|
|
31
34
|
navRequest?: string;
|
|
32
35
|
};
|
|
36
|
+
|
|
37
|
+
export type ScoreObject = {
|
|
38
|
+
raw?: number;
|
|
39
|
+
min?: number;
|
|
40
|
+
max?: number;
|
|
41
|
+
scaled?: number;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export type CommitObject = {
|
|
45
|
+
successStatus: SuccessStatus;
|
|
46
|
+
completionStatus: CompletionStatus;
|
|
47
|
+
totalTimeSeconds: number;
|
|
48
|
+
runtimeData: RefObject;
|
|
49
|
+
score?: ScoreObject;
|
|
50
|
+
};
|
package/test/Scorm12API.spec.ts
CHANGED
|
@@ -358,6 +358,116 @@ describe("SCORM 1.2 API Tests", () => {
|
|
|
358
358
|
const cmiExport: RefObject = scorm12API.renderCommitCMI(true);
|
|
359
359
|
expect(cmiExport.cmi.core.total_time).toEqual("23:59:59");
|
|
360
360
|
});
|
|
361
|
+
it("should return flattened format when dataCommitFormat is 'flattened'", function () {
|
|
362
|
+
const scorm12API = api({
|
|
363
|
+
...DefaultSettings,
|
|
364
|
+
...{ dataCommitFormat: "flattened" },
|
|
365
|
+
});
|
|
366
|
+
scorm12API.cmi.core.student_id = "student_1";
|
|
367
|
+
scorm12API.cmi.core.student_name = "Student 1";
|
|
368
|
+
scorm12API.cmi.core.lesson_status = "completed";
|
|
369
|
+
scorm12API.cmi.core.score.raw = "100";
|
|
370
|
+
scorm12API.cmi.core.score.max = "100";
|
|
371
|
+
scorm12API.cmi.core.score.min = "0";
|
|
372
|
+
scorm12API.cmi.core.session_time = "23:59:59";
|
|
373
|
+
const cmiExport: RefObject = scorm12API.renderCommitCMI(true);
|
|
374
|
+
expect(cmiExport["cmi.core.student_id"]).toEqual("student_1");
|
|
375
|
+
expect(cmiExport["cmi.core.student_name"]).toEqual("Student 1");
|
|
376
|
+
expect(cmiExport["cmi.core.lesson_status"]).toEqual("completed");
|
|
377
|
+
expect(cmiExport["cmi.core.score.raw"]).toEqual("100");
|
|
378
|
+
expect(cmiExport["cmi.core.score.max"]).toEqual("100");
|
|
379
|
+
expect(cmiExport["cmi.core.score.min"]).toEqual("0");
|
|
380
|
+
expect(cmiExport["cmi.core.session_time"]).toEqual("23:59:59");
|
|
381
|
+
});
|
|
382
|
+
it("should return params format when dataCommitFormat is 'params'", function () {
|
|
383
|
+
const scorm12API = api({
|
|
384
|
+
...DefaultSettings,
|
|
385
|
+
...{ dataCommitFormat: "params" },
|
|
386
|
+
});
|
|
387
|
+
scorm12API.cmi.core.student_id = "student_1";
|
|
388
|
+
scorm12API.cmi.core.student_name = "Student 1";
|
|
389
|
+
scorm12API.cmi.core.lesson_status = "completed";
|
|
390
|
+
scorm12API.cmi.core.score.raw = "100";
|
|
391
|
+
scorm12API.cmi.core.score.max = "100";
|
|
392
|
+
scorm12API.cmi.core.score.min = "0";
|
|
393
|
+
scorm12API.cmi.core.session_time = "23:59:59";
|
|
394
|
+
const result = scorm12API.renderCommitCMI(true);
|
|
395
|
+
expect(result).toBeInstanceOf(Array);
|
|
396
|
+
expect(result).toContain("cmi.core.lesson_status=completed");
|
|
397
|
+
expect(result).toContain("cmi.core.score.max=100");
|
|
398
|
+
expect(result).toContain("cmi.core.score.min=0");
|
|
399
|
+
expect(result).toContain("cmi.core.score.raw=100");
|
|
400
|
+
expect(result).toContain("cmi.core.session_time=23:59:59");
|
|
401
|
+
expect(result).toContain("cmi.core.student_id=student_1");
|
|
402
|
+
});
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
describe("renderCommitObject()", () => {
|
|
406
|
+
it("should render commit object with default settings and no score", () => {
|
|
407
|
+
const scorm12API = api();
|
|
408
|
+
scorm12API.cmi.core.lesson_status = "incomplete";
|
|
409
|
+
scorm12API.cmi.core.total_time = "12:34:56";
|
|
410
|
+
scorm12API.cmi.core.session_time = "23:59:59";
|
|
411
|
+
const commitObject = scorm12API.renderCommitObject(true);
|
|
412
|
+
expect(commitObject.successStatus).toEqual("unknown");
|
|
413
|
+
expect(commitObject.completionStatus).toEqual("incomplete");
|
|
414
|
+
expect(commitObject.runtimeData.cmi.core.lesson_status).toEqual(
|
|
415
|
+
"incomplete",
|
|
416
|
+
);
|
|
417
|
+
expect(commitObject.totalTimeSeconds).toEqual(
|
|
418
|
+
12 * 3600 + 34 * 60 + 56 + (23 * 3600 + 59 * 60 + 59),
|
|
419
|
+
);
|
|
420
|
+
expect(commitObject.score.max).toEqual(100);
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
it("should render commit object with score data", () => {
|
|
424
|
+
const scorm12API = api();
|
|
425
|
+
scorm12API.cmi.core.lesson_status = "completed";
|
|
426
|
+
scorm12API.cmi.core.score.raw = "85";
|
|
427
|
+
scorm12API.cmi.core.score.min = "0";
|
|
428
|
+
scorm12API.cmi.core.score.max = "100";
|
|
429
|
+
const commitObject = scorm12API.renderCommitObject(true);
|
|
430
|
+
expect(commitObject.successStatus).toEqual("unknown");
|
|
431
|
+
expect(commitObject.completionStatus).toEqual("completed");
|
|
432
|
+
expect(commitObject.runtimeData.cmi.core.lesson_status).toEqual(
|
|
433
|
+
"completed",
|
|
434
|
+
);
|
|
435
|
+
expect(commitObject.runtimeData.cmi.core.score.raw).toEqual("85");
|
|
436
|
+
expect(commitObject.runtimeData.cmi.core.score.min).toEqual("0");
|
|
437
|
+
expect(commitObject.runtimeData.cmi.core.score.max).toEqual("100");
|
|
438
|
+
expect(commitObject.totalTimeSeconds).toEqual(0);
|
|
439
|
+
expect(commitObject.score).toEqual({
|
|
440
|
+
raw: 85,
|
|
441
|
+
min: 0,
|
|
442
|
+
max: 100,
|
|
443
|
+
});
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
it("should render commit object with completion and success status", () => {
|
|
447
|
+
const scorm12API = api();
|
|
448
|
+
scorm12API.cmi.core.lesson_status = "passed";
|
|
449
|
+
const commitObject = scorm12API.renderCommitObject(true);
|
|
450
|
+
expect(commitObject.successStatus).toEqual("passed");
|
|
451
|
+
expect(commitObject.completionStatus).toEqual("completed");
|
|
452
|
+
expect(commitObject.runtimeData.cmi.core.lesson_status).toEqual("passed");
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
it("should render commit object with failed success status", () => {
|
|
456
|
+
const scorm12API = api();
|
|
457
|
+
scorm12API.cmi.core.lesson_status = "failed";
|
|
458
|
+
const commitObject = scorm12API.renderCommitObject(true);
|
|
459
|
+
expect(commitObject.successStatus).toEqual("failed");
|
|
460
|
+
expect(commitObject.completionStatus).toEqual("incomplete");
|
|
461
|
+
expect(commitObject.runtimeData.cmi.core.lesson_status).toEqual("failed");
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
it("should calculate total time when terminateCommit is true", () => {
|
|
465
|
+
const scorm12API = api();
|
|
466
|
+
scorm12API.cmi.core.total_time = "12:34:56";
|
|
467
|
+
scorm12API.cmi.core.session_time = "23:59:59";
|
|
468
|
+
const commitObject = scorm12API.renderCommitObject(true);
|
|
469
|
+
expect(commitObject.runtimeData.cmi.core.total_time).toEqual("36:34:55");
|
|
470
|
+
});
|
|
361
471
|
});
|
|
362
472
|
|
|
363
473
|
describe("storeData()", () => {
|
|
@@ -827,6 +827,76 @@ describe("SCORM 2004 API Tests", () => {
|
|
|
827
827
|
});
|
|
828
828
|
});
|
|
829
829
|
|
|
830
|
+
describe("renderCommitObject()", () => {
|
|
831
|
+
it("should render commit object with default settings and no score", () => {
|
|
832
|
+
const scorm2004API = api();
|
|
833
|
+
scorm2004API.cmi.completion_status = "incomplete";
|
|
834
|
+
scorm2004API.cmi.total_time = "P12H34M56S";
|
|
835
|
+
scorm2004API.cmi.session_time = "P23H59M59S";
|
|
836
|
+
const commitObject = scorm2004API.renderCommitObject(true);
|
|
837
|
+
expect(commitObject.successStatus).toEqual("unknown");
|
|
838
|
+
expect(commitObject.completionStatus).toEqual("incomplete");
|
|
839
|
+
expect(commitObject.runtimeData.cmi.completion_status).toEqual(
|
|
840
|
+
"incomplete",
|
|
841
|
+
);
|
|
842
|
+
expect(commitObject.totalTimeSeconds).toEqual(
|
|
843
|
+
12 * 3600 + 34 * 60 + 56 + (23 * 3600 + 59 * 60 + 59),
|
|
844
|
+
);
|
|
845
|
+
});
|
|
846
|
+
|
|
847
|
+
it("should render commit object with score data", () => {
|
|
848
|
+
const scorm2004API = api();
|
|
849
|
+
scorm2004API.cmi.completion_status = "completed";
|
|
850
|
+
scorm2004API.cmi.score.raw = "85";
|
|
851
|
+
scorm2004API.cmi.score.min = "0";
|
|
852
|
+
scorm2004API.cmi.score.max = "100";
|
|
853
|
+
scorm2004API.cmi.score.scaled = "0.85";
|
|
854
|
+
const commitObject = scorm2004API.renderCommitObject(true);
|
|
855
|
+
expect(commitObject.successStatus).toEqual("unknown");
|
|
856
|
+
expect(commitObject.completionStatus).toEqual("completed");
|
|
857
|
+
expect(commitObject.runtimeData.cmi.completion_status).toEqual(
|
|
858
|
+
"completed",
|
|
859
|
+
);
|
|
860
|
+
expect(commitObject.runtimeData.cmi.score.raw).toEqual("85");
|
|
861
|
+
expect(commitObject.runtimeData.cmi.score.min).toEqual("0");
|
|
862
|
+
expect(commitObject.runtimeData.cmi.score.max).toEqual("100");
|
|
863
|
+
expect(commitObject.runtimeData.cmi.score.scaled).toEqual("0.85");
|
|
864
|
+
expect(commitObject.totalTimeSeconds).toEqual(0);
|
|
865
|
+
expect(commitObject.score).toEqual({
|
|
866
|
+
raw: 85,
|
|
867
|
+
min: 0,
|
|
868
|
+
max: 100,
|
|
869
|
+
scaled: 0.85,
|
|
870
|
+
});
|
|
871
|
+
});
|
|
872
|
+
|
|
873
|
+
it("should render commit object with completion and success status", () => {
|
|
874
|
+
const scorm2004API = api();
|
|
875
|
+
scorm2004API.cmi.success_status = "passed";
|
|
876
|
+
const commitObject = scorm2004API.renderCommitObject(true);
|
|
877
|
+
expect(commitObject.successStatus).toEqual("passed");
|
|
878
|
+
expect(commitObject.completionStatus).toEqual("unknown");
|
|
879
|
+
expect(commitObject.runtimeData.cmi.success_status).toEqual("passed");
|
|
880
|
+
});
|
|
881
|
+
|
|
882
|
+
it("should render commit object with failed success status", () => {
|
|
883
|
+
const scorm2004API = api();
|
|
884
|
+
scorm2004API.cmi.success_status = "failed";
|
|
885
|
+
const commitObject = scorm2004API.renderCommitObject(true);
|
|
886
|
+
expect(commitObject.successStatus).toEqual("failed");
|
|
887
|
+
expect(commitObject.completionStatus).toEqual("unknown");
|
|
888
|
+
expect(commitObject.runtimeData.cmi.success_status).toEqual("failed");
|
|
889
|
+
});
|
|
890
|
+
|
|
891
|
+
it("should calculate total time when terminateCommit is true", () => {
|
|
892
|
+
const scorm2004API = api();
|
|
893
|
+
scorm2004API.cmi.total_time = "P12H34M56S";
|
|
894
|
+
scorm2004API.cmi.session_time = "P23H59M59S";
|
|
895
|
+
const commitObject = scorm2004API.renderCommitObject(true);
|
|
896
|
+
expect(commitObject.runtimeData.cmi.total_time).toEqual("P1DT12H34M55S");
|
|
897
|
+
});
|
|
898
|
+
});
|
|
899
|
+
|
|
830
900
|
describe("lmsGetDiagnostic()", () => {
|
|
831
901
|
it("should return diagnostic information for a given error code", () => {
|
|
832
902
|
const scorm2004API = api();
|