Skip to content

Commit 2d19477

Browse files
fix static, fix conflict merge
1 parent 99383fc commit 2d19477

File tree

2 files changed

+118
-81
lines changed

2 files changed

+118
-81
lines changed

app/code/Magento/Catalog/Model/Product/Copier.php

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
use Magento\Catalog\Api\Data\ProductInterface;
99
use Magento\Catalog\Model\Attribute\ScopeOverriddenValue;
1010
use Magento\Catalog\Model\Product;
11+
use Magento\Catalog\Model\Product\Attribute\Source\Status;
1112
use Magento\Catalog\Model\Product\Option\Repository as OptionRepository;
1213
use Magento\Catalog\Model\ProductFactory;
1314
use Magento\Framework\App\ObjectManager;
1415
use Magento\Framework\EntityManager\MetadataPool;
16+
use Magento\Store\Model\Store;
1517
use Magento\UrlRewrite\Model\Exception\UrlAlreadyExistsException;
1618

1719
/**
@@ -72,20 +74,17 @@ public function __construct(
7274
/**
7375
* Create product duplicate
7476
*
75-
* @param \Magento\Catalog\Model\Product $product
76-
*
77-
* @return \Magento\Catalog\Model\Product
78-
*
79-
* @throws \Exception
77+
* @param Product $product
78+
* @return Product
8079
*/
81-
public function copy(Product $product)
80+
public function copy(Product $product): Product
8281
{
8382
$product->getWebsiteIds();
8483
$product->getCategoryIds();
8584

8685
$metadata = $this->metadataPool->getMetadata(ProductInterface::class);
8786

88-
/** @var \Magento\Catalog\Model\Product $duplicate */
87+
/** @var Product $duplicate */
8988
$duplicate = $this->productFactory->create();
9089
$productData = $product->getData();
9190
$productData = $this->removeStockItem($productData);
@@ -96,11 +95,11 @@ public function copy(Product $product)
9695
$duplicate->setMetaDescription(null);
9796
$duplicate->setIsDuplicate(true);
9897
$duplicate->setOriginalLinkId($product->getData($metadata->getLinkField()));
99-
$duplicate->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_DISABLED);
98+
$duplicate->setStatus(Status::STATUS_DISABLED);
10099
$duplicate->setCreatedAt(null);
101100
$duplicate->setUpdatedAt(null);
102101
$duplicate->setId(null);
103-
$duplicate->setStoreId(\Magento\Store\Model\Store::DEFAULT_STORE_ID);
102+
$duplicate->setStoreId(Store::DEFAULT_STORE_ID);
104103
$this->copyConstructor->build($product, $duplicate);
105104
$this->setDefaultUrl($product, $duplicate);
106105
$this->setStoresUrl($product, $duplicate);
@@ -118,11 +117,11 @@ public function copy(Product $product)
118117
*/
119118
private function setDefaultUrl(Product $product, Product $duplicate) : void
120119
{
121-
$duplicate->setStoreId(\Magento\Store\Model\Store::DEFAULT_STORE_ID);
120+
$duplicate->setStoreId(Store::DEFAULT_STORE_ID);
122121
$resource = $product->getResource();
123122
$attribute = $resource->getAttribute('url_key');
124123
$productId = $product->getId();
125-
$urlKey = $resource->getAttributeRawValue($productId, 'url_key', \Magento\Store\Model\Store::DEFAULT_STORE_ID);
124+
$urlKey = $resource->getAttributeRawValue($productId, 'url_key', Store::DEFAULT_STORE_ID);
126125
do {
127126
$urlKey = $this->modifyUrl($urlKey);
128127
$duplicate->setUrlKey($urlKey);
@@ -175,7 +174,7 @@ private function setStoresUrl(Product $product, Product $duplicate) : void
175174
$productResource->saveAttribute($duplicate, 'url_path');
176175
$productResource->saveAttribute($duplicate, 'url_key');
177176
}
178-
$duplicate->setStoreId(\Magento\Store\Model\Store::DEFAULT_STORE_ID);
177+
$duplicate->setStoreId(Store::DEFAULT_STORE_ID);
179178
}
180179

181180
/**
@@ -197,7 +196,7 @@ private function modifyUrl(string $urlKey) : string
197196
* @param array $productData
198197
* @return array
199198
*/
200-
private function removeStockItem(array $productData)
199+
private function removeStockItem(array $productData): array
201200
{
202201
if (isset($productData[ProductInterface::EXTENSION_ATTRIBUTES_KEY])) {
203202
$extensionAttributes = $productData[ProductInterface::EXTENSION_ATTRIBUTES_KEY];

app/code/Magento/Catalog/Test/Unit/Model/Product/CopierTest.php

Lines changed: 106 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -3,53 +3,66 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
67
namespace Magento\Catalog\Test\Unit\Model\Product;
78

89
use Magento\Catalog\Api\Data\ProductExtension;
910
use Magento\Catalog\Api\Data\ProductInterface;
11+
use Magento\Catalog\Model\Attribute\ScopeOverriddenValue;
1012
use Magento\Catalog\Model\Product;
13+
use Magento\Catalog\Model\Product\Attribute\Source\Status;
1114
use Magento\Catalog\Model\Product\Copier;
15+
use Magento\Catalog\Model\Product\CopyConstructorInterface;
16+
use Magento\Catalog\Model\Product\Option\Repository;
17+
use Magento\Catalog\Model\ProductFactory;
18+
use Magento\Catalog\Model\ResourceModel\Product as ProductResourceModel;
1219
use Magento\CatalogInventory\Api\Data\StockItemInterface;
20+
use Magento\Eav\Model\Entity\AbstractEntity;
21+
use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
22+
use Magento\Framework\EntityManager\EntityMetadata;
23+
use Magento\Framework\EntityManager\MetadataPool;
24+
use PHPUnit\Framework\MockObject\MockObject;
25+
use PHPUnit\Framework\TestCase;
1326

1427
/**
1528
* Test for Magento\Catalog\Model\Product\Copier class.
1629
*
1730
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
1831
*/
19-
class CopierTest extends \PHPUnit\Framework\TestCase
32+
class CopierTest extends TestCase
2033
{
2134
/**
22-
* @var \PHPUnit_Framework_MockObject_MockObject
35+
* @var Copier
2336
*/
24-
private $optionRepositoryMock;
37+
private $_model;
2538

2639
/**
27-
* @var Copier
40+
* @var Repository|MockObject
2841
*/
29-
private $_model;
42+
private $optionRepositoryMock;
3043

3144
/**
32-
* @var \PHPUnit_Framework_MockObject_MockObject
45+
* @var CopyConstructorInterface|MockObject
3346
*/
3447
private $copyConstructorMock;
3548

3649
/**
37-
* @var \PHPUnit_Framework_MockObject_MockObject
50+
* @var ProductFactory|MockObject
3851
*/
3952
private $productFactoryMock;
4053

4154
/**
42-
* @var \PHPUnit_Framework_MockObject_MockObject
55+
* @var ScopeOverriddenValue|MockObject
4356
*/
4457
private $scopeOverriddenValueMock;
4558

4659
/**
47-
* @var \PHPUnit_Framework_MockObject_MockObject
60+
* @var Product|MockObject
4861
*/
4962
private $productMock;
5063

5164
/**
52-
* @var \PHPUnit_Framework_MockObject_MockObject
65+
* @var EntityMetadata|MockObject
5366
*/
5467
private $metadata;
5568

@@ -58,27 +71,23 @@ class CopierTest extends \PHPUnit\Framework\TestCase
5871
*/
5972
protected function setUp()
6073
{
61-
$this->copyConstructorMock = $this->createMock(\Magento\Catalog\Model\Product\CopyConstructorInterface::class);
62-
$this->productFactoryMock = $this->createPartialMock(
63-
\Magento\Catalog\Model\ProductFactory::class,
64-
['create']
65-
);
66-
$this->scopeOverriddenValueMock = $this->createMock(
67-
\Magento\Catalog\Model\Attribute\ScopeOverriddenValue::class
68-
);
69-
$this->optionRepositoryMock = $this->createMock(
70-
\Magento\Catalog\Model\Product\Option\Repository::class
71-
);
74+
$this->copyConstructorMock = $this->createMock(CopyConstructorInterface::class);
75+
$this->productFactoryMock = $this->createPartialMock(ProductFactory::class, ['create']);
76+
$this->scopeOverriddenValueMock = $this->createMock(ScopeOverriddenValue::class);
77+
$this->optionRepositoryMock = $this->createMock(Repository::class);
7278
$this->productMock = $this->createMock(Product::class);
73-
$this->productMock->expects($this->any())->method('getEntityId')->willReturn(1);
7479

75-
$this->metadata = $this->getMockBuilder(\Magento\Framework\EntityManager\EntityMetadata::class)
80+
$this->metadata = $this->getMockBuilder(EntityMetadata::class)
7681
->disableOriginalConstructor()
7782
->getMock();
78-
$metadataPool = $this->getMockBuilder(\Magento\Framework\EntityManager\MetadataPool::class)
83+
84+
/** @var MetadataPool|MockObject $metadataPool */
85+
$metadataPool = $this->getMockBuilder(MetadataPool::class)
7986
->disableOriginalConstructor()
8087
->getMock();
81-
$metadataPool->expects($this->any())->method('getMetadata')->willReturn($this->metadata);
88+
$metadataPool->expects($this->once())
89+
->method('getMetadata')
90+
->willReturn($this->metadata);
8291
$this->_model = new Copier(
8392
$this->copyConstructorMock,
8493
$this->productFactoryMock,
@@ -89,9 +98,12 @@ protected function setUp()
8998
}
9099

91100
/**
101+
* Test duplicate product
102+
*
103+
* @return void
92104
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
93105
*/
94-
public function testCopy()
106+
public function testCopy(): void
95107
{
96108
$stockItem = $this->createMock(StockItemInterface::class);
97109
$extensionAttributes = $this->getMockBuilder(ProductExtension::class)
@@ -110,51 +122,57 @@ public function testCopy()
110122
'product data' => ['product data'],
111123
ProductInterface::EXTENSION_ATTRIBUTES_KEY => $extensionAttributes,
112124
];
113-
$this->productMock->expects($this->atLeastOnce())->method('getWebsiteIds');
114-
$this->productMock->expects($this->atLeastOnce())->method('getCategoryIds');
115-
$this->productMock->expects($this->any())->method('getData')->willReturnMap([
116-
['', null, $productData],
117-
['linkField', null, '1'],
118-
]);
125+
$this->productMock->expects($this->atLeastOnce())
126+
->method('getWebsiteIds');
127+
$this->productMock->expects($this->atLeastOnce())
128+
->method('getCategoryIds');
129+
$this->productMock->expects($this->exactly(2))
130+
->method('getData')
131+
->willReturnMap([
132+
['', null, $productData],
133+
['linkField', null, '1'],
134+
]);
119135

120136
$entityMock = $this->getMockForAbstractClass(
121-
\Magento\Eav\Model\Entity\AbstractEntity::class,
137+
AbstractEntity::class,
122138
[],
123139
'',
124140
false,
125141
true,
126142
true,
127143
['checkAttributeUniqueValue']
128144
);
129-
$entityMock->expects($this->any())
145+
$entityMock->expects($this->once())
130146
->method('checkAttributeUniqueValue')
131147
->willReturn(true);
132148

133149
$attributeMock = $this->getMockForAbstractClass(
134-
\Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class,
150+
AbstractAttribute::class,
135151
[],
136152
'',
137153
false,
138154
true,
139155
true,
140156
['getEntity']
141157
);
142-
$attributeMock->expects($this->any())
158+
$attributeMock->expects($this->once())
143159
->method('getEntity')
144160
->willReturn($entityMock);
145161

146-
$resourceMock = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Product::class)
162+
$resourceMock = $this->getMockBuilder(ProductResourceModel::class)
147163
->disableOriginalConstructor()
148164
->setMethods(['getAttributeRawValue', 'duplicate', 'getAttribute'])
149165
->getMock();
150-
$resourceMock->expects($this->any())
166+
$resourceMock->expects($this->once())
151167
->method('getAttributeRawValue')
152168
->willReturn('urk-key-1');
153-
$resourceMock->expects($this->any())
169+
$resourceMock->expects($this->exactly(2))
154170
->method('getAttribute')
155171
->willReturn($attributeMock);
156172

157-
$this->productMock->expects($this->any())->method('getResource')->will($this->returnValue($resourceMock));
173+
$this->productMock->expects($this->exactly(2))
174+
->method('getResource')
175+
->willReturn($resourceMock);
158176

159177
$duplicateMock = $this->createPartialMock(
160178
Product::class,
@@ -176,51 +194,71 @@ public function testCopy()
176194
'getStoreIds',
177195
'setMetaTitle',
178196
'setMetaKeyword',
179-
'setMetaDescription'
197+
'setMetaDescription',
180198
]
181199
);
182-
$this->productFactoryMock->expects($this->once())->method('create')->will($this->returnValue($duplicateMock));
200+
$this->productFactoryMock->expects($this->once())
201+
->method('create')
202+
->willReturn($duplicateMock);
183203

184204
$duplicateMock->expects($this->once())->method('setOptions')->with([]);
185205
$duplicateMock->expects($this->once())->method('setIsDuplicate')->with(true);
186206
$duplicateMock->expects($this->once())->method('setOriginalLinkId')->with(1);
187-
$duplicateMock->expects(
188-
$this->once()
189-
)->method(
190-
'setStatus'
191-
)->with(
192-
\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_DISABLED
193-
);
207+
$duplicateMock->expects($this->once())
208+
->method('setStatus')
209+
->with(Status::STATUS_DISABLED);
194210
$duplicateMock->expects($this->atLeastOnce())->method('setStoreId');
195-
$duplicateMock->expects($this->once())->method('setCreatedAt')->with(null);
196-
$duplicateMock->expects($this->once())->method('setUpdatedAt')->with(null);
197-
$duplicateMock->expects($this->once())->method('setId')->with(null);
198-
$duplicateMock->expects($this->once())->method('setMetaTitle')->with(null);
199-
$duplicateMock->expects($this->once())->method('setMetaKeyword')->with(null);
200-
$duplicateMock->expects($this->once())->method('setMetaDescription')->with(null);
201-
$duplicateMock->expects($this->atLeastOnce())->method('getStoreIds')->willReturn([]);
202-
$duplicateMock->expects($this->atLeastOnce())->method('setData')->willReturn($duplicateMock);
203-
$this->copyConstructorMock->expects($this->once())->method('build')->with($this->productMock, $duplicateMock);
204-
$duplicateMock->expects($this->once())->method('setUrlKey')->with('urk-key-2')->willReturn($duplicateMock);
205-
$duplicateMock->expects($this->once())->method('save');
206-
207-
$this->metadata->expects($this->any())->method('getLinkField')->willReturn('linkField');
208-
209-
$duplicateMock->expects($this->any())->method('getData')->willReturnMap([
210-
['linkField', null, '2'],
211-
]);
211+
$duplicateMock->expects($this->once())
212+
->method('setCreatedAt')
213+
->with(null);
214+
$duplicateMock->expects($this->once())
215+
->method('setUpdatedAt')
216+
->with(null);
217+
$duplicateMock->expects($this->once())
218+
->method('setId')
219+
->with(null);
220+
$duplicateMock->expects($this->once())
221+
->method('setMetaTitle')
222+
->with(null);
223+
$duplicateMock->expects($this->once())
224+
->method('setMetaKeyword')
225+
->with(null);
226+
$duplicateMock->expects($this->once())
227+
->method('setMetaDescription')
228+
->with(null);
229+
$duplicateMock->expects($this->atLeastOnce())
230+
->method('getStoreIds')->willReturn([]);
231+
$duplicateMock->expects($this->atLeastOnce())
232+
->method('setData')
233+
->willReturn($duplicateMock);
234+
$this->copyConstructorMock->expects($this->once())
235+
->method('build')
236+
->with($this->productMock, $duplicateMock);
237+
$duplicateMock->expects($this->once())
238+
->method('setUrlKey')
239+
->with('urk-key-2')
240+
->willReturn($duplicateMock);
241+
$duplicateMock->expects($this->once())
242+
->method('save');
243+
$this->metadata->expects($this->once())
244+
->method('getLinkField')
245+
->willReturn('linkField');
246+
$duplicateMock->expects($this->never())
247+
->method('getData');
212248
$this->optionRepositoryMock->expects($this->once())
213249
->method('duplicate')
214250
->with($this->productMock, $duplicateMock);
215-
$resourceMock->expects($this->once())->method('duplicate')->with(1, 2);
216251

217252
$this->assertEquals($duplicateMock, $this->_model->copy($this->productMock));
218253
}
219254

220255
/**
256+
* Test duplicate product with `UrlAlreadyExistsException` while copy stores url
257+
*
258+
* @return void
221259
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
222260
*/
223-
public function testUrlAlreadyExistsExceptionWhileCopyStoresUrl()
261+
public function testUrlAlreadyExistsExceptionWhileCopyStoresUrl(): void
224262
{
225263
$stockItem = $this->getMockBuilder(StockItemInterface::class)
226264
->getMock();

0 commit comments

Comments
 (0)