Client-side validation of password/confirmation match

Fixes bug 1055234

Change-Id: I25a3e8463894f0fb08e26e502f1baf0822d90437
This commit is contained in:
Julie Pichon 2012-11-16 21:12:09 +00:00
parent 241c63b94c
commit ffb98f19e6
6 changed files with 155 additions and 0 deletions

View File

@ -0,0 +1,31 @@
horizon.user = {
init: function() {
$("#id_password").change(function () {
if ($("#id_confirm_password").val() != "") {
horizon.user.check_passwords_match();
}
});
$("#id_confirm_password").change(function () {
horizon.user.check_passwords_match();
});
},
check_passwords_match: function() {
var row = $("label[for='id_confirm_password']");
var error_id = "id_confirm_password_error";
var msg = "<span id='" + error_id + "' class='help-inline'>" + gettext("Passwords do not match.") + "</span>";
var password = $("#id_password").val();
var confirm_password = $("#id_confirm_password").val();
if (password != confirm_password && $("#" + error_id).length == 0) {
$(row).parent().addClass("error");
$(row).after(msg);
} else if (password == confirm_password) {
$(row).parent().removeClass("error");
$("#" + error_id).remove();
}
}
};

View File

@ -28,6 +28,7 @@
<script src='{{ STATIC_URL }}horizon/js/horizon.tables.js' type='text/javascript' charset='utf-8'></script>
<script src='{{ STATIC_URL }}horizon/js/horizon.tabs.js' type='text/javascript' charset='utf-8'></script>
<script src='{{ STATIC_URL }}horizon/js/horizon.templates.js' type='text/javascript' charset='utf-8'></script>
<script src='{{ STATIC_URL }}horizon/js/horizon.users.js' type='text/javascript' charset='utf-8'></script>
<script src='{{ STATIC_URL }}horizon/js/horizon.utils.js' type='text/javascript' charset='utf-8'></script>
<script src='{{ STATIC_URL }}horizon/js/horizon.projects.js' type='text/javascript' charset='utf-8'></script>
{% endcompress %}

View File

@ -16,6 +16,16 @@
<h3>{% trans "Description" %}:</h3>
<p>{% trans "From here you can create a new user and assign them to a project." %}</p>
</div>
<script type="text/javascript">
if (typeof horizon.user !== 'undefined') {
horizon.user.init();
} else {
addHorizonLoadEvent(function() {
horizon.user.init();
});
}
</script>
{% endblock %}
{% block modal-footer %}

View File

@ -16,6 +16,16 @@
<h3>{% trans "Description" %}:</h3>
<p>{% trans "From here you can edit the user's details, including their default project." %}</p>
</div>
<script type="text/javascript">
if (typeof horizon.user !== 'undefined') {
horizon.user.init();
} else {
addHorizonLoadEvent(function() {
horizon.user.init();
});
}
</script>
{% endblock %}
{% block modal-footer %}

View File

@ -355,3 +355,54 @@ class UsersViewTests(test.BaseAdminViewTests):
self.assertEqual(list(res.context['messages'])[0].message,
u'You do not have permission to delete user: %s'
% self.request.user.username)
class SeleniumTests(test.SeleniumAdminTestCase):
@test.create_stubs({api: ('tenant_list',),
api.keystone: ('get_default_role', 'role_list',
'user_list')})
def test_modal_create_user_with_passwords_not_matching(self):
api.tenant_list(IgnoreArg(), admin=True).AndReturn(self.tenants.list())
api.keystone.role_list(IgnoreArg()).AndReturn(self.roles.list())
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
api.keystone.get_default_role(IgnoreArg()) \
.AndReturn(self.roles.first())
self.mox.ReplayAll()
self.selenium.get("%s%s" % (self.live_server_url, USERS_INDEX_URL))
# Open the modal menu
self.selenium.find_element_by_id("users__action_create") \
.send_keys("\n")
wait = self.ui.WebDriverWait(self.selenium, 10)
wait.until(lambda x: self.selenium.find_element_by_id("id_name"))
body = self.selenium.find_element_by_tag_name("body")
self.assertFalse("Passwords do not match" in body.text,
"Error message should not be visible at loading time")
self.selenium.find_element_by_id("id_name").send_keys("Test User")
self.selenium.find_element_by_id("id_password").send_keys("test")
self.selenium.find_element_by_id("id_confirm_password").send_keys("te")
self.selenium.find_element_by_id("id_email").send_keys("a@b.com")
body = self.selenium.find_element_by_tag_name("body")
self.assertTrue("Passwords do not match" in body.text,
"Error message not found in body")
@test.create_stubs({api: ('tenant_list', 'user_get')})
def test_update_user_with_passwords_not_matching(self):
api.user_get(IsA(http.HttpRequest), '1',
admin=True).AndReturn(self.user)
api.tenant_list(IgnoreArg(), admin=True).AndReturn(self.tenants.list())
self.mox.ReplayAll()
self.selenium.get("%s%s" % (self.live_server_url, USER_UPDATE_URL))
body = self.selenium.find_element_by_tag_name("body")
self.assertFalse("Passwords do not match" in body.text,
"Error message should not be visible at loading time")
self.selenium.find_element_by_id("id_password").send_keys("test")
self.selenium.find_element_by_id("id_confirm_password").send_keys("te")
self.selenium.find_element_by_id("id_email").clear()
body = self.selenium.find_element_by_tag_name("body")
self.assertTrue("Passwords do not match" in body.text,
"Error message not found in body")

View File

@ -296,3 +296,55 @@ class APITestCase(TestCase):
.AndReturn(self.swiftclient)
expected_calls -= 1
return self.swiftclient
@unittest.skipUnless(os.environ.get('WITH_SELENIUM', False),
"The WITH_SELENIUM env variable is not set.")
class SeleniumTestCase(horizon_helpers.SeleniumTestCase):
def setUp(self):
super(SeleniumTestCase, self).setUp()
load_test_data(self)
self.mox = mox.Mox()
self._real_get_user = utils.get_user
self.setActiveUser(id=self.user.id,
token=self.token,
username=self.user.name,
tenant_id=self.tenant.id,
service_catalog=self.service_catalog,
authorized_tenants=self.tenants.list())
os.environ["HORIZON_TEST_RUN"] = "True"
def tearDown(self):
self.mox.UnsetStubs()
utils.get_user = self._real_get_user
self.mox.VerifyAll()
del os.environ["HORIZON_TEST_RUN"]
def setActiveUser(self, id=None, token=None, username=None, tenant_id=None,
service_catalog=None, tenant_name=None, roles=None,
authorized_tenants=None, enabled=True):
def get_user(request):
return user.User(id=id,
token=token,
user=username,
tenant_id=tenant_id,
service_catalog=service_catalog,
roles=roles,
enabled=enabled,
authorized_tenants=authorized_tenants,
endpoint=settings.OPENSTACK_KEYSTONE_URL)
utils.get_user = get_user
class SeleniumAdminTestCase(SeleniumTestCase):
"""
A ``TestCase`` subclass which sets an active user with the "admin" role
for testing admin-only views and functionality.
"""
def setActiveUser(self, *args, **kwargs):
if "roles" not in kwargs:
kwargs['roles'] = [self.roles.admin._info]
super(SeleniumAdminTestCase, self).setActiveUser(*args, **kwargs)