Skip to content

Commit e05e6ec

Browse files
author
Magento CICD
authored
merge magento/2.2-develop into magento-firedrakes/MAGETWO-69606
2 parents d3e86ff + 531c257 commit e05e6ec

File tree

8 files changed

+207
-45
lines changed

8 files changed

+207
-45
lines changed

app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,13 @@ public function execute()
104104
$multipleOption = null == $multipleOption ? 'select' : $multipleOption;
105105

106106
if (isset($this->multipleAttributeList[$multipleOption]) && !(null == ($multipleOption))) {
107+
$options = $this->getRequest()->getParam($this->multipleAttributeList[$multipleOption]);
107108
$this->checkUniqueOption(
108109
$response,
109-
$this->getRequest()->getParam($this->multipleAttributeList[$multipleOption])
110+
$options
110111
);
112+
$valueOptions = (isset($options['value']) && is_array($options['value'])) ? $options['value'] : [];
113+
$this->checkEmptyOption($response, $valueOptions);
111114
}
112115

113116
return $this->resultJsonFactory->create()->setJsonData($response->toJson());
@@ -155,13 +158,30 @@ private function setMessageToResponse($response, $messages)
155158
private function checkUniqueOption(DataObject $response, array $options = null)
156159
{
157160
if (is_array($options)
158-
&& !empty($options['value'])
159-
&& !empty($options['delete'])
161+
&& isset($options['value'])
162+
&& isset($options['delete'])
160163
&& !$this->isUniqueAdminValues($options['value'], $options['delete'])
161164
) {
162165
$this->setMessageToResponse($response, [__("The value of Admin must be unique.")]);
163166
$response->setError(true);
164167
}
165168
return $this;
166169
}
170+
171+
/**
172+
* Check that admin does not try to create option with empty admin scope option.
173+
*
174+
* @param DataObject $response
175+
* @param array $optionsForCheck
176+
* @return void
177+
*/
178+
private function checkEmptyOption(DataObject $response, array $optionsForCheck = null)
179+
{
180+
foreach ($optionsForCheck as $optionValues) {
181+
if (isset($optionValues[0]) && $optionValues[0] == '') {
182+
$this->setMessageToResponse($response, [__("The value of Admin scope can't be empty.")]);
183+
$response->setError(true);
184+
}
185+
}
186+
}
167187
}

app/code/Magento/Catalog/Model/Product/Attribute/DataProvider.php

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@
55
*/
66
namespace Magento\Catalog\Model\Product\Attribute;
77

8-
use Magento\Catalog\Model\Category;
98
use Magento\Framework\Stdlib\ArrayManager;
109
use Magento\Store\Api\StoreRepositoryInterface;
1110
use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory;
1211
use Magento\Eav\Model\Entity\Attribute as EavAttribute;
13-
use Magento\Ui\Component\Form;
1412
use Magento\Ui\Component\Form\Element\Input;
1513
use Magento\Ui\Component\Form\Field;
1614
use Magento\Ui\Component\Form\Element\DataType\Text;
15+
use Magento\Store\Model\Store;
1716

