Skip to content

Commit 3ef1e28

Browse files
Merge pull request magento#274 from magento-fearless-kiwis/Fearless-Kiwis-MAGETWO-50123-Unable-to-assign-blank-value-to-attribute
[Fearless Kiwis] MAGETWO-50123 : unable to assign blank value to attribute
2 parents 8904497 + 76d3f43 commit 3ef1e28

File tree

6 files changed

+358
-6
lines changed

6 files changed

+358
-6
lines changed

Diff for: app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php

+207-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Eav;
1010
use Magento\Eav\Model\Config;
1111
use Magento\Framework\App\RequestInterface;
12+
use Magento\Framework\EntityManager\EventManager;
1213
use Magento\Store\Model\StoreManagerInterface;
1314
use Magento\Store\Api\Data\StoreInterface;
1415
use Magento\Ui\DataProvider\EavValidationRules;
@@ -27,11 +28,15 @@
2728
use Magento\Catalog\Api\ProductAttributeRepositoryInterface;
2829
use Magento\Framework\Api\SearchResultsInterface;
2930
use Magento\Catalog\Api\Data\ProductAttributeInterface;
31+
use Magento\Framework\Api\AttributeInterface;
3032
use Magento\Eav\Api\Data\AttributeGroupInterface;
3133
use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
3234
use Magento\Framework\Currency;
3335
use Magento\Framework\Locale\Currency as CurrencyLocale;
3436
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
37+
use Magento\Framework\Stdlib\ArrayManager;
38+
use Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory as EavAttributeFactory;
39+
use Magento\Framework\Event\ManagerInterface;
3540

3641
/**
3742
* Class EavTest
@@ -157,6 +162,26 @@ class EavTest extends AbstractModifierTest
157162
*/
158163
protected $currencyLocaleMock;
159164

165+
/**
166+
* @var ProductAttributeInterface|\PHPUnit_Framework_MockObject_MockObject
167+
*/
168+
protected $productAttributeMock;
169+
170+
/**
171+
* @var ArrayManager|\PHPUnit_Framework_MockObject_MockObject
172+
*/
173+
protected $arrayManagerMock;
174+
175+
/**
176+
* @var EavAttributeFactory|\PHPUnit_Framework_MockObject_MockObject
177+
*/
178+
protected $eavAttributeFactoryMock;
179+
180+
/**
181+
* @var ManagerInterface|\PHPUnit_Framework_MockObject_MockObject
182+
*/
183+
protected $eventManagerMock;
184+
160185
/**
161186
* @var ObjectManager
162187
*/
@@ -167,6 +192,9 @@ class EavTest extends AbstractModifierTest
167192
*/
168193
protected $eav;
169194

195+
/**
196+
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
197+
*/
170198
protected function setUp()
171199
{
172200
parent::setUp();
@@ -228,10 +256,24 @@ protected function setUp()
228256
$this->searchResultsMock = $this->getMockBuilder(SearchResultsInterface::class)
229257
->getMockForAbstractClass();
230258
$this->eavAttributeMock = $this->getMockBuilder(Attribute::class)
231-
->setMethods(['getAttributeGroupCode', 'getApplyTo', 'getFrontendInput', 'getAttributeCode'])
259+
->setMethods(['load', 'getAttributeGroupCode', 'getApplyTo', 'getFrontendInput', 'getAttributeCode'])
260+
->disableOriginalConstructor()
261+
->getMock();
262+
$this->productAttributeMock = $this->getMockBuilder(ProductAttributeInterface::class)
263+
->getMock();
264+
$this->arrayManagerMock = $this->getMockBuilder(ArrayManager::class)
265+
->getMock();
266+
$this->eavAttributeFactoryMock = $this->getMockBuilder(EavAttributeFactory::class)
267+
->disableOriginalConstructor()
268+
->setMethods(['create'])
269+
->getMock();
270+
$this->eventManagerMock = $this->getMockBuilder(ManagerInterface::class)
232271
->disableOriginalConstructor()
233272
->getMock();
234273

274+
$this->eavAttributeFactoryMock->expects($this->any())
275+
->method('create')
276+
->willReturn($this->eavAttributeMock);
235277
$this->groupCollectionFactoryMock->expects($this->any())
236278
->method('create')
237279
->willReturn($this->groupCollectionMock);
@@ -277,6 +319,9 @@ protected function setUp()
277319
->disableOriginalConstructor()
278320
->setMethods(['getCurrency'])
279321
->getMock();
322+
$this->eavAttributeMock->expects($this->any())
323+
->method('load')
324+
->willReturnSelf();
280325

281326
$this->eav =$this->getModel();
282327
$this->objectManager->setBackwardCompatibleProperty(
@@ -304,6 +349,9 @@ protected function createModel()
304349
'attributeGroupRepository' => $this->attributeGroupRepositoryMock,
305350
'sortOrderBuilder' => $this->sortOrderBuilderMock,
306351
'attributeRepository' => $this->attributeRepositoryMock,
352+
'arrayManager' => $this->arrayManagerMock,
353+
'eavAttributeFactory' => $this->eavAttributeFactoryMock,
354+
'_eventManager' => $this->eventManagerMock
307355
]);
308356
}
309357

@@ -399,4 +447,162 @@ public function testModifyData()
399447

400448
$this->assertEquals($sourceData, $this->eav->modifyData([]));
401449
}
450+
451+
/**
452+
* @param int $productId
453+
* @param bool $productRequired
454+
* @param string $attrValue
455+
* @param array $expected
456+
* @covers \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Eav::isProductExists
457+
* @covers \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Eav::setupAttributeMeta
458+
* @dataProvider setupAttributeMetaDataProvider
459+
*/
460+
public function testSetupAttributeMetaDefaultAttribute($productId, $productRequired, $attrValue, $expected)
461+
{
462+
$configPath = 'arguments/data/config';
463+
$groupCode = 'product-details';
464+
$sortOrder = '0';
465+
466+
$this->productMock->expects($this->any())
467+
->method('getId')
468+
->willReturn($productId);
469+
470+
$this->productAttributeMock->expects($this->any())
471+
->method('getIsRequired')
472+
->willReturn($productRequired);
473+
474+
$this->productAttributeMock->expects($this->any())
475+
->method('getDefaultValue')
476+
->willReturn('required_value');
477+
478+
$this->productAttributeMock->expects($this->any())
479+
->method('getAttributeCode')
480+
->willReturn('code');
481+
482+
$this->productAttributeMock->expects($this->any())
483+
->method('getValue')
484+
->willReturn('value');
485+
486+
$attributeMock = $this->getMockBuilder(AttributeInterface::class)
487+
->disableOriginalConstructor()
488+
->getMock();
489+
490+
$attributeMock->expects($this->any())
491+
->method('getValue')
492+
->willReturn($attrValue);
493+
494+
$this->productMock->expects($this->any())
495+
->method('getCustomAttribute')
496+
->willReturn($attributeMock);
497+
498+
$this->arrayManagerMock->expects($this->any())
499+
->method('set')
500+
->with(
501+
$configPath,
502+
[],
503+
$expected
504+
)
505+
->willReturn($expected);
506+
507+
$this->arrayManagerMock->expects($this->any())
508+
->method('merge')
509+
->willReturn($expected);
510+
511+
$this->arrayManagerMock->expects($this->any())
512+
->method('get')
513+
->willReturn([]);
514+
515+
$this->arrayManagerMock->expects($this->any())
516+
->method('exists');
517+
518+
$this->assertEquals(
519+
$expected,
520+
$this->eav->setupAttributeMeta($this->productAttributeMock, $groupCode, $sortOrder)
521+
);
522+
}
523+
524+
/**
525+
* @return array
526+
*/
527+
public function setupAttributeMetaDataProvider()
528+
{
529+
return [
530+
'default_null_prod_not_new_and_required' => [
531+
'productId' => 1,
532+
'productRequired' => true,
533+
'attrValue' => 'val',
534+
'expected' => [
535+
'dataType' => null,
536+
'formElement' => null,
537+
'visible' => null,
538+
'required' => true,
539+
'notice' => null,
540+
'default' => null,
541+
'label' => null,
542+
'code' => 'code',
543+
'source' => 'product-details',
544+
'scopeLabel' => '',
545+
'globalScope' => false,
546+
'sortOrder' => 0
547+
],
548+
],
549+
'default_null_prod_not_new_and_not_required' => [
550+
'productId' => 1,
551+
'productRequired' => false,
552+
'attrValue' => 'val',
553+
'expected' => [
554+
'dataType' => null,
555+
'formElement' => null,
556+
'visible' => null,
557+
'required' => false,
558+
'notice' => null,
559+
'default' => null,
560+
'label' => null,
561+
'code' => 'code',
562+
'source' => 'product-details',
563+
'scopeLabel' => '',
564+
'globalScope' => false,
565+
'sortOrder' => 0
566+
],
567+
],
568+
'default_null_prod_new_and_not_required' => [
569+
'productId' => null,
570+
'productRequired' => false,
571+
'attrValue' => null,
572+
'expected' => [
573+
'dataType' => null,
574+
'formElement' => null,
575+
'visible' => null,
576+
'required' => false,
577+
'notice' => null,
578+
'default' => 'required_value',
579+
'label' => null,
580+
'code' => 'code',
581+
'source' => 'product-details',
582+
'scopeLabel' => '',
583+
'globalScope' => false,
584+
'sortOrder' => 0
585+
],
586+
],
587+
'default_null_prod_new_and_required' => [
588+
'productId' => null,
589+
'productRequired' => false,
590+
'attrValue' => null,
591+
'expected' => [
592+
'dataType' => null,
593+
'formElement' => null,
594+
'visible' => null,
595+
'required' => false,
596+
'notice' => null,
597+
'default' => 'required_value',
598+
'label' => null,
599+
'code' => 'code',
600+
'source' => 'product-details',
601+
'scopeLabel' => '',
602+
'globalScope' => false,
603+
'sortOrder' => 0
604+
],
605+
]
606+
];
607+
}
402608
}

Diff for: app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php

+12-1
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,16 @@ private function getPreviousSetAttributes()
522522
return $this->prevSetAttributes;
523523
}
524524

525+
/**
526+
* Check is product already new or we trying to create one
527+
*
528+
* @return bool
529+
*/
530+
private function isProductExists()
531+
{
532+
return (bool) $this->locator->getProduct()->getId();
533+
}
534+
525535
/**
526536
* Initial meta setup
527537
*
@@ -531,6 +541,7 @@ private function getPreviousSetAttributes()
531541
* @return array
532542
* @throws \Magento\Framework\Exception\LocalizedException
533543
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
544+
* @SuppressWarnings(PHPMD.NPathComplexity)
534545
* @api
535546
*/
536547
public function setupAttributeMeta(ProductAttributeInterface $attribute, $groupCode, $sortOrder)
@@ -543,7 +554,7 @@ public function setupAttributeMeta(ProductAttributeInterface $attribute, $groupC
543554
'visible' => $attribute->getIsVisible(),
544555
'required' => $attribute->getIsRequired(),
545556
'notice' => $attribute->getNote(),
546-
'default' => $attribute->getDefaultValue(),
557+
'default' => (!$this->isProductExists()) ? $attribute->getDefaultValue() : null,
547558
'label' => $attribute->getDefaultFrontendLabel(),
548559
'code' => $attribute->getAttributeCode(),
549560
'source' => $groupCode,

Diff for: app/code/Magento/Ui/view/base/web/js/form/element/select.js

+21-3
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ define([
4444
if (_.isUndefined(caption)) {
4545
caption = node.label;
4646
}
47-
} else {
48-
return node;
4947
}
48+
49+
return node;
5050
});
5151

5252
return {
@@ -194,7 +194,7 @@ define([
194194
},
195195

196196
/**
197-
* Matches specfied value with existing options
197+
* Matches specified value with existing options
198198
* or, if value is not specified, returns value of the first option.
199199
*
200200
* @returns {*}
@@ -286,6 +286,11 @@ define([
286286
return preview;
287287
},
288288

289+
/**
290+
*
291+
* @param {Number} value
292+
* @returns {Object} Chainable
293+
*/
289294
getOption: function (value) {
290295
return this.indexedOptions[value];
291296
},
@@ -301,6 +306,19 @@ define([
301306
this.value(value);
302307

303308
return this;
309+
},
310+
311+
/**
312+
* Initializes observable properties of instance
313+
*
314+
* @returns {Object} Chainable.
315+
*/
316+
setInitialValue: function () {
317+
if (_.isUndefined(this.value()) && !this.default) {
318+
this.clear();
319+
}
320+
321+
return this._super();
304322
}
305323
});
306324
});

Diff for: dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/EavTest.php

+13
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,19 @@ public function testModifyMeta()
7070
$this->prepareDataForComparison($actualMeta, $expectedMeta);
7171
$this->assertEquals($expectedMeta, $actualMeta);
7272
}
73+
74+
public function testModifyMetaNewProduct()
75+
{
76+
$this->objectManager->get(\Magento\Eav\Model\Entity\AttributeCache::class)->clear();
77+
/** @var \Magento\Catalog\Model\Product $product */
78+
$product = $this->objectManager->create(\Magento\Catalog\Model\Product::class);
79+
$product->setAttributeSetId(4);
80+
$this->locatorMock->expects($this->any())->method('getProduct')->willReturn($product);
81+
$expectedMeta = include __DIR__ . '/_files/eav_expected_meta_output_w_default.php';
82+
$actualMeta = $this->eavModifier->modifyMeta([]);
83+
$this->prepareDataForComparison($actualMeta, $expectedMeta);
84+
$this->assertEquals($expectedMeta, $actualMeta);
85+
}
7386

7487
/**
7588
* @magentoDataFixture Magento/Catalog/_files/product_simple_with_admin_store.php

Diff for: dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/_files/eav_expected_meta_output.php

-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
"visible" => "1",
3636
"required" => "0",
3737
"label" => "Enable Product",
38-
"default" => "1",
3938
"source" => "product-details",
4039
"scopeLabel" => "[WEBSITE]",
4140
"globalScope" => false,

0 commit comments

Comments
 (0)