Bug 965896 - Allow a sync startOver to re-enable Firefox Accounts. r=rnewman, a=gavin
authorMark Hammond <mhammond@skippinet.com.au>
Wed, 12 Feb 2014 17:25:41 +1100
changeset 183797 0e1a2fd4a2a025589b36c0adf42b386cff304694
parent 183796 fc402a7182ef27631c3ffa904316f69115e65bff
child 183798 8b2cc1963145b008f08cb4366a2b0d30f14326a1
push id462
push userraliiev@mozilla.com
push dateTue, 22 Apr 2014 00:22:30 +0000
treeherdermozilla-release@ac5db8c74ac0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrnewman, gavin
bugs965896
milestone29.0a2
Bug 965896 - Allow a sync startOver to re-enable Firefox Accounts. r=rnewman, a=gavin
services/common/tests/unit/head_helpers.js
services/sync/Weave.js
services/sync/modules/service.js
services/sync/tests/unit/test_fxa_startOver.js
services/sync/tests/unit/xpcshell.ini
--- a/services/common/tests/unit/head_helpers.js
+++ b/services/common/tests/unit/head_helpers.js
@@ -168,16 +168,21 @@ function installFakePAC() {
 }
 
 function uninstallFakePAC() {
   _("Uninstalling fake PAC.");
   let CID = PACSystemSettings.CID;
   Cm.nsIComponentRegistrar.unregisterFactory(CID, PACSystemSettings);
 }
 
-// We want to ensure the legacy provider is used for most of these tests; the
-// tests that know how to deal with the Firefox Accounts identity hack things
-// to ensure that still works.
+// We want to ensure the legacy provider is used for most of these tests,
+// including after a service.startOver.  The tests that know how to deal with
+// the Firefox Accounts identity hack things to ensure that still works.
 function setDefaultIdentityConfig() {
   Cu.import("resource://gre/modules/Services.jsm");
   Services.prefs.setBoolPref("services.sync.fxaccounts.enabled", false);
+  Services.prefs.setBoolPref("services.sync-testing.startOverKeepIdentity", true);
+  do_register_cleanup(function() {
+    Services.prefs.clearUserPref("services.sync.fxaccounts.enabled");
+    Services.prefs.clearUserPref("services.sync-testing.startOverKeepIdentity");
+  });
 }
 setDefaultIdentityConfig();
--- a/services/sync/Weave.js
+++ b/services/sync/Weave.js
@@ -101,20 +101,20 @@ WeaveService.prototype = {
     } catch (_) {
       // That pref doesn't exist - so let's assume this is a first-run.
       // If sync already appears configured, we assume it's for the legacy
       // provider.
       let prefs = Services.prefs.getBranch(SYNC_PREFS_BRANCH);
       fxAccountsEnabled = !prefs.prefHasUserValue("username");
       Services.prefs.setBoolPref("services.sync.fxaccounts.enabled", fxAccountsEnabled);
     }