1817
/**
1918
* Data provider for the form of adding new product attribute.
@@ -149,40 +148,36 @@ private function customizeOptions($meta)
149148
$sortOrder = 1;
150149
foreach ($this->storeRepository->getList() as $store) {
151150
$storeId = $store->getId();
152-
151+
$storeLabelConfiguration = [
152+
'dataType' => 'text',
153+
'formElement' => 'input',
154+
'component' => 'Magento_Catalog/js/form/element/input',
155+
'template' => 'Magento_Catalog/form/element/input',
156+
'prefixName' => 'option.value',
157+
'prefixElementName' => 'option_',
158+
'suffixName' => (string)$storeId,
159+
'label' => $store->getName(),
160+
'sortOrder' => $sortOrder,
161+
'componentType' => Field::NAME,
162+
];
163+
// JS code can't understand 'required-entry' => false|null, we have to avoid even empty property.
164+
if ($store->getCode() == Store::ADMIN_CODE) {
165+
$storeLabelConfiguration['validation'] = [
166+
'required-entry' => true,
167+
];
168+
}
153169
$meta['attribute_options_select_container']['children']['attribute_options_select']['children']
154170
['record']['children']['value_option_' . $storeId] = $this->arrayManager->set(
155171
'arguments/data/config',
156172
[],
157-
[
158-
'dataType' => 'text',
159-
'formElement' => 'input',
160-
'component' => 'Magento_Catalog/js/form/element/input',
161-
'template' => 'Magento_Catalog/form/element/input',
162-
'prefixName' => 'option.value',
163-
'prefixElementName' => 'option_',
164-
'suffixName' => (string)$storeId,
165-
'label' => $store->getName(),
166-
'sortOrder' => $sortOrder,
167-
'componentType' => Field::NAME,
168-
]
173+
$storeLabelConfiguration
169174
);
175+
170176
$meta['attribute_options_multiselect_container']['children']['attribute_options_multiselect']['children']
171177
['record']['children']['value_option_' . $storeId] = $this->arrayManager->set(
172178
'arguments/data/config',
173179
[],
174-
[
175-
'dataType' => 'text',
176-
'formElement' => 'input',
177-
'component' => 'Magento_Catalog/js/form/element/input',
178-
'template' => 'Magento_Catalog/form/element/input',
179-
'prefixName' => 'option.value',
180-
'prefixElementName' => 'option_',
181-
'suffixName' => (string)$storeId,
182-
'label' => $store->getName(),
183-
'sortOrder' => $sortOrder,
184-
'componentType' => Field::NAME,
185-
]
180+
$storeLabelConfiguration
186181
);
187182
++$sortOrder;
188183
}

app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,4 +251,77 @@ public function provideUniqueData()
251251
],
252252
];
253253
}
254+
255+
/**
256+
* Check that empty admin scope labels will trigger error.
257+
*
258+
* @dataProvider provideEmptyOption
259+
* @param array $options
260+
* @throws \Magento\Framework\Exception\NotFoundException
261+
*/
262+
public function testEmptyOption(array $options, $result)
263+
{
264+
$this->requestMock->expects($this->any())
265+
->method('getParam')
266+
->willReturnMap([
267+
['frontend_label', null, null],
268+
['frontend_input', 'select', 'multipleselect'],
269+
['attribute_code', null, "test_attribute_code"],
270+
['new_attribute_set_name', null, 'test_attribute_set_name'],
271+
['option', null, $options],
272+
['message_key', Validate::DEFAULT_MESSAGE_KEY, 'message'],
273+
]);
274+
275+
$this->objectManagerMock->expects($this->once())
276+
->method('create')
277+
->willReturn($this->attributeMock);
278+
279+
$this->attributeMock->expects($this->once())
280+
->method('loadByCode')
281+
->willReturnSelf();
282+
283+
$this->resultJsonFactoryMock->expects($this->once())
284+
->method('create')
285+
->willReturn($this->resultJson);
286+
287+
$this->resultJson->expects($this->once())
288+
->method('setJsonData')
289+
->willReturnArgument(0);
290+
291+
$response = $this->getModel()->execute();
292+
$responseObject = json_decode($response);
293+
$this->assertEquals($responseObject, $result);
294+
}
295+
296+
/**
297+
* Dataprovider for testEmptyOption.
298+
*
299+
* @return array
300+
*/
301+
public function provideEmptyOption()
302+
{
303+
return [
304+
'empty admin scope options' => [
305+
[
306+
'value' => [
307+
"option_0" => [''],
308+
],
309+
],
310+
(object) [
311+
'error' => true,
312+
'message' => 'The value of Admin scope can\'t be empty.',
313+
]
314+
],
315+
'not empty admin scope options' => [
316+
[
317+
'value' => [
318+
"option_0" => ['asdads'],
319+
],
320+
],
321+
(object) [
322+
'error' => false,
323+
]
324+
]
325+
];
326+
}
254327
}

app/code/Magento/Catalog/etc/adminhtml/di.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
<arguments>
5252
<argument name="multipleAttributeList" xsi:type="array">
5353
<item name="select" xsi:type="string">option</item>
54+
<item name="multiselect" xsi:type="string">option</item>
5455
</argument>
5556
</arguments>
5657
</type>

app/code/Magento/Catalog/view/adminhtml/web/template/form/element/input.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@
1717
id: uid,
1818
disabled: disabled
1919
}"/>
20+
<label class="admin__field-error" if="error" attr="for: uid" text="error"/>

app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,8 @@
2222
<table class="admin__dynamic-rows admin__control-table" data-role="grid" attr="{'data-index': index}">
2323
<thead if="element.columnsHeader">
2424
<tr>
25-
<th if="dndConfig.enabled"/>
25+
<th if="dndConfig.enabled" />
2626
<th repeat="foreach: labels, item: '$label'"
27-
text="$label().label"
2827
css="setClasses($label())"
2928
visible="$label().visible"
3029
disable="$label().disabled">

dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Customer/Webapi.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,14 @@ protected function prepareCustomAttributes(array $data)
150150
*/
151151
protected function getCustomerGroup(Customer $customer)
152152
{
153-
return $customer->hasData('group_id')
154-
? $customer->getDataFieldConfig('group_id')['source']->getCustomerGroup()->getCustomerGroupId()
155-
: self::GENERAL_GROUP;
153+
if ($customer->hasData('group_id')) {
154+
if ($customer->getDataFieldConfig('group_id')['source']->getCustomerGroup()) {
155+
return $customer->getDataFieldConfig('group_id')['source']->getCustomerGroup()->getCustomerGroupId();
156+
}
157+
return $customer->getData('group_id');
158+
} else {
159+
return self::GENERAL_GROUP;
160+
}
156161
}
157162

