summaryrefslogtreecommitdiff
path: root/js_tests
diff options
context:
space:
mode:
authorCarlton Gibson <carlton.gibson@noumenal.es>2019-10-24 16:37:55 +0200
committerCarlton Gibson <carlton@noumenal.es>2019-10-25 13:28:08 +0200
commit24e540fbd71bd2b0843e751bde61ad0052a811b3 (patch)
tree0ad75be6f7adb7cc0eedb83af2dacd8a252455c1 /js_tests
parent6ea3aadd17f937e69d121e3ae1a415a435e3267d (diff)
Fixed #29087 -- Added delete buttons for unsaved admin inlines on validation error.
Diffstat (limited to 'js_tests')
-rw-r--r--js_tests/admin/inlines.test.js128
-rw-r--r--js_tests/tests.html46
2 files changed, 168 insertions, 6 deletions
diff --git a/js_tests/admin/inlines.test.js b/js_tests/admin/inlines.test.js
index 433ea0672a..582ede1465 100644
--- a/js_tests/admin/inlines.test.js
+++ b/js_tests/admin/inlines.test.js
@@ -11,7 +11,7 @@ QUnit.module('admin.inlines: tabular formsets', {
$('#qunit-fixture').append($('#tabular-formset').text());
this.table = $('table.inline');
this.inlineRow = this.table.find('tr');
- that.inlineRow.tabularFormset('table.inline tr', {
+ this.inlineRow.tabularFormset('table.inline tr.form-row', {
prefix: 'first',
addText: that.addText,
deleteText: 'Remove'
@@ -31,6 +31,13 @@ QUnit.test('add form', function(assert) {
assert.ok(this.table.find('#first-1').hasClass('row2'));
});
+QUnit.test('added form has remove button', function(assert) {
+ var addButton = this.table.find('.add-row a');
+ assert.equal(addButton.text(), this.addText);
+ addButton.click();
+ assert.equal(this.table.find('#first-1.row2 .inline-deletelink').length, 1);
+});
+
QUnit.test('add/remove form events', function(assert) {
assert.expect(6);
var $ = django.jQuery;
@@ -49,7 +56,7 @@ QUnit.test('add/remove form events', function(assert) {
assert.equal(true, $row.is(deletedRow));
assert.equal(formsetName, 'first');
});
- deleteLink.click();
+ deleteLink.trigger($.Event('click', {target: deleteLink}));
});
QUnit.test('existing add button', function(assert) {
@@ -69,3 +76,120 @@ QUnit.test('existing add button', function(assert) {
addButton.click();
assert.ok(this.table.find('#first-1').hasClass('row2'));
});
+
+
+QUnit.module('admin.inlines: tabular formsets with validation errors', {
+ beforeEach: function() {
+ var $ = django.jQuery;
+
+ $('#qunit-fixture').append($('#tabular-formset-with-validation-error').text());
+ this.table = $('table.inline');
+ this.inlineRows = this.table.find('tr.form-row');
+ this.inlineRows.tabularFormset('table.inline tr.form-row', {
+ prefix: 'second'
+ });
+ }
+});
+
+QUnit.test('first form has delete checkbox and no button', function(assert) {
+ var tr = this.inlineRows.slice(0, 1);
+ assert.ok(tr.hasClass('dynamic-second'));
+ assert.ok(tr.hasClass('has_original'));
+ assert.equal(tr.find('td.delete input').length, 1);
+ assert.equal(tr.find('td.delete .inline-deletelink').length, 0);
+});
+
+QUnit.test('dynamic form has remove button', function(assert) {
+ var tr = this.inlineRows.slice(1, 2);
+ assert.ok(tr.hasClass('dynamic-second'));
+ assert.notOk(tr.hasClass('has_original'));
+ assert.equal(tr.find('.inline-deletelink').length, 1);
+});
+
+QUnit.test('dynamic template has nothing', function(assert) {
+ var tr = this.inlineRows.slice(2, 3);
+ assert.ok(tr.hasClass('empty-form'));
+ assert.notOk(tr.hasClass('dynamic-second'));
+ assert.notOk(tr.hasClass('has_original'));
+ assert.equal(tr.find('td.delete')[0].innerHTML, '');
+});
+
+QUnit.test('removing a form-row also removed related row with non-field errors', function(assert) {
+ var $ = django.jQuery;
+ assert.ok(this.table.find('.row-form-errors').length);
+ var tr = this.inlineRows.slice(1, 2);
+ var trWithErrors = tr.prev();
+ assert.ok(trWithErrors.hasClass('row-form-errors'));
+ var deleteLink = tr.find('a.inline-deletelink');
+ deleteLink.trigger($.Event('click', {target: deleteLink}));
+ assert.notOk(this.table.find('.row-form-errors').length);
+});
+
+QUnit.test('removing and adding a row keeps cycling row1 and row2 classes', function(assert) {
+ var $ = django.jQuery;
+ var tr = this.inlineRows.slice(1, 2);
+ var deleteLink = tr.find('a.inline-deletelink');
+ var addLink = this.table.find('.add-row > td > a');
+ assert.ok(this.table.find('tr.form-row:even').hasClass('row1'));
+ assert.ok(this.table.find('tr.form-row:odd').hasClass('row2'));
+ deleteLink.trigger($.Event('click', {target: deleteLink}));
+ assert.ok(this.table.find('tr.form-row:even').hasClass('row1'));
+ assert.ok(this.table.find('tr.form-row:odd').hasClass('row2'));
+ addLink.trigger($.Event('click', {target: addLink}));
+ assert.ok(this.table.find('tr.form-row:even').hasClass('row1'));
+ assert.ok(this.table.find('tr.form-row:odd').hasClass('row2'));
+});
+
+
+QUnit.module('admin.inlines: tabular formsets with max_num', {
+ beforeEach: function() {
+ var $ = django.jQuery;
+ $('#qunit-fixture').append($('#tabular-formset-with-validation-error').text());
+ this.table = $('table.inline');
+ this.maxNum = $('input.id_second-MAX_NUM_FORMS');
+ this.maxNum.val(2);
+ this.inlineRows = this.table.find('tr.form-row');
+ this.inlineRows.tabularFormset('table.inline tr.form-row', {
+ prefix: 'second'
+ });
+ }
+});
+
+QUnit.test('does not show the add button if already at max_num', function(assert) {
+ var addButton = this.table.find('tr.add_row > td > a');
+ assert.notOk(addButton.is(':visible'));
+});
+
+QUnit.test('make addButton visible again', function(assert) {
+ var $ = django.jQuery;
+ var addButton = this.table.find('tr.add_row > td > a');
+ var removeButton = this.table.find('tr.form-row:first').find('a.inline-deletelink');
+ removeButton.trigger($.Event( "click", { target: removeButton } ));
+ assert.notOk(addButton.is(':visible'));
+});
+
+
+QUnit.module('admin.inlines: tabular formsets with min_num', {
+ beforeEach: function() {
+ var $ = django.jQuery;
+ $('#qunit-fixture').append($('#tabular-formset-with-validation-error').text());
+ this.table = $('table.inline');
+ this.minNum = $('input#id_second-MIN_NUM_FORMS');
+ this.minNum.val(2);
+ this.inlineRows = this.table.find('tr.form-row');
+ this.inlineRows.tabularFormset('table.inline tr.form-row', {
+ prefix: 'second'
+ });
+ }
+});
+
+QUnit.test('does not show the remove buttons if already at min_num', function(assert) {
+ assert.notOk(this.table.find('.inline-deletelink:visible').length);
+});
+
+QUnit.test('make removeButtons visible again', function(assert) {
+ var $ = django.jQuery;
+ var addButton = this.table.find('tr.add-row > td > a');
+ addButton.trigger($.Event( "click", { target: addButton } ));
+ assert.equal(this.table.find('.inline-deletelink:visible').length, 2);
+});
diff --git a/js_tests/tests.html b/js_tests/tests.html
index a2342883ec..988b7e3a4c 100644
--- a/js_tests/tests.html
+++ b/js_tests/tests.html
@@ -28,18 +28,56 @@
<input id="id_first-TOTAL_FORMS" value="1">
<input id="id_first-MAX_NUM_FORMS" value="">
<table class="inline">
- <tr id="first-0" class="form-row">
+ <tr id="first-0" class="form-row row1">
<td class="field-test_field">
- <input id="id_first-test_field">
+ <input id="id_first-0-test_field">
</td>
</tr>
- <tr id="first-empty" class="empty-row">
+ <tr id="first-empty" class="form-row empty-form">
<td class="field-test_field">
- <input id="id_first-test_field">
+ <input id="id_first-__prefix__-test_field">
</td>
</tr>
</table>
</script>
+ <script type="text/html" id="tabular-formset-with-validation-error">
+ <div class="inline-group">
+ <div class="tabular inline-related">
+ <input id="id_second-TOTAL_FORMS" value="2">
+ <input id="id_second-MAX_NUM_FORMS" value="">
+ <input id="id_second-MIN_NUM_FORMS" value="">
+ <table class="inline">
+ <tr id="second-0" class="form-row has_original row1">
+ <td class="field-test_field">
+ <input id="id_second-0-test_field">
+ </td>
+ <td class="delete">
+ <input type="checkbox" />
+ </td>
+ </tr>
+ <tr class="row-form-errors">
+ <td colspan="2">
+ <ul class="errorlist nonfield">
+ <li>This next form has non-field errors.</li>
+ </ul>
+ </td>
+ </tr>
+ <tr id="second-1" class="form-row row2">
+ <td class="field-test_field">
+ <input id="id_second-1-test_field">
+ </td>
+ <td class="delete"></td>
+ </tr>
+ <tr id="second-empty" class="form-row empty-form">
+ <td class="field-test_field">
+ <input id="id_second-__prefix__-test_field">
+ </td>
+ <td class="delete"></td>
+ </tr>
+ </table>
+ </div>
+ </div>
+ </script>
<script src="./qunit/qunit.js"></script>