Move edx.utils.validate.

The test was not running where it lived before.
This commit is contained in:
cahrens
2015-10-15 10:34:15 -04:00
parent 6fb89fee5a
commit a099ff86e5
8 changed files with 202 additions and 200 deletions

View File

@@ -1,195 +0,0 @@
;(function (define) {
'use strict';
define(['jquery', 'js/utils/edx.utils.validate'],
function($) {
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',
EMAIL_ERROR_FRAGMENT = 'formatted',
MIN_ERROR_FRAGMENT = 'least',
MAX_ERROR_FRAGMENT = 'up to',
REQUIRED_ERROR_FRAGMENT = 'Please enter your',
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(EMAIL_ERROR_FRAGMENT);
// Verify required field behavior
field.prop('required', false);
expectInvalid(EMAIL_ERROR_FRAGMENT);
});
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('succeeds if a select is optional, or required and default is selected, but fails if a required select has the default option selected', function () {
var select = [
'<select id="dropdown" name="country">',
'<option value="" data-isdefault="true">Please select a country</option>',
'<option value="BE">Belgium</option>',
'<option value="DE">Germany</option>',
'</select>'
].join('');
setFixtures(select);
field = $('#dropdown');
// Optional
expectValid();
// Required, default text selected
field.attr('required', true);
expectInvalid(REQUIRED_ERROR_FRAGMENT);
// Required, country selected
field.val('BE');
expectValid();
});
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);
});
});
}).call(this, define || RequireJS.define);

View File

@@ -162,7 +162,8 @@
'common-requirejs/include/common/js/spec/components/paging_header_spec.js',
'common-requirejs/include/common/js/spec/components/paging_footer_spec.js',
'common-requirejs/include/common/js/spec/components/search_field_spec.js',
'common-requirejs/include/common/js/spec/components/view_utils_spec.js'
'common-requirejs/include/common/js/spec/components/view_utils_spec.js',
'common-requirejs/include/common/js/spec/utils/edx.utils.validate_spec.js'
]);
}).call(this, requirejs, define);

View File

@@ -1,193 +0,0 @@
;(function (define) {
'use strict';
define([
'jquery',
'underscore',
'underscore.string',
'gettext'
],
function($, _, _s, gettext) {
var utils;
/* 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.
*/
if (_.isUndefined(_s)) {
_s = _.str;
}
_.mixin( _s.exports() );
utils = (function(){
var _fn = {
validate: {
msg: {
email: '<li><%- gettext("The email address you\'ve provided isn\'t formatted correctly.") %></li>',
min: '<li><%- _.sprintf( gettext("%(field)s must have at least %(count)d characters."), context ) %></li>',
max: '<li><%- _.sprintf( gettext("%(field)s can only contain up to %(count)d characters."), context ) %></li>',
required: '<li><%- _.sprintf( gettext("Please enter your %(field)s."), context ) %></li>',
custom: '<li><%= content %></li>'
},
field: function( el ) {
var $el = $(el),
required = true,
min = true,
max = true,
email = true,
response = {},
isBlank = _fn.validate.isBlank( $el );
if ( _fn.validate.isRequired( $el ) ) {
if ( isBlank ) {
required = false;
} else {
min = _fn.validate.str.minlength( $el );
max = _fn.validate.str.maxlength( $el );
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 );
}
response.isValid = required && min && max && email;
if ( !response.isValid ) {
_fn.validate.removeDefault( $el );
response.message = _fn.validate.getMessage( $el, {
required: required,
min: min,
max: max,
email: email
});
}
return response;
},
str: {
minlength: function( $el ) {
var min = $el.attr('minlength') || 0;
return min <= $el.val().length;
},
maxlength: function( $el ) {
var max = $el.attr('maxlength') || false;
return ( !!max ) ? max >= $el.val().length : true;
}
},
isRequired: function( $el ) {
return $el.attr('required');
},
isBlank: function( $el ) {
var type = $el.attr('type'),
isBlank;
if ( type === 'checkbox' ) {
isBlank = !$el.prop('checked');
} else if ( type === 'select' ) {
isBlank = ( $el.data('isdefault') === true );
} else {
isBlank = !$el.val();
}
return isBlank;
},
email: {
// This is the same regex used to validate email addresses in Django 1.4
regex: new RegExp(
[
'(^[-!#$%&\'*+/=?^_`{}|~0-9A-Z]+(\\.[-!#$%&\'*+/=?^_`{}|~0-9A-Z]+)*',
'|^"([\\001-\\010\\013\\014\\016-\\037!#-\\[\\]-\\177]|\\\\[\\001-\\011\\013\\014\\016-\\177])*"',
')@((?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\\.)+[A-Z]{2,6}\\.?$)',
'|\\[(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\]$'
].join(''), 'i'
),
valid: function( $el ) {
return $el.attr('type') === 'email' ? _fn.validate.email.format( $el.val() ) : true;
},
format: function( str ) {
return _fn.validate.email.regex.test( str );
}
},
getLabel: function( id ) {
// Extract the field label, remove the asterisk (if it appears) and any extra whitespace
return $("label[for=" + id + "]").text().split("*")[0].trim();
},
getMessage: function( $el, tests ) {
var txt = [],
tpl,
label,
obj,
customMsg;
_.each( tests, function( value, key ) {
if ( !value ) {
label = _fn.validate.getLabel( $el.attr('id') );
customMsg = $el.data('errormsg-' + key) || false;
// If the field has a custom error msg attached, use it
if ( customMsg ) {
tpl = _fn.validate.msg.custom;
obj = {
content: customMsg
};
} else {
tpl = _fn.validate.msg[key];
obj = {
// We pass the context object to the template so that
// we can perform variable interpolation using sprintf
context: {
field: label
}
};
if ( key === 'min' ) {
obj.context.count = parseInt( $el.attr('minlength'), 10 );
} else if ( key === 'max' ) {
obj.context.count = parseInt( $el.attr('maxlength'), 10 );
}
}
txt.push( _.template( tpl, obj ) );
}
});
return txt.join(' ');
},
// Removes the default HTML5 validation pop-up
removeDefault: function( $el ) {
if ( $el.setCustomValidity ) {
$el.setCustomValidity(' ');
}
}
}
};
return {
validate: _fn.validate.field
};
})();
return utils;
});
}).call(this, define || RequireJS.define);