Bug 989549 - Call signOut() in FxAccountsClient.jsm from signOut() in FxAccounts.jsm. r=markh, a=sledru
authorChris Karlof <ckarlof@mozilla.com>
Wed, 09 Apr 2014 16:14:19 -0700
changeset 191707 03566d5096aff914d5c83c9775c9e32384610330
parent 191706 5fc53b821f69745a64878b000e0dbc8d9ea7ae00
child 191708 24003d51424d50e65a5f5e2fea0037d3b75e2128
push id3503
push userraliiev@mozilla.com
push dateMon, 28 Apr 2014 18:51:11 +0000
treeherdermozilla-beta@c95ac01e332e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmarkh, sledru
bugs989549
milestone30.0a2
Bug 989549 - Call signOut() in FxAccountsClient.jsm from signOut() in FxAccounts.jsm. r=markh, a=sledru
services/fxaccounts/FxAccounts.jsm
services/fxaccounts/tests/xpcshell/test_accounts.js
--- a/services/fxaccounts/FxAccounts.jsm
+++ b/services/fxaccounts/FxAccounts.jsm
@@ -455,19 +455,36 @@ FxAccountsInternal.prototype = {
       clearTimeout(this.currentTimer);
       this.currentTimer = 0;
     }
     this.currentAccountState.abort();
     this.currentAccountState = new AccountState(this);
   },
 
   signOut: function signOut() {
-    this.abortExistingFlow();
-    this.currentAccountState.signedInUser = null; // clear in-memory cache
-    return this.signedInUserStorage.set(null).then(() => {
+    let currentState = this.currentAccountState;
+    let fxAccountsClient = this.fxAccountsClient;
+    let sessionToken;
+    return currentState.getUserAccountData().then(data => {
+      // Save the session token for use in the call to signOut below.
+      sessionToken = data && data.sessionToken;
+      this.abortExistingFlow();
+      this.currentAccountState.signedInUser = null; // clear in-memory cache
+      return this.signedInUserStorage.set(null);
+    }).then(() => {
+      // Wrap this in a promise so *any* errors in signOut won't
+      // block the local sign out. This is *not* returned.
+      Promise.resolve().then(() => {
+        // This can happen in the background and shouldn't block
+        // the user from signing out. The server must tolerate
+        // clients just disappearing, so this call should be best effort.
+        return fxAccountsClient.signOut(sessionToken);
+      }).then(null, err => {
+        log.error("Error during remote sign out of Firefox Accounts: " + err);
+      });
       this.notifyObservers(ONLOGOUT_NOTIFICATION);
     });
   },
 
   /**
    * Fetch encryption keys for the signed-in-user from the FxA API server.
    *
    * Not for user consumption.  Exists to cause the keys to be fetch.
--- a/services/fxaccounts/tests/xpcshell/test_accounts.js
+++ b/services/fxaccounts/tests/xpcshell/test_accounts.js
@@ -72,16 +72,18 @@ function MockFxAccountsClient() {
 
   this.resendVerificationEmail = function(sessionToken) {
     // Return the session token to show that we received it in the first place
     return Promise.resolve(sessionToken);
   };
 
   this.signCertificate = function() { throw "no" };
 
+  this.signOut = function() { return Promise.resolve(); };
+
   FxAccountsClient.apply(this);
 }
 MockFxAccountsClient.prototype = {
   __proto__: FxAccountsClient.prototype
 }
 
 let MockStorage = function() {
   this.data = null;
@@ -532,16 +534,55 @@ add_test(function test_resend_email() {
         // Ok abort polling before we go on to the next test
         fxa.internal.abortExistingFlow();
         run_next_test();
       });
     });
   });
 });
 
+add_test(function test_sign_out() {
+  do_test_pending();
+  let fxa = new MockFxAccounts();
+  let remoteSignOutCalled = false;
+  let client = fxa.internal.fxAccountsClient;
+  client.signOut = function() { remoteSignOutCalled = true; return Promise.resolve(); };
+  makeObserver(ONLOGOUT_NOTIFICATION, function() {
+    log.debug("test_sign_out_with_remote_error observed onlogout");
+    // user should be undefined after sign out
+    fxa.internal.getUserAccountData().then(user => {
+      do_check_eq(user, null);
+      do_check_true(remoteSignOutCalled);
+      do_test_finished();
+      run_next_test();
+    });
+  });
+  fxa.signOut();
+});
+
+add_test(function test_sign_out_with_remote_error() {
+  do_test_pending();
+  let fxa = new MockFxAccounts();
+  let client = fxa.internal.fxAccountsClient;
+  let remoteSignOutCalled = false;
+  // Force remote sign out to trigger an error
+  client.signOut = function() { remoteSignOutCalled = true; throw "Remote sign out error"; };
+  makeObserver(ONLOGOUT_NOTIFICATION, function() {
+    log.debug("test_sign_out_with_remote_error observed onlogout");
+    // user should be undefined after sign out
+    fxa.internal.getUserAccountData().then(user => {
+      do_check_eq(user, null);
+      do_check_true(remoteSignOutCalled);
+      do_test_finished();
+      run_next_test();
+    });
+  });
+  fxa.signOut();
+});
+
 /*
  * End of tests.
  * Utility functions follow.
  */
 
 function expandHex(two_hex) {
   // Return a 64-character hex string, encoding 32 identical bytes.
   let eight_hex = two_hex + two_hex + two_hex + two_hex;