diff options
Diffstat (limited to 'www/lib/ngCordova/dist/ng-cordova-mocks.js')
| -rw-r--r-- | www/lib/ngCordova/dist/ng-cordova-mocks.js | 3443 |
1 files changed, 3443 insertions, 0 deletions
diff --git a/www/lib/ngCordova/dist/ng-cordova-mocks.js b/www/lib/ngCordova/dist/ng-cordova-mocks.js new file mode 100644 index 00000000..0cf15abd --- /dev/null +++ b/www/lib/ngCordova/dist/ng-cordova-mocks.js @@ -0,0 +1,3443 @@ +/*! + * ngCordova + * v0.1.26-alpha + * Copyright 2015 Drifty Co. http://drifty.com/ + * See LICENSE in this repository for license information + */ +(function(){ +var ngCordovaMocks = angular.module('ngCordovaMocks', []); +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaActionSheet + * + * @description + * A service for testing action sheet + * in an app build with ngCordova. + **/ +ngCordovaMocks.factory('$cordovaActionSheet', ['$q', function ($q) { + var throwsError = false; + + return { + /** + * @ngdoc property + * @name throwsError + * @propertyOf ngCordovaMocks.cordovaActionSheet + * @type Boolean + * + * @description + * A flag that signals whether a promise should be rejected. + * This property should only be used in automated tests + */ + throwsError: throwsError, + + show: function () { + var defer = $q.defer(); + + if (this.throwsError) { + defer.reject('There was an error on showing action sheet'); + } else { + defer.resolve(); + } + + return defer.promise; + } + }; +}]); + +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; + } + }; +}]); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaBarcodeScanner + * + * @description + * A service for testing barcode scanner features + * in an app build with ngCordova. + **/ +ngCordovaMocks.factory('$cordovaBarcodeScanner', ['$q', function ($q) { + var throwsError = false; + + var scannedText = ''; + var scannedFormat = ''; + var wasCancelled = false; + + return { + /** + * @ngdoc property + * @name throwsError + * @propertyOf ngCordovaMocks.cordovaBarcodeScanner + * + * @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 scannedText + * @propertyOf ngCordovaMocks.cordovaBarcodeScanner + * + * @description + * Used to simulate the result.text property of a + * successful scan. For more information, see the text at + * https://github.com/wildabeast/BarcodeScanner/#using-the-plugin + * This property should only be used in automated tests. + **/ + scannedText: scannedText, + + /** + * @ngdoc property + * @name scannedFormat + * @propertyOf ngCordovaMocks.cordovaBarcodeScanner + * @description + * Used to simulate the result.format property of a + * successful scan. For more information, see the text at + * https://github.com/wildabeast/BarcodeScanner/#using-the-plugin + * This property should only be used in automated tests. + **/ + scannedFormat: scannedFormat, + + /** + * @ngdoc property + * @name wasCancelled + * @propertyOf ngCordovaMocks.cordovaBarcodeScanner + * + * @description + * Used to simulate the result.cancelled property of a + * successful scan. For more information, see the text at + * https://github.com/wildabeast/BarcodeScanner/#using-the-plugin + * This property should only be used in automated tests. + **/ + wasCancelled: wasCancelled, + + scan: function () { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error scanning.'); + } else { + defer.resolve({text: this.scannedText, format: this.scannedFormat, cancelled: this.wasCancelled}); + } + + return defer.promise; + }, + + encode: function (type, data) { + this.scannedFormat = type; + this.scannedText = data; + + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error encoding the data.'); + } else { + defer.resolve(); + } + + return defer.promise; + } + }; +}]); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaBLE + * + * @description + * A service for ble features + * in an app build with ngCordova. + **/ +ngCordovaMocks.factory('$cordovaBLE', ['$q', '$timeout', '$interval', '$log', function ($q, $timeout, $interval, $log) { + var deviceScan = { + name: 'Test Device', + id: 'AA:BB:CC:DD:EE:FF', + advertising: [2, 1, 6, 3, 3, 15, 24, 8, 9, 66, 97, 116, 116, 101, 114, 121], + rssi: -55 + }; + + var deviceConnect = { + name: 'Test Device', + id: 'AA:BB:CC:DD:EE:FF', + advertising: [2, 1, 6, 3, 3, 15, 24, 8, 9, 66, 97, 116, 116, 101, 114, 121], + rssi: -55, + services: [ + '1800', + '1801', + '180f' + ], + characteristics: [ + { + service: '1800', + characteristic: '2a00', + properties: ['Read'] + }, + { + service: '1800', + characteristic: '2a01', + properties: ['Read'] + }, + { + service: '1801', + characteristic: '2a05', + properties: ['Read'] + }, + { + service: '180f', + characteristic: '2a19', + properties: ['Read'], + descriptors: [{'uuid': '2901'}, {'uuid': '2904'}] + } + ] + }; + + var readData = new ArrayBuffer(8); + + return { + + scan: function (services, seconds) { + var q = $q.defer(); + + // first notify about discovered device + $timeout(function () { + q.notify(deviceScan); + }, Math.round(seconds * 1000 * Math.random())); + + // end scan + $timeout(function () { + q.resolve(); + }, seconds * 1000); + + return q.promise; + }, + + startScan: function (services, callback, errorCallback) { + $timeout(function () { + callback(deviceScan); + }, Math.round(1000 * Math.random())); + }, + + stopScan: function () { + var q = $q.defer(); + $timeout(function () { + q.resolve(); + }, 500); + return q.promise; + }, + + connect: function (deviceID) { + var q = $q.defer(); + $timeout(function () { + q.resolve(deviceConnect); + }, 1500); + return q.promise; + }, + + disconnect: function (deviceID) { + var q = $q.defer(); + $timeout(function () { + q.resolve(true); + }, 500); + return q.promise; + }, + + read: function (deviceID, serviceUUID, characteristicUUID) { + var q = $q.defer(); + $timeout(function () { + q.resolve(readData); + }, 100); + return q.promise; + }, + + write: function (deviceID, serviceUUID, characteristicUUID, data) { + var q = $q.defer(); + $timeout(function () { + q.resolve(true); + }, 100); + return q.promise; + }, + + writeWithoutResponse: function (deviceID, serviceUUID, characteristicUUID, data) { + var q = $q.defer(); + $timeout(function () { + q.resolve(true); + }, 100); + return q.promise; + }, + + writeCommand: function (deviceID, serviceUUID, characteristicUUID, data) { + $log.warning('writeCommand is deprecated, use writeWithoutResponse'); + return this.writeWithoutResponse(deviceID, serviceUUID, characteristicUUID, data); + }, + + startNotification: function (deviceID, serviceUUID, characteristicUUID, callback, errorCallback) { + $interval(function () { + var data = new Uint8Array([Math.round(255 * Math.random())]); // one byte with random number + callback(data); + }, 200, 10); // repeat 10 times with 200 ms delay for each + }, + + stopNotification: function (deviceID, serviceUUID, characteristicUUID) { + var q = $q.defer(); + $timeout(function () { + q.resolve(); + }, 100); + return q.promise; + }, + + isConnected: function (deviceID) { + var q = $q.defer(); + q.resolve(true); + return q.promise; + }, + + enable: function () { + var q = $q.defer(); + $timeout(function () { + q.resolve(); + }, 1500); + return q.promise; + }, + + isEnabled: function () { + var q = $q.defer(); + q.resolve(true); + return q.promise; + } + }; +}]); + +ngCordovaMocks.factory('$cordovaBrightness', ['$q', function ($q) { + var currentBrightness = 100; + + return { + get: function () { + var q = $q.defer(); + q.resolve(currentBrightness); + return q.promise; + }, + + set: function (data) { + var q = $q.defer(); + currentBrightness = data; + q.resolve('OK'); + return q.promise; + }, + + setKeepScreenOn: function (bool) { + var q = $q.defer(); + q.resolve('OK'); + return q.promise; + } + }; +}]); +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaCamera + * + * @description + * A service for testing camera features + * in an app build with ngCordova. + **/ +ngCordovaMocks.factory('$cordovaCamera', ['$q', function ($q) { + var throwsError = false; + var imageData = ''; + + return { + + /** + * @ngdoc property + * @name throwsError + * @propertyOf ngCordovaMocks.cordovaCamera + * + * @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 imageData + * @propertyOf ngCordovaMocks.cordovaCamera + * + * @description + * The imagedata (e.g. an url) which will be returned from the device. + * This property should only be used in automated tests. + **/ + imageData: imageData, + + getPicture: function (options) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error getting the picture.'); + } else { + if (options) { + options = options; // This is just to get by JSHint. + } + + defer.resolve(this.imageData); + } + + return defer.promise; + } + }; +}]); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaCapture + * + * @description + * A service for testing media capture + * in an app build with ngCordova. + * + * @example + */ +ngCordovaMocks.factory('$cordovaCapture', ['$q', function ($q) { + var throwsError = false; + + return { + /** + * @ngdoc property + * @name throwsError + * @propertyOf ngCordovaMocks.cordovaCapture + * + * @description + * A flag that signals whether a promise should be rejected or not. + * This property should only be used in automated tests. + **/ + throwsError: throwsError, + + captureAudio: function () { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error capturing the audio.'); + } else { + defer.resolve(); + } + + return defer.promise; + }, + + captureImage: function () { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error capturing the image.'); + } else { + defer.resolve(); + } + + return defer.promise; + }, + + captureVideo: function () { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error capturing the video.'); + } else { + defer.resolve(); + } + + return defer.promise; + } + }; +}]); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaContacts + * + * @description + * A service for testing features related with contacts + * in an app build with ngCordova. + **/ +ngCordovaMocks.factory('$cordovaContacts', ['$q', function ($q) { + var throwsError = false; + var contacts = []; + + return { + /** + @ngdoc property + @name throwsError + @propertyOf ngCordovaMocks.cordovaContacts + + @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 contacts + @name throwsError + @propertyOf ngCordovaMocks.cordovaContacts + + @description + An in-memory collection of contacts. + This property should only be used in automated tests. + */ + contacts: contacts, + + save: function (contact) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error saving the contact.'); + } else { + var existingIndex = null; + for (var i = 0; i < this.contacts.length; i++) { + // The actual implementation relies on the entire object match. + // we're gong to rely on the ID. + if (this.contacts[i].id === contact.id) { + existingIndex = i; + break; + } + } + + if (existingIndex === null) { + this.contacts.push(contact); + defer.resolve(); + } else { + defer.reject('Contact already exists.'); + } + } + + return defer.promise; + }, + + remove: function (contact) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error saving the contact.'); + } else { + var toRemove = null; + for (var i = 0; i < this.contacts.length; i++) { + // The actual implementation relies on the entire object match. + // we're gong to rely on the ID. + if (this.contacts[i].id === contact.id) { + toRemove = i; + break; + } + } + + if (toRemove === null) { + defer.reject('Unable to find contact.'); + } else { + this.contacts.splice(toRemove, 1); + defer.resolve(); + } + } + + return defer.promise; + }, + + find: function (options) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error finding the contact.'); + } else { + var fields = options.fields || ['id', 'displayName']; + delete options.fields; + + if (!fields) { + defer.reject('ContactError.INVALID_ARGUMENT_ERROR'); + } else { + if (fields === '*') { + defer.resolve(this.contacts); + } else { + // Implement a very rudimentary search approach for testing purposes. + // This is NOT exhaustive. + var results = []; + for (var i = 0; i < this.contacts.length; i++) { + for (var key in this.contacts[i]) { + var propertyValue = this.contacts[i][key]; + } + } + + // TODO: Search by individual fields + defer.resolve(results); + } + } + } + + return defer.promise; + } + }; +}]); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaDatePicker + * + * @description + * A service for testing datepicker features + * in an app build with ngCordova. + */ +ngCordovaMocks.factory('$cordovaDatePicker', ['$q', function ($q) { + return { + show: function (options) { + var q = $q.defer(); + options = options || {date: new Date(), mode: 'date'}; + q.resolve(options.date); + return q.promise; + } + }; +}]); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaDevice + * + * @description + * A service for testing device information + * in an app build with ngCordova. + **/ +ngCordovaMocks.factory('$cordovaDevice', function () { + var device = ''; + var cordova = ''; + var model = ''; + var platform = ''; + var uuid = ''; + var version = ''; + + return { + /** + @ngdoc property + @name device + @propertyOf ngCordovaMocks.cordovaDevice + + @description + The name of the 'device'. + This property should only be used in automated tests. + */ + device: device, + + /** + @ngdoc property + @name cordova + @propertyOf ngCordovaMocks.cordovaDevice + + @description + The version of cordova in use. + This property should only be used in automated tests. + */ + cordova: cordova, + + /** + @ngdoc property + @name model + @propertyOf ngCordovaMocks.cordovaDevice + + @description + The model of the device using the app. + This property should only be used in automated tests. + */ + model: model, + + /** + @ngdoc property + @name platform + @propertyOf ngCordovaMocks.cordovaDevice + + @description + The name of the operating system in use. + This property should only be used in automated tests. + */ + platform: platform, + + /** + @ngdoc property + @name uuid + @propertyOf ngCordovaMocks.cordovaDevice + + @description + The unique identifier of a device. + This property should only be used in automated tests. + */ + uuid: uuid, + + /** + @ngdoc property + @name version + @propertyOf ngCordovaMocks.cordovaDevice + + @description + The version of the operating system. + This property should only be used in automated tests. + */ + version: version, + + /** + @ngdoc property + @name manufacturer + @propertyOf ngCordovaMocks.cordovaDevice + + @description + The manufacturer of the device. + This property should only be used in automated tests. + */ + version: version, + + getDevice: function () { + return this.device; + }, + + getCordova: function () { + return this.cordova; + }, + + getModel: function () { + return this.model; + }, + + getPlatform: function () { + return this.platform; + }, + + getUUID: function () { + return this.uuid; + }, + + getVersion: function () { + return this.version; + }, + + getManufacturer: function () { + return this.manufacturer; + } + }; +}); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaDeviceMotion + * + * @description + * A service for mocking the accelerometer + * in an app build with ngCordova. + **/ +ngCordovaMocks.factory('$cordovaDeviceMotion', ['$interval', '$q', function ($interval, $q) { + var currentAcceleration = null; + var throwsError = false; + var positions = []; + var watchIntervals = []; + + return { + /** + * @ngdoc property + * @name currentAcceleration + * @propertyOf ngCordovaMocks.cordovaDeviceMotion + * + * @description + * The current acceleration. + * This property should only be used in automated tests. + **/ + currentAcceleration: currentAcceleration, + + /** + @ngdoc property + @name throwsError + @propertyOf ngCordovaMocks.cordovaDeviceMotion + + @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 positions + @propertyOf ngCordovaMocks.cordovaDeviceMotion + + @description + The collection of 'positions' that have been logged. + This property should only be used in automated tests. + */ + positions: positions, + + /** + @ngdoc property + @name watchIntervals + @propertyOf ngCordovaMocks.cordovaDeviceMotion + + @description + The collection of watchers that are currently active. + This property should only be used in automated tests. + */ + watchIntervals: watchIntervals, + + getCurrentAcceleration: function () { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error getting the current acceleration.'); + } else { + defer.resolve(this.currentAcceleration); + } + + return defer.promise; + }, + + watchAcceleration: function (options) { + var defer = $q.defer(); + var watchId = Math.floor((Math.random() * 1000000) + 1); + + this.positions = []; + self = this; + + if (this.throwsError) { + defer.reject('There was an error watching the current acceleration.'); + } else { + var delay = 10000; // The default based on https://github.com/apache/cordova-plugin-device-motion + if (options && options.frequency) { + delay = options.frequency; + } + + this.watchIntervals.push($interval( + function () { + if (self.throwsError) { + defer.reject('There was an error watching the acceleration.'); + } + + // Generate a random position + var randomX = Math.floor((Math.random() * 100) + 1); + var randomY = Math.floor((Math.random() * 100) + 1); + var randomZ = Math.floor((Math.random() * 100) + 1); + var result = {x: randomX, y: randomY, z: randomZ, timestamp: Date.now()}; + + self.positions.push(result); + defer.notify(result); + }, + delay + )); + } + + return { + watchId: watchId, + promise: defer.promise + }; + }, + + clearWatch: function (watchId) { + var defer = $q.defer(); + if (watchId) { + if (this.throwsError) { + defer.reject('Unable to clear watch.'); + } else { + var removed = -1; + for (var i = 0; i < this.watchIntervals.length; i++) { + if (this.watchIntervals[i].watchId === watchId) { + $interval.cancel(watchIntervals[i].interval); + removed = i; + break; + } + } + + if (removed !== -1) { + this.watchIntervals.splice(removed, 1); + } + } + } else { + defer.reject('Unable to clear watch. No watch ID provided.'); + } + + return defer.promise; + } + }; +}]); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaDeviceOrientation + * + * @description + * A service for testing compass fetures + * in an app build with ngCordova. + */ +ngCordovaMocks.factory('$cordovaDeviceOrientation', ['$interval', '$q', function ($interval, $q) { + var currentHeading = null; + var throwsError = false; + var readings = []; + var watchIntervals = []; + + return { + /** + * @ngdoc property + * @name currentHeading + * @propertyOf ngCordovaMocks.cordovaDeviceOrientation + * + * @description + * The current heading. + * This property should only be used in automated tests. + **/ + currentHeading: currentHeading, + + /** + @ngdoc property + @name throwsError + @propertyOf ngCordovaMocks.cordovaDeviceOrientation + + @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 positions + @propertyOf ngCordovaMocks.cordovaDeviceOrientation + + @description + The collection of compass 'readings' that have been logged. + This property should only be used in automated tests. + */ + readings: readings, + + /** + @ngdoc property + @name watchIntervals + @propertyOf ngCordovaMocks.cordovaDeviceOrientation + + @description + The collection of watchers that are currently active. + This property should only be used in automated tests. + */ + watchIntervals: watchIntervals, + + getCurrentHeading: function () { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error getting the current heading.'); + } else { + defer.resolve(this.currentHeading); + } + + return defer.promise; + }, + + watchHeading: function (options) { + var defer = $q.defer(); + var watchID = Math.floor((Math.random() * 1000000) + 1); + var self = this; + + self.readings = []; + + if (self.throwsError) { + defer.reject('There was an error getting the compass heading.'); + } else { + var delay = 100; // The default based on https://github.com/apache/cordova-plugin-device-orientation + if (options && options.frequency) { + delay = options.frequency; + } + + self.watchIntervals.push({ + watchID: watchID, + interval: $interval( + function () { + if (self.throwsError) { + defer.reject('There was an error watching the acceleration.'); + } + + // Generate a random position + var magneticHeading = (Math.random() * 359.99) + 1; + var trueHeading = (Math.random() * 359.99) + 1; + var headingAccuracy = Math.floor((Math.random() * 360) + 1); + var result = {magneticHeading: magneticHeading, trueHeading: trueHeading, headingAccuracy: headingAccuracy, timestamp: Date.now()}; + + self.readings.push(result); + defer.notify(result); + }, + delay + ) + }); + } + + var cancel = function (id) { + var removed = -1; + for (var i = 0; i < self.watchIntervals.length; i++) { + if (self.watchIntervals[i].watchID === id) { + $interval.cancel(watchIntervals[i].interval); + removed = i; + break; + } + } + + if (removed !== -1) { + self.watchIntervals.splice(removed, 1); + } + }; + + defer.promise.cancel = function () { + cancel(watchID); + }; + + defer.promise.clearWatch = function (id) { + cancel(id || watchID); + }; + + defer.promise.watchID = watchID; + + return defer.promise; + }, + + clearWatch: function (watchId) { + var defer = $q.defer(); + if (watchId) { + if (this.throwsError) { + defer.reject('Unable to clear watch.'); + } else { + var removed = -1; + for (var i = 0; i < this.watchIntervals.length; i++) { + if (this.watchIntervals[i].watchId === watchId) { + $interval.cancel(watchIntervals[i].interval); + removed = i; + break; + } + } + + if (removed !== -1) { + this.watchIntervals.splice(removed, 1); + } + } + } else { + defer.reject('Unable to clear watch. No watch ID provided.'); + } + + return defer.promise; + } + }; +}]); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaDialogs + * + * @description + * A service for testing dialogs + * in an app build with ngCordova. + */ +ngCordovaMocks.factory('$cordovaDialogs', ['$q', function ($q) { + var dialogText = false; + var dialogTitle = ''; + var defaultValue = ''; + var promptResponse = ''; + var beepCount = 0; + var useHostAbilities = true; + + return { + /** + @ngdoc property + @name dialogText + @propertyOf ngCordovaMocks.cordovaDialogs + + @description + The main content in the dialog. + This property should only be used in automated tests. + */ + dialogText: dialogText, + + /** + @ngdoc property + @name dialogTitle + @propertyOf ngCordovaMocks.cordovaDialogs + + @description + The title of the dialog. + This property should only be used in automated tests. + */ + dialogTitle: dialogTitle, + + /** + @ngdoc property + @name defaultValue + @propertyOf ngCordovaMocks.cordovaDialogs + + @description + The default value to be used in a prompt. + This property should only be used in automated tests. + */ + defaultValue: defaultValue, + + /** + @ngdoc property + @name promptResponse + @propertyOf ngCordovaMocks.cordovaDialogs + + @description + Used to simulate a user's response to a prompt. + This property should only be used in automated tests. + */ + promptResponse: promptResponse, + + /** + @ngdoc property + @name buttonLabels + @propertyOf ngCordovaMocks.cordovaDialogs + + @description + An array of the text of each button in the dialog. + This property should only be used in automated tests. + */ + buttonLabels: [], + + /** + @ngdoc property + @name beepCount + @propertyOf ngCordovaMocks.cordovaDialogs + + @description + The number of times a beep has occurred. + This property should only be used in automated tests. + */ + beepCount: beepCount, + + /** + @ngdoc property + @name useHostAbilities + @propertyOf ngCordovaMocks.cordovaDialogs + + @description + A flag that signals whether or not to try and use the host's + (browser or otherwise) prompting capabilities. + This property should only be used in automated tests. + */ + useHostAbilities: useHostAbilities, + + alert: function (message, title, buttonName) { + var d = $q.defer(); + + if (this.useHostAbilities) { + // NOTE: The window.alert method doesn't support a title or callbacks. + alert(message); + d.resolve(); + } else { + this.dialogText = message; + this.dialogTitle = title; + this.buttonLabels.push(buttonName); + d.resolve(); + } + + return d.promise; + }, + + confirm: function (message, title, buttonName) { + var d = $q.defer(); + + if (this.useHostAbilities) { + // NOTE: The window.confirm method doesn't support a title or custom button naming. + var result = confirm(message); + d.resolve(result ? 2 : 1); + } else { + this.dialogText = message; + this.dialogTitle = title; + this.buttonLabels.push(buttonName); + d.resolve(0); + } + + return d.promise; + }, + + prompt: function (message, title, buttonLabels, defaultText) { + var d = $q.defer(); + + if (this.useHostAbilities) { + // NOTE: The window.prompt method doesn't support a title or custom button naming. + var result = prompt(message, defaultText); + d.resolve(result); + } else { + this.dialogText = message; + this.dialogTitle = title; + this.defaultValue = defaultText; + + for (var i = 0; i < buttonLabels.length; i++) { + this.buttonLabels.push(buttonLabels[i]); + } + + d.resolve(this.promptResponse); + } + + return d.promise; + }, + + beep: function (times) { + this.beepCount = times; + } + }; +}]); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaFacebook + * + * @description + * A service for testing Facebook features + * in an app built with ngCordova. + **/ +ngCordovaMocks.factory('$cordovaFacebook', ['$q', function ($q) { + return { + + /** + * These properties are here for the purpose of automated testing only. + **/ + loginShouldSucceedWith: null, + showDialogShouldSucceedWith: null, + apiShouldSucceedWith: null, + getAccessTokenShouldSucceedWith: null, + getLoginStatusShouldSucceedWith: null, + logoutShouldSuceedWith: null, + + login: function (permissions) { + if (this.loginShouldSucceedWith !== null) { + return $q.when(this.loginShouldSucceedWith); + } else { + return $q.reject(); + } + }, + + showDialog: function (options) { + if (this.showDialogShouldSucceedWith !== null) { + return $q.when(this.showDialogShouldSucceedWith); + } else { + return $q.reject(); + } + }, + + api: function (path, permissions) { + if (this.apiShouldSucceedWith !== null) { + return $q.when(this.apiShouldSucceedWith); + } else { + return $q.reject(); + } + }, + + getAccessToken: function () { + if (this.getAccessTokenShouldSucceedWith !== null) { + return $q.when(this.getAccessTokenShouldSucceedWith); + } else { + return $q.reject(); + } + }, + + getLoginStatus: function () { + if (this.getLoginStatusShouldSucceedWith !== null) { + return $q.when(this.getLoginStatusShouldSucceedWith); + } else { + return $q.reject(); + } + }, + + logout: function () { + if (this.logoutShouldSuceedWith !== null) { + return $q.when(this.logoutShouldSuceedWith); + } else { + return $q.reject(); + } + } + }; +}]); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaFile + * + * @description + * A service for testing interaction with device directories and files + * in an app build with ngCordova. + */ +ngCordovaMocks.factory('$cordovaFile', ['$q', function ($q) { + var throwsError = false; + var fileSystem = {}; + var shouldMockFiles = false; + var files = {}; + + var mockIt = function (errorMessage) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject(errorMessage); + } else { + defer.resolve(); + } + + return defer.promise; + }; + + return { + /** + * @ngdoc property + * @name throwsError + * @propertyOf ngCordovaMocks.cordovaFile + * + * @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 fileSystem + * @propertyOf ngCordovaMocks.cordovaFile + * + * @description + * A fake, in-memory file system. This is incomplete at this time. + * This property should only be used in automated tests. + **/ + fileSystem: fileSystem, + + /** + * @ngdoc property + * @name shouldMockFiles + * @propertyOf ngCordovaMocks.cordovaFile + * + * @description + * A flag that signals whether one wish to mock files. + * This is useful if you need mocks specific file scenarios. + * This property should only be used in automated tests. + **/ + shouldMockFiles: shouldMockFiles, + + /** + * @ngdoc property + * @name files + * @propertyOf ngCordovaMocks.cordovaFile + * + * @description + * An object that may be used for mocking files on the device. + * This property should only be used in automated tests. + * + * **/ + files: files, + + checkDir: function (directory) { + if (this.shouldMockFiles) { + var defer = $q.defer(); + if (this.files[directory] && !this.files[directory].isFile) { + defer.resolve(); + } else { + defer.reject(); + } + + return defer.promise; + } + + return mockIt.call(this, 'There was an error checking the directory.'); + }, + + createDir: function (directory, overwrite) { + if (this.shouldMockFiles) { + var defer = $q.defer(); + this.files[directory] = {isFile: false}; + defer.resolve(); + return defer.promise; + } + + return mockIt.call(this, 'There was an error creating the directory.'); + }, + + listDir: function (filePath) { + return mockIt.call(this, 'There was an error listing the directory'); + }, + + checkFile: function (filePath) { + if (this.shouldMockFiles) { + var defer = $q.defer(); + if (this.files[filePath] && this.files[filePath].isFile) { + defer.resolve(); + } else { + defer.reject(); + } + + return defer.promise; + } + + return mockIt.call(this, 'There was an error checking for the file.'); + }, + + createFile: function (filePath, overwrite) { + if (this.shouldMockFiles) { + var defer = $q.defer(); + this.files[filePath] = { + isFile: true, + fileContent: '' + }; + defer.resolve(); + return defer.promise; + } + + return mockIt.call(this, 'There was an error creating the file.'); + }, + + removeFile: function (directory, file) { + return mockIt.call(this, 'There was an error removng the file.'); + }, + + writeFile: function (filePath, data, options) { + if (this.shouldMockFiles && filePath && data) { + this.files[filePath] = { + isFile: true, + fileContent: data + }; + } + + return mockIt.call(this, 'There was an error writing the file.'); + }, + + readFile: function (filePath) { + return this.readAsText(filePath); + }, + + readAsText: function (filePath) { + if (this.shouldMockFiles) { + var defer = $q.defer(); + if (files[filePath] && files[filePath].isFile) { + defer.resolve(files[filePath].fileContent); + } else { + defer.reject(); + } + + return defer.promise; + } + + return mockIt.call(this, 'There was an error reading the file as text.'); + }, + + readAsDataURL: function (filePath) { + return mockIt.call(this, 'There was an error reading the file as a data url.'); + }, + + readAsBinaryString: function (filePath) { + return mockIt.call(this, 'There was an error reading the file as a binary string.'); + }, + + readAsArrayBuffer: function (filePath) { + return mockIt.call(this, 'There was an error reading the file as an array buffer.'); + }, + + readFileMetadata: function (filePath) { + return mockIt.call(this, 'There was an error reading the file metadata'); + }, + + readFileAbsolute: function (filePath) { + return mockIt.call(this, 'There was an error reading the file from the absolute path'); + }, + + readFileMetadataAbsolute: function (filePath) { + return mockIt.call(this, 'There was an error reading the file metadta from the absolute path'); + } + }; +}]); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaFileOpener2 + * + * @description + * A service for testing fileOpener2 + * in an app build with ngCordova. + */ +ngCordovaMocks.factory('$cordovaFileOpener2', ['$q', function ($q) { + + var throwsError = false; + + return { + + /** + * @ngdoc property + * @name throwsError + * @propertyOf ngCordovaMocks.cordovaFileOpener2 + * + * @description + * A flag that signals whether a promise should be rejected or not. + * This property should only be used in automated tests. + **/ + throwsError: throwsError, + + open: function (file, type) { + + var defer = $q.defer(); + + if (this.throwError) { + defer.reject({ + status: 0, + message: 'There was an error capturing the file.' + }); + } else { + defer.resolve(); + } + + return defer.promise; + + }, + + uninstall: function (pack) { + + var defer = $q.defer(); + + if (this.throwError) { + defer.reject({ + status: 0, + message: 'There was an error capturing the packageId.' + }); + } else { + defer.resolve(); + } + + return defer.promise; + + }, + + appIsInstalled: function (pack) { + + var defer = $q.defer(); + + if (this.throwError) { + defer.reject({ + status: 0, + message: 'There was an error capturing the packageId.' + }); + } else { + defer.resolve(); + } + + return defer.promise; + + } + + }; + +}]); + + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaFileTransfer + * + * @description + * A service for testing download and upload + * in an app build with ngCordova. + */ +ngCordovaMocks.factory('$cordovaFileTransfer', ['$q', function ($q) { + var throwsError = false; + + var mockIt = function (errorMessage) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject(errorMessage); + } else { + defer.resolve(); + } + return defer.promise; + }; + + return { + /** + * @ngdoc property + * @name throwsError + * @propertyOf ngCordovaMocks.cordovaFileTransfer + * + * @description + * A flag that signals whether a promise should be rejected or not. + * This property should only be used in automated tests. + **/ + throwsError: throwsError, + + download: function (source, filePath, options, trust) { + return mockIt.call(this, 'There was an error downloading the file.'); + }, + + upload: function (server, filePath, options) { + return mockIt.call(this, 'There was an error uploading the file.'); + } + }; +}]); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaGeolocation + * + * @description + * A service for testing location services + * in an app build with ngCordova. + */ +ngCordovaMocks.factory('$cordovaGeolocation', ['$interval', '$q', function ($interval, $q) { + var throwsError = false; + var useHostAbilities = true; + + var watchIntervals = []; + var locations = []; + var currentPosition = null; + var nextPosition = null; + + return { + /** + @ngdoc property + @name throwsError + @propertyOf ngCordovaMocks.cordovaGeolocation + + @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 watchIntervals + @propertyOf ngCordovaMocks.cordovaGeolocation + + @description + The collection of watchers that are currently active. + This property should only be used in automated tests. + */ + watchIntervals: watchIntervals, + + /** + @ngdoc property + @name locations + @propertyOf ngCordovaMocks.cordovaGeolocation + + @description + The collection of 'locations' that have been logged. + This property should only be used in automated tests. + */ + locations: locations, + + /** + @ngdoc property + @name currentPosition + @propertyOf ngCordovaMocks.cordovaGeolocation + + @description + The last location logged. + This property should only be used in automated tests. + */ + currentPosition: currentPosition, + + /** + @ngdoc property + @name nextPosition + @propertyOf ngCordovaMocks.cordovaGeolocation + + @description + The position to be logged the next time that a watcher + gets the location. + This property should only be used in automated tests. + */ + nextPosition: nextPosition, + + /** + @ngdoc property + @name useHostAbilities + @propertyOf ngCordovaMocks.cordovaGeolocation + + @description + A flag that signals whether or not to try and use the host's + (browser or otherwise) geolocation capabilities. + This property should only be used in automated tests. + */ + useHostAbilities: useHostAbilities, + + getCurrentPosition: function (options) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error getting the location.'); + } else { + if (options) { + options = options; // This is just to get by JSHint. + } + + if (this.useHostAbilities) { + if (navigator.geolocation) { + navigator.geolocation.getCurrentPosition( + function (position) { + this.currentPosition = position; + defer.resolve(this.currentPosition); + }, + function (error) { + defer.reject(error); + } + ); + } else { + defer.reject('Geolocation is not supported by this browser.'); + } + } else { + defer.resolve(this.currentPosition); + } + } + + return defer.promise; + }, + + watchPosition: function (options) { + var defer = $q.defer(); + var watchID = Math.floor((Math.random() * 1000000) + 1); + var self = this; + + self.locations = []; + + if (self.throwsError) { + defer.reject('There was an error getting the geolocation.'); + } else { + var delay = 1000; + if (options && options.timeout) { + delay = options.timeout; + } + + self.watchIntervals.push({ + watchID: watchID, + interval: $interval( + function () { + if (self.throwsError) { + defer.reject('There was an error watching the geolocation.'); + } + + // Attempt to use nextPosition. + var result = self.nextPosition; + if (result === null) { + // Determine whether to use the host's geolocation capabilities or not + if (self.useHostAbilities) { + if (navigator.geolocation) { + navigator.geolocation.getCurrentPosition( + function (position) { + self.currentPosition = position; + self.locations.push(position); + defer.resolve(position); + }, + function (error) { + defer.reject(error); + } + ); + } else { + defer.reject('Geolocation is not supported by this browser.'); + } + } else { + result = { + coords: { + latitude: ((Math.random() * 180) + 1) - 90, + longitude: ((Math.random() * 360) + 1) - 180, + altitude: ((Math.random() * 100) + 1), + + accuracy: ((Math.random() * 10) + 1), + altitudeAccuracy: ((Math.random() * 10) + 1), + heading: ((Math.random() * 360) + 1), + speed: ((Math.random() * 100) + 1) + }, + timestamp: Date.now() + }; + + self.currentPosition = result; + self.locations.push(result); + defer.notify(result); + } + } + }, + delay + ) + }); + } + + var cancel = function (id) { + var removed = -1; + for (var i = 0; i < self.watchIntervals.length; i++) { + if (self.watchIntervals[i].watchID === id) { + $interval.cancel(watchIntervals[i].interval); + removed = i; + break; + } + } + + if (removed !== -1) { + self.watchIntervals.splice(removed, 1); + } + }; + + defer.promise.cancel = function () { + cancel(watchID); + }; + + defer.promise.clearWatch = function (id) { + cancel(id || watchID); + }; + + defer.promise.watchID = watchID; + + return defer.promise; + }, + + clearWatch: function (watchID) { + var defer = $q.defer(); + if (watchID) { + if (this.throwsError) { + defer.reject('Unable to clear watch.'); + } else { + var removed = -1; + for (var i = 0; i < this.watchIntervals.length; i++) { + if (this.watchIntervals[i].watchID === watchID) { + $interval.cancel(watchIntervals[i].interval); + removed = i; + break; + } + } + + if (removed !== -1) { + this.watchIntervals.splice(removed, 1); + } + } + } else { + defer.reject('Unable to clear watch. No watch ID provided.'); + } + + return defer.promise; + } + }; +}]); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaGlobalization + * + * @description + * A service for testing features related to a user's locale and timezone. + * in an app build with ngCordova. + */ +ngCordovaMocks.factory('$cordovaGlobalization', ['$q', function ($q) { + var throwsError = false; + var language = (navigator.language) ? navigator.language : 'en-US'; + var preferredLanguage = {value: language}; + var firstDayOfWeek = 'Sunday'; + var localeName = {value: language}; + + return { + /** + * @ngdoc property + * @name throwsError + * @propertyOf ngCordovaMocks.cordovaGlobalization + * + * @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 preferredLanguage + * @propertyOf ngCordovaMocks.cordovaGlobalization + * + * @description + * The user's preferred language. + * This property should only be used in automated tests. + **/ + preferredLanguage: preferredLanguage, + + /** + * @ngdoc property + * @name localeName + * @propertyOf ngCordovaMocks.cordovaGlobalization + * + * @description + * The name of the user's locale. + * This property should only be used in automated tests. + **/ + localeName: localeName, + + /** + * @ngdoc property + * @name firstDayOfWeek + * @propertyOf ngCordovaMocks.cordovaGlobalization + * + * @description + * The first day of the week based on the user's locale. + * This property should only be used in automated tests. + **/ + firstDayOfWeek: firstDayOfWeek, + + getPreferredLanguage: function () { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error getting the preferred language.'); + } else { + defer.resolve(this.preferredLanguage); + } + + return defer.promise; + }, + + getLocaleName: function () { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error getting the locale name.'); + } else { + defer.resolve(this.localeName); + } + + return defer.promise; + }, + + getFirstDayOfWeek: function () { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error getting the first day of week.'); + } else { + defer.resolve(this.firstDayOfWeek); + } + + return defer.promise; + }, + + dateToString: function (date, options) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error getting the string from the date.'); + } else { + var result = ''; + + // TODO: Review + date = date; + options = options; + + // END TODO: Review + + defer.resolve(result); + } + + return defer.promise; + }, + + stringToDate: function (dateString, options) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error getting the date from the string.'); + } else { + var result = ''; + + // TODO: Review + dateString = dateString; + options = options; + + // END TODO: Review + + defer.resolve(result); + } + + return defer.promise; + }, + + getDatePattern: function (options) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error getting the date pattern.'); + } else { + var result = ''; + + // TODO: Review + options = options; + + // END TODO: Review + + defer.resolve(result); + } + + return defer.promise; + }, + + getDateNames: function (options) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error getting the date names.'); + } else { + var result = ''; + + // TODO: Review + options = options; + + // END TODO: Review + + defer.resolve(result); + } + + return defer.promise; + }, + + isDayLightSavingsTime: function (date) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error getting if this is in daylight savings time mode.'); + } else { + var result = ''; + + // TODO: Review + date = date; + + // END TODO: Review + + defer.resolve(result); + } + + return defer.promise; + }, + + numberToString: function (number, options) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error convertng the number to a string.'); + } else { + var result = ''; + + // TODO: Review + number = number; + options = options; + + // END TODO: Review + + defer.resolve(result); + } + + return defer.promise; + }, + + stringToNumber: function (numberString, options) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error convertng the string to a number.'); + } else { + var result = ''; + + // TODO: Review + options = options; + + // END TODO: Review + + defer.resolve(result); + } + + return defer.promise; + }, + + getNumberPattern: function (options) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error convertng the string to a number.'); + } else { + var result = ''; + + // TODO: Review + options = options; + + // END TODO: Review + + defer.resolve(result); + } + + return defer.promise; + }, + + getCurrencyPattern: function (currencyCode) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error convertng the string to a number.'); + } else { + var result = ''; + + // TODO: Review + currencyCode = currencyCode; + + // END TODO: Review + + defer.resolve(result); + } + + return defer.promise; + } + }; +}]); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaGoogleAnalytics + * + * @description + * A service for testing google analytics services + * in an app build with ngCordova. + */ +ngCordovaMocks.factory('$cordovaGoogleAnalytics', ['$q', function ($q) { + var throwsError = false; + var methods = {}; + + /** + * @ngdoc property + * @name throwsError + * @propertyOf ngCordovaMocks.cordovaGeolocation + * + * @description + * A flag that signals whether a promise should be rejected or not. + * This property should only be used in automated tests. + **/ + methods.throwsError = throwsError; + + var methodsName = [ + 'startTrackerWithId', + 'setUserId', + 'debugMode', + 'trackView', + 'addCustomDimension', + 'trackEvent', + 'trackException', + 'trackTiming', + 'addTransaction', + 'addTransactionItem' + ]; + + methodsName.forEach(function (funcName) { + methods[funcName] = function () { + var defer = $q.defer(); + + (this.throwsError) ? + defer.reject() : + defer.resolve(); + + return defer.promise; + }; + }); + + return methods; +}]); + +'use strict'; + +/** + * @ngdoc service + * @name ngCordovaMocks.googlePlayGame + * + * @description + * A service for testing Google Play Game features + * in an app build with ngCordova. + */ +ngCordovaMocks.factory('$cordovaGooglePlayGame', ['$q', function ($q) { + var throwsError = false; + var isSignedIn = false; + var displayName = ''; + + return { + + /** + * @ngdoc property + * @name _throwsError + * @propertyOf ngCordovaMocks.googlePlayGame + * + * @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 _isSignedIn + * @propertyOf ngCordovaMocks.googlePlayGame + * + * @description + * A flag that signals whether a promise should be rejected or not. + * This property should only be used in automated tests. + **/ + _isSignedIn: isSignedIn, + + /** + * @ngdoc property + * @name _displayName + * @propertyOf ngCordovaMocks.googlePlayGame + * + * @description + * A flag that signals whether a promise should be rejected or not. + * This property should only be used in automated tests. + **/ + _displayName: displayName, + + auth: function () { + var defer = $q.defer(); + if (this._throwsError) { + defer.reject('There was a auth error.'); + } else { + this.isSignedIn = true; + defer.resolve('SIGN IN SUCCESS'); + } + + return defer.promise; + }, + signout: function () { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was a signout error.'); + } else { + defer.resolve(); + } + + return defer.promise; + }, + isSignedIn: function () { + var defer = $q.defer(); + if (this._throwsError) { + defer.reject('There was a isSignedIn error.'); + } else { + defer.resolve({ + 'isSignedIn': this._isSignedIn + }); + } + + return defer.promise; + }, + showPlayer: function () { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was a showPlayer error.'); + } else { + defer.resolve({ + 'displayName': this._displayName + }); + } + + return defer.promise; + }, + submitScore: function (data) { + var defer = $q.defer(); + if (this._throwsError) { + defer.reject('There was a submitScore error.'); + } else { + defer.resolve('OK'); + } + + return defer.promise; + }, + showAllLeaderboards: function () { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was a showAllLeaderboards error.'); + } else { + defer.resolve('OK'); + } + + return defer.promise; + }, + showLeaderboard: function (data) { + var defer = $q.defer(); + if (this._throwsError) { + defer.reject('There was a showLeaderboard error.'); + } else { + defer.resolve('OK'); + } + + return defer.promise; + }, + unlockAchievement: function (data) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was a unlockAchievement error.'); + } else { + defer.resolve('OK'); + } + + return defer.promise; + }, + incrementAchievement: function (data) { + var defer = $q.defer(); + if (this._throwsError) { + defer.reject('There was a incrementAchievement error.'); + } else { + defer.resolve('OK'); + } + + return defer.promise; + }, + showAchievements: function () { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was a showAchievements error.'); + } else { + defer.resolve('OK'); + } + + return defer.promise; + } + }; + +}]); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaKeyboard + * + * @description + * A service for testing device keyboard features + * in an app build with ngCordova. + **/ +ngCordovaMocks.factory('$cordovaKeyboard', function () { + var isVisible = false; + + return { + hideAccessoryBar: function (bool) { + }, + + close: function () { + isVisible = false; + }, + + show: function () { + isVisible = true; + }, + + disableScroll: function (bool) { + }, + + isVisible: function () { + return isVisible; + } + + }; +}); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaKeychain + * + * @description + * A service for testing Keychain features + * in an app built with ngCordova. + **/ +ngCordovaMocks.factory('$cordovaKeychain', ['$q', function ($q) { + var keychains = {}; + + return { + /** + * @ngdoc property + * @name keychains + * @propertyOf ngCordovaMocks.cordovaKeychain + * + * @description + * The collection of 'keychains' that have been saved. + * This property should only be used in automated tests. + **/ + keychains: keychains, + + getForKey: function (key, serviceName) { + var defer = $q.defer(); + + if (this.keychains[serviceName]) { + defer.resolve(this.keychains[serviceName][key]); + } else { + defer.reject(); + } + + return defer.promise; + }, + + setForKey: function (key, serviceName, value) { + var defer = $q.defer(); + + if (!this.keychains[serviceName]) { + this.keychains[serviceName] = {}; + } + + this.keychains[serviceName][key] = value; + + defer.resolve(); + + return defer.promise; + }, + + removeForKey: function (key, serviceName) { + var defer = $q.defer(); + + if (this.keychains[serviceName]) { + delete this.keychains[serviceName][key]; + } + + defer.resolve(); + + return defer.promise; + } + }; +}]); + + +/** + * @ngdoc service + * @name ngCordovaMocks.localNotification + * + * @description + * A service for testing LocalNotificatio + * in an app build with ngCordovaMocks. + */ + +ngCordovaMocks.factory('$cordovaLocalNotification', ['$q', function ($q) { + + var storageKeyPfx = "ngCordLocNotif-"; + + function pfxId(id) { + return storageKeyPfx + id; + } + + function getAllIds(){ + var defer = $q.defer(); + var locNotifIds = []; + for ( var i = 0, len = localStorage.length; i < len; ++i ) { + if (localStorage.key( i ).indexOf(storageKeyPfx) > -1) + locNotifIds.push(parseInt(localStorage.key( i ).split("-")[1])); + } + defer.resolve(locNotifIds); + return defer.promise; + } + + + return { + cancel: function (ids) { + var defer = $q.defer(); + if (typeof(ids) == "number") ids = [ids]; + ids.forEach(function (id){ + localStorage.removeItem([pfxId(id)]); + }); + defer.resolve(); + return defer.promise; + }, + cancelAll: function () { + var defer = $q.defer(); + // TODO + defer.resolve(); + return defer.promise; + }, + clear: function (ids) { + if (typeof(ids) == "number") ids = [ids]; + var defer = $q.defer(); + ids.forEach(function (id){ + localStorage.removeItem([pfxId(id)]); + }); + defer.resolve(); + return defer.promise; + }, + clearAll: function () { + var defer = $q.defer(); + // TODO + // defer.resolve(); + return defer.promise; + }, + isScheduled: function (id){ + var defer = $q.defer(); + if (localStorage[pfxId(id)]) { + defer.resolve(true); + } else { + defer.resolve(false); + } + return defer.promise; + }, + isPresent: function (id){ + var defer = $q.defer(); + if (localStorage[pfxId(id)]) { + defer.resolve(true); + } else { + defer.resolve(false); + } + return defer.promise; + }, + isTriggered: function (id){ + var defer = $q.defer(); + if (localStorage[pfxId(id)]) { + defer.resolve(false); + } else { + defer.resolve(true); + } + return defer.promise; + }, + getAllIds: function () { + return getAllIds(); + }, + getIds: function () { + return getAllIds(); + }, + getScheduledIds: function () { + return getAllIds(); + }, + getTriggeredIds: function () { + var defer = $q.defer(); + defer.resolve([]); + return defer.promise; + }, + hasPermission: function (id){ + var defer = $q.defer(); + defer.resolve(true); + return defer.promise; + }, + schedule: function (data){ + var defer = $q.defer(); + var id = pfxId(data.id); + localStorage[id] = JSON.stringify(data); + defer.resolve(); + return defer.promise; + }, + update: function (data){ + var defer = $q.defer(); + var id = pfxId(data.id); + localStorage[id] = JSON.stringify(data); + defer.resolve(); + return defer.promise; + } + }; +}]); +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaNetwork + * + * @description + * A service for testing networked fetures + * in an app build with ngCordova. + */ +ngCordovaMocks.factory('$cordovaNetwork', ['$rootScope',function ($rootScope) { + var connectionType = 'WiFi connection'; + var isConnected = true; + + return { + /** + * @ngdoc property + * @name connectionType + * @propertyOf ngCordovaMocks.cordovaNetwork + * + * @description + * They type of connection. Values should match those found at + * https://github.com/apache/cordova-plugin-network-information + * This property should only be used in automated tests. + **/ + connectionType: connectionType, + + /** + * @ngdoc property + * @name isConnected + * @propertyOf ngCordovaMocks.cordovaNetwork + * + * @description + * A flag that signals whether the app is connected to a network. + * This property should only be used in automated tests. + **/ + isConnected: isConnected, + + switchToOnline: function (){ + this.isConnected = true; + $rootScope.$broadcast('$cordovaNetwork:online'); + }, + + switchToOffline: function (){ + this.isConnected = false; + $rootScope.$broadcast('$cordovaNetwork:offline'); + }, + + getNetwork: function () { + return this.connectionType; + }, + + isOnline: function () { + return this.isConnected; + }, + + isOffline: function () { + return !this.isConnected; + } + }; +}]); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaProgress + * + * @description + * A service for testing Progress Indicator + * in an app build with ngCordova. + */ + +ngCordovaMocks.factory('$cordovaProgress', [ + '$timeout', function ($timeout) { + + return { + show: function (_message) { + var message = _message || 'Please wait...'; + console.info('$cordovaProgress.message', message); + }, + + showSimple: function (_dim) { + var dim = _dim || false; + console.info('$cordovaProgress.dim', dim); + }, + + showSimpleWithLabel: function (_dim, _label) { + var dim = _dim || false; + var label = _label || 'Loading...'; + console.group(); + console.info('$cordovaProgress.dim', dim); + console.info('$cordovaProgress.label', label); + console.groupEnd(); + }, + + showSimpleWithLabelDetail: function (_dim, _label, _detail) { + var dim = _dim || false; + var label = _label || 'Loading...'; + var detail = _detail || 'Please wait'; + + console.group(); + console.info('$cordovaProgress.dim', dim); + console.info('$cordovaProgress.label', label); + console.info('$cordovaProgress.detail', detail); + console.groupEnd(); + }, + + showDeterminate: function (_dim, _timeout) { + var dim = _dim || false; + var timeout = _timeout || 50000; + console.group(); + console.info('$cordovaProgress.dim show', dim); + console.info('$cordovaProgress.timeout', timeout); + console.groupEnd(); + $timeout(function () { + console.info('$cordovaProgress.dim timeout', dim); + }, timeout); + }, + + showDeterminateWithLabel: function (_dim, _timeout, _label) { + var dim = _dim || false; + var timeout = _timeout || 50000; + var label = _label || 'Loading...'; + + console.group(); + console.info('$cordovaProgress.dim', dim); + console.info('$cordovaProgress.timeout', timeout); + console.info('$cordovaProgress.label', label); + console.groupEnd(); + $timeout(function () { + console.info('$cordovaProgress[dim, label] timeout', [dim, label]); + }, timeout); + }, + + showAnnular: function (_dim, _timeout) { + var dim = _dim || false; + var timeout = _timeout || 50000; + + console.group(); + console.info('$cordovaProgress.dim', dim); + console.info('$cordovaProgress.timeout', timeout); + console.groupEnd(); + $timeout(function () { + console.info('$cordovaProgress.dim timeout', dim); + }, timeout); + }, + + showAnnularWithLabel: function (_dim, _timeout, _label) { + var dim = _dim || false; + var timeout = _timeout || 50000; + var label = _label || 'Loading...'; + + console.group(); + console.info('$cordovaProgress.dim', dim); + console.info('$cordovaProgress.timeout', timeout); + console.info('$cordovaProgress.label', label); + console.groupEnd(); + $timeout(function () { + console.info('$cordovaProgress[dim, label] timeout', [dim, label]); + }, timeout); + }, + + showBar: function (_dim, _timeout) { + var dim = _dim || false; + var timeout = _timeout || 50000; + + console.group(); + console.info('$cordovaProgress.dim', dim); + console.info('$cordovaProgress.timeout', timeout); + console.groupEnd(); + $timeout(function () { + console.info('$cordovaProgress.dim timeout', dim); + }, timeout); + }, + + showBarWithLabel: function (_dim, _timeout, _label) { + var dim = _dim || false; + var timeout = _timeout || 50000; + var label = _label || 'Loading...'; + console.group(); + console.info('$cordovaProgress.dim', dim); + console.info('$cordovaProgress.label', label); + console.info('$cordovaProgress.timeout', timeout); + console.groupEnd(); + $timeout(function () { + console.info('$cordovaProgress[dim, label] timeout', [dim, label]); + }, timeout); + }, + + showSuccess: function (_dim, _label) { + var dim = _dim || false; + var label = _label || 'Success'; + console.group(); + console.info('$cordovaProgress.dim', dim); + console.info('$cordovaProgress.label', label); + console.groupEnd(); + }, + + showText: function (_dim, _text, _position) { + var dim = _dim || false; + var text = _text || 'Warning'; + var position = _position || 'center'; + console.group(); + console.info('$cordovaProgress.dim', dim); + console.info('$cordovaProgress.text', text); + console.info('$cordovaProgress.position', position); + console.groupEnd(); + }, + + hide: function () { + console.info('$cordovaProgress.hide'); + } + }; + } +]); + +'use strict'; + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaPush + * + * @description + * A service for testing push notifications features + * in an app build with ngCordova. + */ +ngCordovaMocks.factory('$cordovaPush', ['$q', '$timeout', '$rootScope', function ($q, $timeout, $rootScope) { + var throwsError = false; + + var deviceToken = ''; + + return { + /** + * @ngdoc property + * @name throwsError + * @propertyOf ngCordovaMocks.cordovaPush + * + * @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 deviceToken + * @propertyOf ngCordovaMocks.cordovaPush + * + * @description + * Token send when service register device + * This property should only be used in automated tests. + **/ + deviceToken: deviceToken, + + onNotification: function (notification) { + $timeout(function () { + $rootScope.$broadcast('$cordovaPush:notificationReceived', notification); + }); + }, + + register: function (config) { + var _self = this; + var defer = $q.defer(); + if (config !== undefined && config.ecb === undefined) { + config.ecb = this.onNotification; + } + + if (this.throwsError) { + defer.reject('There was a register error.'); + } else { + defer.resolve(this.deviceToken); + if (config && config.ecb) { + config.ecb({ + event: 'registered', + regid: _self.deviceToken + }); + } + } + return defer.promise; + }, + + unregister: function (options) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was a register error.'); + } else { + defer.resolve(); + } + return defer.promise; + }, + }; +}]); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaScreenshot + * + * @description + * A service for test app screenshot + * in an app build with ngCordova. + * + * @example + */ +ngCordovaMocks.factory('$cordovaScreenshot', ['$q', function ($q) { + var throwsError = false; + + var DATA_URI_MOCK = "data:image/png;base64,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"; + + return { + /** + * @ngdoc property + * @name throwsError + * @propertyOf ngCordovaMocks.cordovaScreenshot + * + * @description + * A flag that signals whether a promise should be rejected or not. + * This property should only be used in automated tests. + **/ + throwsError: throwsError, + + captureToFile: function () { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error capturing the screenshot.'); + } else { + defer.resolve("path"); + } + + return defer.promise; + }, + + captureToUri: function () { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error capturing the screenshot.'); + } else { + defer.resolve(); + } + + return defer.promise; + } + }; +}]); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaSocialSharing + * + * @description + * A service for testing via social services + * in an app build with ngCordova. + */ +ngCordovaMocks.factory('$cordovaSocialSharing', ['$q', function ($q) { + var throwsError = false; + var message = ''; + var image = ''; + var link = ''; + var number = ''; + + var socialService = ''; + var subject = ''; + var toAddresses = []; + var bccAddresses = []; + var attachments = []; + + return { + /** + * @ngdoc property + * @name throwsError + * @propertyOf ngCordovaMocks.cordovaSocialSharing + * + * @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 message + * @propertyOf ngCordovaMocks.cordovaSocialSharing + * + * @description + * The message to be shared via a social service. + * This property should only be used in automated tests. + **/ + message: message, + + /** + * @ngdoc property + * @name image + * @propertyOf ngCordovaMocks.cordovaSocialSharing + * + * @description + * An image to be shared via a social service. + * This property should only be used in automated tests. + **/ + image: image, + + /** + * @ngdoc property + * @name link + * @propertyOf ngCordovaMocks.cordovaSocialSharing + * + * @description + * A link to be shared via a social service. + * This property should only be used in automated tests. + **/ + link: link, + + /** + * @ngdoc property + * @name number + * @propertyOf ngCordovaMocks.cordovaSocialSharing + * + * @description + * A comma-delimited list of phone numbers to send a social message to. + * This property should only be used in automated tests. + **/ + number: number, + + /** + * @ngdoc property + * @name subject + * @propertyOf ngCordovaMocks.cordovaSocialSharing + * + * @description + * The subject of an email. + * This property should only be used in automated tests. + **/ + subject: subject, + + /** + * @ngdoc property + * @name toAddresses + * @propertyOf ngCordovaMocks.cordovaSocialSharing + * + * @description + * An array of email addresses to send an email to. + * This property should only be used in automated tests. + **/ + toAddresses: toAddresses, + + /** + * @ngdoc property + * @name bccAddresses + * @propertyOf ngCordovaMocks.cordovaSocialSharing + * + * @description + * An array of email addresses to blind carbon-copy an email to. + * This property should only be used in automated tests. + **/ + bccAddresses: bccAddresses, + + /** + * @ngdoc property + * @name socialService + * @propertyOf ngCordovaMocks.cordovaSocialSharing + * + * @description + * The name of a social service to share content through. + * This property should only be used in automated tests. + **/ + socialService: socialService, + + /** + * @ngdoc property + * @name attachments + * @propertyOf ngCordovaMocks.cordovaSocialSharing + * + * @description + * An array of attachments to include with an email to be sent. + * This property should only be used in automated tests. + **/ + attachments: attachments, + + shareViaTwitter: function (message, image, link) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error sharing via Twitter.'); + } else { + this.message = message; + this.image = image; + this.link = link; + + defer.resolve(); + } + return defer.promise; + }, + + shareViaWhatsApp: function (message, image, link) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error sharing via WhatsApp.'); + } else { + this.message = message; + this.image = image; + this.link = link; + + defer.resolve(); + } + return defer.promise; + }, + + shareViaFacebook: function (message, image, link) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error sharing via Facebook.'); + } else { + this.message = message; + this.image = image; + this.link = link; + + defer.resolve(); + } + return defer.promise; + }, + + shareViaSMS: function (message, number) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error sharing via SMS.'); + } else { + this.message = message; + this.number = number; + + defer.resolve(); + } + return defer.promise; + }, + + shareViaEmail: function (message, subject, toArr, bccArr, file) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error sharing via SMS.'); + } else { + // These are added to get by JSHINT for now + this.message = message; + this.subject = subject; + this.toAddresses = toArr; + this.bccAddressesc = bccArr; + this.attachments = file; + + defer.resolve(); + } + return defer.promise; + }, + + canShareViaEmail: function () { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject(false); + } else { + defer.resolve(true); + } + return defer.promise; + }, + + canShareVia: function (via, message, subject, file, link) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error sharing via SMS.'); + } else { + // These are added to get by JSHINT for now + this.message = message; + this.socialService = via; + this.subject = subject; + this.attachments = file; + this.link = link; + + defer.resolve(); + } + return defer.promise; + }, + + shareVia: function (via, message, subject, file, link) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error sharing via SMS.'); + } else { + this.socialService = via; + this.message = message; + this.subject = subject; + this.attachments = file; + this.link = link; + + defer.resolve(); + } + return defer.promise; + }, + + share: function (message, subject, file, link) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error sharing via SMS.'); + } else { + this.message = message; + this.subject = subject; + this.attachments = file; + this.link = link; + + defer.resolve(); + } + return defer.promise; + } + }; +}]); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaSplashscreen + * + * @description + * A service for testing the splash screen + * in an app build with ngCordova. + */ +ngCordovaMocks.factory('$cordovaSplashscreen', function () { + var isVisible = false; + + return { + /** + * @ngdoc property + * @name isVisible + * @propertyOf ngCordovaMocks.cordovaSplashscreen + * + * @description + * A flag that signals whether the splash screen is visible or not. + * This property should only be used in automated tests. + **/ + isVisible: isVisible, + + hide: function () { + // do nothing. everything happens behind the scenes in this case. + // its a stub that is present for completeness. + this.isVisible = false; + return true; + }, + show: function () { + // do nothing. everything happens behind the scenes in this case. + // its a stub that is present for completeness. + this.isVisible = true; + return true; + } + }; +}); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaSQLite + * + * @description + * A service for testing SQLite + * in an app build with ngCordova. + */ + +ngCordovaMocks.factory('$cordovaSQLite', ['$q', function ($q) { + + return { + /** + * These properties are here for the purpose of automated testing only. + **/ + openDBShouldSucceedWith: null, + executeShouldSucceedWith: null, + insertCollectionShouldSucceedWith: null, + nestedExecuteShouldSucceedWith: null, + deleteDBShouldSucceedWith : null, + + openDB: function (options, background) { + if (this.openDBShouldSucceedWith !== null) { + $q.when(this.openDBShouldSucceedWith) + } else { + $q.reject() + } + }, + execute: function (db, query, binding) { + if (this.executeShouldSucceedWith !== null) { + $q.when(this.executeShouldSucceedWith) + } else { + $q.reject() + } + }, + insertCollection: function (db, query, bindings) { + if (this.insertCollectionShouldSucceedWith !== null) { + $q.when(this.insertCollectionShouldSucceedWith) + } else { + $q.reject() + } + }, + nestedExecute: function (db, query1, query2, binding1, binding2) { + if (this.nestedExecuteShouldSucceedWith !== null) { + $q.when(this.nestedExecuteShouldSucceedWith) + } else { + $q.reject() + } + }, + deleteDB: function (dbName) { + if (this.deleteDBShouldSucceedWith !== null) { + $q.when(this.deleteDBShouldSucceedWith) + } else { + $q.reject() + } + } + } +}]); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaStatusbar + * + * @description + * A service for testing the status bar + * in an app build with ngCordova. + */ +ngCordovaMocks.factory('$cordovaStatusbar', function () { + var isStatusBarVisible = true; + var canOverlayWebView = true; + + return { + /** + * @ngdoc property + * @name isStatusBarVisible + * @propertyOf ngCordovaMocks.cordovaStatusbar + * + * @description + * A flag that signals whether the status bar is visible or not. + * This property should only be used in automated tests. + **/ + isStatusBarVisible: isStatusBarVisible, + + /** + * @ngdoc property + * @name canOverlayWebView + * @propertyOf ngCordovaMocks.cordovaStatusbar + * + * @description + * A flag that signals whether the status bar can overlay the web view. + * This property should only be used in automated tests. + **/ + canOverlayWebView: canOverlayWebView, + + overlaysWebView: function (bool) { + this.canOverlayWebView = bool; + }, + + style: function (style) { + // TODO: Review + return style; + }, + + styleHex: function (colorHex) { + // TODO: review + return colorHex; + }, + + styleColor: function (color) { + // TODO: review + return color; + }, + + hide: function () { + this.isStatusBarVisible = false; + }, + + show: function () { + this.isStatusBarVisible = true; + }, + + isVisible: function () { + return this.isStatusBarVisible; + } + }; +}); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaToast + * + * @description + * A service for testing toasts + * in an app build with ngCordova. + * + * @example + */ +ngCordovaMocks.factory('$cordovaToast', ['$q', function ($q) { + var throwsError = false; + + return { + /** + * @ngdoc property + * @name throwsError + * @propertyOf ngCordovaMocks.cordovaToast + * + * @description + * A flag that signals whether a promise should be rejected or not. + * This property should only be used in automated tests. + **/ + throwsError: throwsError, + + showShortTop: function (message) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error showing the toast.'); + } else { + defer.resolve(); + } + return defer.promise; + }, + showShortCenter: function (message) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error showing the toast.'); + } else { + defer.resolve(); + } + return defer.promise; + }, + showShortBottom: function (message) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error showing the toast.'); + } else { + defer.resolve(); + } + return defer.promise; + }, + showLongTop: function (message) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error showing the toast.'); + } else { + defer.resolve(); + } + return defer.promise; + }, + showLongCenter: function (message) { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error showing the toast.'); + } else { + defer.resolve(); + } + return defer.promise; + }, + showLongBottom: function (message) { + 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) { + defer.reject('There was an error showing the toast.'); + } else { + defer.resolve(); + } + return defer.promise; + }, + hide: function () { + var defer = $q.defer(); + if (this.throwsError) { + defer.reject('There was an error hiding the toast.'); + } else { + defer.resolve(); + } + return defer.promise; + } + }; +}]); + +/** + * @ngdoc service + * @name ngCordovaMocks.cordovaVibration + * + * @description + * A service for testing vibration + * in an app build with ngCordova. + */ +ngCordovaMocks.factory('$cordovaVibration', ['$timeout', function ($timeout) { + var isVibrating = false; + var vibrateTimer = null; + + return { + /** + * @ngdoc property + * @name vibrateTimer + * @propertyOf ngCordovaMocks.cordovaVibration + * + * @description + * Access to the timer associated with vibration. + * This property should only be used in automated tests. + **/ + vibrateTimer: vibrateTimer, + + /** + * @ngdoc property + * @name isVibrating + * @propertyOf ngCordovaMocks.cordovaVibration + * + * @description + * A flag that signals whether vibration is active. + * This property should only be used in automated tests. + **/ + isVibrating: isVibrating, + + vibrate: function (time) { + if (time > 0) { + this.isVibrating = true; + self = this; + + if (time instanceof Array) { + // TODO: Implement pattern here. + // The following is a temporary timer that just looks at the first value + this.vibrateTimer = $timeout( + function () { + self.isVibrating = false; + self.vibrateTimer = null; + }, + time[0] + ); + } else { + this.vibrateTimer = $timeout( + function () { + self.isVibrating = false; + self.vibrateTimer = null; + }, + time + ); + } + } + }, + + /* jshint ignore:start */ + vibrateWithPattern: function (pattern, repeat) { + // Based on the documentation (https://github.com/apache/cordova-plugin-vibration) + // This method is deprecated. For that reason, this isn't implemented at this time. + }, + /* jshint ignore:end */ + + cancelVibration: function () { + if (this.vibrateTimer !== null) { + if (this.isVibrating === true) { + $timeout.cancel(this.vibrateTimer); + this.isVibrating = false; + } + } + } + }; +}]); + +})();
\ No newline at end of file |
