Permalink
Browse files

Client-side validation of password/confirmation match

Fixes bug 1055234

Change-Id: I25a3e8463894f0fb08e26e502f1baf0822d90437
  • Loading branch information...
1 parent 241c63b commit ffb98f19e6f5e66f9d9b4036ded446f5e15eb32a @jpichon jpichon committed Nov 16, 2012
@@ -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();
+ }
+ }
+};
@@ -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 %}
@@ -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 %}
@@ -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 %}
@@ -355,3 +355,54 @@ def test_delete_user_with_improper_permissions(self):
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")
@@ -296,3 +296,55 @@ def stub_swiftclient(self, expected_calls=1):
.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)

0 comments on commit ffb98f1

Please sign in to comment.