158163
/**

dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/ApplyTaxBasedOnVatIdTest.php

Lines changed: 78 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,9 @@
88

99
use Magento\Tax\Test\Fixture\TaxRule;
1010
use Magento\Checkout\Test\Fixture\Cart;
11-
use Magento\Customer\Test\Fixture\Customer;
1211
use Magento\Config\Test\Fixture\ConfigData;
1312
use Magento\Checkout\Test\Page\CheckoutCart;
1413
use Magento\Sales\Test\Fixture\OrderInjectable;
15-
use Magento\Catalog\Test\Fixture\CatalogProductSimple;
1614
use Magento\Customer\Test\TestCase\AbstractApplyVatIdTest;
1715

1816
/**
@@ -80,23 +78,28 @@ public function test(
8078
) {
8179
// Preconditions
8280
$this->configData = $configData;
81+
$this->customer = $order->getDataFieldConfig('customer_id')['source']->getCustomer();
8382
$this->objectManager->create(
8483
\Magento\Config\Test\TestStep\SetupConfigurationStep::class,
8584
['configData' => $this->configData]
8685
)->run();
87-
$taxRule->persist();
86+
8887
// Prepare data
89-
$this->customer = $order->getDataFieldConfig('customer_id')['source']->getCustomer();
90-
$address = $this->customer->getDataFieldConfig('address')['source']->getAddresses()[0];
91-
$this->prepareVatConfig($vatConfig, $customerGroup);
92-
$poducts = $order->getEntityId()['products'];
88+
$taxRule->persist();
89+
$this->prepareVatConfiguration($vatConfig);
90+
$this->prepareCustomer($customerGroup);
91+
92+
$products = $order->getEntityId()['products'];
9393
$cart = $this->fixtureFactory->createByCode(
9494
'cart',
95-
['data' => array_merge($cart->getData(), ['items' => ['products' => $poducts]])]
95+
['data' => array_merge($cart->getData(), ['items' => ['products' => $products]])]
9696
);
97+
$address = $this->customer->getDataFieldConfig('address')['source']->getAddresses()[0];
9798

98-
// Steps
9999
$order->persist();
100+
$this->updateCustomer($customerGroup);
101+
102+
// Steps
100103
$this->objectManager->create(
101104
\Magento\Customer\Test\TestStep\LoginCustomerOnFrontendStep::class,
102105
['customer' => $this->customer]
@@ -115,8 +118,73 @@ public function test(
115118
'address' => $address,
116119
'orderId' => $order->getId(),
117120
'cart' => $cart,
118-
'products' => $poducts
121+
'products' => $products
122+
];
123+
}
124+
125+
/**
126+
* Persist vat configuration
127+
*
128+
* @param string $vatConfig
129+
* @return void
130+
*/
131+
private function prepareVatConfiguration($vatConfig)
132+
{
133+
$groupConfig = [
134+
'customer/create_account/viv_domestic_group' => [
135+
'value' => $this->vatGroups['valid_domestic_group']->getCustomerGroupId()
136+
],
137+
'customer/create_account/viv_intra_union_group' => [
138+
'value' => $this->vatGroups['valid_intra_union_group']->getCustomerGroupId()
139+
],
140+
'customer/create_account/viv_invalid_group' => [
141+
'value' => $this->vatGroups['invalid_group']->getCustomerGroupId()
142+
],
143+
'customer/create_account/viv_error_group' => [
144+
'value' => $this->vatGroups['error_group']->getCustomerGroupId()
145+
]
119146
];
147+
$vatConfig = $this->fixtureFactory->createByCode(
148+
'configData',
149+
['data' => array_replace_recursive($vatConfig->getSection(), $groupConfig)]
150+
);
151+
$vatConfig->persist();
152+
}
153+
154+
/**
155+
* Persist customer with valid customer group
156+
*
157+
* @param string $customerGroup
158+
* @return void
159+
*/
160+
private function prepareCustomer($customerGroup)
161+
{
162+
$customerData = array_merge(
163+
$this->customer->getData(),
164+
['group_id' => ['value' => $this->vatGroups[$customerGroup]->getCustomerGroupId()]],
165+
['address' => ['addresses' => $this->customer->getDataFieldConfig('address')['source']->getAddresses()]],
166+
['email' => 'JohnDoe%isolation%@example.com']
167+
);
168+
169+
unset($customerData['id']);
170+
$this->customer = $this->fixtureFactory->createByCode('customer', ['data' => $customerData]);
171+
$this->customer->persist();
172+
}
173+
174+
/**
175+
* Update customer with customer group code for assert
176+
*
177+
* @param string $customerGroup
178+
* @return void
179+
*/
180+
private function updateCustomer($customerGroup)
181+
{
182+
$customerData = array_merge(
183+
$this->customer->getData(),
184+
['group_id' => ['value' => $this->vatGroups[$customerGroup]->getCustomerGroupCode()]]
185+
);
186+
187+
$this->customer = $this->fixtureFactory->createByCode('customer', ['data' => $customerData]);
120188
}
121189

122190
/**

0 commit comments

Comments
 (0)