From f19948b19d943c6cc7d98c8ab25460289da660f6 Mon Sep 17 00:00:00 2001 From: Mark Hammond Date: Fri, 9 Jan 2015 09:53:34 +1100 Subject: [PATCH 01/19] Bug 1117001 - xpcshell tests now log console messages. r=chmanchester --- testing/xpcshell/head.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/testing/xpcshell/head.js b/testing/xpcshell/head.js index c2440b833fc4..30d3f7bdf3b1 100644 --- a/testing/xpcshell/head.js +++ b/testing/xpcshell/head.js @@ -111,6 +111,30 @@ try { } catch (e) { } +// Configure a console listener so messages sent to it are logged as part +// of the test. +try { + let levelNames = {} + for (let level of ["debug", "info", "warn", "error"]) { + levelNames[Components.interfaces.nsIConsoleMessage[level]] = level; + } + + let listener = { + QueryInterface : function(iid) { + if (!iid.equals(Components.interfaces.nsISupports) && + !iid.equals(Components.interfaces.nsIConsoleListener)) { + throw Components.results.NS_NOINTERFACE; + } + return this; + }, + observe : function (msg) { + do_print("CONSOLE_MESSAGE: (" + levelNames[msg.logLevel] + ") " + msg.toString()); + } + }; + Components.classes["@mozilla.org/consoleservice;1"] + .getService(Components.interfaces.nsIConsoleService) + .registerListener(listener); +} catch (e) {} /** * Date.now() is not necessarily monotonically increasing (insert sob story * about times not being the right tool to use for measuring intervals of time, From f3daa22bc754b3535a8d137e14f7184d11178f0b Mon Sep 17 00:00:00 2001 From: Mark Hammond Date: Fri, 9 Jan 2015 09:53:34 +1100 Subject: [PATCH 02/19] Bug 1119104 - add a migration=sync11 query param when about:accounts is opened via migration flow. r=adw --- services/sync/modules/FxaMigrator.jsm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/sync/modules/FxaMigrator.jsm b/services/sync/modules/FxaMigrator.jsm index 863982732da0..e59154098e9f 100644 --- a/services/sync/modules/FxaMigrator.jsm +++ b/services/sync/modules/FxaMigrator.jsm @@ -387,6 +387,8 @@ Migrator.prototype = { // See if we can find a default account name to use. let email = yield this._getDefaultAccountName(sentinel); let tail = email ? "&email=" + encodeURIComponent(email) : ""; + // A special flag so server-side metrics can tell this is part of migration. + tail += "&migration=sync11"; // We want to ask FxA to offer a "Customize Sync" checkbox iff any engines // are disabled. let customize = !this._allEnginesEnabled(); From 1738e10508ae5065f26883fbde5cb9cba917a085 Mon Sep 17 00:00:00 2001 From: Mark Hammond Date: Fri, 9 Jan 2015 09:56:25 +1100 Subject: [PATCH 03/19] Backout 40b7a74be389 due to wrong bug number in commit message --- testing/xpcshell/head.js | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/testing/xpcshell/head.js b/testing/xpcshell/head.js index 30d3f7bdf3b1..c2440b833fc4 100644 --- a/testing/xpcshell/head.js +++ b/testing/xpcshell/head.js @@ -111,30 +111,6 @@ try { } catch (e) { } -// Configure a console listener so messages sent to it are logged as part -// of the test. -try { - let levelNames = {} - for (let level of ["debug", "info", "warn", "error"]) { - levelNames[Components.interfaces.nsIConsoleMessage[level]] = level; - } - - let listener = { - QueryInterface : function(iid) { - if (!iid.equals(Components.interfaces.nsISupports) && - !iid.equals(Components.interfaces.nsIConsoleListener)) { - throw Components.results.NS_NOINTERFACE; - } - return this; - }, - observe : function (msg) { - do_print("CONSOLE_MESSAGE: (" + levelNames[msg.logLevel] + ") " + msg.toString()); - } - }; - Components.classes["@mozilla.org/consoleservice;1"] - .getService(Components.interfaces.nsIConsoleService) - .registerListener(listener); -} catch (e) {} /** * Date.now() is not necessarily monotonically increasing (insert sob story * about times not being the right tool to use for measuring intervals of time, From f0a3a7e379565d48fcd4a0e6645cc4729704b167 Mon Sep 17 00:00:00 2001 From: Dan Mosedale Date: Thu, 8 Jan 2015 14:58:59 -0800 Subject: [PATCH 04/19] Bug 1118402-Close panel after sign-in/sign-up clicked to avoid user confusion, r=MattN --- browser/components/loop/content/js/panel.js | 3 ++ browser/components/loop/content/js/panel.jsx | 3 ++ .../loop/test/desktop-local/panel_test.js | 28 ++++++++++++++++--- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/browser/components/loop/content/js/panel.js b/browser/components/loop/content/js/panel.js index 53807a63a69b..ffb2c519b318 100644 --- a/browser/components/loop/content/js/panel.js +++ b/browser/components/loop/content/js/panel.js @@ -513,8 +513,11 @@ loop.panel = (function(_, mozL10n) { * FxA sign in/up link component. */ var AuthLink = React.createClass({displayName: "AuthLink", + mixins: [sharedMixins.WindowCloseMixin], + handleSignUpLinkClick: function() { navigator.mozLoop.logInToFxA(); + this.closeWindow(); }, render: function() { diff --git a/browser/components/loop/content/js/panel.jsx b/browser/components/loop/content/js/panel.jsx index f186ed815453..20afd56c0c6e 100644 --- a/browser/components/loop/content/js/panel.jsx +++ b/browser/components/loop/content/js/panel.jsx @@ -513,8 +513,11 @@ loop.panel = (function(_, mozL10n) { * FxA sign in/up link component. */ var AuthLink = React.createClass({ + mixins: [sharedMixins.WindowCloseMixin], + handleSignUpLinkClick: function() { navigator.mozLoop.logInToFxA(); + this.closeWindow(); }, render: function() { diff --git a/browser/components/loop/test/desktop-local/panel_test.js b/browser/components/loop/test/desktop-local/panel_test.js index 33b8b3fa877c..f35a60afad5b 100644 --- a/browser/components/loop/test/desktop-local/panel_test.js +++ b/browser/components/loop/test/desktop-local/panel_test.js @@ -253,6 +253,17 @@ describe("loop.panel", function() { }); describe("AuthLink", function() { + + beforeEach(function() { + navigator.mozLoop.calls = { clearCallInProgress: function() {} }; + }); + + afterEach(function() { + delete navigator.mozLoop.logInToFxA; + delete navigator.mozLoop.calls; + navigator.mozLoop.fxAEnabled = true; + }); + it("should trigger the FxA sign in/up process when clicking the link", function() { navigator.mozLoop.loggedInToFxA = false; @@ -266,6 +277,19 @@ describe("loop.panel", function() { sinon.assert.calledOnce(navigator.mozLoop.logInToFxA); }); + it("should close the panel after clicking the link", + function() { + navigator.mozLoop.loggedInToFxA = false; + navigator.mozLoop.logInToFxA = sandbox.stub(); + + var view = createTestPanelView(); + + TestUtils.Simulate.click( + view.getDOMNode().querySelector(".signin-link a")); + + sinon.assert.calledOnce(fakeWindow.close); + }); + it("should be hidden if FxA is not enabled", function() { navigator.mozLoop.fxAEnabled = false; @@ -273,10 +297,6 @@ describe("loop.panel", function() { React.createElement(loop.panel.AuthLink)); expect(view.getDOMNode()).to.be.null; }); - - afterEach(function() { - navigator.mozLoop.fxAEnabled = true; - }); }); describe("SettingsDropdown", function() { From bee2d8a0f5c139a6e64571417b9507fdc2929146 Mon Sep 17 00:00:00 2001 From: Mark Hammond Date: Fri, 9 Jan 2015 10:00:05 +1100 Subject: [PATCH 05/19] Bug 1116708 - xpcshell tests now log console messages. r=chmanchester --- testing/xpcshell/head.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/testing/xpcshell/head.js b/testing/xpcshell/head.js index c2440b833fc4..30d3f7bdf3b1 100644 --- a/testing/xpcshell/head.js +++ b/testing/xpcshell/head.js @@ -111,6 +111,30 @@ try { } catch (e) { } +// Configure a console listener so messages sent to it are logged as part +// of the test. +try { + let levelNames = {} + for (let level of ["debug", "info", "warn", "error"]) { + levelNames[Components.interfaces.nsIConsoleMessage[level]] = level; + } + + let listener = { + QueryInterface : function(iid) { + if (!iid.equals(Components.interfaces.nsISupports) && + !iid.equals(Components.interfaces.nsIConsoleListener)) { + throw Components.results.NS_NOINTERFACE; + } + return this; + }, + observe : function (msg) { + do_print("CONSOLE_MESSAGE: (" + levelNames[msg.logLevel] + ") " + msg.toString()); + } + }; + Components.classes["@mozilla.org/consoleservice;1"] + .getService(Components.interfaces.nsIConsoleService) + .registerListener(listener); +} catch (e) {} /** * Date.now() is not necessarily monotonically increasing (insert sob story * about times not being the right tool to use for measuring intervals of time, From 67df6f0217e4cbd491d84b72c455f7a06a2cba9e Mon Sep 17 00:00:00 2001 From: Mark Hammond Date: Thu, 8 Jan 2015 15:03:22 -0800 Subject: [PATCH 06/19] Bug 1110336 - Update sync old-dialog-based preferences UI to match FxA migration flows, part 1. r=adw --- browser/components/preferences/sync.js | 60 ++++++++++++++++++- browser/components/preferences/sync.xul | 25 ++++++++ .../themes/linux/preferences/preferences.css | 17 ++++++ .../themes/osx/preferences/preferences.css | 17 ++++++ .../windows/preferences/preferences.css | 17 ++++++ services/sync/modules/FxaMigrator.jsm | 26 ++++++-- 6 files changed, 154 insertions(+), 8 deletions(-) diff --git a/browser/components/preferences/sync.js b/browser/components/preferences/sync.js index 80e74b1ed053..97da14f56f76 100644 --- a/browser/components/preferences/sync.js +++ b/browser/components/preferences/sync.js @@ -9,6 +9,12 @@ XPCOMUtils.defineLazyGetter(this, "FxAccountsCommon", function () { return Components.utils.import("resource://gre/modules/FxAccountsCommon.js", {}); }); +XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts", + "resource://gre/modules/FxAccounts.jsm"); + +XPCOMUtils.defineLazyModuleGetter(this, "fxaMigrator", + "resource://services-sync/FxaMigrator.jsm"); + const PAGE_NO_ACCOUNT = 0; const PAGE_HAS_ACCOUNT = 1; const PAGE_NEEDS_UPDATE = 2; @@ -89,6 +95,7 @@ let gSyncPane = { "weave:service:setup-complete", "weave:service:logout:finish", FxAccountsCommon.ONVERIFIED_NOTIFICATION]; + let migrateTopic = "fxa-migration:state-changed"; // Add the observers now and remove them on unload //XXXzpao This should use Services.obs.* but Weave's Obs does nice handling @@ -96,12 +103,22 @@ let gSyncPane = { topics.forEach(function (topic) { Weave.Svc.Obs.add(topic, this.updateWeavePrefs, this); }, this); + // The FxA migration observer is a special case. + Weave.Svc.Obs.add(migrateTopic, this.updateMigrationState, this); + window.addEventListener("unload", function() { topics.forEach(function (topic) { Weave.Svc.Obs.remove(topic, this.updateWeavePrefs, this); }, gSyncPane); + Weave.Svc.Obs.remove(migrateTopic, this.updateMigrationState, this); }, false); + // ask the migration module to broadcast its current state (and nothing will + // happen if it's not loaded - which is good, as that means no migration + // is pending/necessary) - we don't want to suck that module in just to + // find there's nothing to do. + Services.obs.notifyObservers(null, "fxa-migration:state-request", null); + this._stringBundle = Services.strings.createBundle("chrome://browser/locale/preferences/preferences.properties"); this.updateWeavePrefs(); @@ -116,7 +133,6 @@ let gSyncPane = { if (service.fxAccountsEnabled) { // determine the fxa status... this.page = PAGE_PLEASE_WAIT; - Components.utils.import("resource://gre/modules/FxAccounts.jsm"); fxAccounts.getSignedInUser().then(data => { if (!data) { this.page = FXA_PAGE_LOGGED_OUT; @@ -175,6 +191,31 @@ let gSyncPane = { } }, + updateMigrationState: function(subject, state) { + let selIndex; + switch (state) { + case fxaMigrator.STATE_USER_FXA: + selIndex = 0; + break; + case fxaMigrator.STATE_USER_FXA_VERIFIED: + let email = subject.QueryInterface(Components.interfaces.nsISupportsString).data; + let fsfn = this._stringBundle.formatStringFromName; + let label = fsfn("fxaVerificationNeeded.label", [email], 1); + let elt = document.getElementById("sync-migrate-verify-label"); + elt.setAttribute("value", label); + selIndex = 1; + break; + default: + if (state) { // |null| is expected, but everything else is not. + Cu.reportError("updateMigrationState has unknown state: " + state); + } + document.getElementById("sync-migration").hidden = true; + return; + } + document.getElementById("sync-migration").hidden = false; + document.getElementById("sync-migration-deck").selectedIndex = selIndex; + }, + startOver: function (showDialog) { if (showDialog) { let flags = Services.prompt.BUTTON_POS_0 * Services.prompt.BUTTON_TITLE_IS_STRING + @@ -282,7 +323,6 @@ let gSyncPane = { }, verifyFirefoxAccount: function() { - Components.utils.import("resource://gre/modules/FxAccounts.jsm"); fxAccounts.resendVerificationEmail().then(() => { fxAccounts.getSignedInUser().then(data => { let sb = Services.strings.createBundle("chrome://browser/locale/accounts.properties"); @@ -323,7 +363,6 @@ let gSyncPane = { return; } } - Components.utils.import('resource://gre/modules/FxAccounts.jsm'); fxAccounts.signOut().then(() => { this.updateWeavePrefs(); }); @@ -356,5 +395,20 @@ let gSyncPane = { resetSync: function () { this.openSetup("reset"); }, + + // click handlers for the FxA migration. + migrateUpgrade: function() { + fxaMigrator.getFxAccountOptions().then(({url, options}) => { + this.openContentInBrowser(url, options); + }); + }, + + migrateForget: function() { + fxaMigrator.forgetFxAccount(); + }, + + migrateResend: function() { + fxaMigrator.resendVerificationMail(window); + }, }; diff --git a/browser/components/preferences/sync.xul b/browser/components/preferences/sync.xul index 123c367fdc88..8385ffd98c04 100644 --- a/browser/components/preferences/sync.xul +++ b/browser/components/preferences/sync.xul @@ -36,6 +36,31 @@