From 5e69945543668a8df9fd1568e9a21e608dea00aa Mon Sep 17 00:00:00 2001 From: Shane Tomlinson <stomlinson@mozilla.com> Date: Fri, 13 Apr 2012 16:09:45 +0100 Subject: [PATCH] Fully bring in reset password using the set_password controller. * Remove the forgot_password controller, templates, tests, etc. * Update authenticate to trigger "new_user" with rehydration info * Update set_password to be able to handle resetting passwords as well. * Update the state machine to handle password setting or resetting. --- lib/static_resources.js | 1 - .../static/dialog/controllers/actions.js | 7 +- .../static/dialog/controllers/authenticate.js | 2 +- .../dialog/controllers/forgot_password.js | 49 ------------ .../static/dialog/controllers/set_password.js | 9 ++- resources/static/dialog/resources/helpers.js | 22 +++--- resources/static/dialog/resources/state.js | 79 +++++++++++-------- resources/static/dialog/start.js | 1 - .../static/dialog/views/forgot_password.ejs | 30 ------- .../static/dialog/views/set_password.ejs | 15 +++- resources/static/shared/history.js | 1 + .../static/shared/modules/page_module.js | 3 + resources/static/shared/network.js | 9 ++- resources/static/shared/state_machine.js | 1 + resources/static/shared/user.js | 7 +- .../static/test/cases/controllers/actions.js | 42 +++++++++- .../test/cases/controllers/authenticate.js | 7 +- .../test/cases/controllers/forgot_password.js | 6 +- .../test/cases/controllers/set_password.js | 2 +- .../static/test/cases/resources/helpers.js | 16 ++-- .../static/test/cases/resources/state.js | 23 ++++-- resources/static/test/cases/shared/network.js | 19 +++-- resources/static/test/cases/shared/user.js | 14 ++-- resources/static/test/testHelpers/helpers.js | 2 +- resources/views/test.ejs | 2 - 25 files changed, 183 insertions(+), 186 deletions(-) delete mode 100644 resources/static/dialog/controllers/forgot_password.js delete mode 100644 resources/static/dialog/views/forgot_password.ejs diff --git a/lib/static_resources.js b/lib/static_resources.js index 26e7b85da..e387b3748 100644 --- a/lib/static_resources.js +++ b/lib/static_resources.js @@ -89,7 +89,6 @@ var dialog_js = und.flatten([ '/dialog/controllers/actions.js', '/dialog/controllers/dialog.js', '/dialog/controllers/authenticate.js', - '/dialog/controllers/forgot_password.js', '/dialog/controllers/check_registration.js', '/dialog/controllers/pick_email.js', '/dialog/controllers/add_email.js', diff --git a/resources/static/dialog/controllers/actions.js b/resources/static/dialog/controllers/actions.js index c674f1dc9..b0142af79 100644 --- a/resources/static/dialog/controllers/actions.js +++ b/resources/static/dialog/controllers/actions.js @@ -78,8 +78,7 @@ BrowserID.Modules.Actions = (function() { }, doStageUser: function(info) { - var email = info.email; - bid.Helpers.Dialog.createUser.call(this, email); + dialogHelpers.createUser.call(this, info.email, info.password, info.ready); }, doConfirmUser: function(info) { @@ -103,11 +102,11 @@ BrowserID.Modules.Actions = (function() { }, doForgotPassword: function(info) { - startService("forgot_password", info); + startService("set_password", _.extend(info, { password_reset: true })); }, doResetPassword: function(info) { - this.doConfirmUser(info); + dialogHelpers.resetPassword.call(this, info.email, info.password, info.ready); }, doConfirmEmail: function(info) { diff --git a/resources/static/dialog/controllers/authenticate.js b/resources/static/dialog/controllers/authenticate.js index 692c62e3e..d81fc9db3 100644 --- a/resources/static/dialog/controllers/authenticate.js +++ b/resources/static/dialog/controllers/authenticate.js @@ -71,7 +71,7 @@ BrowserID.Modules.Authenticate = (function() { email = getEmail(); if (email) { - self.close("new_user", { email: email }); + self.close("new_user", { email: email }, { email: email }); } else { complete(callback); } diff --git a/resources/static/dialog/controllers/forgot_password.js b/resources/static/dialog/controllers/forgot_password.js deleted file mode 100644 index 268f72417..000000000 --- a/resources/static/dialog/controllers/forgot_password.js +++ /dev/null @@ -1,49 +0,0 @@ -/*jshint browser:true, jQuery: true, forin: true, laxbreak:true */ -/*global BrowserID:true, PageController: true */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -BrowserID.Modules.ForgotPassword = (function() { - "use strict"; - - var ANIMATION_TIME = 250, - bid = BrowserID, - helpers = bid.Helpers, - dialogHelpers = helpers.Dialog, - dom = bid.DOM; - - function resetPassword() { - var self=this; - dialogHelpers.resetPassword.call(self, self.email); - } - - function cancelResetPassword() { - this.close("cancel_state", { email: this.email }); - } - - var Module = bid.Modules.PageModule.extend({ - start: function(options) { - var self=this; - self.email = options.email; - self.renderDialog("forgot_password", { - email: options.email || "", - requiredEmail: options.requiredEmail - }); - - self.click("#cancel", cancelResetPassword); - - Module.sc.start.call(self, options); - }, - - submit: resetPassword - - // BEGIN TESTING API - , - resetPassword: resetPassword, - cancelResetPassword: cancelResetPassword - // END TESTING API - }); - - return Module; - -}()); diff --git a/resources/static/dialog/controllers/set_password.js b/resources/static/dialog/controllers/set_password.js index ac0a24cb7..308cee328 100644 --- a/resources/static/dialog/controllers/set_password.js +++ b/resources/static/dialog/controllers/set_password.js @@ -7,16 +7,19 @@ BrowserID.Modules.SetPassword = (function() { "use strict"; var bid = BrowserID, dom = bid.DOM, - complete = bid.Helpers.complete, + helpers = bid.Helpers, + complete = helpers.complete, + dialogHelpers = helpers.Dialog, sc; function submit(callback) { var pass = dom.getInner("#password"), - vpass = dom.getInner("#vpassword"); + vpass = dom.getInner("#vpassword"), + options = this.options; var valid = bid.Validation.passwordAndValidationPassword(pass, vpass); if(valid) { - this.close("password_set", { password: pass }); + this.publish("password_set", { password: pass }); } complete(callback, valid); diff --git a/resources/static/dialog/resources/helpers.js b/resources/static/dialog/resources/helpers.js index 12029173c..46f771258 100644 --- a/resources/static/dialog/resources/helpers.js +++ b/resources/static/dialog/resources/helpers.js @@ -39,7 +39,7 @@ user.getAssertion(email, user.getOrigin(), function(assert) { assert = assert || null; wait.hide(); - self.close("assertion_generated", { + self.publish("assertion_generated", { assertion: assert }); @@ -58,28 +58,28 @@ }, self.getErrorDialog(errors.authenticate, callback)); } - function createUser(email, callback) { + function createUser(email, password, callback) { var self=this; - user.createSecondaryUser(email, function(status) { + user.createSecondaryUser(email, password, function(status) { if (status) { var info = { email: email }; - self.close("user_staged", info, info); + self.publish("user_staged", info, info); complete(callback, true); } else { + // XXX will this tooltip ever be shown, the authentication screen has + // already been torn down by this point? tooltip.showTooltip("#could_not_add"); complete(callback, false); } }, self.getErrorDialog(errors.createUser, callback)); } - function resetPassword(email, callback) { + function resetPassword(email, password, callback) { var self=this; - user.requestPasswordReset(email, function(status) { + user.requestPasswordReset(email, password, function(status) { if (status.success) { - self.close("reset_password", { - email: email - }); + self.publish("password_reset", { email: email }); } else { tooltip.showTooltip("#could_not_add"); @@ -100,14 +100,14 @@ user.addressInfo(email, function(info) { if (info.type === "primary") { var info = _.extend(info, { email: email, add: true }); - self.close("primary_user", info, info); + self.publish("primary_user", info, info); complete(callback, true); } else { user.addEmail(email, function(added) { if (added) { var info = { email: email }; - self.close("email_staged", info, info ); + self.publish("email_staged", info, info ); } else { tooltip.showTooltip("#could_not_add"); diff --git a/resources/static/dialog/resources/state.js b/resources/static/dialog/resources/state.js index 2103ffd00..909993abd 100644 --- a/resources/static/dialog/resources/state.js +++ b/resources/static/dialog/resources/state.js @@ -20,7 +20,13 @@ BrowserID.State = (function() { function startStateMachine() { var self = this, - handleState = self.subscribe.bind(self), + handleState = function(msg, callback) { + self.subscribe(msg, function(msg, info) { + // This level of indirection is to ensure an info object is + // always present in the handler. + callback(msg, info || {}); + }); + }, redirectToState = mediator.publish.bind(mediator), startAction = function(save, msg, options) { if (typeof save !== "boolean") { @@ -35,8 +41,6 @@ BrowserID.State = (function() { cancelState = self.popState.bind(self); handleState("start", function(msg, info) { - info = info || {}; - self.hostname = info.hostname; self.privacyURL = info.privacyURL; self.tosURL = info.tosURL; @@ -87,7 +91,6 @@ BrowserID.State = (function() { }); handleState("authenticate", function(msg, info) { - info = info || {}; info.privacyURL = self.privacyURL; info.tosURL = self.tosURL; startAction("doAuthenticate", info); @@ -95,14 +98,26 @@ BrowserID.State = (function() { handleState("new_user", function(msg, info) { self.newUserEmail = info.email; - startAction("doSetPassword", info); + startAction(false, "doSetPassword", info); }); handleState("password_set", function(msg, info) { - info = info || {}; - info.email = self.newUserEmail; - - startAction("doStageUser", info); + /* A password can be set for one of three reasons - 1) This is a new user + * or 2) a user is adding the first secondary address to an account that + * consists only of primary addresses, or 3) an existing user has + * forgotten their password and wants to reset it. #1 is taken care of + * by newUserEmail, #3 is taken care of by resetPasswordEmail. + */ + info = _.extend({ email: self.newUserEmail || self.resetPasswordEmail }, info); + + if(self.newUserEmail) { + self.newUserEmail = null; + startAction(false, "doStageUser", info); + } + else if(self.resetPasswordEmail) { + self.resetPasswordEmail = null; + startAction(false, "doResetPassword", info); + } }); handleState("user_staged", function(msg, info) { @@ -133,7 +148,6 @@ BrowserID.State = (function() { }); handleState("primary_user_provisioned", function(msg, info) { - info = info || {}; info.add = !!addPrimaryUser; // The user is is authenticated with their IdP. Two possibilities exist // for the email - 1) create a new account or 2) add address to the @@ -143,7 +157,7 @@ BrowserID.State = (function() { }); handleState("primary_user_unauthenticated", function(msg, info) { - info = helpers.extend(info || {}, { + info = helpers.extend(info, { add: !!addPrimaryUser, email: email, requiredEmail: !!requiredEmail, @@ -191,8 +205,6 @@ BrowserID.State = (function() { }); handleState("email_chosen", function(msg, info) { - info = info || {}; - var email = info.email, idInfo = storage.getEmail(email); @@ -283,6 +295,25 @@ BrowserID.State = (function() { startAction("doGenerateAssertion", info); }); + handleState("forgot_password", function(msg, info) { + // User has forgotten their password, let them reset it. The response + // message from the forgot_password controller will be a set_password. + // the set_password handler needs to know the forgotPassword email so it + // knows how to handle the password being set. When the password is + // finally reset, the password_reset message will be raised where we must + // await email confirmation. + self.resetPasswordEmail = info.email; + startAction(false, "doForgotPassword", info); + }); + + handleState("password_reset", function(msg, info) { + // password_reset says the user has confirmed that they want to + // reset their password. doResetPassword will attempt to invoke + // the create_user wsapi. If the wsapi call is successful, + // the user will be shown the "go verify your account" message. + redirectToState("user_staged", info); + }); + handleState("assertion_generated", function(msg, info) { self.success = true; if (info.assertion !== null) { @@ -307,26 +338,8 @@ BrowserID.State = (function() { redirectToState("email_chosen", info); }); - handleState("forgot_password", function(msg, info) { - // forgot password initiates the forgotten password flow. - startAction(false, "doForgotPassword", info); - }); - - handleState("reset_password", function(msg, info) { - info = info || {}; - // reset_password says the user has confirmed that they want to - // reset their password. doResetPassword will attempt to invoke - // the create_user wsapi. If the wsapi call is successful, - // the user will be shown the "go verify your account" message. - - // We have to save the staged email address here for when the user - // verifies their account and user_confirmed is called. - self.stagedEmail = info.email; - startAction(false, "doResetPassword", info); - }); - handleState("add_email", function(msg, info) { - info = helpers.extend(info || {}, { + info = helpers.extend(info, { privacyURL: self.privacyURL, tosURL: self.tosURL }); @@ -341,7 +354,7 @@ BrowserID.State = (function() { }); handleState("email_confirmed", function() { - redirectToState("email_chosen", { email: self.stagedEmail} ); + redirectToState("email_chosen", { email: self.stagedEmail } ); }); handleState("cancel_state", function(msg, info) { diff --git a/resources/static/dialog/start.js b/resources/static/dialog/start.js index 14cfe1cf3..49c7c439b 100644 --- a/resources/static/dialog/start.js +++ b/resources/static/dialog/start.js @@ -23,7 +23,6 @@ moduleManager.register("add_email", modules.AddEmail); moduleManager.register("authenticate", modules.Authenticate); moduleManager.register("check_registration", modules.CheckRegistration); - moduleManager.register("forgot_password", modules.ForgotPassword); moduleManager.register("is_this_your_computer", modules.IsThisYourComputer); moduleManager.register("pick_email", modules.PickEmail); moduleManager.register("required_email", modules.RequiredEmail); diff --git a/resources/static/dialog/views/forgot_password.ejs b/resources/static/dialog/views/forgot_password.ejs deleted file mode 100644 index 3bbd7cd8e..000000000 --- a/resources/static/dialog/views/forgot_password.ejs +++ /dev/null @@ -1,30 +0,0 @@ -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - - <strong> - <% if (requiredEmail) { %> - <%= gettext('The site requested you sign in using') %> - <% } else { %> - <%= gettext('Sign in using') %> - <% } %> - </strong> - - <div class="form_section"> - <ul class="inputs"> - <li> - <label for="email" class="serif"><%= gettext('Email') %></label> - <input id="email" class="sans" type="email" value="<%= email %>" disabled /> - - <div id="could_not_add" class="tooltip" for="email"> - <%= gettext('We just sent an email to that address! If you really want to send another, wait a minute or two and try again.') %> - </div> - </li> - - </ul> - - <div class="submit cf"> - <button tabindex="1"><%= gettext('reset password') %></button> - <a href="#" id="cancel" class="action" tabindex="2"><%= gettext('cancel') %></a> - </div> - </div> diff --git a/resources/static/dialog/views/set_password.ejs b/resources/static/dialog/views/set_password.ejs index b970090ff..c57943f4d 100644 --- a/resources/static/dialog/views/set_password.ejs +++ b/resources/static/dialog/views/set_password.ejs @@ -6,9 +6,12 @@ <div class="form_section" id="set_password"> <ul class="inputs"> - <li> - <%= gettext("This email looks new, so let's get you set up.") %> - </li> + <% if(!password_reset) { %> + <li> + <%= gettext("This email looks new, so let's get you set up.") %> + </li> + <% } %> + <li> <label for="password" class="serif"><%= gettext('Password') %></label> @@ -21,6 +24,10 @@ <div class="tooltip" id="password_length" for="password"> <%= gettext('Password must be between 8 and 80 characters long.') %> </div> + + <div id="could_not_add" class="tooltip" for="password"> + <%= gettext('We just sent an email to that address! If you really want to send another, wait a minute or two and try again.') %> + </div> </li> <li> @@ -42,6 +49,6 @@ <button tabindex="1" id="<%= password_reset ? "password_reset" : "verify_user" %>"> <%= password_reset ? gettext('reset password') : gettext('verify email') %> </button> - <a id="cancel" href="#"><%= gettext('cancel') %></a> + <a id="cancel" class="action" href="#"><%= gettext('cancel') %></a> </div> </div> diff --git a/resources/static/shared/history.js b/resources/static/shared/history.js index 6cbaa68fe..8c7653c3a 100644 --- a/resources/static/shared/history.js +++ b/resources/static/shared/history.js @@ -29,6 +29,7 @@ BrowserID.History = (function() { return this.current; }, + // XXX this should be renamed to pushState saveState: function() { this.history.push(this.current); }, diff --git a/resources/static/shared/modules/page_module.js b/resources/static/shared/modules/page_module.js index 97936af09..1de6032ac 100644 --- a/resources/static/shared/modules/page_module.js +++ b/resources/static/shared/modules/page_module.js @@ -51,6 +51,8 @@ BrowserID.Modules.PageModule = (function() { start: function(options) { var self=this; + self.options = options || {}; + self.bind("form", "submit", cancelEvent(onSubmit)); // TODO - why is this here and not in pick_email? self.click("#thisIsNotMe", self.close.bind(self, "notme")); @@ -154,6 +156,7 @@ BrowserID.Modules.PageModule = (function() { submit: function() { }, + // XXX maybe we should not get rid of this. close: function(message) { this.destroy(); if (message) { diff --git a/resources/static/shared/network.js b/resources/static/shared/network.js index 9b11a7039..478531dcb 100644 --- a/resources/static/shared/network.js +++ b/resources/static/shared/network.js @@ -321,14 +321,15 @@ BrowserID.Network = (function() { /** * Request a password reset for the given email address. * @method requestPasswordReset - * @param {string} email - email address to reset password for. + * @param {string} email + * @param {string} password + * @param {string} origin * @param {function} [onComplete] - Callback to call when complete. * @param {function} [onFailure] - Called on XHR failure. */ - requestPasswordReset: function(email, origin, onComplete, onFailure) { + requestPasswordReset: function(email, password, origin, onComplete, onFailure) { if (email) { - // XXX we need a password! - Network.createUser(email, origin, "", onComplete, onFailure); + Network.createUser(email, password, origin, onComplete, onFailure); } else { // TODO: if no email is provided, then what? throw "no email provided to password reset"; diff --git a/resources/static/shared/state_machine.js b/resources/static/shared/state_machine.js index 1b2c90b37..c6dcafdcc 100644 --- a/resources/static/shared/state_machine.js +++ b/resources/static/shared/state_machine.js @@ -53,6 +53,7 @@ BrowserID.StateMachine = (function() { // only save the current state when a new state comes in. var cmd = history.getCurrent(); if(cmd && cmd.save) { + // XXX saveState should be renamed to pushState history.saveState(); } diff --git a/resources/static/shared/user.js b/resources/static/shared/user.js index 1ea183078..fe76e8c11 100644 --- a/resources/static/shared/user.js +++ b/resources/static/shared/user.js @@ -599,17 +599,18 @@ BrowserID.User = (function() { /** * Request a password reset for the given email address. * @method requestPasswordReset - * @param {string} email - email address to reset password for. + * @param {string} email + * @param {string} password * @param {function} [onComplete] - Callback to call when complete, called * with a single object, info. * info.status {boolean} - true or false whether request was successful. * info.reason {string} - if status false, reason of failure. * @param {function} [onFailure] - Called on XHR failure. */ - requestPasswordReset: function(email, onComplete, onFailure) { + requestPasswordReset: function(email, password, onComplete, onFailure) { User.isEmailRegistered(email, function(registered) { if (registered) { - network.requestPasswordReset(email, origin, function(reset) { + network.requestPasswordReset(email, password, origin, function(reset) { var status = { success: reset }; diff --git a/resources/static/test/cases/controllers/actions.js b/resources/static/test/cases/controllers/actions.js index 0e0881e27..488639009 100644 --- a/resources/static/test/cases/controllers/actions.js +++ b/resources/static/test/cases/controllers/actions.js @@ -84,7 +84,7 @@ asyncTest("doCannotVerifyRequiredPrimary - show the error screen", function() { createController({ ready: function() { - controller.doCannotVerifyRequiredPrimary({ email: "testuser@testuser.com"}); + controller.doCannotVerifyRequiredPrimary({ email: TEST_EMAIL}); testHelpers.testErrorVisible(); start(); @@ -112,5 +112,45 @@ testActionStartsModule('doGenerateAssertion', { email: TEST_EMAIL }, "generate_assertion"); }); + asyncTest("doEmailChosen - start the email_chosen service", function() { + testActionStartsModule('doEmailChosen', { email: TEST_EMAIL }, "email_chosen"); + }); + + + asyncTest("doEmailConfirmed - generate an assertion for the email", function() { + createController({ + ready: function() { + testHelpers.register("assertion_generated", function(msg, info) { + ok(info.assertion, "assertion generated"); + start(); + }); + + user.syncEmailKeypair(TEST_EMAIL, function() { + controller.doEmailConfirmed({email: TEST_EMAIL}); + }); + } + }); + }); + + asyncTest("doStageUser with successful creation - trigger user_staged", function() { + createController({ + ready: function() { + var email; + testHelpers.register("user_staged", function(msg, info) { + email = info.email; + }); + + controller.doStageUser({ email: TEST_EMAIL, password: "password", ready: function(status) { + equal(status, true, "correct status"); + equal(email, TEST_EMAIL, "user successfully staged"); + start(); + }}); + } + }); + }); + + asyncTest("doForgotPassword - call the set_password controller with reset_password true", function() { + testActionStartsModule('doForgotPassword', { email: TEST_EMAIL }, "set_password"); + }); }()); diff --git a/resources/static/test/cases/controllers/authenticate.js b/resources/static/test/cases/controllers/authenticate.js index 91cbe5e6e..653a7bd19 100644 --- a/resources/static/test/cases/controllers/authenticate.js +++ b/resources/static/test/cases/controllers/authenticate.js @@ -80,8 +80,11 @@ }); function testUserUnregistered() { - register("new_user", function() { - ok(true, "email was valid, user not registered"); + register("new_user", function(msg, info, rehydrate) { + ok(info.email, "new_user triggered with info.email"); + // rehydration email used to go back to authentication controller if + // the user cancels one of the next steps. + ok(rehydrate.email, "new_user triggered with rehydrate.email"); start(); }); diff --git a/resources/static/test/cases/controllers/forgot_password.js b/resources/static/test/cases/controllers/forgot_password.js index 77c24dd89..d81d8b1de 100644 --- a/resources/static/test/cases/controllers/forgot_password.js +++ b/resources/static/test/cases/controllers/forgot_password.js @@ -40,9 +40,9 @@ equal($("#email").val(), "registered@testuser.com", "email prefilled"); }); - asyncTest("resetPassword raises 'reset_password' with email address", function() { - register("reset_password", function(msg, info) { - equal(info.email, "registered@testuser.com", "reset_password raised with correct email address"); + asyncTest("resetPassword raises 'password_reset' with email address", function() { + register("password_reset", function(msg, info) { + equal(info.email, "registered@testuser.com", "password_reset raised with correct email address"); start(); }); diff --git a/resources/static/test/cases/controllers/set_password.js b/resources/static/test/cases/controllers/set_password.js index 3de244dbd..bfdda1c0b 100644 --- a/resources/static/test/cases/controllers/set_password.js +++ b/resources/static/test/cases/controllers/set_password.js @@ -53,7 +53,7 @@ }); controller.submit(function() { - ok(password, "password", "password_set message raised with correct password"); + equal(password, "password", "password_set message raised with correct password"); start(); }); }); diff --git a/resources/static/test/cases/resources/helpers.js b/resources/static/test/cases/resources/helpers.js index 279f7dee8..4a80ad29e 100644 --- a/resources/static/test/cases/resources/helpers.js +++ b/resources/static/test/cases/resources/helpers.js @@ -21,7 +21,7 @@ badError = testHelpers.unexpectedXHRFailure; var controllerMock = { - close: function(message, info) { + publish: function(message, info) { closeCB && closeCB(message, info); }, @@ -116,7 +116,7 @@ xhr.useResult("unknown_secondary"); closeCB = expectedClose("user_staged", "email", "unregistered@testuser.com"); - dialogHelpers.createUser.call(controllerMock, "unregistered@testuser.com", function(staged) { + dialogHelpers.createUser.call(controllerMock, "unregistered@testuser.com", "password", function(staged) { equal(staged, true, "user was staged"); start(); }); @@ -126,7 +126,7 @@ closeCB = badClose; xhr.useResult("throttle"); - dialogHelpers.createUser.call(controllerMock, "unregistered@testuser.com", function(staged) { + dialogHelpers.createUser.call(controllerMock, "unregistered@testuser.com", "password", function(staged) { equal(staged, false, "user was not staged"); start(); }); @@ -136,7 +136,7 @@ errorCB = expectedError; xhr.useResult("ajaxError"); - dialogHelpers.createUser.call(controllerMock, "registered@testuser.com", testHelpers.unexpectedSuccess); + dialogHelpers.createUser.call(controllerMock, "registered@testuser.com", "password", testHelpers.unexpectedSuccess); }); asyncTest("addEmail with primary email happy case, expects primary_user message", function() { @@ -185,8 +185,8 @@ }); asyncTest("resetPassword happy case", function() { - closeCB = expectedClose("reset_password", "email", "registered@testuser.com"); - dialogHelpers.resetPassword.call(controllerMock, "registered@testuser.com", function(reset) { + closeCB = expectedClose("password_reset", "email", "registered@testuser.com"); + dialogHelpers.resetPassword.call(controllerMock, "registered@testuser.com", "password", function(reset) { ok(reset, "password reset"); start(); }); @@ -195,7 +195,7 @@ asyncTest("resetPassword throttled", function() { xhr.useResult("throttle"); - dialogHelpers.resetPassword.call(controllerMock, "registered@testuser.com", function(reset) { + dialogHelpers.resetPassword.call(controllerMock, "registered@testuser.com", "password", function(reset) { equal(reset, false, "password not reset"); start(); }); @@ -205,7 +205,7 @@ errorCB = expectedError; xhr.useResult("ajaxError"); - dialogHelpers.resetPassword.call(controllerMock, "registered@testuser.com", function(reset) { + dialogHelpers.resetPassword.call(controllerMock, "registered@testuser.com", "password", function(reset) { ok(false, "unexpected close"); start(); }); diff --git a/resources/static/test/cases/resources/state.js b/resources/static/test/cases/resources/state.js index 4ce48b1ba..f1981a196 100644 --- a/resources/static/test/cases/resources/state.js +++ b/resources/static/test/cases/resources/state.js @@ -84,6 +84,15 @@ equal(actions.info.doSetPassword.email, TEST_EMAIL, "correct email sent to doSetPassword"); }); + test("cancel new user password_set flow - go back to the authentication screen", function() { + mediator.publish("authenticate"); + mediator.publish("new_user", undefined, { email: TEST_EMAIL }); + mediator.publish("password_set"); + actions.info.doAuthenticate = {}; + mediator.publish("cancel_state"); + equal(actions.info.doAuthenticate.email, TEST_EMAIL, "authenticate called with the correct email"); + }); + test("password_set - call doStageUser with correct email", function() { mediator.publish("new_user", { email: TEST_EMAIL }); mediator.publish("password_set"); @@ -223,13 +232,13 @@ equal(actions.info.doForgotPassword.requiredEmail, true, "correct requiredEmail passed"); }); - test("reset_password to user_confirmed - call doResetPassword then doEmailConfirmed", function() { - // reset_password indicates the user has verified that they want to reset + test("password_reset to user_confirmed - call doUserStaged then doEmailConfirmed", function() { + // password_reset indicates the user has verified that they want to reset // their password. - mediator.publish("reset_password", { + mediator.publish("password_reset", { email: TEST_EMAIL }); - equal(actions.info.doResetPassword.email, TEST_EMAIL, "reset password with the correct email"); + equal(actions.info.doConfirmUser.email, TEST_EMAIL, "doConfirmUser with the correct email"); // At this point the user should be displayed the "go confirm your address" // screen. @@ -247,13 +256,13 @@ }); - test("cancel reset_password flow - go two steps back", function() { + test("cancel password_reset flow - go two steps back", function() { // we want to skip the "verify" screen of reset password and instead go two // screens back. Do do this, we are simulating the steps necessary to get - // to the reset_password flow. + // to the password_reset flow. mediator.publish("authenticate"); mediator.publish("forgot_password", undefined, { email: TEST_EMAIL }); - mediator.publish("reset_password", { email: TEST_EMAIL }); + mediator.publish("password_reset"); actions.info.doAuthenticate = {}; mediator.publish("cancel_state"); equal(actions.info.doAuthenticate.email, TEST_EMAIL, "authenticate called with the correct email"); diff --git a/resources/static/test/cases/shared/network.js b/resources/static/test/cases/shared/network.js index b5a501960..4aea2350f 100644 --- a/resources/static/test/cases/shared/network.js +++ b/resources/static/test/cases/shared/network.js @@ -327,7 +327,7 @@ asyncTest("addSecondaryEmail valid", function() { - network.addSecondaryEmail("address", "origin", function onSuccess(added) { + network.addSecondaryEmail("testuser@testuser.com", "origin", function onSuccess(added) { ok(added); start(); }, testHelpers.unexpectedFailure); @@ -335,7 +335,7 @@ asyncTest("addSecondaryEmail invalid", function() { transport.useResult("invalid"); - network.addSecondaryEmail("address", "origin", function onSuccess(added) { + network.addSecondaryEmail("testuser@testuser.com", "origin", function onSuccess(added) { equal(added, false); start(); }, testHelpers.unexpectedFailure); @@ -344,14 +344,14 @@ asyncTest("addSecondaryEmail throttled", function() { transport.useResult("throttle"); - network.addSecondaryEmail("address", "origin", function onSuccess(added) { + network.addSecondaryEmail("testuser@testuser.com", "origin", function onSuccess(added) { equal(added, false, "throttled email returns onSuccess but with false as the value"); start(); }, testHelpers.unexpectedFailure); }); asyncTest("addSecondaryEmail with XHR failure", function() { - failureCheck(network.addSecondaryEmail, "address", "origin"); + failureCheck(network.addSecondaryEmail, "testuser@testuser.com", "origin"); }); asyncTest("checkEmailRegistration pending", function() { @@ -377,7 +377,7 @@ }); asyncTest("checkEmailRegistration with XHR failure", function() { - failureCheck(network.checkEmailRegistration, "address"); + failureCheck(network.checkEmailRegistration, "testuser@testuser.com"); }); @@ -456,16 +456,15 @@ }); - asyncTest("requestPasswordReset", function() { - network.requestPasswordReset("address", "origin", function onSuccess() { - // XXX need a test here; - ok(true); + asyncTest("requestPasswordReset - true status", function() { + network.requestPasswordReset("testuser@testuser.com", "password", "origin", function onSuccess(status) { + equal(status, true, "password reset request success"); start(); }, testHelpers.unexpectedFailure); }); asyncTest("requestPasswordReset with XHR failure", function() { - failureCheck(network.requestPasswordReset, "address", "origin"); + failureCheck(network.requestPasswordReset, "testuser@testuser.com", "password", "origin"); }); asyncTest("setPassword happy case expects true status", function() { diff --git a/resources/static/test/cases/shared/user.js b/resources/static/test/cases/shared/user.js index 7fa7b2626..3489f27f4 100644 --- a/resources/static/test/cases/shared/user.js +++ b/resources/static/test/cases/shared/user.js @@ -490,24 +490,24 @@ var vep = require("./vep"); ); }); - asyncTest("requestPasswordReset with known email", function() { - lib.requestPasswordReset("registered@testuser.com", function(status) { + asyncTest("requestPasswordReset with known email - true status", function() { + lib.requestPasswordReset("registered@testuser.com", "password", function(status) { equal(status.success, true, "password reset for known user"); start(); }, testHelpers.unexpectedXHRFailure); }); - asyncTest("requestPasswordReset with unknown email", function() { - lib.requestPasswordReset("unregistered@testuser.com", function(status) { + asyncTest("requestPasswordReset with unknown email - false status, invalid_user", function() { + lib.requestPasswordReset("unregistered@testuser.com", "password", function(status) { equal(status.success, false, "password not reset for unknown user"); equal(status.reason, "invalid_user", "invalid_user is the reason"); start(); }, testHelpers.unexpectedXHRFailure); }); - asyncTest("requestPasswordReset with throttle", function() { + asyncTest("requestPasswordReset with throttle - false status, throttle", function() { xhr.useResult("throttle"); - lib.requestPasswordReset("registered@testuser.com", function(status) { + lib.requestPasswordReset("registered@testuser.com", "password", function(status) { equal(status.success, false, "password not reset for throttle"); equal(status.reason, "throttle", "password reset was throttled"); start(); @@ -515,7 +515,7 @@ var vep = require("./vep"); }); asyncTest("requestPasswordReset with XHR failure", function() { - failureCheck(lib.requestPasswordReset, "registered@testuser.com"); + failureCheck(lib.requestPasswordReset, "registered@testuser.com", "password"); }); diff --git a/resources/static/test/testHelpers/helpers.js b/resources/static/test/testHelpers/helpers.js index 31ac2d086..9c85bf656 100644 --- a/resources/static/test/testHelpers/helpers.js +++ b/resources/static/test/testHelpers/helpers.js @@ -29,7 +29,7 @@ BrowserID.TestHelpers = (function() { } calls[msg] = true; - cb && cb(msg, info); + cb && cb.apply(null, arguments); })); } diff --git a/resources/views/test.ejs b/resources/views/test.ejs index a6cf9e913..b7fcf298b 100644 --- a/resources/views/test.ejs +++ b/resources/views/test.ejs @@ -119,7 +119,6 @@ <script src="/dialog/controllers/dialog.js"></script> <script src="/dialog/controllers/check_registration.js"></script> <script src="/dialog/controllers/authenticate.js"></script> - <script src="/dialog/controllers/forgot_password.js"></script> <script src="/dialog/controllers/required_email.js"></script> <script src="/dialog/controllers/verify_primary_user.js"></script> <script src="/dialog/controllers/generate_assertion.js"></script> @@ -179,7 +178,6 @@ <script src="cases/controllers/add_email.js"></script> <script src="cases/controllers/check_registration.js"></script> <script src="cases/controllers/authenticate.js"></script> - <script src="cases/controllers/forgot_password.js"></script> <script src="cases/controllers/required_email.js"></script> <script src="cases/controllers/verify_primary_user.js"></script> <script src="cases/controllers/generate_assertion.js"></script> -- GitLab