Skip to content

Commit 67ccb74

Browse files
committed
Merge remote-tracking branch 'origin/MAGETWO-54733' into BUGS
2 parents 5006d40 + 535db29 commit 67ccb74

File tree

8 files changed

+222
-8
lines changed

8 files changed

+222
-8
lines changed

app/code/Magento/Eav/Model/Entity/Attribute/Backend/ArrayBackend.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ public function validate($object)
4242
$data = $object->getData($attributeCode);
4343
if (is_array($data)) {
4444
$object->setData($attributeCode, implode(',', array_filter($data)));
45+
} elseif (empty($data)) {
46+
$object->setData($attributeCode, null);
4547
}
4648
return parent::validate($object);
4749
}

app/code/Magento/Eav/Test/Unit/Model/Entity/Attribute/Backend/ArrayTest.php renamed to app/code/Magento/Eav/Test/Unit/Model/Entity/Attribute/Backend/ArrayBackendTest.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66
namespace Magento\Eav\Test\Unit\Model\Entity\Attribute\Backend;
77

8-
class ArrayTest extends \PHPUnit_Framework_TestCase
8+
class ArrayBackendTest extends \PHPUnit_Framework_TestCase
99
{
1010
/**
1111
* @var \Magento\Eav\Model\Entity\Attribute\Backend\ArrayBackend
@@ -37,9 +37,10 @@ protected function setUp()
3737
public function testValidate($data)
3838
{
3939
$this->_attribute->expects($this->atLeastOnce())->method('getAttributeCode')->will($this->returnValue('code'));
40-
$product = new \Magento\Framework\DataObject(['code' => $data]);
40+
$product = new \Magento\Framework\DataObject(['code' => $data, 'empty' => '']);
4141
$this->_model->validate($product);
4242
$this->assertEquals('1,2,3', $product->getCode());
43+
$this->assertEquals(null, $product->getEmpty());
4344
}
4445

4546
public static function attributeValueDataProvider()

app/code/Magento/Ui/view/base/web/js/form/client.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ define([
2222
function beforeSave(data, url, selectorPrefix, messagesClass) {
2323
var save = $.Deferred();
2424

25-
data = utils.serialize(data);
26-
25+
data = utils.serialize(utils.filterFormData(data));
2726
data['form_key'] = window.FORM_KEY;
2827

2928
if (!url || url === 'undefined') {

app/code/Magento/Ui/view/base/web/js/form/element/multiselect.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ define([
1313
return Select.extend({
1414
defaults: {
1515
size: 5,
16-
elementTmpl: 'ui/form/element/multiselect'
16+
elementTmpl: 'ui/form/element/multiselect',
17+
listens: {
18+
value: 'setDifferedFromDefault setPrepareToSendData'
19+
}
1720
},
1821

1922
/**
@@ -38,6 +41,21 @@ define([
3841
return _.isString(value) ? value.split(',') : value;
3942
},
4043

44+
/**
45+
* Sets the prepared data to dataSource
46+
* by path, where key is component link to dataSource with
47+
* suffix "-prepared-for-send"
48+
*
49+
* @param {Array} data - current component value
50+
*/
51+
setPrepareToSendData: function (data) {
52+
if (!data.length) {
53+
data = '';
54+
}
55+
56+
this.source.set(this.dataScope + '-prepared-for-send', data);
57+
},
58+
4159
/**
4260
* @inheritdoc
4361
*/

dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/form/client.test.js

Lines changed: 98 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,22 @@
1010
define([
1111
'underscore',
1212
'uiRegistry',
13-
'Magento_Ui/js/form/client'
14-
], function (_, registry, Constr) {
13+
'Magento_Ui/js/form/client',
14+
'jquery',
15+
'mageUtils',
16+
'jquery/ui'
17+
], function (_, registry, Constr, $, utils) {
1518
'use strict';
1619

1720
describe('Magento_Ui/js/form/client', function () {
18-
1921
var obj = new Constr({
2022
provider: 'provName',
2123
name: '',
2224
index: ''
2325
});
2426

27+
window.FORM_KEY = 'magentoFormKey';
28+
2529
registry.set('provName', {
2630
on: function () {
2731
},
@@ -50,7 +54,98 @@ define([
5054

5155
expect(type).toEqual('object');
5256
});
57+
it('Check "beforeSave" method. ' +
58+
'Check calls "filterFormData", "serialize" and "ajax" inside themselves.', function () {
59+
var data = {
60+
key: {
61+
anotherKey: 'value'
62+
},
63+
anotherKey: []
64+
},
65+
params;
66+
67+
obj.urls.beforeSave = 'requestPath';
68+
obj.selectorPrefix = 'selectorPrefix';
69+
obj.messagesClass = 'messagesClass';
70+
71+
params = {
72+
url: obj.urls.beforeSave,
73+
data: _.extend(data, {
74+
form_key: 'magentoFormKey'
75+
}),
76+
success: jasmine.any(Function),
77+
complete: jasmine.any(Function)
78+
};
79+
80+
utils.filterFormData = jasmine.createSpy().and.returnValue(data);
81+
utils.serialize = jasmine.createSpy().and.returnValue(data);
82+
83+
$.ajax = jasmine.createSpy();
84+
obj.save(data);
85+
expect(utils.filterFormData).toHaveBeenCalledWith(data);
86+
expect(utils.serialize).toHaveBeenCalledWith(data);
87+
expect($.ajax).toHaveBeenCalledWith(params);
88+
89+
});
90+
it('Check call "beforeSave" method without parameters', function () {
91+
$.ajax = jasmine.createSpy();
92+
obj.urls.beforeSave = null;
93+
obj.save();
94+
95+
expect($.ajax).not.toHaveBeenCalled();
96+
});
97+
it('Check call "beforeSave" method. Check "success" ajax callback with success response.' , function () {
98+
var request;
99+
100+
$.ajax = jasmine.createSpy().and.callFake(function (req) {
101+
request = req.success;
102+
});
103+
$.fn.notification = jasmine.createSpy();
104+
obj.urls.beforeSave = 'requestPath';
105+
obj.save();
106+
107+
expect(request({error: false})).toBe(true);
108+
expect($('body').notification).not.toHaveBeenCalledWith('clear');
109+
});
110+
111+
it('Check call "beforeSave" method. Check "success" ajax callback with error response.' , function () {
112+
var request,
113+
notificationArguments;
114+
115+
$.ajax = jasmine.createSpy().and.callFake(function (req) {
116+
request = req.success;
117+
});
118+
$.fn.notification = jasmine.createSpy();
119+
obj.urls.beforeSave = 'requestPath';
120+
obj.save();
121+
122+
notificationArguments = {
123+
error: true,
124+
message: 1,
125+
insertMethod: jasmine.any(Function)
126+
};
127+
128+
expect(request({
129+
error: true,
130+
messages: [1]
131+
})).toBeUndefined();
132+
expect($('body').notification.calls.allArgs()).toEqual([['clear'], ['add', notificationArguments]]);
133+
});
134+
it('Check call "beforeSave" method. Check "complete" ajax callback.' , function () {
135+
var request;
136+
137+
$.ajax = jasmine.createSpy().and.callFake(function (req) {
138+
request = req.complete;
139+
});
140+
$.fn.trigger = jasmine.createSpy();
141+
obj.urls.beforeSave = 'requestPath';
142+
obj.save();
143+
144+
expect(request()).toBeUndefined();
145+
expect($('body').trigger).toHaveBeenCalledWith('processStop');
146+
});
53147
});
148+
54149
describe('"initialize" method', function () {
55150
it('Check for defined ', function () {
56151
expect(obj.hasOwnProperty('initialize')).toBeDefined();
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
/* eslint max-nested-callbacks: 0 */
7+
define([
8+
'squire'
9+
], function (Squire) {
10+
'use strict';
11+
12+
var injector = new Squire(),
13+
mocks = {
14+
'Magento_Ui/js/lib/core/events': {
15+
on: jasmine.createSpy()
16+
},
17+
'Magento_Ui/js/lib/registry/registry': {
18+
get: function() {
19+
return {
20+
get: jasmine.createSpy(),
21+
set: jasmine.createSpy()
22+
};
23+
},
24+
create: jasmine.createSpy(),
25+
set: jasmine.createSpy(),
26+
async: jasmine.createSpy()
27+
},
28+
'/mage/utils/wrapper': jasmine.createSpy()
29+
},
30+
obj,
31+
dataScope = 'dataScope';
32+
33+
beforeEach(function (done) {
34+
injector.mock(mocks);
35+
injector.require(['Magento_Ui/js/form/element/multiselect'], function (Constr) {
36+
obj = new Constr({
37+
provider: 'provName',
38+
name: '',
39+
index: '',
40+
dataScope: dataScope
41+
});
42+
43+
done();
44+
});
45+
});
46+
47+
describe('Magento_Ui/js/form/element/multiselect', function () {
48+
describe('"setPrepareToSendData" method', function () {
49+
it('Check method call with empty array as parameter.', function () {
50+
expect(obj.setPrepareToSendData([])).toBeUndefined();
51+
expect(obj.source.set).toHaveBeenCalledWith(dataScope + '-prepared-for-send', '');
52+
});
53+
54+
it('Check method call with array with data as parameter.', function () {
55+
expect(obj.setPrepareToSendData(['1', '2', '3'])).toBeUndefined();
56+
expect(obj.source.set).toHaveBeenCalledWith(dataScope + '-prepared-for-send', ['1', '2', '3']);
57+
});
58+
});
59+
});
60+
});

dev/tests/js/jasmine/tests/lib/mage/misc.test.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,18 @@ define([
1919
expect(utils.convertToMomentFormat(format)).toBe(momentFormat);
2020
});
2121

22+
it('Check "filterFormData" method', function () {
23+
var suffix = 'prepared-for-send',
24+
separator = '-',
25+
data = {
26+
key: 'value-prepared-before-save'
27+
};
28+
expect(utils.filterFormData(data, suffix, separator)).toEqual(data);
29+
expect(utils.filterFormData(data, suffix)).toEqual(data);
30+
expect(utils.filterFormData(data)).toEqual(data);
31+
expect(utils.filterFormData()).toEqual({});
32+
});
33+
2234
it('Check convertToMomentFormat function for all Magento supported locales', function () {
2335

2436
var fixture,

lib/web/mage/utils/misc.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,33 @@ define([
209209
return formData;
210210
},
211211

212+
/**
213+
* Filters data object. Finds properties with suffix
214+
* and sets their values to properties with the same name without suffix.
215+
*
216+
* @param {Object} data - The data object that should be filtered
217+
* @param {String} suffix - The string by which data object should be filtered
218+
* @param {String} separator - The string that is separator between property and suffix
219+
*
220+
* @returns {Object} Filtered data object
221+
*/
222+
filterFormData: function (data, suffix, separator) {
223+
data = data || {};
224+
suffix = suffix || 'prepared-for-send';
225+
separator = separator || '-';
226+
227+
_.each(data, function (value, key) {
228+
if (_.isObject(value) && !value.length) {
229+
this.filterFormData(value, suffix, separator)
230+
} else if (_.isString(key) && ~key.indexOf(suffix)) {
231+
data[key.split(separator)[0]] = value;
232+
delete data[key];
233+
}
234+
}, this);
235+
236+
return data;
237+
},
238+
212239
/**
213240
* Converts PHP IntlFormatter format to moment format.
214241
*

0 commit comments

Comments
 (0)