Skip to content

Commit ecd6a67

Browse files
committed
MAGETWO-56862: [Github] Saving Product does not update URL rewrite in Magento 2.1.0 with single-store mode #5929
2 parents 1b719ef + 94dc702 commit ecd6a67

File tree

2 files changed

+103
-144
lines changed
  • app/code/Magento/Catalog
    • Controller/Adminhtml/Product/Initialization
    • Test/Unit/Controller/Adminhtml/Product/Initialization

2 files changed

+103
-144
lines changed

app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,7 @@ public function initializeFromData(\Magento\Catalog\Model\Product $product, arra
131131
$productData[$field] = [];
132132
}
133133
}
134-
135-
foreach ($productData['website_ids'] as $websiteId => $checkboxValue) {
136-
if (!$checkboxValue) {
137-
unset($productData['website_ids'][$websiteId]);
138-
}
139-
}
134+
$productData['website_ids'] = $this->filterWebsiteIds($productData['website_ids']);
140135

141136
$wasLockedMedia = false;
142137
if ($product->isLockedAttribute('media')) {
@@ -422,4 +417,23 @@ private function getDateTimeFilter()
422417
}
423418
return $this->dateTimeFilter;
424419
}
420+
421+
/**
422+
* Remove ids of non selected websites from $websiteIds array and return filtered data
423+
* $websiteIds parameter expects array with website ids as keys and 1 (selected) or 0 (non selected) as values
424+
* Only one id (default website ID) will be set to $websiteIds array when the single store mode is turned on
425+
*
426+
* @param array $websiteIds
427+
* @return array
428+
*/
429+
private function filterWebsiteIds($websiteIds)
430+
{
431+
if (!$this->storeManager->isSingleStoreMode()) {
432+
$websiteIds = array_filter((array)$websiteIds);
433+
} else {
434+
$websiteIds[$this->storeManager->getWebsite(true)->getId()] = 1;
435+
}
436+
437+
return $websiteIds;
438+
}
425439
}

app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php

Lines changed: 83 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,14 @@
55
*/
66
namespace Magento\Catalog\Test\Unit\Controller\Adminhtml\Product\Initialization;
77

8-
use Magento\Catalog\Api\Data\ProductLinkInterfaceFactory;
98
use Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper;
109
use Magento\Catalog\Controller\Adminhtml\Product\Initialization\StockDataFilter;
1110
use Magento\Catalog\Model\Product;
1211
use Magento\Catalog\Model\Product\Option;
13-
use Magento\Catalog\Model\ProductRepository;
1412
use Magento\Framework\App\RequestInterface;
1513
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
16-
use Magento\Store\Api\Data\StoreInterface;
1714
use Magento\Store\Api\Data\WebsiteInterface;
1815
use Magento\Store\Model\StoreManagerInterface;
19-
use Magento\Framework\Stdlib\DateTime\Filter\Date as DateFilter;
2016
use Magento\Catalog\Api\Data\ProductCustomOptionInterfaceFactory;
2117
use Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks;
2218

@@ -34,11 +30,6 @@ class HelperTest extends \PHPUnit_Framework_TestCase
3430
*/
3531
protected $objectManager;
3632

37-
/**
38-
* @var int
39-
*/
40-
protected $websiteId = 1;
41-
4233
/**
4334
* @var Helper
4435
*/
@@ -64,106 +55,54 @@ class HelperTest extends \PHPUnit_Framework_TestCase
6455
*/
6556
protected $productMock;
6657

67-
/**
68-
* @var StoreInterface|\PHPUnit_Framework_MockObject_MockObject
69-
*/
70-
protected $storeMock;
71-
72-
/**
73-
* @var WebsiteInterface|\PHPUnit_Framework_MockObject_MockObject
74-
*/
75-
protected $websiteMock;
76-
77-
/**
78-
* @var DateFilter|\PHPUnit_Framework_MockObject_MockObject
79-
*/
80-
protected $dateFilterMock;
81-
82-
/**
83-
* @var ProductLinkInterfaceFactory|\PHPUnit_Framework_MockObject_MockObject
84-
*/
85-
protected $productLinkFactoryMock;
86-
87-
/**
88-
* @var ProductRepository|\PHPUnit_Framework_MockObject_MockObject
89-
*/
90-
protected $productRepositoryMock;
91-
9258
/**
9359
* @var ProductCustomOptionInterfaceFactory|\PHPUnit_Framework_MockObject_MockObject
9460
*/
9561
protected $customOptionFactoryMock;
9662

