Files
dist
src
test
libs
unit
api.js
checklist.js
combodate.js
common.js
date.js
datefield.js
datetime.js
datetimefield.js
dateui.js
dateuifield.js
select.js
select2.js
text.js
textarea.js
typeahead.js
typeaheadjs.js
wysihtml5.js
coverage
index.html
loader.js
main.js
mocks.js
require.js
style.css
.gitignore
CHANGELOG.txt
Gruntfile.js
LICENSE-MIT
Package.nuspec
README.md
bower.json
composer.json
package.json
x-editable/test/unit/api.js
2013-11-04 17:54:16 +04:00

577 lines
21 KiB
JavaScript

$(function () {
module("api", {
setup: function(){
fx = $('#async-fixture');
$.support.transition = false;
}
});
test("validate, getValue, option", function () {
var e = $(
'<a href="#" data-type="text" id="username">user</a>' +
'<a href="#" data-type="textarea" id="comment">12345</a>' +
'<a href="#" data-type="select" id="sex" data-value="1" data-source=\'{"1":"q", "2":"w"}\'>q</a>' +
'<a href="#" data-type="date" id="dob" data-format="dd.mm.yyyy">15.05.1984</a>'
).appendTo('#qunit-fixture').editable(),
e1 = $('#username').editable('option', 'validate', function(value) {
if($.trim(value) !== 'user1') return 'username is required';
}),
e2 = $('#sex').editable('option', 'validate', function(value) {
if($.trim(value) != 2) return 'error';
});
//check get value
var values = e.editable('getValue');
equal(values.username, 'user', 'username ok') ;
equal(values.comment, '12345', 'comment ok') ;
equal(values.sex, 1, 'sex ok') ;
equal(values.dob, '15.05.1984', 'dob ok') ;
//validate
var errors = e.editable('validate');
ok(errors.username && errors.sex && !errors.comment, 'validation failed ok');
//enter correct values
e1.click();
var p = tip(e1);
p.find('input').val('user1');
p.find('button[type="submit"]').click();
ok(!p.is(':visible'), 'username changed');
e2.click();
p = tip(e2);
p.find('select').val(2);
p.find('button[type="submit"]').click();
ok(!p.is(':visible'), 'sex changed');
//validate again
var errors = e.editable('validate');
ok($.isEmptyObject(errors), 'validation ok');
});
test("getValue with originally empty elements", function () {
var e = $(
'<a href="#" data-type="text" id="username"></a>' +
'<a href="#" data-type="textarea" id="comment"></a>' +
'<a href="#" data-type="select" id="sex" data-source=\'{"1":"q", "2":"w"}\'></a>' +
'<a href="#" data-type="date" id="dob"></a>'
).appendTo('#qunit-fixture').editable();
//check get value
var values = e.editable('getValue');
equal(values.username, '', 'text empyt value') ;
equal(values.comment, '', 'textarea empty value') ;
ok(!('sex' in values), 'select value not present') ;
ok(!('dob' in values), 'date value not present') ;
});
test("getValue with isSingle = true", function () {
var v = '123',
e = $(
'<a href="#" data-type="text" id="username">'+v+'</a>' +
'<a href="#" data-type="textarea" id="comment">456</a>'
).appendTo('#qunit-fixture').editable();
//check get value
var value = e.editable('getValue', true);
equal(value, v, 'value ok');
});
asyncTest("'init' event", function () {
expect(3);
var e = $('<a href="#" data-pk="1" data-url="post.php" data-name="text1">abc</a>').appendTo(fx);
e.on('init', function(event, editable) {
equal(e[0], this, 'scope ok');
equal(editable.value, 'abc', 'init triggered, value correct');
setTimeout(function() {
equal(editable, e.data('editable'), 'editable param ok');
e.remove();
start();
}, timeout);
});
e.editable();
});
asyncTest("events: shown / hidden (reason: cancel, onblur, nochange, manual)", function () {
var val = '1', test_reason,
e = $('<a href="#" data-pk="1" data-type="select" data-url="post.php" data-name="text" data-value="'+val+'"></a>').appendTo(fx);
e.on('shown', function(event, edt) {
//distinguish from native bootstrap popover event
if(arguments.length != 2) return;
var editable = $(this).data('editable');
equal(editable.value, val, 'shown triggered, value correct');
equal(edt, editable, 'edt param correct');
});
e.on('hidden', function(event, reason) {
//distinguish from native bootstrap popover event
if(arguments.length != 2) return;
ok((reason === test_reason) || (test_reason === 'manual' && reason === undefined), 'hidden triggered, reason ok');
});
e.editable({
source: 'groups.php'
});
e.click();
setTimeout(function() {
var p = tip(e);
test_reason = 'cancel'
p.find('.editable-cancel').click(); //cancel
ok(!p.is(':visible'), 'popover closed '+test_reason);
test_reason = 'onblur'
e.click();
p = tip(e);
ok(p.is(':visible'), 'popover shown '+test_reason);
e.parent().click();
ok(!p.is(':visible'), 'popover closed '+test_reason);
test_reason = 'nochange'
e.click();
p = tip(e);
ok(p.is(':visible'), 'popover shown '+test_reason);
p.find('form').submit(); //submit value without changes
ok(!p.is(':visible'), 'popover closed '+test_reason);
test_reason = 'manual'
e.click();
p = tip(e);
ok(p.is(':visible'), 'popover shown '+test_reason);
e.editable('hide');
ok(!p.is(':visible'), 'popover closed '+test_reason);
e.remove();
start();
}, timeout);
});
asyncTest("event: save / hidden (reason: save)", function () {
expect(3);
var val = '1',
e = $('<a href="#" data-pk="1" data-type="select" data-url="post.php" data-name="text" data-value="'+val+'"></a>').appendTo(fx);
e.on('save', function(event, params) {
equal(params.newValue, 2, 'save triggered, value correct');
equal(params.submitValue, '2', 'submitValue property correct');
});
e.on('hidden', function(event, reason) {
//distinguish from native bootstrap popover event
if(arguments.length != 2) return;
equal(reason, 'save', 'hidden triggered, reason ok');
});
e.editable({
source: groups
});
e.click();
var p = tip(e);
p.find('select').val(2);
p.find('form').submit();
setTimeout(function() {
e.remove();
start();
}, timeout);
});
asyncTest("hide when saving value", function () {
var newVal = 2,
e = $('<a href="#" data-pk="1" data-type="select" data-url="post.php" data-name="text" data-value="1"></a>')
.appendTo(fx)
.editable({
source: groupsArr
});
e.click();
var p = tip(e);
p.find('select').val(2);
p.find('form').submit();
e.parent().click();
ok(p.is(':visible'), 'popover still visible');
setTimeout(function() {
equal(e.data('editable').value, newVal, 'new value saved');
ok(!p.is(':visible'), 'popover closed');
e.remove();
start();
}, timeout);
});
test("show/hide/toggle methods", function () {
var e = $('<a href="#" data-pk="1" data-url="post.php" data-name="text1">abc</a>').appendTo('#qunit-fixture').editable();
e.editable('show');
var p = tip(e);
ok(p.is(':visible'), 'popover shown');
e.editable('hide');
p = tip(e);
ok(!p.is(':visible'), 'popover closed');
e.editable('toggle');
p = tip(e);
ok(p.is(':visible'), 'popover shown');
});
test("enable/disable/toggleDisabled methods", function () {
var e = $('<a href="#" data-type="text" data-pk="1" data-url="post.php" data-name="text1">abc</a>').appendTo('#qunit-fixture').editable({
disabled: true
});
ok(e.hasClass('editable-disabled'), 'has disabled class');
ok(e.hasClass('editable-click'), 'has click class');
e.click();
ok(!e.data('editableContainer'), 'nothing on click');
e.editable('enable');
ok(!e.hasClass('editable-disabled'), 'does not have disabled class');
e.click();
var p = tip(e);
ok(p.is(':visible'), 'popover shown on click');
e.editable('disable');
p = tip(e);
ok(e.hasClass('editable-disabled'), 'has disabled class');
ok(!p.is(':visible'), 'popover closed');
e.editable('toggleDisabled');
ok(!e.hasClass('editable-disabled'), 'does not have disabled class (toggle)');
});
test("option method (string and object)", function () {
var e = $('<a href="#" data-url="post.php" data-name="text">abc</a>').appendTo('#qunit-fixture').editable(),
e1 = $('<a href="#" data-pk="1" data-name="text1">abc</a>').appendTo('#qunit-fixture').editable(),
url = 'abc';
$('#qunit-fixture a').editable('option', 'pk', 2);
equal(e.data('editable').options.pk, 2, 'pk set correctly');
equal(e1.data('editable').options.pk, 2, 'pk2 set correctly');
$('#qunit-fixture a').editable('option', {pk: 3, value: 'abcd'});
equal(e.data('editable').options.pk, 3, 'pk set correctly (by object)');
equal(e.data('editable').value, 'abcd', 'value set correctly (by object)');
equal(e.text(), 'abcd', 'text set correctly (by object)');
});
asyncTest("'submit' method: client and server validation errors", function () {
var ev1 = 'ev1',
ev2 = 'ev2',
e1v = 'e1v',
e = $('<a href="#" class="new-val" data-type="text" data-url="post.php" data-name="text">'+ev1+'</a>').appendTo(fx).editable({
validate: function(value) {
if(value == ev1) return 'invalid';
}
}),
e1 = $('<a href="#" class="new-val" data-type="text" data-name="text1">'+e1v+'</a>').appendTo(fx).editable();
$.mockjax({
url: 'new-error.php',
response: function(settings) {
equal(settings.data.text, ev2, 'first value ok');
equal(settings.data.text1, e1v, 'second value ok');
equal(settings.data.a, 123, 'custom data ok');
equal(settings.type, 'PUT', 'ajaxOptions ok');
this.responseText = {errors: {
text1: 'server-invalid'
}
};
}
});
$.mockjax({
url: 'new.php',
response: function(settings) {
ok(false, 'should not submit to new.php');
}
});
$(fx).find('.new-val').editable('submit', {
url: 'new.php',
error: function(errors) {
equal(errors.text, 'invalid', 'client validation error ok');
}
});
//change value to pass client side validation
e.click();
var p = tip(e);
p.find('input[type=text]').val(ev2);
p.find('button[type=submit]').click();
$(fx).find('.new-val').editable('submit', {
url: 'new-error.php',
data: {a: 123},
success: function(data, config) {
ok(data.errors, 'errors received from server');
ok(typeof config.error === 'function', 'config passed correctly');
if(data && data.id) {
//success
} else if(data && data.errors){
config.error.call(this, data.errors); //call error from success
}
},
error: function(errors) {
equal(errors.text1, 'server-invalid', 'server validation error ok');
},
ajaxOptions: {
type: 'PUT',
dataType: 'json'
}
});
setTimeout(function() {
e.remove();
e1.remove();
start();
}, timeout);
});
asyncTest("'submit' method: server error", function () {
var ev1 = 'ev1',
e1v = 'e1v',
e = $('<a href="#" class="new-err" data-type="text" data-url="post.php" data-name="text">'+ev1+'</a>').appendTo(fx).editable(),
e1 = $('<a href="#" class="new-err" data-type="text" data-name="text1">'+e1v+'</a>').appendTo(fx).editable();
$(fx).find('.new-err').editable('submit', {
url: 'error.php',
error: function(data) {
equal(this[0], $(fx).find('.new-err')[0], 'success context ok');
equal(this[1], $(fx).find('.new-err')[1], 'success context2 ok');
equal(data.status, 500, 'status 500 ok');
equal(data.responseText, 'customtext', 'server error ok');
e.remove();
e1.remove();
start();
}
});
});
asyncTest("'submit' method: success (multiple elems)", function () {
var ev1 = 'ev1',
e1v = 'e1v',
pk = 123,
e = $('<a href="#" class="new" data-type="text" data-url="post.php" data-name="text">'+ev1+'</a>').appendTo(fx).editable(),
e1 = $('<a href="#" class="new" data-type="text" data-name="text1">'+e1v+'</a>').appendTo(fx).editable();
$.mockjax({
url: 'new-success.php',
response: function(settings) {
equal(settings.data.text, ev1, 'first value ok');
equal(settings.data.text1, e1v, 'second value ok');
this.responseText = 'response-body';
}
});
$(fx).find('.new').editable('submit', {
url: 'new-success.php',
success: function(data) {
equal(this[0], $(fx).find('.new')[0], 'success context ok');
equal(this[1], $(fx).find('.new')[1], 'success context2 ok');
equal(data, 'response-body', 'response body ok');
e.remove();
e1.remove();
start();
},
error: function(errors) {
ok(false, 'error should not be called');
}
});
});
asyncTest("'submit' method: success (single elem)", function () {
expect(5);
var ev1 = 'ev1',
pk = 123,
e = $('<a href="#" class="new" data-type="text" data-pk="'+pk+'" data-url="submit-single" data-name="text">'+ev1+'</a>').appendTo(fx).editable({
success: function(data) {
equal(data, 'response-body', 'response body ok');
}
});
$.mockjax({
url: 'submit-single',
response: function(settings) {
equal(settings.data.name, 'text', 'name ok');
equal(settings.data.pk, pk, 'pk ok');
equal(settings.data.value, ev1, 'value ok');
equal(settings.data.a, 1, 'extra data ok');
this.responseText = 'response-body';
}
});
$(fx).find('.new').editable('submit', {
data: {a: 1}
});
setTimeout(function() {
e.remove();
start();
}, timeout);
});
asyncTest("'submit' method: error (single elem)", function () {
expect(1);
var e = $('<a href="#" class="new" data-type="text" data-pk="123" data-url="error.php" data-name="text">text</a>').appendTo(fx).editable();
$(fx).find('.new').editable('submit', {
error: function() {
equal(this[0], e[0], 'error called in correct scope');
}
});
setTimeout(function() {
e.remove();
start();
}, timeout);
});
test("setValue method", function () {
var e = $('<a href="#" data-name="name" data-type="select" data-url="post.php"></a>').appendTo('#qunit-fixture').editable({
value: 1,
source: groups
});
equal(e.data('editable').value, 1, 'value correct');
equal(e.text(), groups[1], 'text shown correctly');
//open editable to check update of input
e.click();
var p = tip(e);
equal(p.find('select').find('option').length, size, 'options loaded');
equal(p.find('select').val(), e.data('editable').value, 'selected value correct');
e.editable('setValue', 2);
equal(e.data('editable').value, 2, 'new value correct');
equal(e.text(), groups[2], 'new text shown correctly');
equal(p.find('select').val(), e.data('editable').value, 'new selected value correct');
});
test("`destroy` method", function () {
var e = $('<a href="#" data-name="name" data-type="text" data-url="post.php"></a>').appendTo('#qunit-fixture').editable({
});
e.click();
var p = tip(e);
ok(p.is(':visible'), 'container visible');
equal(e.text(), 'Empty', 'emptytext shown');
e.editable('destroy');
ok(!p.is(':visible'), 'container closed');
ok(!e.data('editable'), 'editable instance removed');
ok(!e.data('editableContainer'), 'editableContainer instance removed');
ok(!e.hasClass('editable'), 'editable class removed');
ok(!e.hasClass('editable-click'), 'editable-click class removed');
equal(e.text(), '', 'emptytext removed');
e.click();
});
asyncTest("'validate' that change value", function () {
expect(3);
var e = $('<a href="#" data-type="text" data-pk="1" data-url="validate-change-ok" data-name="text">abc</a>').appendTo(fx).editable({
validate: function(value) {
return {newValue: 'newval'};
}
});
$.mockjax({
url: 'validate-change-ok',
response: function(settings) {
equal(settings.data.value, 'newval', 'validate-change-ok');
this.responseText = '';
}
});
//change value to pass client side validation
e.click();
var p = tip(e);
p.find('input[type=text]').val('cde');
p.find('button[type=submit]').click();
setTimeout(function() {
equal(e.data('editable').value, 'newval', 'new value saved');
ok(!p.is(':visible'), 'popover closed');
e.remove();
start();
}, timeout);
});
asyncTest("'validate' that change value and shows message", function () {
expect(3);
var e = $('<a href="#" data-type="text" data-url="validate-change-error" data-name="text">abc</a>').appendTo(fx).editable({
validate: function(value) {
return {newValue: 'newval', msg: 'error!'};
}
});
$.mockjax({
url: 'validate-change-error',
response: function(settings) {
ok(true, 'should not call');
this.responseText = '';
}
});
//change value to pass client side validation
e.click();
var p = tip(e);
p.find('input[type=text]').val('cde');
p.find('button[type=submit]').click();
setTimeout(function() {
ok(p.is(':visible'), 'popover visible');
equal(p.find('input[type=text]').val(), 'newval', 'new value shown in input');
equal(p.find('.editable-error-block').text(), 'error!', 'error msg shown');
e.remove();
start();
}, timeout);
});
});