-    // Currently we don't support toggling this pref after initialization, so
-    // inject the pref value as a regular boolean.
-    delete this.fxAccountsEnabled;
-    return this.fxAccountsEnabled = fxAccountsEnabled;
+    // Currently we don't support toggling this pref after initialization -
+    // except when sync is reset - but this 1 exception is enough that we can't
+    // cache the value.
+    return fxAccountsEnabled;
   },
 
   observe: function (subject, topic, data) {
     switch (topic) {
     case "app-startup":
       let os = Cc["@mozilla.org/observer-service;1"].
                getService(Ci.nsIObserverService);
       os.addObserver(this, "final-ui-startup", true);
--- a/services/sync/modules/service.js
+++ b/services/sync/modules/service.js
@@ -884,17 +884,42 @@ Sync11Service.prototype = {
     this._ignorePrefObserver = true;
     Svc.Prefs.resetBranch("");
     this._ignorePrefObserver = false;
 
     Svc.Prefs.set("lastversion", WEAVE_VERSION);
 
     this.identity.deleteSyncCredentials();
 
-    Svc.Obs.notify("weave:service:start-over:finish");
+    // If necessary, reset the identity manager, then re-initialize it so the
+    // FxA manager is used.  This is configurable via a pref - mainly for tests.
+    let keepIdentity = false;
+    try {
+      keepIdentity = Services.prefs.getBoolPref("services.sync-testing.startOverKeepIdentity");
+    } catch (_) { /* no such pref */ }
+    if (keepIdentity) {
+      Svc.Obs.notify("weave:service:start-over:finish");
+      return;
+    }
+
+    this.identity.username = "";
+    Services.prefs.clearUserPref("services.sync.fxaccounts.enabled");
+    this.status.__authManager = null;
+    this.identity = Status._authManager;
+    this._clusterManager = this.identity.createClusterManager(this);
+
+    // Tell the new identity manager to initialize itself
+    this.identity.initialize().then(() => {
+      Svc.Obs.notify("weave:service:start-over:finish");
+    }).then(null, err => {
+      this._log.error("startOver failed to re-initialize the identity manager: " + err);
+      // Still send the observer notification so the current state is
+      // reflected in the UI.
+      Svc.Obs.notify("weave:service:start-over:finish");
+    });
   },
 
   persistLogin: function persistLogin() {
     try {
       this.identity.persistCredentials(true);
     } catch (ex) {
       this._log.info("Unable to persist credentials: " + ex);
     }
new file mode 100644
--- /dev/null
+++ b/services/sync/tests/unit/test_fxa_startOver.js
@@ -0,0 +1,61 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+Cu.import("resource://testing-common/services/sync/utils.js");
+Cu.import("resource://services-sync/identity.js");
+Cu.import("resource://services-sync/browserid_identity.js");
+Cu.import("resource://services-sync/service.js");
+
+function run_test() {
+  initTestLogging("Trace");
+  run_next_test();
+}
+
+add_task(function* test_startover() {
+  let oldValue = Services.prefs.getBoolPref("services.sync-testing.startOverKeepIdentity", true);
+  Services.prefs.setBoolPref("services.sync-testing.startOverKeepIdentity", false);
+
+  yield configureIdentity({username: "johndoe"});
+  // The pref that forces FxA identities should not be set.
+  do_check_false(Services.prefs.getBoolPref("services.sync.fxaccounts.enabled"));
+  // And the boolean flag on the xpcom service should reflect this.
+  let xps = Cc["@mozilla.org/weave/service;1"]
+            .getService(Components.interfaces.nsISupports)
+            .wrappedJSObject;
+  do_check_false(xps.fxAccountsEnabled);
+
+  // we expect the "legacy" provider (but can't instanceof that, as BrowserIDManager
+  // extends it)
+  do_check_false(Service.identity instanceof BrowserIDManager);
+  Service.login();
+  // We should have a cluster URL
+  do_check_true(Service.clusterURL.length > 0);
+
+  // remember some stuff so we can reset it after.
+  let oldIdentidy = Service.identity;
+  let oldClusterManager = Service._clusterManager;
+  let deferred = Promise.defer();
+  Services.obs.addObserver(function observeStartOverFinished() {
+    Services.obs.removeObserver(observeStartOverFinished, "weave:service:start-over:finish");
+    deferred.resolve();
+  }, "weave:service:start-over:finish", false);
+
+  Service.startOver();
+  yield deferred; // wait for the observer to fire.
+
+  // should have reset the pref that indicates if FxA is enabled.
+  do_check_true(Services.prefs.getBoolPref("services.sync.fxaccounts.enabled"));
+  // the xpcom service should agree FxA is enabled.
+  do_check_true(xps.fxAccountsEnabled);
+  // should have swapped identities.
+  do_check_true(Service.identity instanceof BrowserIDManager);
+  // should have clobbered the cluster URL
+  do_check_eq(Service.clusterURL, "");
+
+  // reset the world.
+  Service.identity = oldIdentity = Service.identity;
+  Service._clusterManager = Service._clusterManager;
+  Services.prefs.setBoolPref("services.sync.fxaccounts.enabled", false);
+
+  Services.prefs.setBoolPref("services.sync-testing.startOverKeepIdentity", oldValue);
+});
--- a/services/sync/tests/unit/xpcshell.ini
+++ b/services/sync/tests/unit/xpcshell.ini
@@ -116,16 +116,19 @@ skip-if = os == "android"
 [test_notifications.js]
 [test_score_triggers.js]
 [test_sendcredentials_controller.js]
 [test_status.js]
 [test_status_checkSetup.js]
 [test_syncscheduler.js]
 [test_upgrade_old_sync_key.js]
 
+# Firefox Accounts specific tests
+[test_fxa_startOver.js]
+
 # Finally, we test each engine.
 [test_addons_engine.js]
 run-sequentially = Hardcoded port in static files.
 [test_addons_reconciler.js]
 [test_addons_store.js]
 run-sequentially = Hardcoded port in static files.
 [test_addons_tracker.js]
 [test_bookmark_batch_fail.js]