9763
/**
98-
* @var Option|\PHPUnit_Framework_MockObject_MockObject
99-
*/
100-
protected $customOptionMock;
101-
102-
/**
103-
* @var \PHPUnit_Framework_MockObject_MockObject
64+
* @var \Magento\Catalog\Model\Product\Link\Resolver|\PHPUnit_Framework_MockObject_MockObject
10465
*/
10566
protected $linkResolverMock;
10667

10768
/**
108-
* @var ProductLinks
69+
* @var ProductLinks|\PHPUnit_Framework_MockObject_MockObject
10970
*/
11071
protected $productLinksMock;
11172

11273
protected function setUp()
11374
{
11475
$this->objectManager = new ObjectManager($this);
115-
$this->productLinkFactoryMock = $this->getMockBuilder(ProductLinkInterfaceFactory::class)
116-
->disableOriginalConstructor()
117-
->getMock();
118-
$this->productRepositoryMock = $this->getMockBuilder(ProductRepository::class)
119-
->disableOriginalConstructor()
120-
->getMock();
12176
$this->requestMock = $this->getMockBuilder(RequestInterface::class)
12277
->setMethods(['getPost'])
12378
->getMockForAbstractClass();
124-
$this->storeMock = $this->getMockBuilder(StoreInterface::class)
125-
->setMethods(['getWebsite'])
126-
->getMockForAbstractClass();
127-
$this->websiteMock = $this->getMockBuilder(WebsiteInterface::class)
128-
->getMockForAbstractClass();
12979
$this->storeManagerMock = $this->getMockBuilder(StoreManagerInterface::class)
13080
->getMockForAbstractClass();
131-
$this->dateFilterMock = $this->getMockBuilder(DateFilter::class)
132-
->disableOriginalConstructor()
133-
->getMock();
13481
$this->stockFilterMock = $this->getMockBuilder(StockDataFilter::class)
13582
->disableOriginalConstructor()
13683
->getMock();
13784
$this->productMock = $this->getMockBuilder(Product::class)
138-
->setMethods([
139-
'getId',
140-
'setWebsiteIds',
141-
'isLockedAttribute',
142-
'lockAttribute',
143-
'getAttributes',
144-
'unlockAttribute',
145-
'getOptionsReadOnly',
146-
'setCanSaveCustomOptions',
147-
'__sleep',
148-
'__wakeup',
149-
'getSku',
150-
'getProductLinks',
151-
'getWebsiteIds'
152-
])
85+
->setMethods(
86+
[
87+
'getId',
88+
'isLockedAttribute',
89+
'lockAttribute',
90+
'getAttributes',
91+
'unlockAttribute',
92+
'getOptionsReadOnly',
93+
'getSku',
94+
'getProductLinks',
95+
]
96+
)
15397
->disableOriginalConstructor()
154-
->getMock();
98+
->getMockForAbstractClass();
15599
$this->customOptionFactoryMock = $this->getMockBuilder(ProductCustomOptionInterfaceFactory::class)
156100
->disableOriginalConstructor()
157101
->setMethods(['create'])
158102
->getMock();
159-
$this->customOptionMock = $this->getMockBuilder(Option::class)
160-
->disableOriginalConstructor()
161-
->setMethods(null)
162-
->getMock();
163103
$this->productLinksMock = $this->getMockBuilder(ProductLinks::class)
164104
->disableOriginalConstructor()
165105
->getMock();
166-
167106
$this->productLinksMock->expects($this->any())
168107
->method('initializeLinks')
169108
->willReturn($this->productMock);
@@ -173,10 +112,7 @@ protected function setUp()
173112
'storeManager' => $this->storeManagerMock,
174113
'stockFilter' => $this->stockFilterMock,
175114
'productLinks' => $this->productLinksMock,
176-
'dateFilter' => $this->dateFilterMock,
177115
'customOptionFactory' => $this->customOptionFactoryMock,
178-
'productLinkFactory' => $this->productLinkFactoryMock,
179-
'productRepository' => $this->productRepositoryMock,
180116
]);
181117

182118
$this->linkResolverMock = $this->getMockBuilder(\Magento\Catalog\Model\Product\Link\Resolver::class)
@@ -190,9 +126,13 @@ protected function setUp()
190126

191127
/**
192128
* @covers \Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper::initialize
193-
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
129+
* @param bool $isSingleStore
130+
* @param array $websiteIds
131+
* @param array $expWebsiteIds
132+
*
133+
* @dataProvider initializeDataProvider
194134
*/
195-
public function testInitialize()
135+
public function testInitialize($isSingleStore, $websiteIds, $expWebsiteIds)
196136
{
197137
$optionsData = [
198138
'option1' => ['is_delete' => true, 'name' => 'name1', 'price' => 'price1', 'option_id' => ''],
@@ -202,6 +142,7 @@ public function testInitialize()
202142
$productData = [
203143
'stock_data' => ['stock_data'],
204144
'options' => $optionsData,
145+
'website_ids' => $websiteIds
205146
];
206147
$attributeNonDate = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class)
207148
->disableOriginalConstructor()
@@ -218,69 +159,39 @@ public function testInitialize()
218159
->disableOriginalConstructor()
219160
->getMock();
220161

221-
$attributeNonDate->expects($this->any())
222-
->method('getBackend')
223-
->willReturn($attributeNonDateBackEnd);
224-
$attributeDate->expects($this->any())
225-
->method('getBackend')
226-
->willReturn($attributeDateBackEnd);
227-
$this->productMock->expects($this->any())
228-
->method('getProductLinks')
229-
->willReturn([]);
230-
$attributeNonDateBackEnd->expects($this->any())
231-
->method('getType')
232-
->willReturn('non-datetime');
233-
$attributeDateBackEnd->expects($this->any())
234-
->method('getType')
235-
->willReturn('datetime');
236-
237-
$attributesArray = [
238-
$attributeNonDate,
239-
$attributeDate
240-
];
162+
$attributeNonDate->expects($this->any())->method('getBackend')->willReturn($attributeNonDateBackEnd);
163+
$attributeDate->expects($this->any())->method('getBackend')->willReturn($attributeDateBackEnd);
164+
$this->productMock->expects($this->any())->method('getProductLinks')->willReturn([]);
165+
$attributeNonDateBackEnd->expects($this->any())->method('getType')->willReturn('non-datetime');
166+
$attributeDateBackEnd->expects($this->any())->method('getType')->willReturn('datetime');
241167

242168
$useDefaults = ['attributeCode1', 'attributeCode2'];
243169

244-
$this->requestMock->expects($this->at(0))
245-
->method('getPost')
246-
->with('product')
247-
->willReturn($productData);
248-
$this->requestMock->expects($this->at(1))
249-
->method('getPost')
250-
->with('use_default')
251-
->willReturn($useDefaults);
170+
$this->requestMock->expects($this->any())->method('getPost')->willReturnMap(
171+
[
172+
['product', [], $productData],
173+
['use_default', null, $useDefaults]
174+
]
175+
);
252176
$this->linkResolverMock->expects($this->once())->method('getLinks')->willReturn([]);
253-
$this->stockFilterMock->expects($this->once())
254-
->method('filter')
255-
->with(['stock_data'])
177+
$this->stockFilterMock->expects($this->once())->method('filter')->with(['stock_data'])
256178
->willReturn(['stock_data']);
257-
$this->productMock->expects($this->once())
258-
->method('isLockedAttribute')
259-
->with('media')
260-
->willReturn(true);
261-
$this->productMock->expects($this->once())
262-
->method('unlockAttribute')
263-
->with('media');
264-
$this->productMock->expects($this->any())
265-
->method('getProductLinks')
266-
->willReturn([]);
267-
$this->productMock->expects($this->once())
268-
->method('lockAttribute')
269-
->with('media');
270-
$this->productMock->expects($this->once())
271-
->method('getAttributes')
272-
->willReturn($attributesArray);
273-
274-
$this->productMock->expects($this->any())
275-
->method('getSku')
276-
->willReturn('sku');
277-
$this->productMock->expects($this->any())
278-
->method('getOptionsReadOnly')
279-
->willReturn(false);
280-
281-
$firstExpectedCustomOption = clone $this->customOptionMock;
179+
$this->productMock->expects($this->once())->method('isLockedAttribute')->with('media')->willReturn(true);
180+
$this->productMock->expects($this->once())->method('unlockAttribute')->with('media');
181+
$this->productMock->expects($this->any())->method('getProductLinks')->willReturn([]);
182+
$this->productMock->expects($this->once())->method('lockAttribute')->with('media');
183+
$this->productMock->expects($this->once())->method('getAttributes')
184+
->willReturn([$attributeNonDate, $attributeDate]);
185+
$this->productMock->expects($this->any())->method('getSku')->willReturn('sku');
186+
$this->productMock->expects($this->any())->method('getOptionsReadOnly')->willReturn(false);
187+
188+
$customOptionMock = $this->getMockBuilder(Option::class)
189+
->disableOriginalConstructor()
190+
->setMethods(null)
191+
->getMock();
192+
$firstExpectedCustomOption = clone $customOptionMock;
282193
$firstExpectedCustomOption->setData($optionsData['option2']);
283-
$secondExpectedCustomOption = clone $this->customOptionMock;
194+
$secondExpectedCustomOption = clone $customOptionMock;
284195
$secondExpectedCustomOption->setData($optionsData['option3']);
285196
$this->customOptionFactoryMock->expects($this->any())
286197
->method('create')
@@ -293,8 +204,13 @@ public function testInitialize()
293204
$secondExpectedCustomOption
294205
]
295206
]);
207+
$website = $this->getMockBuilder(WebsiteInterface::class)->getMockForAbstractClass();
208+
$website->expects($this->any())->method('getId')->willReturn(1);
209+
$this->storeManagerMock->expects($this->once())->method('isSingleStoreMode')->willReturn($isSingleStore);
210+
$this->storeManagerMock->expects($this->any())->method('getWebsite')->willReturn($website);
296211

297212
$this->assertEquals($this->productMock, $this->helper->initialize($this->productMock));
213+
$this->assertEquals($expWebsiteIds, $this->productMock->getDataByKey('website_ids'));
298214

299215
$productOptions = $this->productMock->getOptions();
300216
$this->assertTrue(2 == count($productOptions));
@@ -305,6 +221,35 @@ public function testInitialize()
305221
$this->assertTrue('sku' == $option2->getData('product_sku'));
306222
}
307223

224+
/**
225+
* @return array
226+
*/
227+
public function initializeDataProvider()
228+
{
229+
return [
230+
[
231+
'single_store' => false,
232+
'website_ids' => ['1' => 1, '2' => 1],
233+
'expected_website_ids' => ['1' => 1, '2' => 1]
234+
],
235+
[
236+
'single_store' => false,
237+
'website_ids' => ['1' => 1, '2' => 0],
238+
'expected_website_ids' => ['1' => 1]
239+
],
240+
[
241+
'single_store' => false,
242+
'website_ids' => ['1' => 0, '2' => 0],
243+
'expected_website_ids' => []
244+
],
245+
[
246+
'single_store' => true,
247+
'website_ids' => [],
248+
'expected_website_ids' => ['1' => 1]
249+
],
250+
];
251+
}
252+
308253
/**
309254
* Data provider for testMergeProductOptions
310255
*

0 commit comments

Comments
 (0)