You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by om...@apache.org on 2016/05/12 19:48:48 UTC

[4/6] cordova-cli git commit: Telemetry: Adding Unit Tests

Telemetry: Adding Unit Tests


Project: http://git-wip-us.apache.org/repos/asf/cordova-cli/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-cli/commit/55df8989
Tree: http://git-wip-us.apache.org/repos/asf/cordova-cli/tree/55df8989
Diff: http://git-wip-us.apache.org/repos/asf/cordova-cli/diff/55df8989

Branch: refs/heads/master
Commit: 55df89894e15cec9393460f0cb0a78dd2f55d818
Parents: 330dea1
Author: Omar Mefire <om...@gmail.com>
Authored: Fri May 6 12:44:43 2016 -0700
Committer: Omar Mefire <om...@gmail.com>
Committed: Thu May 12 11:14:55 2016 -0700

----------------------------------------------------------------------
 spec/cli.spec.js | 422 ++++++++++++++++++++++++++++++++++++--------------
 src/cli.js       |  88 ++++++-----
 src/telemetry.js |  97 ++++++------
 3 files changed, 406 insertions(+), 201 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/55df8989/spec/cli.spec.js
----------------------------------------------------------------------
diff --git a/spec/cli.spec.js b/spec/cli.spec.js
index b6064e9..c8b1e9a 100644
--- a/spec/cli.spec.js
+++ b/spec/cli.spec.js
@@ -21,8 +21,9 @@ var cli = require("../src/cli"),
     Q = require('q'),
     cordova_lib = require('cordova-lib'),
     events = cordova_lib.events,
-    cordova = cordova_lib.cordova;
-
+    cordova = cordova_lib.cordova,
+    telemetry = require('../src/telemetry');
+    
     //avoid node complaining of too many event listener added
     process.setMaxListeners(0);
 
@@ -41,6 +42,11 @@ describe("cordova cli", function () {
 
         spyOn(events, "on").andReturn(new FakeEvents());
         spyOn(console, 'log');
+        
+        // Prevent accidentally turning telemetry on/off during testing
+        telemetry.turnOn = function() {};
+        telemetry.turnOff = function() {};
+        telemetry.track = function() {};
     });
 
     describe("options", function () {
@@ -49,20 +55,35 @@ describe("cordova cli", function () {
 
             beforeEach(function () {
             });
-
-            it("will spit out the version with -v", function () {
-                cli(["node", "cordova", "-v"]);
-                expect(console.log.mostRecentCall.args[0]).toContain(version);
+            
+            it("will spit out the version with -v", function (done) {
+                cli(["node", "cordova", "-v"]).then(function() {
+                    expect(console.log.mostRecentCall.args[0]).toMatch(version);
+                    done();
+                }).fail(function() {
+                    expect(true).toBe(false);
+                    done();
+                });
             });
 
-            it("will spit out the version with --version", function () {
-                cli(["node", "cordova", "--version"]);
-                expect(console.log.mostRecentCall.args[0]).toContain(version);
+            it("will spit out the version with --version", function (done) {
+                cli(["node", "cordova", "--version"]).then(function() {
+                    expect(console.log.mostRecentCall.args[0]).toMatch(version);
+                    done();
+                }).fail(function() {
+                    assert(true).toBe(false);
+                    done();
+                });
             });
 
-            it("will spit out the version with -v anywhere", function () {
-                cli(["node", "cordova", "one", "-v", "three"]);
-                expect(console.log.mostRecentCall.args[0]).toContain(version);
+            it("will spit out the version with -v anywhere", function (done) {
+                cli(["node", "cordova", "one", "-v", "three"]).then(function() {
+                    expect(console.log.mostRecentCall.args[0]).toMatch(version);
+                    done();
+                }).fail(function() {
+                    expect(true).toBe(false);
+                    done();
+                });
             });
         });
     });
@@ -72,88 +93,64 @@ describe("cordova cli", function () {
             spyOn(cordova.raw, "build").andReturn(Q());
         });
 
-        it("will call command with all arguments passed through", function () {
-            cli(["node", "cordova", "build", "blackberry10", "--", "-k", "abcd1234"]);
-            expect(cordova.raw.build).toHaveBeenCalledWith(jasmine.objectContaining({
-                platforms : [ 'blackberry10' ],
-                options : { argv : [ '-k', 'abcd1234' ] },
-                verbose : false,
-                silent : false,
-                fetch: false,
-                browserify : false,
-                nohooks:[],
-                searchpath : undefined
-            }));
+        it("will call command with all arguments passed through", function (done) {
+            cli(["node", "cordova", "build", "blackberry10", "--", "-k", "abcd1234"]).then(function () {
+                expect(cordova.raw.build).toHaveBeenCalledWith({ platforms: ['blackberry10'], options: { argv: ['-k', 'abcd1234'] }, verbose: false, silent: false, browserify: false, nohooks: [], searchpath: undefined });
+                done();
+            }).fail(function () {
+                expect(true).toBe(false);
+                done();
+            });
         });
 
-        it("will consume the first instance of -d", function () {
-            cli(["node", "cordova", "-d", "build", "blackberry10", "--", "-k", "abcd1234", "-d"]);
-            expect(cordova.raw.build).toHaveBeenCalledWith(jasmine.objectContaining({
-                platforms : [ 'blackberry10' ],
-                options : { verbose : true, argv : [ '-k', 'abcd1234', '-d' ] },
-                verbose : true,
-                silent : false,
-                fetch: false,
-                browserify : false,
-                nohooks:[],
-                searchpath : undefined
-            }));
+        it("will consume the first instance of -d", function (done) {
+            cli(["node", "cordova", "-d", "build", "blackberry10", "--", "-k", "abcd1234", "-d"]).then(function () {
+                expect(cordova.raw.build).toHaveBeenCalledWith({ platforms: ['blackberry10'], options: { verbose: true, argv: ['-k', 'abcd1234', '-d'] }, verbose: true, silent: false, browserify: false, nohooks: [], searchpath: undefined });
+                done();
+            }).fail(function () {
+                expect(true).toBe(false);
+                done();
+            });
         });
 
-        it("will consume the first instance of --verbose", function () {
-            cli(["node", "cordova", "--verbose", "build", "blackberry10", "--", "-k", "abcd1234", "--verbose"]);
-            expect(cordova.raw.build).toHaveBeenCalledWith(jasmine.objectContaining({
-                platforms : [ 'blackberry10' ],
-                options : { verbose : true, argv : [ '-k', 'abcd1234', '--verbose' ] },
-                verbose : true,
-                silent : false,
-                fetch: false,
-                browserify : false,
-                nohooks:[],
-                searchpath : undefined
-            }));
+        it("will consume the first instance of --verbose", function (done) {
+            cli(["node", "cordova", "--verbose", "build", "blackberry10", "--", "-k", "abcd1234", "--verbose"]).then(function () {
+                expect(cordova.raw.build).toHaveBeenCalledWith({ platforms: ['blackberry10'], options: { verbose: true, argv: ['-k', 'abcd1234', '--verbose'] }, verbose: true, silent: false, browserify: false, nohooks: [], searchpath: undefined });
+                done();
+            }).fail(function () {
+                expect(true).toBe(false);
+                done();
+            });
         });
 
-        it("will consume the first instance of either --verbose of -d", function () {
-            cli(["node", "cordova", "--verbose", "build", "blackberry10", "--", "-k", "abcd1234", "-d"]);
-            expect(cordova.raw.build).toHaveBeenCalledWith(jasmine.objectContaining({
-                platforms : [ 'blackberry10' ],
-                options : { verbose : true, argv : [ '-k', 'abcd1234', '-d' ] },
-                verbose : true,
-                silent : false,
-                fetch: false,
-                browserify : false,
-                nohooks:[],
-                searchpath : undefined
-            }));
+        it("will consume the first instance of either --verbose or -d", function (done) {
+            cli(["node", "cordova", "--verbose", "build", "blackberry10", "--", "-k", "abcd1234", "-d"]).then(function () {
+                expect(cordova.raw.build).toHaveBeenCalledWith({ platforms: ['blackberry10'], options: { verbose: true, argv: ['-k', 'abcd1234', '-d'] }, verbose: true, silent: false, browserify: false, nohooks: [], searchpath: undefined });
+                done();
+            }).fail(function () {
+                expect(true).toBe(false);
+                done();
+            });
         });
 
-        it("will consume the first instance of either --verbose of -d", function () {
-            cli(["node", "cordova", "-d", "build", "blackberry10", "--", "-k", "abcd1234", "--verbose"]);
-            expect(cordova.raw.build).toHaveBeenCalledWith(jasmine.objectContaining({
-                platforms : [ 'blackberry10' ],
-                options : { verbose : true, argv : [ '-k', 'abcd1234', '--verbose' ] },
-                verbose : true,
-                silent : false,
-                fetch: false,
-                browserify : false,
-                nohooks:[],
-                searchpath : undefined
-            }));
+        it("will consume the first instance of either --verbose or -d", function (done) {
+            cli(["node", "cordova", "-d", "build", "blackberry10", "--", "-k", "abcd1234", "--verbose"]).then(function () {
+                expect(cordova.raw.build).toHaveBeenCalledWith({ platforms: ['blackberry10'], options: { verbose: true, argv: ['-k', 'abcd1234', '--verbose'] }, verbose: true, silent: false, browserify: false, nohooks: [], searchpath: undefined });
+                done();
+            }).fail(function () {
+                expect(true).toBe(false);
+                done();
+            });
         });
 
-        it("will consume the first instance of --silent", function () {
-            cli(["node", "cordova", "--silent", "build", "blackberry10", "--",  "-k", "abcd1234", "--silent"]);
-            expect(cordova.raw.build).toHaveBeenCalledWith(jasmine.objectContaining({
-                platforms : [ 'blackberry10' ],
-                options : { silent : true, argv : [ '-k', 'abcd1234', '--silent' ] },
-                verbose : false,
-                silent : true,
-                fetch: false,
-                browserify : false,
-                nohooks:[],
-                searchpath : undefined
-            }));
+        it("will consume the first instance of --silent", function (done) {
+            cli(["node", "cordova", "--silent", "build", "blackberry10", "--", "-k", "abcd1234", "--silent"]).then(function () {
+                expect(cordova.raw.build).toHaveBeenCalledWith({ platforms: ['blackberry10'], options: { silent: true, argv: ['-k', 'abcd1234', '--silent'] }, verbose: false, silent: true, browserify: false, nohooks: [], searchpath: undefined });
+                done();
+            }).fail(function () {
+                expect(true).toBe(false);
+                done();
+            });
         });
     });
 
@@ -163,9 +160,14 @@ describe("cordova cli", function () {
             spyOn(cordova_lib, "CordovaError");
         });
 
-        it("calls cordova raw create", function () {
-            cli(["node", "cordova", "create", "a", "b" , "c", "--link-to", "c:\\personalWWW"]);
-            expect(cordova.raw.create).toHaveBeenCalledWith("a","b","c", jasmine.any(Object));
+        it("calls cordova raw create", function (done) {
+            cli(["node", "cordova", "create", "a", "b", "c", "--link-to", "c:\\personalWWW"]).then(function () {
+                expect(cordova.raw.create).toHaveBeenCalledWith("a", "b", "c", jasmine.any(Object));
+                done();
+            }).fail(function () {
+                expect(true).toBe(false);
+                done();
+            });
         });
     });
 
@@ -174,38 +176,230 @@ describe("cordova cli", function () {
             spyOn(cordova.raw, "plugin").andReturn(Q());
         });
 
-        it("will pass variables", function () {
-            cli(["node", "cordova", "plugin", "add", "facebook", "--variable", "FOO=foo"]);
-            expect(cordova.raw.plugin).toHaveBeenCalledWith(
-                "add",
-                ["facebook"],
-                jasmine.any(Object)
-            );
-            var opts = cordova.raw.plugin.calls[0].args[2];
-            expect(opts.cli_variables.FOO).toBe('foo');
+        it("will pass variables", function (done) {
+            cli(["node", "cordova", "plugin", "add", "facebook", "--variable", "FOO=foo"]).then(function () {
+                expect(cordova.raw.plugin).toHaveBeenCalledWith(
+                    "add",
+                    ["facebook"],
+                    jasmine.any(Object)
+                );
+                var opts = cordova.raw.plugin.calls[0].args[2];
+                expect(opts.cli_variables.FOO).toBe('foo');
+                done();
+            }).fail(function() {
+                expect(true).toBe(false);
+                done();
+            });
+
         });
 
-          it("will  support variables with =", function () {
-            cli(["node", "cordova", "plugin", "add", "facebook", "--variable", "MOTO=DELTA=WAS=HERE"]);
-            expect(cordova.raw.plugin).toHaveBeenCalledWith(
-                "add",
-                ["facebook"],
-                jasmine.any(Object)
-            );
-            var opts = cordova.raw.plugin.calls[0].args[2];
-            expect(opts.cli_variables.MOTO).toBe('DELTA=WAS=HERE');
+        it("will  support variables with =", function (done) {
+            cli(["node", "cordova", "plugin", "add", "facebook", "--variable", "MOTO=DELTA=WAS=HERE"]).then(function () {
+                expect(cordova.raw.plugin).toHaveBeenCalledWith(
+                    "add",
+                    ["facebook"],
+                    jasmine.any(Object)
+                );
+                var opts = cordova.raw.plugin.calls[0].args[2];
+                expect(opts.cli_variables.MOTO).toBe('DELTA=WAS=HERE');
+                done();
+            }).fail(function () {
+                expect(true).toBe(false);
+                done();
+            });
         });
 
-        it("will pass hook patterns to suppress", function () {
-            cli(["node", "cordova", "plugin", "add", "facebook", "--nohooks", "before_plugin_add"]);
-            expect(cordova.raw.plugin).toHaveBeenCalledWith(
-                "add",
-                ["facebook"],
-                jasmine.any(Object)
-            );
-            var opts = cordova.raw.plugin.calls[0].args[2];
-            expect(opts.nohooks[0]).toBe("before_plugin_add");
+        it("will pass hook patterns to suppress", function (done) {
+            cli(["node", "cordova", "plugin", "add", "facebook", "--nohooks", "before_plugin_add"]).then(function () {
+                expect(cordova.raw.plugin).toHaveBeenCalledWith(
+                    "add",
+                    ["facebook"],
+                    jasmine.any(Object)
+                );
+                var opts = cordova.raw.plugin.calls[0].args[2];
+                expect(opts.nohooks[0]).toBe("before_plugin_add");
+                done();
+            }).fail(function () {
+                expect(true).toBe(false);
+                done();
+            });  
         });
 
     });
+    
+    describe("telemetry", function() {
+       it("skips prompt when user runs 'cordova telemetry X'", function(done) {
+           var wasPromptShown = false;
+           spyOn(telemetry, "showPrompt").andCallFake(function () {
+               wasPromptShown = true;
+           });
+
+           cli(["node", "cordova", "telemetry", "on"]).then(function (done) {
+               return cli(["node", "cordova", "telemetry", "off"])
+           }).then(function () {
+               expect(wasPromptShown).toBeFalsy();
+               done();
+           }).fail(function () {
+               expect(true).toBe(false);
+               done();
+           });           
+       });
+       
+       it("is NOT collected when user runs 'cordova telemetry on' while NOT opted-in", function(done) {
+           spyOn(telemetry, "isOptedIn").andReturn(false);
+           spyOn(telemetry, "isCI").andReturn(false);
+           
+           spyOn(telemetry, "track");
+           
+           cli(["node", "cordova", "telemetry", "on"]).then(function () {
+               expect(telemetry.track).not.toHaveBeenCalled();
+               done();
+           }).fail(function () {
+               expect(true).toBe(false);
+               done();
+           });  
+       });
+       
+       it("is collected when user runs 'cordova telemetry off' while opted-in", function(done) {
+           spyOn(telemetry, "isOptedIn").andReturn(true);
+           spyOn(telemetry, "isCI").andReturn(false);
+           
+           spyOn(telemetry, "track");
+           
+           cli(["node", "cordova", "telemetry", "off"]).then(function () {
+               expect(telemetry.track).toHaveBeenCalledWith("telemetry-opt-out", "via-cordova-telemetry-off");
+               done();
+           }).fail(function () {
+               expect(true).toBe(false);
+               done();
+           });  
+       });
+       
+       it("shows prompt if user neither opted in or out yet", function(done) {
+           spyOn(cordova.raw, "prepare").andReturn(Q());
+           spyOn(telemetry, "hasUserOptedInOrOut").andReturn(false);
+           
+           spyOn(telemetry, "isCI").andReturn(false);
+           spyOn(telemetry, "isNoTelemetryFlag").andReturn(false);
+           spyOn(telemetry, "showPrompt").andReturn(Q(false));
+           
+           return cli(["node", "cordova", "prepare"]).then(function() {
+               expect(telemetry.showPrompt).toHaveBeenCalled();
+               done();
+           }).fail(function() {
+               expect(true).toBe(false);
+               done();
+           });
+       });
+
+       // ToDO: Figure out a way to modify default timeout
+       // ... Timeout overriding isn't working anymore due to a bug with jasmine-node
+       xit("opts-out if prompt times out AND it tracks opt-out", function(done) {
+           // Remove any optOut settings that might have been saved
+           // ... and force prompt to be shown
+           telemetry.clear();
+           spyOn(telemetry, "hasUserOptedInOrOut").andReturn(false);
+           spyOn(telemetry, "isCI").andReturn(false);
+           spyOn(telemetry, "track");
+           
+           cli(["node", "cordova", "--version"]).then(function() {
+               expect(telemetry.isOptedIn()).toBeFalsy();
+               expect(telemetry.track).toHaveBeenCalledWith('telemetry-opt-out', 'via-cli-prompt-choice');
+               done();
+           }).fail(function() {
+               expect(true).toBe(false);
+               done();
+           });
+       }/*, 45000*/);
+       
+       it("is NOT collected in CI environments and doesn't prompt", function(done) {
+           spyOn(telemetry, "hasUserOptedInOrOut").andReturn(true);
+           spyOn(telemetry, "isOptedIn").andReturn(true);
+           spyOn(telemetry, "isCI").andReturn(true);
+           
+           spyOn(telemetry, "showPrompt");
+           spyOn(telemetry, "track");
+           
+           cli(["node", "cordova", "--version"]).then(function() {
+               expect(telemetry.showPrompt).not.toHaveBeenCalled();
+               expect(telemetry.track).not.toHaveBeenCalled();
+               done();
+           }).fail(function() {
+               expect(true).toBe(false);
+               done();
+           });
+       });
+       
+       it("is NOT collected when --no-telemetry flag found and doesn't prompt", function(done) {
+           spyOn(telemetry, "hasUserOptedInOrOut").andReturn(false);
+           spyOn(telemetry, "isOptedIn").andReturn(true);
+           spyOn(telemetry, "isCI").andReturn(false);
+           
+           spyOn(telemetry, "showPrompt");
+           spyOn(telemetry, "track");
+           
+           cli(["node", "cordova", "--version", "--no-telemetry"]).then(function() {
+               expect(telemetry.showPrompt).not.toHaveBeenCalled();
+               expect(telemetry.track).not.toHaveBeenCalled();
+               done();
+           }).fail(function() {
+               expect(true).toBe(false);
+               done();
+           });
+       });
+       
+       it("is NOT collected if user opted out", function(done) {
+           spyOn(telemetry, "hasUserOptedInOrOut").andReturn(true);
+           spyOn(telemetry, "isOptedIn").andReturn(false);
+           spyOn(telemetry, "isCI").andReturn(false);
+           
+           spyOn(telemetry, "showPrompt");
+           spyOn(telemetry, "track");
+           
+           cli(["node", "cordova", "--version"]).then(function() {
+               expect(telemetry.showPrompt).not.toHaveBeenCalled();
+               expect(telemetry.track).not.toHaveBeenCalled();
+               done();
+           }).fail(function() {
+               expect(true).toBe(false);
+               done();
+           });
+       });
+       
+       it("is collected if user opted in", function(done) {
+           spyOn(telemetry, "hasUserOptedInOrOut").andReturn(true);
+           spyOn(telemetry, "isOptedIn").andReturn(true);
+           spyOn(telemetry, "isCI").andReturn(false);
+           
+           spyOn(telemetry, "showPrompt");
+           spyOn(telemetry, "track");
+           
+           cli(["node", "cordova", "--version"]).then(function() {
+               expect(telemetry.showPrompt).not.toHaveBeenCalled();
+               expect(telemetry.track).toHaveBeenCalled();
+               done();
+           }).fail(function() {
+               expect(true).toBe(false);
+               done();
+           });
+       });
+       
+       it("track opt-out that happened via 'cordova telemetry off' even if user is NOT opted-in ", function(done) {
+           spyOn(telemetry, "isCI").andReturn(false);
+           spyOn(telemetry, "isOptedIn").andReturn(false); // same as calling `telemetry.turnOff();`
+           spyOn(telemetry, "hasUserOptedInOrOut").andReturn(true);
+           spyOn(telemetry, "track");
+
+           expect(telemetry.isOptedIn()).toBeFalsy();
+           
+           cli(["node", "cordova", "telemetry", "off"]).then(function() {
+               expect(telemetry.isOptedIn()).toBeFalsy();
+               expect(telemetry.track).toHaveBeenCalledWith("telemetry-opt-out", "via-cordova-telemetry-off");
+               done();
+           }).fail(function() {
+               expect(true).toBe(false);
+               done();
+           });;
+       });
+    });
 });

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/55df8989/src/cli.js
----------------------------------------------------------------------
diff --git a/src/cli.js b/src/cli.js
index 890f54a..23d4ecf 100644
--- a/src/cli.js
+++ b/src/cli.js
@@ -89,29 +89,43 @@ module.exports = function(inputArgs) {
     inputArgs = inputArgs || process.argv;
         
     return Q().then(function() {
-        // Skip telemetry prompt when user runs: `cordova telemetry on | off`, `cordova telemetry ...`
-        var isTelemetryCmd = (function() {
-            return inputArgs[2] === 'telemetry';
-        })(inputArgs);
         
-        if (isTelemetryCmd) {
-            return Q(telemetry.isOptedIn);
+        /**
+         * 1- Skip telemetry prompt if:
+         * - CI environment variable is present
+         * - Command is run with `--no-telemetry` flag
+         * - Command ran is: `cordova telemetry on | off | ...`
+         */
+        
+        if(telemetry.isCI(process.env) || telemetry.isNoTelemetryFlag(inputArgs)) {
+            return Q(false);
         }
-
-        // Telemetry Prompt: only shows up on first run
-        // If the user has not made any decision about telemetry yet,
-        // ... a timed prompt is shown(30 seconds), asking him whether or not he wants to opt-in.
-        // ... If the timeout expires without him having made any decisions, he is considered to have opted out.
-
-        // Note: The timed prompt can be prevented from being shown by setting an environment variable: CORDOVA_TELEMETRY_OPT_OUT
-        // ... This is useful in CI environments.
-        return telemetry.setup();
-    }).then(function(isUserOptedIntoTelemetry) {
-        return cli(inputArgs, isUserOptedIntoTelemetry);
+        
+        /**
+         * 2- We shouldn't prompt for telemetry if user issues a command of the form: `cordova telemetry on | off | ...x`
+         */
+        var isTelemetryCmd = inputArgs[2] === 'telemetry';
+        if(isTelemetryCmd) {
+            return Q(telemetry.isOptedIn());
+        }
+        
+        // 3- If user has already been prompted and made a decision, use his saved answer
+        if(telemetry.hasUserOptedInOrOut()) {
+            return Q(telemetry.isOptedIn());
+        }
+        
+        /**
+         * 4- Otherwise, prompt user to opt-in or out
+         * Note: the prompt is shown for 30 seconds. If no choice is made by that time, User is considered to have opted out.
+         */
+        return telemetry.showPrompt();
+        
+    }).then(function(shouldCollectTelemetry) { 
+        cli(inputArgs, shouldCollectTelemetry);
     });
 };
 
-function cli(inputArgs, isUserOptedIntoTelemetry) {
+function cli(inputArgs, shouldCollectTelemetry) {
     // When changing command line arguments, update doc/help.txt accordingly.
     var knownOpts =
         { 'verbose' : Boolean
@@ -164,11 +178,11 @@ function cli(inputArgs, isUserOptedIntoTelemetry) {
             toPrint += ' (cordova-lib@' + libVersion + ')';
         }
         console.log(toPrint);
-        if(isUserOptedIntoTelemetry) {
+        if(shouldCollectTelemetry) {
             var cmd = 'version';
             telemetry.track(cmd, args.version);
         }
-        return;
+        return Q();
     }
 
 
@@ -176,11 +190,13 @@ function cli(inputArgs, isUserOptedIntoTelemetry) {
     // are in a verbose mode.
     process.on('uncaughtException', function(err) {
         logger.error(err);
-        // Test this: err could cause issues
-        telemetry.track('uncaughtException', err);
+        // Don't send exception details, just send that it happened
+        if(shouldCollectTelemetry) {
+            telemetry.track('uncaughtException');
+        }
         process.exit(1);
     });
-
+    
     logger.subscribe(events);
 
     if (args.silent) {
@@ -218,26 +234,22 @@ function cli(inputArgs, isUserOptedIntoTelemetry) {
         if (!args.help && remain[0] == 'help') {
             remain.shift();
         }
-        if(isUserOptedIntoTelemetry) {
+        if(shouldCollectTelemetry) {
             telemetry.track(cmd); 
-            telemetry.trackEvent('category', cmd);
         }
         return help(remain);
     }
     
-    // ToDO: Test this
-    // ToDO: Write console help
-    // ToDO: when running `cordova telemetry on|off`, don't show telemetry prompt
     if (cmd === 'telemetry') {
         if (undashed[1] === 'on') {
             telemetry.turnOn();
-            if (isUserOptedIntoTelemetry) {
+            if (shouldCollectTelemetry) {
                 telemetry.track(cmd, 'on');
             }
         } else if (undashed[1] === 'off') {
             telemetry.turnOff();
-            // Always track telemetry opt-outs whether user opted out or not!
-            telemetry.track('telemetry-opt-out', 'via-telemetry-cmd'); 
+            // Always track telemetry opt-outs (whether user opted out or not!)
+            telemetry.track('telemetry-opt-out', 'via-cordova-telemetry-off'); 
         } else {
             return help('telemetry'); // test this.
         }
@@ -280,9 +292,8 @@ function cli(inputArgs, isUserOptedIntoTelemetry) {
         if (cmd === 'run' && args.list && cordova.raw.targets) {
             var result = cordova.raw.targets.call(null, opts);
             return result.finally(function() {
-                if (isUserOptedIntoTelemetry) {
+                if (shouldCollectTelemetry) {
                     telemetry.track(cmd, result.isFulfilled() ? 'successful' : 'unsuccessful');
-                    telemetry.trackEvent('category', cmd);
                 }
                 return result;
             });
@@ -290,9 +301,8 @@ function cli(inputArgs, isUserOptedIntoTelemetry) {
 
         var result = cordova.raw[cmd].call(null, opts);
         return result.finally(function() {
-            if (isUserOptedIntoTelemetry) {
+            if (shouldCollectTelemetry) {
                 telemetry.track(cmd, result.isFulfilled() ? 'successful' : 'unsuccessful');
-                telemetry.trackEvent('category', cmd);
             }
             return result;
         });
@@ -336,7 +346,7 @@ function cli(inputArgs, isUserOptedIntoTelemetry) {
                 if (someChecksFailed) throw new CordovaError('Some of requirements check failed');
             });
         return result.finally(function() {
-            if (isUserOptedIntoTelemetry) {
+            if (shouldCollectTelemetry) {
                 telemetry.track(cmd, result.isFulfilled() ? 'successful' : 'unsuccessful');
             }
             return result;
@@ -345,14 +355,14 @@ function cli(inputArgs, isUserOptedIntoTelemetry) {
         var port = undashed[1];
         var result = cordova.raw.serve(port);
         return result.finally(function() {
-            if(isUserOptedIntoTelemetry) {
+            if(shouldCollectTelemetry) {
                 telemetry.track(cmd, result.isFulfilled() ? 'successful' : 'unsuccessful');
             }
         });
     } else if (cmd == 'create') {
         var result = create();
         return result.finally(function() {
-            if (isUserOptedIntoTelemetry) {
+            if (shouldCollectTelemetry) {
                 telemetry.track(cmd, result.isFulfilled() ? 'successful' : 'unsuccessful');
             }
             return result;
@@ -386,7 +396,7 @@ function cli(inputArgs, isUserOptedIntoTelemetry) {
                             };
         var result = cordova.raw[cmd](subcommand, targets, download_opts);
         return result.finally(function() {
-            if (isUserOptedIntoTelemetry) {
+            if (shouldCollectTelemetry) {
                 telemetry.track(cmd, result.isFulfilled() ? 'successful' : 'unsuccessful');
             }
             return result;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/55df8989/src/telemetry.js
----------------------------------------------------------------------
diff --git a/src/telemetry.js b/src/telemetry.js
index 0c40c71..77243c6 100644
--- a/src/telemetry.js
+++ b/src/telemetry.js
@@ -22,64 +22,31 @@
           laxcomma:true
 */
 
-var path = require('path');
 var Q = require('q');
 
-var GOOGLE_ANALYTICS_TRACKING_ID = 'UA-64283057-7'; 
+// Google Analytics tracking code
+var GA_TRACKING_CODE = 'UA-64283057-7';
 
 var pkg = require('../package.json');
 var Insight = require('insight');
 var insight = new Insight({
-    trackingCode: GOOGLE_ANALYTICS_TRACKING_ID,
+    trackingCode: GA_TRACKING_CODE,
     pkg: pkg
 });
 
-/**
- * Telemetry Prompt:
- * If the user has not made any decision about telemetry yet,
- * ... a timed prompt is shown, asking him whether or not he wants to opt-in.
- * ... If the timeout expires without him having made any decisions, he is considered to have opted out.
-
- * Note: The timed prompt can be prevented from being shown by setting an environment variable: CORDOVA_TELEMETRY_OPT_OUT
- * ... This is useful in CI environments.
 
-@returns {Boolean} It returns true if the user has agreed to opt-in to telemetry, false otherwise
-*/
-function setup() {
-    var deferred = Q.defer();
+function showPrompt() {
     
-    // ToDO: should we just rely on 'CI' env variable? (what are others doing?)
-    var isInteractive = !process.env.CORDOVA_TELEMETRY_OPT_OUT && !process.env.CI;
-    if(!isInteractive) {
-        // Update user's config file to make sure telemetry doesn't get collected
-        // This handles the case where user had previously opted-in, then 
-        // ... sets up environment variable to signify they want out
-        insight.optOut = true; 
-    }
+    var deferred = Q.defer();
     
-    if (isInteractive && insight.optOut === undefined) {
-
-        // Note: insight.askPermission() won't display the permissions prompt if one of these is true:
-        //     - the process is not a TTY
-        //     - the process was started with --no-insight flag
-        //     - the CI environment variable is set 
-        // For further infos, see: https://github.com/yeoman/insight/blob/3a6ac613b7312272f9f10e1188310b199afa4e1d/lib/index.js#L133
-        
-        // ToDO: Fix link to privacy-statement
-        var msg = 'Privacy statement: http://docs.cordova.io/privacy-statement.html' + require('os').EOL +
-                    'May cordova anonymously report usage statitics to improve the tool over time ?';
-        insight.askPermission(msg, function(unused, optIn) {
-            if(!optIn) {
-                // Always track telemetry opt-outs!
-                track('telemetry-opt-out', 'via-cli-prompt-choice');
-            }
-            deferred.resolve(optIn /* same as !insight.optOut */);
-        }, {
-            optInByDefault: false // If prompt timeout expires, opt the user out of telemetry
-        });
-    } else {
-        deferred.resolve(!insight.optOut);
-    }
+    var msg = 'Do you want to prevent cordova from anonymously collecting usage statitics to improve the tool over time ?';
+    insight.askPermission(msg, function (unused, optIn) {
+        if (!optIn) {
+            // Always track telemetry opt-outs! (whether opted-in or opted-out)
+            track('telemetry-opt-out', 'via-cli-prompt-choice');
+        }
+        deferred.resolve(optIn /* same as !insight.optOut */);
+    });
     
     return deferred.promise;
 }
@@ -105,15 +72,49 @@ function turnOff() {
     insight.optOut = true;
 }
 
+/**
+ * Clears telemetry setting
+ * Has the same effect as if user never answered the telemetry prompt
+ * Useful for testing purposes
+ */
+function clear() {
+    insight.optOut = undefined;
+}
+
 function isOptedIn() {
     return !insight.optOut;
 }
 
+/**
+ * Has the user already answered the telemetry prompt? (thereby opting in or out?)
+ */
+function hasUserOptedInOrOut() {
+    return !(insight.optOut === undefined);
+}
+
+/**
+ * Is the environment variable 'CI' specified ?
+ */
+function isCI(env) {
+    return !!env.CI;
+}
+
+/**
+ * Has the user ran a command of the form: `cordova run --no-telemetry` ?
+ */
+function isNoTelemetryFlag(args) {
+    return args.indexOf('--no-telemetry') > -1;
+}
+
 module.exports = {
-    setup: setup,
     track: track,
     trackEvent: trackEvent,
     turnOn: turnOn,
     turnOff: turnOff,
-    isOptedIn: isOptedIn
+    clear: clear,
+    isOptedIn: isOptedIn,
+    hasUserOptedInOrOut: hasUserOptedInOrOut,
+    isCI: isCI,
+    showPrompt: showPrompt,
+    isNoTelemetryFlag: isNoTelemetryFlag
 };
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org