Skip to content

Commit 86ec99b

Browse files
🔃 [Magento Community Engineering] Community Contributions - 2.4-develop
Accepted Community Pull Requests: - #27369: Fixed issue 27051: Saving an attribute with backend_type static (by @jiten-patel) Fixed GitHub Issues: - #27051: Saving an attribute with backend_type 'static' will remove the content of the 'frontend_class' field. (reported by @MLucaciu) has been fixed in #27369 by @jiten-patel in 2.4-develop branch Related commits: 1. b06db1f 2. aaa7054 3. fa154cd 4. 7d8b893 5. 054bf5d 6. 2160c37 7. 83545c0 8. c1a01fc 9. eeb7433 10. 7d2d0d3 11. eb34341
2 parents 5d3d5c7 + 1e68561 commit 86ec99b

File tree

2 files changed

+117
-41
lines changed
  • app/code/Magento/Catalog
    • Controller/Adminhtml/Product/Attribute
    • Test/Unit/Controller/Adminhtml/Product/Attribute

2 files changed

+117
-41
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,10 @@ public function execute()
261261
unset($data['apply_to']);
262262
}
263263

264+
if ($model->getBackendType() == 'static' && !$model->getIsUserDefined()) {
265+
$data['frontend_class'] = $model->getFrontendClass();
266+
}
267+
264268
$model->addData($data);
265269

266270
if (!$attributeId) {

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

Lines changed: 113 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77

88
namespace Magento\Catalog\Test\Unit\Controller\Adminhtml\Product\Attribute;
99

10+
use Magento\Backend\Model\Session;
1011
use Magento\Backend\Model\View\Result\Redirect as ResultRedirect;
1112
use Magento\Catalog\Api\Data\ProductAttributeInterface;
1213
use Magento\Catalog\Controller\Adminhtml\Product\Attribute\Save;
1314
use Magento\Catalog\Helper\Product as ProductHelper;
15+
use Magento\Catalog\Model\Product\Attribute\Frontend\Inputtype\Presentation;
1416
use Magento\Catalog\Model\Product\AttributeSet\Build;
1517
use Magento\Catalog\Model\Product\AttributeSet\BuildFactory;
1618
use Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory;
@@ -31,63 +33,64 @@
3133

3234
/**
3335
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
36+
* @SuppressWarnings(PHPMD.TooManyFields)
3437
*/
3538
class SaveTest extends AttributeTest
3639
{
3740
/**
3841
* @var BuildFactory|MockObject
3942
*/
40-
protected $buildFactoryMock;
43+
private $buildFactoryMock;
4144

4245
/**
4346
* @var FilterManager|MockObject
4447
*/
45-
protected $filterManagerMock;
48+
private $filterManagerMock;
4649

4750
/**
4851
* @var ProductHelper|MockObject
4952
*/
50-
protected $productHelperMock;
53+
private $productHelperMock;
5154

5255
/**
5356
* @var AttributeFactory|MockObject
5457
*/
55-
protected $attributeFactoryMock;
58+
private $attributeFactoryMock;
5659

5760
/**
5861
* @var ValidatorFactory|MockObject
5962
*/
60-
protected $validatorFactoryMock;
63+
private $validatorFactoryMock;
6164

6265
/**
6366
* @var CollectionFactory|MockObject
6467
*/
65-
protected $groupCollectionFactoryMock;
68+
private $groupCollectionFactoryMock;
6669

6770
/**
6871
* @var LayoutFactory|MockObject
6972
*/
70-
protected $layoutFactoryMock;
73+
private $layoutFactoryMock;
7174

7275
/**
7376
* @var ResultRedirect|MockObject
7477
*/
75-
protected $redirectMock;
78+
private $redirectMock;
7679

7780
/**
78-
* @var AttributeSet|MockObject
81+
* @var AttributeSetInterface|MockObject
7982
*/
80-
protected $attributeSetMock;
83+
private $attributeSetMock;
8184

8285
/**
8386
* @var Build|MockObject
8487
*/
85-
protected $builderMock;
88+
private $builderMock;
8689

8790
/**
8891
* @var InputTypeValidator|MockObject
8992
*/
90-
protected $inputTypeValidatorMock;
93+
private $inputTypeValidatorMock;
9194

9295
/**
9396
* @var FormData|MockObject
@@ -104,19 +107,34 @@ class SaveTest extends AttributeTest
104107
*/
105108
private $attributeCodeValidatorMock;
106109

110+
/**
111+
* @var Presentation|MockObject
112+
*/
113+
private $presentationMock;
114+
115+
/**
116+
* @var Session|MockObject
117+
*/
118+
119+
private $sessionMock;
120+
107121
protected function setUp(): void
108122
{
109123
parent::setUp();
124+
$this->filterManagerMock = $this->createMock(FilterManager::class);
125+
$this->productHelperMock = $this->createMock(ProductHelper::class);
126+
$this->attributeSetMock = $this->createMock(AttributeSetInterface::class);
127+
$this->builderMock = $this->createMock(Build::class);
128+
$this->inputTypeValidatorMock = $this->createMock(InputTypeValidator::class);
129+
$this->formDataSerializerMock = $this->createMock(FormData::class);
130+
$this->attributeCodeValidatorMock = $this->createMock(AttributeCodeValidator::class);
131+
$this->presentationMock = $this->createMock(Presentation::class);
132+
$this->sessionMock = $this->createMock(Session::class);
133+
$this->layoutFactoryMock = $this->createMock(LayoutFactory::class);
110134
$this->buildFactoryMock = $this->getMockBuilder(BuildFactory::class)
111135
->setMethods(['create'])
112136
->disableOriginalConstructor()
113137
->getMock();
114-
$this->filterManagerMock = $this->getMockBuilder(FilterManager::class)
115-
->disableOriginalConstructor()
116-
->getMock();
117-
$this->productHelperMock = $this->getMockBuilder(ProductHelper::class)
118-
->disableOriginalConstructor()
119-
->getMock();
120138
$this->attributeFactoryMock = $this->getMockBuilder(AttributeFactory::class)
121139
->setMethods(['create'])
122140
->disableOriginalConstructor()
@@ -129,32 +147,23 @@ protected function setUp(): void
129147
->setMethods(['create'])
130148
->disableOriginalConstructor()
131149
->getMock();
132-
$this->layoutFactoryMock = $this->getMockBuilder(LayoutFactory::class)
133-
->disableOriginalConstructor()
134-
->getMock();
135150
$this->redirectMock = $this->getMockBuilder(ResultRedirect::class)
136151
->setMethods(['setData', 'setPath'])
137152
->disableOriginalConstructor()
138153
->getMock();
139-
$this->attributeSetMock = $this->getMockBuilder(AttributeSetInterface::class)
140-
->disableOriginalConstructor()
141-
->getMockForAbstractClass();
142-
$this->builderMock = $this->getMockBuilder(Build::class)
143-
->disableOriginalConstructor()
144-
->getMock();
145-
$this->inputTypeValidatorMock = $this->getMockBuilder(InputTypeValidator::class)
146-
->disableOriginalConstructor()
147-
->getMock();
148-
$this->formDataSerializerMock = $this->getMockBuilder(FormData::class)
149-
->disableOriginalConstructor()
150-
->getMock();
151-
$this->attributeCodeValidatorMock = $this->getMockBuilder(AttributeCodeValidator::class)
152-
->disableOriginalConstructor()
153-
->getMock();
154154
$this->productAttributeMock = $this->getMockBuilder(ProductAttributeInterface::class)
155-
->setMethods(['getId', 'get'])
156-
->getMockForAbstractClass();
157-
155+
->setMethods(
156+
[
157+
'getId',
158+
'get',
159+
'getBackendTypeByInput',
160+
'getDefaultValueByInput',
161+
'getBackendType',
162+
'getFrontendClass',
163+
'addData',
164+
'save'
165+
]
166+
)->getMockForAbstractClass();
158167
$this->buildFactoryMock->expects($this->any())
159168
->method('create')
160169
->willReturn($this->builderMock);
@@ -167,7 +176,7 @@ protected function setUp(): void
167176
}
168177

169178
/**
170-
* {@inheritdoc}
179+
* @inheritdoc
171180
*/
172181
protected function getModel()
173182
{
@@ -184,7 +193,9 @@ protected function getModel()
184193
'groupCollectionFactory' => $this->groupCollectionFactoryMock,
185194
'layoutFactory' => $this->layoutFactoryMock,
186195
'formDataSerializer' => $this->formDataSerializerMock,
187-
'attributeCodeValidator' => $this->attributeCodeValidatorMock
196+
'attributeCodeValidator' => $this->attributeCodeValidatorMock,
197+
'presentation' => $this->presentationMock,
198+
'_session' => $this->sessionMock
188199
]);
189200
}
190201

@@ -214,6 +225,67 @@ public function testExecuteWithEmptyData()
214225
$this->assertInstanceOf(ResultRedirect::class, $this->getModel()->execute());
215226
}
216227

228+
public function testExecuteSaveFrontendClass()
229+
{
230+
$data = [
231+
'frontend_input' => 'test_frontend_input',
232+
];
233+
234+
$this->requestMock->expects($this->any())
235+
->method('getParam')
236+
->willReturnMap([
237+
['isAjax', null, null],
238+
['serialized_options', '[]', ''],
239+
['set', null, 1],
240+
['attribute_code', null, 'test_attribute_code'],
241+
]);
242+
$this->formDataSerializerMock
243+
->expects($this->once())
244+
->method('unserialize')
245+
->with('')
246+
->willReturn([]);
247+
$this->requestMock->expects($this->once())
248+
->method('getPostValue')
249+
->willReturn($data);
250+
$this->inputTypeValidatorMock->expects($this->any())
251+
->method('isValid')
252+
->with($data['frontend_input'])
253+
->willReturn(true);
254+
$this->presentationMock->expects($this->once())
255+
->method('convertPresentationDataToInputType')
256+
->willReturn($data);
257+
$this->productHelperMock->expects($this->once())
258+
->method('getAttributeSourceModelByInputType')
259+
->with($data['frontend_input'])
260+
->willReturn(null);
261+
$this->productHelperMock->expects($this->once())
262+
->method('getAttributeBackendModelByInputType')
263+
->with($data['frontend_input'])
264+
->willReturn(null);
265+
$this->productAttributeMock->expects($this->once())
266+
->method('getBackendTypeByInput')
267+
->with($data['frontend_input'])
268+
->willReturnSelf('test_backend_type');
269+
$this->productAttributeMock->expects($this->once())
270+
->method('getDefaultValueByInput')
271+
->with($data['frontend_input'])
272+
->willReturn(null);
273+
$this->productAttributeMock->expects($this->once())
274+
->method('getBackendType')
275+
->willReturn('static');
276+
$this->productAttributeMock->expects($this->once())
277+
->method('getFrontendClass')
278+
->willReturn('static');
279+
$this->resultFactoryMock->expects($this->any())
280+
->method('create')
281+
->willReturn($this->redirectMock);
282+
$this->redirectMock->expects($this->any())
283+
->method('setPath')
284+
->willReturnSelf();
285+
286+
$this->assertInstanceOf(ResultRedirect::class, $this->getModel()->execute());
287+
}
288+
217289
public function testExecute()
218290
{
219291
$data = [

0 commit comments

Comments
 (0)