diff --git a/browserid/static/dialog/controllers/dialog_controller.js b/browserid/static/dialog/controllers/dialog_controller.js index 491d983fabfa5bced7d4e27424bf97ac90c57715..9f0507b275c2c141b29e9ad2b1e306ed7b6b313b 100644 --- a/browserid/static/dialog/controllers/dialog_controller.js +++ b/browserid/static/dialog/controllers/dialog_controller.js @@ -42,7 +42,9 @@ (function() { "use strict"; - var user = BrowserID.User; + var bid = BrowserID, + user = bid.User, + errors = bid.Errors; PageController.extend("Dialog", {}, { init: function(el) { @@ -182,7 +184,8 @@ doEmailConfirmed: function() { var self=this; // yay! now we need to produce an assertion. - user.getAssertion(this.confirmEmail, self.doAssertionGenerated.bind(self)); + user.getAssertion(this.confirmEmail, self.doAssertionGenerated.bind(self), + self.getErrorDialog(errors.getAssertion)); }, doAssertionGenerated: function(assertion) { @@ -195,16 +198,16 @@ }, doNotMe: function() { - user.logoutUser(this.doAuthenticate.bind(this)); + var self=this; + user.logoutUser(self.doAuthenticate.bind(self), self.getErrorDialog(errors.logoutUser)); }, syncEmails: function() { var self = this; user.syncEmails(self.doPickEmail.bind(self), - self.getErrorDialog(BrowserID.Errors.signIn)); + self.getErrorDialog(errors.signIn)); }, - doCheckAuth: function() { var self=this; user.checkAuthenticationAndSync(function onSuccess() {}, @@ -215,7 +218,7 @@ self.doAuthenticate(); } }, - self.getErrorDialog(BrowserID.Errors.checkAuthentication)); + self.getErrorDialog(errors.checkAuthentication)); } }); diff --git a/browserid/static/dialog/controllers/pickemail_controller.js b/browserid/static/dialog/controllers/pickemail_controller.js index 43e23513bec1d6b5cfb0a6ca6557291cdea11209..5266c4efe4067165667476b91e58ecbc0eeeac4f 100644 --- a/browserid/static/dialog/controllers/pickemail_controller.js +++ b/browserid/static/dialog/controllers/pickemail_controller.js @@ -40,6 +40,7 @@ var ANIMATION_TIME = 250, bid = BrowserID, user = bid.User, + errors = bid.Errors, body = $("body"), animationComplete = body.innerWidth() < 640, assertion; @@ -110,7 +111,7 @@ user.getAssertion(email, function(assert) { assertion = assert || null; tryClose.call(self); - }); + }, self.getErrorDialog(errors.getAssertion)); } function startAnimation() { @@ -168,7 +169,7 @@ bid.Tooltip.showTooltip("#could_not_add"); }); } - }); + }, self.getErrorDialog(errors.isEmailRegistered)); } diff --git a/browserid/static/dialog/resources/error-messages.js b/browserid/static/dialog/resources/error-messages.js index 2549941dc02fca1c091dd47ac703d04973495b11..860825d589d909dd7ac1b2290e64dc2d1d0f08c4 100644 --- a/browserid/static/dialog/resources/error-messages.js +++ b/browserid/static/dialog/resources/error-messages.js @@ -54,16 +54,28 @@ BrowserID.Errors = (function(){ message: "There was a technical problem while trying to log you in. Yucky!" }, + createUser: { + type: "serverError", + title: "Error Creating Account", + message: "There was a technical problem while trying to create your account. Yucky!" + }, + + getAssertion: { + type: "serverError", + title: "Error Getting Assertion", + message: "There was a technical problem while trying to authenticate you. Yucky!" + }, + isEmailRegistered: { type: "serverError", title: "Error Checking Email Address", message: "There was a technical problem while trying to check that email address. Yucky!" }, - createUser: { + logoutUser: { type: "serverError", - title: "Error Creating Account", - message: "There was a technical problem while trying to create your account. Yucky!" + title: "Logout Failed", + message: "An error was encountered while signing you out. Yucky!" }, registration: { diff --git a/browserid/static/dialog/resources/user.js b/browserid/static/dialog/resources/user.js index 27105f7f4e798961bd9669063cb850501671b9d1..c5117db0399743dc12d69e6c41e21279e0f43f6d 100644 --- a/browserid/static/dialog/resources/user.js +++ b/browserid/static/dialog/resources/user.js @@ -118,7 +118,7 @@ BrowserID.User = (function() { else if (onFailure) { onFailure(status); } - }); + }, onFailure); }; poll(); @@ -285,7 +285,7 @@ BrowserID.User = (function() { if (onSuccess) { onSuccess(); } - }); + }, onFailure); }, @@ -301,7 +301,7 @@ BrowserID.User = (function() { if (onSuccess) { onSuccess(); } - }); + }, onFailure); }, /** @@ -356,7 +356,7 @@ BrowserID.User = (function() { } addNextEmail(); - }); + }, onFailure); }, /** @@ -533,7 +533,7 @@ BrowserID.User = (function() { if (onSuccess) { onSuccess(assertion); } - }); + }, onFailure); } if (storedID) { diff --git a/browserid/static/dialog/test/qunit/resources/user_unit_test.js b/browserid/static/dialog/test/qunit/resources/user_unit_test.js index a9808f19316334cc25ccb4944e07f175f3770995..6f980c1d627340c6b153f900221dcf698bf0a27f 100644 --- a/browserid/static/dialog/test/qunit/resources/user_unit_test.js +++ b/browserid/static/dialog/test/qunit/resources/user_unit_test.js @@ -55,7 +55,8 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio var credentialsValid, unknownEmails, keyRefresh, syncValid, userEmails, userCheckCount = 0, emailCheckCount = 0, - registrationResponse; + registrationResponse, + xhrFailure = false; var netStub = { reset: function() { @@ -64,54 +65,50 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio keyRefresh = []; userEmails = {"testuser@testuser.com": {}}; registrationResponse = "complete"; - }, - - stageUser: function(email, password, onSuccess) { - onSuccess(); + xhrFailure = false; }, checkUserRegistration: function(email, onSuccess, onFailure) { userCheckCount++; var status = userCheckCount === 2 ? registrationResponse : "pending"; - onSuccess(status); + xhrFailure ? onFailure() : onSuccess(status); }, authenticate: function(email, password, onSuccess, onFailure) { - onSuccess(credentialsValid); + xhrFailure ? onFailure() : onSuccess(credentialsValid); }, checkAuth: function(onSuccess, onFailure) { - onSuccess(credentialsValid); + xhrFailure ? onFailure() : onSuccess(credentialsValid); }, emailRegistered: function(email, onSuccess, onFailure) { - onSuccess(email === "registered"); + xhrFailure ? onFailure() : onSuccess(email === "registered"); }, addEmail: function(email, origin, onSuccess, onFailure) { - onSuccess(true); + xhrFailure ? onFailure() : onSuccess(true); }, checkEmailRegistration: function(email, onSuccess, onFailure) { emailCheckCount++; var status = emailCheckCount === 2 ? registrationResponse : "pending"; - onSuccess(status); - + xhrFailure ? onFailure() : onSuccess(status); }, removeEmail: function(email, onSuccess, onFailure) { - onSuccess(); + xhrFailure ? onFailure() : onSuccess(); }, listEmails: function(onSuccess, onFailure) { - onSuccess(userEmails); + xhrFailure ? onFailure() : onSuccess(userEmails); }, certKey: function(email, pubkey, onSuccess, onFailure) { if (syncValid) { - onSuccess(random_cert); + xhrFailure ? onFailure() : onSuccess(random_cert); } else { onFailure(); @@ -119,7 +116,7 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio }, syncEmails: function(issued_identities, onSuccess, onFailure) { - onSuccess({ + xhrFailure ? onFailure() : onSuccess({ unknown_emails: unknownEmails, key_refresh: keyRefresh }); @@ -127,36 +124,36 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio setKey: function(email, keypair, onSuccess, onFailure) { if (syncValid) { - onSuccess(); + xhrFailure ? onFailure() : onSuccess(); } else { onFailure(); } }, - createUser: function(email, origin, onSuccess) { - onSuccess(true); + createUser: function(email, origin, onSuccess, onFailure) { + xhrFailure ? onFailure() : onSuccess(true); }, setPassword: function(password, onSuccess) { - onSuccess(); + xhrFailure ? onFailure() : onSuccess(); }, requestPasswordReset: function(email, origin, onSuccess, onFailure) { - onSuccess(true); + xhrFailure ? onFailure() : onSuccess(true); }, - cancelUser: function(onSuccess) { - onSuccess(); + cancelUser: function(onSuccess, onFailure) { + xhrFailure ? onFailure() : onSuccess(); }, - serverTime: function(onSuccess) { - onSuccess(new Date()); + serverTime: function(onSuccess, onFailure) { + xhrFailure ? onFailure() : onSuccess(new Date()); }, - logout: function(onSuccess) { + logout: function(onSuccess, onFailure) { credentialsValid = false; - onSuccess(); + xhrFailure ? onFailure() : onSuccess(); } }; @@ -273,6 +270,20 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio stop(); }); + test("createUser with XHR failure", function() { + xhrFailure = true; + + lib.createUser("testuser@testuser.com", function(status) { + ok(false, "xhr failure should never succeed"); + start(); + }, function() { + ok(true, "xhr failure should always be a failure"); + start(); + }); + + stop(); + }); + /** * The next three tests use the mock network harness. The tests are testing * the polling action and whether `waitForUserValidation` reacts as expected @@ -316,6 +327,21 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio stop(); }); + test("waitForUserValidation with XHR failure", function() { + xhrFailure = true; + + lib.waitForUserValidation("baduser@testuser.com", function(status) { + ok(false, "xhr failure should never succeed"); + start(); + }, function() { + ok(true, "xhr failure should always be a failure"); + start(); + }); + + stop(); + }); + + test("setPassword", function() { lib.setPassword("password", function() { // XXX fill this in. @@ -348,7 +374,6 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio }); - test("authenticate with invalid credentials", function() { credentialsValid = false; lib.authenticate("testuser@testuser.com", "testuser", function onComplete(authenticated) { @@ -361,6 +386,21 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio }); + test("authenticate with XHR failure", function() { + xhrFailure = true; + lib.authenticate("testuser@testuser.com", "testuser", function onComplete(authenticated) { + ok(false, "xhr failure should never succeed"); + start(); + }, function() { + ok(true, "xhr failure should always be a failure"); + start(); + }); + + stop(); + + }); + + test("checkAuthentication with valid authentication", function() { credentialsValid = true; lib.checkAuthentication(function(authenticated) { @@ -385,6 +425,21 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio + test("checkAuthentication with XHR failure", function() { + xhrFailure = true; + lib.checkAuthentication(function(authenticated) { + ok(false, "xhr failure should never succeed"); + start(); + }, function() { + ok(true, "xhr failure should always be a failure"); + start(); + }); + + stop(); + }); + + + test("checkAuthenticationAndSync with valid authentication", function() { credentialsValid = true; lib.checkAuthenticationAndSync(function onSuccess() {}, @@ -411,6 +466,24 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio stop(); }); + + test("checkAuthenticationAndSync with XHR failure", function() { + xhrFailure = true; + lib.checkAuthenticationAndSync(function onSuccess() { + ok(false, "xhr failure should never succeed"); + }, function onComplete() { + ok(false, "xhr failure should never succeed"); + + start(); + }, function onFailure() { + ok(true, "xhr failure should always be a failure"); + start(); + }); + + stop(); + }); + + test("isEmailRegistered with registered email", function() { lib.isEmailRegistered("registered", function(registered) { ok(registered); @@ -435,6 +508,19 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio stop(); }); + test("isEmailRegistered with XHR failure", function() { + xhrFailure = true; + lib.isEmailRegistered("registered", function(registered) { + ok(false, "xhr failure should never succeed"); + start(); + }, function() { + ok(true, "xhr failure should always be a failure"); + start(); + }); + + stop(); + }); + test("addEmail", function() { lib.addEmail("testemail@testemail.com", function(added) { ok(added, "user was added"); @@ -448,6 +534,20 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio stop(); }); + test("addEmail with XHR failure", function() { + xhrFailure = true; + lib.addEmail("testemail@testemail.com", function(added) { + ok(false, "xhr failure should never succeed"); + start(); + }, function() { + ok(true, "xhr failure should always be a failure"); + start(); + }); + + stop(); + }); + + /** * The next three tests use the mock network harness. The tests are testing @@ -492,6 +592,21 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio stop(); }); + + test("waitForEmailValidation XHR failure", function() { + xhrFailure = true; + lib.waitForEmailValidation("testemail@testemail.com", function(status) { + ok(false, "xhr failure should never succeed"); + start(); + }, function() { + ok(true, "xhr failure should always be a failure"); + start(); + }); + + stop(); + }); + + test("syncEmailKeypair with successful sync", function() { syncValid = true; lib.syncEmailKeypair("testemail@testemail.com", function(keypair) { @@ -523,6 +638,19 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio stop(); }); + test("syncEmailKeypair with XHR failure", function() { + xhrFailure = true; + lib.syncEmailKeypair("testemail@testemail.com", function(keypair) { + ok(false, "xhr failure should never succeed"); + start(); + }, function() { + ok(true, "xhr failure should always be a failure"); + start(); + }); + + stop(); + }); + test("removeEmail that is added", function() { storage.addEmail("testemail@testemail.com", {pub: "pub", priv: "priv"}); @@ -548,6 +676,22 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio stop(); }); + test("removeEmail with XHR failure", function() { + storage.addEmail("testemail@testemail.com", {pub: "pub", priv: "priv"}); + + xhrFailure = true; + lib.removeEmail("testemail@testemail.com", function() { + ok(false, "xhr failure should never succeed"); + start(); + }, function() { + ok(true, "xhr failure should always be a failure"); + start(); + }); + + stop(); + }); + + test("syncEmails with no pre-loaded identities and no identities to add", function() { @@ -636,6 +780,19 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio stop(); }); + test("syncEmails with XHR failure", function() { + xhrFailure = true; + + lib.syncEmails(function onSuccess() { + ok(false, "xhr failure should never succeed"); + start(); + }, function() { + ok(true, "xhr failure should always be a failure"); + start(); + }); + + stop(); + }); test("getAssertion with known email that has key", function() { lib.setOrigin(testOrigin); @@ -673,6 +830,22 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio stop(); }); + test("getAssertion with XHR failure", function() { + lib.setOrigin(testOrigin); + xhrFailure = true; + + lib.syncEmailKeypair("testuser@testuser.com", function() { + ok(false, "xhr failure should never succeed"); + start(); + }, function() { + ok(true, "xhr failure should always be a failure"); + start(); + }); + + stop(); + }); + + test("logoutUser", function(onSuccess) { credentialsValid = true; keyRefresh = ["testuser@testuser.com"]; @@ -695,6 +868,29 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio stop(); }); + test("logoutUser with XHR failure", function(onSuccess) { + credentialsValid = true; + keyRefresh = ["testuser@testuser.com"]; + + lib.authenticate("testuser@testuser.com", "testuser", function(authenticated) { + lib.syncEmails(function() { + xhrFailure = true; + + lib.logoutUser(function() { + ok(false, "xhr failure should never succeed"); + start(); + }, function() { + ok(true, "xhr failure should always be a failure"); + start(); + }); + + + }, failure("syncEmails failure")); + }, failure("authenticate failure")); + + stop(); + }); + test("cancelUser", function(onSuccess) { lib.cancelUser(function() { var storedIdentities = storage.getEmails(); @@ -705,4 +901,17 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio stop(); }); + test("cancelUser with XHR failure", function(onSuccess) { + xhrFailure = true; + lib.cancelUser(function() { + ok(false, "xhr failure should never succeed"); + start(); + }, function() { + ok(true, "xhr failure should always be a failure"); + start(); + }); + + stop(); + }); + });