Client-side validation of password/confirmation match
Fixes bug 1055234 Change-Id: I25a3e8463894f0fb08e26e502f1baf0822d90437
This commit is contained in:
parent
241c63b94c
commit
ffb98f19e6
|
@ -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 @@ 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")
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue