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.
This commit is contained in:
@@ -720,7 +720,6 @@ class LoginSessionViewTest(ApiTestCase):
|
||||
|
||||
# Missing both email and password
|
||||
response = self.client.post(self.url, {})
|
||||
#COMEBACK
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
|
||||
166
common/static/js/spec/edx.utils.validate_spec.js
Normal file
166
common/static/js/spec/edx.utils.validate_spec.js
Normal file
@@ -0,0 +1,166 @@
|
||||
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);
|
||||
});
|
||||
});
|
||||
@@ -1,8 +1,16 @@
|
||||
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 );
|
||||
}
|
||||
|
||||
@@ -77,7 +87,7 @@ var edx = edx || {};
|
||||
},
|
||||
|
||||
isBlank: function( $el ) {
|
||||
return ( $el.attr('type') === 'checkbox' ) ? !$el.prop('checked') : !$el.val();
|
||||
return ( $el.attr('type') === 'checkbox' ) ? !$el.prop('checked') : !$el.val();
|
||||
},
|
||||
|
||||
email: {
|
||||
@@ -92,7 +102,7 @@ var edx = edx || {};
|
||||
),
|
||||
|
||||
valid: function( $el ) {
|
||||
return $el.attr('type') === 'email' ? _fn.validate.email.format( $el.val() ) : true;
|
||||
return $el.attr('type') === 'email' ? _fn.validate.email.format( $el.val() ) : true;
|
||||
},
|
||||
|
||||
format: function( str ) {
|
||||
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user