From 75948467a7ac1a4fa3f4980bf0fb47412bb226c5 Mon Sep 17 00:00:00 2001 From: Samer Albahra Date: Tue, 26 Nov 2024 17:24:53 -0500 Subject: [PATCH 01/14] Apply suggested fix for lint warnings --- www/js/home.js | 2 +- www/js/modules/dates.js | 2 +- www/js/modules/import-export.js | 2 +- www/js/modules/language.js | 2 +- www/js/modules/network.js | 6 +++--- www/js/modules/options.js | 6 +++--- www/js/modules/sites.js | 10 +++++----- www/js/modules/stations.js | 6 +++--- www/js/modules/status.js | 2 +- www/js/modules/storage.js | 6 +++--- www/js/modules/ui-dom.js | 10 +++++----- www/js/modules/utils.js | 2 +- 12 files changed, 28 insertions(+), 28 deletions(-) diff --git a/www/js/home.js b/www/js/home.js index af7edd48..ac4bab35 100644 --- a/www/js/home.js +++ b/www/js/home.js @@ -27,7 +27,7 @@ return def; } - mainScript = /^\s*(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/.exec( mainScript || "" ) || []; + mainScript = /^\s*(((([^:/#?]+:)?(?:(\/\/)((?:(([^:@/#?]+)(?::([^:@/#?]+))?)@)?(([^:/#?\][]+|\[[^/\]@#?]+\])(?::([0-9]+))?))?)?)?((\/?(?:[^/?#]+\/+)*)([^?#]*)))?(\?[^#]+)?)(#.*)?/.exec( mainScript || "" ) || []; return mainScript[ 1 ].slice( 0, -10 ) || def; } diff --git a/www/js/modules/dates.js b/www/js/modules/dates.js index edd7e179..b5fe05de 100644 --- a/www/js/modules/dates.js +++ b/www/js/modules/dates.js @@ -18,7 +18,7 @@ OSApp.Dates = OSApp.Dates || {}; OSApp.Dates.Constants = { MIN_DATE: "01/01", MAX_DATE: "12/31", - DATE_REGEX: /[0-9]{1,2}[\/][0-9]{1,2}/g + DATE_REGEX: /[0-9]{1,2}[/][0-9]{1,2}/g }; // TODO: mellodev some of this should refactor out to programs.js? diff --git a/www/js/modules/import-export.js b/www/js/modules/import-export.js index f6c80889..4ff0c419 100644 --- a/www/js/modules/import-export.js +++ b/www/js/modules/import-export.js @@ -184,7 +184,7 @@ OSApp.ImportExport.importConfig = function( data ) { var findKey = function( index ) { return OSApp.Constants.keyIndex[ index ] === key; }; for ( i in data.options ) { - if ( data.options.hasOwnProperty( i ) && OSApp.Constants.keyIndex.hasOwnProperty( i ) ) { + if ( Object.prototype.hasOwnProperty.call(data.options, i ) && Object.prototype.hasOwnProperty.call(OSApp.Constants.keyIndex, i ) ) { key = OSApp.Constants.keyIndex[ i ]; if ( $.inArray( key, [ 2, 14, 16, 21, 22, 25, 36 ] ) !== -1 && data.options[ i ] === 0 ) { continue; diff --git a/www/js/modules/language.js b/www/js/modules/language.js index 422e82bf..9a412488 100644 --- a/www/js/modules/language.js +++ b/www/js/modules/language.js @@ -21,7 +21,7 @@ OSApp.Language = OSApp.Language || {}; OSApp.Language._ = function( key ) { //Translate item (key) based on currently defined language - if ( typeof OSApp.uiState.language === "object" && OSApp.uiState.language.hasOwnProperty( key ) ) { + if ( typeof OSApp.uiState.language === "object" && Object.prototype.hasOwnProperty.call(OSApp.uiState.language, key ) ) { var trans = OSApp.uiState.language[ key ]; return trans ? trans : key; } else { diff --git a/www/js/modules/network.js b/www/js/modules/network.js index 322fb767..fdb3af1d 100644 --- a/www/js/modules/network.js +++ b/www/js/modules/network.js @@ -77,7 +77,7 @@ OSApp.Network.startScan = function( port, type ) { i; for ( i in oldsites ) { - if ( oldsites.hasOwnProperty( i ) ) { + if ( Object.prototype.hasOwnProperty.call(oldsites, i ) ) { oldips.push( oldsites[ i ].os_ip ); } } @@ -103,7 +103,7 @@ OSApp.Network.startScan = function( port, type ) { } fwv = tmp[ 1 ]; } else { - if ( !reply.hasOwnProperty( "fwv" ) ) { + if ( !Object.prototype.hasOwnProperty.call(reply, "fwv" ) ) { return; } fwv = reply.fwv; @@ -314,7 +314,7 @@ OSApp.Network.checkPublicAccess = function( eip ) { type: "GET" } ).then( function( data ) { - if ( typeof data !== "object" || !data.hasOwnProperty( "fwv" ) || data.fwv !== OSApp.currentSession.controller.options.fwv || + if ( typeof data !== "object" || !Object.prototype.hasOwnProperty.call(data, "fwv" ) || data.fwv !== OSApp.currentSession.controller.options.fwv || ( OSApp.Firmware.checkOSVersion( 214 ) && OSApp.currentSession.controller.options.ip4 !== data.ip4 ) ) { fail(); return; diff --git a/www/js/modules/options.js b/www/js/modules/options.js index 113a9f45..de917c0b 100644 --- a/www/js/modules/options.js +++ b/www/js/modules/options.js @@ -538,7 +538,7 @@ OSApp.Options.showOptions = function( expandItem ) { "" + "" + "
" + - "" + + "" + "
" + "" + "" + @@ -1681,7 +1681,7 @@ OSApp.Options.coordsToLocation = function( lat, lon, callback, fallback ) { var hasEnd = false; for ( var item in data ) { - if ( data.hasOwnProperty( item ) ) { + if ( Object.prototype.hasOwnProperty.call(data, item ) ) { if ( $.inArray( "locality", data[ item ].types ) > -1 || $.inArray( "sublocality", data[ item ].types ) > -1 || $.inArray( "postal_code", data[ item ].types ) > -1 || @@ -1705,7 +1705,7 @@ OSApp.Options.coordsToLocation = function( lat, lon, callback, fallback ) { hasEnd = false; for ( item in data ) { - if ( data.hasOwnProperty( item ) && !hasEnd ) { + if ( Object.prototype.hasOwnProperty.call(data, item ) && !hasEnd ) { if ( location === "" && $.inArray( "locality", data[ item ].types ) > -1 ) { location = data[ item ].long_name + ", " + location; } diff --git a/www/js/modules/sites.js b/www/js/modules/sites.js index 5a219b0f..8d4cbbe3 100644 --- a/www/js/modules/sites.js +++ b/www/js/modules/sites.js @@ -61,7 +61,7 @@ OSApp.Sites.updateSiteList = function( names, current ) { OSApp.Sites.findLocalSiteName = function( sites, callback ) { callback = callback || function() {}; for ( var site in sites ) { - if ( sites.hasOwnProperty( site ) ) { + if ( Object.prototype.hasOwnProperty.call(sites, site ) ) { if ( OSApp.currentSession.ip.indexOf( sites[ site ].os_ip ) !== -1 ) { callback( site ); return; @@ -675,7 +675,7 @@ OSApp.Sites.updateControllerPrograms = function( callback ) { // If the controller is using firmware 1.8.3, then parse the script tag for variables return OSApp.Firmware.sendToOS( "/gp?d=0" ).done( function( programs ) { - var vars = programs.match( /(nprogs|nboards|mnp)=[\w|\d|.\"]+/g ), + var vars = programs.match( /(nprogs|nboards|mnp)=[\w|\d|."]+/g ), progs = /pd=\[\];(.*);/.exec( programs ), newdata = {}, tmp, prog; @@ -752,7 +752,7 @@ OSApp.Sites.updateControllerOptions = function( callback ) { vars = {}, tmp, i, o; if ( isOSPi ) { - var varsRegex = /(tz|htp|htp2|nbrd|seq|sdt|mas|mton|mtoff|urs|rst|wl|ipas)\s?[=|:]\s?([\w|\d|.\"]+)/gm, + var varsRegex = /(tz|htp|htp2|nbrd|seq|sdt|mas|mton|mtoff|urs|rst|wl|ipas)\s?[=|:]\s?([\w|\d|."]+)/gm, name; while ( ( tmp = varsRegex.exec( options ) ) !== null ) { @@ -821,8 +821,8 @@ OSApp.Sites.updateControllerSettings = function( callback ) { // If the controller is using firmware 1.8.3, then parse the script tag for variables return OSApp.Firmware.sendToOS( "" ).then( function( settings ) { - var varsRegex = /(ver|devt|nbrd|tz|en|rd|rs|mm|rdst|urs)\s?[=|:]\s?([\w|\d|.\"]+)/gm, - loc = settings.match( /loc\s?[=|:]\s?[\"|'](.*)[\"|']/ ), + var varsRegex = /(ver|devt|nbrd|tz|en|rd|rs|mm|rdst|urs)\s?[=|:]\s?([\w|\d|."]+)/gm, + loc = settings.match( /loc\s?[=|:]\s?["|'](.*)["|']/ ), lrun = settings.match( /lrun=\[(.*)\]/ ), ps = settings.match( /ps=\[(.*)\];/ ), vars = {}, tmp, i; diff --git a/www/js/modules/stations.js b/www/js/modules/stations.js index d6d939a1..7c3c6133 100644 --- a/www/js/modules/stations.js +++ b/www/js/modules/stations.js @@ -138,7 +138,7 @@ OSApp.Stations.stopAllStations = function() { OSApp.Stations.removeStationTimers = function() { for ( var timer in OSApp.uiState.timers ) { - if ( OSApp.uiState.timers.hasOwnProperty( timer ) ) { + if ( Object.prototype.hasOwnProperty.call(OSApp.uiState.timers, timer ) ) { if ( timer !== "clock" ) { delete OSApp.uiState.timers[ timer ]; } @@ -194,11 +194,11 @@ OSApp.Stations.verifyRemoteStation = function( data, callback ) { dataType: "json" } ).then( function( result ) { - if ( typeof result !== "object" || !result.hasOwnProperty( "fwv" ) ) { + if ( typeof result !== "object" || !Object.prototype.hasOwnProperty.call(result, "fwv" ) ) { callback( -1 ); } else if ( Object.keys( result ).length === 1 ) { callback( -2 ); - } else if ( !result.hasOwnProperty( "re" ) || result.re === 0 ) { + } else if ( !Object.prototype.hasOwnProperty.call(result, "re" ) || result.re === 0 ) { callback( -3 ); } else { callback( true ); diff --git a/www/js/modules/status.js b/www/js/modules/status.js index e8ff8cd2..19dd305d 100644 --- a/www/js/modules/status.js +++ b/www/js/modules/status.js @@ -150,7 +150,7 @@ OSApp.Status.checkStatus = function() { ptotal = 0; for ( i in open ) { - if ( open.hasOwnProperty( i ) ) { + if ( Object.prototype.hasOwnProperty.call(open, i ) ) { tmp = OSApp.Stations.getRemainingRuntime( i ); if ( tmp > ptotal ) { ptotal = tmp; diff --git a/www/js/modules/storage.js b/www/js/modules/storage.js index c1494cbe..bfcb2ec0 100644 --- a/www/js/modules/storage.js +++ b/www/js/modules/storage.js @@ -26,7 +26,7 @@ OSApp.Storage.get = function( query, callback ) { } for ( i in query ) { - if ( query.hasOwnProperty( i ) ) { + if ( Object.prototype.hasOwnProperty.call(query, i ) ) { data[ query[ i ] ] = localStorage.getItem( query[ i ] ); } } @@ -39,7 +39,7 @@ OSApp.Storage.set = function( query, callback ) { var i; if ( typeof query === "object" ) { for ( i in query ) { - if ( query.hasOwnProperty( i ) ) { + if ( Object.prototype.hasOwnProperty.call(query, i ) ) { localStorage.setItem( i, query[ i ] ); } } @@ -58,7 +58,7 @@ OSApp.Storage.remove = function( query, callback ) { } for ( i in query ) { - if ( query.hasOwnProperty( i ) ) { + if ( Object.prototype.hasOwnProperty.call(query, i ) ) { localStorage.removeItem( query[ i ] ); } } diff --git a/www/js/modules/ui-dom.js b/www/js/modules/ui-dom.js index 1ae9ddf3..e666c58c 100644 --- a/www/js/modules/ui-dom.js +++ b/www/js/modules/ui-dom.js @@ -509,8 +509,8 @@ OSApp.UIDom.launchApp = function() { name = button.siblings( "[id='station_" + sid + "']" ), showSpecialOptions = function( value ) { var opts = select.find( "#specialOpts" ), - data = OSApp.currentSession.controller.special && OSApp.currentSession.controller.special.hasOwnProperty( sid ) ? OSApp.currentSession.controller.special[ sid ].sd : "", - type = OSApp.currentSession.controller.special && OSApp.currentSession.controller.special.hasOwnProperty( sid ) ? OSApp.currentSession.controller.special[ sid ].st : 0; + data = OSApp.currentSession.controller.special && Object.prototype.hasOwnProperty.call(OSApp.currentSession.controller.special, sid ) ? OSApp.currentSession.controller.special[ sid ].sd : "", + type = OSApp.currentSession.controller.special && Object.prototype.hasOwnProperty.call(OSApp.currentSession.controller.special, sid ) ? OSApp.currentSession.controller.special[ sid ].st : 0; opts.empty(); @@ -532,7 +532,7 @@ OSApp.UIDom.launchApp = function() { opts.append( "
" + OSApp.Language._( "Remote Address" ) + ":
" + - "" + + "" + "
" + OSApp.Language._( "Remote Port" ) + ":
" + "" + "
" + OSApp.Language._( "Remote Station" ) + ":
" + @@ -3188,7 +3188,7 @@ OSApp.UIDom.launchApp = function() { }; for ( group in sortedData ) { - if ( sortedData.hasOwnProperty( group ) ) { + if ( Object.prototype.hasOwnProperty.call(sortedData, group ) ) { ct = sortedData[ group ].length; if ( ct === 0 ) { continue; @@ -5464,7 +5464,7 @@ OSApp.UIDom.updateTimers = function() { } for ( var timer in OSApp.uiState.timers ) { - if ( OSApp.uiState.timers.hasOwnProperty( timer ) ) { + if ( Object.prototype.hasOwnProperty.call(OSApp.uiState.timers, timer ) ) { if ( OSApp.uiState.timers[ timer ].val <= 0 ) { if ( timer === "statusbar" ) { OSApp.UIDom.showLoading( "#footer-running" ); diff --git a/www/js/modules/utils.js b/www/js/modules/utils.js index 04cd2f1b..e1cbb956 100644 --- a/www/js/modules/utils.js +++ b/www/js/modules/utils.js @@ -119,7 +119,7 @@ OSApp.Utils.sortObj = function( obj, type ) { var tempArray = []; for ( var key in obj ) { - if ( obj.hasOwnProperty( key ) ) { + if ( Object.prototype.hasOwnProperty.call(obj, key ) ) { tempArray.push( key ); } } From 55c345d5a1a0ea6bfecea5b2be3db9731165fed7 Mon Sep 17 00:00:00 2001 From: Samer Albahra Date: Tue, 26 Nov 2024 19:01:14 -0500 Subject: [PATCH 02/14] Fix many unit tests --- Gruntfile.js | 16 - package-lock.json | 1503 ++++++++++++++----------------- package.json | 34 +- test/karma.conf.js | 20 + test/tests.html | 102 --- test/tests.js | 86 +- www/js/modules/import-export.js | 2 +- www/js/modules/language.js | 2 +- www/js/modules/network.js | 18 +- www/js/modules/options.js | 2 +- www/js/modules/sites.js | 4 +- www/js/modules/stations.js | 2 +- www/js/modules/storage.js | 14 +- www/js/modules/ui-dom.js | 18 +- 14 files changed, 787 insertions(+), 1036 deletions(-) create mode 100644 test/karma.conf.js delete mode 100644 test/tests.html diff --git a/Gruntfile.js b/Gruntfile.js index 4c40dde6..48212c99 100755 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -17,7 +17,6 @@ module.exports = function( grunt ) { grunt.loadNpmTasks( "grunt-shell" ); grunt.loadNpmTasks( "grunt-contrib-compress" ); grunt.loadNpmTasks( "grunt-contrib-csslint" ); - grunt.loadNpmTasks( "grunt-blanket-mocha" ); grunt.loadNpmTasks( "grunt-eslint" ); var secrets; @@ -51,20 +50,6 @@ module.exports = function( grunt ) { } }, - blanket_mocha: { - test: { - src: [ "test/tests.html" ], - options: { - threshold: 5, - page: { - settings: { - webSecurityEnabled: false - } - } - } - } - }, - compress: { makeFW: { options: { @@ -121,7 +106,6 @@ module.exports = function( grunt ) { // Default task(s). grunt.registerTask( "default", [ "eslint" ] ); - grunt.registerTask( "test", [ "default", "blanket_mocha" ] ); grunt.registerTask( "updateLang", [ "shell:updateLang" ] ); grunt.registerTask( "pushEng", [ "shell:pushEng" ] ); grunt.registerTask( "prepareFW", [ "compress:makeFW", "shell:unzipFW" ] ); diff --git a/package-lock.json b/package-lock.json index ea7da289..b4f38fa8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,11 +10,9 @@ "license": "AGPL-3.0", "devDependencies": { "@eslint/js": "^9.15.0", - "blanket": "^1.2.1", - "chai": "^4.3.7", + "chai": "^4.5.0", "cordova": "^12.0.0", "cordova-android": "^12.0.0", - "cordova-androidx-build": "^1.0.4", "cordova-ios": "^7.0.0", "cordova-osx": "^7.0.0", "cordova-plugin-3dtouch": "^1.3.8", @@ -26,21 +24,31 @@ "eslint": "^9.15.0", "globals": "^15.12.0", "grunt": "^1.6.1", - "grunt-blanket-mocha": "^1.0.0", "grunt-contrib-compress": "^2.0.0", "grunt-contrib-csslint": "^2.0.0", "grunt-eslint": "^25.0.0", - "grunt-lib-phantomjs": "^1.1.0", "grunt-shell": "^4.0.0", "http-server": "^14.1.1", "husky": "^9.1.6", + "karma": "^6.4.4", + "karma-chai": "^0.1.0", + "karma-chrome-launcher": "^3.2.0", + "karma-mocha": "^2.0.1", "lint-staged": "^15.2.10", - "lodash": "^4.17.19", - "mocha": "^10.2.0", + "mocha": "^10.8.2", "po2json": "^0.4.5", "sort-package-json": "^2.10.1" } }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", @@ -116,13 +124,6 @@ "node": "*" } }, - "node_modules/@eslint/config-array/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, "node_modules/@eslint/core": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.9.0.tgz", @@ -221,13 +222,6 @@ "node": "*" } }, - "node_modules/@eslint/eslintrc/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, "node_modules/@eslint/eslintrc/node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -1240,6 +1234,12 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "dev": true + }, "node_modules/@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", @@ -1295,6 +1295,21 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", + "dev": true + }, + "node_modules/@types/cors": { + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", @@ -1309,6 +1324,15 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "dependencies": { + "undici-types": "~6.20.0" + } + }, "node_modules/@xmldom/xmldom": { "version": "0.8.8", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.8.tgz", @@ -1370,18 +1394,6 @@ "node": ">= 0.6" } }, - "node_modules/acorn": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-1.2.2.tgz", - "integrity": "sha1-yM4n3grMdtiW0rH6099YjZ6C8BQ=", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/adm-zip": { "version": "0.5.10", "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz", @@ -1575,9 +1587,9 @@ "dev": true }, "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true, "engines": { "node": ">=6" @@ -1869,6 +1881,15 @@ } ] }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "dev": true, + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, "node_modules/basic-auth": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", @@ -1950,23 +1971,6 @@ "node": ">=8" } }, - "node_modules/blanket": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/blanket/-/blanket-1.2.3.tgz", - "integrity": "sha1-FRtJh8O9hFUrtfA7kO9fflkx5HM=", - "dev": true, - "dependencies": { - "acorn": "^1.0.3", - "falafel": "~1.2.0", - "foreach": "^2.0.5", - "isarray": "0.0.1", - "object-keys": "^1.0.6", - "xtend": "~4.0.0" - }, - "engines": { - "node": ">=0.10.7" - } - }, "node_modules/body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", @@ -2098,12 +2102,6 @@ "node": "*" } }, - "node_modules/buffer-from": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", - "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", - "dev": true - }, "node_modules/builtins": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", @@ -2269,18 +2267,18 @@ } }, "node_modules/chai": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", - "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", "dev": true, "dependencies": { "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^4.1.2", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", "pathval": "^1.1.1", - "type-detect": "^4.0.5" + "type-detect": "^4.1.0" }, "engines": { "node": ">=4" @@ -2318,10 +2316,13 @@ "dev": true }, "node_modules/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, "engines": { "node": "*" } @@ -2660,57 +2661,6 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/concat-stream/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "node_modules/concat-stream/node_modules/process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true - }, - "node_modules/concat-stream/node_modules/readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/concat-stream/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, "node_modules/conf": { "version": "10.2.0", "resolved": "https://registry.npmjs.org/conf/-/conf-10.2.0.tgz", @@ -2816,6 +2766,60 @@ "node": ">=8" } }, + "node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/connect/node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/connect/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/connect/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", @@ -3088,12 +3092,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/cordova-androidx-build": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cordova-androidx-build/-/cordova-androidx-build-1.0.4.tgz", - "integrity": "sha512-ZC+NHOA4WPI8qV+YyvBba/XokF169tpc9X08fbov6zNXwczeA0w+9lqq+E5Nyp+hX4OX/r8p3q1MSPPYLDa8tA==", - "dev": true - }, "node_modules/cordova-app-hello-world": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cordova-app-hello-world/-/cordova-app-hello-world-6.0.0.tgz", @@ -4219,6 +4217,19 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/corser": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", @@ -4385,6 +4396,12 @@ "node": ">=0.10.0" } }, + "node_modules/custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", + "dev": true + }, "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -4406,6 +4423,15 @@ "node": ">=0.8" } }, + "node_modules/date-format": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", + "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, "node_modules/dateformat": { "version": "4.6.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", @@ -4582,10 +4608,16 @@ "node": ">=8" } }, + "node_modules/di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", + "dev": true + }, "node_modules/diff": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", - "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true, "engines": { "node": ">=0.3.1" @@ -4603,6 +4635,18 @@ "node": ">=8" } }, + "node_modules/dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", + "dev": true, + "dependencies": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, "node_modules/dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -4711,6 +4755,74 @@ "objectorarray": "^1.0.4" } }, + "node_modules/engine.io": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.2.tgz", + "integrity": "sha512-gmNvsYi9C8iErnZdVcJnvCpSKbWTt1E8+JZo8b+daLninywUWi5NQ5STSHZ9rFjFO7imNcvb8Pc5pe/wMR5xEw==", + "dev": true, + "dependencies": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.7.2", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io/node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/engine.io/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/ent": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.1.tgz", + "integrity": "sha512-QHuXVeZx9d+tIQAz/XztU0ZwZf2Agg9CcXcgE1rurqvdBeDBrpSwjl8/6XUqMg7tw2Y7uAdKb2sRv+bSEFqQ5A==", + "dev": true, + "dependencies": { + "punycode": "^1.4.1" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", @@ -4762,12 +4874,6 @@ "node": ">= 0.4" } }, - "node_modules/es6-promise": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", - "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==", - "dev": true - }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -5025,13 +5131,6 @@ "node": "*" } }, - "node_modules/eslint/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, "node_modules/eslint/node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -5394,40 +5493,6 @@ "node": ">=0.6.0" } }, - "node_modules/extract-zip": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz", - "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=", - "dev": true, - "dependencies": { - "concat-stream": "1.6.2", - "debug": "2.6.9", - "mkdirp": "0.5.1", - "yauzl": "2.4.1" - }, - "bin": { - "extract-zip": "cli.js" - } - }, - "node_modules/extract-zip/node_modules/minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "node_modules/extract-zip/node_modules/mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", - "dev": true, - "dependencies": { - "minimist": "0.0.8" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, "node_modules/extsprintf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", @@ -5437,21 +5502,6 @@ "node >=0.6.0" ] }, - "node_modules/falafel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/falafel/-/falafel-1.2.0.tgz", - "integrity": "sha1-wY0k71CRF0pJfzGM0ksCaiXN2rQ=", - "dev": true, - "dependencies": { - "acorn": "^1.0.3", - "foreach": "^2.0.5", - "isarray": "0.0.1", - "object-keys": "^1.0.6" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -5503,15 +5553,6 @@ "reusify": "^1.0.4" } }, - "node_modules/fd-slicer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", - "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", - "dev": true, - "dependencies": { - "pend": "~1.2.0" - } - }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -5684,12 +5725,6 @@ "node": ">=0.10.0" } }, - "node_modules/foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true - }, "node_modules/foreground-child": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", @@ -5742,17 +5777,6 @@ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", "dev": true }, - "node_modules/fs-extra": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", - "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0" - } - }, "node_modules/fs-minipass": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.2.tgz", @@ -5818,9 +5842,9 @@ } }, "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, "engines": { "node": "*" @@ -6043,12 +6067,6 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, - "node_modules/growl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", - "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", - "dev": true - }, "node_modules/grunt": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.6.1.tgz", @@ -6076,158 +6094,6 @@ "node": ">=16" } }, - "node_modules/grunt-blanket-mocha": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/grunt-blanket-mocha/-/grunt-blanket-mocha-1.0.0.tgz", - "integrity": "sha1-wfJFaktS2mhhuKsFabg6dhVztUI=", - "dev": true, - "dependencies": { - "blanket": "~1.1.6", - "grunt": ">=0.4.0", - "grunt-lib-phantomjs": "^1.0.2", - "lodash": "^3.9.0", - "mocha": "^2.4.5" - }, - "engines": { - "node": ">= 0.8.0" - }, - "peerDependencies": { - "grunt": ">=0.4.0" - } - }, - "node_modules/grunt-blanket-mocha/node_modules/blanket": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/blanket/-/blanket-1.1.10.tgz", - "integrity": "sha1-m+r8WbZmvUetlOxkCCvxl++Ms0I=", - "dev": true, - "dependencies": { - "acorn": "^1.0.3", - "falafel": "~1.2.0", - "foreach": "^2.0.5", - "isarray": "0.0.1", - "object-keys": "^1.0.6", - "xtend": "~4.0.0" - }, - "engines": { - "node": ">=0.10.7" - } - }, - "node_modules/grunt-blanket-mocha/node_modules/commander": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz", - "integrity": "sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM=", - "dev": true, - "engines": { - "node": ">= 0.6.x" - } - }, - "node_modules/grunt-blanket-mocha/node_modules/debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "dev": true, - "dependencies": { - "ms": "0.7.1" - } - }, - "node_modules/grunt-blanket-mocha/node_modules/escape-string-regexp": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz", - "integrity": "sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/grunt-blanket-mocha/node_modules/glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", - "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", - "dev": true, - "dependencies": { - "inherits": "2", - "minimatch": "0.3" - }, - "engines": { - "node": "*" - } - }, - "node_modules/grunt-blanket-mocha/node_modules/lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true - }, - "node_modules/grunt-blanket-mocha/node_modules/minimatch": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", - "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", - "deprecated": "Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue", - "dev": true, - "dependencies": { - "lru-cache": "2", - "sigmund": "~1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/grunt-blanket-mocha/node_modules/minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "node_modules/grunt-blanket-mocha/node_modules/mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", - "dev": true, - "dependencies": { - "minimist": "0.0.8" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/grunt-blanket-mocha/node_modules/mocha": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-2.5.3.tgz", - "integrity": "sha1-FhvlvetJZ3HrmzV0UFC2IrWu/Fg=", - "dev": true, - "dependencies": { - "commander": "2.3.0", - "debug": "2.2.0", - "diff": "1.4.0", - "escape-string-regexp": "1.0.2", - "glob": "3.2.11", - "growl": "1.9.2", - "jade": "0.26.3", - "mkdirp": "0.5.1", - "supports-color": "1.2.0", - "to-iso-string": "0.0.2" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" - }, - "engines": { - "node": ">= 0.8.x" - } - }, - "node_modules/grunt-blanket-mocha/node_modules/supports-color": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.0.tgz", - "integrity": "sha1-/x7R5hFp0Gs88tWI4YixjYhH4X4=", - "dev": true, - "bin": { - "supports-color": "cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/grunt-cli": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.4.3.tgz", @@ -6613,34 +6479,6 @@ "node": ">= 8" } }, - "node_modules/grunt-lib-phantomjs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/grunt-lib-phantomjs/-/grunt-lib-phantomjs-1.1.0.tgz", - "integrity": "sha1-np7c3Z/S3UDgwYHJQ3HVcqpe6tI=", - "dev": true, - "dependencies": { - "eventemitter2": "^0.4.9", - "phantomjs-prebuilt": "^2.1.3", - "rimraf": "^2.5.2", - "semver": "^5.1.0", - "temporary": "^0.0.8" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/grunt-lib-phantomjs/node_modules/rimraf": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", - "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", - "dev": true, - "dependencies": { - "glob": "^7.0.5" - }, - "bin": { - "rimraf": "bin.js" - } - }, "node_modules/grunt-shell": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/grunt-shell/-/grunt-shell-4.0.0.tgz", @@ -6903,19 +6741,6 @@ "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "dev": true }, - "node_modules/hasha": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz", - "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=", - "dev": true, - "dependencies": { - "is-stream": "^1.0.1", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -7238,12 +7063,6 @@ "ms": "^2.0.0" } }, - "node_modules/humanize-ms/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, "node_modules/husky": { "version": "9.1.6", "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.6.tgz", @@ -7947,15 +7766,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -8007,11 +7817,17 @@ "node": ">=8" } }, - "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true + "node_modules/isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true, + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } }, "node_modules/isexe": { "version": "2.0.0", @@ -8052,39 +7868,6 @@ "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/jade": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", - "integrity": "sha1-jxDXl32NefL2/4YqgbBRPMslaGw=", - "deprecated": "Jade has been renamed to pug, please install the latest version of pug instead of jade", - "dev": true, - "dependencies": { - "commander": "0.6.1", - "mkdirp": "0.3.0" - }, - "bin": { - "jade": "bin/jade" - } - }, - "node_modules/jade/node_modules/commander": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz", - "integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=", - "dev": true, - "engines": { - "node": ">= 0.4.x" - } - }, - "node_modules/jade/node_modules/mkdirp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", - "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=", - "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/js-yaml": { "version": "3.14.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", @@ -8174,15 +7957,6 @@ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "dev": true }, - "node_modules/jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, "node_modules/jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", @@ -8228,11 +8002,71 @@ "integrity": "sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw==", "dev": true }, - "node_modules/kew": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", - "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=", - "dev": true + "node_modules/karma": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.4.tgz", + "integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==", + "dev": true, + "dependencies": { + "@colors/colors": "1.5.0", + "body-parser": "^1.19.0", + "braces": "^3.0.2", + "chokidar": "^3.5.1", + "connect": "^3.7.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.1", + "glob": "^7.1.7", + "graceful-fs": "^4.2.6", + "http-proxy": "^1.18.1", + "isbinaryfile": "^4.0.8", + "lodash": "^4.17.21", + "log4js": "^6.4.1", + "mime": "^2.5.2", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.5", + "qjobs": "^1.2.0", + "range-parser": "^1.2.1", + "rimraf": "^3.0.2", + "socket.io": "^4.7.2", + "source-map": "^0.6.1", + "tmp": "^0.2.1", + "ua-parser-js": "^0.7.30", + "yargs": "^16.1.1" + }, + "bin": { + "karma": "bin/karma" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/karma-chai": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/karma-chai/-/karma-chai-0.1.0.tgz", + "integrity": "sha512-mqKCkHwzPMhgTYca10S90aCEX9+HjVjjrBFAsw36Zj7BlQNbokXXCAe6Ji04VUMsxcY5RLP7YphpfO06XOubdg==", + "dev": true, + "peerDependencies": { + "chai": "*", + "karma": ">=0.10.9" + } + }, + "node_modules/karma-chrome-launcher": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz", + "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==", + "dev": true, + "dependencies": { + "which": "^1.2.1" + } + }, + "node_modules/karma-mocha": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-2.0.1.tgz", + "integrity": "sha512-Tzd5HBjm8his2OA4bouAsATYEpZrp9vC7z5E5j4C5Of5Rrs1jY67RAwXNcVmd/Bnk1wgvQRou0zGVLey44G4tQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.3" + } }, "node_modules/keyv": { "version": "4.5.4", @@ -8253,15 +8087,6 @@ "node": ">=0.10.0" } }, - "node_modules/klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.9" - } - }, "node_modules/lazystream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", @@ -8509,13 +8334,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lint-staged/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, "node_modules/lint-staged/node_modules/npm-run-path": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", @@ -9087,6 +8905,39 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/log4js": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", + "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", + "dev": true, + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.5" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/log4js/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/loud-rejection": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-2.2.0.tgz", @@ -9109,12 +8960,6 @@ "get-func-name": "^2.0.0" } }, - "node_modules/lru-cache": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", - "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", - "dev": true - }, "node_modules/macos-release": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.5.1.tgz", @@ -9272,6 +9117,18 @@ "node": ">=8.6" } }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/mime-db": { "version": "1.40.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", @@ -9508,32 +9365,31 @@ } }, "node_modules/mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", - "dev": true, - "dependencies": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "nanoid": "3.3.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", + "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" }, "bin": { "_mocha": "bin/_mocha", @@ -9541,10 +9397,6 @@ }, "engines": { "node": ">= 14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" } }, "node_modules/mocha/node_modules/argparse": { @@ -9553,13 +9405,22 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/mocha/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -9570,21 +9431,6 @@ } } }, - "node_modules/mocha/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/mocha/node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/mocha/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -9598,37 +9444,25 @@ } }, "node_modules/mocha/node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "minimatch": "^5.0.1", + "once": "^1.3.0" }, "engines": { - "node": "*" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/mocha/node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/mocha/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -9651,9 +9485,9 @@ } }, "node_modules/mocha/node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -9662,21 +9496,6 @@ "node": ">=10" } }, - "node_modules/mocha/node_modules/minimatch/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, "node_modules/mocha/node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -9705,9 +9524,9 @@ } }, "node_modules/ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "node_modules/mute-stream": { @@ -9716,18 +9535,6 @@ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, - "node_modules/nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -9859,21 +9666,6 @@ "node": ">= 6" } }, - "node_modules/node-gyp/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/node-gyp/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -10252,6 +10044,15 @@ "node": ">=4" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", @@ -10265,15 +10066,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object-keys": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", - "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/object.defaults": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", @@ -10531,15 +10323,6 @@ "node": ">=6" } }, - "node_modules/package": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package/-/package-1.0.1.tgz", - "integrity": "sha1-0lofmeJQbcsn1nBLg9yooxLk7cw=", - "dev": true, - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/pacote": { "version": "15.2.0", "resolved": "https://registry.npmjs.org/pacote/-/pacote-15.2.0.tgz", @@ -10736,40 +10519,12 @@ "node": ">=8" } }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "dev": true - }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, - "node_modules/phantomjs-prebuilt": { - "version": "2.1.16", - "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz", - "integrity": "sha1-79ISpKOWbTZHaE6ouniFSb4q7+8=", - "deprecated": "this package is now deprecated", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "es6-promise": "^4.0.3", - "extract-zip": "^1.6.5", - "fs-extra": "^1.0.0", - "hasha": "^2.2.0", - "kew": "^0.7.0", - "progress": "^1.1.8", - "request": "^2.81.0", - "request-progress": "^2.0.1", - "which": "^1.2.10" - }, - "bin": { - "phantomjs": "bin/phantomjs" - } - }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -10804,27 +10559,6 @@ "node": ">=6" } }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "dependencies": { - "pinkie": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/pkg-up": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", @@ -10957,13 +10691,6 @@ "ms": "^2.1.1" } }, - "node_modules/portfinder/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, "node_modules/postcss-selector-parser": { "version": "6.0.13", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", @@ -11023,15 +10750,6 @@ "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", "dev": true }, - "node_modules/progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/promise-all-reject-late": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz", @@ -11149,6 +10867,15 @@ "teleport": ">=0.2.0" } }, + "node_modules/qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true, + "engines": { + "node": ">=0.9" + } + }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", @@ -11400,15 +11127,6 @@ "node": ">= 4" } }, - "node_modules/request-progress": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz", - "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=", - "dev": true, - "dependencies": { - "throttleit": "^1.0.0" - } - }, "node_modules/request/node_modules/assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", @@ -11673,6 +11391,22 @@ "dev": true, "license": "MIT" }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", @@ -11744,15 +11478,6 @@ "dev": true, "license": "MIT" }, - "node_modules/semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, "node_modules/send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -11789,16 +11514,10 @@ "node": ">=4" } }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "dependencies": { "randombytes": "^2.1.0" @@ -11889,12 +11608,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", - "dev": true - }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -12031,6 +11744,98 @@ "npm": ">= 3.0.0" } }, + "node_modules/socket.io": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", + "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.3.2", + "engine.io": "~6.6.0", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", + "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", + "dev": true, + "dependencies": { + "debug": "~4.3.4", + "ws": "~8.17.1" + } + }, + "node_modules/socket.io-adapter/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "dev": true, + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/socks": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", @@ -12191,6 +11996,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -12301,6 +12115,69 @@ "node": ">= 0.10.0" } }, + "node_modules/streamroller": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", + "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", + "dev": true, + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/streamroller/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/streamroller/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/streamroller/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/streamroller/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/string-argv": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", @@ -12634,24 +12511,6 @@ "node": ">=10" } }, - "node_modules/temporary": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/temporary/-/temporary-0.0.8.tgz", - "integrity": "sha1-oYqYHSi6jKNgJ/s8MFOMPst0CsA=", - "dev": true, - "dependencies": { - "package": ">= 1.0.0 < 1.2.0" - }, - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/throttleit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", - "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=", - "dev": true - }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -12670,28 +12529,6 @@ "node": ">=8.17.0" } }, - "node_modules/tmp/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/to-iso-string": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/to-iso-string/-/to-iso-string-0.0.2.tgz", - "integrity": "sha1-TcGeZk38y+Jb2NtQiwDG2hWCVdE=", - "deprecated": "to-iso-string has been deprecated, use @segment/to-iso-string instead.", - "dev": true - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -12800,9 +12637,9 @@ } }, "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", "dev": true, "engines": { "node": ">=4" @@ -12842,12 +12679,6 @@ "node": ">= 0.6" } }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", @@ -12857,6 +12688,32 @@ "is-typedarray": "^1.0.0" } }, + "node_modules/ua-parser-js": { + "version": "0.7.39", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.39.tgz", + "integrity": "sha512-IZ6acm6RhQHNibSt7+c09hhvsKy9WUr4DVbeq9U8o71qxyYtJpQeDxQnMrVqnIFMLcQjHO0I9wgfO2vIahht4w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "bin": { + "ua-parser-js": "script/cli.js" + }, + "engines": { + "node": "*" + } + }, "node_modules/unc-path-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", @@ -12891,6 +12748,12 @@ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", "dev": true }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true + }, "node_modules/union": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", @@ -13102,6 +12965,15 @@ "extsprintf": "1.0.2" } }, + "node_modules/void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/walk-up-path": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-3.0.1.tgz", @@ -13276,9 +13148,9 @@ } }, "node_modules/workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", "dev": true }, "node_modules/wrap-ansi": { @@ -13442,6 +13314,27 @@ "typedarray-to-buffer": "^3.1.5" } }, + "node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/xcode": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/xcode/-/xcode-3.0.1.tgz", @@ -13479,15 +13372,6 @@ "integrity": "sha512-B/T4sDK8Z6aUh/qNr7mjKAwwncIljFuUP+DO/D5hloYFj+90O88z8Wf7oSucZTHxBAsC1/CTP4rtx/x1Uf72Mg==", "dev": true }, - "node_modules/xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -13535,9 +13419,9 @@ } }, "node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, "engines": { "node": ">=10" @@ -13558,15 +13442,6 @@ "node": ">=10" } }, - "node_modules/yauzl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", - "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", - "dev": true, - "dependencies": { - "fd-slicer": "~1.0.1" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 44a8aa21..68017b0a 100644 --- a/package.json +++ b/package.json @@ -30,11 +30,9 @@ }, "devDependencies": { "@eslint/js": "^9.15.0", - "blanket": "^1.2.1", - "chai": "^4.3.7", + "chai": "^4.5.0", "cordova": "^12.0.0", "cordova-android": "^12.0.0", - "cordova-androidx-build": "^1.0.4", "cordova-ios": "^7.0.0", "cordova-osx": "^7.0.0", "cordova-plugin-3dtouch": "^1.3.8", @@ -46,17 +44,18 @@ "eslint": "^9.15.0", "globals": "^15.12.0", "grunt": "^1.6.1", - "grunt-blanket-mocha": "^1.0.0", "grunt-contrib-compress": "^2.0.0", "grunt-contrib-csslint": "^2.0.0", "grunt-eslint": "^25.0.0", - "grunt-lib-phantomjs": "^1.1.0", "grunt-shell": "^4.0.0", "http-server": "^14.1.1", "husky": "^9.1.6", + "karma": "^6.4.4", + "karma-chai": "^0.1.0", + "karma-chrome-launcher": "^3.2.0", + "karma-mocha": "^2.0.1", "lint-staged": "^15.2.10", - "lodash": "^4.17.19", - "mocha": "^10.2.0", + "mocha": "^10.8.2", "po2json": "^0.4.5", "sort-package-json": "^2.10.1" }, @@ -67,30 +66,11 @@ "cordova-plugin-networkinterface": {}, "cordova-plugin-statusbar": {}, "cordova-plugin-transport-security": {}, - "cordova-plugin-inappbrowser": {}, - "cordova-androidx-build": {} + "cordova-plugin-inappbrowser": {} }, "platforms": [ "android", "ios" ] - }, - "no-edit-menu": true, - "phonegap": { - "id": "1371093" - }, - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36", - "webkit": { - "page-cache": true - }, - "window": { - "toolbar": false, - "width": 942, - "height": 512, - "title": "OpenSprinkler", - "icon": "res/ios-web/icons/icon.png", - "resizable": true, - "fullscreen": false, - "position": "center" } } diff --git a/test/karma.conf.js b/test/karma.conf.js new file mode 100644 index 00000000..3eb8ffe6 --- /dev/null +++ b/test/karma.conf.js @@ -0,0 +1,20 @@ +module.exports = function (config) { + config.set({ + frameworks: ['mocha', 'chai'], + files: [ + { pattern: '../www/css/jqm.css', included: true, watched: false }, + { pattern: '../www/css/main.css', included: true, watched: false }, + { pattern: '../node_modules/mocha/mocha.css', included: true, watched: false }, + { pattern: '../www/vendor-js/jquery.js', included: true, watched: false }, + { pattern: '../www/vendor-js/libs.js', included: true, watched: false }, + { pattern: '../www/vendor-js/apexcharts.min.js', included: true, watched: false }, + { pattern: '../www/vendor-js/jqm.js', included: true, watched: false }, + { pattern: '../www/vendor-js/dataTables-2.1.8.min.js.js', included: true, watched: false }, + { pattern: '../www/js/modules/*.js', included: true, watched: false }, + { pattern: '../www/js/main.js', included: true, watched: false }, + 'tests.js' + ], + browsers: ['ChromeHeadless'], + singleRun: true + }); +}; diff --git a/test/tests.html b/test/tests.html deleted file mode 100644 index 5c1d291e..00000000 --- a/test/tests.html +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - OpenSprinkler - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - diff --git a/test/tests.js b/test/tests.js index 1266fdaa..432786a3 100644 --- a/test/tests.js +++ b/test/tests.js @@ -18,26 +18,24 @@ var assert = chai.assert; describe( "Initial Definition Check", function() { it( "storage.set(object,callback) should accept an object of key/value pairs to be set into localStorage and respond with callback", function( done ) { assert.doesNotThrow( function() { - storage.set( { + OSApp.Storage.set( { "testkey": "helloworld", "sites": JSON.stringify( { "Test": { - "os_ip": "127.0.0.1:8080", + "os_ip": "demo.opensprinkler.com", "os_pw":"opendoor" } } ), "current_site": "Test" }, function( result ) { - if ( result === true ) { - done(); - } + result === true ? done() : done( new Error( "Failed to set key/value pairs", result.Error ) ); } ); } ); } ); it( "storage.get(object,callback) should accept an array of keys to be retrieved from localStorage and respond with callback", function( done ) { assert.doesNotThrow( function() { - storage.get( [ "testkey" ], function( result ) { + OSApp.Storage.get( [ "testkey" ], function( result ) { if ( result.testkey === "helloworld" ) { done(); } @@ -47,7 +45,7 @@ describe( "Initial Definition Check", function() { it( "storage.remove(object,callback) should accept an array of keys to be deleted from localStorage and respond with callback", function( done ) { assert.doesNotThrow( function() { - storage.remove( [ "testkey" ], function( result ) { + OSApp.Storage.remove( [ "testkey" ], function( result ) { if ( result === true ) { done(); } @@ -57,7 +55,7 @@ describe( "Initial Definition Check", function() { it( "storage.remove(string,callback) should accept a key to be deleted from localStorage and respond with callback", function( done ) { assert.doesNotThrow( function() { - storage.remove( "fakekey", function( result ) { + OSApp.Storage.remove( "fakekey", function( result ) { if ( result === true ) { done(); } @@ -70,68 +68,68 @@ describe( "OpenSprinkler Firmware Version Functions", function() { describe( "Test against Arduino Firmware Version", function() { before( function() { - controller.options = { + OSApp.currentSession.controller.options = { fwv: 210 }; } ); it( "isOPSi() should identify if the device is an OSPi", function() { - assert.equal( false, isOSPi() ); // TODO mellodev tests need to be updated to use new OSApp.XXX namespace + assert.equal( false, OSApp.Firmware.isOSPi() ); } ); it( "versionCompare(device,compare) should check the given firmware (device) against the compare firmware where the input is an array", function() { - assert.strictEqual( false, versionCompare( [ 1 ], [ 1, 5 ] ) ); - assert.strictEqual( 0, versionCompare( [ 1, 5 ], [ 1, 5 ] ) ); - assert.strictEqual( 1, versionCompare( [ 2, 1 ], [ 1, 5 ] ) ); + assert.strictEqual( false, OSApp.Firmware.versionCompare( [ 1 ], [ 1, 5 ] ) ); + assert.strictEqual( 0, OSApp.Firmware.versionCompare( [ 1, 5 ], [ 1, 5 ] ) ); + assert.strictEqual( 1, OSApp.Firmware.versionCompare( [ 2, 1 ], [ 1, 5 ] ) ); } ); it( "checkOSVersion(compare) should compare the input firmware version against the Arduino firmware version.", function() { - assert.strictEqual( false, checkOSVersion( 211 ) ); - assert.strictEqual( true, checkOSVersion( 210 ) ); - assert.strictEqual( 1, checkOSVersion( 208 ) ); + assert.strictEqual( false, OSApp.Firmware.checkOSVersion( 211 ) ); + assert.strictEqual( true, OSApp.Firmware.checkOSVersion( 210 ) ); + assert.strictEqual( 1, OSApp.Firmware.checkOSVersion( 208 ) ); } ); it( "checkOSPiVersion(compare) should compare the input firmware version against the OSPi firmware version.", function() { - assert.strictEqual( false, checkOSPiVersion( "2.0" ) ); - assert.strictEqual( false, checkOSPiVersion( "1.9" ) ); - assert.strictEqual( false, checkOSPiVersion( "2.1" ) ); + assert.strictEqual( false, OSApp.Firmware.checkOSPiVersion( "2.0" ) ); + assert.strictEqual( false, OSApp.Firmware.checkOSPiVersion( "1.9" ) ); + assert.strictEqual( false, OSApp.Firmware.checkOSPiVersion( "2.1" ) ); } ); } ); describe( "Test against OSPi Firmware Version", function() { before( function() { - controller.options = { + OSApp.currentSession.controller.options = { fwv: "1.9.0-OSPi" }; } ); it( "isOPSi() should identify if the device is an OSPi", function() { - assert.equal( true, isOSPi() ); + assert.equal( true, OSApp.Firmware.isOSPi() ); } ); it( "versionCompare(device,compare) should check the given firmware (device) against the compare firmware where the input is an array", function() { - assert.strictEqual( false, versionCompare( [ 1 ], [ 1, 5 ] ) ); - assert.strictEqual( 0, versionCompare( [ 1, 5 ], [ 1, 5 ] ) ); - assert.strictEqual( 1, versionCompare( [ 2, 1 ], [ 1, 5 ] ) ); + assert.strictEqual( false, OSApp.Firmware.versionCompare( [ 1 ], [ 1, 5 ] ) ); + assert.strictEqual( 0, OSApp.Firmware.versionCompare( [ 1, 5 ], [ 1, 5 ] ) ); + assert.strictEqual( 1, OSApp.Firmware.versionCompare( [ 2, 1 ], [ 1, 5 ] ) ); } ); it( "checkOSVersion(compare) should compare the input firmware version against the Arduino firmware version.", function() { - assert.strictEqual( false, checkOSVersion( 211 ) ); - assert.strictEqual( false, checkOSVersion( 210 ) ); - assert.strictEqual( false, checkOSVersion( 208 ) ); + assert.strictEqual( false, OSApp.Firmware.checkOSVersion( 211 ) ); + assert.strictEqual( false, OSApp.Firmware.checkOSVersion( 210 ) ); + assert.strictEqual( false, OSApp.Firmware.checkOSVersion( 208 ) ); } ); it( "checkOSPiVersion(compare) should compare the input firmware version against the OSPi firmware version.", function() { - assert.strictEqual( 1, checkOSPiVersion( "1.8" ) ); - assert.strictEqual( true, checkOSPiVersion( "1.9.0" ) ); - assert.strictEqual( false, checkOSPiVersion( "2.0" ) ); - assert.strictEqual( false, checkOSPiVersion( "2.1" ) ); + assert.strictEqual( 1, OSApp.Firmware.checkOSPiVersion( "1.8" ) ); + assert.strictEqual( true, OSApp.Firmware.checkOSPiVersion( "1.9.0" ) ); + assert.strictEqual( false, OSApp.Firmware.checkOSPiVersion( "2.0" ) ); + assert.strictEqual( false, OSApp.Firmware.checkOSPiVersion( "2.1" ) ); } ); } ); describe( "Retrieve the formatted firmware version", function() { before( function() { - controller.options = { + OSApp.currentSession.controller.options = { fwv: 204 }; } ); it( "getOSVersion(fwv) should return the firmware in a string representation", function() { - assert.equal( "1.8.3-OSPi", getOSVersion( "1.8.3-OSPi" ) ); - assert.equal( "2.1.193-OSPi", getOSVersion( "2.1.193-OSPi" ) ); - assert.equal( "2.0.8", getOSVersion( 208 ) ); - assert.equal( "2.0.4", getOSVersion() ); + assert.equal( "1.8.3-OSPi", OSApp.Firmware.getOSVersion( "1.8.3-OSPi" ) ); + assert.equal( "2.1.193-OSPi", OSApp.Firmware.getOSVersion( "2.1.193-OSPi" ) ); + assert.equal( "2.0.8", OSApp.Firmware.getOSVersion( 208 ) ); + assert.equal( "2.0.4", OSApp.Firmware.getOSVersion() ); } ); } ); } ); @@ -190,10 +188,10 @@ describe( "General Function Checks", function() { describe( "Page Navigation Checks", function() { it( "Start jQuery Mobile Page Initialization", function( done ) { - currIp = "127.0.0.1:8080"; - currPass = "opendoor"; - currPrefix = "http://"; - curr183 = false; + OSApp.currentSession.currIp = "demo.opensprinkler.com"; + OSApp.currentSession.currPass = "opendoor"; + OSApp.currentSession.currPrefix = "http://"; + OSApp.currentSession.curr183 = false; OSApp.Sites.updateSiteList( [ "Test" ], "Test" ); @@ -297,7 +295,7 @@ describe( "Popup Checks", function() { $( "#durationBox" ).popup( "close" ).remove(); } ); assert.doesNotThrow( function() { - $( "#mainMenu" ).find( "a[href='#raindelay']" ).click(); + $( "#mainMenu" ).find( "a[href='#raindelay']" ).trigger( "click" ); } ); } ); @@ -327,7 +325,7 @@ describe( "Popup Checks", function() { it( "Show are you sure popup", function( done ) { $.mobile.document.one( "popupafteropen", "#sure", function() { - $( "#sure .sure-do" ).click(); + $( "#sure .sure-do" ).trigger( "click" ); } ); assert.doesNotThrow( function() { OSApp.UIDom.areYouSure( null, null, done ); @@ -373,7 +371,7 @@ describe( "Popup Checks", function() { describe( "Logout / Clean up", function() { it( "Remove all variables", function( done ) { - storage.remove( [ "sites", "current_site", "lang", "runonce" ], function() { + OSApp.Storage.remove( [ "sites", "current_site", "lang", "runonce" ], function() { done(); } ); } ); @@ -382,7 +380,7 @@ describe( "Logout / Clean up", function() { $.mobile.document.one( "pageshow", "#start", function() { done(); } ); - currIp = ""; + OSApp.currentSession.currIp = ""; OSApp.UIDom.changePage( "#start" ); } ); } ); diff --git a/www/js/modules/import-export.js b/www/js/modules/import-export.js index 4ff0c419..2bc96cc2 100644 --- a/www/js/modules/import-export.js +++ b/www/js/modules/import-export.js @@ -48,7 +48,7 @@ OSApp.ImportExport.getExportMethod = function() { popup.find( ".localMethod" ).on( "click", function() { popup.popup( "close" ); - OSApp.Storage.set( { "backup":JSON.stringify( OSApp.currentSession.controller ) }, function() { + OSApp.Storage.set( { "backup": JSON.stringify( OSApp.currentSession.controller ) }, function() { OSApp.Errors.showError( OSApp.Language._( "Backup saved on this device" ) ); } ); } ); diff --git a/www/js/modules/language.js b/www/js/modules/language.js index 9a412488..5d1ed0af 100644 --- a/www/js/modules/language.js +++ b/www/js/modules/language.js @@ -70,7 +70,7 @@ OSApp.Language.updateLang = function( lang ) { return; } - OSApp.Storage.set( { "lang":lang } ); + OSApp.Storage.set( { "lang": lang } ); OSApp.currentSession.lang = lang; if ( lang === "en" ) { diff --git a/www/js/modules/network.js b/www/js/modules/network.js index fdb3af1d..2b8dbbdf 100644 --- a/www/js/modules/network.js +++ b/www/js/modules/network.js @@ -327,7 +327,7 @@ OSApp.Network.checkPublicAccess = function( eip ) { // sites[ current ].os_ip = ip + ( port === 80 ? "" : ":" + port ); - // OSApp.Storage.set( { "sites":JSON.stringify( sites ) }, OSApp.Network.cloudSaveSites ); + // OSApp.Storage.set( { "sites":JSON.stringify( sites ) }, () => OSApp.Network.cloudSaveSites() ); // } ); }, fail @@ -553,16 +553,16 @@ OSApp.Network.cloudSyncStart = function() { OSApp.Language._( "This site is not found in the currently synced site list but may be added now." ), function() { sites[ OSApp.currentSession.ip ] = data.sites.Local; - OSApp.Storage.set( { "sites": JSON.stringify( sites ) }, OSApp.Network.cloudSaveSites ); + OSApp.Storage.set( { "sites": JSON.stringify( sites ) }, () => OSApp.Network.cloudSaveSites() ); OSApp.Storage.set( { "current_site": OSApp.currentSession.ip } ); OSApp.Sites.updateSiteList( Object.keys( sites ), OSApp.currentSession.ip ); }, function() { - OSApp.Storage.remove( "cloudToken", OSApp.UIDom.updateLoginButtons ); + OSApp.Storage.remove( "cloudToken", () => OSApp.UIDom.updateLoginButtons() ); } ); } else { - OSApp.Storage.set( { "sites": JSON.stringify( sites ) }, OSApp.Network.cloudSaveSites ); + OSApp.Storage.set( { "sites": JSON.stringify( sites ) }, () => OSApp.Network.cloudSaveSites() ); OSApp.Storage.set( { "current_site": result } ); OSApp.Sites.updateSiteList( Object.keys( sites ), result ); } @@ -584,7 +584,7 @@ OSApp.Network.cloudSyncStart = function() { "" + "" ), finish = function() { - OSApp.Storage.set( { "sites":JSON.stringify( sites ) }, OSApp.Network.cloudSaveSites ); + OSApp.Storage.set( { "sites":JSON.stringify( sites ) }, () => OSApp.Network.cloudSaveSites() ); popup.popup( "close" ); if ( page === "site-control" ) { @@ -646,7 +646,7 @@ OSApp.Network.getTokenUser = function( token ) { }; OSApp.Network.handleExpiredLogin = function() { - OSApp.Storage.remove( [ "cloudToken" ], OSApp.UIDom.updateLoginButtons ); + OSApp.Storage.remove( [ "cloudToken" ], () => OSApp.UIDom.updateLoginButtons() ); OSApp.Notifications.addNotification( { title: OSApp.Language._( "OpenSprinkler.com Login Expired" ), @@ -762,7 +762,7 @@ OSApp.Network.changePassword = function( opt ) { success = function( pass ) { OSApp.currentSession.pass = pass; sites[ opt.name ].os_pw = popup.find( "#save_pw" ).is( ":checked" ) ? pass : ""; - OSApp.Storage.set( { "sites":JSON.stringify( sites ) }, OSApp.Network.cloudSaveSites ); + OSApp.Storage.set( { "sites":JSON.stringify( sites ) }, () => OSApp.Network.cloudSaveSites() ); popup.popup( "close" ); opt.callback(); }; @@ -814,7 +814,7 @@ OSApp.Network.changePassword = function( opt ) { sites[ data.current_site ].os_pw = npw; OSApp.currentSession.pass = npw; - OSApp.Storage.set( { "sites":JSON.stringify( sites ) }, OSApp.Network.cloudSaveSites ); + OSApp.Storage.set( { "sites":JSON.stringify( sites ) }, () => OSApp.Network.cloudSaveSites() ); } ); $.mobile.loading( "hide" ); popup.popup( "close" ); @@ -851,7 +851,7 @@ OSApp.Network.changePassword = function( opt ) { } ).then( function() { sites[ current ].os_pw = OSApp.currentSession.pass = pw; - OSApp.Storage.set( { "sites":JSON.stringify( sites ) }, OSApp.Network.cloudSaveSites ); + OSApp.Storage.set( { "sites":JSON.stringify( sites ) }, () => OSApp.Network.cloudSaveSites() ); opt.callback(); }, function() { diff --git a/www/js/modules/options.js b/www/js/modules/options.js index de917c0b..210084e5 100644 --- a/www/js/modules/options.js +++ b/www/js/modules/options.js @@ -1041,7 +1041,7 @@ OSApp.Options.showOptions = function( expandItem ) { sites[ data.current_site ].images = {}; sites[ data.current_site ].lastRunTime = {}; - OSApp.Storage.set( { "sites": JSON.stringify( sites ) }, OSApp.Network.cloudSaveSites ); + OSApp.Storage.set( { "sites": JSON.stringify( sites ) }, () => OSApp.Network.cloudSaveSites() ); } ); OSApp.Firmware.sendToOS( "/cs?pw=&" + cs ).done( function() { OSApp.Errors.showError( OSApp.Language._( "Stations have been updated" ) ); diff --git a/www/js/modules/sites.js b/www/js/modules/sites.js index 8d4cbbe3..122bf150 100644 --- a/www/js/modules/sites.js +++ b/www/js/modules/sites.js @@ -970,7 +970,7 @@ OSApp.Sites.updateSite = function( newsite ) { var sites = OSApp.Sites.parseSites( data.sites ); if ( newsite in sites ) { OSApp.UIDom.closePanel( function() { - OSApp.Storage.set( { "current_site":newsite }, OSApp.Sites.checkConfigured ); + OSApp.Storage.set( { "current_site":newsite }, () => OSApp.Sites.checkConfigured() ); } ); } } ); @@ -993,7 +993,7 @@ OSApp.Sites.fixPasswordHash = function( current ) { return false; } else { sites[ current ].os_pw = OSApp.currentSession.pass = pw; - OSApp.Storage.set( { "sites":JSON.stringify( sites ) }, OSApp.Network.cloudSaveSites ); + OSApp.Storage.set( { "sites":JSON.stringify( sites ) }, () => OSApp.Network.cloudSaveSites() ); } } ); } diff --git a/www/js/modules/stations.js b/www/js/modules/stations.js index 7c3c6133..b7c55a73 100644 --- a/www/js/modules/stations.js +++ b/www/js/modules/stations.js @@ -238,7 +238,7 @@ OSApp.Stations.submitRunonce = function( runonce ) { var submit = function() { $.mobile.loading( "show" ); - OSApp.Storage.set( { "runonce":JSON.stringify( runonce ) } ); + OSApp.Storage.set( { "runonce": JSON.stringify( runonce ) } ); OSApp.Firmware.sendToOS( "/cr?pw=&t=" + JSON.stringify( runonce ) ).done( function() { $.mobile.loading( "hide" ); $.mobile.document.one( "pageshow", function() { diff --git a/www/js/modules/storage.js b/www/js/modules/storage.js index bfcb2ec0..b6a6f256 100644 --- a/www/js/modules/storage.js +++ b/www/js/modules/storage.js @@ -37,16 +37,13 @@ OSApp.Storage.get = function( query, callback ) { OSApp.Storage.set = function( query, callback ) { callback = callback || function() {}; var i; - if ( typeof query === "object" ) { - for ( i in query ) { - if ( Object.prototype.hasOwnProperty.call(query, i ) ) { - localStorage.setItem( i, query[ i ] ); - } + for ( i in query ) { + if ( Object.prototype.hasOwnProperty.call(query, i ) ) { + localStorage.setItem( i, query[ i ] ); } } - // Callback( true ); mellodev this causes other functions that require a callback func arg to fail - callback(); + callback( true ); }; OSApp.Storage.remove = function( query, callback ) { @@ -63,8 +60,7 @@ OSApp.Storage.remove = function( query, callback ) { } } - // Callback( true ); mellodev this causes other functions that require a callback func arg to fail - callback(); + callback( true ); }; OSApp.Storage.loadLocalSettings = function() { diff --git a/www/js/modules/ui-dom.js b/www/js/modules/ui-dom.js index e666c58c..b27188d7 100644 --- a/www/js/modules/ui-dom.js +++ b/www/js/modules/ui-dom.js @@ -287,7 +287,7 @@ OSApp.UIDom.launchApp = function() { delete sites[ site ]; site = nm; if ( isCurrent ) { - OSApp.Storage.set( { "current_site":site } ); + OSApp.Storage.set( { "current_site": site } ); data.current_site = site; } OSApp.Sites.updateSiteList( Object.keys( sites ), data.current_site ); @@ -295,7 +295,7 @@ OSApp.UIDom.launchApp = function() { //OSApp.Firmware.sendToOS( "/cv?pw=&cn=" + data.current_site ); } - OSApp.Storage.set( { "sites":JSON.stringify( sites ) }, OSApp.Network.cloudSaveSites ); + OSApp.Storage.set( { "sites":JSON.stringify( sites ) }, () => OSApp.Network.cloudSaveSites() ); OSApp.Errors.showError( OSApp.Language._( "Site updated successfully" ) ); @@ -323,7 +323,7 @@ OSApp.UIDom.launchApp = function() { } delete sites[ site ]; - OSApp.Storage.set( { "sites":JSON.stringify( sites ) }, function() { + OSApp.Storage.set( { "sites": JSON.stringify( sites ) }, function() { OSApp.Network.cloudSaveSites(); OSApp.Sites.updateSiteList( Object.keys( sites ), data.current_site ); if ( $.isEmptyObject( sites ) ) { @@ -738,7 +738,7 @@ OSApp.UIDom.launchApp = function() { // Update the notes section sites[ currentSite ].notes[ sid ] = select.find( "#stn-notes" ).val(); - OSApp.Storage.set( { "sites": JSON.stringify( sites ) }, OSApp.Network.cloudSaveSites ); + OSApp.Storage.set( { "sites": JSON.stringify( sites ) }, () => OSApp.Network.cloudSaveSites() ); submitStations( sid ); select.popup( "destroy" ).remove(); @@ -940,7 +940,7 @@ OSApp.UIDom.launchApp = function() { OSApp.UIDom.getPicture( function( image ) { sites[ currentSite ].images[ sid ] = image; - OSApp.Storage.set( { "sites":JSON.stringify( sites ) }, OSApp.Network.cloudSaveSites ); + OSApp.Storage.set( { "sites":JSON.stringify( sites ) }, () => OSApp.Network.cloudSaveSites() ); updateContent(); button.innerHTML = OSApp.Language._( "Change" ) + " " + OSApp.Language._( "Image" ); @@ -1448,7 +1448,7 @@ OSApp.UIDom.launchApp = function() { // Save run time for this station sites[ currentSite ].lastRunTime[ sid ] = duration; - OSApp.Storage.set( { "sites": JSON.stringify( sites ) }, OSApp.Network.cloudSaveSites ); + OSApp.Storage.set( { "sites": JSON.stringify( sites ) }, () => OSApp.Network.cloudSaveSites() ); } ); } } ); @@ -1484,13 +1484,13 @@ OSApp.UIDom.launchApp = function() { if ( hasImage ) { OSApp.UIDom.areYouSure( OSApp.Language._( "Do you want to delete the current image?" ), "", function() { delete sites[ currentSite ].images[ id ]; - OSApp.Storage.set( { "sites":JSON.stringify( sites ) }, OSApp.Network.cloudSaveSites ); + OSApp.Storage.set( { "sites":JSON.stringify( sites ) }, () => OSApp.Network.cloudSaveSites() ); updateContent(); } ); } else { OSApp.UIDom.getPicture( function( image ) { sites[ currentSite ].images[ id ] = image; - OSApp.Storage.set( { "sites":JSON.stringify( sites ) }, OSApp.Network.cloudSaveSites ); + OSApp.Storage.set( { "sites":JSON.stringify( sites ) }, () => OSApp.Network.cloudSaveSites() ); updateContent(); } ); } @@ -1738,7 +1738,7 @@ OSApp.UIDom.launchApp = function() { callback: function( result ) { dur.val( result ); dur.text( OSApp.Dates.dhms2str( OSApp.Dates.sec2dhms( result ) ) ); - OSApp.Storage.set( { "autoOff":result } ); + OSApp.Storage.set( { "autoOff": result } ); }, maximum: 32768 } ); From 9278cb4b9056f3fea04bcf3767340aefdc252c8d Mon Sep 17 00:00:00 2001 From: Samer Albahra Date: Tue, 26 Nov 2024 19:05:35 -0500 Subject: [PATCH 03/14] Update unit test GH action --- .github/workflows/test.yml | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b58e0c66..16b1c76e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,17 +11,24 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + fetch-depth: 0 - - name: Use Node.js 18.x - uses: actions/setup-node@v3 - with: - node-version: 18.x + - name: Cache Dependencies + id: cache_npm + uses: actions/cache@v4 + with: + path: node_modules + key: ${{ runner.os }}-npm-${{ hashFiles('package-lock.json') }} + restore-keys: | + ${{ runner.os }}-npm- - - name: Install dependencies - run: | - npm install + - name: Install dependencies + if: steps.cache_npm.outputs.cache-hit != 'true' + run: npm install - - name: Run test steps - run: | - grunt + - name: Run test steps + run: | + grunt + npm run test From c7a04542dff4b04e940211061247a485d689187f Mon Sep 17 00:00:00 2001 From: Samer Albahra Date: Tue, 26 Nov 2024 19:30:18 -0500 Subject: [PATCH 04/14] Working state (with tests commented out) --- package.json | 2 +- test/karma.conf.js | 23 +++--- test/tests.js | 202 ++++++++++++++++++++++----------------------- 3 files changed, 114 insertions(+), 113 deletions(-) diff --git a/package.json b/package.json index 68017b0a..246d7129 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "lint": "eslint ./www/js/**", "prepare": "husky", "start": "npx http-server --port 8080 --cors '*' -c-1 ./www", - "test": "echo \"Error: no test specified\" && exit 1" + "test": "npx karma start --browsers ChromeHeadless test/karma.conf.js" }, "lint-staged": { "package.json": "sort-package-json" diff --git a/test/karma.conf.js b/test/karma.conf.js index 3eb8ffe6..72555a44 100644 --- a/test/karma.conf.js +++ b/test/karma.conf.js @@ -1,18 +1,19 @@ module.exports = function (config) { config.set({ frameworks: ['mocha', 'chai'], + basePath: '../', files: [ - { pattern: '../www/css/jqm.css', included: true, watched: false }, - { pattern: '../www/css/main.css', included: true, watched: false }, - { pattern: '../node_modules/mocha/mocha.css', included: true, watched: false }, - { pattern: '../www/vendor-js/jquery.js', included: true, watched: false }, - { pattern: '../www/vendor-js/libs.js', included: true, watched: false }, - { pattern: '../www/vendor-js/apexcharts.min.js', included: true, watched: false }, - { pattern: '../www/vendor-js/jqm.js', included: true, watched: false }, - { pattern: '../www/vendor-js/dataTables-2.1.8.min.js.js', included: true, watched: false }, - { pattern: '../www/js/modules/*.js', included: true, watched: false }, - { pattern: '../www/js/main.js', included: true, watched: false }, - 'tests.js' + { pattern: 'www/css/jqm.css', included: true, watched: false }, + { pattern: 'www/css/main.css', included: true, watched: false }, + { pattern: 'node_modules/mocha/mocha.css', included: true, watched: false }, + { pattern: 'www/vendor-js/jquery.js', included: true, watched: false }, + { pattern: 'www/vendor-js/libs.js', included: true, watched: false }, + { pattern: 'www/vendor-js/apexcharts.min.js', included: true, watched: false }, + { pattern: 'www/vendor-js/jqm.js', included: true, watched: false }, + { pattern: 'www/vendor-js/dataTables-2.1.8.min.js', included: true, watched: false }, + { pattern: 'www/js/modules/*.js', included: true, watched: false }, + { pattern: 'www/js/main.js', included: true, watched: false }, + 'test/tests.js' ], browsers: ['ChromeHeadless'], singleRun: true diff --git a/test/tests.js b/test/tests.js index 432786a3..455ebac6 100644 --- a/test/tests.js +++ b/test/tests.js @@ -186,94 +186,94 @@ describe( "General Function Checks", function() { } ); } ); -describe( "Page Navigation Checks", function() { - it( "Start jQuery Mobile Page Initialization", function( done ) { - OSApp.currentSession.currIp = "demo.opensprinkler.com"; - OSApp.currentSession.currPass = "opendoor"; - OSApp.currentSession.currPrefix = "http://"; - OSApp.currentSession.curr183 = false; - - OSApp.Sites.updateSiteList( [ "Test" ], "Test" ); - - $.mobile.document.one( "pageshow", "#sprinklers", function() { - done(); - } ); - - OSApp.Sites.newLoad(); - } ); - - it( "Change page to program preview", function( done ) { - $.mobile.document.one( "pageshow", "#preview", function() { - done(); - } ); - assert.doesNotThrow( function() { - OSApp.UIDom.changePage( "#preview" ); - } ); - } ); - - it( "Change to logs page", function( done ) { - $.mobile.document.one( "pageshow", "#logs", function() { - done(); - } ); - assert.doesNotThrow( function() { - OSApp.UIDom.changePage( "#logs" ); - } ); - } ); - - it( "Change to runonce page", function( done ) { - $.mobile.document.one( "pageshow", "#runonce", function() { - done(); - } ); - assert.doesNotThrow( function() { - OSApp.UIDom.changePage( "#runonce" ); - } ); - } ); - - it( "Change to edit programs page", function( done ) { - $.mobile.document.one( "pageshow", "#programs", function() { - done(); - } ); - assert.doesNotThrow( function() { - OSApp.UIDom.changePage( "#programs" ); - } ); - } ); - - it( "Change to add new program page", function( done ) { - $.mobile.document.one( "pageshow", "#addprogram", function() { - done(); - } ); - assert.doesNotThrow( function() { - OSApp.UIDom.changePage( "#addprogram" ); - } ); - } ); - - it( "Change to options page", function( done ) { - $.mobile.document.one( "pageshow", "#os-options", function() { - done(); - } ); - assert.doesNotThrow( function() { - OSApp.UIDom.changePage( "#os-options" ); - } ); - } ); - - it( "Change to site manager page", function( done ) { - $.mobile.document.one( "pageshow", "#site-control", function() { - done(); - } ); - assert.doesNotThrow( function() { - OSApp.UIDom.changePage( "#site-control" ); - } ); - } ); - - it( "Change to about page", function( done ) { - $.mobile.document.one( "pageshow", "#about", function() { - done(); - } ); - assert.doesNotThrow( function() { - OSApp.UIDom.changePage( "#about" ); - } ); - } ); -} ); +// describe( "Page Navigation Checks", function() { +// it( "Start jQuery Mobile Page Initialization", function( done ) { +// OSApp.currentSession.currIp = "demo.opensprinkler.com"; +// OSApp.currentSession.currPass = "opendoor"; +// OSApp.currentSession.currPrefix = "http://"; +// OSApp.currentSession.curr183 = false; + +// OSApp.Sites.updateSiteList( [ "Test" ], "Test" ); + +// $.mobile.document.one( "pageshow", "#sprinklers", function() { +// done(); +// } ); + +// OSApp.Sites.newLoad(); +// } ); + +// it( "Change page to program preview", function( done ) { +// $.mobile.document.one( "pageshow", "#preview", function() { +// done(); +// } ); +// assert.doesNotThrow( function() { +// OSApp.UIDom.changePage( "#preview" ); +// } ); +// } ); + +// it( "Change to logs page", function( done ) { +// $.mobile.document.one( "pageshow", "#logs", function() { +// done(); +// } ); +// assert.doesNotThrow( function() { +// OSApp.UIDom.changePage( "#logs" ); +// } ); +// } ); + +// it( "Change to runonce page", function( done ) { +// $.mobile.document.one( "pageshow", "#runonce", function() { +// done(); +// } ); +// assert.doesNotThrow( function() { +// OSApp.UIDom.changePage( "#runonce" ); +// } ); +// } ); + +// it( "Change to edit programs page", function( done ) { +// $.mobile.document.one( "pageshow", "#programs", function() { +// done(); +// } ); +// assert.doesNotThrow( function() { +// OSApp.UIDom.changePage( "#programs" ); +// } ); +// } ); + +// it( "Change to add new program page", function( done ) { +// $.mobile.document.one( "pageshow", "#addprogram", function() { +// done(); +// } ); +// assert.doesNotThrow( function() { +// OSApp.UIDom.changePage( "#addprogram" ); +// } ); +// } ); + +// it( "Change to options page", function( done ) { +// $.mobile.document.one( "pageshow", "#os-options", function() { +// done(); +// } ); +// assert.doesNotThrow( function() { +// OSApp.UIDom.changePage( "#os-options" ); +// } ); +// } ); + +// it( "Change to site manager page", function( done ) { +// $.mobile.document.one( "pageshow", "#site-control", function() { +// done(); +// } ); +// assert.doesNotThrow( function() { +// OSApp.UIDom.changePage( "#site-control" ); +// } ); +// } ); + +// it( "Change to about page", function( done ) { +// $.mobile.document.one( "pageshow", "#about", function() { +// done(); +// } ); +// assert.doesNotThrow( function() { +// OSApp.UIDom.changePage( "#about" ); +// } ); +// } ); +// } ); describe( "Popup Checks", function() { @@ -283,21 +283,21 @@ describe( "Popup Checks", function() { // done(); // } ); // assert.doesNotThrow( function() { - // showHomeMenu(); + // OSApp.UIDom.showHomeMenu(); // } ); // } ); - it( "Show change rain delay popup", function( done ) { - $.mobile.document.one( "popupafteropen", "#durationBox", function() { - $.mobile.document.one( "popupafterclose", "#durationBox", function() { - done(); - } ); - $( "#durationBox" ).popup( "close" ).remove(); - } ); - assert.doesNotThrow( function() { - $( "#mainMenu" ).find( "a[href='#raindelay']" ).trigger( "click" ); - } ); - } ); + // it( "Show change rain delay popup", function( done ) { + // $.mobile.document.one( "popupafteropen", "#durationBox", function() { + // $.mobile.document.one( "popupafterclose", "#durationBox", function() { + // done(); + // } ); + // $( "#durationBox" ).popup( "close" ).remove(); + // } ); + // assert.doesNotThrow( function() { + // $( "#mainMenu" ).find( "a[href='#raindelay']" ).trigger( "click" ); + // } ); + // } ); it( "Show add new site popup", function( done ) { $.mobile.document.one( "popupafteropen", "#addnew", function() { @@ -364,7 +364,7 @@ describe( "Popup Checks", function() { $( "#localization" ).popup( "close" ).remove(); } ); assert.doesNotThrow( function() { - languageSelect(); + OSApp.Language.languageSelect(); } ); } ); } ); From 3ea66cfc5ec45e203c8f882f39cb763159f1dc25 Mon Sep 17 00:00:00 2001 From: Samer Albahra Date: Tue, 26 Nov 2024 20:47:30 -0500 Subject: [PATCH 05/14] More updates --- test/karma.conf.js | 5 + test/prepare_tests.js | 15 ++ test/tests.js | 608 +++++++++++++++++++++--------------------- 3 files changed, 325 insertions(+), 303 deletions(-) create mode 100644 test/prepare_tests.js diff --git a/test/karma.conf.js b/test/karma.conf.js index 72555a44..ea7a0306 100644 --- a/test/karma.conf.js +++ b/test/karma.conf.js @@ -1,3 +1,5 @@ +const path = require('path'); + module.exports = function (config) { config.set({ frameworks: ['mocha', 'chai'], @@ -11,6 +13,9 @@ module.exports = function (config) { { pattern: 'www/vendor-js/apexcharts.min.js', included: true, watched: false }, { pattern: 'www/vendor-js/jqm.js', included: true, watched: false }, { pattern: 'www/vendor-js/dataTables-2.1.8.min.js', included: true, watched: false }, + { pattern: 'www/index.html', included: false, watched: false, served: true }, + 'test/prepare_tests.js', + { pattern: 'www/css/images/ajax-loader.gif', included: false, watched: false, served: true }, { pattern: 'www/js/modules/*.js', included: true, watched: false }, { pattern: 'www/js/main.js', included: true, watched: false }, 'test/tests.js' diff --git a/test/prepare_tests.js b/test/prepare_tests.js new file mode 100644 index 00000000..da183168 --- /dev/null +++ b/test/prepare_tests.js @@ -0,0 +1,15 @@ +describe('prepare_tests', function() { + before(function() { + return new Promise(function (resolve) { + $.ajax({ + url: "/base/www/index.html", + cache: true, + type: "GET" + }).done(function (index) { + var body = index.match(/([.\s\S]*)<\/body>/)[1]; + $("body").prepend(body); + resolve(); + }); + } ); + }) +}); diff --git a/test/tests.js b/test/tests.js index 455ebac6..25435be7 100644 --- a/test/tests.js +++ b/test/tests.js @@ -15,267 +15,269 @@ var assert = chai.assert; -describe( "Initial Definition Check", function() { - it( "storage.set(object,callback) should accept an object of key/value pairs to be set into localStorage and respond with callback", function( done ) { - assert.doesNotThrow( function() { - OSApp.Storage.set( { +describe("Initial Definition Check", function () { + it("storage.set(object,callback) should accept an object of key/value pairs to be set into localStorage and respond with callback", function (done) { + assert.doesNotThrow(function () { + OSApp.Storage.set({ "testkey": "helloworld", - "sites": JSON.stringify( { + "sites": JSON.stringify({ "Test": { "os_ip": "demo.opensprinkler.com", - "os_pw":"opendoor" + "os_pw": "opendoor" } - } ), - "current_site": "Test" - }, function( result ) { - result === true ? done() : done( new Error( "Failed to set key/value pairs", result.Error ) ); - } ); - } ); - } ); - - it( "storage.get(object,callback) should accept an array of keys to be retrieved from localStorage and respond with callback", function( done ) { - assert.doesNotThrow( function() { - OSApp.Storage.get( [ "testkey" ], function( result ) { - if ( result.testkey === "helloworld" ) { + }), + "current_site": "Test" + }, function (result) { + result === true ? done() : done(new Error("Failed to set key/value pairs", result.Error)); + }); + }); + }); + + it("storage.get(object,callback) should accept an array of keys to be retrieved from localStorage and respond with callback", function (done) { + assert.doesNotThrow(function () { + OSApp.Storage.get(["testkey"], function (result) { + if (result.testkey === "helloworld") { done(); } - } ); - } ); - } ); - - it( "storage.remove(object,callback) should accept an array of keys to be deleted from localStorage and respond with callback", function( done ) { - assert.doesNotThrow( function() { - OSApp.Storage.remove( [ "testkey" ], function( result ) { - if ( result === true ) { + }); + }); + }); + + it("storage.remove(object,callback) should accept an array of keys to be deleted from localStorage and respond with callback", function (done) { + assert.doesNotThrow(function () { + OSApp.Storage.remove(["testkey"], function (result) { + if (result === true) { done(); } - } ); - } ); - } ); - - it( "storage.remove(string,callback) should accept a key to be deleted from localStorage and respond with callback", function( done ) { - assert.doesNotThrow( function() { - OSApp.Storage.remove( "fakekey", function( result ) { - if ( result === true ) { + }); + }); + }); + + it("storage.remove(string,callback) should accept a key to be deleted from localStorage and respond with callback", function (done) { + assert.doesNotThrow(function () { + OSApp.Storage.remove("fakekey", function (result) { + if (result === true) { done(); } - } ); - } ); - } ); -} ); + }); + }); + }); +}); -describe( "OpenSprinkler Firmware Version Functions", function() { +describe("OpenSprinkler Firmware Version Functions", function () { - describe( "Test against Arduino Firmware Version", function() { - before( function() { + describe("Test against Arduino Firmware Version", function () { + before(function () { OSApp.currentSession.controller.options = { fwv: 210 }; - } ); - it( "isOPSi() should identify if the device is an OSPi", function() { - assert.equal( false, OSApp.Firmware.isOSPi() ); - } ); - it( "versionCompare(device,compare) should check the given firmware (device) against the compare firmware where the input is an array", function() { - assert.strictEqual( false, OSApp.Firmware.versionCompare( [ 1 ], [ 1, 5 ] ) ); - assert.strictEqual( 0, OSApp.Firmware.versionCompare( [ 1, 5 ], [ 1, 5 ] ) ); - assert.strictEqual( 1, OSApp.Firmware.versionCompare( [ 2, 1 ], [ 1, 5 ] ) ); - } ); - it( "checkOSVersion(compare) should compare the input firmware version against the Arduino firmware version.", function() { - assert.strictEqual( false, OSApp.Firmware.checkOSVersion( 211 ) ); - assert.strictEqual( true, OSApp.Firmware.checkOSVersion( 210 ) ); - assert.strictEqual( 1, OSApp.Firmware.checkOSVersion( 208 ) ); - } ); - it( "checkOSPiVersion(compare) should compare the input firmware version against the OSPi firmware version.", function() { - assert.strictEqual( false, OSApp.Firmware.checkOSPiVersion( "2.0" ) ); - assert.strictEqual( false, OSApp.Firmware.checkOSPiVersion( "1.9" ) ); - assert.strictEqual( false, OSApp.Firmware.checkOSPiVersion( "2.1" ) ); - } ); - } ); - - describe( "Test against OSPi Firmware Version", function() { - before( function() { + }); + it("isOPSi() should identify if the device is an OSPi", function () { + assert.equal(false, OSApp.Firmware.isOSPi()); + }); + it("versionCompare(device,compare) should check the given firmware (device) against the compare firmware where the input is an array", function () { + assert.strictEqual(false, OSApp.Firmware.versionCompare([1], [1, 5])); + assert.strictEqual(0, OSApp.Firmware.versionCompare([1, 5], [1, 5])); + assert.strictEqual(1, OSApp.Firmware.versionCompare([2, 1], [1, 5])); + }); + it("checkOSVersion(compare) should compare the input firmware version against the Arduino firmware version.", function () { + assert.strictEqual(false, OSApp.Firmware.checkOSVersion(211)); + assert.strictEqual(true, OSApp.Firmware.checkOSVersion(210)); + assert.strictEqual(1, OSApp.Firmware.checkOSVersion(208)); + }); + it("checkOSPiVersion(compare) should compare the input firmware version against the OSPi firmware version.", function () { + assert.strictEqual(false, OSApp.Firmware.checkOSPiVersion("2.0")); + assert.strictEqual(false, OSApp.Firmware.checkOSPiVersion("1.9")); + assert.strictEqual(false, OSApp.Firmware.checkOSPiVersion("2.1")); + }); + }); + + describe("Test against OSPi Firmware Version", function () { + before(function () { OSApp.currentSession.controller.options = { fwv: "1.9.0-OSPi" }; - } ); - it( "isOPSi() should identify if the device is an OSPi", function() { - assert.equal( true, OSApp.Firmware.isOSPi() ); - } ); - it( "versionCompare(device,compare) should check the given firmware (device) against the compare firmware where the input is an array", function() { - assert.strictEqual( false, OSApp.Firmware.versionCompare( [ 1 ], [ 1, 5 ] ) ); - assert.strictEqual( 0, OSApp.Firmware.versionCompare( [ 1, 5 ], [ 1, 5 ] ) ); - assert.strictEqual( 1, OSApp.Firmware.versionCompare( [ 2, 1 ], [ 1, 5 ] ) ); - } ); - it( "checkOSVersion(compare) should compare the input firmware version against the Arduino firmware version.", function() { - assert.strictEqual( false, OSApp.Firmware.checkOSVersion( 211 ) ); - assert.strictEqual( false, OSApp.Firmware.checkOSVersion( 210 ) ); - assert.strictEqual( false, OSApp.Firmware.checkOSVersion( 208 ) ); - } ); - it( "checkOSPiVersion(compare) should compare the input firmware version against the OSPi firmware version.", function() { - assert.strictEqual( 1, OSApp.Firmware.checkOSPiVersion( "1.8" ) ); - assert.strictEqual( true, OSApp.Firmware.checkOSPiVersion( "1.9.0" ) ); - assert.strictEqual( false, OSApp.Firmware.checkOSPiVersion( "2.0" ) ); - assert.strictEqual( false, OSApp.Firmware.checkOSPiVersion( "2.1" ) ); - } ); - } ); - - describe( "Retrieve the formatted firmware version", function() { - before( function() { + }); + it("isOPSi() should identify if the device is an OSPi", function () { + assert.equal(true, OSApp.Firmware.isOSPi()); + }); + it("versionCompare(device,compare) should check the given firmware (device) against the compare firmware where the input is an array", function () { + assert.strictEqual(false, OSApp.Firmware.versionCompare([1], [1, 5])); + assert.strictEqual(0, OSApp.Firmware.versionCompare([1, 5], [1, 5])); + assert.strictEqual(1, OSApp.Firmware.versionCompare([2, 1], [1, 5])); + }); + it("checkOSVersion(compare) should compare the input firmware version against the Arduino firmware version.", function () { + assert.strictEqual(false, OSApp.Firmware.checkOSVersion(211)); + assert.strictEqual(false, OSApp.Firmware.checkOSVersion(210)); + assert.strictEqual(false, OSApp.Firmware.checkOSVersion(208)); + }); + it("checkOSPiVersion(compare) should compare the input firmware version against the OSPi firmware version.", function () { + assert.strictEqual(1, OSApp.Firmware.checkOSPiVersion("1.8")); + assert.strictEqual(true, OSApp.Firmware.checkOSPiVersion("1.9.0")); + assert.strictEqual(false, OSApp.Firmware.checkOSPiVersion("2.0")); + assert.strictEqual(false, OSApp.Firmware.checkOSPiVersion("2.1")); + }); + }); + + describe("Retrieve the formatted firmware version", function () { + before(function () { OSApp.currentSession.controller.options = { fwv: 204 }; - } ); - it( "getOSVersion(fwv) should return the firmware in a string representation", function() { - assert.equal( "1.8.3-OSPi", OSApp.Firmware.getOSVersion( "1.8.3-OSPi" ) ); - assert.equal( "2.1.193-OSPi", OSApp.Firmware.getOSVersion( "2.1.193-OSPi" ) ); - assert.equal( "2.0.8", OSApp.Firmware.getOSVersion( 208 ) ); - assert.equal( "2.0.4", OSApp.Firmware.getOSVersion() ); - } ); - } ); -} ); - -describe( "General Function Checks", function() { - it( "OSApp.Utils.parseIntArray(array) should convert all members into integers", function() { - assert.deepEqual( [ 9, 394, 29193, -1 ], OSApp.Utils.parseIntArray( [ "9", "394", "29193", "-1" ] ) ); - } ); - - it( "OSApp.Dates.sec2hms(number) should return a string representation of the difference the input represents (seconds)", function() { - assert.equal( "23:59:59", OSApp.Dates.sec2hms( 86399 ) ); - assert.equal( "15:00", OSApp.Dates.sec2hms( 900 ) ); - } ); - - it( "OSApp.Dates.sec2dhms(number) should return an object containing days, hours, minutes and seconds from the input (seconds)", function() { - assert.deepEqual( { + }); + it("getOSVersion(fwv) should return the firmware in a string representation", function () { + assert.equal("1.8.3-OSPi", OSApp.Firmware.getOSVersion("1.8.3-OSPi")); + assert.equal("2.1.193-OSPi", OSApp.Firmware.getOSVersion("2.1.193-OSPi")); + assert.equal("2.0.8", OSApp.Firmware.getOSVersion(208)); + assert.equal("2.0.4", OSApp.Firmware.getOSVersion()); + }); + }); +}); + +describe("General Function Checks", function () { + it("OSApp.Utils.parseIntArray(array) should convert all members into integers", function () { + assert.deepEqual([9, 394, 29193, -1], OSApp.Utils.parseIntArray(["9", "394", "29193", "-1"])); + }); + + it("OSApp.Dates.sec2hms(number) should return a string representation of the difference the input represents (seconds)", function () { + assert.equal("23:59:59", OSApp.Dates.sec2hms(86399)); + assert.equal("15:00", OSApp.Dates.sec2hms(900)); + }); + + it("OSApp.Dates.sec2dhms(number) should return an object containing days, hours, minutes and seconds from the input (seconds)", function () { + assert.deepEqual({ days: 936, hours: 17, minutes: 20, seconds: 9 - }, OSApp.Dates.sec2dhms( 80932809 ) ); - } ); - - it( "OSApp.Dates.dhms2str(object) should convert an object with elements days, hours, minutes and seconds into a string representation", function() { - assert.equal( "5d 4h 3m 1s", OSApp.Dates.dhms2str( { days:5, hours:4, minutes:3, seconds:1 } ) ); - assert.equal( "0s", OSApp.Dates.dhms2str( {} ) ); - } ); - - it( "OSApp.Dates.dhms2sec(object) should convert an object with elements days, hours, minutes and seconds into a second value", function() { - assert.equal( 100981, OSApp.Dates.dhms2sec( { days:1, hours:4, minutes:3, seconds:1 } ) ); - } ); - - it( "OSApp.Dates.getDayName(day,type) should return the day of the week and can be of type 'short'", function() { - assert.equal( "Sunday", OSApp.Dates.getDayName( new Date( 1410745528126 ) ) ); - assert.equal( "Thu", OSApp.Dates.getDayName( new Date( 1410445528126 ), "short" ) ); - } ); - - it( "OSApp.Utils.pad(number) should successfully prepend a 0 to a single digit", function() { - assert.equal( "00", OSApp.Utils.pad( 0 ) ); - assert.equal( "01", OSApp.Utils.pad( 1 ) ); - assert.equal( "10", OSApp.Utils.pad( 10 ) ); - assert.equal( "999", OSApp.Utils.pad( 999 ) ); - } ); - - it( "OSApp.Weather.getCurrentAdjustmentMethodId() should return the adjustment method ID", function() { - assert.equal( 0, OSApp.Weather.getCurrentAdjustmentMethodId() ); - } ); - - it( "OSApp.Weather.getAdjustmentMethod(uwt) should return the adjustment method for the corresponding ID", function() { - assert.equal( "Manual", OSApp.Weather.getAdjustmentMethod( 0 ).name ); - assert.equal( "Manual", OSApp.Weather.getAdjustmentMethod( 128 ).name ); - assert.equal( "Zimmerman", OSApp.Weather.getAdjustmentMethod( 1 ).name ); - assert.equal( "Zimmerman", OSApp.Weather.getAdjustmentMethod( 129 ).name ); - } ); -} ); - -// describe( "Page Navigation Checks", function() { -// it( "Start jQuery Mobile Page Initialization", function( done ) { -// OSApp.currentSession.currIp = "demo.opensprinkler.com"; -// OSApp.currentSession.currPass = "opendoor"; -// OSApp.currentSession.currPrefix = "http://"; -// OSApp.currentSession.curr183 = false; - -// OSApp.Sites.updateSiteList( [ "Test" ], "Test" ); - -// $.mobile.document.one( "pageshow", "#sprinklers", function() { -// done(); -// } ); - -// OSApp.Sites.newLoad(); -// } ); - -// it( "Change page to program preview", function( done ) { -// $.mobile.document.one( "pageshow", "#preview", function() { -// done(); -// } ); -// assert.doesNotThrow( function() { -// OSApp.UIDom.changePage( "#preview" ); -// } ); -// } ); - -// it( "Change to logs page", function( done ) { -// $.mobile.document.one( "pageshow", "#logs", function() { -// done(); -// } ); -// assert.doesNotThrow( function() { -// OSApp.UIDom.changePage( "#logs" ); -// } ); -// } ); - -// it( "Change to runonce page", function( done ) { -// $.mobile.document.one( "pageshow", "#runonce", function() { -// done(); -// } ); -// assert.doesNotThrow( function() { -// OSApp.UIDom.changePage( "#runonce" ); -// } ); -// } ); - -// it( "Change to edit programs page", function( done ) { -// $.mobile.document.one( "pageshow", "#programs", function() { -// done(); -// } ); -// assert.doesNotThrow( function() { -// OSApp.UIDom.changePage( "#programs" ); -// } ); -// } ); - -// it( "Change to add new program page", function( done ) { -// $.mobile.document.one( "pageshow", "#addprogram", function() { -// done(); -// } ); -// assert.doesNotThrow( function() { -// OSApp.UIDom.changePage( "#addprogram" ); -// } ); -// } ); - -// it( "Change to options page", function( done ) { -// $.mobile.document.one( "pageshow", "#os-options", function() { -// done(); -// } ); -// assert.doesNotThrow( function() { -// OSApp.UIDom.changePage( "#os-options" ); -// } ); -// } ); - -// it( "Change to site manager page", function( done ) { -// $.mobile.document.one( "pageshow", "#site-control", function() { -// done(); -// } ); -// assert.doesNotThrow( function() { -// OSApp.UIDom.changePage( "#site-control" ); -// } ); -// } ); - -// it( "Change to about page", function( done ) { -// $.mobile.document.one( "pageshow", "#about", function() { -// done(); -// } ); -// assert.doesNotThrow( function() { -// OSApp.UIDom.changePage( "#about" ); -// } ); -// } ); -// } ); - -describe( "Popup Checks", function() { + }, OSApp.Dates.sec2dhms(80932809)); + }); + + it("OSApp.Dates.dhms2str(object) should convert an object with elements days, hours, minutes and seconds into a string representation", function () { + assert.equal("5d 4h 3m 1s", OSApp.Dates.dhms2str({ days: 5, hours: 4, minutes: 3, seconds: 1 })); + assert.equal("0s", OSApp.Dates.dhms2str({})); + }); + + it("OSApp.Dates.dhms2sec(object) should convert an object with elements days, hours, minutes and seconds into a second value", function () { + assert.equal(100981, OSApp.Dates.dhms2sec({ days: 1, hours: 4, minutes: 3, seconds: 1 })); + }); + + it("OSApp.Dates.getDayName(day,type) should return the day of the week and can be of type 'short'", function () { + assert.equal("Sunday", OSApp.Dates.getDayName(new Date(1410745528126))); + assert.equal("Thu", OSApp.Dates.getDayName(new Date(1410445528126), "short")); + }); + + it("OSApp.Utils.pad(number) should successfully prepend a 0 to a single digit", function () { + assert.equal("00", OSApp.Utils.pad(0)); + assert.equal("01", OSApp.Utils.pad(1)); + assert.equal("10", OSApp.Utils.pad(10)); + assert.equal("999", OSApp.Utils.pad(999)); + }); + + it("OSApp.Weather.getCurrentAdjustmentMethodId() should return the adjustment method ID", function () { + assert.equal(0, OSApp.Weather.getCurrentAdjustmentMethodId()); + }); + + it("OSApp.Weather.getAdjustmentMethod(uwt) should return the adjustment method for the corresponding ID", function () { + assert.equal("Manual", OSApp.Weather.getAdjustmentMethod(0).name); + assert.equal("Manual", OSApp.Weather.getAdjustmentMethod(128).name); + assert.equal("Zimmerman", OSApp.Weather.getAdjustmentMethod(1).name); + assert.equal("Zimmerman", OSApp.Weather.getAdjustmentMethod(129).name); + }); +}); + +describe("Page Navigation Checks", function () { + // before(function () { + // OSApp.currentSession.ip = "demo.opensprinkler.com"; + // OSApp.currentSession.pass = "opendoor"; + // OSApp.currentSession.prefix = "https://"; + // OSApp.currentSession.fw183 = false; + + // OSApp.Sites.updateSiteList(["Test"], "Test"); + // }); + + // it("Start jQuery Mobile Page Initialization", function (done) { + // $.mobile.document.one("pageshow", "#sprinklers", function () { + // done(); + // }); + + // OSApp.Sites.newLoad(); + // }); + + // it( "Change page to program preview", function( done ) { + // $.mobile.document.one( "pageshow", "#preview", function() { + // done(); + // } ); + // assert.doesNotThrow( function() { + // OSApp.UIDom.changePage( "#preview" ); + // } ); + // } ); + + // it( "Change to logs page", function( done ) { + // $.mobile.document.one( "pageshow", "#logs", function() { + // done(); + // } ); + // assert.doesNotThrow( function() { + // OSApp.UIDom.changePage( "#logs" ); + // } ); + // } ); + + // it( "Change to runonce page", function( done ) { + // $.mobile.document.one( "pageshow", "#runonce", function() { + // done(); + // } ); + // assert.doesNotThrow( function() { + // OSApp.UIDom.changePage( "#runonce" ); + // } ); + // } ); + + // it( "Change to edit programs page", function( done ) { + // $.mobile.document.one( "pageshow", "#programs", function() { + // done(); + // } ); + // assert.doesNotThrow( function() { + // OSApp.UIDom.changePage( "#programs" ); + // } ); + // } ); + + // it( "Change to add new program page", function( done ) { + // $.mobile.document.one( "pageshow", "#addprogram", function() { + // done(); + // } ); + // assert.doesNotThrow( function() { + // OSApp.UIDom.changePage( "#addprogram" ); + // } ); + // } ); + + // it( "Change to options page", function( done ) { + // $.mobile.document.one( "pageshow", "#os-options", function() { + // done(); + // } ); + // assert.doesNotThrow( function() { + // OSApp.UIDom.changePage( "#os-options" ); + // } ); + // } ); + + // it( "Change to site manager page", function( done ) { + // $.mobile.document.one( "pageshow", "#site-control", function() { + // done(); + // } ); + // assert.doesNotThrow( function() { + // OSApp.UIDom.changePage( "#site-control" ); + // } ); + // } ); + + // it( "Change to about page", function( done ) { + // $.mobile.document.one( "pageshow", "#about", function() { + // done(); + // } ); + // assert.doesNotThrow( function() { + // OSApp.UIDom.changePage( "#about" ); + // } ); + // } ); +}); + +describe("Popup Checks", function () { // 20241121 commented by mellodev (refactor how showHomeMenu works) // it( "Show main menu popup", function( done ) { @@ -299,88 +301,88 @@ describe( "Popup Checks", function() { // } ); // } ); - it( "Show add new site popup", function( done ) { - $.mobile.document.one( "popupafteropen", "#addnew", function() { - $.mobile.document.one( "popupafterclose", "#addnew", function() { + it("Show add new site popup", function (done) { + $.mobile.document.one("popupafteropen", "#addnew", function () { + $.mobile.document.one("popupafterclose", "#addnew", function () { done(); - } ); - $( "#addnew" ).popup( "close" ).remove(); - } ); - assert.doesNotThrow( function() { + }); + $("#addnew").popup("close").remove(); + }); + assert.doesNotThrow(function () { OSApp.Sites.showAddNew(); - } ); - } ); + }); + }); - it( "Show site select popup", function( done ) { - $.mobile.document.one( "popupafteropen", "#site-select", function() { - $.mobile.document.one( "popupafterclose", "#site-select", function() { + it("Show site select popup", function (done) { + $.mobile.document.one("popupafteropen", "#site-select", function () { + $.mobile.document.one("popupafterclose", "#site-select", function () { done(); - } ); - $( "#site-select" ).popup( "close" ).remove(); - } ); - assert.doesNotThrow( function() { + }); + $("#site-select").popup("close").remove(); + }); + assert.doesNotThrow(function () { OSApp.Sites.showSiteSelect(); - } ); - } ); - - it( "Show are you sure popup", function( done ) { - $.mobile.document.one( "popupafteropen", "#sure", function() { - $( "#sure .sure-do" ).trigger( "click" ); - } ); - assert.doesNotThrow( function() { - OSApp.UIDom.areYouSure( null, null, done ); - } ); - } ); - - it( "Show IP Address input popup", function( done ) { - $.mobile.document.one( "popupafteropen", "#ipInput", function() { - $.mobile.document.one( "popupafterclose", "#ipInput", function() { + }); + }); + + it("Show are you sure popup", function (done) { + $.mobile.document.one("popupafteropen", "#sure", function () { + $("#sure .sure-do").trigger("click"); + }); + assert.doesNotThrow(function () { + OSApp.UIDom.areYouSure(null, null, done); + }); + }); + + it("Show IP Address input popup", function (done) { + $.mobile.document.one("popupafteropen", "#ipInput", function () { + $.mobile.document.one("popupafterclose", "#ipInput", function () { done(); - } ); - $( "#ipInput" ).popup( "close" ).remove(); - } ); - assert.doesNotThrow( function() { + }); + $("#ipInput").popup("close").remove(); + }); + assert.doesNotThrow(function () { OSApp.UIDom.showIPRequest(); - } ); - } ); + }); + }); - it( "Show single duration input popup", function( done ) { - $.mobile.document.one( "popupafteropen", "#singleDuration", function() { - $.mobile.document.one( "popupafterclose", "#singleDuration", function() { + it("Show single duration input popup", function (done) { + $.mobile.document.one("popupafteropen", "#singleDuration", function () { + $.mobile.document.one("popupafterclose", "#singleDuration", function () { done(); - } ); - $( "#singleDuration" ).popup( "close" ).remove(); - } ); - assert.doesNotThrow( function() { + }); + $("#singleDuration").popup("close").remove(); + }); + assert.doesNotThrow(function () { OSApp.UIDom.showSingleDurationInput(); - } ); - } ); + }); + }); - it( "Show language selection popup", function( done ) { - $.mobile.document.one( "popupafteropen", "#localization", function() { - $.mobile.document.one( "popupafterclose", "#localization", function() { + it("Show language selection popup", function (done) { + $.mobile.document.one("popupafteropen", "#localization", function () { + $.mobile.document.one("popupafterclose", "#localization", function () { done(); - } ); - $( "#localization" ).popup( "close" ).remove(); - } ); - assert.doesNotThrow( function() { + }); + $("#localization").popup("close").remove(); + }); + assert.doesNotThrow(function () { OSApp.Language.languageSelect(); - } ); - } ); -} ); + }); + }); +}); -describe( "Logout / Clean up", function() { - it( "Remove all variables", function( done ) { - OSApp.Storage.remove( [ "sites", "current_site", "lang", "runonce" ], function() { +describe("Logout / Clean up", function () { + it("Remove all variables", function (done) { + OSApp.Storage.remove(["sites", "current_site", "lang", "runonce"], function () { done(); - } ); - } ); + }); + }); - it( "Go to start page", function( done ) { - $.mobile.document.one( "pageshow", "#start", function() { + it("Go to start page", function (done) { + $.mobile.document.one("pageshow", "#start", function () { done(); - } ); + }); OSApp.currentSession.currIp = ""; - OSApp.UIDom.changePage( "#start" ); - } ); -} ); + OSApp.UIDom.changePage("#start"); + }); +}); From fd7f2f275e3abf3e2093bd61b59cc518f66cc876 Mon Sep 17 00:00:00 2001 From: Samer Albahra Date: Wed, 27 Nov 2024 07:53:41 -0500 Subject: [PATCH 06/14] Minor fix --- test/prepare_tests.js | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/test/prepare_tests.js b/test/prepare_tests.js index da183168..c28f055e 100644 --- a/test/prepare_tests.js +++ b/test/prepare_tests.js @@ -1,15 +1,15 @@ -describe('prepare_tests', function() { - before(function() { - return new Promise(function (resolve) { - $.ajax({ - url: "/base/www/index.html", - cache: true, - type: "GET" - }).done(function (index) { - var body = index.match(/([.\s\S]*)<\/body>/)[1]; - $("body").prepend(body); - resolve(); - }); - } ); - }) +/* eslint-disable */ + +before(function () { + return new Promise(function (resolve) { + $.ajax({ + url: "/base/www/index.html", + cache: true, + type: "GET" + }).done(function (index) { + var body = index.match(/([.\s\S]*)<\/body>/)[1]; + $("body").prepend(body); + resolve(); + }); + }); }); From a2b21be0d2faa9e673b74ade727e8a9c4112f93d Mon Sep 17 00:00:00 2001 From: Samer Albahra Date: Thu, 28 Nov 2024 09:26:55 -0500 Subject: [PATCH 07/14] Fix timezone issue in unit test --- test/tests.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/tests.js b/test/tests.js index 25435be7..76ffbbe5 100644 --- a/test/tests.js +++ b/test/tests.js @@ -163,8 +163,8 @@ describe("General Function Checks", function () { }); it("OSApp.Dates.getDayName(day,type) should return the day of the week and can be of type 'short'", function () { - assert.equal("Sunday", OSApp.Dates.getDayName(new Date(1410745528126))); - assert.equal("Thu", OSApp.Dates.getDayName(new Date(1410445528126), "short")); + assert.equal("Monday", OSApp.Dates.getDayName(new Date(Date.UTC(2014, 8, 15, 12, 45, 28)))); + assert.equal("Thu", OSApp.Dates.getDayName(new Date(Date.UTC(2014, 8, 11, 12, 45, 28)), "short")); }); it("OSApp.Utils.pad(number) should successfully prepend a 0 to a single digit", function () { From aa2a212fbc36d4cbe577fded28c36188de3b72df Mon Sep 17 00:00:00 2001 From: Samer Albahra Date: Thu, 28 Nov 2024 09:32:18 -0500 Subject: [PATCH 08/14] Fix many unit tests --- test/tests.js | 170 +++++++++++++++++++++++++------------------------- 1 file changed, 85 insertions(+), 85 deletions(-) diff --git a/test/tests.js b/test/tests.js index 76ffbbe5..d444c940 100644 --- a/test/tests.js +++ b/test/tests.js @@ -187,94 +187,94 @@ describe("General Function Checks", function () { }); describe("Page Navigation Checks", function () { - // before(function () { - // OSApp.currentSession.ip = "demo.opensprinkler.com"; - // OSApp.currentSession.pass = "opendoor"; - // OSApp.currentSession.prefix = "https://"; - // OSApp.currentSession.fw183 = false; + before(function () { + OSApp.currentSession.ip = "demo.opensprinkler.com"; + OSApp.currentSession.pass = "opendoor"; + OSApp.currentSession.prefix = "https://"; + OSApp.currentSession.fw183 = false; - // OSApp.Sites.updateSiteList(["Test"], "Test"); - // }); - - // it("Start jQuery Mobile Page Initialization", function (done) { - // $.mobile.document.one("pageshow", "#sprinklers", function () { - // done(); - // }); - - // OSApp.Sites.newLoad(); - // }); - - // it( "Change page to program preview", function( done ) { - // $.mobile.document.one( "pageshow", "#preview", function() { - // done(); - // } ); - // assert.doesNotThrow( function() { - // OSApp.UIDom.changePage( "#preview" ); - // } ); - // } ); - - // it( "Change to logs page", function( done ) { - // $.mobile.document.one( "pageshow", "#logs", function() { - // done(); - // } ); - // assert.doesNotThrow( function() { - // OSApp.UIDom.changePage( "#logs" ); - // } ); - // } ); - - // it( "Change to runonce page", function( done ) { - // $.mobile.document.one( "pageshow", "#runonce", function() { - // done(); - // } ); - // assert.doesNotThrow( function() { - // OSApp.UIDom.changePage( "#runonce" ); - // } ); - // } ); - - // it( "Change to edit programs page", function( done ) { - // $.mobile.document.one( "pageshow", "#programs", function() { - // done(); - // } ); - // assert.doesNotThrow( function() { - // OSApp.UIDom.changePage( "#programs" ); - // } ); - // } ); - - // it( "Change to add new program page", function( done ) { - // $.mobile.document.one( "pageshow", "#addprogram", function() { - // done(); - // } ); - // assert.doesNotThrow( function() { - // OSApp.UIDom.changePage( "#addprogram" ); - // } ); - // } ); + OSApp.Sites.updateSiteList(["Test"], "Test"); + }); - // it( "Change to options page", function( done ) { - // $.mobile.document.one( "pageshow", "#os-options", function() { - // done(); - // } ); - // assert.doesNotThrow( function() { - // OSApp.UIDom.changePage( "#os-options" ); - // } ); - // } ); + it("Start jQuery Mobile Page Initialization", function (done) { + $.mobile.document.one("pageshow", "#sprinklers", function () { + done(); + }); - // it( "Change to site manager page", function( done ) { - // $.mobile.document.one( "pageshow", "#site-control", function() { - // done(); - // } ); - // assert.doesNotThrow( function() { - // OSApp.UIDom.changePage( "#site-control" ); - // } ); - // } ); + OSApp.Sites.newLoad(); + }); - // it( "Change to about page", function( done ) { - // $.mobile.document.one( "pageshow", "#about", function() { - // done(); - // } ); - // assert.doesNotThrow( function() { - // OSApp.UIDom.changePage( "#about" ); - // } ); - // } ); + it( "Change page to program preview", function( done ) { + $.mobile.document.one( "pageshow", "#preview", function() { + done(); + } ); + assert.doesNotThrow( function() { + OSApp.UIDom.changePage( "#preview" ); + } ); + } ); + + it( "Change to logs page", function( done ) { + $.mobile.document.one( "pageshow", "#logs", function() { + done(); + } ); + assert.doesNotThrow( function() { + OSApp.UIDom.changePage( "#logs" ); + } ); + } ); + + it( "Change to runonce page", function( done ) { + $.mobile.document.one( "pageshow", "#runonce", function() { + done(); + } ); + assert.doesNotThrow( function() { + OSApp.UIDom.changePage( "#runonce" ); + } ); + } ); + + it( "Change to edit programs page", function( done ) { + $.mobile.document.one( "pageshow", "#programs", function() { + done(); + } ); + assert.doesNotThrow( function() { + OSApp.UIDom.changePage( "#programs" ); + } ); + } ); + + it( "Change to add new program page", function( done ) { + $.mobile.document.one( "pageshow", "#addprogram", function() { + done(); + } ); + assert.doesNotThrow( function() { + OSApp.UIDom.changePage( "#addprogram" ); + } ); + } ); + + it( "Change to options page", function( done ) { + $.mobile.document.one( "pageshow", "#os-options", function() { + done(); + } ); + assert.doesNotThrow( function() { + OSApp.UIDom.changePage( "#os-options" ); + } ); + } ); + + it( "Change to site manager page", function( done ) { + $.mobile.document.one( "pageshow", "#site-control", function() { + done(); + } ); + assert.doesNotThrow( function() { + OSApp.UIDom.changePage( "#site-control" ); + } ); + } ); + + it( "Change to about page", function( done ) { + $.mobile.document.one( "pageshow", "#about", function() { + done(); + } ); + assert.doesNotThrow( function() { + OSApp.UIDom.changePage( "#about" ); + } ); + } ); }); describe("Popup Checks", function () { @@ -382,7 +382,7 @@ describe("Logout / Clean up", function () { $.mobile.document.one("pageshow", "#start", function () { done(); }); - OSApp.currentSession.currIp = ""; + OSApp.currentSession.ip = ""; OSApp.UIDom.changePage("#start"); }); }); From f296477b28414d94490a498fd35070075432962f Mon Sep 17 00:00:00 2001 From: Samer Albahra Date: Thu, 28 Nov 2024 09:38:13 -0500 Subject: [PATCH 09/14] Restore all unit tests to working order --- test/tests.js | 41 +++++---- www/js/modules/ui-dom.js | 186 +++++++++++++++++++-------------------- 2 files changed, 113 insertions(+), 114 deletions(-) diff --git a/test/tests.js b/test/tests.js index d444c940..e62e054f 100644 --- a/test/tests.js +++ b/test/tests.js @@ -279,27 +279,26 @@ describe("Page Navigation Checks", function () { describe("Popup Checks", function () { - // 20241121 commented by mellodev (refactor how showHomeMenu works) - // it( "Show main menu popup", function( done ) { - // $.mobile.document.one( "popupafteropen", "#mainMenu", function() { - // done(); - // } ); - // assert.doesNotThrow( function() { - // OSApp.UIDom.showHomeMenu(); - // } ); - // } ); - - // it( "Show change rain delay popup", function( done ) { - // $.mobile.document.one( "popupafteropen", "#durationBox", function() { - // $.mobile.document.one( "popupafterclose", "#durationBox", function() { - // done(); - // } ); - // $( "#durationBox" ).popup( "close" ).remove(); - // } ); - // assert.doesNotThrow( function() { - // $( "#mainMenu" ).find( "a[href='#raindelay']" ).trigger( "click" ); - // } ); - // } ); + it( "Show main menu popup", function( done ) { + $.mobile.document.one( "popupafteropen", "#mainMenu", function() { + done(); + } ); + assert.doesNotThrow( function() { + OSApp.UIDom.showHomeMenu(); + } ); + } ); + + it( "Show change rain delay popup", function( done ) { + $.mobile.document.one( "popupafteropen", "#durationBox", function() { + $.mobile.document.one( "popupafterclose", "#durationBox", function() { + done(); + } ); + $( "#durationBox" ).popup( "close" ).remove(); + } ); + assert.doesNotThrow( function() { + $( "#mainMenu" ).find( "a[href='#raindelay']" ).trigger( "click" ); + } ); + } ); it("Show add new site popup", function (done) { $.mobile.document.one("popupafteropen", "#addnew", function () { diff --git a/www/js/modules/ui-dom.js b/www/js/modules/ui-dom.js index b27188d7..c204a569 100644 --- a/www/js/modules/ui-dom.js +++ b/www/js/modules/ui-dom.js @@ -3863,6 +3863,97 @@ OSApp.UIDom.launchApp = function() { }; +// FIXME: This needs to be rewritten and refactored out to OSApp.Sites.showSites so it works properly (mellodev) +OSApp.UIDom.showHomeMenu = ( function() { + var page, id, showHidden, popup; + + function makeMenu() { + page = $( ".ui-page-active" ); + id = page.attr( "id" ); + showHidden = page.hasClass( "show-hidden" ); + popup = $( "" ); + } + + function begin( btn ) { + btn = btn instanceof $ ? btn : $( btn ); + + $( ".ui-popup-active" ).find( "[data-role='popup']" ).popup( "close" ); + + makeMenu(); + + popup.on( "click", "a", function() { + var clicked = $( this ), + href = clicked.attr( "href" ); + + popup.popup( "close" ); + + if ( href === "#stop-all" ) { + OSApp.Stations.stopAllStations(); + } else if ( href === "#show-hidden" ) { + if ( showHidden ) { + $( ".station-hidden" ).hide(); + page.removeClass( "show-hidden" ); + } else { + $( ".station-hidden" ).show(); + page.addClass( "show-hidden" ); + } + } else if ( href === "#raindelay" ) { + OSApp.Weather.showRainDelay(); + } else if ( href === "#globalpause" ) { + OSApp.UIDom.showPause(); + } else { + OSApp.UIDom.checkChanges( function() { + OSApp.UIDom.changePage( href ); + } ); + } + + return false; + } ); + + $( "#mainMenu" ).remove(); + + popup.one( "popupafterclose", function() { + btn.show(); + } ); + + OSApp.UIDom.openPopup( popup, { positionTo: btn } ); + + btn.hide(); + } + + return begin; +} )(); + OSApp.UIDom.initAppData = function() { //Update the language on the page using the browser's locale @@ -3961,97 +4052,6 @@ OSApp.UIDom.initAppData = function() { } } ); - // FIXME: This needs to be rewritten and refactored out to OSApp.Sites.showSites so it works properly (mellodev) - var showHomeMenu = ( function() { - var page, id, showHidden, popup; - - function makeMenu() { - page = $( ".ui-page-active" ); - id = page.attr( "id" ); - showHidden = page.hasClass( "show-hidden" ); - popup = $( "" ); - } - - function begin( btn ) { - btn = btn instanceof $ ? btn : $( btn ); - - $( ".ui-popup-active" ).find( "[data-role='popup']" ).popup( "close" ); - - makeMenu(); - - popup.on( "click", "a", function() { - var clicked = $( this ), - href = clicked.attr( "href" ); - - popup.popup( "close" ); - - if ( href === "#stop-all" ) { - OSApp.Stations.stopAllStations(); - } else if ( href === "#show-hidden" ) { - if ( showHidden ) { - $( ".station-hidden" ).hide(); - page.removeClass( "show-hidden" ); - } else { - $( ".station-hidden" ).show(); - page.addClass( "show-hidden" ); - } - } else if ( href === "#raindelay" ) { - OSApp.Weather.showRainDelay(); - } else if ( href === "#globalpause" ) { - OSApp.UIDom.showPause(); - } else { - OSApp.UIDom.checkChanges( function() { - OSApp.UIDom.changePage( href ); - } ); - } - - return false; - } ); - - $( "#mainMenu" ).remove(); - - popup.one( "popupafterclose", function() { - btn.show(); - } ); - - OSApp.UIDom.openPopup( popup, { positionTo: btn } ); - - btn.hide(); - } - - return begin; - } )(); - // Extend collapsible widget with event before change $.widget( "mobile.collapsible", $.mobile.collapsible, { _handleExpandCollapse: function( isCollapse ) { @@ -4068,7 +4068,7 @@ OSApp.UIDom.initAppData = function() { // Bind footer menu button $( "#footer-menu" ).on( "click", function() { - showHomeMenu( this ); + OSApp.UIDom.showHomeMenu( this ); } ); // Initialize the app header @@ -4097,7 +4097,7 @@ OSApp.UIDom.initAppData = function() { if ( menu.length > 0 ) { $( "#mainMenu" ).popup( "close" ); } else { - showHomeMenu(); + OSApp.UIDom.showHomeMenu(); } } else if ( ( menuOpen || altDown ) && code === 80 ) { // P e.preventDefault(); From 1036bfd104c6b89e40789a82a61bea83c04a3cc6 Mon Sep 17 00:00:00 2001 From: Samer Albahra Date: Thu, 28 Nov 2024 10:04:23 -0500 Subject: [PATCH 10/14] Switch to local firmware demo --- .github/workflows/test.yml | 1 + Gruntfile.js | 9 --------- README.md | 11 ----------- test/tests.js | 4 ++-- 4 files changed, 3 insertions(+), 22 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 16b1c76e..4bbfe976 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,4 +31,5 @@ jobs: - name: Run test steps run: | grunt + ./test/launch_osdemo.sh start npm run test diff --git a/Gruntfile.js b/Gruntfile.js index 48212c99..d99133c2 100755 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -91,15 +91,6 @@ module.exports = function( grunt ) { "git diff-index --quiet HEAD || git commit -m 'Localization: Update languages from Transifex'", "git push" ].join( "&&" ) - }, - startDemo: { - command: "test/launch_osdemo.sh start" - }, - stopDemo: { - command: [ - "test/launch_osdemo.sh stop", - "rm -r build/firmware/unified" - ].join( "&&" ) } } } ); diff --git a/README.md b/README.md index fba73c12..aeb956a3 100644 --- a/README.md +++ b/README.md @@ -117,23 +117,12 @@ This project uses Grunt to automate various development tasks. Here are some of * **`grunt eslint`**: Checks JavaScript code for potential errors and style issues. * **`grunt csslint`**: Analyzes CSS code for potential errors and style issues. -* **`grunt blanket_mocha`**: Runs tests using Mocha and Blanket.js to generate code coverage reports. **Building and Deployment** * **`grunt compress:makeFW`**: Creates a ZIP archive of the application files for firmware updates. -* **`grunt shell:updateUI`**: Updates the UI on the OpenSprinkler device by transferring the ZIP archive. -* **`grunt shell:updateBetaUI`**: Updates the UI on a beta OpenSprinkler device. **Localization** * **`grunt shell:pushEng`**: Extracts English strings for translation, pushes them to Transifex, and updates the English PO file. * **`grunt shell:updateLang`**: Pulls translations from Transifex and updates the language files. - -**Other** - -* **`grunt shell:startDemo`**: Starts a demo instance of the OpenSprinkler app. -* **`grunt shell:stopDemo`**: Stops the demo instance. -* **`grunt bump`**: Bumps the version number in various files (source code, Cordova config, and package.json) and push commit -* **`grunt bump-version`**: Bumps the version number in various files (source code, Cordova config, and package.json). Does not commit or push! - diff --git a/test/tests.js b/test/tests.js index e62e054f..4c783c35 100644 --- a/test/tests.js +++ b/test/tests.js @@ -22,7 +22,7 @@ describe("Initial Definition Check", function () { "testkey": "helloworld", "sites": JSON.stringify({ "Test": { - "os_ip": "demo.opensprinkler.com", + "os_ip": "127.0.0.1:8080", "os_pw": "opendoor" } }), @@ -188,7 +188,7 @@ describe("General Function Checks", function () { describe("Page Navigation Checks", function () { before(function () { - OSApp.currentSession.ip = "demo.opensprinkler.com"; + OSApp.currentSession.ip = "127.0.0.1:8080"; OSApp.currentSession.pass = "opendoor"; OSApp.currentSession.prefix = "https://"; OSApp.currentSession.fw183 = false; From 59a2750e5793b4ea6eefad0646e16d717a39ce5d Mon Sep 17 00:00:00 2001 From: Samer Albahra Date: Thu, 28 Nov 2024 10:07:05 -0500 Subject: [PATCH 11/14] Attempt fix for launch script --- test/launch_osdemo.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/test/launch_osdemo.sh b/test/launch_osdemo.sh index 0e7c6ff5..21477f59 100755 --- a/test/launch_osdemo.sh +++ b/test/launch_osdemo.sh @@ -1,5 +1,6 @@ #!/bin/bash +mkdir -p build/firmware cd build/firmware if [ $1 == "start" ]; then From 10f176bb380e0ca4232da76a4db28c447d02d8c8 Mon Sep 17 00:00:00 2001 From: Samer Albahra Date: Thu, 28 Nov 2024 10:11:18 -0500 Subject: [PATCH 12/14] Another attempt --- test/tests.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/tests.js b/test/tests.js index 4c783c35..e5a86692 100644 --- a/test/tests.js +++ b/test/tests.js @@ -190,7 +190,7 @@ describe("Page Navigation Checks", function () { before(function () { OSApp.currentSession.ip = "127.0.0.1:8080"; OSApp.currentSession.pass = "opendoor"; - OSApp.currentSession.prefix = "https://"; + OSApp.currentSession.prefix = "http://"; OSApp.currentSession.fw183 = false; OSApp.Sites.updateSiteList(["Test"], "Test"); From 93d79d319fa2ae59f2e807f7820d515bc8ac1ac8 Mon Sep 17 00:00:00 2001 From: Samer Albahra Date: Thu, 28 Nov 2024 10:29:51 -0500 Subject: [PATCH 13/14] Attempt to mock firmware for unit testing --- .github/workflows/test.yml | 1 - package-lock.json | 127 +++++++++++++++++++++++++++++++++++++ package.json | 1 + test/karma.conf.js | 1 + test/launch_osdemo.sh | 19 ------ test/tests.js | 61 +++++++++++++++++- 6 files changed, 188 insertions(+), 22 deletions(-) delete mode 100755 test/launch_osdemo.sh diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4bbfe976..16b1c76e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,5 +31,4 @@ jobs: - name: Run test steps run: | grunt - ./test/launch_osdemo.sh start npm run test diff --git a/package-lock.json b/package-lock.json index b4f38fa8..984afc76 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,6 +37,7 @@ "lint-staged": "^15.2.10", "mocha": "^10.8.2", "po2json": "^0.4.5", + "sinon": "^19.0.2", "sort-package-json": "^2.10.1" } }, @@ -1234,6 +1235,50 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/commons/node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "13.0.5", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", + "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.1" + } + }, + "node_modules/@sinonjs/samsam": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.2.tgz", + "integrity": "sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.1", + "lodash.get": "^4.4.2", + "type-detect": "^4.1.0" + } + }, + "node_modules/@sinonjs/text-encoding": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz", + "integrity": "sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==", + "dev": true + }, "node_modules/@socket.io/component-emitter": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", @@ -8002,6 +8047,12 @@ "integrity": "sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw==", "dev": true }, + "node_modules/just-extend": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", + "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", + "dev": true + }, "node_modules/karma": { "version": "6.4.4", "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.4.tgz", @@ -8566,6 +8617,12 @@ "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", "dev": true }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "dev": true + }, "node_modules/lodash.isdate": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/lodash.isdate/-/lodash.isdate-4.0.1.tgz", @@ -9544,6 +9601,28 @@ "node": ">= 0.6" } }, + "node_modules/nise": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/nise/-/nise-6.1.1.tgz", + "integrity": "sha512-aMSAzLVY7LyeM60gvBS423nBmIPP+Wy7St7hsb+8/fc1HmeoHJfLO8CKse4u3BtOZvQLJghYPI2i/1WZrEj5/g==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.1", + "@sinonjs/fake-timers": "^13.0.1", + "@sinonjs/text-encoding": "^0.7.3", + "just-extend": "^6.2.0", + "path-to-regexp": "^8.1.0" + } + }, + "node_modules/nise/node_modules/path-to-regexp": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", + "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, "node_modules/node-gyp": { "version": "9.4.0", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.0.tgz", @@ -11682,6 +11761,54 @@ "node": ">= 5.10.0" } }, + "node_modules/sinon": { + "version": "19.0.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-19.0.2.tgz", + "integrity": "sha512-euuToqM+PjO4UgXeLETsfQiuoyPXlqFezr6YZDFwHR3t4qaX0fZUe1MfPMznTL5f8BWrVS89KduLdMUsxFCO6g==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.1", + "@sinonjs/fake-timers": "^13.0.2", + "@sinonjs/samsam": "^8.0.1", + "diff": "^7.0.0", + "nise": "^6.1.1", + "supports-color": "^7.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, + "node_modules/sinon/node_modules/diff": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/sinon/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/sinon/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", diff --git a/package.json b/package.json index 246d7129..4771ee5f 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "lint-staged": "^15.2.10", "mocha": "^10.8.2", "po2json": "^0.4.5", + "sinon": "^19.0.2", "sort-package-json": "^2.10.1" }, "cordova": { diff --git a/test/karma.conf.js b/test/karma.conf.js index ea7a0306..d953ad67 100644 --- a/test/karma.conf.js +++ b/test/karma.conf.js @@ -18,6 +18,7 @@ module.exports = function (config) { { pattern: 'www/css/images/ajax-loader.gif', included: false, watched: false, served: true }, { pattern: 'www/js/modules/*.js', included: true, watched: false }, { pattern: 'www/js/main.js', included: true, watched: false }, + 'node_modules/sinon/pkg/sinon.js', 'test/tests.js' ], browsers: ['ChromeHeadless'], diff --git a/test/launch_osdemo.sh b/test/launch_osdemo.sh deleted file mode 100755 index 21477f59..00000000 --- a/test/launch_osdemo.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -mkdir -p build/firmware -cd build/firmware - -if [ $1 == "start" ]; then - if [ ! -d "unified" ]; then - git clone https://github.com/OpenSprinkler/OpenSprinkler-Firmware unified - fi - cd unified - sudo ./build.sh demo - ./OpenSprinkler >/dev/null 2>&1 & - echo $! > pid - sleep 5 -else - kill -9 `cat unified/pid` - rm unified/pid - sleep 5 -fi diff --git a/test/tests.js b/test/tests.js index e5a86692..40bc3df0 100644 --- a/test/tests.js +++ b/test/tests.js @@ -14,6 +14,63 @@ */ var assert = chai.assert; +var server; + +before(function() { + server = sinon.fakeServer.create(); + server.autoRespond = true; + + // Mock responses using a function to handle requests + server.respondWith(function(request) { + var url = request.url; + var baseUrl = 'https://demo.opensprinkler.com'; + var urlObj = new URL(url, baseUrl); + var pathname = urlObj.pathname; + var params = new URLSearchParams(urlObj.search); + + if (pathname === '/jp') { + request.respond(200, { "Content-Type": "application/json" }, + '{"nprogs":0,"nboards":1,"mnp":40,"mnst":4,"pnsize":32,"pd":[]}' + ); + } else if (pathname === '/jn') { + request.respond(200, { "Content-Type": "application/json" }, + '{"masop":[255],"masop2":[0],"ignore_rain":[0],"ignore_sn1":[0],"ignore_sn2":[0],"stn_dis":[0],"stn_spe":[0],"stn_grp":[0,0,0,0,0,0,0,0],"snames":["S01","S02","S03","S04","S05","S06","S07","S08"],"maxlen":32}' + ); + } else if (pathname === '/jo') { + request.respond(200, { "Content-Type": "application/json" }, + '{"fwv":221,"tz":28,"hp0":144,"hp1":31,"hwv":255,"ext":0,"sdt":0,"mas":0,"mton":0,"mtof":0,"wl":100,"den":1,"ipas":0,"devid":0,"uwt":0,"ntp1":0,"ntp2":0,"ntp3":0,"ntp4":0,"lg":1,"mas2":0,"mton2":0,"mtof2":0,"fwm":0,"fpr0":100,"fpr1":0,"re":0,"sar":0,"ife":0,"sn1t":0,"sn1o":1,"sn2t":0,"sn2o":1,"sn1on":0,"sn1of":0,"sn2on":0,"sn2of":0,"resv1":0,"resv2":0,"resv3":0,"resv4":0,"resv5":0,"resv6":0,"resv7":0,"resv8":0,"wimod":169,"reset":0,"dexp":-1,"mexp":24,"hwt":255,"ms":[0,0,0,0,0,0]}' + ); + } else if (pathname === '/js') { + request.respond(200, { "Content-Type": "application/json" }, + '{"sn":[0,0,0,0,0,0,0,0],"nstations":8}' + ); + } else if (pathname === '/jc') { + request.respond(200, { "Content-Type": "application/json" }, + '{"devt":1732789106,"nbrd":1,"en":1,"sn1":0,"sn2":0,"rd":0,"rdst":0,"sunrise":412,"sunset":975,"eip":2728304343,"lwc":1732784441,"lswc":1732784441,"lupt":0,"lrbtc":1,"lrun":[0,0,0,0],"pq":0,"pt":0,"nq":0,"otc":{},"otcs":0,"mac":"02:42:AC:12:00:02","loc":"42.36,-71.06","jsp":"https://ui.opensprinkler.com/js","wsp":"weather.opensprinkler.com","wto":{},"ifkey":"","mqtt":{},"wtdata":{"wp":"Manual"},"wterr":0,"dname":"My OpenSprinkler","email":{},"sbits":[0,0],"ps":[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]],"gpio":[]}' + ); + } else if (pathname === '/jl') { + // Handle dynamic URLs with start and end query parameters + var type = params.get('type'); + var response; + if (type === 'wl') { + response = `[[0,"wl",100,1732158027],[0,"wl",100,1732179641],[0,"wl",100,1732201255],[0,"wl",100,1732222812],[0,"wl",100,1732244426],[0,"wl",100,1732266040],[0,"wl",100,1732287654],[0,"wl",100,1732309212],[0,"wl",100,1732330826],[0,"wl",100,1732352440],[0,"wl",100,1732374054],[0,"wl",100,1732395613],[0,"wl",100,1732417227],[0,"wl",100,1732438841],[0,"wl",100,1732460455],[0,"wl",100,1732482013],[0,"wl",100,1732503627],[0,"wl",100,1732525241],[0,"wl",100,1732546855],[0,"wl",100,1732568414],[0,"wl",100,1732590028],[0,"wl",100,1732611642],[0,"wl",100,1732633256],[0,"wl",100,1732639575],[0,"wl",100,1732654813],[0,"wl",100,1732676427],[0,"wl",100,1732698041],[0,"wl",100,1732719655],[0,"wl",100,1732741213],[0,"wl",100,1732762827],[0,"wl",100,1732784441]]`; + } else if (type === 'fl') { + response = '[]'; + } else { + response = `[[99,0,64,1732207586],[99,0,64,1732505562],[1,0,60,1732514461],[1,1,60,1732514521]]`; + } + request.respond(200, { "Content-Type": "application/json" }, response); + } else { + request.respond(404, { "Content-Type": "application/json" }, '{"error": "Not Found"}'); + } + }); +}); + +after(function() { + if (server) { + server.restore(); + } +}); describe("Initial Definition Check", function () { it("storage.set(object,callback) should accept an object of key/value pairs to be set into localStorage and respond with callback", function (done) { @@ -188,9 +245,9 @@ describe("General Function Checks", function () { describe("Page Navigation Checks", function () { before(function () { - OSApp.currentSession.ip = "127.0.0.1:8080"; + OSApp.currentSession.ip = "demo.opensprinkler.com"; OSApp.currentSession.pass = "opendoor"; - OSApp.currentSession.prefix = "http://"; + OSApp.currentSession.prefix = "https://"; OSApp.currentSession.fw183 = false; OSApp.Sites.updateSiteList(["Test"], "Test"); From 509c403d6955f953e60ffb220dcf88f54a979621 Mon Sep 17 00:00:00 2001 From: Samer Albahra Date: Thu, 28 Nov 2024 10:32:37 -0500 Subject: [PATCH 14/14] Rename job for unit testing --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 16b1c76e..0b41bcb6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ on: branches: [ "master" ] jobs: - build: + validate_tests: runs-on: ubuntu-latest steps: