$(function () { $.mockjaxSettings.logging = false $.mockjax({ url: '/success', status: 200, responseText: 'cool' }) $.mockjax({ url: '/error', status: 418, responseText: 'dang' }) QUnit.module("validator") QUnit.test("should provide no conflict", function (assert) { var validator = $.fn.validator.noConflict() assert.ok(!$.fn.validator, 'validator was set back to undefined (org value)') $.fn.validator = validator }) QUnit.test("should be defined on jquery object", function (assert) { var div = $('
') assert.ok(div.validator, 'validator method is defined') }) QUnit.test("should return element", function (assert) { var form = $('') assert.ok(form.validator()[0] == form[0], 'same element returned') }) QUnit.test("should expose defaults var for settings", function (assert) { assert.ok($.fn.validator.Constructor.DEFAULTS, 'default object exposed') }) QUnit.test('should not fire validated when validate is prevented', function (assert) { var done = assert.async() $('') .on('validate.bs.validator', function (e) { e.preventDefault() assert.ok(true) done() }) .on('validated.bs.validator', function (e) { assert.ok(false) }) .validator('validate') }) QUnit.test('should validate match', 2, function (assert) { var done = assert.async() var form = '' form = $(form) .appendTo($('#qunit-fixture')) .on('invalid.bs.validator', function (e) { var $el = $(e.relatedTarget) if ($el.attr('id') !== 'wannabe') return assert.ok(true) $el.val('pizza').trigger('input') }) .on('valid.bs.validator', function (e) { var $el = $(e.relatedTarget) if ($el.attr('id') !== 'wannabe') return assert.ok(true) done() }) .validator('validate') }) QUnit.test('should validate minlength', 2, function (assert) { var done = assert.async() $('') .on('invalid.bs.validator', function (e) { assert.ok(true) $(e.relatedTarget).val('pizzas').trigger('input') }) .on('valid.bs.validator', function (e) { assert.ok(true) done() }) .validator('validate') }) QUnit.test('should allow custom generic error message', function (assert) { var done = assert.async() var form = '' $(form) .on('invalid.bs.validator', function (e) { assert.ok($(this).find('.help-block.with-errors').text() == 'generic error', 'generic error message was set') done() }) .validator('validate') }) QUnit.test('should allow custom error-specific message for standard attribute validators', function (assert) { var form = '' $(form) .appendTo('#qunit-fixture') .validator('validate') assert.equal($('#type').text(), 'type', 'type error message was set') assert.equal($('#pattern').text(), 'pattern', 'pattern error message was set') assert.equal($('#min').text(), 'min', 'min error message was set') assert.equal($('#max').text(), 'max', 'max error message was set') assert.equal($('#step').text(), 'step', 'step error message was set') assert.equal($('#required').text(), 'required', 'required error message was set') }) QUnit.test('should allow custom error-specific message for non-standard validators', function (assert) { var done = assert.async() var form = '' $(form) .on('invalid.bs.validator', function (e) { assert.ok($(this).find('.help-block.with-errors').text() == 'minlength error', 'specific error message was set') done() }) .validator('validate') }) QUnit.test('should give precedence to specific error message over generic error message', function (assert) { var done = assert.async() var form = '' $(form) .on('invalid.bs.validator', function (e) { assert.ok($(this).find('.help-block.with-errors').text() == 'minlength error', 'specific error message displayed instead of generic error') done() }) .validator('validate') }) QUnit.test('should escape html in error messages if html option is false', function (assert) { var done = assert.async() var form = '' $(form) .on('invalid.bs.validator', function (e) { assert.ok($(this).find('.help-block.with-errors').text() == 'Too short', 'html escaped from error message') done() }) .validator({html: false}) .validator('validate') }) QUnit.test('should allow html in error messages if html option is true', function (assert) { var done = assert.async() var form = '' $(form) .on('invalid.bs.validator', function (e) { assert.ok($(this).find('.help-block.with-errors').text() == 'Too short', 'html allowed in error message') done() }) .validator({html: true}) .validator('validate') }) QUnit.test('should restore .help-block content once valid', function (assert) { var done = assert.async() var form = '' $(form) .on('invalid.bs.validator', function (e) { assert.ok($(this).find('.help-block.with-errors').text() != '6 characters', 'error message was set') $(e.relatedTarget).val('pizzas').trigger('input') }) .on('valid.bs.validator', function (e) { assert.ok($(this).find('.help-block.with-errors').text() == '6 characters', 'help text was restored') done() }) .validator('validate') }) QUnit.test('should add .has-error class to the closest .form-group', function (assert) { var done = assert.async() var form = '' $(form) .on('invalid.bs.validator', function (e) { assert.ok($(this).find('.form-group').hasClass('has-error'), '.has-error class added to form-group') $(e.relatedTarget).val('pizzas').trigger('input') }) .on('valid.bs.validator', function (e) { assert.ok(!$(this).find('.form-group').hasClass('has-error'), '.has-error class removed from form-group') done() }) .validator('validate') }) QUnit.test('should add feedback classes to .form-control-feedback elements when the form group .has-feedback', function (assert) { var done = assert.async() var form = '' $(form) .on('invalid.bs.validator', function (e) { assert.ok($(this).find('.form-control-feedback').hasClass('glyphicon-remove'), 'error feedback class added to .form-control-feedback') $(e.relatedTarget).val('pizzas').trigger('input') }) .on('valid.bs.validator', function (e) { assert.ok($(this).find('.form-control-feedback').hasClass('glyphicon-ok'), 'success feedback class added to .form-control-feedback') done() }) .validator('validate') }) QUnit.test('should not add feedback classes to .form-control-feedback elements when the form group does not .has-feedback', function (assert) { var done = assert.async() var form = '' $(form) .on('invalid.bs.validator', function (e) { assert.ok(!$(this).find('.form-control-feedback').hasClass('glyphicon-remove'), 'error feedback class not added to .form-control-feedback') $(e.relatedTarget).val('pizzas').trigger('input') }) .on('valid.bs.validator', function (e) { assert.ok(!$(this).find('.form-control-feedback').hasClass('glyphicon-ok'), 'success feedback class not added to .form-control-feedback') done() }) .validator('validate') }) QUnit.test('should not add success feedback classes to empty fields', function (assert) { var done = assert.async() var form = '' $(form) .on('invalid.bs.validator', function (e) { assert.ok($(this).find('.form-control-feedback').hasClass('glyphicon-remove'), 'error feedback class added to .form-control-feedback') $(e.relatedTarget).val('').trigger('input') }) .on('valid.bs.validator', function (e) { assert.ok(!$(this).find('.form-control-feedback').hasClass('glyphicon-ok'), 'success feedback class not added to .form-control-feedback') assert.ok(!$(this).find('.form-group').hasClass('has-success'), '.has-success not added to .form-group') done() }) .validator('validate') }) QUnit.test('should disable submit button unless form is complete and valid', function (assert) { var form = '' form = $(form) .appendTo('#qunit-fixture') .validator() var $btn = $('#btn') assert.ok($btn.hasClass('disabled'), 'submit button disabled because form is incomplete and invalid') $('#required').val('hamburgers').trigger('input') assert.ok(!$btn.hasClass('disabled'), 'submit button enabled because form is sufficiently complete and no fields are invalid') $('#minlength').val('pizza').trigger('input') assert.ok($btn.hasClass('disabled'), 'submit button disabled because form is invalid') $('#minlength').val('pizzas').trigger('input') assert.ok(!$btn.hasClass('disabled'), 'submit button enabled because form is complete and valid') }) QUnit.test('should not disable submit button if disable option is set to false', function (assert) { var form = '' form = $(form) .appendTo('#qunit-fixture') .validator({ disable: false }) var $btn = $('#btn') assert.ok($btn.not('.disabled'), 'submit button enabled although form is incomplete and invalid because disabling of submit is disabled') $('#required').val('hamburgers').trigger('input') $('#minlength').val('pizza').trigger('input') assert.ok($btn.not('.disabled'), 'submit button enabled although form is invalid because disabling of submit is disable') }) QUnit.test('should only disable the submit buttons', function (assert) { var form = '' form = $(form) .appendTo('#qunit-fixture') .validator() var $submit = $('#submit') var $cancel = $('#cancel') var $btn = $('#btn') assert.ok($submit.hasClass('disabled'), 'submit button disabled') assert.ok(!$cancel.hasClass('disabled'), 'cancel button not disabled') assert.ok(!$btn.hasClass('disabled'), 'button without a type not disabled') }) QUnit.test('should respect the required attribute on checkboxes', function (assert) { var form = '' form = $(form) .appendTo('#qunit-fixture') .validator() var $btn = $('#btn') assert.ok($btn.hasClass('disabled'), 'submit button disabled because form is incomplete') $('#required').prop('checked', true).trigger('change') assert.ok(!$btn.hasClass('disabled'), 'submit button enabled because form is complete') $('#required').prop('checked', false).trigger('change') assert.ok($btn.hasClass('disabled'), 'submit button disabled because form is incomplete') $('#required').prop('checked', true).trigger('change') assert.ok(!$btn.hasClass('disabled'), 'submit button enabled because form is complete') }) QUnit.test('should respect the required attribute on radio button groups', function (assert) { var form = '' form = $(form) .appendTo('#qunit-fixture') .validator() var $btn = $('#btn') assert.ok($btn.hasClass('disabled'), 'submit button disabled because form is incomplete') $('#required1').prop('checked', true).trigger('change') assert.ok(!$btn.hasClass('disabled'), 'submit button enabled because form is complete') $('#required2').prop('checked', false).trigger('change') assert.ok(!$btn.hasClass('disabled'), 'submit button still enabled') }) QUnit.test('should support [form] attribute on submit buttons outside of form element', function (assert) { var form = '' + '' form = $(form) .appendTo('#qunit-fixture') .validator() var $btn = $('#btn') assert.ok($btn.hasClass('disabled'), 'submit button outside of referenced form is disabled') $('#input').val('sup').trigger('change') assert.ok(!$btn.hasClass('disabled'), 'submit button outside of referenced form reacted to changes') }) QUnit.test('should ignore button fields', function (assert) { var form = '' form = $(form) .appendTo('#qunit-fixture') .validator('validate') var $errors = $('#errors') assert.equal($errors.text(), 'error', 'buttons did not inadvertently get validated and clear the form-group errors') }) QUnit.test('should validate remote endpoints with success if response is 200', function (assert) { var done = assert.async() var form = '' form = $(form) .appendTo('#qunit-fixture') .on('valid.bs.validator', function (e) { assert.ok(e.relatedTarget === $('#remote')[0], 'remote endpoint validated successfully with a 200 response') done() }) .validator('validate') }) QUnit.test('should validate remote endpoints with error if response is 4xx', function (assert) { var done = assert.async() var form = '' form = $(form) .appendTo('#qunit-fixture') .on('invalid.bs.validator', function (e) { assert.ok(e.relatedTarget === $('#remote')[0], 'remote endpoint validated with error with a 4xx response') done() }) .validator('validate') }) QUnit.test('should clean up after itself when destroy called', function (assert) { var done = assert.async() var form = '' form = $(form) .appendTo('#qunit-fixture') .validator('validate') var validator = form.data('bs.validator') window.setTimeout(function () { form.validator('destroy') Object.keys(validator).forEach(function (key) { assert.ok(validator[key] === null, 'removed ' + key + ' reference from plugin instance') }) assert.ok(!form.data('bs.validator'), 'removed data reference to plugin instance') assert.ok(!form.attr('novalidate'), 'removed novalidate browser override') assert.ok(Object.keys(form.find('input').data()).length === 1, 'removed data left on inputs (excluding data-* attrs)') assert.ok(!form.find('.has-error').length, 'removed has-error class from all inputs') assert.ok(!form.find('.glyphicon-remove').length, 'removed feedback class from all inputs') assert.ok(form.find('.help-block').html() === 'original content', 'help block content restored') assert.ok(!form.find('button').is('.disabled'), 're-enabled submit button') done() }) }) QUnit.test('should run custom validators', function (assert) { var form = '' var options = { custom: { foo: function ($el) { if ($el.data('foo') != $el.val()) return 'not equal to ' + $el.data('foo') } } } form = $(form) .appendTo('#qunit-fixture') .validator(options) .validator('validate') assert.ok($('#foo').data('bs.validator.errors').length === 0, 'foo input is valid') assert.ok($('#bar').data('bs.validator.errors').length === 1, 'bar input is invalid') assert.ok($('#bar').data('bs.validator.errors')[0] === 'not equal to foo', 'bar error is custom error') assert.ok($('#baz').data('bs.validator.errors').length === 1, 'baz ran validator even though data-foo has no attr value') }) QUnit.test('should update set of fields', function (assert) { var form = '' var group = '