mirror of
https://github.com/yiisoft/yii2.git
synced 2025-08-26 06:15:19 +08:00
Additionally added tests for #10302 (#10284 (comment)), #10284 (#10217 (comment)), #11729
This commit is contained in:

committed by
Alexander Makarov

parent
24dae19fc8
commit
8d813f7bf1
170
tests/js/data/yii.gridView.html
Normal file
170
tests/js/data/yii.gridView.html
Normal file
@ -0,0 +1,170 @@
|
||||
<!-- Filters for testing of multiple grid views -->
|
||||
|
||||
<div id="w-common-filters">
|
||||
<input name="PostSearch[id]" type="text">
|
||||
<input name="PostSearch[name]" type="text">
|
||||
</div>
|
||||
|
||||
<!-- The main setup -->
|
||||
|
||||
<div id="w0" class="grid-view">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><input id="w0-check-all" name="selection_all" value="1" type="checkbox"></th>
|
||||
<th>Name</th>
|
||||
<th>Category</th>
|
||||
<th>Tags</th>
|
||||
</tr>
|
||||
<tr id="w0-filters">
|
||||
<td> </td>
|
||||
<td><input id="w0-name" name="PostSearch[name]" type="text"></td>
|
||||
<td>
|
||||
<select id="w0-category" name="PostSearch[category_id]">
|
||||
<option value="" selected>None</option>
|
||||
<option value="1">Programming</option>
|
||||
<option value="2">Traveling</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<select id="w0-tags" name="PostSearch[tags][]" multiple>
|
||||
<option value="1">html</option>
|
||||
<option value="2">css</option>
|
||||
<option value="3">js</option>
|
||||
<option value="4">php</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr data-key="1">
|
||||
<td><input class="w0-check-row" name="selection[]" value="1" type="checkbox"></td>
|
||||
<td>Name 1</td>
|
||||
<td>Programming</td>
|
||||
<td>html, css</td>
|
||||
</tr>
|
||||
<tr data-key="2">
|
||||
<td><input class="w0-check-row" name="selection[]" value="2" type="checkbox"></td>
|
||||
<td>Name 2</td>
|
||||
<td>Programming</td>
|
||||
<td>js</td>
|
||||
</tr>
|
||||
<tr data-key="3">
|
||||
<td><input class="w0-check-row" name="selection[]" value="3" type="checkbox"></td>
|
||||
<td>Name 3</td>
|
||||
<td>Programming</td>
|
||||
<td>php</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- The basic setup, used for testing of multiple grid views -->
|
||||
|
||||
<div id="w1" class="grid-view">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><input name="selection_all" value="1" type="checkbox"></th>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
</tr>
|
||||
<tr id="w1-filters">
|
||||
<td> </td>
|
||||
<td><input name="PostSearch[id]" type="text"></td>
|
||||
<td><input name="PostSearch[name]" type="text"></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr data-key="1">
|
||||
<td><input name="selection[]" value="1" type="checkbox"></td>
|
||||
<td>1</td>
|
||||
<td>Name 1</td>
|
||||
</tr>
|
||||
<tr data-key="2">
|
||||
<td><input name="selection[]" value="2" type="checkbox"></td>
|
||||
<td>2</td>
|
||||
<td>Name 2</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- https://github.com/yiisoft/yii2/pull/10284 -->
|
||||
|
||||
<div id="w2">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Tags</th>
|
||||
</tr>
|
||||
<tr id="w2-filters">
|
||||
<td><input name="PostSearch[name]" type="text"></td>
|
||||
<td>
|
||||
<input type="hidden" name="PostSearch[tags]" value="-1">
|
||||
<select id="w2-tags" name="PostSearch[tags][]" multiple>
|
||||
<option value="1">html</option>
|
||||
<option value="2">css</option>
|
||||
<option value="3">js</option>
|
||||
<option value="4">php</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr data-key="1">
|
||||
<td>Name 1</td>
|
||||
<td>html, css</td>
|
||||
</tr>
|
||||
<tr data-key="2">
|
||||
<td>Name 2</td>
|
||||
<td>js</td>
|
||||
</tr>
|
||||
<tr data-key="3">
|
||||
<td>Name 3</td>
|
||||
<td>php</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Setup for testing that event handlers are correctly removed with new selectors -->
|
||||
|
||||
<div id="w3">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<input name="selection_all" value="1" type="checkbox">
|
||||
<input name="selection_all2" value="1" type="checkbox">
|
||||
</th>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
</tr>
|
||||
<tr id="w3-filters">
|
||||
<td> </td>
|
||||
<td><input name="PostSearch[id]" type="text"></td>
|
||||
<td><input name="PostSearch[name]" type="text"></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr data-key="1">
|
||||
<td>
|
||||
<input class="w3-check-row" name="selection[]" value="1" type="checkbox">
|
||||
<input name="selection2[]" value="1" type="checkbox">
|
||||
</td>
|
||||
<td>1</td>
|
||||
<td>Name 1</td>
|
||||
</tr>
|
||||
<tr data-key="2">
|
||||
<td>
|
||||
<input class="w3-check-row" name="selection[]" value="2" type="checkbox">
|
||||
<input name="selection2[]" value="2" type="checkbox">
|
||||
</td>
|
||||
<td>2</td>
|
||||
<td>Name 2</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
754
tests/js/tests/yii.gridView.test.js
Normal file
754
tests/js/tests/yii.gridView.test.js
Normal file
@ -0,0 +1,754 @@
|
||||
var assert = require('chai').assert;
|
||||
var sinon;
|
||||
var withData = require('leche').withData;
|
||||
var jsdom = require('mocha-jsdom');
|
||||
|
||||
var fs = require('fs');
|
||||
var vm = require('vm');
|
||||
|
||||
describe('yii.gridView', function () {
|
||||
var yiiGridViewPath = 'framework/assets/yii.gridView.js';
|
||||
var yiiPath = 'framework/assets/yii.js';
|
||||
var jQueryPath = 'vendor/bower/jquery/dist/jquery.js';
|
||||
var $;
|
||||
var $gridView;
|
||||
var settings = {
|
||||
filterUrl: '/posts/index',
|
||||
filterSelector: '#w0-filters input, #w0-filters select'
|
||||
};
|
||||
var commonSettings = {
|
||||
filterUrl: '/posts/index',
|
||||
filterSelector: '#w-common-filters input, #w-common-filters select'
|
||||
};
|
||||
var $textInput;
|
||||
var $select;
|
||||
var $multipleSelect;
|
||||
var $listBox;
|
||||
var $checkAllCheckbox;
|
||||
var $checkRowCheckboxes;
|
||||
|
||||
function registerYii() {
|
||||
var code = fs.readFileSync(yiiPath);
|
||||
var script = new vm.Script(code);
|
||||
var sandbox = {window: window, jQuery: $};
|
||||
var context = new vm.createContext(sandbox);
|
||||
script.runInContext(context);
|
||||
return sandbox.window.yii;
|
||||
}
|
||||
|
||||
function registerTestableCode() {
|
||||
var yii = registerYii();
|
||||
var code = fs.readFileSync(yiiGridViewPath);
|
||||
var script = new vm.Script(code);
|
||||
var context = new vm.createContext({window: window, document: window.document, yii: yii});
|
||||
script.runInContext(context);
|
||||
}
|
||||
|
||||
var gridViewHtml = fs.readFileSync('tests/js/data/yii.gridView.html', 'utf-8');
|
||||
var html = '<!doctype html><html><head><meta charset="utf-8"></head><body>' + gridViewHtml + '</body></html>';
|
||||
|
||||
jsdom({
|
||||
html: html,
|
||||
src: fs.readFileSync(jQueryPath, 'utf-8')
|
||||
});
|
||||
|
||||
before(function () {
|
||||
$ = window.$;
|
||||
registerTestableCode();
|
||||
sinon = require('sinon');
|
||||
});
|
||||
|
||||
beforeEach(function () {
|
||||
$textInput = $('#w0-name');
|
||||
$select = $('#w0-category');
|
||||
$multipleSelect = $('#w0-tags');
|
||||
$listBox = $('#w2-tags');
|
||||
$checkAllCheckbox = $('#w0-check-all');
|
||||
$checkRowCheckboxes = $('.w0-check-row');
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
if ($gridView.length) {
|
||||
$gridView.yiiGridView('destroy');
|
||||
}
|
||||
$textInput.val('');
|
||||
$select.val('');
|
||||
$multipleSelect.find('option:selected').prop('selected', false);
|
||||
$listBox.find('option:selected').prop('selected', false);
|
||||
$checkAllCheckbox.prop('checked', false);
|
||||
$checkRowCheckboxes.prop('checked', false);
|
||||
});
|
||||
|
||||
/**
|
||||
* Simulate pressing "Enter" button while focused on some element
|
||||
* @param $el
|
||||
*/
|
||||
function pressEnter($el) {
|
||||
var e = $.Event('keydown', {keyCode: 13});
|
||||
$el.trigger(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate pressing keyboard button while focused on the text input. For simplicity, intended to use with letter
|
||||
* buttons, such as "a", "b", etc. Case insensitive.
|
||||
* @param $el
|
||||
* @param buttonName
|
||||
*/
|
||||
function pressButton($el, buttonName) {
|
||||
$el.val(buttonName);
|
||||
var keyCode = buttonName.charCodeAt(0);
|
||||
var e = $.Event('keydown', {keyCode: keyCode});
|
||||
$el.trigger(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate changing value in the select
|
||||
* @param $el
|
||||
* @param value
|
||||
*/
|
||||
function changeValue($el, value) {
|
||||
$el.val(value);
|
||||
var e = $.Event('change');
|
||||
$el.trigger(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate losing focus of the element after the value was changed
|
||||
* @param $el
|
||||
*/
|
||||
function loseFocus($el) {
|
||||
var e = $.Event('change');
|
||||
$el.trigger(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate click in the checkbox
|
||||
* @param $el
|
||||
*/
|
||||
function click($el) {
|
||||
var e = $.Event('click');
|
||||
$el.trigger(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate hovering on the new value and pressing "Enter" button in the select
|
||||
* @param $el
|
||||
*/
|
||||
function hoverAndPressEnter($el) {
|
||||
pressEnter($el);
|
||||
// After pressing enter while hovering the value will be immediately changed as well like with losing focus
|
||||
loseFocus($el);
|
||||
}
|
||||
|
||||
describe('init', function () {
|
||||
var customSettings = {
|
||||
filterUrl: '/posts/filter',
|
||||
filterSelector: '#w-common-filters input'
|
||||
};
|
||||
|
||||
withData({
|
||||
'no method specified': [function () {
|
||||
$gridView = $('.grid-view').yiiGridView(commonSettings);
|
||||
}, commonSettings],
|
||||
'no method specified, custom settings': [function () {
|
||||
$gridView = $('.grid-view').yiiGridView(customSettings);
|
||||
}, customSettings],
|
||||
'manual method call': [function () {
|
||||
$gridView = $('.grid-view').yiiGridView('init', commonSettings);
|
||||
}, commonSettings]
|
||||
}, function (initFunction, expectedSettings) {
|
||||
it('should save settings for all elements', function () {
|
||||
initFunction();
|
||||
assert.deepEqual($('#w0').yiiGridView('data'), {settings: expectedSettings});
|
||||
assert.deepEqual($('#w1').yiiGridView('data'), {settings: expectedSettings});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with repeated call', function () {
|
||||
var jQuerySubmitStub;
|
||||
|
||||
before(function () {
|
||||
jQuerySubmitStub = sinon.stub($.fn, 'submit');
|
||||
});
|
||||
|
||||
after(function () {
|
||||
jQuerySubmitStub.restore();
|
||||
});
|
||||
|
||||
it('should remove "filter" event handler', function () {
|
||||
$gridView = $('#w0').yiiGridView(settings);
|
||||
$gridView.yiiGridView(settings);
|
||||
// Change selector to make sure event handlers are removed regardless of the selector
|
||||
$gridView.yiiGridView({
|
||||
filterUrl: '/posts/index',
|
||||
filterSelector: '#w0-filters select'
|
||||
});
|
||||
|
||||
pressEnter($textInput);
|
||||
assert.isFalse(jQuerySubmitStub.called);
|
||||
|
||||
changeValue($select, 1);
|
||||
assert.isTrue(jQuerySubmitStub.calledOnce);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('applyFilter', function () {
|
||||
var jQuerySubmit = function () {
|
||||
};
|
||||
var jQuerySubmitStub;
|
||||
|
||||
beforeEach(function () {
|
||||
jQuerySubmitStub = sinon.stub($.fn, 'submit', jQuerySubmit);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
jQuerySubmitStub.restore();
|
||||
});
|
||||
|
||||
describe('with beforeFilter returning not false', function () {
|
||||
var calledMethods = []; // For testing the order of called methods
|
||||
var beforeFilterSpy;
|
||||
var afterFilterSpy;
|
||||
|
||||
before(function () {
|
||||
jQuerySubmit = function () {
|
||||
calledMethods.push('submit');
|
||||
|
||||
return this;
|
||||
};
|
||||
beforeFilterSpy = sinon.spy(function () {
|
||||
calledMethods.push('beforeFilter');
|
||||
});
|
||||
afterFilterSpy = sinon.spy(function () {
|
||||
calledMethods.push('afterFilter');
|
||||
});
|
||||
});
|
||||
|
||||
after(function () {
|
||||
jQuerySubmit = function () {
|
||||
};
|
||||
beforeFilterSpy.reset();
|
||||
afterFilterSpy.reset();
|
||||
calledMethods = [];
|
||||
});
|
||||
|
||||
var message = 'should send the request to correct url with correct parameters and apply events in ' +
|
||||
'correct order';
|
||||
it(message, function () {
|
||||
$gridView = $('#w0').yiiGridView(settings)
|
||||
.on('beforeFilter', beforeFilterSpy)
|
||||
.on('afterFilter', afterFilterSpy);
|
||||
|
||||
$textInput.val('a');
|
||||
$select.val(1);
|
||||
$multipleSelect.find('option[value="1"]').prop('selected', true);
|
||||
$multipleSelect.find('option[value="2"]').prop('selected', true);
|
||||
|
||||
$gridView.yiiGridView('applyFilter');
|
||||
|
||||
var expectedHtml = '<form action="/posts/index" method="get" class="gridview-filter-form" ' +
|
||||
'style="display:none" data-pjax="">' +
|
||||
'<input type="hidden" name="PostSearch[name]" value="a">' +
|
||||
'<input type="hidden" name="PostSearch[category_id]" value="1">' +
|
||||
'<input type="hidden" name="PostSearch[tags][]" value="1">' +
|
||||
'<input type="hidden" name="PostSearch[tags][]" value="2">' +
|
||||
'</form>';
|
||||
var $form = $('.grid-view .gridview-filter-form');
|
||||
assert.equal($form.get(0).outerHTML, expectedHtml);
|
||||
|
||||
assert.isTrue(beforeFilterSpy.calledOnce);
|
||||
assert.instanceOf(beforeFilterSpy.getCall(0).args[0], $.Event);
|
||||
assert.equal($(beforeFilterSpy.getCall(0).args[0].target).attr('id'), $gridView.attr('id'));
|
||||
|
||||
assert.isTrue(jQuerySubmitStub.calledOnce);
|
||||
assert.equal(jQuerySubmitStub.returnValues[0].attr('class'), 'gridview-filter-form');
|
||||
|
||||
assert.isTrue(afterFilterSpy.calledOnce);
|
||||
assert.instanceOf(afterFilterSpy.getCall(0).args[0], $.Event);
|
||||
assert.equal($(afterFilterSpy.getCall(0).args[0].target).attr('id'), $gridView.attr('id'));
|
||||
|
||||
assert.deepEqual(calledMethods, ['beforeFilter', 'submit', 'afterFilter']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with beforeFilter returning false', function () {
|
||||
var beforeFilterSpy;
|
||||
var afterFilterSpy;
|
||||
|
||||
before(function () {
|
||||
beforeFilterSpy = sinon.spy(function () {
|
||||
return false;
|
||||
});
|
||||
afterFilterSpy = sinon.spy();
|
||||
});
|
||||
|
||||
after(function () {
|
||||
beforeFilterSpy.reset();
|
||||
afterFilterSpy.reset();
|
||||
});
|
||||
|
||||
it('should prevent from sending request and triggering "afterFilter" event', function () {
|
||||
$gridView = $('#w0').yiiGridView(settings)
|
||||
.on('beforeFilter', beforeFilterSpy)
|
||||
.on('afterFilter', afterFilterSpy);
|
||||
$gridView.yiiGridView('applyFilter');
|
||||
|
||||
assert.isTrue(beforeFilterSpy.calledOnce);
|
||||
assert.isFalse(jQuerySubmitStub.called);
|
||||
assert.isFalse(afterFilterSpy.called);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with different urls', function () {
|
||||
describe('with no filter data sent', function () {
|
||||
withData({
|
||||
'query parameters': [
|
||||
'/posts/index?foo=1&bar=2',
|
||||
'/posts/index',
|
||||
'PostSearch[name]=&PostSearch[category_id]=&foo=1&bar=2'
|
||||
],
|
||||
// https://github.com/yiisoft/yii2/pull/10302
|
||||
'query parameter with multiple values (not array)': [
|
||||
'/posts/index?foo=1&foo=2',
|
||||
'/posts/index',
|
||||
'PostSearch[name]=&PostSearch[category_id]=&foo=1&foo=2'
|
||||
],
|
||||
'query parameter with multiple values (array)': [
|
||||
'/posts/index?foo[]=1&foo[]=2',
|
||||
'/posts/index',
|
||||
'PostSearch[name]=&PostSearch[category_id]=&foo[]=1&foo[]=2'
|
||||
],
|
||||
// https://github.com/yiisoft/yii2/issues/12836
|
||||
'anchor': [
|
||||
'/posts/index#post',
|
||||
'/posts/index#post',
|
||||
'PostSearch[name]=&PostSearch[category_id]='
|
||||
],
|
||||
'query parameters, anchor': [
|
||||
'/posts/index?foo=1&bar=2#post',
|
||||
'/posts/index#post',
|
||||
'PostSearch[name]=&PostSearch[category_id]=&foo=1&bar=2'
|
||||
],
|
||||
'relative url, query parameters': [
|
||||
'?foo=1&bar=2',
|
||||
'',
|
||||
'PostSearch[name]=&PostSearch[category_id]=&foo=1&bar=2'
|
||||
],
|
||||
'relative url, anchor': [
|
||||
'#post',
|
||||
'#post',
|
||||
'PostSearch[name]=&PostSearch[category_id]='
|
||||
],
|
||||
'relative url, query parameters, anchor': [
|
||||
'?foo=1&bar=2#post',
|
||||
'#post',
|
||||
'PostSearch[name]=&PostSearch[category_id]=&foo=1&bar=2'
|
||||
]
|
||||
}, function (filterUrl, expectedUrl, expectedQueryString) {
|
||||
it('should send the request to correct url with correct parameters', function () {
|
||||
var customSettings = $.extend({}, settings, {filterUrl: filterUrl});
|
||||
$gridView = $('#w0').yiiGridView(customSettings);
|
||||
$gridView.yiiGridView('applyFilter');
|
||||
|
||||
var $form = $gridView.find('.gridview-filter-form');
|
||||
assert.isTrue(jQuerySubmitStub.calledOnce);
|
||||
assert.equal($form.attr('action'), expectedUrl);
|
||||
assert.equal(decodeURIComponent($form.serialize()), expectedQueryString);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// https://github.com/yiisoft/yii2/pull/10302
|
||||
|
||||
describe('with filter data sent', function () {
|
||||
it('should send the request to correct url with new parameter values', function () {
|
||||
var filterUrl = '/posts/index?CategorySearch[id]=5&CategorySearch[name]=c' +
|
||||
'&PostSearch[name]=a&PostSearch[category_id]=1&PostSearch[tags][]=1&PostSearch[tags][]=2' +
|
||||
'&foo[]=1&foo[]=2&bar=1#post';
|
||||
var customSettings = $.extend({}, settings, {filterUrl: filterUrl});
|
||||
$gridView = $('#w0').yiiGridView(customSettings);
|
||||
|
||||
$textInput.val('b');
|
||||
$select.val('1'); // Leave value as is (simulate setting "selected" in HTML)
|
||||
$multipleSelect.find('option[value="2"]').prop('selected', true);
|
||||
$multipleSelect.find('option[value="3"]').prop('selected', true);
|
||||
|
||||
$gridView.yiiGridView('applyFilter');
|
||||
|
||||
var $form = $gridView.find('.gridview-filter-form');
|
||||
assert.isTrue(jQuerySubmitStub.calledOnce);
|
||||
assert.equal($form.attr('action'), '/posts/index#post');
|
||||
// Parameters not related with current filter are appended to the end
|
||||
var expectedQueryString = 'PostSearch[name]=b&PostSearch[category_id]=1' +
|
||||
'&PostSearch[tags][]=2&PostSearch[tags][]=3' +
|
||||
'&CategorySearch[id]=5&CategorySearch[name]=c' +
|
||||
'&foo[]=1&foo[]=2&bar=1';
|
||||
assert.equal(decodeURIComponent($form.serialize()), expectedQueryString);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// https://github.com/yiisoft/yii2/pull/10284
|
||||
|
||||
describe('with list box', function () {
|
||||
var queryString = 'PostSearch[name]=&PostSearch[tags]=-1&PostSearch[tags][]=1&PostSearch[tags][]=2';
|
||||
|
||||
beforeEach(function () {
|
||||
$listBox.find('option[value="1"]').prop('selected', true);
|
||||
$listBox.find('option[value="2"]').prop('selected', true);
|
||||
});
|
||||
|
||||
describe('with values selected', function () {
|
||||
it('should send the request to correct url with correct parameters', function () {
|
||||
$gridView = $('#w2').yiiGridView({
|
||||
filterUrl: '/posts/index',
|
||||
filterSelector: '#w2-filters input, #w2-filters select'
|
||||
});
|
||||
$gridView.yiiGridView('applyFilter');
|
||||
|
||||
var $form = $gridView.find('.gridview-filter-form');
|
||||
assert.equal($form.attr('action'), '/posts/index');
|
||||
assert.equal(decodeURIComponent($form.serialize()), queryString);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with unselected values after applied filter', function () {
|
||||
it('should send the request to correct url with correct parameters', function () {
|
||||
$gridView = $('#w2').yiiGridView({
|
||||
filterUrl: '/posts/index/?' + queryString,
|
||||
filterSelector: '#w2-filters input, #w2-filters select'
|
||||
});
|
||||
$listBox.find('option:selected').prop('selected', false);
|
||||
$gridView.yiiGridView('applyFilter');
|
||||
|
||||
var $form = $gridView.find('.gridview-filter-form');
|
||||
assert.equal($form.attr('action'), '/posts/index/');
|
||||
assert.equal(decodeURIComponent($form.serialize()), 'PostSearch[name]=&PostSearch[tags]=-1');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with repeated method call', function () {
|
||||
it('should delete the hidden form', function () {
|
||||
$gridView = $('#w0').yiiGridView(settings);
|
||||
$gridView.yiiGridView('applyFilter');
|
||||
$gridView.yiiGridView('applyFilter');
|
||||
|
||||
var $form = $gridView.find('.gridview-filter-form');
|
||||
assert.lengthOf($form, 1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with filter event handlers', function () {
|
||||
beforeEach(function () {
|
||||
$gridView = $('#w0').yiiGridView(settings);
|
||||
});
|
||||
|
||||
describe('with text entered in the text input', function () {
|
||||
it('should not submit form', function () {
|
||||
pressButton($textInput, 'a');
|
||||
assert.isFalse(jQuerySubmitStub.called);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with "Enter" pressed in the text input', function () {
|
||||
it('should submit form once', function () {
|
||||
pressEnter($textInput);
|
||||
assert.isTrue(jQuerySubmitStub.calledOnce);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with text entered in the text input and lost focus', function () {
|
||||
it('should submit form once', function () {
|
||||
pressButton($textInput, 'a');
|
||||
loseFocus($textInput);
|
||||
|
||||
assert.isTrue(jQuerySubmitStub.calledOnce);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with value changed in the select', function () {
|
||||
it('should submit form once', function () {
|
||||
changeValue($select, 1);
|
||||
assert.isTrue(jQuerySubmitStub.calledOnce);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with hover on different value and "Enter" pressed in select', function () {
|
||||
it('should submit form once', function () {
|
||||
// Simulate hovering on new value and pressing "Enter"
|
||||
$select.val(1);
|
||||
hoverAndPressEnter($select);
|
||||
|
||||
assert.isTrue(jQuerySubmitStub.calledOnce);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('setSelectionColumn method', function () {
|
||||
describe('with name option and', function () {
|
||||
withData({
|
||||
'nothing else': [{}],
|
||||
'checkAll option': [{checkAll: 'selection_all'}],
|
||||
'multiple option set to true': [{multiple: true}],
|
||||
'multiple and checkAll options, multiple set to false': [{multiple: false, checkAll: 'selection_all'}]
|
||||
}, function (customOptions) {
|
||||
it('should update data and do not activate "check all" functionality', function () {
|
||||
$gridView = $('#w0').yiiGridView(settings);
|
||||
|
||||
var defaultOptions = {name: 'selection[]'};
|
||||
var options = $.extend({}, defaultOptions, customOptions);
|
||||
$gridView.yiiGridView('setSelectionColumn', options);
|
||||
|
||||
assert.equal($gridView.yiiGridView('data').selectionColumn, 'selection[]');
|
||||
|
||||
click($checkAllCheckbox);
|
||||
assert.lengthOf($checkRowCheckboxes.filter(':checked'), 0);
|
||||
|
||||
click($checkAllCheckbox); // Back to initial condition
|
||||
click($checkRowCheckboxes);
|
||||
assert.isFalse($checkAllCheckbox.prop('checked'));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with name, multiple and checkAll options, multiple set to true and', function () {
|
||||
withData({
|
||||
'nothing else': [{}],
|
||||
// https://github.com/yiisoft/yii2/pull/11729
|
||||
'class option': [{'class': 'w0-check-row'}]
|
||||
}, function (customOptions) {
|
||||
it('should update data and "check all" functionality should work', function () {
|
||||
$gridView = $('#w0').yiiGridView(settings);
|
||||
|
||||
var defaultOptions = {name: 'selection[]', multiple: true, checkAll: 'selection_all'};
|
||||
var options = $.extend({}, defaultOptions, customOptions);
|
||||
$gridView.yiiGridView('setSelectionColumn', options);
|
||||
|
||||
assert.equal($gridView.yiiGridView('data').selectionColumn, 'selection[]');
|
||||
|
||||
var $checkFirstRowCheckbox = $checkRowCheckboxes.filter('[value="1"]');
|
||||
|
||||
// Check all
|
||||
click($checkAllCheckbox);
|
||||
assert.lengthOf($checkRowCheckboxes.filter(':checked'), 3);
|
||||
assert.isTrue($checkAllCheckbox.prop('checked'));
|
||||
|
||||
// Uncheck all
|
||||
click($checkAllCheckbox);
|
||||
assert.lengthOf($checkRowCheckboxes.filter(':checked'), 0);
|
||||
assert.isFalse($checkAllCheckbox.prop('checked'));
|
||||
|
||||
// Check all manually
|
||||
click($checkRowCheckboxes);
|
||||
assert.lengthOf($checkRowCheckboxes.filter(':checked'), 3);
|
||||
assert.isTrue($checkAllCheckbox.prop('checked'));
|
||||
|
||||
// Uncheck all manually
|
||||
click($checkRowCheckboxes);
|
||||
assert.lengthOf($checkRowCheckboxes.filter(':checked'), 0);
|
||||
assert.isFalse($checkAllCheckbox.prop('checked'));
|
||||
|
||||
// Check first row
|
||||
click($checkFirstRowCheckbox);
|
||||
assert.isTrue($checkFirstRowCheckbox.prop('checked'));
|
||||
assert.lengthOf($checkRowCheckboxes.filter(':checked'), 1);
|
||||
assert.isFalse($checkAllCheckbox.prop('checked'));
|
||||
|
||||
// Then check all
|
||||
click($checkAllCheckbox);
|
||||
assert.lengthOf($checkRowCheckboxes.filter(':checked'), 3);
|
||||
assert.isTrue($checkAllCheckbox.prop('checked'));
|
||||
|
||||
// Uncheck first row
|
||||
click($checkFirstRowCheckbox);
|
||||
assert.isFalse($checkFirstRowCheckbox.prop('checked'));
|
||||
assert.lengthOf($checkRowCheckboxes.filter(':checked'), 2);
|
||||
assert.isFalse($checkAllCheckbox.prop('checked'));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with repeated calls', function () {
|
||||
var jQueryPropStub;
|
||||
|
||||
before(function () {
|
||||
jQueryPropStub = sinon.stub($, 'prop');
|
||||
});
|
||||
|
||||
after(function () {
|
||||
jQueryPropStub.restore();
|
||||
});
|
||||
|
||||
it('should not duplicate event handler calls', function () {
|
||||
$gridView = $('#w3').yiiGridView({
|
||||
filterUrl: '/posts/index',
|
||||
filterSelector: '#w3-filters input, #w3-filters select'
|
||||
});
|
||||
|
||||
$gridView.yiiGridView('setSelectionColumn', {
|
||||
name: 'selection[]',
|
||||
multiple: true,
|
||||
checkAll: 'selection_all'
|
||||
});
|
||||
// Change selectors to make sure event handlers are removed regardless of the selector
|
||||
$gridView.yiiGridView('setSelectionColumn', {
|
||||
name: 'selection2[]',
|
||||
multiple: true,
|
||||
checkAll: 'selection_all2'
|
||||
});
|
||||
$gridView.yiiGridView('setSelectionColumn', {
|
||||
name: 'selection[]',
|
||||
multiple: true,
|
||||
checkAll: 'selection_all'
|
||||
});
|
||||
$gridView.yiiGridView('setSelectionColumn', {
|
||||
'class': 'w3-check-row',
|
||||
multiple: true,
|
||||
checkAll: 'selection_all'
|
||||
});
|
||||
|
||||
// Check first row ("prop" should be called once)
|
||||
click($gridView.find('input[name="selection[]"][value="1"]'));
|
||||
// Check all rows ("prop" should be called 2 times, 1 time for each row)
|
||||
click($gridView.find('input[name="selection_all"]'));
|
||||
|
||||
assert.equal(jQueryPropStub.callCount, 3);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSelectedRows method', function () {
|
||||
withData({
|
||||
'selectionColumn not set, no rows selected': [undefined, [], false, []],
|
||||
'selectionColumn not set, 1st and 2nd rows selected': [undefined, [1, 2], false, []],
|
||||
'selectionColumn set, no rows selected': ['selection[]', [], false, []],
|
||||
'selectionColumn set, 1st row selected': ['selection[]', [1], false, [1]],
|
||||
'selectionColumn set, 1st and 2nd rows selected': ['selection[]', [1, 2], false, [1, 2]],
|
||||
'selectionColumn set, all rows selected, "Check all" checkbox checked': [
|
||||
'selection[]', [1, 2, 3], true, [1, 2, 3]
|
||||
]
|
||||
}, function (selectionColumn, selectedRows, checkAll, expectedSelectedRows) {
|
||||
it('should return array with ids of selected rows', function () {
|
||||
$gridView = $('#w0').yiiGridView(settings);
|
||||
$gridView.yiiGridView('setSelectionColumn', {name: selectionColumn});
|
||||
for (var i = 0; i < selectedRows.length; i++) {
|
||||
$checkRowCheckboxes.filter('[value="' + selectedRows[i] + '"]').prop('checked', true);
|
||||
}
|
||||
if (checkAll) {
|
||||
$checkAllCheckbox.prop('checked', true);
|
||||
}
|
||||
assert.deepEqual($gridView.yiiGridView('getSelectedRows'), expectedSelectedRows);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('destroy method', function () {
|
||||
var jQuerySubmitStub;
|
||||
var jQueryPropStub;
|
||||
var beforeFilterSpy;
|
||||
var afterFilterSpy;
|
||||
|
||||
beforeEach(function () {
|
||||
jQuerySubmitStub = sinon.stub($.fn, 'submit');
|
||||
jQueryPropStub = sinon.stub($, 'prop');
|
||||
beforeFilterSpy = sinon.spy();
|
||||
afterFilterSpy = sinon.spy();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
jQuerySubmitStub.restore();
|
||||
jQueryPropStub.restore();
|
||||
beforeFilterSpy.reset();
|
||||
afterFilterSpy.reset();
|
||||
});
|
||||
|
||||
it('should remove saved settings for destroyed element only and return initial jQuery object', function () {
|
||||
$gridView = $('.grid-view').yiiGridView(commonSettings);
|
||||
var $gridView1 = $('#w0');
|
||||
var $gridView2 = $('#w1');
|
||||
var destroyResult = $gridView1.yiiGridView('destroy');
|
||||
|
||||
assert.strictEqual(destroyResult, $gridView1);
|
||||
assert.isUndefined($gridView1.yiiGridView('data'));
|
||||
assert.deepEqual($gridView2.yiiGridView('data'), {settings: commonSettings});
|
||||
});
|
||||
|
||||
it('should remove "beforeFilter" and "afterFilter" event handlers for destroyed element only', function () {
|
||||
$gridView = $('.grid-view').yiiGridView(commonSettings)
|
||||
.on('beforeFilter', beforeFilterSpy)
|
||||
.on('afterFilter', afterFilterSpy);
|
||||
var $gridView1 = $('#w0');
|
||||
var $gridView2 = $('#w1');
|
||||
$gridView1.yiiGridView('destroy');
|
||||
|
||||
assert.throws(function () {
|
||||
$gridView1.yiiGridView('applyFilter');
|
||||
}, "Cannot read property 'settings' of undefined");
|
||||
$gridView1.yiiGridView(settings); // Reinitialize without "beforeFilter" and "afterFilter" event handlers
|
||||
|
||||
$gridView1.yiiGridView('applyFilter');
|
||||
assert.isTrue(jQuerySubmitStub.calledOnce);
|
||||
assert.isFalse(beforeFilterSpy.called);
|
||||
assert.isFalse(afterFilterSpy.called);
|
||||
|
||||
$gridView2.yiiGridView('applyFilter');
|
||||
assert.isTrue(jQuerySubmitStub.calledTwice);
|
||||
assert.isTrue(beforeFilterSpy.calledOnce);
|
||||
assert.isTrue(afterFilterSpy.calledOnce);
|
||||
});
|
||||
|
||||
it('should remove "filter" event handler for destroyed element only', function () {
|
||||
var $gridView1 = $('#w0');
|
||||
var $gridView2 = $('#w1');
|
||||
$gridView1.yiiGridView(settings);
|
||||
$gridView2.yiiGridView({
|
||||
filterUrl: '/posts/index',
|
||||
filterSelector: '#w1-filters input, #w1-filters select'
|
||||
});
|
||||
$gridView2.yiiGridView('destroy');
|
||||
|
||||
pressEnter($gridView2.find('input[name="PostSearch[id]"]'));
|
||||
assert.isFalse(jQuerySubmitStub.called);
|
||||
|
||||
pressEnter($textInput);
|
||||
assert.isTrue(jQuerySubmitStub.calledOnce);
|
||||
});
|
||||
|
||||
it('should remove "checkRow" and "checkAllRows" filter event handlers for destroyed element only', function () {
|
||||
$gridView = $('.grid-view').yiiGridView(commonSettings);
|
||||
var options = {name: 'selection[]', multiple: true, checkAll: 'selection_all'};
|
||||
var $gridView1 = $('#w0');
|
||||
var $gridView2 = $('#w1');
|
||||
$gridView1.yiiGridView('setSelectionColumn', options);
|
||||
$gridView2.yiiGridView('setSelectionColumn', options);
|
||||
$gridView2.yiiGridView('destroy');
|
||||
|
||||
click($gridView2.find('input[name="selection_all"]'));
|
||||
click($gridView2.find('input[name="selection[]"][value="1"]'));
|
||||
assert.equal(jQueryPropStub.callCount, 0);
|
||||
|
||||
click($checkRowCheckboxes.filter('[value="1"]')); // Check first row ("prop" should be called once)
|
||||
click($checkAllCheckbox); // Check all rows ("prop" should be called 3 times, 1 time for each row)
|
||||
assert.equal(jQueryPropStub.callCount, 4);
|
||||
});
|
||||
});
|
||||
|
||||
describe('data method', function () {
|
||||
it('should return saved settings', function () {
|
||||
$gridView = $('#w0').yiiGridView(settings);
|
||||
assert.deepEqual($gridView.yiiGridView('data'), {settings: settings});
|
||||
});
|
||||
});
|
||||
|
||||
describe('call of not existing method', function () {
|
||||
it('should throw according error', function () {
|
||||
$gridView = $('#w0').yiiGridView(settings);
|
||||
assert.throws(function () {
|
||||
$gridView.yiiGridView('foobar');
|
||||
}, 'Method foobar does not exist in jQuery.yiiGridView');
|
||||
});
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user