Commit bedd6cc2 by Renzo Lucioni

Jasmine tests of validation utility

Includes a modification of validation logic which performs min and max length checks on optional fields in addition to required fields.
parent a86c80bb
......@@ -720,7 +720,6 @@ class LoginSessionViewTest(ApiTestCase):
# Missing both email and password
response = self.client.post(self.url, {})
#COMEBACK
@ddt.ddt
......
describe('edx.utils.validate', function () {
'use strict';
var fixture = null,
field = null,
result = null,
MIN_LENGTH = 2,
MAX_LENGTH = 20,
VALID_STRING = 'xsy_is_awesome',
SHORT_STRING = 'x',
LONG_STRING = 'xsy_is_way_too_awesome',
REQUIRED_ERROR_FRAGMENT = 'required',
MIN_ERROR_FRAGMENT = 'least',
MAX_ERROR_FRAGMENT = 'up to',
CUSTOM_MESSAGE = 'custom message';
var createFixture = function( type, name, required, minlength, maxlength, value ) {
setFixtures('<input id="field" type=' + type + '>');
field = $('#field');
field.prop('required', required);
field.attr({
name: name,
minlength: minlength,
maxlength: maxlength,
value: value
});
};
var expectValid = function() {
result = edx.utils.validate(field);
expect(result.isValid).toBe(true);
};
var expectInvalid = function( errorFragment ) {
result = edx.utils.validate(field);
expect(result.isValid).toBe(false);
expect(result.message).toMatch(errorFragment);
};
it('succeeds if an optional field is left blank', function () {
createFixture('text', 'username', false, MIN_LENGTH, MAX_LENGTH, '');
expectValid();
});
it('succeeds if a required field is provided a valid value', function () {
createFixture('text', 'username', true, MIN_LENGTH, MAX_LENGTH, VALID_STRING);
expectValid();
});
it('fails if a required field is left blank', function () {
createFixture('text', 'username', true, MIN_LENGTH, MAX_LENGTH, '');
expectInvalid(REQUIRED_ERROR_FRAGMENT);
});
it('fails if a field is provided a value below its minimum character limit', function () {
createFixture('text', 'username', false, MIN_LENGTH, MAX_LENGTH, SHORT_STRING);
// Verify optional field behavior
expectInvalid(MIN_ERROR_FRAGMENT);
// Verify required field behavior
field.prop('required', true);
expectInvalid(MIN_ERROR_FRAGMENT);
});
it('succeeds if a field with no minimum character limit is provided a value below its maximum character limit', function () {
createFixture('text', 'username', false, null, MAX_LENGTH, SHORT_STRING);
// Verify optional field behavior
expectValid();
// Verify required field behavior
field.prop('required', true);
expectValid();
});
it('fails if a required field with no minimum character limit is left blank', function () {
createFixture('text', 'username', true, null, MAX_LENGTH, '');
expectInvalid(REQUIRED_ERROR_FRAGMENT);
});
it('fails if a field is provided a value above its maximum character limit', function () {
createFixture('text', 'username', false, MIN_LENGTH, MAX_LENGTH, LONG_STRING);
// Verify optional field behavior
expectInvalid(MAX_ERROR_FRAGMENT);
// Verify required field behavior
field.prop('required', true);
expectInvalid(MAX_ERROR_FRAGMENT);
});
it('succeeds if a field with no maximum character limit is provided a value above its minimum character limit', function () {
createFixture('text', 'username', false, MIN_LENGTH, null, LONG_STRING);
// Verify optional field behavior
expectValid();
// Verify required field behavior
field.prop('required', true);
expectValid();
});
it('succeeds if a field with no character limits is provided a value', function () {
createFixture('text', 'username', false, null, null, VALID_STRING);
// Verify optional field behavior
expectValid();
// Verify required field behavior
field.prop('required', true);
expectValid();
});
it('fails if an email field is provided an invalid address', function () {
createFixture('email', 'email', false, MIN_LENGTH, MAX_LENGTH, 'localpart');
// Verify optional field behavior
expectInvalid('invalid');
// Verify required field behavior
field.prop('required', false);
expectInvalid('invalid');
});
it('succeeds if an email field is provided a valid address', function () {
createFixture('email', 'email', false, MIN_LENGTH, MAX_LENGTH, 'localpart@label.tld');
// Verify optional field behavior
expectValid();
// Verify required field behavior
field.prop('required', true);
expectValid();
});
it('succeeds if a checkbox is optional, or required and checked, but fails if a required checkbox is unchecked', function () {
createFixture('checkbox', 'checkbox', false, null, null, 'value');
// Optional, unchecked
expectValid();
// Optional, checked
field.prop('checked', true);
expectValid();
// Required, checked
field.prop('required', true);
expectValid();
// Required, unchecked
field.prop('checked', false);
expectInvalid(REQUIRED_ERROR_FRAGMENT);
});
it('returns a custom error message if an invalid field has one attached', function () {
// Create a blank required field
createFixture('text', 'username', true, MIN_LENGTH, MAX_LENGTH, '');
// Attach a custom error message to the field
field.data('errormsg-required', CUSTOM_MESSAGE);
expectInvalid(CUSTOM_MESSAGE);
});
});
var edx = edx || {};
(function( $, _, gettext ) {
(function( $, _, _s, gettext ) {
'use strict';
/* Mix non-conflicting functions from underscore.string
* (all but include, contains, and reverse) into the
* Underscore namespace. In practice, this mixin is done
* by the access view, but doing it here helps keep the
* utility self-contained.
*/
_.mixin( _.str.exports() );
edx.utils = edx.utils || {};
var utils = (function(){
......@@ -35,6 +43,8 @@ var edx = edx || {};
email = _fn.validate.email.valid( $el );
}
} else if ( !isBlank ) {
min = _fn.validate.str.minlength( $el );
max = _fn.validate.str.maxlength( $el );
email = _fn.validate.email.valid( $el );
}
......@@ -112,7 +122,7 @@ var edx = edx || {};
name = $el.attr('name');
customMsg = $el.data('errormsg-' + key) || false;
// If the field has a custom error msg attached use it
// If the field has a custom error msg attached, use it
if ( customMsg ) {
tpl = _fn.validate.msg.custom;
......@@ -154,4 +164,4 @@ var edx = edx || {};
edx.utils.validate = utils.validate;
})( jQuery, _, gettext );
})( jQuery, _, _.str, gettext );
......@@ -34,6 +34,7 @@ lib_paths:
- js/vendor/jquery.truncate.js
- js/vendor/mustache.js
- js/vendor/underscore-min.js
- js/vendor/underscore.string.min.js
- js/vendor/backbone-min.js
- js/vendor/jquery.timeago.js
- js/vendor/URI.min.js
......@@ -46,6 +47,7 @@ lib_paths:
src_paths:
- coffee/src
- js/src
- js/utils
- js/capa/src
# Paths to spec (test) JavaScript files
......
......@@ -1032,8 +1032,8 @@ instructor_dash_js = sorted(rooted_glob(PROJECT_ROOT / 'static', 'coffee/src/ins
# These are not courseware, so they do not need many of the courseware-specific
# JavaScript modules.
student_account_js = [
'js/common_helpers/rwd_header_footer.js',
'js/common_helpers/edx.utils.validate.js',
'js/utils/rwd_header_footer.js',
'js/utils/edx.utils.validate.js',
'js/student_account/enrollment_interface.js',
'js/student_account/models/LoginModel.js',
'js/student_account/models/RegisterModel.js',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment