Bug 1249029 - Add quality metrics for FxA Verification via Push r=markh draft push-metrics
authorvladikoff <vlad@vladikoff.com>
Tue, 15 Mar 2016 20:28:50 -0400
branchpush-metrics
changeset 343228 7d52b9b5e171851797c6940a235d5970c0679e77
parent 342225 9c5d494d05485aebf3fedf649abc0e7ae9d2dcf2
child 724551 dcb9537b4bcaadd335666f9d810014145e3888b7
push id13559
push uservlad@vladikoff.com
push dateTue, 22 Mar 2016 02:27:32 +0000
reviewersmarkh
bugs1249029
milestone48.0a1
Bug 1249029 - Add quality metrics for FxA Verification via Push r=markh MozReview-Commit-ID: 6bCjSZt85Kw
services/fxaccounts/FxAccounts.jsm
services/fxaccounts/FxAccountsClient.jsm
services/fxaccounts/tests/xpcshell/test_client.js
--- a/services/fxaccounts/FxAccounts.jsm
+++ b/services/fxaccounts/FxAccounts.jsm
@@ -410,18 +410,18 @@ FxAccountsInternal.prototype = {
    */
   get localtimeOffsetMsec() {
     return this.fxAccountsClient.localtimeOffsetMsec;
   },
 
   /**
    * Ask the server whether the user's email has been verified
    */
-  checkEmailStatus: function checkEmailStatus(sessionToken) {
-    return this.fxAccountsClient.recoveryEmailStatus(sessionToken);
+  checkEmailStatus: function checkEmailStatus(sessionToken, options = {}) {
+    return this.fxAccountsClient.recoveryEmailStatus(sessionToken, options);
   },
 
   /**
    * Once the user's email is verified, we can request the keys
    */
   fetchKeys: function fetchKeys(keyFetchToken) {
     log.debug("fetchKeys: " + !!keyFetchToken);
     if (logPII) {
@@ -630,17 +630,17 @@ FxAccountsInternal.prototype = {
     return currentState.getUserAccountData().then(data => {
       if (!data) {
         log.trace("checkVerificationStatus - no user data");
         return null;
       }
 
       if (!this.isUserEmailVerified(data)) {
         log.trace("checkVerificationStatus - forcing verification status check");
-        this.pollEmailStatus(currentState, data.sessionToken, "start");
+        this.pollEmailStatus(currentState, data.sessionToken, "push");
       }
     });
   },
 
   _destroyOAuthToken: function(tokenData) {
     let client = new FxAccountsOAuthGrantClient({
       serverURL: tokenData.server,
       client_id: FX_OAUTH_CLIENT_ID
@@ -1027,17 +1027,17 @@ FxAccountsInternal.prototype = {
   notifyObservers: function(topic, data) {
     log.debug("Notifying observers of " + topic);
     Services.obs.notifyObservers(null, topic, data);
   },
 
   // XXX - pollEmailStatus should maybe be on the AccountState object?
   pollEmailStatus: function pollEmailStatus(currentState, sessionToken, why) {
     log.debug("entering pollEmailStatus: " + why);
-    if (why == "start") {
+    if (why == "start" || why == "push") {
       if (this.currentTimer) {
         log.debug("pollEmailStatus starting while existing timer is running");
         clearTimeout(this.currentTimer);
         this.currentTimer = null;
       }
 
       // If we were already polling, stop and start again.  This could happen
       // if the user requested the verification email to be resent while we
@@ -1050,17 +1050,17 @@ FxAccountsInternal.prototype = {
         // handle a rejection" messages, so add an error handler directly
         // on the promise to log the error.
         currentState.whenVerifiedDeferred.promise.then(null, err => {
           log.info("the wait for user verification was stopped: " + err);
         });
       }
     }
 
-    this.checkEmailStatus(sessionToken)
+    this.checkEmailStatus(sessionToken, { reason: why })
       .then((response) => {
         log.debug("checkEmailStatus -> " + JSON.stringify(response));
         if (response && response.verified) {
           currentState.updateUserAccountData({ verified: true })
             .then(() => {
               return currentState.getUserAccountData();
             })
             .then(data => {
--- a/services/fxaccounts/FxAccountsClient.jsm
+++ b/services/fxaccounts/FxAccountsClient.jsm
@@ -201,18 +201,23 @@ this.FxAccountsClient.prototype = {
 
   /**
    * Check the verification status of the user's FxA email address
    *
    * @param sessionTokenHex
    *        The current session token encoded in hex
    * @return Promise
    */
-  recoveryEmailStatus: function (sessionTokenHex) {
-    return this._request("/recovery_email/status", "GET",
+  recoveryEmailStatus: function (sessionTokenHex, options = {}) {
+    let path = "/recovery_email/status";
+    if (options.reason) {
+      path += "?reason=" + encodeURIComponent(options.reason);
+    }
+
+    return this._request(path, "GET",
       deriveHawkCredentials(sessionTokenHex, "sessionToken"));
   },
 
   /**
    * Resend the verification email for the user
    *
    * @param sessionTokenHex
    *        The current token encoded in hex
--- a/services/fxaccounts/tests/xpcshell/test_client.js
+++ b/services/fxaccounts/tests/xpcshell/test_client.js
@@ -379,16 +379,17 @@ add_task(function* test_signOut() {
 add_task(function* test_recoveryEmailStatus() {
   let emailStatus = JSON.stringify({verified: true});
   let errorMessage = JSON.stringify({code: 400, errno: 102, error: "doesn't exist"});
   let tries = 0;
 
   let server = httpd_setup({
     "/recovery_email/status": function(request, response) {
       do_check_true(request.hasHeader("Authorization"));
+      do_check_eq("", request._queryString);
 
       if (tries === 0) {
         tries += 1;
         response.setStatusLine(request.httpVersion, 200, "OK");
         response.bodyOutputStream.write(emailStatus, emailStatus.length);
         return;
       }
 
@@ -409,16 +410,38 @@ add_task(function* test_recoveryEmailSta
     do_throw("Expected to catch an exception");
   } catch(expectedError) {
     do_check_eq(102, expectedError.errno);
   }
 
   yield deferredStop(server);
 });
 
+add_task(function* test_recoveryEmailStatusWithReason() {
+  let emailStatus = JSON.stringify({verified: true});
+  let server = httpd_setup({
+    "/recovery_email/status": function(request, response) {
+      do_check_true(request.hasHeader("Authorization"));
+      // if there is a query string then it will have a reason
+      do_check_eq("reason=push", request._queryString);
+
+      response.setStatusLine(request.httpVersion, 200, "OK");
+      response.bodyOutputStream.write(emailStatus, emailStatus.length);
+      return;
+    },
+  });
+
+  let client = new FxAccountsClient(server.baseURI);
+  let result = yield client.recoveryEmailStatus(FAKE_SESSION_TOKEN, {
+    reason: "push",
+  });
+  do_check_eq(result.verified, true);
+  yield deferredStop(server);
+});
+
 add_task(function* test_resendVerificationEmail() {
   let emptyMessage = "{}";
   let errorMessage = JSON.stringify({code: 400, errno: 102, error: "doesn't exist"});
   let tries = 0;
 
   let server = httpd_setup({
     "/recovery_email/resend_code": function(request, response) {
       do_check_true(request.hasHeader("Authorization"));