diff --git a/resources/static/pages/js/manage_account.js b/resources/static/pages/js/manage_account.js index c5452ffa19628d9f18a81287424c92ee19a4e461..6b515f8a60bdf5520990a64cd0d8e3c4b2a524f8 100644 --- a/resources/static/pages/js/manage_account.js +++ b/resources/static/pages/js/manage_account.js @@ -139,6 +139,13 @@ BrowserID.manageAccount = (function() { tooltip.showTooltip("#tooltipOldRequired"); complete(false); } + else if(oldPassword.length < bid.PASSWORD_MIN_LENGTH || bid.PASSWORD_MAX_LENGTH < oldPassword.length) { + // If the old password is out of range, we know it is invalid. Show the + // tooltip. See issue #2121 + // - https://github.com/mozilla/browserid/issues/2121 + tooltip.showTooltip("#tooltipInvalidPassword"); + complete(false); + } else if(!newPassword) { tooltip.showTooltip("#tooltipNewRequired"); complete(false); diff --git a/resources/static/test/cases/pages/js/manage_account.js b/resources/static/test/cases/pages/js/manage_account.js index 61b83965746fc475bc596ec0f38b158ccd898930..2b5caff3e100f3cb8d860c2bbe900ccd43059585 100644 --- a/resources/static/test/cases/pages/js/manage_account.js +++ b/resources/static/test/cases/pages/js/manage_account.js @@ -1,5 +1,5 @@ /*jshint browser: true, forin: true, laxbreak: true */ -/*global test: true, start: true, module: true, ok: true, equal: true, BrowserID:true */ +/*global test: true, start: true, module: true, ok: true, equal: true, BrowserID:true, notEqual: 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/. */ @@ -9,8 +9,10 @@ var bid = BrowserID, xhr = bid.Mocks.xhr, errorScreen = bid.Screens.error, + network = bid.Network, storage = bid.Storage, testHelpers = bid.TestHelpers, + generateString = testHelpers.generateString, tooltip = bid.Tooltip, mocks = { confirm: function() { return true; }, @@ -29,6 +31,37 @@ } }); + function testPasswordChangeSuccess(oldPass, newPass, msg) { + testPasswordChange(oldPass, newPass, function(status) { + equal(status, true, msg); + // if success is expected, both password fields should be visible. + equal($("#old_password").val(), "", "old_password field is cleared"); + equal($("#new_password").val(), "", "new_password field is cleared"); + testHelpers.testTooltipNotVisible(); + network.checkAuth(function(authLevel) { + equal(authLevel, "password", "after password change, user authenticated to password level"); + start(); + }, testHelpers.unexpectedXHRFailure); + }, msg); + } + + function testPasswordChangeFailure(oldPass, newPass, msg) { + testPasswordChange(oldPass, newPass, function(status) { + equal(status, false, msg); + testHelpers.testTooltipVisible(); + start(); + }, msg); + } + + function testPasswordChange(oldPass, newPass, testStrategy, msg) { + bid.manageAccount(mocks, function() { + $("#old_password").val(oldPass); + $("#new_password").val(newPass); + + bid.manageAccount.changePassword(testStrategy); + }); + } + asyncTest("no email addresses are displayed if there are no children", function() { xhr.useResult("no_identities"); @@ -178,84 +211,32 @@ }); asyncTest("changePassword with missing old password - tooltip", function() { - bid.manageAccount(mocks, function() { - $("#old_password").val(""); - $("#new_password").val("newpassword"); - - bid.manageAccount.changePassword(function(status) { - equal(status, false, "on missing old password, status is false"); - testHelpers.testTooltipVisible(); - start(); - }); - }); + testPasswordChangeFailure("", "newpassword", "missing old password, expected failure"); }); - asyncTest("changePassword with missing new password - tooltip", function() { - bid.manageAccount(mocks, function() { - $("#old_password").val("oldpassword"); - $("#new_password").val(""); - - bid.manageAccount.changePassword(function(status) { - equal(status, false, "on missing new password, status is false"); - testHelpers.testTooltipVisible(); - start(); - }); - }); + asyncTest("changePassword with too short of an old password - tooltip", function() { + testPasswordChangeFailure(generateString(bid.PASSWORD_MIN_LENGTH - 1), "newpassword", "missing old password, expected failure"); }); - asyncTest("changePassword with too short of a password - tooltip", function() { - bid.manageAccount(mocks, function() { - $("#old_password").val("oldpassword"); - $("#new_password").val(testHelpers.generateString(bid.PASSWORD_MIN_LENGTH - 1)); - - bid.manageAccount.changePassword(function(status) { - equal(status, false, "on too short of a password, status is false"); - testHelpers.testTooltipVisible(); - start(); - }); - }); + asyncTest("changePassword with too long of an old password - tooltip", function() { + testPasswordChangeFailure(generateString(bid.PASSWORD_MAX_LENGTH + 1), "newpassword", "missing old password, expected failure"); }); - asyncTest("changePassword with too long of a password - tooltip", function() { - bid.manageAccount(mocks, function() { - $("#old_password").val("oldpassword"); - $("#new_password").val(testHelpers.generateString(bid.PASSWORD_MAX_LENGTH + 1)); - - bid.manageAccount.changePassword(function(status) { - equal(status, false, "on too long of a password, status is false"); - testHelpers.testTooltipVisible(); - start(); - }); - }); + asyncTest("changePassword with missing new password - tooltip", function() { + testPasswordChangeFailure("oldpassword", "", "missing new password, expected failure"); }); + asyncTest("changePassword with too short of a new password - tooltip", function() { + testPasswordChangeFailure("oldpassword", generateString(bid.PASSWORD_MIN_LENGTH - 1), "too short new password, expected failure"); + }); - asyncTest("changePassword with incorrect old password - tooltip", function() { - bid.manageAccount(mocks, function() { - xhr.useResult("incorrectPassword"); - - $("#old_password").val("incorrectpassword"); - $("#new_password").val("newpassword"); - - bid.manageAccount.changePassword(function(status) { - equal(status, false, "on incorrect old password, status is false"); - testHelpers.testTooltipVisible(); - start(); - }); - }); + asyncTest("changePassword with too long of a new password - tooltip", function() { + testPasswordChangeFailure("oldpassword", generateString(bid.PASSWORD_MAN_LENGTH + 1), "too short new password, expected failure"); }); - asyncTest("changePassword with same old and new password - tooltip", function() { - bid.manageAccount(mocks, function() { - $("#old_password").val("password"); - $("#new_password").val("password"); - bid.manageAccount.changePassword(function(status) { - equal(status, false, "do not update when old and new passwords are the same"); - testHelpers.testTooltipVisible(); - start(); - }); - }); + asyncTest("changePassword with same old and new password - tooltip", function() { + testPasswordChangeFailure("password", "password", "password same, expected failure"); }); asyncTest("changePassword with XHR error - error message", function() { @@ -272,52 +253,29 @@ }); }); - asyncTest("changePassword with user authenticated to password level, happy case", function() { - bid.manageAccount(mocks, function() { - $("#old_password").val("oldpassword"); - $("#new_password").val("newpassword"); - - bid.manageAccount.changePassword(function(status) { - equal(status, true, "on proper completion, status is true"); - equal(tooltip.shown, false, "on proper completion, tooltip is not shown"); - - equal($("#old_password").val(), "", "old_password field is cleared"); - equal($("#new_password").val(), "", "new_password field is cleared"); - - start(); - }); - }); + asyncTest("changePassword with user authenticated to password level, incorrect old password - tooltip", function() { + xhr.setContextInfo("auth_level", "password"); + xhr.useResult("incorrectPassword"); + testPasswordChangeFailure("incorrectpassword", "newpassword", "incorrect old password, expected failure"); }); - asyncTest("changePassword with user authenticated to assertion level level, incorrect password - show tooltip", function() { + asyncTest("changePassword with user authenticated to assertion level, incorrect password - show tooltip", function() { xhr.setContextInfo("auth_level", "assertion"); + xhr.useResult("incorrectPassword"); - bid.manageAccount(mocks, function() { - $("#old_password").val("oldpassword"); - $("#new_password").val("newpassword"); - xhr.useResult("incorrectPassword"); + testPasswordChangeFailure("oldpassword", "newpassword", "incorrect old password, expected failure"); + }); - bid.manageAccount.changePassword(function(status) { - equal(status, false, "bad password, status is false"); - testHelpers.testTooltipVisible(); - start(); - }); - }); + asyncTest("changePassword with user authenticated to password level, happy case", function() { + xhr.setContextInfo("auth_level", "password"); + + testPasswordChangeSuccess("oldpassword", "newpassword", "proper completion, no need to authenticate"); }); asyncTest("changePassword with user authenticated to assertion level level, correct password - log user in, change password", function() { xhr.setContextInfo("auth_level", "assertion"); - bid.manageAccount(mocks, function() { - $("#old_password").val("oldpassword"); - $("#new_password").val("newpassword"); - - bid.manageAccount.changePassword(function(status) { - equal(status, true, "on proper completion, status is true"); - equal(tooltip.shown, false, "on proper completion, tooltip is not shown"); - start(); - }); - }); + testPasswordChangeSuccess("oldpassword", "newpassword", "proper completion after authenticating user"); }); }()); diff --git a/resources/static/test/testHelpers/helpers.js b/resources/static/test/testHelpers/helpers.js index c9f9329442d808d31b1e158ccb23c079519d1bd1..55035dbfb4511d44ed59a3f7ea6689261827a031 100644 --- a/resources/static/test/testHelpers/helpers.js +++ b/resources/static/test/testHelpers/helpers.js @@ -197,6 +197,10 @@ BrowserID.TestHelpers = (function() { equal(tooltip.shown, true, "tooltip is visible"); }, + testTooltipNotVisible: function() { + equal(tooltip.shown, false, "tooltip is not visible"); + }, + failureCheck: function failureCheck(cb) { // Take the original arguments, take off the function. Add any additional // arguments that were passed in, and then tack on the onSuccess and