├── Gruntfile.js ├── LICENSE ├── README.md ├── bower.json ├── dist ├── angularjs-scorm-wrapper.js └── angularjs-scorm-wrapper.min.js ├── karma.config.js ├── package.json ├── src └── angular-scorm-wrapper.js └── test └── angular-scorm-wrapper.tests.js /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 3 | grunt.initConfig({ 4 | pkg: grunt.file.readJSON('package.json'), 5 | concat: { 6 | options: { 7 | separator: ';' 8 | }, 9 | dist: { 10 | src: ['src/**/*.js'], 11 | dest: 'dist/<%= pkg.name %>.js' 12 | } 13 | }, 14 | uglify: { 15 | options: { 16 | banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n' 17 | }, 18 | dist: { 19 | files: { 20 | 'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>'] 21 | } 22 | } 23 | }, 24 | karma: { 25 | options: { 26 | configFile: 'karma.config.js' 27 | }, 28 | unit: { 29 | singleRun: true 30 | } 31 | 32 | }, 33 | eslint: { 34 | target: ['Gruntfile.js', 'src/*.js', 'test/*.js'], 35 | }, 36 | watch: { 37 | files: ['<%= eslint.target %>'], 38 | tasks: ['eslint', 'karma'] 39 | } 40 | }); 41 | 42 | grunt.loadNpmTasks('grunt-contrib-uglify'); 43 | grunt.loadNpmTasks('grunt-eslint'); 44 | grunt.loadNpmTasks('grunt-karma'); 45 | grunt.loadNpmTasks('grunt-contrib-watch'); 46 | grunt.loadNpmTasks('grunt-contrib-concat'); 47 | 48 | grunt.registerTask('test', ['eslint', 'karma']); 49 | 50 | grunt.registerTask('default', ['eslint', 'karma', 'concat', 'uglify']); 51 | 52 | }; 53 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2016 Andy Dennis 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files 5 | (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, 6 | publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 7 | subject to the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 12 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 14 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Scorm API Wrapper Programming Guide 2 | *********************************** 3 | 4 | Support for AngularJS (https://angularjs.org/) officially ended in Jan 2022 5 | 6 | https://blog.angular.io/discontinued-long-term-support-for-angularjs-cc066b82e65a 7 | 8 | Engineering teams are encouraged to upgrade to Angular: https://angular.io/ 9 | 10 | As a result this repository has officially been Archived as of November 2022. 11 | 12 | 13 | Overview 14 | ======== 15 | 16 | The SCORM API wrapper is a JavaScript library designed to 17 | provide a method for eLearning courseware to interact with 18 | SCORM based learning management systems. It provides 19 | a wrapper to the JavaScript API object provided by the 20 | LMS and supports SCORM versions 1.2 and 2004. 21 | 22 | This wrapper takes care of the necessary task of locating the 23 | API object in course opener window and wrapping the API calls 24 | in a way that provides a single interface to the courseware regardless 25 | of which SCORM version is used/supported by the LMS. 26 | 27 | The contents of this repository is a porting of the code from the 28 | original APIWrapper.js file to Angular JS with a 29 | number of improvements. The original APIWrapper.js was released 30 | by Concurrent Technologies Corporation (CTC) 31 | under the MIT style license available 32 | on the ADL SCORM website [2] 33 | 34 | The code has been updated to wrap the original functions in 35 | in an angularjs service[5] and extend support for SCORM 2004. 36 | It draws upon some of features offered in the Pipewerks API wrapper[3] 37 | 38 | 39 | Usage 40 | ===== 41 | 42 | To use the SCORM API wrapper, include the angular-scorm-wrapper.js file 43 | in your project. 44 | You can then make calls to the angular service as needed. 45 | 46 | 47 | 48 | API Functionality 49 | ================= 50 | 51 | The SCORM wrapper provides a mapping between a number of 52 | JavaScript functions, those being the SCORM Wrapper functions 53 | and their SCORM 1.2 and 2004 equivalent in the LMS. 54 | 55 | 56 | SCORM API Functions supported 57 | ------------------------------ 58 | 59 | The following functions for SCORM 2004 and 1.2 are supported 60 | in the API wrapper[4]: 61 | 62 | **SCORM 2004** 63 | 64 | API calls for SCORM 2004 via API_1484_11 object 65 | 66 | ``` 67 | Initialize( “” ) : bool 68 | 69 | Terminate( “” ) : bool 70 | 71 | GetValue( element : CMIElement ) : string 72 | 73 | SetValue( element : CMIElement, value : string) : string 74 | 75 | Commit( “” ) : bool 76 | 77 | GetLastError() : CMIErrorCode 78 | 79 | GetErrorString( errorCode : CMIErrorCode ) : string 80 | 81 | GetDiagnostic( errocCode : CMIErrorCode ) : string 82 | ``` 83 | 84 | **SCORM 1.2** 85 | 86 | API calls for SCORM 1.2 via API object 87 | 88 | 89 | ``` 90 | LMSInitialize( “” ) : bool 91 | 92 | LMSFinish( “” ) : bool 93 | 94 | LMSGetValue( element : CMIElement ) : string 95 | 96 | LMSSetValue( element : CMIElement, value : string) : string 97 | 98 | LMSCommit( “” ) : bool 99 | 100 | LMSGetLastError() : CMIErrorCode 101 | 102 | LMSGetErrorString( errorCode : CMIErrorCode ) : string 103 | 104 | LMSGetDiagnostic( errocCode : CMIErrorCode ) : string 105 | ``` 106 | 107 | SCORM Wrapper Functions 108 | ----------------------- 109 | 110 | The functions listed in above section can be accessed 111 | through the following calls. The wrapper functions 112 | take care of making the correct API call based upon the 113 | SCORM version you are implementing: 114 | 115 | 116 | ``` this.setAPIVersion ``` 117 | 118 | A setter function for telling the SCORM wrapper which API to use. 119 | 120 | Arguments: 121 | 122 | "1.2" 123 | The SCORM 1.2 API object 124 | 125 | "2004" 126 | The SCORM 2004 API object 127 | 128 | "Auto" 129 | Tells the API to search for a SCORM API object. Starts with 130 | SCORM 1.2 and then moves onto 2004. 131 | 132 | API functions: 133 | 134 | None 135 | 136 | 137 | 138 | ``` this.getAPIVersion ``` 139 | 140 | Getter function for returning the API object set in the SCORM wrapper. 141 | 142 | Arguments: 143 | 144 | None 145 | 146 | API functions: 147 | 148 | None 149 | 150 | 151 | ``` this.doLMSInitialize ``` 152 | 153 | Kicks of the initialization process which starts communication between the courseware 154 | and the LMS. 155 | 156 | Arguments: 157 | 158 | None 159 | 160 | API functions: 161 | 162 | LMSInitialize("") 163 | SCORM 1.2 API function called by this method. 164 | 165 | Initialize("") 166 | SCORM 2004 API function called by this method. 167 | 168 | 169 | ``` this.isAvailable ``` 170 | 171 | Function called by Flash to check if SCORM Wrapper is available. 172 | 173 | Arguments: 174 | 175 | None 176 | 177 | API functions: 178 | 179 | None 180 | 181 | 182 | ``` this.doLMSFinish ``` 183 | 184 | Called when the courseware has finished interacting with the LMS. For example may be used on an 185 | exit button. 186 | 187 | Arguments: 188 | 189 | None 190 | 191 | API functions: 192 | 193 | LMSFinish("") 194 | SCORM 1.2 method for ending communication between LMS and courseware 195 | 196 | Terminate("") 197 | SCORM 2004 method for ending communication between LMS and courseware 198 | 199 | 200 | 201 | ``` this.doLMSGetValue ``` 202 | 203 | Used for returning a value from the CMS for example cmi.score.raw 204 | 205 | Arguments: 206 | 207 | Valid element from data model: 208 | 209 | SCORM 1.2 210 | http://scorm.com/scorm-explained/technical-scorm/run-time/run-time-reference/ 211 | 212 | SCORM 2004 (2nd, 3rd and 4th editions) 213 | http://scorm.com/scorm-explained/technical-scorm/run-time/run-time-reference/ 214 | 215 | API functions: 216 | 217 | LMSGetValue(parameter) 218 | SCORM 1.2 method 219 | 220 | GetValue(parameter) 221 | SCORM 2004 method 222 | 223 | 224 | 225 | ``` this.doLMSSetValue ``` 226 | 227 | Used for setting a value in the CMS for example cmi.score.raw 228 | 229 | Arguments: 230 | 231 | doLMSSetValue takes two arguments. The Data model element and the value to set. 232 | 233 | Valid element from data model: 234 | 235 | SCORM 1.2 236 | http://scorm.com/scorm-explained/technical-scorm/run-time/run-time-reference/ 237 | 238 | SCORM 2004 (2nd, 3rd and 4th editions) 239 | http://scorm.com/scorm-explained/technical-scorm/run-time/run-time-reference/ 240 | 241 | 242 | API functions: 243 | 244 | LMSSetValue(parameter, value) 245 | SCORM 1.2 method 246 | 247 | SetValue(parameter, value) 248 | SCORM 2004 method 249 | 250 | 251 | 252 | ``` this.doLMSCommit ``` 253 | 254 | Used to persist data in the LMS. Call once the value has been set using doLMSSet(parameter, value). 255 | 256 | Arguments: 257 | 258 | None 259 | 260 | API functions: 261 | 262 | LMSCommit("") 263 | SCORM 1.2 method for committing data to the LMS 264 | 265 | Commit("") 266 | SCORM 2004 method for committing data to the LMS 267 | 268 | 269 | 270 | ``` this.doLMSGetLastError ``` 271 | 272 | Get the last error code generated by the LMS. 273 | 274 | Arguments: 275 | 276 | None 277 | 278 | API functions: 279 | 280 | LMSGetLastError() 281 | SCORM 1.2 method 282 | 283 | GetLastError() 284 | SCORM 2004 method 285 | 286 | 287 | 288 | ``` this.doLMSGetErrorString ``` 289 | 290 | Get the last error description generated by the LMS as a string. 291 | 292 | Arguments: 293 | 294 | Error code 295 | Should be a valid SCORM error code. These can be found in the Run Time Reference document. 296 | http://scorm.com/scorm-explained/technical-scorm/run-time/run-time-reference/ 297 | 298 | API functions: 299 | 300 | LMSGetErrorString(errorCode.toString()) 301 | SCORM 1.2 method 302 | 303 | GetErrorString(errorCode.toString()) 304 | SCORM 2004 method 305 | 306 | 307 | 308 | ``` this.doLMSGetDiagnostic ``` 309 | 310 | The vendor specific textual description that corresponds to the input error code. 311 | 312 | Argument: 313 | 314 | Error code 315 | Should be a valid SCORM error code. These can be found in the Run Time Reference document. 316 | http://scorm.com/scorm-explained/technical-scorm/run-time/run-time-reference/ 317 | 318 | API functions: 319 | 320 | LMSGetDiagnostic(errorCode.toString()) 321 | SCORM 1.2 method 322 | 323 | GetDiagnostic(errorCode.toString()) 324 | SCORM 2004 method 325 | 326 | 327 | ``` this.LMSIsInitialized ``` 328 | 329 | Method for checking if LMS is already initialized. There is no one method that can be called in 330 | the API for checking if the LMS is initialized, or if it is still present (for example has the LMS browser window 331 | accidentally been closed). 332 | Therefore we check the status by getting a value from the LMS - "cmi.core.student_name". 333 | 334 | Argument: 335 | 336 | None 337 | 338 | API function: 339 | 340 | LMSGetValue("cmi.core.student_name") 341 | SCORM 1.2 method 342 | 343 | GetValue("cmi.core.student_name") 344 | SCORM 2004 method 345 | 346 | 347 | ``` this.ErrorHandler ``` 348 | 349 | Determines if an error was encountered by the previous API call and if so, displays a message to the user. 350 | If the error code has associated text it is also displayed. 351 | 352 | Argument: 353 | 354 | None 355 | 356 | API functions: 357 | 358 | LMSGetLastError() 359 | SCORM 1.2 method 360 | 361 | GetLastError() 362 | SCORM 2004 method 363 | 364 | 365 | ``` this.getAPIHandle ``` 366 | 367 | Returns the handle to API object if it was previously set, otherwise it returns null. 368 | 369 | Argument: 370 | 371 | None 372 | 373 | API functions: 374 | 375 | None 376 | 377 | 378 | ``` this.findAPI ``` 379 | 380 | This function looks for an object named API/API_1484_11 in parent and opener windows. 381 | It calls a number of other functions to assist in this process based upon the SCORM 382 | version we wish to use. 383 | 384 | Argument: 385 | 386 | None 387 | 388 | API functions: 389 | 390 | None 391 | 392 | ``` this.searchForAPI ``` 393 | 394 | This function does a lookup for the SCORM API starting with 1.2 and then 2004. 395 | 396 | Argument: 397 | 398 | None 399 | 400 | API functions: 401 | 402 | None 403 | 404 | 405 | ``` this.scorm1Point2 ``` 406 | 407 | Called by this.searchForAPI to look for API object. 408 | 409 | Argument: 410 | 411 | None 412 | 413 | API functions: 414 | 415 | None 416 | 417 | 418 | 419 | ``` this.scorm2004 ``` 420 | 421 | Called by this.searchForAPI to look for API_1484_11 object. 422 | 423 | Argument: 424 | 425 | None 426 | 427 | API functions: 428 | 429 | None 430 | 431 | 432 | ``` this.getAPI ``` 433 | 434 | This function looks for an object named API, first in the current window's 435 | frame hierarchy and then, if necessary, in the current window's opener window 436 | hierarchy (if there is an opener window). It calls findAPI which then finds 437 | the API based upon the chosen SCORM version. 438 | 439 | Argument: 440 | 441 | None 442 | 443 | API functions: 444 | 445 | None 446 | 447 | 448 | ``` this.cmiBooleanToJs ``` 449 | 450 | The bool type on the API is a SCORM boolean, which is actually a string 451 | having the value “true” or “false”. 452 | http://scorm.com/scorm-explained/technical-scorm/run-time/ 453 | 454 | However some LMS's may return a Boolean True or False or possibly even 455 | 1 or 0. We therefore include this function to guard against edge cases. 456 | 457 | In the case of an error we could also have null come back from the LMS so 458 | we also need to program with this in mind. 459 | 460 | Argument: 461 | 462 | None 463 | 464 | API functions: 465 | 466 | None 467 | 468 | 469 | 470 | Tests 471 | ===== 472 | 473 | Testing is done via Karma using Jasmine. 474 | 475 | 476 | To add a test suite use the following format: 477 | 478 | ``` 479 | 480 | describe('When I call scormWrapper.setAPIVersion() with "1.2" ', function(){ 481 | beforeEach(module('scormwrapper')); 482 | it('returns true', inject(function(scormWrapper){ 483 | 484 | expect( scormWrapper.setAPIVersion("1.2") ).toEqual(true); 485 | //add further test cases to the suite here if needed. 486 | 487 | })) 488 | 489 | }); 490 | ``` 491 | 492 | 493 | 494 | References 495 | ========== 496 | 497 | [1] ADL 498 | http://www.adlnet.gov/scorm 499 | 500 | [2] CTC SCORM SCORM 1.2 API wrapper 501 | http://www.adlnet.gov/resources/scorm-1-2-content-packages?type=software_downloads 502 | 503 | [3] Pipewerks SCORM wrapper 504 | https://github.com/pipwerks/scorm-api-wrapper 505 | 506 | [4] SCORM.com 507 | http://scorm.com/scorm-explained/technical-scorm/run-time/ 508 | 509 | [5] Angularjs services 510 | http://docs.angularjs.org/guide/dev_guide.services 511 | 512 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angularjs-scorm-wrapper", 3 | "version": "1.2.2", 4 | "main": "dist/angularjs-scorm-wrapper.min.js", 5 | "ignore": [ 6 | ".jshintrc", 7 | "**/*.txt" 8 | ], 9 | "dependencies": { 10 | }, 11 | "devDependencies": { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /dist/angularjs-scorm-wrapper.js: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | ** 3 | ** Prometheus Research SCORM API Wrapper 4 | ** 5 | ** Supports: 6 | ** 7 | ** SCORM 1.2, SCORM 2004.[1] 8 | ** 9 | ** The following is a porting of the code from the 10 | ** original APIWrapper.js file to Angular JS with a 11 | ** number of improvements from 12 | ** Concurrent Technologies Corporation (CTC) released 13 | ** under the MIT style license available 14 | ** on the ADL scorm website [2] 15 | ** 16 | ** The code has been updated to wrap the original functions in 17 | ** in angularjs and extend support for SCORM 2004 [4]. 18 | ** It draws upon some of concepts offered in the Pipewerks[3] 19 | ** 20 | ** The code is served as an AngularJS service [5]. 21 | ** 22 | ** References/Inspiration: 23 | ** 24 | ** [1] ADL 25 | ** http://www.adlnet.gov/scorm 26 | ** 27 | ** [2] CTC SCORM SCORM 1.2 API wrapper 28 | ** http://www.adlnet.gov/resources/scorm-1-2-content-packages?type=software_downloads 29 | ** 30 | ** [3] Pipewerks SCORM wrapper 31 | ** https://github.com/pipwerks/scorm-api-wrapper 32 | ** 33 | ** [4] SCORM.com 34 | ** http://scorm.com/scorm-explained/technical-scorm/run-time/ 35 | ** 36 | ** [5] Angularjs services 37 | ** http://docs.angularjs.org/guide/dev_guide.services 38 | ** 39 | ** Copyright (c) Prometheus Research 2014 40 | ** Copyright (c) Philip Hutchison 41 | ** Copyright (c) Concurrent Technologies Corporation (CTC) 42 | ** --------------------------------------------------------------------------------- 43 | ** License: 44 | ** 45 | ** 46 | ** Permission is hereby granted, free of charge, to any person obtaining a 47 | ** copy of this software and associated documentation files (the “Software”), 48 | ** to deal in the Software without restriction, including without limitation the 49 | ** rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 50 | ** copies of the Software, and to permit persons to whom the Software is furnished to 51 | ** do so, subject to the following conditions: 52 | ** 53 | ** The above copyright notice and this permission notice shall be included in 54 | ** all copies or substantial portions of the Software. 55 | ** 56 | ** THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 57 | ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 58 | ** FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 59 | ** COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 60 | ** IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 61 | ** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 62 | ** 63 | *********************************************************************************/ 64 | 65 | var scormwrapper = angular.module('scormwrapper', []); 66 | 67 | scormwrapper.service('scormWrapper', function () { 68 | "use strict"; 69 | 70 | var version = "Auto"; 71 | var API = false; 72 | var scormVersions = ["Auto","1.2","2004"]; 73 | 74 | this.setAPIVersion = function (scormVersion) { 75 | 76 | scormVersion = scormVersion || "Auto"; 77 | 78 | var v = scormVersions.indexOf(scormVersion.toString()); 79 | (v > -1) ? version = scormVersions[v] : console.log("Not found, default to Auto"); 80 | return version; 81 | }; 82 | 83 | this.getAPIVersion = function () { 84 | return version; 85 | }; 86 | 87 | this.isAvailable = function () { 88 | return true; 89 | }; 90 | 91 | this.doLMSInitialize = function () { 92 | return this.cmiBooleanToJs(this.getAPICall("LMSInitialize", "Initialize")("")); 93 | }; 94 | 95 | this.doLMSFinish = function () { 96 | return this.cmiBooleanToJs(this.getAPICall("LMSFinish", "Terminate")("")); 97 | }; 98 | 99 | this.doLMSGetValue = function (parameter) { 100 | return this.getAPICall("LMSGetValue", "GetValue")(parameter); 101 | }; 102 | 103 | this.doLMSSetValue = function (parameter, value) { 104 | return this.cmiBooleanToJs(this.getAPICall("LMSSetValue", "SetValue")(parameter, value)); 105 | }; 106 | 107 | this.doLMSCommit = function () { 108 | return this.cmiBooleanToJs(this.getAPICall("LMSCommit", "Commit")("")); 109 | }; 110 | 111 | this.doLMSGetLastError = function () { 112 | return this.getAPICall("LMSGetLastError", "GetLastError")(); 113 | }; 114 | 115 | this.doLMSGetErrorString = function (errorCode) { 116 | return this.getAPICall("LMSGetErrorString", "GetErrorString")(errorCode.toString()); 117 | }; 118 | 119 | this.doLMSGetDiagnostic = function (errorCode) { 120 | return this.getAPICall("LMSGetDiagnostic", "GetDiagnostic")(errorCode.toString()); 121 | }; 122 | 123 | this.LMSIsInitialized = function () { 124 | return API; 125 | }; 126 | 127 | this.ErrorHandler = function () { 128 | return this.getAPICall("LMSGetLastError", "GetLastError")(); 129 | }; 130 | 131 | this.cmiBooleanToJs = function (value) { 132 | return (value === "1" || value === 1 || value === "true" || value === true); 133 | }; 134 | 135 | this.getAPIHandle = function () { 136 | 137 | var win = window; 138 | 139 | if (win.parent && win.parent != win) { 140 | this.findAPI(win.parent); 141 | } 142 | 143 | if (!API && win.top.opener) { 144 | this.findAPI(win.top.opener); 145 | } else if (!API) { 146 | console.log("Unable to find API adapter"); 147 | } 148 | }; 149 | 150 | this.findAPI = function (win) { 151 | 152 | var findAttempts = 0, 153 | findAttemptLimit = 500; 154 | 155 | for (findAttempts; findAttempts < findAttemptLimit; findAttempts++) { 156 | 157 | if (win.API && (version === "1.2" || version === "Auto" )) { 158 | API = win.API; 159 | version = "1.2"; 160 | break; 161 | } else if (win.API_1484_11 && (version === "2004" || version === "Auto" )) { 162 | API = win.API_1484_11; 163 | version = "2004"; 164 | break; 165 | } else if (win.parent && win.parent != win) { 166 | findAttempts++; 167 | win = win.parent; 168 | } 169 | } 170 | }; 171 | 172 | this.getAPICall = function(funcname12, funcname2004) { 173 | 174 | if (!API) { 175 | this.getAPIHandle(); 176 | if (!API) { 177 | return (function(){ 178 | console.log("No API found, can't execute: " + funcname12 + " or " + funcname2004); 179 | }); 180 | } 181 | } 182 | 183 | switch(version) { 184 | case "2004": 185 | return function() { 186 | return API[funcname2004].apply(API, arguments); 187 | }; 188 | 189 | case "1.2": 190 | return function() { 191 | return API[funcname12].apply(API, arguments); 192 | }; 193 | } 194 | }; 195 | }); 196 | 197 | -------------------------------------------------------------------------------- /dist/angularjs-scorm-wrapper.min.js: -------------------------------------------------------------------------------- 1 | /*! angularjs-scorm-wrapper 26-05-2016 */ 2 | var scormwrapper=angular.module("scormwrapper",[]);scormwrapper.service("scormWrapper",function(){"use strict";var a="Auto",b=!1,c=["Auto","1.2","2004"];this.setAPIVersion=function(b){b=b||"Auto";var d=c.indexOf(b.toString());return d>-1?a=c[d]:console.log("Not found, default to Auto"),a},this.getAPIVersion=function(){return a},this.isAvailable=function(){return!0},this.doLMSInitialize=function(){return this.cmiBooleanToJs(this.getAPICall("LMSInitialize","Initialize")(""))},this.doLMSFinish=function(){return this.cmiBooleanToJs(this.getAPICall("LMSFinish","Terminate")(""))},this.doLMSGetValue=function(a){return this.getAPICall("LMSGetValue","GetValue")(a)},this.doLMSSetValue=function(a,b){return this.cmiBooleanToJs(this.getAPICall("LMSSetValue","SetValue")(a,b))},this.doLMSCommit=function(){return this.cmiBooleanToJs(this.getAPICall("LMSCommit","Commit")(""))},this.doLMSGetLastError=function(){return this.getAPICall("LMSGetLastError","GetLastError")()},this.doLMSGetErrorString=function(a){return this.getAPICall("LMSGetErrorString","GetErrorString")(a.toString())},this.doLMSGetDiagnostic=function(a){return this.getAPICall("LMSGetDiagnostic","GetDiagnostic")(a.toString())},this.LMSIsInitialized=function(){return b},this.ErrorHandler=function(){return this.getAPICall("LMSGetLastError","GetLastError")()},this.cmiBooleanToJs=function(a){return"1"===a||1===a||"true"===a||a===!0},this.getAPIHandle=function(){var a=window;a.parent&&a.parent!=a&&this.findAPI(a.parent),!b&&a.top.opener?this.findAPI(a.top.opener):b||console.log("Unable to find API adapter")},this.findAPI=function(c){var d=0,e=500;for(d;e>d;d++){if(c.API&&("1.2"===a||"Auto"===a)){b=c.API,a="1.2";break}if(c.API_1484_11&&("2004"===a||"Auto"===a)){b=c.API_1484_11,a="2004";break}c.parent&&c.parent!=c&&(d++,c=c.parent)}},this.getAPICall=function(c,d){if(!b&&(this.getAPIHandle(),!b))return function(){console.log("No API found, can't execute: "+c+" or "+d)};switch(a){case"2004":return function(){return b[d].apply(b,arguments)};case"1.2":return function(){return b[c].apply(b,arguments)}}}}); -------------------------------------------------------------------------------- /karma.config.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // Generated on Mon Jan 20 2014 13:41:55 GMT-0500 (EST) 3 | 4 | module.exports = function(config) { 5 | config.set({ 6 | 7 | // base path, that will be used to resolve files and exclude 8 | basePath: '', 9 | 10 | plugins:[ 11 | 'karma-jasmine', 12 | 'karma-phantomjs-launcher', 13 | ], 14 | 15 | // frameworks to use 16 | frameworks: ['jasmine'], 17 | 18 | 19 | // list of files / patterns to load in the browser 20 | files: [ 21 | 'http://code.angularjs.org/1.1.4/angular.js', 22 | 'http://code.angularjs.org/1.1.4/angular-mocks.js', 23 | 'src/angular-scorm-wrapper.js', 24 | 'test/*.js' 25 | ], 26 | 27 | 28 | // list of files to exclude 29 | exclude: [ 30 | 31 | ], 32 | 33 | 34 | // test results reporter to use 35 | // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage' 36 | reporters: ['progress'], 37 | 38 | 39 | // web server port 40 | port: 9876, 41 | 42 | 43 | // enable / disable colors in the output (reporters and logs) 44 | colors: true, 45 | 46 | 47 | // level of logging 48 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 49 | logLevel: config.LOG_INFO, 50 | 51 | 52 | // enable / disable watching file and executing tests whenever any file changes 53 | autoWatch: true, 54 | 55 | 56 | // Start these browsers, currently available: 57 | // - Chrome 58 | // - ChromeCanary 59 | // - Firefox 60 | // - Opera (has to be installed with `npm install karma-opera-launcher`) 61 | // - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`) 62 | // - PhantomJS 63 | // - IE (only Windows; has to be installed with `npm install karma-ie-launcher`) 64 | browsers: ['PhantomJS'], 65 | 66 | 67 | // If browser does not capture in given timeout [ms], kill it 68 | captureTimeout: 60000, 69 | 70 | 71 | // Continuous Integration mode 72 | // if true, it capture browsers, run tests and exit 73 | singleRun: false 74 | }); 75 | }; 76 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angularjs-scorm-wrapper", 3 | "description": "SCORM API Wrapper for SCORM 1.2 and 2004", 4 | "version": "1.2.1", 5 | "filename": "angular-scorm-wrapper.js", 6 | "main": "", 7 | "homepage": "", 8 | "author": "Andy Dennis", 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/andydennis/angularjs-scorm-wrapper" 12 | }, 13 | "engines": { 14 | "node": ">= 0.9" 15 | }, 16 | "keywords": [ 17 | "angular", 18 | "eLearning", 19 | "SCORM", 20 | "LMS", 21 | "SCORM 1.2", 22 | "SCORM 2004", 23 | "API Wrapper" 24 | ], 25 | "maintainers": [ 26 | { 27 | "name": "Andy Dennis", 28 | "website": "https://github.com/andydennis/angularjs-scorm-wrapper" 29 | } 30 | ], 31 | "dependencies": {}, 32 | "devDependencies": { 33 | "grunt": "", 34 | "grunt-contrib-uglify": "", 35 | "grunt-eslint": "", 36 | "grunt-karma": "", 37 | "grunt-contrib-watch": "", 38 | "grunt-contrib-concat": "" 39 | }, 40 | "scripts": { 41 | 42 | }, 43 | "license": "MIT" 44 | } 45 | -------------------------------------------------------------------------------- /src/angular-scorm-wrapper.js: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | ** 3 | ** Prometheus Research SCORM API Wrapper 4 | ** 5 | ** Supports: 6 | ** 7 | ** SCORM 1.2, SCORM 2004.[1] 8 | ** 9 | ** The following is a porting of the code from the 10 | ** original APIWrapper.js file to Angular JS with a 11 | ** number of improvements from 12 | ** Concurrent Technologies Corporation (CTC) released 13 | ** under the MIT style license available 14 | ** on the ADL scorm website [2] 15 | ** 16 | ** The code has been updated to wrap the original functions in 17 | ** in angularjs and extend support for SCORM 2004 [4]. 18 | ** It draws upon some of concepts offered in the Pipewerks[3] 19 | ** 20 | ** The code is served as an AngularJS service [5]. 21 | ** 22 | ** References/Inspiration: 23 | ** 24 | ** [1] ADL 25 | ** http://www.adlnet.gov/scorm 26 | ** 27 | ** [2] CTC SCORM SCORM 1.2 API wrapper 28 | ** http://www.adlnet.gov/resources/scorm-1-2-content-packages?type=software_downloads 29 | ** 30 | ** [3] Pipewerks SCORM wrapper 31 | ** https://github.com/pipwerks/scorm-api-wrapper 32 | ** 33 | ** [4] SCORM.com 34 | ** http://scorm.com/scorm-explained/technical-scorm/run-time/ 35 | ** 36 | ** [5] Angularjs services 37 | ** http://docs.angularjs.org/guide/dev_guide.services 38 | ** 39 | ** Copyright (c) Prometheus Research 2014 40 | ** Copyright (c) Philip Hutchison 41 | ** Copyright (c) Concurrent Technologies Corporation (CTC) 42 | ** --------------------------------------------------------------------------------- 43 | ** License: 44 | ** 45 | ** 46 | ** Permission is hereby granted, free of charge, to any person obtaining a 47 | ** copy of this software and associated documentation files (the “Software”), 48 | ** to deal in the Software without restriction, including without limitation the 49 | ** rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 50 | ** copies of the Software, and to permit persons to whom the Software is furnished to 51 | ** do so, subject to the following conditions: 52 | ** 53 | ** The above copyright notice and this permission notice shall be included in 54 | ** all copies or substantial portions of the Software. 55 | ** 56 | ** THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 57 | ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 58 | ** FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 59 | ** COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 60 | ** IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 61 | ** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 62 | ** 63 | *********************************************************************************/ 64 | 65 | var scormwrapper = angular.module('scormwrapper', []); 66 | 67 | scormwrapper.service('scormWrapper', function () { 68 | "use strict"; 69 | 70 | var version = "Auto"; 71 | var API = false; 72 | var scormVersions = ["Auto","1.2","2004"]; 73 | 74 | this.setAPIVersion = function (scormVersion) { 75 | 76 | scormVersion = scormVersion || "Auto"; 77 | 78 | var v = scormVersions.indexOf(scormVersion.toString()); 79 | (v > -1) ? version = scormVersions[v] : console.log("Not found, default to Auto"); 80 | return version; 81 | }; 82 | 83 | this.getAPIVersion = function () { 84 | return version; 85 | }; 86 | 87 | this.isAvailable = function () { 88 | return true; 89 | }; 90 | 91 | this.doLMSInitialize = function () { 92 | return this.cmiBooleanToJs(this.getAPICall("LMSInitialize", "Initialize")("")); 93 | }; 94 | 95 | this.doLMSFinish = function () { 96 | return this.cmiBooleanToJs(this.getAPICall("LMSFinish", "Terminate")("")); 97 | }; 98 | 99 | this.doLMSGetValue = function (parameter) { 100 | return this.getAPICall("LMSGetValue", "GetValue")(parameter); 101 | }; 102 | 103 | this.doLMSSetValue = function (parameter, value) { 104 | return this.cmiBooleanToJs(this.getAPICall("LMSSetValue", "SetValue")(parameter, value)); 105 | }; 106 | 107 | this.doLMSCommit = function () { 108 | return this.cmiBooleanToJs(this.getAPICall("LMSCommit", "Commit")("")); 109 | }; 110 | 111 | this.doLMSGetLastError = function () { 112 | return this.getAPICall("LMSGetLastError", "GetLastError")(); 113 | }; 114 | 115 | this.doLMSGetErrorString = function (errorCode) { 116 | return this.getAPICall("LMSGetErrorString", "GetErrorString")(errorCode.toString()); 117 | }; 118 | 119 | this.doLMSGetDiagnostic = function (errorCode) { 120 | return this.getAPICall("LMSGetDiagnostic", "GetDiagnostic")(errorCode.toString()); 121 | }; 122 | 123 | this.LMSIsInitialized = function () { 124 | return API; 125 | }; 126 | 127 | this.ErrorHandler = function () { 128 | return this.getAPICall("LMSGetLastError", "GetLastError")(); 129 | }; 130 | 131 | this.cmiBooleanToJs = function (value) { 132 | return (value === "1" || value === 1 || value === "true" || value === true); 133 | }; 134 | 135 | this.getAPIHandle = function () { 136 | 137 | var win = window; 138 | 139 | if (win.parent && win.parent != win) { 140 | this.findAPI(win.parent); 141 | } 142 | 143 | if (!API && win.top.opener) { 144 | this.findAPI(win.top.opener); 145 | } else if (!API) { 146 | console.log("Unable to find API adapter"); 147 | } 148 | }; 149 | 150 | this.findAPI = function (win) { 151 | 152 | var findAttempts = 0, 153 | findAttemptLimit = 500; 154 | 155 | for (findAttempts; findAttempts < findAttemptLimit; findAttempts++) { 156 | 157 | if (win.API && (version === "1.2" || version === "Auto" )) { 158 | API = win.API; 159 | version = "1.2"; 160 | break; 161 | } else if (win.API_1484_11 && (version === "2004" || version === "Auto" )) { 162 | API = win.API_1484_11; 163 | version = "2004"; 164 | break; 165 | } else if (win.parent && win.parent != win) { 166 | findAttempts++; 167 | win = win.parent; 168 | } 169 | } 170 | }; 171 | 172 | this.getAPICall = function(funcname12, funcname2004) { 173 | 174 | if (!API) { 175 | this.getAPIHandle(); 176 | if (!API) { 177 | return (function(){ 178 | console.log("No API found, can't execute: " + funcname12 + " or " + funcname2004); 179 | }); 180 | } 181 | } 182 | 183 | switch(version) { 184 | case "2004": 185 | return function() { 186 | return API[funcname2004].apply(API, arguments); 187 | }; 188 | 189 | case "1.2": 190 | return function() { 191 | return API[funcname12].apply(API, arguments); 192 | }; 193 | } 194 | }; 195 | }); 196 | 197 | -------------------------------------------------------------------------------- /test/angular-scorm-wrapper.tests.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Mock SCORM 1.2 API 4 | var API = { 5 | 6 | 7 | /******************************************************************************* 8 | ** 9 | ** Function: LMSInitialize() 10 | ** Inputs: None 11 | ** Return: CMIBoolean true if the initialization was successful, or 12 | ** CMIBoolean false if the initialization failed. These are strings 13 | ** for example "true" or "false" 14 | ** 15 | ** Description: 16 | ** Mimics the LMS SCORM 1.2 LMSInitialize function 17 | ** 18 | *******************************************************************************/ 19 | 20 | 21 | LMSInitialize : function (emptyString) { 22 | if (emptyString !== "") { 23 | return "false"; 24 | } else { 25 | return "true"; 26 | } 27 | }, 28 | 29 | /******************************************************************************* 30 | ** 31 | ** Function LMSFinish() 32 | ** Inputs: None 33 | ** Return: CMIBoolean true if successful 34 | ** CMIBoolean false if failed. 35 | ** 36 | ** Description: 37 | ** Closes communication with LMS and return "true" or "false" 38 | ** 39 | *******************************************************************************/ 40 | 41 | 42 | LMSFinish : function (emptyString) { 43 | if (emptyString !== "") { 44 | return "false"; 45 | } else { 46 | return "true"; 47 | } 48 | }, 49 | 50 | /******************************************************************************* 51 | ** 52 | ** Function LMSGetValue(name) 53 | ** Inputs: name - string representing the cmi data model defined category or 54 | ** element (e.g. cmi.core.student_id) 55 | ** Return: The value presently assigned by the LMS to the cmi data model 56 | ** element defined by the element or category identified by the name 57 | ** input value. 58 | ** 59 | ** Description: 60 | ** Returns a test string "Test Data" 61 | ** 62 | *******************************************************************************/ 63 | 64 | LMSGetValue : function (element) { 65 | if (element === "" || element === undefined) { 66 | return ""; 67 | } else { 68 | return "Test Data"; 69 | } 70 | }, 71 | 72 | /******************************************************************************* 73 | ** 74 | ** Function LMSSetValue(name, value) 75 | ** Inputs: name -string representing the data model defined category or element 76 | ** value -the value that the named element or category will be assigned 77 | ** Return: CMIBoolean true if successful 78 | ** CMIBoolean false if failed. 79 | ** 80 | ** Description: 81 | ** Returns "true" or "false" 82 | ** 83 | *******************************************************************************/ 84 | 85 | LMSSetValue : function (element, value) { 86 | if (element === "") { 87 | return "false"; 88 | } else { 89 | return "true"; 90 | } 91 | }, 92 | 93 | /******************************************************************************* 94 | ** 95 | ** Function LMSCommit() 96 | ** Inputs: None 97 | ** Return: "true" 98 | ** 99 | ** Description: 100 | ** Returns "true" 101 | ** 102 | *******************************************************************************/ 103 | 104 | LMSCommit : function () { 105 | return "true"; 106 | }, 107 | 108 | /******************************************************************************* 109 | ** 110 | ** Function LMSGetLastError() 111 | ** Inputs: None 112 | ** Return: The error code that was set by the last LMS function call 113 | ** 114 | ** Description: 115 | ** Returns 0 - which is no error. 116 | ** 117 | *******************************************************************************/ 118 | 119 | 120 | LMSGetLastError : function () { 121 | return 0; 122 | }, 123 | 124 | /******************************************************************************* 125 | ** 126 | ** Function LMSGetErrorString(errorCode) 127 | ** Inputs: errorCode - Error Code 128 | ** Return: The textual description that corresponds to the input error code 129 | ** 130 | ** Description: 131 | ** Returns a test error string "Test: No error" 132 | ** 133 | ********************************************************************************/ 134 | 135 | 136 | LMSGetErrorString : function(errorCode) { 137 | return "Test: No error"; 138 | }, 139 | 140 | /******************************************************************************* 141 | ** 142 | ** Function LMSGetDiagnostic(errorCode) 143 | ** Inputs: errorCode - Error Code(integer format), or null 144 | ** Return: The vendor specific textual description that corresponds to the 145 | ** input error code 146 | ** 147 | ** Description: 148 | ** Returns a test string "Test: Diagnostic no error" 149 | ** 150 | *******************************************************************************/ 151 | 152 | LMSGetDiagnostic : function(errorCode) { 153 | return "Test: Diagnostic no error"; 154 | } 155 | 156 | }; 157 | 158 | 159 | // Mock SCORM 2004 API 160 | var API_1484_11 = { 161 | 162 | /******************************************************************************* 163 | ** 164 | ** Function: Initialize() 165 | ** Inputs: None 166 | ** Return: CMIBoolean true if the initialization was successful, or 167 | ** CMIBoolean false if the initialization failed. These are strings 168 | ** for example "true" or "false" 169 | ** 170 | ** Description: 171 | ** Mimics the LMS SCORM 2004 Initialize function 172 | ** 173 | *******************************************************************************/ 174 | 175 | 176 | Initialize : function (emptyString) { 177 | if (emptyString !== "") { 178 | return "false"; 179 | } else { 180 | return "true"; 181 | } 182 | }, 183 | 184 | /******************************************************************************* 185 | ** 186 | ** Function Terminate() 187 | ** Inputs: None 188 | ** Return: CMIBoolean true if successful 189 | ** CMIBoolean false if failed. 190 | ** 191 | ** Description: 192 | ** Closes communication with LMS and return "true" or "false" 193 | ** 194 | *******************************************************************************/ 195 | 196 | 197 | Terminate : function (emptyString) { 198 | if (emptyString !== "") { 199 | return "false"; 200 | } else { 201 | return "true"; 202 | } 203 | }, 204 | 205 | /******************************************************************************* 206 | ** 207 | ** Function GetValue(name) 208 | ** Inputs: name - string representing the cmi data model defined category or 209 | ** element (e.g. cmi.core.student_id) 210 | ** Return: The value presently assigned by the LMS to the cmi data model 211 | ** element defined by the element or category identified by the name 212 | ** input value. 213 | ** 214 | ** Description: 215 | ** Returns a test string "Test Data" 216 | ** 217 | *******************************************************************************/ 218 | 219 | GetValue : function (element) { 220 | if (element === "" || element === undefined) { 221 | return ""; 222 | } else { 223 | return "Test Data"; 224 | } 225 | }, 226 | 227 | /******************************************************************************* 228 | ** 229 | ** Function SetValue(name, value) 230 | ** Inputs: name -string representing the data model defined category or element 231 | ** value -the value that the named element or category will be assigned 232 | ** Return: CMIBoolean true if successful 233 | ** CMIBoolean false if failed. 234 | ** 235 | ** Description: 236 | ** Returns "true" or "false" 237 | ** 238 | *******************************************************************************/ 239 | 240 | SetValue : function (element, value) { 241 | if (element === "") { 242 | return "false"; 243 | } else { 244 | return "true"; 245 | } 246 | }, 247 | 248 | /******************************************************************************* 249 | ** 250 | ** Function Commit() 251 | ** Inputs: None 252 | ** Return: "true" 253 | ** 254 | ** Description: 255 | ** Returns "true" 256 | ** 257 | *******************************************************************************/ 258 | 259 | Commit : function () { 260 | return "true"; 261 | }, 262 | 263 | /******************************************************************************* 264 | ** 265 | ** Function GetLastError() 266 | ** Inputs: None 267 | ** Return: The error code that was set by the last LMS function call 268 | ** 269 | ** Description: 270 | ** Returns 0 - which is no error. 271 | ** 272 | *******************************************************************************/ 273 | 274 | 275 | GetLastError : function () { 276 | return 0; 277 | }, 278 | 279 | /******************************************************************************* 280 | ** 281 | ** Function GetErrorString(errorCode) 282 | ** Inputs: errorCode - Error Code 283 | ** Return: The textual description that corresponds to the input error code 284 | ** 285 | ** Description: 286 | ** Returns a test error string "Test: No error" 287 | ** 288 | ********************************************************************************/ 289 | 290 | 291 | GetErrorString : function(errorCode) { 292 | return "Test: No error"; 293 | }, 294 | 295 | /******************************************************************************* 296 | ** 297 | ** Function GetDiagnostic(errorCode) 298 | ** Inputs: errorCode - Error Code(integer format), or null 299 | ** Return: The vendor specific textual description that corresponds to the 300 | ** input error code 301 | ** 302 | ** Description: 303 | ** Returns a test string "Test: Diagnostic no error" 304 | ** 305 | *******************************************************************************/ 306 | 307 | GetDiagnostic : function(errorCode) { 308 | return "Test: Diagnostic no error"; 309 | } 310 | 311 | }; 312 | 313 | 314 | describe('scormWrapper test', function(){ 315 | 316 | /****************************************** 317 | ** Tests for getting and setting SCORM API 318 | ** version. 319 | *******************************************/ 320 | 321 | describe('When I call scormWrapper.setAPIVersion() with 1.2 ', function(){ 322 | beforeEach(module('scormwrapper')); 323 | it('returns "1.2" ', inject(function(scormWrapper){ 324 | 325 | expect( scormWrapper.setAPIVersion("1.2") ).toEqual("1.2"); 326 | 327 | })); 328 | 329 | }); 330 | 331 | describe('When I call scormWrapper.setAPIVersion() with 2004 ', function(){ 332 | beforeEach(module('scormwrapper')); 333 | it('returns "2004" ', inject(function(scormWrapper){ 334 | 335 | expect( scormWrapper.setAPIVersion("2004") ).toEqual("2004"); 336 | 337 | })); 338 | 339 | }); 340 | 341 | describe('When I call scormWrapper.getAPIVersion() without a param ', function(){ 342 | beforeEach(module('scormwrapper')); 343 | it('returns "Auto"', inject(function(scormWrapper){ 344 | 345 | expect( scormWrapper.getAPIVersion() ).toEqual("Auto"); 346 | 347 | })); 348 | 349 | }); 350 | 351 | 352 | describe('When I call scormWrapper.setAPIVersion() with "1.2" and scormWrapper.getAPIVersion()', function(){ 353 | beforeEach(module('scormwrapper')); 354 | it(' returns "1.2" true and "1.2"', inject(function(scormWrapper){ 355 | 356 | expect( scormWrapper.setAPIVersion("1.2") ).toEqual("1.2"); 357 | expect( scormWrapper.getAPIVersion() ).toEqual("1.2"); 358 | 359 | })); 360 | 361 | }); 362 | 363 | describe('When I call scormWrapper.setAPIVersion() with "2004" and scormWrapper.getAPIVersion()', function(){ 364 | beforeEach(module('scormwrapper')); 365 | it('returns "2004" and "2004"', inject(function(scormWrapper){ 366 | 367 | expect( scormWrapper.setAPIVersion("2004") ).toEqual("2004"); 368 | expect( scormWrapper.getAPIVersion() ).toEqual("2004"); 369 | 370 | })); 371 | 372 | }); 373 | 374 | describe('When I call scormWrapper.setAPIVersion() with "Auto" and scormWrapper.getAPIVersion()', function(){ 375 | beforeEach(module('scormwrapper')); 376 | it('returns "Auto" and "Auto"', inject(function(scormWrapper){ 377 | 378 | expect( scormWrapper.setAPIVersion("Auto") ).toEqual("Auto"); 379 | expect( scormWrapper.getAPIVersion() ).toEqual("Auto"); 380 | 381 | })); 382 | 383 | }); 384 | 385 | 386 | describe('When I call scormWrapper.setAPIVersion() with erroneous data', function(){ 387 | beforeEach(module('scormwrapper')); 388 | it('returns "Auto" and version is "Auto"', inject(function(scormWrapper){ 389 | 390 | expect( scormWrapper.setAPIVersion("1.3") ).toEqual("Auto"); 391 | expect( scormWrapper.getAPIVersion() ).toEqual("Auto"); 392 | 393 | expect( scormWrapper.setAPIVersion("abc") ).toEqual("Auto"); 394 | expect( scormWrapper.getAPIVersion() ).toEqual("Auto"); 395 | 396 | expect( scormWrapper.setAPIVersion("SCORM 1.2") ).toEqual("Auto"); 397 | expect( scormWrapper.getAPIVersion() ).toEqual("Auto"); 398 | 399 | expect( scormWrapper.setAPIVersion("SCORM 2004") ).toEqual("Auto"); 400 | expect( scormWrapper.getAPIVersion() ).toEqual("Auto"); 401 | 402 | expect( scormWrapper.setAPIVersion("12") ).toEqual("Auto"); 403 | expect( scormWrapper.getAPIVersion() ).toEqual("Auto"); 404 | 405 | expect( scormWrapper.setAPIVersion("") ).toEqual("Auto"); 406 | expect( scormWrapper.getAPIVersion() ).toEqual("Auto"); 407 | 408 | expect( scormWrapper.setAPIVersion() ).toEqual("Auto"); 409 | expect( scormWrapper.getAPIVersion() ).toEqual("Auto"); 410 | 411 | expect( scormWrapper.setAPIVersion(null) ).toEqual("Auto"); 412 | expect( scormWrapper.getAPIVersion() ).toEqual("Auto"); 413 | 414 | expect( scormWrapper.setAPIVersion(undefined) ).toEqual("Auto"); 415 | expect( scormWrapper.getAPIVersion() ).toEqual("Auto"); 416 | 417 | 418 | })); 419 | 420 | 421 | }); 422 | 423 | describe('When I call scormWrapper.setAPIVersion() with 1.2 or 2004 as numeric values', function(){ 424 | beforeEach(module('scormwrapper')); 425 | it('returns the version as a string', inject(function(scormWrapper){ 426 | 427 | expect( scormWrapper.setAPIVersion(1.2) ).toEqual("1.2"); 428 | expect( scormWrapper.getAPIVersion() ).toEqual("1.2"); 429 | 430 | expect( scormWrapper.setAPIVersion(2004) ).toEqual("2004"); 431 | expect( scormWrapper.getAPIVersion() ).toEqual("2004"); 432 | 433 | })); 434 | 435 | }); 436 | 437 | 438 | /****************************************** 439 | ** Tests function that lets Flash know 440 | ** Scorm API wrapper exists. 441 | *******************************************/ 442 | 443 | describe('When I call scormWrapper.isAvailable() ', function(){ 444 | beforeEach(module('scormwrapper')); 445 | it('returns true', inject(function(scormWrapper){ //parameter name = service name 446 | 447 | expect( scormWrapper.isAvailable() ).toEqual(true); 448 | 449 | })); 450 | 451 | }); 452 | 453 | /****************************************** 454 | ** Tests doLMSInitialize() in various 455 | ** scenarios. 456 | *******************************************/ 457 | 458 | describe('When I call scormWrapper.doLMSInitialize with no LMS present ', function(){ 459 | beforeEach(module('scormwrapper')); 460 | it('returns false', inject(function(scormWrapper){ 461 | window.parent.API = undefined; 462 | window.parent.API_1484_11 = undefined; 463 | expect( scormWrapper.doLMSInitialize() ).toEqual(false); 464 | 465 | })); 466 | 467 | }); 468 | 469 | //Auto 470 | describe('When I call scormWrapper.doLMSInitialize with an LMS present ', function(){ 471 | beforeEach(module('scormwrapper')); 472 | it('Auto returns true and version is "1.2" ', inject(function(scormWrapper){ 473 | window.parent.API = API; 474 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 475 | expect( scormWrapper.getAPIVersion() ).toEqual("1.2"); 476 | 477 | })); 478 | 479 | }); 480 | 481 | //Scorm 1.2 482 | describe('When I call scormWrapper.doLMSInitialize with an LMS present and version = 1.2 ', function(){ 483 | beforeEach(module('scormwrapper')); 484 | it('SCORM 1.2 returns true', inject(function(scormWrapper){ 485 | window.parent.API = API; 486 | expect( scormWrapper.setAPIVersion("1.2") ).toEqual("1.2"); 487 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 488 | 489 | })); 490 | 491 | }); 492 | 493 | 494 | //Scorm 2004 495 | describe('When I call scormWrapper.doLMSInitialize with an LMS present and version = 2004 ', function(){ 496 | beforeEach(module('scormwrapper')); 497 | it('SCORM 2004 returns true', inject(function(scormWrapper){ 498 | window.parent.API_1484_11 = API_1484_11; 499 | expect( scormWrapper.setAPIVersion("2004") ).toEqual("2004"); 500 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 501 | 502 | })); 503 | 504 | }); 505 | 506 | /****************************************** 507 | ** Tests doLMSFinish() in various 508 | ** scenarios. 509 | *******************************************/ 510 | 511 | //Auto 512 | describe('When I call scormWrapper.doLMSFinish with an LMS present ', function(){ 513 | beforeEach(module('scormwrapper')); 514 | it(' it returns true', inject(function(scormWrapper){ 515 | window.parent.API = API; 516 | expect( scormWrapper.setAPIVersion("Auto") ).toEqual("Auto"); 517 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 518 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 519 | 520 | })); 521 | 522 | }); 523 | 524 | //Scorm 1.2 525 | describe('When I call scormWrapper.doLMSFinish with an LMS present and version = 1.2 ', function(){ 526 | beforeEach(module('scormwrapper')); 527 | it('SCORM 1.2 returns true', inject(function(scormWrapper){ 528 | window.parent.API = API; 529 | expect( scormWrapper.setAPIVersion("1.2") ).toEqual("1.2"); 530 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 531 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 532 | 533 | })); 534 | 535 | }); 536 | 537 | 538 | //Scorm 2004 539 | describe('When I call scormWrapper.doLMSFinish with an LMS present and version = 2004 ', function(){ 540 | beforeEach(module('scormwrapper')); 541 | it('SCORM 2004 returns true', inject(function(scormWrapper){ 542 | window.parent.API_1484_11 = API_1484_11; 543 | expect( scormWrapper.setAPIVersion("2004") ).toEqual("2004"); 544 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 545 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 546 | 547 | })); 548 | 549 | }); 550 | 551 | /****************************************** 552 | ** Tests doLMSGetValue() in various 553 | ** scenarios. 554 | *******************************************/ 555 | 556 | //Auto 557 | describe('When I call scormWrapper.doLMSGetValue with an LMS present ', function(){ 558 | beforeEach(module('scormwrapper')); 559 | it('Auto returns Test Data', inject(function(scormWrapper){ 560 | window.parent.API = API; 561 | expect( scormWrapper.setAPIVersion("Auto") ).toEqual("Auto"); 562 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 563 | expect( scormWrapper.doLMSGetValue("cmi.suspend_data") ).toEqual("Test Data"); 564 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 565 | 566 | })); 567 | 568 | }); 569 | 570 | //Scorm 1.2 571 | describe('When I call scormWrapper.doLMSGetValue with an LMS present and version = 1.2 ', function(){ 572 | beforeEach(module('scormwrapper')); 573 | it('SCORM 1.2 returns Test Data', inject(function(scormWrapper){ 574 | window.parent.API = API; 575 | expect( scormWrapper.setAPIVersion("1.2") ).toEqual("1.2"); 576 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 577 | expect( scormWrapper.doLMSGetValue("cmi.suspend_data") ).toEqual("Test Data"); 578 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 579 | 580 | })); 581 | 582 | }); 583 | 584 | describe('When I call scormWrapper.doLMSGetValue with no data model element ', function(){ 585 | beforeEach(module('scormwrapper')); 586 | it('SCORM 1.2 returns ""', inject(function(scormWrapper){ 587 | window.parent.API = API; 588 | expect( scormWrapper.setAPIVersion("1.2") ).toEqual("1.2"); 589 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 590 | expect( scormWrapper.doLMSGetValue("") ).toEqual(""); 591 | expect( scormWrapper.doLMSGetValue() ).toEqual(""); 592 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 593 | 594 | })); 595 | 596 | }); 597 | 598 | //Scorm 2004 599 | describe('When I call scormWrapper.doLMSGetValue with an LMS present and version = 2004 ', function(){ 600 | beforeEach(module('scormwrapper')); 601 | it('SCORM 2004 returns Test Data', inject(function(scormWrapper){ 602 | window.parent.API_1484_11 = API_1484_11; 603 | expect( scormWrapper.setAPIVersion("2004") ).toEqual("2004"); 604 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 605 | expect( scormWrapper.doLMSGetValue("cmi.suspend_data") ).toEqual("Test Data"); 606 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 607 | 608 | })); 609 | 610 | }); 611 | 612 | describe('When I call scormWrapper.doLMSGetValue with no data model element ', function(){ 613 | beforeEach(module('scormwrapper')); 614 | it('SCORM 2004 returns ""', inject(function(scormWrapper){ 615 | window.parent.API_1484_11 = API_1484_11; 616 | expect( scormWrapper.setAPIVersion("2004") ).toEqual("2004"); 617 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 618 | expect( scormWrapper.doLMSGetValue("") ).toEqual(""); 619 | expect( scormWrapper.doLMSGetValue() ).toEqual(""); 620 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 621 | 622 | })); 623 | 624 | }); 625 | 626 | /****************************************** 627 | ** Tests doLMSSetValue() in various 628 | ** scenarios. 629 | *******************************************/ 630 | 631 | //Auto 632 | describe('When I call scormWrapper.doLMSSetValue with an LMS present ', function(){ 633 | beforeEach(module('scormwrapper')); 634 | it('Auto returns true', inject(function(scormWrapper){ 635 | window.parent.API = API; 636 | expect( scormWrapper.setAPIVersion("Auto") ).toEqual("Auto"); 637 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 638 | expect( scormWrapper.doLMSSetValue("cmi.score.raw",10) ).toEqual(true); 639 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 640 | 641 | })); 642 | 643 | }); 644 | 645 | //Scorm 1.2 646 | describe('When I call scormWrapper.doLMSSetValue with an LMS present and version = 1.2 ', function(){ 647 | beforeEach(module('scormwrapper')); 648 | it('SCORM 1.2 returns true', inject(function(scormWrapper){ 649 | window.parent.API = API; 650 | expect( scormWrapper.setAPIVersion("1.2") ).toEqual("1.2"); 651 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 652 | expect( scormWrapper.doLMSSetValue("cmi.score.raw",10) ).toEqual(true); 653 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 654 | 655 | })); 656 | 657 | }); 658 | 659 | describe('When I call scormWrapper.doLMSSetValue missing a data model element', function(){ 660 | beforeEach(module('scormwrapper')); 661 | it('SCORM 1.2 returns false', inject(function(scormWrapper){ 662 | window.parent.API = API; 663 | expect( scormWrapper.setAPIVersion("1.2") ).toEqual("1.2"); 664 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 665 | expect( scormWrapper.doLMSSetValue("",10) ).toEqual(false); 666 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 667 | 668 | })); 669 | 670 | }); 671 | 672 | //Scorm 2004 673 | describe('When I call scormWrapper.doLMSSetValue with an LMS present and version = 2004 ', function(){ 674 | beforeEach(module('scormwrapper')); 675 | it('SCORM 2004 returns true', inject(function(scormWrapper){ 676 | window.parent.API_1484_11 = API_1484_11; 677 | expect( scormWrapper.setAPIVersion("2004") ).toEqual("2004"); 678 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 679 | expect( scormWrapper.doLMSSetValue("cmi.score.raw",10) ).toEqual(true); 680 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 681 | 682 | })); 683 | 684 | }); 685 | 686 | describe('When I call scormWrapper.doLMSSetValue missing a data model element ', function(){ 687 | beforeEach(module('scormwrapper')); 688 | it('SCORM 2004 returns false', inject(function(scormWrapper){ 689 | window.parent.API_1484_11 = API_1484_11; 690 | expect( scormWrapper.setAPIVersion("2004") ).toEqual("2004"); 691 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 692 | expect( scormWrapper.doLMSSetValue("",10) ).toEqual(false); 693 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 694 | 695 | })); 696 | 697 | }); 698 | 699 | /****************************************** 700 | ** Tests doLMSCommit() in various 701 | ** scenarios. 702 | *******************************************/ 703 | 704 | //Auto 705 | describe('When I call scormWrapper.doLMSCommit with an LMS present ', function(){ 706 | beforeEach(module('scormwrapper')); 707 | it('Auto returns true', inject(function(scormWrapper){ 708 | window.parent.API = API; 709 | expect( scormWrapper.setAPIVersion("Auto") ).toEqual("Auto"); 710 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 711 | expect( scormWrapper.doLMSSetValue("cmi.score.raw",10) ).toEqual(true); 712 | expect( scormWrapper.doLMSCommit() ).toEqual(true); 713 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 714 | 715 | })); 716 | 717 | }); 718 | 719 | //Scorm 1.2 720 | describe('When I call scormWrapper.doLMSCommit with an LMS present and version = 1.2 ', function(){ 721 | beforeEach(module('scormwrapper')); 722 | it('SCORM 1.2 returns true', inject(function(scormWrapper){ 723 | window.parent.API = API; 724 | expect( scormWrapper.setAPIVersion("1.2") ).toEqual("1.2"); 725 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 726 | expect( scormWrapper.doLMSSetValue("cmi.score.raw",10) ).toEqual(true); 727 | expect( scormWrapper.doLMSCommit() ).toEqual(true); 728 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 729 | 730 | })); 731 | 732 | }); 733 | 734 | 735 | //Scorm 2004 736 | describe('When I call scormWrapper.doLMSCommit with an LMS present and version = 2004 ', function(){ 737 | beforeEach(module('scormwrapper')); 738 | it('SCORM 2004 returns true', inject(function(scormWrapper){ 739 | window.parent.API_1484_11 = API_1484_11; 740 | expect( scormWrapper.setAPIVersion("2004") ).toEqual("2004"); 741 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 742 | expect( scormWrapper.doLMSSetValue("cmi.score.raw",10) ).toEqual(true); 743 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 744 | 745 | })); 746 | 747 | }); 748 | 749 | 750 | /****************************************** 751 | ** Tests doLMSGetLastError() in various 752 | ** scenarios. 753 | *******************************************/ 754 | 755 | //Auto 756 | describe('When I call scormWrapper.doLMSGetLastError with an LMS present ', function(){ 757 | beforeEach(module('scormwrapper')); 758 | it('Auto returns 0', inject(function(scormWrapper){ 759 | window.parent.API = API; 760 | expect( scormWrapper.setAPIVersion("Auto") ).toEqual("Auto"); 761 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 762 | expect( scormWrapper.doLMSGetLastError() ).toEqual(0); 763 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 764 | 765 | })); 766 | 767 | }); 768 | 769 | //Scorm 1.2 770 | describe('When I call scormWrapper.doLMSGetLastError with an LMS present and version = 1.2 ', function(){ 771 | beforeEach(module('scormwrapper')); 772 | it('SCORM 1.2 returns 0', inject(function(scormWrapper){ 773 | window.parent.API = API; 774 | expect( scormWrapper.setAPIVersion("1.2") ).toEqual("1.2"); 775 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 776 | expect( scormWrapper.doLMSGetLastError() ).toEqual(0); 777 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 778 | 779 | })); 780 | 781 | }); 782 | 783 | 784 | //Scorm 2004 785 | describe('When I call scormWrapper.doLMSGetLastError with an LMS present and version = 2004 ', function(){ 786 | beforeEach(module('scormwrapper')); 787 | it('SCORM 2004 returns 0', inject(function(scormWrapper){ 788 | window.parent.API_1484_11 = API_1484_11; 789 | expect( scormWrapper.setAPIVersion("2004") ).toEqual("2004"); 790 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 791 | expect( scormWrapper.doLMSGetLastError() ).toEqual(0); 792 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 793 | 794 | })); 795 | 796 | }); 797 | 798 | /****************************************** 799 | ** Tests doLMSGetErrorString() in various 800 | ** scenarios. 801 | *******************************************/ 802 | 803 | //Auto 804 | describe('When I call scormWrapper.doLMSGetErrorString with an LMS present ', function(){ 805 | beforeEach(module('scormwrapper')); 806 | it('Auto returns Test: No error', inject(function(scormWrapper){ 807 | window.parent.API = API; 808 | expect( scormWrapper.setAPIVersion("Auto") ).toEqual("Auto"); 809 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 810 | expect( scormWrapper.doLMSGetErrorString(0) ).toEqual("Test: No error"); 811 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 812 | 813 | })); 814 | 815 | }); 816 | 817 | //Scorm 1.2 818 | describe('When I call scormWrapper.doLMSGetErrorString with an LMS present and version = 1.2 ', function(){ 819 | beforeEach(module('scormwrapper')); 820 | it('SCORM 1.2 returns Test: No error', inject(function(scormWrapper){ 821 | window.parent.API = API; 822 | expect( scormWrapper.setAPIVersion("1.2") ).toEqual("1.2"); 823 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 824 | expect( scormWrapper.doLMSGetErrorString(0) ).toEqual("Test: No error"); 825 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 826 | 827 | })); 828 | 829 | }); 830 | 831 | 832 | //Scorm 2004 833 | describe('When I call scormWrapper.doLMSGetErrorString with an LMS present and version = 2004 ', function(){ 834 | beforeEach(module('scormwrapper')); 835 | it('SCORM 2004 returns Test: No error', inject(function(scormWrapper){ 836 | window.parent.API_1484_11 = API_1484_11; 837 | expect( scormWrapper.setAPIVersion("2004") ).toEqual("2004"); 838 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 839 | expect( scormWrapper.doLMSGetErrorString(0) ).toEqual("Test: No error"); 840 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 841 | 842 | })); 843 | 844 | }); 845 | 846 | /****************************************** 847 | ** Tests doLMSGetDiagnostic() in various 848 | ** scenarios. 849 | *******************************************/ 850 | 851 | //Auto 852 | describe('When I call scormWrapper.doLMSGetDiagnostic with an LMS present ', function(){ 853 | beforeEach(module('scormwrapper')); 854 | it('Auto returns Test: Diagnostic no error', inject(function(scormWrapper){ 855 | window.parent.API = API; 856 | expect( scormWrapper.setAPIVersion("Auto") ).toEqual("Auto"); 857 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 858 | expect( scormWrapper.doLMSGetDiagnostic(0) ).toEqual("Test: Diagnostic no error"); 859 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 860 | 861 | })); 862 | 863 | }); 864 | 865 | //Scorm 1.2 866 | describe('When I call scormWrapper.doLMSGetDiagnostic with an LMS present and version = 1.2 ', function(){ 867 | beforeEach(module('scormwrapper')); 868 | it('SCORM 1.2 returns Test: Diagnostic no error', inject(function(scormWrapper){ 869 | window.parent.API = API; 870 | expect( scormWrapper.setAPIVersion("1.2") ).toEqual("1.2"); 871 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 872 | expect( scormWrapper.doLMSGetDiagnostic(0) ).toEqual("Test: Diagnostic no error"); 873 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 874 | 875 | })); 876 | 877 | }); 878 | 879 | 880 | //Scorm 2004 881 | describe('When I call scormWrapper.doLMSGetDiagnostic with an LMS present and version = 2004 ', function(){ 882 | beforeEach(module('scormwrapper')); 883 | it('SCORM 2004 returns Test: Diagnostic no error', inject(function(scormWrapper){ 884 | window.parent.API_1484_11 = API_1484_11; 885 | expect( scormWrapper.setAPIVersion("2004") ).toEqual("2004"); 886 | expect( scormWrapper.doLMSInitialize() ).toEqual(true); 887 | expect( scormWrapper.doLMSGetDiagnostic(0) ).toEqual("Test: Diagnostic no error"); 888 | expect( scormWrapper.doLMSFinish() ).toEqual(true); 889 | 890 | })); 891 | 892 | }); 893 | 894 | }); 895 | --------------------------------------------------------------------------------