From b8d2fabb1b77cf15de2632fd29e8421367e5a14d Mon Sep 17 00:00:00 2001
From: Shane Tomlinson <stomlinson@mozilla.com>
Date: Fri, 6 Jan 2012 09:19:18 +0000
Subject: [PATCH] Covering the case of a user choosing a primary email whose
 cert is expired.

* Put the user into the primary_email flow, which will do the provisioning/redirection.
---
 .../static/dialog/resources/state_machine.js  | 27 ++++++++++--
 .../resources/state_machine_unit_test.js      | 43 ++++++++++++++++++-
 2 files changed, 65 insertions(+), 5 deletions(-)

diff --git a/resources/static/dialog/resources/state_machine.js b/resources/static/dialog/resources/state_machine.js
index 04be03ea8..a0b0e3f3c 100644
--- a/resources/static/dialog/resources/state_machine.js
+++ b/resources/static/dialog/resources/state_machine.js
@@ -36,7 +36,9 @@
  * ***** END LICENSE BLOCK ***** */
 (function() {
   var bid = BrowserID,
+      storage = bid.Storage,
       mediator = bid.Mediator,
+      publish = mediator.publish.bind(mediator),
       subscriptions = [],
       stateStack = [],
       controller,
@@ -144,9 +146,9 @@
         });
       }
       else if (authenticated) {
-        mediator.publish("pick_email");
+        publish("pick_email");
       } else {
-        mediator.publish("authenticate");
+        publish("authenticate");
       }
     });
 
@@ -212,7 +214,24 @@
     });
 
     subscribe("email_chosen", function(msg, info) {
-      startState("doEmailChosen", info);
+      var idInfo = storage.getEmail(info.email);
+      if(idInfo) {
+        if(idInfo.type === "primary") {
+          // If the email is a primary, throw the user down the primary flow.
+          // Doing so will catch cases where the primary certificate is expired
+          // and the user must re-verify with their IdP. This flow will
+          // generate its own assertion when ready.  For efficiency, we could
+          // check here whether the cert is ready, but it is early days yet and
+          // the format may change.
+          publish("primary_user", info);
+        }
+        else {
+          startState("doEmailChosen", info);
+        }
+      }
+      else {
+        throw "invalid email";
+      }
     });
 
     subscribe("notme", function() {
@@ -220,7 +239,7 @@
     });
 
     subscribe("logged_out", function() {
-      mediator.publish("authenticate");
+      publish("authenticate");
     });
 
     subscribe("authenticated", function(msg, info) {
diff --git a/resources/static/test/qunit/resources/state_machine_unit_test.js b/resources/static/test/qunit/resources/state_machine_unit_test.js
index b4f136cb2..0a413215b 100644
--- a/resources/static/test/qunit/resources/state_machine_unit_test.js
+++ b/resources/static/test/qunit/resources/state_machine_unit_test.js
@@ -40,7 +40,9 @@
   var bid = BrowserID,
       mediator = bid.Mediator,
       machine,
-      actions;
+      actions,
+      storage = bid.Storage,
+      testHelpers = bid.TestHelpers;
 
   var ActionsMock = function() {
     this.called = {};
@@ -66,10 +68,12 @@
 
   module("resources/state_machine", {
     setup: function() {
+      testHelpers.setup();
       createMachine();
     },
 
     teardown: function() {
+      testHelpers.teardown();
       machine.stop();
     }
   });
@@ -256,4 +260,41 @@
     equal(actions.called.doCancel, true, "cancelled everything");
   });
 
+
+  test("email_chosen with secondary email - call doEmailChosen", function() {
+    var email = "testuser@testuser.com";
+    storage.addEmail(email, { type: "secondary" });
+    mediator.publish("email_chosen", { email: email });
+
+    equal(actions.called.doEmailChosen, true, "doEmailChosen called");
+
+  });
+
+  test("email_chosen with primary email - call doProvisionPrimaryUser", function() {
+    // If the email is a primary, throw the user down the primary flow.
+    // Doing so will catch cases where the primary certificate is expired
+    // and the user must re-verify with their IdP. This flow will
+    // generate its own assertion when ready.  For efficiency, we could
+    // check here whether the cert is ready, but it is early days yet and
+    // the format may change.
+    var email = "testuser@testuser.com";
+    storage.addEmail(email, { type: "primary" });
+    mediator.publish("email_chosen", { email: email });
+
+    equal(actions.called.doProvisionPrimaryUser, true, "doProvisionPrimaryUser called");
+  });
+
+  test("email_chosen with invalid email - throw exception", function() {
+    var email = "testuser@testuser.com",
+        error;
+
+    try {
+      mediator.publish("email_chosen", { email: email });
+    } catch(e) {
+      error = e;
+    }
+
+    equal(error, "invalid email", "expected exception thrown");
+  });
+
 }());
-- 
GitLab