Bug 758237 - Account Provisioner tab should close and respawn AP dialog if provider XML is corrupt or returns error. r+ui-r=bwinton, a=Standard8.
authorMike Conley <mconley@mozilla.com>
Mon, 28 May 2012 17:04:25 -0400
changeset 11350 f875a2e013396434c9dd94ffe9e437280f2e4e90
parent 11349 e893db8a2ea501bd69b388429e48d99780f18be9
child 11351 08204ee681fe42189ae9acb5272b2874eff1817c
push id513
push usermconley@mozilla.com
push dateMon, 28 May 2012 21:06:09 +0000
treeherdercomm-beta@ff96b286f877 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersStandard8
bugs758237
Bug 758237 - Account Provisioner tab should close and respawn AP dialog if provider XML is corrupt or returns error. r+ui-r=bwinton, a=Standard8.
mail/components/newmailaccount/content/accountProvisioner.js
mail/components/newmailaccount/content/uriListener.js
mail/test/mozmill/newmailaccount/html/configError.xml
mail/test/mozmill/newmailaccount/html/providerList
mail/test/mozmill/newmailaccount/html/registrationError.html
mail/test/mozmill/newmailaccount/html/suggestFromName
mail/test/mozmill/newmailaccount/test-newmailaccount.js
mail/test/mozmill/shared-modules/test-newmailaccount-helpers.js
--- a/mail/components/newmailaccount/content/accountProvisioner.js
+++ b/mail/components/newmailaccount/content/accountProvisioner.js
@@ -365,17 +365,17 @@ var EmailAccountProvisioner = {
     $(window).unload(function() {
       if (window.arguments[0].search_engine
           && $("#search_engine_check").prop("checked")) {
         let engine = Services.search.getEngineByName(window.arguments[0].search_engine);
         Services.search.currentEngine = engine;
       }
     });
 
-    if (window.arguments[0].search_engine || window.arguments[0].success) {
+    if (window.arguments[0].success) {
       // Show the success page which lets a user compose mail, find add-ons,
       // set a signature, etc.
       gLog.info("Looks like we just finished ordering an address - showing the success page...");
       EmailAccountProvisioner.showSuccessPage();
     } else {
       // The default mode, where we display the search input, providers, etc
       $("#window").show();
       $("#successful_account").hide();
--- a/mail/components/newmailaccount/content/uriListener.js
+++ b/mail/components/newmailaccount/content/uriListener.js
@@ -175,53 +175,55 @@ TracingListener.prototype = {
   onStartRequest: function (/* nsIRequest */ aRequest,
                             /* nsISupports */ aContext) {
     this.oldListener.onStartRequest(aRequest, aContext);
   },
 
   onStopRequest: function (/* nsIRequest */ aRequest,
                            /* nsISupports */ aContext,
                            /* int */ aStatusCode) {
+    let tabmail = document.getElementById('tabmail');
+    let success = false;
+    let account;
+
     try {
       // Attempt to construct the downloaded data into XML
       let data = this.chunks.join("");
       let xml = new XML(data);
 
       // Attempt to derive email account information
       let accountConfig = accountCreationFuncs.readFromXML(xml);
       accountCreationFuncs.replaceVariables(accountConfig,
-        this.params.realName,
-        this.params.email);
-      let account = accountCreationFuncs.createAccountInBackend(accountConfig);
-
-      // Switch to the mail tab
-      let tabmail = document.getElementById('tabmail');
-      tabmail.switchToTab(0);
-
-      // Find the tab associated with this browser, and close it.
-      let myTabInfo = tabmail.tabInfo
-        .filter((function (x) {
-              return "browser" in x && x.browser == this.browser;
-              }).bind(this))[0];
-      tabmail.closeTab(myTabInfo);
-
-      // Respawn the account provisioner to announce our success
-      NewMailAccountProvisioner(null, {
-        success: true,
-        search_engine: this.params.searchEngine,
-        account: account,
-      });
+                                            this.params.realName,
+                                            this.params.email);
+      account = accountCreationFuncs.createAccountInBackend(accountConfig);
+      success = true;
     } catch (e) {
-      // Something went wrong.  Right now, we just dump the problem out
-      // to the Error Console.  We should really do something smarter and
-      // more user-facing, because if - for example - a provider passes
-      // some bogus XML, this routine silently fails.
+      // Something went wrong with account set up. Dump the error out to the
+      // error console. The tab will be closed, and the Account Provisioner
+      // tab will be reopened.
       Components.utils.reportError("Problem interpreting provider XML:" + e);
     }
 
+    tabmail.switchToTab(0);
+
+    // Find the tab associated with this browser, and close it.
+    let myTabInfo = tabmail.tabInfo
+      .filter((function (x) {
+            return "browser" in x && x.browser == this.browser;
+            }).bind(this))[0];
+    tabmail.closeTab(myTabInfo);
+
+    // Respawn the account provisioner to announce our success
+    NewMailAccountProvisioner(null, {
+      success: success,
+      search_engine: this.params.searchEngine,
+      account: account,
+    });
+
     this.oldListener.onStopRequest(aRequest, aContext, aStatusCode);
   },
 
   onDataAvailable: function (/* nsIRequest */ aRequest,
                              /* nsISupports */ aContext,
                              /* nsIInputStream */ aStream,
                              /* int */ aOffset,
                              /* int */ aCount) {
new file mode 100644
--- /dev/null
+++ b/mail/test/mozmill/newmailaccount/html/configError.xml
@@ -0,0 +1,6 @@
+<clientConfig version="1.1">
+  <emailProvider id="%DOMAIN%"/>
+  <error code="USER_CANCEL">
+    You have cancelled your order.
+  </error>
+</clientConfig>
--- a/mail/test/mozmill/newmailaccount/html/providerList
+++ b/mail/test/mozmill/newmailaccount/html/providerList
@@ -35,11 +35,16 @@
   "search_engine": "German"
 },{"id": "corrupt",
   "label": "Corrupt Provider",
   "paid": false,
   "languages" : ["en-US"],
   "api": "http://localhost:43336/registrationCorrupt.html",
   "tos_url": "http://www.example.com/corrupt-tos",
   "privacy_url": "http://www.example.com/corrupt-privacy"
-}
-
-]
+},{"id": "err",
+  "label": "Error Provider",
+  "paid": false,
+  "languages" : ["en-US"],
+  "api": "http://localhost:43336/registrationError.html",
+  "tos_url": "http://www.example.com/err-tos",
+  "privacy_url": "http://www.example.com/err-privacy"
+}]
new file mode 100644
--- /dev/null
+++ b/mail/test/mozmill/newmailaccount/html/registrationError.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+  <head>
+    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+    <title>Fake registration page to Error XML</title>
+  </head>
+  <body>
+
+    <div class="title">Local version</div>
+    <div class="content">
+      <form action="configError.xml" method="GET">
+         <p>
+         First name: <input value="Green" id="first" name="firstname" type="text"><br>
+         Last name: <input value="Llama" id="last" name="lastname" type="text"><br>
+         Email: <input value="da.green.llama@example.com" id="email" name="email" type="text"><br>
+         <input value="Send" type="submit">
+         </p>
+      </form>
+    </div>
+  </body>
+</html>
--- a/mail/test/mozmill/newmailaccount/html/suggestFromName
+++ b/mail/test/mozmill/newmailaccount/html/suggestFromName
@@ -1,10 +1,11 @@
-
 [{"product": "personalized_email", "addresses": ["green@example.com",
 "green_llama@example.com", "gllama@example.com"], "succeeded": true, "quote":
 "b28acb3c0a464d33af22", "price": 0, "provider": "bar"}, {"product":
 "personalized_email", "addresses": ["green-bar@example.com", "me-bar@example.com",
 "green-bar@madeup.nul", "green@bar.nul", "green@barexample.nul",
 "greenbar@greenllama.nul", "mebar@greenllama.nul"], "succeeded": true, "quote":
 "3f93e48679ab46a49475", "price": "20.00", "provider": "foo"},
 {"product": "personalized_email", "addresses": ["corrupt@corrupt.nul"],
-"succeeded": true, "quote": "abcdefg", "price": 0, "provider": "corrupt"}]
+"succeeded": true, "quote": "abcdefg", "price": 0, "provider": "corrupt"},
+{"product": "personalized_email", "addresses": ["error@error.nul"],
+"succeeded": true, "quote": "abcdefg", "price": 0, "provider": "err"}]
--- a/mail/test/mozmill/newmailaccount/test-newmailaccount.js
+++ b/mail/test/mozmill/newmailaccount/test-newmailaccount.js
@@ -210,17 +210,17 @@ function subtest_get_an_account(w) {
 }
 
 /**
  * This is a subtest for test_get_an_account, and runs the second time the
  * account provisioner window is opened.
  */
 function subtest_get_an_account_part_2(w) {
   // Re-get the new window
-  $ = w.window.$;
+  let $ = w.window.$;
 
   // An account should have been added.
   assert_equals(nAccounts(), gNumAccounts + 1);
 
   // We want this provider to be our default search engine.
   wait_for_element_invisible(w, "window");
   wait_for_element_visible(w, "successful_account");
 
@@ -619,24 +619,25 @@ function test_throws_console_error_on_co
   gNumAccounts = nAccounts();
 
   gConsoleListener.reset();
   gConsoleListener.listenFor("Problem interpreting provider XML:");
 
   Services.console.registerListener(gConsoleListener);
 
   // Click the OK button to order the account.
+  plan_for_modal_dialog("AccountCreation", close_dialog_immediately);
+
   let btn = tab.browser.contentWindow.document.querySelector("input[value=Send]");
   mc.click(new elib.Elem(btn));
+  wait_for_modal_dialog("AccountCreation");
 
   gConsoleListener.wait();
 
   Services.console.unregisterListener(gConsoleListener);
-
-  mc.tabmail.closeTab(tab);
 }
 
 /**
  * Test that if the providerList is invalid or broken JSON, that
  * we "go offline" and display an error message.
  */
 function test_broken_provider_list_goes_offline() {
   let original = Services.prefs.getCharPref(kProviderListPref);
@@ -912,16 +913,26 @@ function sub_get_to_order_form(aControll
   // Pick the email address green@example.com
   plan_for_content_tab_load();
 
   // Clicking this button should close the modal dialog.
   $('button.create[address="' + aAddress + '"]').click();
 }
 
 /**
+ * Helper function to be passed to plan_for_modal_dialog that closes the
+ * Account Provisioner dialog immediately.
+ */
+function close_dialog_immediately(aController) {
+  plan_for_window_close(aController);
+  mc.click(new elib.Elem(aController.window.document.querySelector(".close")));
+  wait_for_window_close();
+}
+
+/**
  * Test that clicking on links in the order form open in the same account
  * provisioner tab.
  */
 function test_internal_link_opening_behaviour() {
   get_to_order_form();
 
   // Open the provisioner - once opened, let subtest_get_an_account run...
   let tab = mc.tabmail.currentTabInfo;
@@ -977,8 +988,35 @@ function test_external_link_opening_beha
   mc.click(new elib.Elem(external));
 
   mc.waitFor(function () gMockExtProtSvc.urlLoaded(targetHref),
              "Timed out waiting for the link " + targetHref + "to be " +
              "opened in the default browser.");
   gMockExtProtSvcReg.unregister();
   mc.tabmail.closeTab(tab);
 }
+
+/**
+ * Test that if the provider returns XML that we can't turn into an account,
+ * then we error out and go back to the Account Provisioner dialog.
+ */
+function test_return_to_provisioner_on_error_XML() {
+  const kOriginalTabNum = mc.tabmail.tabContainer.childNodes.length;
+
+  get_to_order_form("error@error.nul");
+
+  let tab = mc.tabmail.currentTabInfo;
+  let doc = tab.browser.contentWindow.document;
+
+  plan_for_modal_dialog("AccountCreation", close_dialog_immediately);
+
+  // Click the OK button to order the account.
+  let btn = tab.browser.contentWindow.document.querySelector("input[value=Send]");
+  mc.click(new elib.Elem(btn));
+
+  wait_for_modal_dialog("AccountCreation");
+
+  // We should be done executing the function defined in plan_for_modal_dialog
+  // now, so the Account Provisioner dialog should be closed, and the order
+  // form tab should have been closed.
+  assert_equals(kOriginalTabNum, mc.tabmail.tabContainer.childNodes.length,
+                "Timed out waiting for the order form tab to close.");
+}
--- a/mail/test/mozmill/shared-modules/test-newmailaccount-helpers.js
+++ b/mail/test/mozmill/shared-modules/test-newmailaccount-helpers.js
@@ -194,17 +194,17 @@ var gConsoleListener = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIConsoleListener]),
   _msg: null,
   _sawMsg: false,
 
   observe: function(aMsg) {
     if (!this._msg)
       return;
 
-    this._sawMsg = (aMsg.message.indexOf(this._msg) != -1);
+    this._sawMsg |= (aMsg.message.indexOf(this._msg) != -1);
   },
 
   listenFor: function(aMsg) {
     this._msg = aMsg;
   },
 
   reset: function() {
     this._msg = null;