From c604150a261b498184dce166ec5b5ade6f1f3b46 Mon Sep 17 00:00:00 2001 From: Brian Pietravalle Date: Tue, 12 Apr 2016 15:13:51 -0400 Subject: [PATCH 01/29] added method to src,mocks, and respective tests (#1218) --- src/mocks/toast.js | 9 +++++++++ src/plugins/toast.js | 10 ++++++++++ test/mocks/toast.spec.js | 1 + test/plugins/toast.spec.js | 1 + 4 files changed, 21 insertions(+) diff --git a/src/mocks/toast.js b/src/mocks/toast.js index 1bb99818..87ddab7c 100644 --- a/src/mocks/toast.js +++ b/src/mocks/toast.js @@ -77,6 +77,15 @@ ngCordovaMocks.factory('$cordovaToast', ['$q', function ($q) { } return defer.promise; }, + showWithOptions: function (options) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error showing the toast.'); + } else { + defer.resolve(); + } + return defer.promise; + }, show: function (message, duration, position) { var defer = $q.defer(); if (this.throwsError) { diff --git a/src/plugins/toast.js b/src/plugins/toast.js index 7be9358f..b082134c 100644 --- a/src/plugins/toast.js +++ b/src/plugins/toast.js @@ -66,6 +66,16 @@ angular.module('ngCordova.plugins.toast', []) return q.promise; }, + showWithOptions: function (options) { + var q = $q.defer(); + $window.plugins.toast.showWithOptions(options, function (response) { + q.resolve(response); + }, function (error) { + q.reject(error); + }); + return q.promise; + }, + show: function (message, duration, position) { var q = $q.defer(); $window.plugins.toast.show(message, duration, position, function (response) { diff --git a/test/mocks/toast.spec.js b/test/mocks/toast.spec.js index ef4f369a..6e645b69 100644 --- a/test/mocks/toast.spec.js +++ b/test/mocks/toast.spec.js @@ -15,6 +15,7 @@ describe('ngCordovaMocks', function () { 'showLongTop', 'showLongCenter', 'showLongBottom', + 'showWithOptions', 'show' ]; diff --git a/test/plugins/toast.spec.js b/test/plugins/toast.spec.js index 464d834a..430affcf 100644 --- a/test/plugins/toast.spec.js +++ b/test/plugins/toast.spec.js @@ -8,6 +8,7 @@ describe('Service: $cordovaToast', function() { 'showShortBottom', 'showLongTop', 'showLongCenter', + 'showWithOptions', 'showLongBottom' ]; From 82e60c808c370c30991dd40090cf369ca459ad3a Mon Sep 17 00:00:00 2001 From: Markus Scholtysik Date: Tue, 12 Apr 2016 21:14:08 +0200 Subject: [PATCH 02/29] update localNotification.ctrl.js (#1213) i think, to be able to calculate "_60_seconds_from_now", the "now" value has to be a number, so I added the "getTime()" method --- demo/www/app/localNotification/localNotification.ctrl.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/www/app/localNotification/localNotification.ctrl.js b/demo/www/app/localNotification/localNotification.ctrl.js index 5a6d7213..ad971a91 100644 --- a/demo/www/app/localNotification/localNotification.ctrl.js +++ b/demo/www/app/localNotification/localNotification.ctrl.js @@ -3,7 +3,7 @@ angular.module('demo.localNotification.ctrl', []) .controller('LocalNotificationCtrl', function ($scope, $rootScope, $cordovaLocalNotification) { $scope.addNotification = function () { - var now = new Date(); + var now = new Date().getTime(); var _60_seconds_from_now = new Date(now + 60 * 1000); var event = { id: 1, From 2afc1477b00a8b5fccd365c6afd0257947a1a8b1 Mon Sep 17 00:00:00 2001 From: Phil McCloghry-Laing Date: Wed, 13 Apr 2016 05:14:36 +1000 Subject: [PATCH 03/29] $cordovaAppRate sets callbacks correctly (onButtonClicked, onRateDialogShow) (#1209) --- src/plugins/appRate.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/plugins/appRate.js b/src/plugins/appRate.js index cf928386..b649f445 100644 --- a/src/plugins/appRate.js +++ b/src/plugins/appRate.js @@ -43,6 +43,7 @@ angular.module('ngCordova.plugins.appRate', []) * * @param {Object} customObj * @param {string} customObj.title + * @param {string} customObj.message * @param {string} customObj.cancelButtonLabel * @param {string} customObj.laterButtonLabel * @param {string} customObj.rateButtonLabel @@ -80,13 +81,11 @@ angular.module('ngCordova.plugins.appRate', []) }, onButtonClicked: function (cb) { - AppRate.onButtonClicked = function (buttonIndex) { - cb.call(this, buttonIndex); - }; + AppRate.preferences.callbacks.onButtonClicked = cb.bind(this); }, onRateDialogShow: function (cb) { - AppRate.onRateDialogShow = cb(); + AppRate.preferences.callbacks.onRateDialogShow = cb.bind(this); } }; }]; From 3ce1f6149a63edba6c3ca0ec1e74397b8df62802 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nikola=20Ple=C5=A1a?= Date: Thu, 14 Apr 2016 17:35:27 +0200 Subject: [PATCH 04/29] Wrapper for 3d touch plugin (#1155) * Add wrapper for 3d plugin * Fixed JSHint warnings for undefined variable --- src/plugins/3dtouch.js | 147 +++++++++++++++++++++++++++++++++++++++++ src/plugins/module.js | 1 + 2 files changed, 148 insertions(+) create mode 100644 src/plugins/3dtouch.js diff --git a/src/plugins/3dtouch.js b/src/plugins/3dtouch.js new file mode 100644 index 00000000..9313569f --- /dev/null +++ b/src/plugins/3dtouch.js @@ -0,0 +1,147 @@ +// install : cordova plugin add https://github.com/EddyVerbruggen/cordova-plugin-3dtouch.git +// link : https://github.com/EddyVerbruggen/cordova-plugin-3dtouch + +angular.module('ngCordova.plugins.3dtouch', []) + + .factory('$cordova3DTouch', ['$q', function($q) { + var quickActions = []; + var quickActionHandler = {}; + + var createQuickActionHandler = function(quickActionHandler) { + return function (payload) { + for (var key in quickActionHandler) { + if (payload.type === key) { + quickActionHandler[key](); + } + } + }; + }; + + return { + /* + * Checks if Cordova 3D touch is present and loaded + * + * @return promise + */ + isAvailable: function () { + var deferred = $q.defer(); + if (!window.cordova) { + deferred.reject('Not supported in browser'); + } else { + if (!window.ThreeDeeTouch) { + deferred.reject('Could not find 3D touch plugin'); + } else { + window.ThreeDeeTouch.isAvailable(function (value) { + deferred.resolve(value); + }, function (err) { + deferred.reject(err); + }); + } + } + + return deferred.promise; + }, + + /* + * Add a quick action to menu + * + * @param string type + * @param string title + * @param string iconType (optional) + * @param string subtitle (optional) + * @param function callback (optional) + * @return promise + */ + addQuickAction: function(type, title, iconType, iconTemplate, subtitle, callback) { + var deferred = $q.defer(); + + var quickAction = { + type: type, + title: title, + subtitle: subtitle + }; + + if (iconType) { + quickAction.iconType = iconType; + } + + if (iconTemplate) { + quickAction.iconTemplate = iconTemplate; + } + + this.isAvailable().then(function() { + quickActions.push(quickAction); + quickActionHandler[type] = callback; + window.ThreeDeeTouch.configureQuickActions(quickActions); + window.ThreeDeeTouch.onHomeIconPressed = createQuickActionHandler(quickActionHandler); + deferred.resolve(quickActions); + }, + function(err) { + deferred.reject(err); + }); + + return deferred.promise; + }, + + /* + * Add a quick action handler. Used for static quick actions + * + * @param string type + * @param function callback + * @return promise + */ + addQuickActionHandler: function(type, callback) { + var deferred = $q.defer(); + + this.isAvailable().then(function() { + quickActionHandler[type] = callback; + window.ThreeDeeTouch.onHomeIconPressed = createQuickActionHandler(quickActionHandler); + deferred.resolve(true); + }, + function(err) { + deferred.reject(err); + }); + + return deferred.promise; + }, + + /* + * Enable link preview popup when force touch is appled to link elements + * + * @return bool + */ + enableLinkPreview: function() { + var deferred = $q.defer(); + + this.isAvailable().then(function() { + window.ThreeDeeTouch.enableLinkPreview(); + deferred.resolve(true); + }, + function(err) { + deferred.reject(err); + }); + + return deferred.promise; + }, + + /* + * Add a hanlder function for force touch events, + * + * @param function callback + * @return promise + */ + addForceTouchHandler: function(callback) { + var deferred = $q.defer(); + + this.isAvailable().then(function() { + window.ThreeDeeTouch.watchForceTouches(callback); + deferred.resolve(true); + }, + function(err) { + deferred.reject(err); + }); + + return deferred.promise; + } + }; + }]); diff --git a/src/plugins/module.js b/src/plugins/module.js index 26a2147c..829e90fe 100644 --- a/src/plugins/module.js +++ b/src/plugins/module.js @@ -1,4 +1,5 @@ angular.module('ngCordova.plugins', [ + 'ngCordova.plugins.3dtouch', 'ngCordova.plugins.actionSheet', 'ngCordova.plugins.adMob', 'ngCordova.plugins.appAvailability', From b4356c09ae937b9890477ccb8b94faaf260f551d Mon Sep 17 00:00:00 2001 From: Allen Conquest Date: Sun, 17 Apr 2016 21:47:25 +0100 Subject: [PATCH 05/29] added iosOptions to $cordovaSpinnerDialog.show() (#1224) * added iosOptions to $cordovaSpinnerDialog.show() * added missing comma * added additional test for options in spinnerDialog.show() method --- src/plugins/spinnerDialog.js | 4 ++-- test/plugins/spinnerDialog.spec.js | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/plugins/spinnerDialog.js b/src/plugins/spinnerDialog.js index a6934889..7c607b25 100644 --- a/src/plugins/spinnerDialog.js +++ b/src/plugins/spinnerDialog.js @@ -6,9 +6,9 @@ angular.module('ngCordova.plugins.spinnerDialog', []) .factory('$cordovaSpinnerDialog', ['$window', function ($window) { return { - show: function (title, message, fixed) { + show: function (title, message, fixed, iosOptions) { fixed = fixed || false; - return $window.plugins.spinnerDialog.show(title, message, fixed); + return $window.plugins.spinnerDialog.show(title, message, fixed, iosOptions); }, hide: function () { return $window.plugins.spinnerDialog.hide(); diff --git a/test/plugins/spinnerDialog.spec.js b/test/plugins/spinnerDialog.spec.js index f0b16257..c198bfbe 100644 --- a/test/plugins/spinnerDialog.spec.js +++ b/test/plugins/spinnerDialog.spec.js @@ -12,9 +12,14 @@ describe('Service: $cordovaSpinnerDialog', function() { } })); - it('should call window.plugins\'s spinnerDialog.show', function() { + it('should call window.plugins\'s spinnerDialog.show method with options', function() { + $cordovaSpinnerDialog.show('hi', 'nice hi message', true, {overlayOpacity: 0.75, textColorRed: 1, textColorGreen: 0, textColorBlue: 0.4}); + expect(window.plugins.spinnerDialog.show).toHaveBeenCalledWith('hi', 'nice hi message', true, {overlayOpacity: 0.75, textColorRed: 1, textColorGreen: 0, textColorBlue: 0.4}); + }); + + it('should call window.plugins\'s spinnerDialog.show method without options', function() { $cordovaSpinnerDialog.show('hi', 'nice hi message', true); - expect(window.plugins.spinnerDialog.show).toHaveBeenCalledWith('hi', 'nice hi message', true); + expect(window.plugins.spinnerDialog.show).toHaveBeenCalledWith('hi', 'nice hi message', true, undefined); }); it('should call window.plugins\'s spinnerDialog.hide', function() { From de9e36aade96ca91fcd277f3e7e3c6cd958beb82 Mon Sep 17 00:00:00 2001 From: Jacques Bouman Date: Thu, 21 Apr 2016 20:56:53 +0200 Subject: [PATCH 06/29] Updated appVersion mocks and added tests (#1231) --- src/mocks/appVersion.js | 27 +++++++++++--- test/mocks/appVersion.spec.js | 66 +++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 test/mocks/appVersion.spec.js diff --git a/src/mocks/appVersion.js b/src/mocks/appVersion.js index c040f3f3..db95ef20 100644 --- a/src/mocks/appVersion.js +++ b/src/mocks/appVersion.js @@ -2,10 +2,29 @@ ngCordovaMocks.factory('$cordovaAppVersion', ['$q', function ($q) { var throwsError = false; return { throwsError: throwsError, - getAppVersion: function () { - var defer = $q.defer(); - defer.resolve('mock v'); - return defer.promise; + + getAppName: function () { + var q = $q.defer(); + q.resolve('mock app name'); + return q.promise; + }, + + getPackageName: function () { + var q = $q.defer(); + q.resolve('com.package.mock'); + return q.promise; + }, + + getVersionNumber: function () { + var q = $q.defer(); + q.resolve('1.2.3'); + return q.promise; + }, + + getVersionCode: function () { + var q = $q.defer(); + q.resolve('4.5.6'); + return q.promise; } }; }]); diff --git a/test/mocks/appVersion.spec.js b/test/mocks/appVersion.spec.js new file mode 100644 index 00000000..b4e73dcb --- /dev/null +++ b/test/mocks/appVersion.spec.js @@ -0,0 +1,66 @@ +describe('ngCordovaMocks', function() { + beforeEach(function() { + module('ngCordovaMocks'); + }); + + describe('cordovaAppVersion', function() { + var $rootScope = null; + var $cordovaActionSheet = null; + var options = {}; + + beforeEach(inject(function (_$cordovaAppVersion_, _$rootScope_) { + $cordovaAppVersion = _$cordovaAppVersion_; + $rootScope = _$rootScope_; + })); + + it('should be able to retrieve app name', function(done) { + $cordovaAppVersion + .getAppName() + .then( + function(name) { expect(name).toBe("mock app name") }, + function() { expect(false).toBe(true) } + ) + .finally(function() { done(); }); + + $rootScope.$digest(); + }); + + it('should be able to retrieve package name', function(done) { + $cordovaAppVersion + .getPackageName() + .then( + function(name) { expect(name).toBe("com.package.mock") }, + function() { expect(false).toBe(true) } + ) + .finally(function() { done(); }); + + $rootScope.$digest(); + }); + + it('should be able to retrieve version number', function(done) { + $cordovaAppVersion + .getVersionNumber() + .then( + function(name) { expect(name).toBe("1.2.3") }, + function() { expect(false).toBe(true) } + ) + .finally(function() { done(); }); + + $rootScope.$digest(); + }); + + it('should be able to retrieve version code', function(done) { + $cordovaAppVersion + .getVersionCode() + .then( + function(name) { expect(name).toBe("4.5.6") }, + function() { expect(false).toBe(true) } + ) + .finally(function() { done(); }); + + $rootScope.$digest(); + }); + + + }); +}); From 7d1c50625081b9d0ec6bda115b288835ce70f157 Mon Sep 17 00:00:00 2001 From: Vitaliy Bobrov Date: Thu, 19 May 2016 18:15:30 +0300 Subject: [PATCH 07/29] Issue #1228 - google analytics (#1247) * Add key param check * Tests fix * Tests fix --- src/plugins/googleAnalytics.js | 7 ++++++- test/plugins/googleAnalytics.spec.js | 8 ++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/plugins/googleAnalytics.js b/src/plugins/googleAnalytics.js index 3926ead6..1bec1adf 100755 --- a/src/plugins/googleAnalytics.js +++ b/src/plugins/googleAnalytics.js @@ -56,8 +56,13 @@ angular.module('ngCordova.plugins.googleAnalytics', []) addCustomDimension: function (key, value) { var d = $q.defer(); + var parsedKey = parseInt(key, 10); - $window.analytics.addCustomDimension(key, value, function () { + if (isNaN(parsedKey)) { + d.reject('Parameter "key" must be an integer.'); + } + + $window.analytics.addCustomDimension(parsedKey, value, function () { d.resolve(); }, function (error) { d.reject(error); diff --git a/test/plugins/googleAnalytics.spec.js b/test/plugins/googleAnalytics.spec.js index 7787d2d4..c8430f0e 100644 --- a/test/plugins/googleAnalytics.spec.js +++ b/test/plugins/googleAnalytics.spec.js @@ -192,7 +192,7 @@ describe('Service: $cordovaGoogleAnalytics', function() { }); $cordovaGoogleAnalytics - .addCustomDimension('dimension1', 'Level 1') + .addCustomDimension(1, 'Level 1') .then(function (response) { result = 'success'; }); @@ -200,7 +200,7 @@ describe('Service: $cordovaGoogleAnalytics', function() { $rootScope.$digest(); expect(result).toBe('success'); - expect($window.analytics.addCustomDimension.calls.argsFor(0)[0]).toBe('dimension1'); + expect($window.analytics.addCustomDimension.calls.argsFor(0)[0]).toBe(1); expect($window.analytics.addCustomDimension.calls.argsFor(0)[1]).toBe('Level 1'); }); @@ -210,7 +210,7 @@ describe('Service: $cordovaGoogleAnalytics', function() { spyOn($window.analytics, 'addCustomDimension') .and.callFake(function (key, value, successCb, errorCb) { - errorCb('Expected one non-empty string argument'); + errorCb('Parameter "key" must be an integer.'); }); $cordovaGoogleAnalytics.addCustomDimension() @@ -220,7 +220,7 @@ describe('Service: $cordovaGoogleAnalytics', function() { $rootScope.$digest(); - expect(result).toBe('Expected one non-empty string argument'); + expect(result).toBe('Parameter "key" must be an integer.'); }); it('should call $window\'s analytics.trackEvent method', function() { From 2605cfe4fa946056f160fe3fbed6d9f1e6505440 Mon Sep 17 00:00:00 2001 From: David Gray Date: Tue, 7 Jun 2016 06:37:39 +1000 Subject: [PATCH 08/29] Added shareWithOptions, which was introduced in 5.1.0 (#1263) See https://github.com/EddyVerbruggen/SocialSharing-PhoneGap-Plugin#using-the-share-sheet for usage details --- src/mocks/socialSharing.js | 15 +++++++++++++++ src/plugins/socialSharing.js | 12 +++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/mocks/socialSharing.js b/src/mocks/socialSharing.js index 77f0617b..96faf674 100644 --- a/src/mocks/socialSharing.js +++ b/src/mocks/socialSharing.js @@ -258,6 +258,21 @@ ngCordovaMocks.factory('$cordovaSocialSharing', ['$q', function ($q) { defer.resolve(); } return defer.promise; + }, + + shareWithOptions: function (options) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error sharing via SMS.'); + } else { + this.message = options.message; + this.subject = options.subject; + this.attachments = options.files; + this.link = options.url; + + defer.resolve(); + } + return defer.promise; } }; }]); diff --git a/src/plugins/socialSharing.js b/src/plugins/socialSharing.js index 0976c966..88a1a459 100644 --- a/src/plugins/socialSharing.js +++ b/src/plugins/socialSharing.js @@ -22,6 +22,16 @@ angular.module('ngCordova.plugins.socialSharing', []) return q.promise; }, + shareWithOptions: function (options) { + var q = $q.defer(); + $window.plugins.socialsharing.shareWithOptions(options, function () { + q.resolve(true); + }, function () { + q.reject(false); + }); + return q.promise; + }, + shareViaTwitter: function (message, file, link) { var q = $q.defer(); file = file || null; @@ -139,7 +149,7 @@ angular.module('ngCordova.plugins.socialSharing', []) q.reject(); } }); - + return q.promise; } }; From 876ef6889fb72954dbcd64b182b602104e51a825 Mon Sep 17 00:00:00 2001 From: Avi Y Date: Mon, 27 Jun 2016 21:36:02 +0300 Subject: [PATCH 09/29] added tts plugin wrapper (#1265) * added tts plugin wrapper * commit only tts.js * only commit plugin --- src/plugins/tts.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/plugins/tts.js diff --git a/src/plugins/tts.js b/src/plugins/tts.js new file mode 100644 index 00000000..337d72f0 --- /dev/null +++ b/src/plugins/tts.js @@ -0,0 +1,13 @@ +// install : cordova plugin add cordova-plugin-tts +// link : https://github.com/smcpjames/cordova-plugin-tts + +/* globals TTS: true */ +angular.module('ngCordova.plugins.tts', []) + +.factory('$cordovaTTS', function () { + return { + speak: function (text, onfulfilled, onrejected) { + return TTS.speak(text, onfulfilled, onrejected); + } + }; +}); \ No newline at end of file From 89b5f761edd42fdc36b51c1c7440f76c8c9edec4 Mon Sep 17 00:00:00 2001 From: Megan Kearl Date: Mon, 27 Jun 2016 13:38:05 -0500 Subject: [PATCH 10/29] Add serial plugin wrapper (#1274) * Add cordovaSerial plugin wrapper and unit tests * Update README with serial plugin * Add serial to jshint globals --- README.md | 1 + src/plugins/serial.js | 92 ++++++++++ test/plugins/serial.spec.js | 333 ++++++++++++++++++++++++++++++++++++ 3 files changed, 426 insertions(+) create mode 100644 src/plugins/serial.js create mode 100644 test/plugins/serial.spec.js diff --git a/README.md b/README.md index 94b3d2b5..a712fb6a 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,7 @@ $ bower install ngCordova - [Push Notifications](https://github.com/phonegap-build/PushPlugin) (**deprecated** - Will be removed in future release) - [Push Notifications - V5] (https://github.com/phonegap/phonegap-plugin-push) - [Screenshots](https://github.com/gitawego/cordova-screenshot) +- [Serial](https://github.com/xseignard/cordovarduino) - [SMS](https://github.com/aharris88/phonegap-sms-plugin) - [Social Sharing](https://github.com/EddyVerbruggen/SocialSharing-PhoneGap-Plugin) - [Spinner Dialog](https://github.com/Paldom/SpinnerDialog) diff --git a/src/plugins/serial.js b/src/plugins/serial.js new file mode 100644 index 00000000..14bd286f --- /dev/null +++ b/src/plugins/serial.js @@ -0,0 +1,92 @@ +// install : cordova plugin add https://github.com/xseignard/cordovarduino.git +// link : https://github.com/xseignard/cordovarduino + +/* globals serial: true */ +angular.module('ngCordova.plugins.serial', []) + + .factory('$cordovaSerial', ['$q', function ($q) { + + var serialService = {}; + + serialService.requestPermission = function requestPermission(options) { + var q = $q.defer(); + + serial.requestPermission(options, function success() { + q.resolve(); + }, function error(err) { + q.reject(err); + }); + + return q.promise; + }; + + serialService.open = function(options) { + var q = $q.defer(); + + serial.open(options, function success() { + q.resolve(); + }, function error(err) { + q.reject(err); + }); + + return q.promise; + }; + + serialService.write = function(data) { + var q = $q.defer(); + + serial.write(data, function success() { + q.resolve(); + }, function error(err) { + q.reject(err); + }); + + return q.promise; + }; + + serialService.writeHex = function(data) { + var q = $q.defer(); + + serial.writeHex(data, function success() { + q.resolve(); + }, function error(err) { + q.reject(err); + }); + + return q.promise; + }; + + serialService.read = function() { + var q = $q.defer(); + + serial.read(function success(buffer) { + var view = new Uint8Array(buffer); + q.resolve(view); + }, function error(err) { + q.reject(err); + }); + + return q.promise; + }; + + serialService.registerReadCallback = function(successCallback, errorCallback) { + serial.registerReadCallback(function success(buffer) { + var view = new Uint8Array(buffer); + successCallback(view); + }, errorCallback); + }; + + serialService.close = function() { + var q = $q.defer(); + + serial.close(function success() { + q.resolve(); + }, function error(err) { + q.reject(err); + }); + + return q.promise; + }; + + return serialService; + }]); diff --git a/test/plugins/serial.spec.js b/test/plugins/serial.spec.js new file mode 100644 index 00000000..09ec06db --- /dev/null +++ b/test/plugins/serial.spec.js @@ -0,0 +1,333 @@ +describe('Service: $cordovaSerial', function() { + + var $cordovaSerial, $rootScope; + + beforeEach(module('ngCordova.plugins.serial')); + + beforeEach(inject(function (_$cordovaSerial_, _$q_, _$rootScope_) { + $cordovaSerial = _$cordovaSerial_; + $rootScope = _$rootScope_; + + serial = { + requestPermission: angular.noop, + open: angular.noop, + write: angular.noop, + writeHex: angular.noop, + read: angular.noop, + registerReadCallback: angular.noop, + close: angular.noop + }; + })); + + describe('when requestPermission is called', function() { + var options = { + vid: '1000', + pid: '1200', + driver: 'FtdiSerialDriver' + }; + + it('should call serial.requestPermission with the provided options', function() { + spyOn(serial, 'requestPermission'); + $cordovaSerial.requestPermission(options); + expect(serial.requestPermission).toHaveBeenCalledWith(options, jasmine.any(Function), jasmine.any(Function)); + }); + + it('should resolve the promise when serial.requestPermission is successful', function() { + var result; + + spyOn(serial, 'requestPermission').and.callFake(function(options, successCallback, errorCallback) { + successCallback(); + }); + $cordovaSerial.requestPermission(options).then(function() { + result = 'success'; + }).catch(function(err) { + fail(err); + }); + $rootScope.$digest(); + expect(result).toEqual('success'); + }); + + it('should reject the promise when serial.requestPermission has an error', function() { + var expectedError = 'Some error'; + var error; + + spyOn(serial, 'requestPermission').and.callFake(function(options, successCallback, errorCallback) { + errorCallback(expectedError); + }); + $cordovaSerial.requestPermission(options).then(function() { + fail('Expected requestPermission to reject promise'); + }).catch(function(err) { + error = err; + }); + $rootScope.$digest(); + expect(error).toEqual(expectedError); + }); + }); + + describe('when open is called', function() { + var options = { + baudRate: 115200 + }; + + it('should call serial.open with the provided options', function() { + spyOn(serial, 'open'); + $cordovaSerial.open(options); + expect(serial.open).toHaveBeenCalledWith(options, jasmine.any(Function), jasmine.any(Function)); + }); + + it('should resolve the promise when serial.open is successful', function() { + var result; + + spyOn(serial, 'open').and.callFake(function(options, successCallback, errorCallback) { + successCallback(); + }); + $cordovaSerial.open(options).then(function() { + result = 'success'; + }).catch(function(err) { + fail(err); + }); + $rootScope.$digest(); + expect(result).toEqual('success'); + }); + + it('should reject the promise when serial.open has an error', function() { + var expectedError = 'Some error'; + var error; + + spyOn(serial, 'open').and.callFake(function(options, successCallback, errorCallback) { + errorCallback(expectedError); + }); + $cordovaSerial.open(options).then(function() { + fail('Expected open to reject promise'); + }).catch(function(err) { + error = err; + }); + $rootScope.$digest(); + expect(error).toEqual(expectedError); + }); + }); + + describe('when write is called', function() { + var data = 'ff'; + + it('should call serial.write with the provided options', function() { + spyOn(serial, 'write'); + $cordovaSerial.write(data); + expect(serial.write).toHaveBeenCalledWith(data, jasmine.any(Function), jasmine.any(Function)); + }); + + it('should resolve the promise when serial.write is successful', function() { + var result; + + spyOn(serial, 'write').and.callFake(function(data, successCallback, errorCallback) { + successCallback(); + }); + $cordovaSerial.write(data).then(function() { + result = 'success'; + }).catch(function(err) { + fail(err); + }); + $rootScope.$digest(); + expect(result).toEqual('success'); + }); + + it('should reject the promise when serial.write has an error', function() { + var expectedError = 'Some error'; + var error; + + spyOn(serial, 'write').and.callFake(function(data, successCallback, errorCallback) { + errorCallback(expectedError); + }); + $cordovaSerial.write(data).then(function() { + fail('Expected write to reject promise'); + }).catch(function(err) { + error = err; + }); + $rootScope.$digest(); + expect(error).toEqual(expectedError); + }); + }); + + describe('when writeHex is called', function() { + var data = 'ff'; + + it('should call serial.writeHex with the provided options', function() { + spyOn(serial, 'writeHex'); + $cordovaSerial.writeHex(data); + expect(serial.writeHex).toHaveBeenCalledWith(data, jasmine.any(Function), jasmine.any(Function)); + }); + + it('should resolve the promise when serial.writeHex is successful', function() { + var result; + + spyOn(serial, 'writeHex').and.callFake(function(data, successCallback, errorCallback) { + successCallback(); + }); + $cordovaSerial.writeHex(data).then(function() { + result = 'success'; + }).catch(function(err) { + fail(err); + }); + $rootScope.$digest(); + expect(result).toEqual('success'); + }); + + it('should reject the promise when serial.writeHex has an error', function() { + var expectedError = 'Some error'; + var error; + + spyOn(serial, 'writeHex').and.callFake(function(data, successCallback, errorCallback) { + errorCallback(expectedError); + }); + $cordovaSerial.writeHex(data).then(function() { + fail('Expected writeHex to reject promise'); + }).catch(function(err) { + error = err; + }); + $rootScope.$digest(); + expect(error).toEqual(expectedError); + }); + }); + + describe('when read is called', function() { + var data = [0,1]; + + it('should resolve the promise when serial.read is successful', function() { + var result; + + spyOn(serial, 'read').and.callFake(function(successCallback, errorCallback) { + successCallback(data); + }); + $cordovaSerial.read().then(function() { + result = 'success'; + }).catch(function(err) { + fail(err); + }); + $rootScope.$digest(); + expect(result).toEqual('success'); + }); + + it('should parse the successful response data as a Uint8Array', function() { + var response; + + spyOn(serial, 'read').and.callFake(function(successCallback, errorCallback) { + successCallback(data); + }); + $cordovaSerial.read().then(function(result) { + response = result; + }).catch(function(err) { + fail(err); + }); + $rootScope.$digest(); + expect(response instanceof Uint8Array).toEqual(true); + }); + + it('should reject the promise when serial.read has an error', function() { + var expectedError = 'Some error'; + var error; + + spyOn(serial, 'read').and.callFake(function(successCallback, errorCallback) { + errorCallback(expectedError); + }); + $cordovaSerial.read().then(function() { + fail('Expected read to reject promise'); + }).catch(function(err) { + error = err; + }); + $rootScope.$digest(); + expect(error).toEqual(expectedError); + }); + }); + + describe('when registerReadCallback is called', function() { + var data = [0,1]; + + it('should call serial.registerReadCallback with a success and failure callback', function() { + var successCallback = angular.noop; + var errorCallback = angular.noop; + spyOn(serial, 'registerReadCallback'); + $cordovaSerial.registerReadCallback(successCallback, errorCallback); + expect(serial.registerReadCallback).toHaveBeenCalledWith(jasmine.any(Function), errorCallback); + }); + + it('should call the provided success callback', function() { + var successCallback = jasmine.createSpy('successCallback'); + var errorCallback = jasmine.createSpy('errorCallback'); + + spyOn(serial, 'registerReadCallback').and.callFake(function(successCallback, errorCallback) { + successCallback(data); + }); + + $cordovaSerial.registerReadCallback(successCallback, errorCallback); + + expect(successCallback).toHaveBeenCalled(); + expect(errorCallback).not.toHaveBeenCalled(); + }); + + it('should parse the successful response data as a Uint8Array', function() { + var response; + + var successCallback = jasmine.createSpy('successCallback').and.callFake(function(data) { + response = data; + }); + var errorCallback = jasmine.createSpy('errorCallback'); + + spyOn(serial, 'registerReadCallback').and.callFake(function(successCallback, errorCallback) { + successCallback(data); + }); + + $cordovaSerial.registerReadCallback(successCallback, errorCallback); + + expect(response instanceof Uint8Array).toEqual(true); + }); + + it('should call the provided failure callback', function() { + var error = 'Some error'; + var successCallback = jasmine.createSpy('successCallback'); + var errorCallback = jasmine.createSpy('errorCallback'); + + spyOn(serial, 'registerReadCallback').and.callFake(function(successCallback, errorCallback) { + errorCallback(error); + }); + + $cordovaSerial.registerReadCallback(successCallback, errorCallback); + + expect(successCallback).not.toHaveBeenCalled(); + expect(errorCallback).toHaveBeenCalledWith(error); + }); + }); + + describe('when close is called', function() { + it('should resolve the promise when serial.close is successful', function() { + var result; + + spyOn(serial, 'close').and.callFake(function(successCallback, errorCallback) { + successCallback(); + }); + $cordovaSerial.close().then(function() { + result = 'success'; + }).catch(function(err) { + fail(err); + }); + $rootScope.$digest(); + expect(result).toEqual('success'); + }); + + it('should reject the promise when serial.close has an error', function() { + var expectedError = 'Some error'; + var error; + + spyOn(serial, 'close').and.callFake(function(successCallback, errorCallback) { + errorCallback(expectedError); + }); + $cordovaSerial.close().then(function() { + fail('Expected close to reject promise'); + }).catch(function(err) { + error = err; + }); + $rootScope.$digest(); + expect(error).toEqual(expectedError); + }); + }); + +}); From 807db3eea66818d2f99be3962a3f21f6360ace0a Mon Sep 17 00:00:00 2001 From: Avi Y Date: Wed, 6 Jul 2016 19:41:01 +0300 Subject: [PATCH 11/29] added recents control plugin wrapper (#1264) * added recents control plugin * built added recents control plugin * added plugin to plugin list * added tts plugin wrapper * commit only tts.js * only commit plugin * only commit recents plugin * remove tts plugin * added plugin to list * added coma :| --- dist/ng-cordova.js | 3 ++- src/plugins/recentsControl.js | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 src/plugins/recentsControl.js diff --git a/dist/ng-cordova.js b/dist/ng-cordova.js index a59620b6..242e8e37 100644 --- a/dist/ng-cordova.js +++ b/dist/ng-cordova.js @@ -5579,6 +5579,7 @@ angular.module('ngCordova.plugins', [ 'ngCordova.plugins.progressIndicator', 'ngCordova.plugins.push', 'ngCordova.plugins.push_v5', + 'ngCordova.plugins.recentsControl', 'ngCordova.plugins.sms', 'ngCordova.plugins.socialSharing', 'ngCordova.plugins.spinnerDialog', @@ -7058,4 +7059,4 @@ angular.module('ngCordova.plugins.zip', []) }; }]); -})(); \ No newline at end of file +})(); diff --git a/src/plugins/recentsControl.js b/src/plugins/recentsControl.js new file mode 100644 index 00000000..c5ffd0db --- /dev/null +++ b/src/plugins/recentsControl.js @@ -0,0 +1,21 @@ +// install : cordova plugin add cordova-plugin-recentscontrol +// link : https://github.com/smcpjames/cordova-plugin-recentscontrol + +/* globals RecentsControl: true */ +angular.module('ngCordova.plugins.recentsControl', []) + +.factory('$cordovaRecents', function () { + return { + setColor: function (color) { + return RecentsControl.setColor(color); + }, + + setDescription: function (desc) { + return RecentsControl.setDescription(desc); + }, + + setOptions: function (colorStr, desc) { + return RecentsControl.setOptions(colorStr, desc); + } + }; +}); \ No newline at end of file From 5cd6110374af4bc0cc7d27915a639ba49b64510f Mon Sep 17 00:00:00 2001 From: Nikolay Polukhin Date: Mon, 22 Aug 2016 23:32:08 +0900 Subject: [PATCH 12/29] Update google-analytics-plugin (#1309) * Update google-analytics-plugin * add test * revert dist/* folders --- src/mocks/googleAnalytics.js | 9 +- src/plugins/googleAnalytics.js | 80 ++++++- test/mocks/googleAnalytics.spec.js | 22 +- test/plugins/googleAnalytics.spec.js | 327 ++++++++++++++++++++++----- 4 files changed, 374 insertions(+), 64 deletions(-) diff --git a/src/mocks/googleAnalytics.js b/src/mocks/googleAnalytics.js index 4d15e8de..ccec0258 100644 --- a/src/mocks/googleAnalytics.js +++ b/src/mocks/googleAnalytics.js @@ -13,7 +13,7 @@ ngCordovaMocks.factory('$cordovaGoogleAnalytics', ['$q', function ($q) { /** * @ngdoc property * @name throwsError - * @propertyOf ngCordovaMocks.cordovaGeolocation + * @propertyOf ngCordovaMocks.cordovaGoogleAnalytics * * @description * A flag that signals whether a promise should be rejected or not. @@ -24,14 +24,19 @@ ngCordovaMocks.factory('$cordovaGoogleAnalytics', ['$q', function ($q) { var methodsName = [ 'startTrackerWithId', 'setUserId', + 'setAppVersion', 'debugMode', 'trackView', 'addCustomDimension', 'trackEvent', + 'trackMetric', 'trackException', 'trackTiming', 'addTransaction', - 'addTransactionItem' + 'addTransactionItem', + 'setAnonymizeIp', + 'setAllowIDFACollection', + 'enableUncaughtExceptionReporting' ]; methodsName.forEach(function (funcName) { diff --git a/src/plugins/googleAnalytics.js b/src/plugins/googleAnalytics.js index 1bec1adf..6de9f6ff 100755 --- a/src/plugins/googleAnalytics.js +++ b/src/plugins/googleAnalytics.js @@ -9,7 +9,7 @@ angular.module('ngCordova.plugins.googleAnalytics', []) startTrackerWithId: function (id) { var d = $q.defer(); - $window.analytics.startTrackerWithId(id, function (response) { + $window.ga.startTrackerWithId(id, function (response) { d.resolve(response); }, function (error) { d.reject(error); @@ -21,7 +21,19 @@ angular.module('ngCordova.plugins.googleAnalytics', []) setUserId: function (id) { var d = $q.defer(); - $window.analytics.setUserId(id, function (response) { + $window.ga.setUserId(id, function (response) { + d.resolve(response); + }, function (error) { + d.reject(error); + }); + + return d.promise; + }, + + setAppVersion: function (version) { + var d = $q.defer(); + + $window.ga.setAppVersion(version, function (response) { d.resolve(response); }, function (error) { d.reject(error); @@ -33,7 +45,7 @@ angular.module('ngCordova.plugins.googleAnalytics', []) debugMode: function () { var d = $q.defer(); - $window.analytics.debugMode(function (response) { + $window.ga.debugMode(function (response) { d.resolve(response); }, function () { d.reject(); @@ -45,7 +57,7 @@ angular.module('ngCordova.plugins.googleAnalytics', []) trackView: function (screenName) { var d = $q.defer(); - $window.analytics.trackView(screenName, function (response) { + $window.ga.trackView(screenName, function (response) { d.resolve(response); }, function (error) { d.reject(error); @@ -62,7 +74,7 @@ angular.module('ngCordova.plugins.googleAnalytics', []) d.reject('Parameter "key" must be an integer.'); } - $window.analytics.addCustomDimension(parsedKey, value, function () { + $window.ga.addCustomDimension(parsedKey, value, function () { d.resolve(); }, function (error) { d.reject(error); @@ -74,7 +86,19 @@ angular.module('ngCordova.plugins.googleAnalytics', []) trackEvent: function (category, action, label, value) { var d = $q.defer(); - $window.analytics.trackEvent(category, action, label, value, function (response) { + $window.ga.trackEvent(category, action, label, value, function (response) { + d.resolve(response); + }, function (error) { + d.reject(error); + }); + + return d.promise; + }, + + trackMetric: function (key, value) { + var d = $q.defer(); + + $window.ga.trackMetric(key, value, function (response) { d.resolve(response); }, function (error) { d.reject(error); @@ -86,7 +110,7 @@ angular.module('ngCordova.plugins.googleAnalytics', []) trackException: function (description, fatal) { var d = $q.defer(); - $window.analytics.trackException(description, fatal, function (response) { + $window.ga.trackException(description, fatal, function (response) { d.resolve(response); }, function (error) { d.reject(error); @@ -98,7 +122,7 @@ angular.module('ngCordova.plugins.googleAnalytics', []) trackTiming: function (category, milliseconds, variable, label) { var d = $q.defer(); - $window.analytics.trackTiming(category, milliseconds, variable, label, function (response) { + $window.ga.trackTiming(category, milliseconds, variable, label, function (response) { d.resolve(response); }, function (error) { d.reject(error); @@ -110,7 +134,7 @@ angular.module('ngCordova.plugins.googleAnalytics', []) addTransaction: function (transactionId, affiliation, revenue, tax, shipping, currencyCode) { var d = $q.defer(); - $window.analytics.addTransaction(transactionId, affiliation, revenue, tax, shipping, currencyCode, function (response) { + $window.ga.addTransaction(transactionId, affiliation, revenue, tax, shipping, currencyCode, function (response) { d.resolve(response); }, function (error) { d.reject(error); @@ -122,7 +146,43 @@ angular.module('ngCordova.plugins.googleAnalytics', []) addTransactionItem: function (transactionId, name, sku, category, price, quantity, currencyCode) { var d = $q.defer(); - $window.analytics.addTransactionItem(transactionId, name, sku, category, price, quantity, currencyCode, function (response) { + $window.ga.addTransactionItem(transactionId, name, sku, category, price, quantity, currencyCode, function (response) { + d.resolve(response); + }, function (error) { + d.reject(error); + }); + + return d.promise; + }, + + setAnonymizeIp: function (anonymize) { + var d = $q.defer(); + + $window.ga.setAnonymizeIp(anonymize, function (response) { + d.resolve(response); + }, function (error) { + d.reject(error); + }); + + return d.promise; + }, + + setAllowIDFACollection: function (enable) { + var d = $q.defer(); + + $window.ga.setAllowIDFACollection(enable, function (response) { + d.resolve(response); + }, function (error) { + d.reject(error); + }); + + return d.promise; + }, + + enableUncaughtExceptionReporting: function (enable) { + var d = $q.defer(); + + $window.ga.enableUncaughtExceptionReporting(enable, function (response) { d.resolve(response); }, function (error) { d.reject(error); diff --git a/test/mocks/googleAnalytics.spec.js b/test/mocks/googleAnalytics.spec.js index 23a4442d..fa027f70 100644 --- a/test/mocks/googleAnalytics.spec.js +++ b/test/mocks/googleAnalytics.spec.js @@ -31,7 +31,7 @@ describe('ngCordovaMocks', function() { $timeout.flush(); }; - it('should start tracker', function () { + it('should start tracker', function() { testPromises('startTrackerWithId'); }); @@ -39,6 +39,10 @@ describe('ngCordovaMocks', function() { testPromises('setUserId'); }); + it('should set App version', function() { + testPromises('setAppVersion'); + }); + it('should set debug mode.', function() { testPromises('debugMode'); }); @@ -55,6 +59,10 @@ describe('ngCordovaMocks', function() { testPromises('trackEvent'); }); + it('should track metric', function() { + testPromises('trackMetric'); + }); + it('should track exception.', function() { testPromises('trackException'); }); @@ -70,5 +78,17 @@ describe('ngCordovaMocks', function() { it('should add add a transaction item.', function() { testPromises('addTransactionItem'); }); + + it('should set Anonymize Ip', function() { + testPromises('setAnonymizeIp'); + }); + + it('should set Allow IDFA Collection', function() { + testPromises('setAllowIDFACollection'); + }); + + it('should enable Uncaught Exception Reporting', function() { + testPromises('enableUncaughtExceptionReporting'); + }); }); }) \ No newline at end of file diff --git a/test/plugins/googleAnalytics.spec.js b/test/plugins/googleAnalytics.spec.js index c8430f0e..c8b9342d 100644 --- a/test/plugins/googleAnalytics.spec.js +++ b/test/plugins/googleAnalytics.spec.js @@ -9,25 +9,30 @@ describe('Service: $cordovaGoogleAnalytics', function() { $window = _$window_; $rootScope = _$rootScope_; - $window.analytics = { + $window.ga = { startTrackerWithId: angular.noop, setUserId: angular.noop, + setAppVersion: angular.noop, debugMode: angular.noop, trackView: angular.noop, addCustomDimension: angular.noop, trackEvent: angular.noop, + trackMetric: angular.noop, trackException: angular.noop, trackTiming: angular.noop, addTransaction: angular.noop, addTransactionItem: angular.noop, + setAnonymizeIp: angular.noop, + setAllowIDFACollection: angular.noop, + enableUncaughtExceptionReporting: angular.noop }; })); - it('should call $window\'s analytics.startTrackerWithId method', function() { + it('should call $window\'s ga.startTrackerWithId method', function() { var result; - spyOn($window.analytics, 'startTrackerWithId') + spyOn($window.ga, 'startTrackerWithId') .and.callFake(function (id, successCb, errorCb) { successCb('tracker started'); }); @@ -41,14 +46,14 @@ describe('Service: $cordovaGoogleAnalytics', function() { $rootScope.$digest(); expect(result).toBe('tracker started'); - expect($window.analytics.startTrackerWithId.calls.argsFor(0)[0]).toBe('UA-000000-01'); + expect($window.ga.startTrackerWithId.calls.argsFor(0)[0]).toBe('UA-000000-01'); }); - it('should call errorCb when in $window\'s analytics.startTrackerWithId a error orccurs', function() { + it('should call errorCb when in $window\'s ga.startTrackerWithId a error orccurs', function() { var result; - spyOn($window.analytics, 'startTrackerWithId') + spyOn($window.ga, 'startTrackerWithId') .and.callFake(function (id, successCb, errorCb) { errorCb('tracker id is not valid'); }); @@ -63,11 +68,11 @@ describe('Service: $cordovaGoogleAnalytics', function() { expect(result).toBe('tracker id is not valid'); }); - it('should call $window\'s analytics.setUserId method', function() { + it('should call $window\'s ga.setUserId method', function() { var result; - spyOn($window.analytics, 'setUserId') + spyOn($window.ga, 'setUserId') .and.callFake(function (id, successCb, errorCb) { successCb('Set user id: ' + id); }); @@ -81,14 +86,14 @@ describe('Service: $cordovaGoogleAnalytics', function() { $rootScope.$digest(); expect(result).toBe('Set user id: USER_ID'); - expect($window.analytics.setUserId.calls.argsFor(0)[0]).toBe('USER_ID'); + expect($window.ga.setUserId.calls.argsFor(0)[0]).toBe('USER_ID'); }); - it('should call errorCb when in $window\'s analytics.setUserId a error orccurs', function() { + it('should call errorCb when in $window\'s ga.setUserId a error orccurs', function() { var result; - spyOn($window.analytics, 'setUserId') + spyOn($window.ga, 'setUserId') .and.callFake(function (id, successCb, errorCb) { errorCb('Tracker not started'); }); @@ -103,11 +108,55 @@ describe('Service: $cordovaGoogleAnalytics', function() { expect(result).toBe('Tracker not started'); }); - it('should call $window\'s analytics.debugMode method', function() { + it('should call $window\'s ga.setAppVersion method', function () { var result; - spyOn($window.analytics, 'debugMode') + spyOn($window.ga, 'setAppVersion') + .and.callFake(function (version, successCb, errorCb) { + successCb('Set app version: ' + version); + }); + + $cordovaGoogleAnalytics + .setAppVersion('VERSION') + .then(function (response) { + result = response; + }); + + $rootScope.$digest(); + + expect(result).toBe('Set app version: VERSION'); + expect($window.ga.setAppVersion).toHaveBeenCalledWith( + 'VERSION', + jasmine.any(Function), + jasmine.any(Function) + ); + }); + + it('should call errorCb when in $window\'s ga.setAppVersion a error orccurs', function() { + + var result; + + spyOn($window.ga, 'setAppVersion') + .and.callFake(function (version, successCb, errorCb) { + errorCb('error orccurs'); + }); + + $cordovaGoogleAnalytics.setAppVersion() + .then(angular.noop, function (response) { + result = response; + }); + + $rootScope.$digest(); + + expect(result).toBe('error orccurs'); + }); + + it('should call $window\'s ga.debugMode method', function() { + + var result; + + spyOn($window.ga, 'debugMode') .and.callFake(function (successCb, errorCb) { successCb('debugMode enabled'); }); @@ -123,11 +172,11 @@ describe('Service: $cordovaGoogleAnalytics', function() { expect(result).toBe('debugMode enabled'); }); - it('should call errorCb when in $window\'s analytics.debugMode a error orccurs', function() { + it('should call errorCb when in $window\'s ga.debugMode a error orccurs', function() { var result; - spyOn($window.analytics, 'debugMode') + spyOn($window.ga, 'debugMode') .and.callFake(function (successCb, errorCb) { errorCb(); }); @@ -142,11 +191,11 @@ describe('Service: $cordovaGoogleAnalytics', function() { expect(result).toBe('error orccurs'); }); - it('should call $window\'s analytics.trackView method', function() { + it('should call $window\'s ga.trackView method', function() { var result; - spyOn($window.analytics, 'trackView') + spyOn($window.ga, 'trackView') .and.callFake(function (screenName, successCb, errorCb) { successCb('Track Screen: ' + screenName); }); @@ -160,14 +209,14 @@ describe('Service: $cordovaGoogleAnalytics', function() { $rootScope.$digest(); expect(result).toBe('Track Screen: Home Screen'); - expect($window.analytics.trackView.calls.argsFor(0)[0]).toBe('Home Screen'); + expect($window.ga.trackView.calls.argsFor(0)[0]).toBe('Home Screen'); }); - it('should call errorCb when in $window\'s analytics.trackView a error orccurs', function() { + it('should call errorCb when in $window\'s ga.trackView a error orccurs', function() { var result; - spyOn($window.analytics, 'trackView') + spyOn($window.ga, 'trackView') .and.callFake(function (screenName, successCb, errorCb) { errorCb('Expected one non-empty string argument'); }); @@ -182,11 +231,11 @@ describe('Service: $cordovaGoogleAnalytics', function() { expect(result).toBe('Expected one non-empty string argument'); }); - it('should call $window\'s analytics.addCustomDimension method', function() { + it('should call $window\'s ga.addCustomDimension method', function() { var result; - spyOn($window.analytics, 'addCustomDimension') + spyOn($window.ga, 'addCustomDimension') .and.callFake(function (key, value, successCb, errorCb) { successCb(); }); @@ -200,15 +249,15 @@ describe('Service: $cordovaGoogleAnalytics', function() { $rootScope.$digest(); expect(result).toBe('success'); - expect($window.analytics.addCustomDimension.calls.argsFor(0)[0]).toBe(1); - expect($window.analytics.addCustomDimension.calls.argsFor(0)[1]).toBe('Level 1'); + expect($window.ga.addCustomDimension.calls.argsFor(0)[0]).toBe(1); + expect($window.ga.addCustomDimension.calls.argsFor(0)[1]).toBe('Level 1'); }); - it('should call errorCb when in $window\'s analytics.addCustomDimension a error orccurs', function() { + it('should call errorCb when in $window\'s ga.addCustomDimension a error orccurs', function() { var result; - spyOn($window.analytics, 'addCustomDimension') + spyOn($window.ga, 'addCustomDimension') .and.callFake(function (key, value, successCb, errorCb) { errorCb('Parameter "key" must be an integer.'); }); @@ -223,11 +272,11 @@ describe('Service: $cordovaGoogleAnalytics', function() { expect(result).toBe('Parameter "key" must be an integer.'); }); - it('should call $window\'s analytics.trackEvent method', function() { + it('should call $window\'s ga.trackEvent method', function() { var result; - spyOn($window.analytics, 'trackEvent') + spyOn($window.ga, 'trackEvent') .and.callFake(function (category, action, label, value, successCb, errorCb) { successCb('Track Event: ' + category); }); @@ -241,18 +290,18 @@ describe('Service: $cordovaGoogleAnalytics', function() { $rootScope.$digest(); expect(result).toBe('Track Event: Videos'); - expect($window.analytics.trackEvent).toHaveBeenCalledWith( + expect($window.ga.trackEvent).toHaveBeenCalledWith( 'Videos', 'Video Load Time', 'Gone With the Wind', 100, jasmine.any(Function), jasmine.any(Function) ); }); - it('should call errorCb when in $window\'s analytics.trackEvent a error orccurs', function() { + it('should call errorCb when in $window\'s ga.trackEvent a error orccurs', function() { var result; - spyOn($window.analytics, 'trackEvent') + spyOn($window.ga, 'trackEvent') .and.callFake(function (category, action, label, value, successCb, errorCb) { errorCb('Tracker not started'); }); @@ -268,11 +317,56 @@ describe('Service: $cordovaGoogleAnalytics', function() { expect(result).toBe('Tracker not started'); }); - it('should call $window\'s analytics.trackException method', function() { + it('should call $window\'s ga.trackMetric method', function() { + + var result; + + spyOn($window.ga, 'trackMetric') + .and.callFake(function (key, value, successCb, errorCb) { + successCb('Track Metric: ' + key); + }); + + $cordovaGoogleAnalytics + .trackMetric('Custom', 1) + .then(function (response) { + result = response; + }); + + $rootScope.$digest(); + + expect(result).toBe('Track Metric: Custom'); + expect($window.ga.trackMetric).toHaveBeenCalledWith( + 'Custom', 1, + jasmine.any(Function), + jasmine.any(Function) + ); + }); + + it('should call errorCb when in $window\'s ga.trackMetric a error orccurs', function() { var result; - spyOn($window.analytics, 'trackException') + spyOn($window.ga, 'trackMetric') + .and.callFake(function (key, value, successCb, errorCb) { + errorCb('Tracker not started'); + }); + + $cordovaGoogleAnalytics + .trackMetric() + .then(angular.noop, function (response) { + result = response; + }); + + $rootScope.$digest(); + + expect(result).toBe('Tracker not started'); + }); + + it('should call $window\'s ga.trackException method', function() { + + var result; + + spyOn($window.ga, 'trackException') .and.callFake(function (description, fatal, successCb, errorCb) { successCb('Track Exception: ' + description); }); @@ -286,18 +380,18 @@ describe('Service: $cordovaGoogleAnalytics', function() { $rootScope.$digest(); expect(result).toBe('Track Exception: Video player exception'); - expect($window.analytics.trackException).toHaveBeenCalledWith( + expect($window.ga.trackException).toHaveBeenCalledWith( 'Video player exception', false, jasmine.any(Function), jasmine.any(Function) ); }); - it('should call errorCb when in $window\'s analytics.trackException a error orccurs', function() { + it('should call errorCb when in $window\'s ga.trackException a error orccurs', function() { var result; - spyOn($window.analytics, 'trackException') + spyOn($window.ga, 'trackException') .and.callFake(function (description, fatal, successCb, errorCb) { errorCb('Tracker not started'); }); @@ -313,11 +407,11 @@ describe('Service: $cordovaGoogleAnalytics', function() { expect(result).toBe('Tracker not started'); }); - it('should call $window\'s analytics.trackTiming method', function() { + it('should call $window\'s ga.trackTiming method', function() { var result; - spyOn($window.analytics, 'trackTiming') + spyOn($window.ga, 'trackTiming') .and.callFake(function (category, milliseconds, variable, label, successCb, errorCb) { successCb('Track Timing: ' + category); }); @@ -331,18 +425,18 @@ describe('Service: $cordovaGoogleAnalytics', function() { $rootScope.$digest(); expect(result).toBe('Track Timing: Videos'); - expect($window.analytics.trackTiming).toHaveBeenCalledWith( + expect($window.ga.trackTiming).toHaveBeenCalledWith( 'Videos', 100, 'Video Load Time', 'Gone With the Wind', jasmine.any(Function), jasmine.any(Function) ); }); - it('should call errorCb when in $window\'s analytics.trackTiming a error orccurs', function() { + it('should call errorCb when in $window\'s ga.trackTiming a error orccurs', function() { var result; - spyOn($window.analytics, 'trackTiming') + spyOn($window.ga, 'trackTiming') .and.callFake(function (category, milliseconds, variable, label, successCb, errorCb) { errorCb('Tracker not started'); }); @@ -358,11 +452,11 @@ describe('Service: $cordovaGoogleAnalytics', function() { expect(result).toBe('Tracker not started'); }); - it('should call $window\'s analytics.addTransaction method', function() { + it('should call $window\'s ga.addTransaction method', function() { var result; - spyOn($window.analytics, 'addTransaction') + spyOn($window.ga, 'addTransaction') .and.callFake(function (transactionId, affiliation, revenue, tax, shipping, currencyCode, successCb, errorCb) { successCb('Add Transaction: ' + transactionId); }); @@ -376,18 +470,18 @@ describe('Service: $cordovaGoogleAnalytics', function() { $rootScope.$digest(); expect(result).toBe('Add Transaction: 1234'); - expect($window.analytics.addTransaction).toHaveBeenCalledWith( + expect($window.ga.addTransaction).toHaveBeenCalledWith( '1234', 'Acme Clothing', '11.99', '5', '1.29', 'EUR', jasmine.any(Function), jasmine.any(Function) ); }); - it('should call errorCb when in $window\'s analytics.addTransaction a error orccurs', function() { + it('should call errorCb when in $window\'s ga.addTransaction a error orccurs', function() { var result; - spyOn($window.analytics, 'addTransaction') + spyOn($window.ga, 'addTransaction') .and.callFake(function (transactionId, affiliation, revenue, tax, shipping, currencyCode, successCb, errorCb) { errorCb('Tracker not started'); }); @@ -402,11 +496,11 @@ describe('Service: $cordovaGoogleAnalytics', function() { expect(result).toBe('Tracker not started'); }); - it('should call $window\'s analytics.addTransactionItem method', function() { + it('should call $window\'s ga.addTransactionItem method', function() { var result; - spyOn($window.analytics, 'addTransactionItem') + spyOn($window.ga, 'addTransactionItem') .and.callFake(function (transactionId, name ,sku, category, price, quantity, currencyCode, successCb, errorCb) { successCb('Add Transaction Item: ' + transactionId); }); @@ -420,18 +514,18 @@ describe('Service: $cordovaGoogleAnalytics', function() { $rootScope.$digest(); expect(result).toBe('Add Transaction Item: 1234'); - expect($window.analytics.addTransactionItem).toHaveBeenCalledWith( + expect($window.ga.addTransactionItem).toHaveBeenCalledWith( '1234', 'Fluffy Pink Bunnies', 'DD23444', 'Party Toys', '11.99', '1', 'GBP', jasmine.any(Function), jasmine.any(Function) ); }); - it('should call errorCb when in $window\'s analytics.addTransactionItem a error orccurs', function() { + it('should call errorCb when in $window\'s ga.addTransactionItem a error orccurs', function() { var result; - spyOn($window.analytics, 'addTransactionItem') + spyOn($window.ga, 'addTransactionItem') .and.callFake(function (transactionId, name ,sku, category, price, quantity, currencyCode, successCb, errorCb) { errorCb('Tracker not started'); }); @@ -446,4 +540,135 @@ describe('Service: $cordovaGoogleAnalytics', function() { expect(result).toBe('Tracker not started'); }); + it('should call $window\'s ga.setAnonymizeIp method', function() { + + var result; + + spyOn($window.ga, 'setAnonymizeIp') + .and.callFake(function (anonymize, successCb, errorCb) { + successCb('Set anonymize: ' + anonymize); + }); + + $cordovaGoogleAnalytics + .setAnonymizeIp(true) + .then(function (response) { + result = response; + }); + + $rootScope.$digest(); + + expect(result).toBe('Set anonymize: true'); + expect($window.ga.setAnonymizeIp).toHaveBeenCalledWith( + true, + jasmine.any(Function), + jasmine.any(Function) + ); + }); + + it('should call errorCb when in $window\'s ga.setAnonymizeIp a error orccurs', function() { + + var result; + + spyOn($window.ga, 'setAnonymizeIp') + .and.callFake(function (anonymize, successCb, errorCb) { + errorCb('error orccurs'); + }); + + $cordovaGoogleAnalytics.setAnonymizeIp() + .then(angular.noop, function (response) { + result = response; + }); + + $rootScope.$digest(); + + expect(result).toBe('error orccurs'); + }); + + it('should call $window\'s ga.setAllowIDFACollection method', function() { + + var result; + + spyOn($window.ga, 'setAllowIDFACollection') + .and.callFake(function (enable, successCb, errorCb) { + successCb('Set allow IDFA collection: ' + enable); + }); + + $cordovaGoogleAnalytics + .setAllowIDFACollection(true) + .then(function (response) { + result = response; + }); + + $rootScope.$digest(); + + expect(result).toBe('Set allow IDFA collection: true'); + expect($window.ga.setAllowIDFACollection).toHaveBeenCalledWith( + true, + jasmine.any(Function), + jasmine.any(Function) + ); + }); + + it('should call errorCb when in $window\'s ga.setAllowIDFACollection a error orccurs', function() { + + var result; + + spyOn($window.ga, 'setAllowIDFACollection') + .and.callFake(function (enable, successCb, errorCb) { + errorCb('error orccurs'); + }); + + $cordovaGoogleAnalytics.setAllowIDFACollection() + .then(angular.noop, function (response) { + result = response; + }); + + $rootScope.$digest(); + + expect(result).toBe('error orccurs'); + }); + + it('should call $window\'s ga.enableUncaughtExceptionReporting method', function() { + + var result; + + spyOn($window.ga, 'enableUncaughtExceptionReporting') + .and.callFake(function (enable, successCb, errorCb) { + successCb('Enable uncaught exception reporting: ' + enable); + }); + + $cordovaGoogleAnalytics + .enableUncaughtExceptionReporting(true) + .then(function (response) { + result = response; + }); + + $rootScope.$digest(); + + expect(result).toBe('Enable uncaught exception reporting: true'); + expect($window.ga.enableUncaughtExceptionReporting).toHaveBeenCalledWith( + true, + jasmine.any(Function), + jasmine.any(Function) + ); + }); + + it('should call errorCb when in $window\'s ga.enableUncaughtExceptionReporting a error orccurs', function() { + + var result; + + spyOn($window.ga, 'enableUncaughtExceptionReporting') + .and.callFake(function (enable, successCb, errorCb) { + errorCb('error orccurs'); + }); + + $cordovaGoogleAnalytics.enableUncaughtExceptionReporting() + .then(angular.noop, function (response) { + result = response; + }); + + $rootScope.$digest(); + + expect(result).toBe('error orccurs'); + }); }); From eb6600a78f6308b063960a590a9cc2c9d4dbc81a Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Mon, 22 Aug 2016 17:32:38 +0300 Subject: [PATCH 13/29] ev args added to $cordovaKeyboard events (#1324) --- src/plugins/keyboard.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/keyboard.js b/src/plugins/keyboard.js index 0ac5e41a..d7adf572 100644 --- a/src/plugins/keyboard.js +++ b/src/plugins/keyboard.js @@ -5,15 +5,15 @@ angular.module('ngCordova.plugins.keyboard', []) .factory('$cordovaKeyboard', ['$rootScope', function ($rootScope) { - var keyboardShowEvent = function () { + var keyboardShowEvent = function (ev) { $rootScope.$evalAsync(function () { - $rootScope.$broadcast('$cordovaKeyboard:show'); + $rootScope.$broadcast('$cordovaKeyboard:show', { ev: ev }); }); }; - var keyboardHideEvent = function () { + var keyboardHideEvent = function (ev) { $rootScope.$evalAsync(function () { - $rootScope.$broadcast('$cordovaKeyboard:hide'); + $rootScope.$broadcast('$cordovaKeyboard:hide', { ev: ev }); }); }; From 43fff1a8998762f34464fbe3e25e1661bcde579e Mon Sep 17 00:00:00 2001 From: Niklas M Date: Mon, 22 Aug 2016 16:38:08 +0200 Subject: [PATCH 14/29] Add sqlite functions (#1314) * add SQL Batch * add closeDB + test * fix close * Removed invalid test --- src/plugins/sqlite.js | 23 +++++++++++++++++++++++ test/plugins/sqlite.spec.js | 3 +-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/plugins/sqlite.js b/src/plugins/sqlite.js index dba8e3b3..7dd9b366 100644 --- a/src/plugins/sqlite.js +++ b/src/plugins/sqlite.js @@ -34,6 +34,17 @@ angular.module('ngCordova.plugins.sqlite', []) return q.promise; }, + batch: function (db, queries) { + var q = $q.defer(); + db.sqlBatch(queries, function () { + q.resolve(); + }, + function (error) { + q.reject(error); + }); + return q.promise; + }, + insertCollection: function (db, query, bindings) { var q = $q.defer(); var coll = bindings.slice(0); // clone collection @@ -78,6 +89,18 @@ angular.module('ngCordova.plugins.sqlite', []) return q.promise; }, + closeDB: function (db) { + var q = $q.defer(); + + db.close(function (success) { + q.resolve(success); + }, function (error) { + q.reject(error); + }); + + return q.promise; + }, + deleteDB: function (dbName) { var q = $q.defer(); diff --git a/test/plugins/sqlite.spec.js b/test/plugins/sqlite.spec.js index e99d04b5..1d1e3c0a 100644 --- a/test/plugins/sqlite.spec.js +++ b/test/plugins/sqlite.spec.js @@ -70,7 +70,7 @@ describe('Service: $cordovaSQLite', function() { expect(result).toBe(true); }); - it('should call errorCb when in window\'s sqlitePlugin.deleteDatabase a error orccurs', function() { + it('should call errorCb when in window\'s sqlitePlugin.deleteDatabase an error orccurs', function() { var result; var errorObj = { someError: 1 }; @@ -90,5 +90,4 @@ describe('Service: $cordovaSQLite', function() { expect(result).toBe(errorObj); }); - }); From be147c2dad993ce4e294c68160b62355992ad11c Mon Sep 17 00:00:00 2001 From: Matthieu Date: Mon, 22 Aug 2016 16:39:00 +0200 Subject: [PATCH 15/29] New wrapper for webIntent plugin (#1306) * New wrapper for webIntent plugin * Added webIntent in the README --- README.md | 1 + src/mocks/webIntent.js | 75 ++++++++++++++ src/plugins/webIntent.js | 133 ++++++++++++++++++++++++ test/mocks/webIntent.spec.js | 178 +++++++++++++++++++++++++++++++++ test/plugins/webIntent.spec.js | 92 +++++++++++++++++ 5 files changed, 479 insertions(+) create mode 100644 src/mocks/webIntent.js create mode 100644 src/plugins/webIntent.js create mode 100644 test/mocks/webIntent.spec.js create mode 100644 test/plugins/webIntent.spec.js diff --git a/README.md b/README.md index a712fb6a..e9651ee4 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,7 @@ $ bower install ngCordova - [Touchid](https://github.com/leecrossley/cordova-plugin-touchid) - [Vibration](https://github.com/apache/cordova-plugin-vibration) * - [Video Capture Plus](https://github.com/EddyVerbruggen/VideoCapturePlus-PhoneGap-Plugin) * +- [Web Intent](https://github.com/Initsogar/cordova-webintent) - [Zip](https://github.com/MobileChromeApps/cordova-plugin-zip) `* official Apache Cordova Plugin` diff --git a/src/mocks/webIntent.js b/src/mocks/webIntent.js new file mode 100644 index 00000000..ccf126f2 --- /dev/null +++ b/src/mocks/webIntent.js @@ -0,0 +1,75 @@ +ngCordovaMocks.factory('$webIntent', ['$q', '$rootScope', function($q, $rootScope) { + var scope = $rootScope.$new(); + var has = true; + var url = "http://url.mock/ressource"; + var throwsError = false; + + return{ + has: has, + url: url, + throwsError: throwsError, + + startActivity: function (params) { + var q = $q.defer(); + if(this.throwsError) { + q.reject(new Error()); + } else { + q.resolve(); + } + return q.promise; + }, + hasExtra: function (params) { + var q = $q.defer(); + if(this.throwsError) { + q.reject(new Error()); + } else { + q.resolve(has); + } + return q.promise; + }, + getUri: function () { + var q = $q.defer(); + if(this.throwsError) { + q.reject(new Error()); + } else { + q.resolve(url); + } + return q.promise; + }, + getExtra: function (params) { + var q = $q.defer(); + if(this.throwsError) { + q.reject(new Error()); + } else { + q.resolve(url); + } + return q.promise; + }, + onNewIntent: function (callback) { + scope.$on('newIntent', function() { + callback(url); + }); + }, + newIntent: function() { + scope.$broadcast('newIntent') + }, + sendBroadcast: function (params) { + var q = $q.defer(); + if(this.throwsError) { + q.reject(new Error()); + } else { + q.resolve(); + } + return q.promise; + }, + actionSend: function() {return "actionSend"}, + actionView: function() {return "actionView"}, + actionCall: function() {return "actionCall"}, + actionSendTo: function() {return "actionSendTo"}, + extraText: function() {return "extraText"}, + extraSubject: function() {return "extraSubject"}, + extraStream: function() {return "extraStream"}, + extraEmail: function() {return "extraEmail"} + } + +}]); diff --git a/src/plugins/webIntent.js b/src/plugins/webIntent.js new file mode 100644 index 00000000..ae7b1442 --- /dev/null +++ b/src/plugins/webIntent.js @@ -0,0 +1,133 @@ +// install : cordova plugin add https://github.com/Initsogar/cordova-webintent.git +// link : https://github.com/Initsogar/cordova-webintent + +angular.module('ngCordova.plugins.webIntent', []) + + .factory('$webIntent', ['$q', '$window', function ($q, $window) { + + return { + startActivity: function (params) { + var q = $q.defer(); + + if (!$window.cordova) { + q.reject('Not supported without cordova.js'); + } else { + $window.plugins.webintent.startActivity(params, function (result) { + q.resolve(result); + }, function (err) { + q.reject(err); + }); + } + + return q.promise; + }, + hasExtra: function(params) { + var q = $q.defer(); + + if (!$window.cordova) { + q.reject('Not supported without cordova.js'); + } else { + $window.plugins.webintent.hasExtra(params, function (result) { + q.resolve(result); + }, function (err) { + q.reject(err); + }); + } + + return q.promise; + }, + getUri: function() { + var q = $q.defer(); + + if (!$window.cordova) { + q.reject('Not supported without cordova.js'); + } else { + $window.plugins.webintent.getUri(function (result) { + q.resolve(result); + }, function (err) { + q.reject(err); + }); + } + + return q.promise; + }, + getExtra: function(params) { + var q = $q.defer(); + + if (!$window.cordova) { + q.reject('Not supported without cordova.js'); + } else { + $window.plugins.webintent.getExtra(params, function (result) { + q.resolve(result); + }, function (err) { + q.reject(err); + }); + } + + return q.promise; + }, + onNewIntent: function(callback) { + if ($window.plugins) { + $window.plugins.webintent.onNewIntent(callback); + } + }, + sendBroadcast: function(params) { + var q = $q.defer(); + + if (!$window.cordova) { + q.reject('Not supported without cordova.js'); + } else { + $window.plugins.webintent.sendBroadcast(params, function (result) { + q.resolve(result); + }, function (err) { + q.reject(err); + }); + } + + return q.promise; + }, + + actionSend: function() { + if ($window.plugins) { + return $window.plugins.webintent.ACTION_SEND; + } + }, + actionView: function() { + if ($window.plugins) { + return $window.plugins.webintent.ACTION_VIEW; + } + }, + actionCall: function() { + if ($window.plugins) { + return $window.plugins.webintent.ACTION_CALL; + } + }, + actionSendTo: function() { + if ($window.plugins) { + return $window.plugins.webintent.ACTION_SENDTO; + } + }, + extraText: function() { + if ($window.plugins) { + return $window.plugins.webintent.EXTRA_TEXT; + } + }, + extraSubject: function() { + if ($window.plugins) { + return $window.plugins.webintent.EXTRA_SUBJECT; + } + }, + extraStream: function() { + if ($window.plugins) { + return $window.plugins.webintent.EXTRA_STREAM; + } + }, + extraEmail: function() { + if ($window.plugins) { + return $window.plugins.webintent.EXTRA_EMAIL; + } + } + + + }; + }] ); diff --git a/test/mocks/webIntent.spec.js b/test/mocks/webIntent.spec.js new file mode 100644 index 00000000..74ed3bf6 --- /dev/null +++ b/test/mocks/webIntent.spec.js @@ -0,0 +1,178 @@ +describe('ngCordovaMocks', function() { + + beforeEach(function() { + module('ngCordovaMocks'); + }); + + describe('webIntent', function () { + var $webIntent = null; + var $rootScope = null; + var spy = {}; + + //beforeEach(module('ngCordova.plugins.webIntent')); + + beforeEach(inject(function (_$webIntent_, _$rootScope_) { + $webIntent = _$webIntent_; + $rootScope = _$rootScope_; + + spy.success = jasmine.createSpy('success'); + spy.fail = function() {};//jasmine.createSpy('fail'); + + spyOn(spy, 'fail').and.callThrough(); + })); + + it('should return actionSend on actionSend', function() { + expect($webIntent.actionSend()).toBe("actionSend"); + }); + + it('should return actionView on actionView', function() { + expect($webIntent.actionView()).toBe("actionView"); + }); + + it('should return extraText on extraText', function() { + expect($webIntent.extraText()).toBe("extraText"); + }); + + it('should return extraSubject on extraSubject', function() { + expect($webIntent.extraSubject()).toBe("extraSubject"); + }); + + it('should return extraStream on extraStream', function() { + expect($webIntent.extraStream()).toBe("extraStream"); + }); + + it('should return extraEmail on extraEmail', function() { + expect($webIntent.extraEmail()).toBe("extraEmail"); + }); + + it('should return actionCall on actionCall', function() { + expect($webIntent.actionCall()).toBe("actionCall"); + }); + + it('should return actionSendTo on actionSendTo', function() { + expect($webIntent.actionSendTo()).toBe("actionSendTo"); + }); + + describe('startActivity', function() { + it('should call the success callback', function(done) { + $webIntent.startActivity("myFile") + .then(spy.success).catch(spy.fail).then(function() { + expect(spy.success).toHaveBeenCalled(); + expect(spy.fail).not.toHaveBeenCalled(); + }).finally(done); + + $rootScope.$apply(); + }); + + it('should call the fail callback', function(done) { + $webIntent.throwsError = true; + $webIntent.startActivity("myFile") + .then(spy.success).catch(spy.fail).then(function() { + expect(spy.fail).toHaveBeenCalled(); + expect(spy.success).not.toHaveBeenCalled(); + }).finally(done); + $rootScope.$apply(); + }); + }); + + describe('hasExtra', function() { + it('should call the success callback', function(done) { + $webIntent.hasExtra("extraText") + .then(spy.success).catch(spy.fail).then(function() { + expect(spy.success).toHaveBeenCalledWith($webIntent.has); + expect(spy.fail).not.toHaveBeenCalled(); + }).finally(done); + + $rootScope.$apply(); + }); + + it('should call the fail callback', function(done) { + $webIntent.throwsError = true; + $webIntent.hasExtra("extraText") + .then(spy.success).catch(spy.fail).then(function() { + expect(spy.fail).toHaveBeenCalled(); + expect(spy.success).not.toHaveBeenCalled(); + }).finally(done); + $rootScope.$apply(); + }); + }); + + describe('getExtra', function() { + it('should call the success callback', function(done) { + $webIntent.getExtra("extraText") + .then(spy.success).catch(spy.fail).then(function() { + expect(spy.success).toHaveBeenCalledWith($webIntent.url); + expect(spy.fail).not.toHaveBeenCalled(); + }).finally(done); + + $rootScope.$apply(); + }); + + it('should call the fail callback', function(done) { + $webIntent.throwsError = true; + $webIntent.getExtra("extraText") + .then(spy.success).catch(spy.fail).then(function() { + expect(spy.fail).toHaveBeenCalled(); + expect(spy.success).not.toHaveBeenCalled(); + }).finally(done); + $rootScope.$apply(); + }); + }); + + describe('getUri', function() { + it('should call the success callback', function(done) { + $webIntent.getUri() + .then(spy.success).catch(spy.fail).then(function() { + expect(spy.success).toHaveBeenCalledWith($webIntent.url); + expect(spy.fail).not.toHaveBeenCalled(); + }).finally(done); + + $rootScope.$apply(); + }); + + it('should call the fail callback', function(done) { + $webIntent.throwsError = true; + $webIntent.getUri() + .then(spy.success).catch(spy.fail).then(function() { + expect(spy.fail).toHaveBeenCalled(); + expect(spy.success).not.toHaveBeenCalled(); + }).finally(done); + $rootScope.$apply(); + }); + }); + + describe('onNewIntent', function() { + it('should call the success callback', function() { + $webIntent.onNewIntent(spy.success); + $webIntent.newIntent(); + + expect(spy.success).toHaveBeenCalled(); + }); + }); + + describe('sendBroadcast', function() { + it('should call the success callback', function(done) { + $webIntent.sendBroadcast() + .then(spy.success).catch(spy.fail).then(function() { + expect(spy.success).toHaveBeenCalled(); + expect(spy.fail).not.toHaveBeenCalled(); + }).finally(done); + + $rootScope.$apply(); + }); + + it('should call the fail callback', function(done) { + $webIntent.throwsError = true; + $webIntent.sendBroadcast() + .then(spy.success).catch(spy.fail).then(function() { + expect(spy.fail).toHaveBeenCalled(); + expect(spy.success).not.toHaveBeenCalled(); + }).finally(done); + $rootScope.$apply(); + }); + }); + + + + }); +}); diff --git a/test/plugins/webIntent.spec.js b/test/plugins/webIntent.spec.js new file mode 100644 index 00000000..697114fd --- /dev/null +++ b/test/plugins/webIntent.spec.js @@ -0,0 +1,92 @@ +describe('Service: $webIntent', function() { + + var $webIntent, $rootScope; + + beforeEach(module('ngCordova.plugins.webIntent')); + + beforeEach(inject(function (_$webIntent_, _$q_, _$rootScope_) { + $webIntent = _$webIntent_; + $rootScope = _$rootScope_; + + window.plugins.webintent = { + ACTION_SEND: "actionSend", + ACTION_VIEW: "actionView", + EXTRA_TEXT: "extraText", + EXTRA_SUBJECT: "extraSubject", + EXTRA_STREAM: "extraStream", + EXTRA_EMAIL: "extraEmail", + ACTION_CALL: "actionCall", + ACTION_SENDTO: "actionSendTo", + startActivity: jasmine.createSpy(), + hasExtra: jasmine.createSpy(), + getUri: jasmine.createSpy(), + getExtra: jasmine.createSpy(), + onNewIntent: jasmine.createSpy(), + sendBroadcast: jasmine.createSpy() + }; + })); + + it('should return window.plugins.webintent.ACTION_SEND on actionSend', function() { + expect($webIntent.actionSend()).toBe(window.plugins.webintent.ACTION_SEND); + }); + + it('should return window.plugins.webintent.ACTION_VIEW on actionView', function() { + expect($webIntent.actionView()).toBe(window.plugins.webintent.ACTION_VIEW); + }); + + it('should return window.plugins.webintent.EXTRA_TEXT on extraText', function() { + expect($webIntent.extraText()).toBe(window.plugins.webintent.EXTRA_TEXT); + }); + + it('should return window.plugins.webintent.EXTRA_SUBJECT on extraSubject', function() { + expect($webIntent.extraSubject()).toBe(window.plugins.webintent.EXTRA_SUBJECT); + }); + + it('should return window.plugins.webintent.EXTRA_STREAM on extraStream', function() { + expect($webIntent.extraStream()).toBe(window.plugins.webintent.EXTRA_STREAM); + }); + + it('should return window.plugins.webintent.EXTRA_EMAIL on extraEmail', function() { + expect($webIntent.extraEmail()).toBe(window.plugins.webintent.EXTRA_EMAIL); + }); + + it('should return window.plugins.webintent.ACTION_CALL on actionCall', function() { + expect($webIntent.actionCall()).toBe(window.plugins.webintent.ACTION_CALL); + }); + + it('should return window.plugins.webintent.ACTION_SENDTO on actionSendTo', function() { + expect($webIntent.actionSendTo()).toBe(window.plugins.webintent.ACTION_SENDTO); + }); + + + it('should call window.plugins.webintent.startActivity on startActivity', function() { + $webIntent.startActivity("myFile"); + expect(window.plugins.webintent.startActivity).toHaveBeenCalled(); + }); + + it('should call window.plugins.webintent.hasExtra on hasExtra', function() { + $webIntent.hasExtra($webIntent.extraText()); + expect(window.plugins.webintent.hasExtra).toHaveBeenCalled(); + }); + + it('should call window.plugins.webintent.getExtra on getExtra', function() { + $webIntent.getExtra($webIntent.extraText()); + expect(window.plugins.webintent.getExtra).toHaveBeenCalled(); + }); + + it('should call window.plugins.webintent.getUri on getUri', function() { + $webIntent.getUri(); + expect(window.plugins.webintent.getUri).toHaveBeenCalled(); + }); + + it('should call window.plugins.webintent.onNewIntent on onNewIntent', function() { + $webIntent.onNewIntent(function() {}); + expect(window.plugins.webintent.onNewIntent).toHaveBeenCalled(); + }); + + it('should call window.plugins.webintent.sendBroadcast on sendBroadcast', function() { + $webIntent.sendBroadcast("myFile"); + expect(window.plugins.webintent.sendBroadcast).toHaveBeenCalled(); + }); + +}); From f39878b3465413360c49d55e4265426d93450867 Mon Sep 17 00:00:00 2001 From: Carlos Hernandez Date: Mon, 22 Aug 2016 16:39:58 +0200 Subject: [PATCH 16/29] Add advertising id collection support (to $cordovaGoogleAnalytics) (#1300) * Add advertising id collection support Add the avaliabilty of enable the Advertising ID Collection using the new function added to the plugin (in https://github.com/danwilson/google-analytics-plugin/pull/252) * Epic fail ; to , fix Yes, shit happen. --- src/mocks/googleAnalytics.js | 1 + src/plugins/googleAnalytics.js | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/mocks/googleAnalytics.js b/src/mocks/googleAnalytics.js index ccec0258..90d72bb5 100644 --- a/src/mocks/googleAnalytics.js +++ b/src/mocks/googleAnalytics.js @@ -26,6 +26,7 @@ ngCordovaMocks.factory('$cordovaGoogleAnalytics', ['$q', function ($q) { 'setUserId', 'setAppVersion', 'debugMode', + 'setAllowIDFACollection', 'trackView', 'addCustomDimension', 'trackEvent', diff --git a/src/plugins/googleAnalytics.js b/src/plugins/googleAnalytics.js index 6de9f6ff..e23c7166 100755 --- a/src/plugins/googleAnalytics.js +++ b/src/plugins/googleAnalytics.js @@ -54,6 +54,20 @@ angular.module('ngCordova.plugins.googleAnalytics', []) return d.promise; }, + setAllowIDFACollection: function(enable) { + var d = $q.defer(); + + if(typeof(enable) === 'undefined') { + enable = true; + } + + $window.analytics.setAllowIDFACollection(enable, function (response) { + d.resolve(response); + }, function () { + d.reject(); + }); + }, + trackView: function (screenName) { var d = $q.defer(); From 7a7dc84e945819b1ea5b913d5eea5b034df840e2 Mon Sep 17 00:00:00 2001 From: olivier evalet Date: Mon, 22 Aug 2016 16:40:47 +0200 Subject: [PATCH 17/29] attach promise with media instance (#1288) * attach promise to the media instance * #1288 add cleartimer on stop and release --- src/plugins/media.js | 80 +++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/src/plugins/media.js b/src/plugins/media.js index 93ec8ee8..a9b23d07 100644 --- a/src/plugins/media.js +++ b/src/plugins/media.js @@ -5,26 +5,27 @@ angular.module('ngCordova.plugins.media', []) .service('NewMedia', ['$q', '$interval', function ($q, $interval) { - var q, q2, q3, mediaStatus = null, mediaPosition = -1, mediaTimer, mediaDuration = -1; - function setTimer(media) { - if (angular.isDefined(mediaTimer)) { + // + // Privates functions + function setTimer(player) { + if (angular.isDefined(player.mediaTimer)) { return; } - mediaTimer = $interval(function () { - if (mediaDuration < 0) { - mediaDuration = media.getDuration(); - if (q && mediaDuration > 0) { - q.notify({duration: mediaDuration}); + player.mediaTimer = $interval(function () { + if (player.mediaDuration < 0) { + player.mediaDuration = player.media.getDuration(); + if (player.$defer && player.mediaDuration > 0) { + player.$defer.notify({duration: player.mediaDuration}); } } - media.getCurrentPosition( + player.media.getCurrentPosition( // success callback function (position) { if (position > -1) { - mediaPosition = position; + player.mediaPosition = position; } }, // error callback @@ -32,38 +33,36 @@ angular.module('ngCordova.plugins.media', []) console.log('Error getting pos=' + e); }); - if (q) { - q.notify({position: mediaPosition}); - } + player.$defer.notify({position: player.mediaPosition}); }, 1000); } - function clearTimer() { - if (angular.isDefined(mediaTimer)) { - $interval.cancel(mediaTimer); - mediaTimer = undefined; + function clearTimer(player) { + if (angular.isDefined(player.mediaTimer)) { + $interval.cancel(player.mediaTimer); + player.mediaTimer = undefined; } } - function resetValues() { - mediaPosition = -1; - mediaDuration = -1; - } + // + // Public API function NewMedia(src) { + var self=this; + this.$defer=$q.defer(); + this.mediaPosition = -1; + this.mediaDuration = -1; + this.mediaTimer = undefined; + this.media = new Media(src, function (success) { - clearTimer(); - resetValues(); - q.resolve(success); + self.$defer.resolve(success); }, function (error) { - clearTimer(); - resetValues(); - q.reject(error); + self.$defer.reject(error); }, function (status) { - mediaStatus = status; - q.notify({status: mediaStatus}); + self.media.mediaStatus = status; + self.$defer.notify({status: self.media.mediaStatus}); }); } @@ -71,7 +70,6 @@ angular.module('ngCordova.plugins.media', []) // - myMedia.play({ numberOfLoops: 2 }) -> looping // - myMedia.play({ playAudioWhenScreenIsLocked : false }) NewMedia.prototype.play = function (options) { - q = $q.defer(); if (typeof options !== 'object') { options = {}; @@ -79,23 +77,27 @@ angular.module('ngCordova.plugins.media', []) this.media.play(options); - setTimer(this.media); + setTimer(this); - return q.promise; + return this.$defer.promise; }; NewMedia.prototype.pause = function () { - clearTimer(); + clearTimer(this); this.media.pause(); }; NewMedia.prototype.stop = function () { + clearTimer(this); this.media.stop(); }; NewMedia.prototype.release = function () { + clearTimer(this); this.media.release(); this.media = undefined; + this.mediaPosition = -1; + this.mediaDuration = -1; }; NewMedia.prototype.seekTo = function (timing) { @@ -115,19 +117,19 @@ angular.module('ngCordova.plugins.media', []) }; NewMedia.prototype.currentTime = function () { - q2 = $q.defer(); + var q = $q.defer(); this.media.getCurrentPosition(function (position){ - q2.resolve(position); + q.resolve(position); }); - return q2.promise; + return q.promise; }; NewMedia.prototype.getDuration = function () { - q3 = $q.defer(); + var q = $q.defer(); this.media.getDuration(function (duration){ - q3.resolve(duration); + q.resolve(duration); }); - return q3.promise; + return q.promise; }; return NewMedia; From 1f7429958e7b0f11e5cef652ab8817cf4967b9aa Mon Sep 17 00:00:00 2001 From: Niklas M Date: Thu, 25 Aug 2016 19:15:17 +0200 Subject: [PATCH 18/29] Removed duplicate function (#1329) I added the type check to the existing function and removed the new one fixes driftyco/ng-cordova#1328 --- src/plugins/googleAnalytics.js | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/plugins/googleAnalytics.js b/src/plugins/googleAnalytics.js index e23c7166..58c5ae7b 100755 --- a/src/plugins/googleAnalytics.js +++ b/src/plugins/googleAnalytics.js @@ -54,20 +54,6 @@ angular.module('ngCordova.plugins.googleAnalytics', []) return d.promise; }, - setAllowIDFACollection: function(enable) { - var d = $q.defer(); - - if(typeof(enable) === 'undefined') { - enable = true; - } - - $window.analytics.setAllowIDFACollection(enable, function (response) { - d.resolve(response); - }, function () { - d.reject(); - }); - }, - trackView: function (screenName) { var d = $q.defer(); @@ -188,7 +174,7 @@ angular.module('ngCordova.plugins.googleAnalytics', []) d.resolve(response); }, function (error) { d.reject(error); - }); + }); return d.promise; }, @@ -196,6 +182,10 @@ angular.module('ngCordova.plugins.googleAnalytics', []) enableUncaughtExceptionReporting: function (enable) { var d = $q.defer(); + if(typeof(enable) === 'undefined') { + enable = true; + } + $window.ga.enableUncaughtExceptionReporting(enable, function (response) { d.resolve(response); }, function (error) { From 4218730d1c22246d6ef860029fa24bb4dedf597e Mon Sep 17 00:00:00 2001 From: Niklas M Date: Fri, 26 Aug 2016 03:31:05 +0200 Subject: [PATCH 19/29] Changed license field in package.json and added keywords + Readme title (#1336) * Changed license field in package.json and added keywords Added linebreak to remove strange title on npm page * Added tags from bower --- README.md | 1 + package.json | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e9651ee4..fa946a95 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ [ngCordova](http://ngcordova.com/) + ========== [![Travis](https://img.shields.io/travis/driftyco/ng-cordova.svg?style=flat)](https://travis-ci.org/driftyco/ng-cordova) [![Bower](https://img.shields.io/badge/bower-ngCordova-FFCC2F.svg?style=flat)](http://bower.io/search/?q=ngCordova) diff --git a/package.json b/package.json index 96f86c31..3187392d 100644 --- a/package.json +++ b/package.json @@ -27,10 +27,18 @@ "minimist": "^0.1.0", "phantomjs-prebuilt": "^2.1.4" }, - "licenses": [ - { - "type": "MIT" - } + + "keywords": [ + "ngCordova", + "ng-cordova", + "ngcordova", + "ng cordova", + "cordova", + "phonegap", + "angular", + "angularjs", + "ionic", + "cordova plugin" ], "scripts": { "test": "gulp lint && gulp karma --browsers=PhantomJS --reporters=progress" From db29fba032be219b296fbb2f9cb1a69b819f21e5 Mon Sep 17 00:00:00 2001 From: Niklas M Date: Tue, 13 Sep 2016 06:05:06 -0700 Subject: [PATCH 20/29] Make executesql more efficient (#1337) close driftyco/ng-cordova#1319 --- src/plugins/sqlite.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/plugins/sqlite.js b/src/plugins/sqlite.js index 7dd9b366..475edcaf 100644 --- a/src/plugins/sqlite.js +++ b/src/plugins/sqlite.js @@ -23,13 +23,11 @@ angular.module('ngCordova.plugins.sqlite', []) execute: function (db, query, binding) { var q = $q.defer(); - db.transaction(function (tx) { - tx.executeSql(query, binding, function (tx, result) { - q.resolve(result); - }, - function (transaction, error) { - q.reject(error); - }); + db.executeSql(query, binding, function (result) { + q.resolve(result); + }, + function (error) { + q.reject(error); }); return q.promise; }, From 04b6c5a320b0aeb8d85578e0bc7c36c31067358c Mon Sep 17 00:00:00 2001 From: Nicolas Galler Date: Tue, 13 Sep 2016 08:05:49 -0500 Subject: [PATCH 21/29] Add instagram mock (#1262) --- src/mocks/instagram.js | 53 ++++++++++++++++++++++++ test/mocks/instagram.spec.js | 79 ++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 src/mocks/instagram.js create mode 100644 test/mocks/instagram.spec.js diff --git a/src/mocks/instagram.js b/src/mocks/instagram.js new file mode 100644 index 00000000..0bdca5ef --- /dev/null +++ b/src/mocks/instagram.js @@ -0,0 +1,53 @@ +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaInstagram + * + * @description + * A service for testing instagram features + * in an app build with ngCordova. + **/ +ngCordovaMocks.factory('$cordovaInstagram', ['$q', function ($q) { + var throwsError = false; + var returnIsInstalled = true; + + return { + + /** + * @ngdoc property + * @name throwsError + * @propertyOf ngCordovaMocks.cordovaInstagram + * + * @description + * A flag that signals whether a promise should be rejected or not. + * This property should only be used in automated tests. + **/ + throwsError: throwsError, + + /** + * @ngdoc property + * @name returnIsInstalled + * @propertyOf ngCordovaMocks.cordovaInstagram + * + * @description + * A flag that signals whether the mock should simulate that the instagram app + * is installed or not. + * This property should only be used in automated tests. + **/ + returnIsInstalled: returnIsInstalled, + + share: function (options) { + if(this.throwsError) { + return $q.reject('an error occurred'); + } + return $q.when(true); + }, + + + isInstalled: function () { + if(this.throwsError) { + return $q.reject('an error occurred'); + } + return $q.when(this.returnIsInstalled); + } + } +}]); diff --git a/test/mocks/instagram.spec.js b/test/mocks/instagram.spec.js new file mode 100644 index 00000000..60cd0eed --- /dev/null +++ b/test/mocks/instagram.spec.js @@ -0,0 +1,79 @@ +describe('ngCordovaMocks', function() { + beforeEach(function() { + module('ngCordovaMocks'); + }); + + describe('cordovaInstagram', function () { + var $rootScope = null; + var $cordovaInstagram = null; + var shareOptions = {}; + + beforeEach(inject(function (_$cordovaInstagram_, _$rootScope_) { + $cordovaInstagram = _$cordovaInstagram_; + $rootScope = _$rootScope_; + })); + + it('should share', function (done) { + $cordovaInstagram.share(shareOptions) + .then( + function() { expect(true).toBe(true); }, + function() { expect(false).toBe(true); } + ) + .finally(done) + ; + + $rootScope.$digest(); + }); + + it('should throw an error while sharing.', function(done) { + $cordovaInstagram.throwsError = true; + $cordovaInstagram.share(shareOptions) + .then( + function() { expect(true).toBe(false); }, + function() { expect(true).toBe(true); } + ) + .finally(done) + ; + + $rootScope.$digest(); + }); + + it('should return is installed', function (done) { + $cordovaInstagram.isInstalled() + .then( + function(isInstalled) { expect(isInstalled).toBe(true); }, + function() { expect(false).toBe(true); } + ) + .finally(done) + ; + + $rootScope.$digest(); + }); + + it('should throw an error while checking isInstalled.', function(done) { + $cordovaInstagram.throwsError = true; + $cordovaInstagram.isInstalled() + .then( + function() { expect(true).toBe(false); }, + function() { expect(true).toBe(true); } + ) + .finally(done) + ; + + $rootScope.$digest(); + }); + + it('should return isInstalled as false', function(done) { + $cordovaInstagram.returnIsInstalled = false; + $cordovaInstagram.isInstalled() + .then( + function(isInstalled) { expect(isInstalled).toBe(false); }, + function() { expect(true).toBe(true); } + ) + .finally(done) + ; + + $rootScope.$digest(); + }); + }); +}); From b041f8098d54463152849440998715d10958d8eb Mon Sep 17 00:00:00 2001 From: Fabio Huser Date: Tue, 13 Sep 2016 15:07:22 +0200 Subject: [PATCH 22/29] chore(npm): remove fs npm package (#1330) The module `fs` is not actually needed to require the standard library `fs`. This module was temporarily wiped, since the whole module only consists out of a single `console.log(...)` [1]. [1] http://status.npmjs.org/incidents/dw8cr1lwxkcr --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 3187392d..4c690658 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,6 @@ }, "dependencies": { "conventional-changelog": "0.0.11", - "fs": "0.0.2", "gulp-git": "^1.2.4", "q": "^1.1.2" } From a38470ec51e137d9344bc667f5416c8a57699a68 Mon Sep 17 00:00:00 2001 From: John Wnek Date: Tue, 13 Sep 2016 09:07:49 -0400 Subject: [PATCH 23/29] added hasPermission method to cordovaPushV5 and created initial spec suite (#1335) --- src/plugins/push_v5.js | 7 +++++ test/plugins/push_V5.spec.js | 53 ++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 test/plugins/push_V5.spec.js diff --git a/src/plugins/push_v5.js b/src/plugins/push_v5.js index 02706e9c..dcdb555f 100644 --- a/src/plugins/push_v5.js +++ b/src/plugins/push_v5.js @@ -14,6 +14,13 @@ angular.module('ngCordova.plugins.push_v5', []) q.resolve(push); return q.promise; }, + hasPermission : function () { + var q = $q.defer(); + PushNotification.hasPermission(function(response) { + q.resolve(response); + }); + return q.promise; + }, onNotification : function () { $timeout(function () { push.on('notification', function (notification) { diff --git a/test/plugins/push_V5.spec.js b/test/plugins/push_V5.spec.js new file mode 100644 index 00000000..6896e5bb --- /dev/null +++ b/test/plugins/push_V5.spec.js @@ -0,0 +1,53 @@ +describe('Service: $cordovaPushV5', function() { + + var $cordovaPushV5, $rootScope; + + beforeEach(module('ngCordova.plugins.push_v5')); + + beforeEach(inject(function (_$cordovaPushV5_, _$rootScope_) { + $cordovaPushV5 = _$cordovaPushV5_; + $rootScope = _$rootScope_; + + + window.PushNotification = { + init: angular.noop, + hasPermission: angular.noop, + }; + })); + + it('should call the PushNotification.init method', function() { + + var result; + var config = { someConfig: 1 }; + + spyOn(window.PushNotification, 'init').and.returnValue(true); + + $cordovaPushV5.initialize(config) + .then(function (response) { + result = response; + }); + + $rootScope.$digest(); + expect(window.PushNotification.init.calls.argsFor(0)[0]).toBe(config); + expect(result).toBe(true); + }); + + it('should call the PushNotification.hasPermission method', function() { + + var result; + + spyOn(window.PushNotification, 'hasPermission') + .and.callFake(function (successCb) { + successCb({ isEnabled: true }); + }); + + $cordovaPushV5.hasPermission() + .then(function (response) { + result = response; + }); + + $rootScope.$digest(); + expect(window.PushNotification.hasPermission).toHaveBeenCalled; + expect(result.isEnabled).toBe(true); + }); +}); From 82be9be34efc7874b1242f1e4884f22439979d10 Mon Sep 17 00:00:00 2001 From: fantapop Date: Tue, 13 Sep 2016 06:09:58 -0700 Subject: [PATCH 24/29] return after promises are rejected (#1074) From fe850f824574b0241dc75a5fa61c46b8822f83c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatas=20Gusm=C3=A3o?= Date: Tue, 13 Sep 2016 12:28:44 -0300 Subject: [PATCH 25/29] [] Using db.sqlBatch within insertCollection (#1344) --- src/plugins/sqlite.js | 61 +++++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/src/plugins/sqlite.js b/src/plugins/sqlite.js index 475edcaf..7e6a74a0 100644 --- a/src/plugins/sqlite.js +++ b/src/plugins/sqlite.js @@ -44,28 +44,49 @@ angular.module('ngCordova.plugins.sqlite', []) }, insertCollection: function (db, query, bindings) { + if (!bindings || bindings.constructor !== Array) { + throw new Error('insertCollection expects an array'); + } + var q = $q.defer(); - var coll = bindings.slice(0); // clone collection - db.transaction(function (tx) { - (function insertOne() { - var record = coll.splice(0, 1)[0]; // get the first record of coll and reduce coll by one - try { - tx.executeSql(query, record, function (tx, result) { - if (coll.length === 0) { - q.resolve(result); - } else { - insertOne(); - } - }, function (transaction, error) { - q.reject(error); - return; - }); - } catch (exception) { - q.reject(exception); - } - })(); - }); + if (db.sqlBatch) { + var queryBatch = [], i = 0, len = bindings.length; + + for (i; i < len; i++) { + queryBatch.push([query, bindings[i]]); + } + + db.sqlBatch(queryBatch, + function() { + q.resolve(); + }, function(error) { + q.reject(error); + }); + } else { + var coll = bindings.slice(0); // clone collection + + db.transaction(function (tx) { + (function insertOne() { + var record = coll.splice(0, 1)[0]; // get the first record of coll and reduce coll by one + try { + tx.executeSql(query, record, function (tx, result) { + if (coll.length === 0) { + q.resolve(result); + } else { + insertOne(); + } + }, function (transaction, error) { + q.reject(error); + return; + }); + } catch (exception) { + q.reject(exception); + } + })(); + }); + } + return q.promise; }, From 75688e848f8727dbe7dcdd6840c6837f9b04f1b9 Mon Sep 17 00:00:00 2001 From: Niklas M Date: Wed, 21 Sep 2016 06:08:09 -0700 Subject: [PATCH 26/29] Add fingerprint aio plugin (#1347) * Add fingerprint aio plugin * Tests fingerprint * fingerprint * Fingerprint to build * Fix camelcase * fixup! Fix camelcase --- README.md | 1 + src/plugins/3dtouch.js | 28 ++++---- src/plugins/fingerprint.js | 41 +++++++++++ src/plugins/module.js | 1 + src/plugins/serial.js | 12 ++-- test/plugins/fingerprint.spec.js | 112 +++++++++++++++++++++++++++++++ 6 files changed, 175 insertions(+), 20 deletions(-) create mode 100644 src/plugins/fingerprint.js create mode 100644 test/plugins/fingerprint.spec.js diff --git a/README.md b/README.md index fa946a95..52955873 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,7 @@ $ bower install ngCordova - [Facebook AudienceNetwork Ads](https://github.com/floatinghotpot/cordova-plugin-facebookads) (:warning: share % Ad revenue) - [File](https://github.com/apache/cordova-plugin-file) * - [File Transfer](https://github.com/apache/cordova-plugin-file-transfer) * +- [Fingerprint](https://github.com/NiklasMerz/cordova-plugin-fingerprint-aio) * - [Flashlight](https://github.com/EddyVerbruggen/Flashlight-PhoneGap-Plugin) - [Flurry Ads](https://github.com/floatinghotpot/cordova-plugin-flurry) (:warning: share % Ad revenue) - [Geolocation](https://github.com/apache/cordova-plugin-geolocation) * diff --git a/src/plugins/3dtouch.js b/src/plugins/3dtouch.js index 9313569f..9338a79b 100644 --- a/src/plugins/3dtouch.js +++ b/src/plugins/3dtouch.js @@ -3,11 +3,11 @@ angular.module('ngCordova.plugins.3dtouch', []) - .factory('$cordova3DTouch', ['$q', function($q) { + .factory('$cordova3DTouch', ['$q', function ($q) { var quickActions = []; var quickActionHandler = {}; - var createQuickActionHandler = function(quickActionHandler) { + var createQuickActionHandler = function (quickActionHandler) { return function (payload) { for (var key in quickActionHandler) { if (payload.type === key) { @@ -52,7 +52,7 @@ angular.module('ngCordova.plugins.3dtouch', []) * @param function callback (optional) * @return promise */ - addQuickAction: function(type, title, iconType, iconTemplate, subtitle, callback) { + addQuickAction: function (type, title, iconType, iconTemplate, subtitle, callback) { var deferred = $q.defer(); var quickAction = { @@ -69,14 +69,14 @@ angular.module('ngCordova.plugins.3dtouch', []) quickAction.iconTemplate = iconTemplate; } - this.isAvailable().then(function() { + this.isAvailable().then(function () { quickActions.push(quickAction); quickActionHandler[type] = callback; window.ThreeDeeTouch.configureQuickActions(quickActions); window.ThreeDeeTouch.onHomeIconPressed = createQuickActionHandler(quickActionHandler); deferred.resolve(quickActions); }, - function(err) { + function (err) { deferred.reject(err); }); @@ -90,15 +90,15 @@ angular.module('ngCordova.plugins.3dtouch', []) * @param function callback * @return promise */ - addQuickActionHandler: function(type, callback) { + addQuickActionHandler: function (type, callback) { var deferred = $q.defer(); - this.isAvailable().then(function() { + this.isAvailable().then(function () { quickActionHandler[type] = callback; window.ThreeDeeTouch.onHomeIconPressed = createQuickActionHandler(quickActionHandler); deferred.resolve(true); }, - function(err) { + function (err) { deferred.reject(err); }); @@ -110,14 +110,14 @@ angular.module('ngCordova.plugins.3dtouch', []) * * @return bool */ - enableLinkPreview: function() { + enableLinkPreview: function () { var deferred = $q.defer(); - this.isAvailable().then(function() { + this.isAvailable().then(function () { window.ThreeDeeTouch.enableLinkPreview(); deferred.resolve(true); }, - function(err) { + function (err) { deferred.reject(err); }); @@ -130,14 +130,14 @@ angular.module('ngCordova.plugins.3dtouch', []) * @param function callback * @return promise */ - addForceTouchHandler: function(callback) { + addForceTouchHandler: function (callback) { var deferred = $q.defer(); - this.isAvailable().then(function() { + this.isAvailable().then(function () { window.ThreeDeeTouch.watchForceTouches(callback); deferred.resolve(true); }, - function(err) { + function (err) { deferred.reject(err); }); diff --git a/src/plugins/fingerprint.js b/src/plugins/fingerprint.js new file mode 100644 index 00000000..5d72969c --- /dev/null +++ b/src/plugins/fingerprint.js @@ -0,0 +1,41 @@ +// install : cordova plugin add https://github.com/NiklasMerz/cordova-plugin-fingerprint-aio +// link : https://github.com/NiklasMerz/cordova-plugin-fingerprint-aio + +/* globals Fingerprint: true */ +angular.module('ngCordova.plugins.fingerprint', []) + + .factory('$cordovaFingerprint', ['$q', function ($q) { + + return { + isAvailable: function () { + var defer = $q.defer(); + if (!window.cordova) { + defer.reject('Not supported without cordova.js'); + } else { + Fingerprint.isAvailable(function (value) { + defer.resolve(value); + }, function (err) { + defer.reject(err); + }); + } + + return defer.promise; + }, + + show: function (options) { + var defer = $q.defer(); + if (!window.cordova) { + defer.reject('Not supported without cordova.js'); + } else { + Fingerprint.show(options, + function (value) { + defer.resolve(value); + }, function (err) { + defer.reject(err); + }); + } + + return defer.promise; + } + }; + }]); diff --git a/src/plugins/module.js b/src/plugins/module.js index 829e90fe..c2a19210 100644 --- a/src/plugins/module.js +++ b/src/plugins/module.js @@ -29,6 +29,7 @@ angular.module('ngCordova.plugins', [ 'ngCordova.plugins.file', 'ngCordova.plugins.fileTransfer', 'ngCordova.plugins.fileOpener2', + 'ngCordova.plugins.fingerprint', 'ngCordova.plugins.flashlight', 'ngCordova.plugins.flurryAds', 'ngCordova.plugins.ga', diff --git a/src/plugins/serial.js b/src/plugins/serial.js index 14bd286f..a732be4d 100644 --- a/src/plugins/serial.js +++ b/src/plugins/serial.js @@ -20,7 +20,7 @@ angular.module('ngCordova.plugins.serial', []) return q.promise; }; - serialService.open = function(options) { + serialService.open = function (options) { var q = $q.defer(); serial.open(options, function success() { @@ -32,7 +32,7 @@ angular.module('ngCordova.plugins.serial', []) return q.promise; }; - serialService.write = function(data) { + serialService.write = function (data) { var q = $q.defer(); serial.write(data, function success() { @@ -44,7 +44,7 @@ angular.module('ngCordova.plugins.serial', []) return q.promise; }; - serialService.writeHex = function(data) { + serialService.writeHex = function (data) { var q = $q.defer(); serial.writeHex(data, function success() { @@ -56,7 +56,7 @@ angular.module('ngCordova.plugins.serial', []) return q.promise; }; - serialService.read = function() { + serialService.read = function () { var q = $q.defer(); serial.read(function success(buffer) { @@ -69,14 +69,14 @@ angular.module('ngCordova.plugins.serial', []) return q.promise; }; - serialService.registerReadCallback = function(successCallback, errorCallback) { + serialService.registerReadCallback = function (successCallback, errorCallback) { serial.registerReadCallback(function success(buffer) { var view = new Uint8Array(buffer); successCallback(view); }, errorCallback); }; - serialService.close = function() { + serialService.close = function () { var q = $q.defer(); serial.close(function success() { diff --git a/test/plugins/fingerprint.spec.js b/test/plugins/fingerprint.spec.js new file mode 100644 index 00000000..60d8241b --- /dev/null +++ b/test/plugins/fingerprint.spec.js @@ -0,0 +1,112 @@ +describe('Service: $cordovaFingerprint', function() { + + var $cordovaTouchID, $rootScope; + + beforeEach(module('ngCordova.plugins.fingerprint')); + + beforeEach(inject(function (_$cordovaFingerprint_, _$q_, _$rootScope_) { + $cordovaFingerprint = _$cordovaFingerprint_; + $rootScope = _$rootScope_; + + window.Fingerprint = { + isAvailable: angular.noop, + show: angular.noop + }; + })); + + it("calls isAvailable", function() { + var result; + + spyOn(window.Fingerprint, 'isAvailable') + .and.callFake(function(successCb, errCb) { + successCb(); + }); + + $cordovaFingerprint.isAvailable() + .then(function() { + result = true; + }); + $rootScope.$digest(); + expect(result).toBe(true); + expect(window.Fingerprint.isAvailable).toHaveBeenCalledWith( + jasmine.any(Function), + jasmine.any(Function) + ); + }); + + it("rejects isAvailable on err callback", function() { + var errorResult; + + spyOn(window.Fingerprint, 'isAvailable') + .and.callFake(function(successCb, errCb) { + errCb("Not available in test"); + }); + + $cordovaFingerprint.isAvailable() + .then(angular.noop, + function(err) { + errorResult = false; + } + ); + $rootScope.$digest(); + expect(errorResult).toBe(false); + }); + + it("rejects checkSupport when window.cordova is not present", function() { + var errorResult; + _cordova = window.cordova; + window.cordova = null; + + $cordovaFingerprint.isAvailable() + .then(angular.noop, + function(err) { + errorResult = false; + } + ); + $rootScope.$digest(); + expect(errorResult).toBe(false); + + window.cordova = _cordova + }); + + it("calls show with options", function() { + var result; + var options = { + clientId: "ngCordova", + clientSecret: "test" + }; + + spyOn(window.Fingerprint, 'show') + .and.callFake(function(options, successCb, errCb) { + successCb(); + }); + + $cordovaFingerprint.show(options) + .then(function() { + result = true; + }); + $rootScope.$digest(); + expect(result).toBe(true); + expect(window.Fingerprint.show).toHaveBeenCalledWith( + options, + jasmine.any(Function), + jasmine.any(Function) + ); + }); + + it("rejects show when window.cordova is not present", function() { + var errorResult; + _cordova = window.cordova; + window.cordova = null; + + $cordovaFingerprint.show() + .then(angular.noop, + function(err) { + errorResult = false; + } + ); + $rootScope.$digest(); + expect(errorResult).toBe(false); + window.cordova = _cordova + }); +}); From ca3225e6ed29691a157138cae605bbab54243537 Mon Sep 17 00:00:00 2001 From: Carson Drake Date: Wed, 21 Sep 2016 06:45:03 -0700 Subject: [PATCH 27/29] the 'OR' operator ignores all zero values when checking if a preference is set for (#1345) --- src/plugins/appRate.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/appRate.js b/src/plugins/appRate.js index b649f445..b238c9b9 100644 --- a/src/plugins/appRate.js +++ b/src/plugins/appRate.js @@ -30,7 +30,7 @@ angular.module('ngCordova.plugins.appRate', []) AppRate.preferences.displayAppName = defaults.appName || ''; AppRate.preferences.promptAgainForEachNewVersion = defaults.promptForNewVersion || true; AppRate.preferences.openStoreInApp = defaults.openStoreInApp || false; - AppRate.preferences.usesUntilPrompt = defaults.usesUntilPrompt || 3; + AppRate.preferences.usesUntilPrompt = (typeof defaults.usesUntilPrompt === 'undefined'|| defaults.usesUntilPrompt===null)?3:defaults.usesUntilPrompt; AppRate.preferences.useCustomRateDialog = defaults.useCustomRateDialog || false; AppRate.preferences.storeAppURL.ios = defaults.iosURL || null; AppRate.preferences.storeAppURL.android = defaults.androidURL || null; From e69b0dc1021ae4f3c4a0b636084c50c3bc0c1ba1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1r=20Do=C4=9Fan?= Date: Thu, 22 Sep 2016 17:27:35 +0300 Subject: [PATCH 28/29] Screen Size --- src/plugins/module.js | 1 + src/plugins/screensize.js | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 src/plugins/screensize.js diff --git a/src/plugins/module.js b/src/plugins/module.js index c2a19210..328c71ae 100644 --- a/src/plugins/module.js +++ b/src/plugins/module.js @@ -62,6 +62,7 @@ angular.module('ngCordova.plugins', [ 'ngCordova.plugins.progressIndicator', 'ngCordova.plugins.push', 'ngCordova.plugins.push_v5', + 'ngCordova.plugins.screensize', 'ngCordova.plugins.sms', 'ngCordova.plugins.socialSharing', 'ngCordova.plugins.spinnerDialog', diff --git a/src/plugins/screensize.js b/src/plugins/screensize.js new file mode 100644 index 00000000..c292ed4a --- /dev/null +++ b/src/plugins/screensize.js @@ -0,0 +1,16 @@ +angular.module('ngCordova.plugins.screensize', []) + + .factory('$cordovaScreenSize', ['$q', '$window', function ($q, $window) { + return { + + get: function () { + var q = $q.defer(); + $window.plugins.screensize.get(function (result) { + q.resolve(result); + }, function (error) { + q.reject(); + }); + return q.promise; + } + } + }]); From ba01defac5dbd52981f102a9d9d284bb988b0cc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1r=20Do=C4=9Fan?= Date: Thu, 22 Sep 2016 17:37:49 +0300 Subject: [PATCH 29/29] update --- src/plugins/screensize.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/screensize.js b/src/plugins/screensize.js index c292ed4a..3f487474 100644 --- a/src/plugins/screensize.js +++ b/src/plugins/screensize.js @@ -8,9 +8,9 @@ angular.module('ngCordova.plugins.screensize', []) $window.plugins.screensize.get(function (result) { q.resolve(result); }, function (error) { - q.reject(); + q.reject(error); }); return q.promise; } - } + }; }]);