Skip to content

Commit 8291220

Browse files
committed
MC-29188: Storefront: Create configurable product on (multiple websites/multiple storeviews)
1 parent 0c13c55 commit 8291220

File tree

2 files changed

+103
-96
lines changed

2 files changed

+103
-96
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\TestFramework\Store;
9+
10+
use Magento\Store\Api\Data\StoreInterface;
11+
use Magento\Store\Model\StoreManagerInterface;
12+
13+
/**
14+
* Execute operation in specified store
15+
*/
16+
class ExecuteInStoreContext
17+
{
18+
/** @var StoreManagerInterface */
19+
private $storeManager;
20+
21+
/**
22+
* @param StoreManagerInterface $storeManager
23+
*/
24+
public function __construct(StoreManagerInterface $storeManager)
25+
{
26+
$this->storeManager = $storeManager;
27+
}
28+
29+
/**
30+
* Execute callback in store context
31+
*
32+
* @param callable $method
33+
* @param array $arguments
34+
* @param null|string|bool|int|StoreInterface $store
35+
* @return void
36+
*/
37+
public function execute(callable $method, array $arguments, $store = 'default'): void
38+
{
39+
$currentStore = $this->storeManager->getStore();
40+
try {
41+
$this->storeManager->setCurrentStore($store);
42+
$method(...$arguments);
43+
} finally {
44+
$this->storeManager->setCurrentStore($currentStore);
45+
}
46+
}
47+
}

dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Product/View/Type/MultiStoreConfigurableViewOnProductPageTest.php

Lines changed: 56 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Magento\Framework\View\LayoutInterface;
1717
use Magento\Store\Model\StoreManagerInterface;
1818
use Magento\TestFramework\Helper\Bootstrap;
19+
use Magento\TestFramework\Store\ExecuteInStoreContext;
1920
use PHPUnit\Framework\TestCase;
2021

2122
/**
@@ -34,9 +35,6 @@ class MultiStoreConfigurableViewOnProductPageTest extends TestCase
3435
/** @var StoreManagerInterface */
3536
private $storeManager;
3637

37-
/** @var Configurable */
38-
private $block;
39-
4038
/** @var LayoutInterface */
4139
private $layout;
4240

@@ -46,6 +44,9 @@ class MultiStoreConfigurableViewOnProductPageTest extends TestCase
4644
/** @var ProductResource */
4745
private $productResource;
4846

47+
/** @var ExecuteInStoreContext */
48+
private $executeInStoreContext;
49+
4950
/**
5051
* @inheritdoc
5152
*/
@@ -58,9 +59,9 @@ protected function setUp()
5859
$this->productRepository->cleanCache();
5960
$this->storeManager = $this->objectManager->get(StoreManagerInterface::class);
6061
$this->layout = $this->objectManager->get(LayoutInterface::class);
61-
$this->block = $this->layout->createBlock(Configurable::class);
6262
$this->serializer = $this->objectManager->get(SerializerInterface::class);
6363
$this->productResource = $this->objectManager->get(ProductResource::class);
64+
$this->executeInStoreContext = $this->objectManager->get(ExecuteInStoreContext::class);
6465
}
6566

6667
/**
@@ -74,8 +75,12 @@ protected function setUp()
7475
*/
7576
public function testMultiStoreLabelView(array $expectedStoreData, array $expectedSecondStoreData): void
7677
{
77-
$this->assertProductLabelConfigDataPerStore($expectedStoreData);
78-
$this->assertProductLabelConfigDataPerStore($expectedSecondStoreData, 'fixturestore', true);
78+
$this->executeInStoreContext->execute([$this, 'assertProductLabel'], [$expectedStoreData]);
79+
$this->executeInStoreContext->execute(
80+
[$this, 'assertProductLabel'],
81+
[$expectedSecondStoreData],
82+
'fixturestore'
83+
);
7984
}
8085

8186
/**
@@ -111,6 +116,20 @@ public function expectedLabelsDataProvider(): array
111116
];
112117
}
113118

119+
/**
120+
* Assert configurable product labels config
121+
*
122+
* @param $expectedStoreData
123+
* @return void
124+
*/
125+
public function assertProductLabel($expectedStoreData): void
126+
{
127+
$product = $this->productRepository->get('configurable', false, null, true);
128+
$config = $this->getBlockConfig($product)['attributes'] ?? null;
129+
$this->assertNotNull($config);
130+
$this->assertAttributeConfig($expectedStoreData, reset($config));
131+
}
132+
114133
/**
115134
* @magentoDataFixture Magento/ConfigurableProduct/_files/configurable_product_two_websites.php
116135
*
@@ -123,8 +142,12 @@ public function expectedLabelsDataProvider(): array
123142
public function testMultiStoreOptionsView(array $expectedProducts, array $expectedSecondStoreProducts): void
124143
{
125144
$this->prepareConfigurableProduct('configurable', 'fixture_second_store');
126-
$this->assertProductConfigPerStore($expectedProducts);
127-
$this->assertProductConfigPerStore($expectedSecondStoreProducts, 'fixture_second_store', true);
145+
$this->executeInStoreContext->execute([$this, 'assertProductConfig'], [$expectedProducts]);
146+
$this->executeInStoreContext->execute(
147+
[$this, 'assertProductConfig'],
148+
[$expectedSecondStoreProducts],
149+
'fixture_second_store'
150+
);
128151
}
129152

130153
/**
@@ -140,6 +163,20 @@ public function expectedProductDataProvider(): array
140163
];
141164
}
142165

166+
/**
167+
* Assert configurable product config
168+
*
169+
* @param $expectedProducts
170+
* @return void
171+
*/
172+
public function assertProductConfig($expectedProducts): void
173+
{
174+
$product = $this->productRepository->get('configurable', false, null, true);
175+
$config = $this->getBlockConfig($product)['index'] ?? null;
176+
$this->assertNotNull($config);
177+
$this->assertProducts($expectedProducts, $config);
178+
}
179+
143180
/**
144181
* Prepare configurable product to test
145182
*
@@ -150,9 +187,10 @@ public function expectedProductDataProvider(): array
150187
private function prepareConfigurableProduct(string $sku, string $storeCode): void
151188
{
152189
$product = $this->productRepository->get($sku, false, null, true);
153-
$productToUpdate = $product->getTypeInstance()->getUsedProductCollection($product)->getFirstItem();
190+
$productToUpdate = $product->getTypeInstance()->getUsedProductCollection($product)
191+
->setPageSize(1)->getFirstItem();
154192
$this->assertNotEmpty($productToUpdate->getData(), 'Configurable product does not have a child');
155-
$this->setProductDisabledPerStore($productToUpdate, $storeCode);
193+
$this->executeInStoreContext->execute([$this, 'setProductDisabled'], [$productToUpdate], $storeCode);
156194
}
157195

158196
/**
@@ -162,7 +200,7 @@ private function prepareConfigurableProduct(string $sku, string $storeCode): voi
162200
* @param array $config
163201
* @return void
164202
*/
165-
private function assertProductConfig(array $expectedProducts, array $config): void
203+
private function assertProducts(array $expectedProducts, array $config): void
166204
{
167205
$this->assertCount(count($expectedProducts), $config);
168206
$idsBySkus = $this->productResource->getProductsIdsBySkus($expectedProducts);
@@ -179,102 +217,24 @@ private function assertProductConfig(array $expectedProducts, array $config): vo
179217
* @param string $storeCode
180218
* @return void
181219
*/
182-
private function setProductDisabledPerStore(ProductInterface $product, string $storeCode): void
220+
public function setProductDisabled(ProductInterface $product): void
183221
{
184-
$currentStore = $this->storeManager->getStore();
185-
try {
186-
$this->storeManager->setCurrentStore($storeCode);
187-
$product->setStatus(Status::STATUS_DISABLED);
188-
$this->productRepository->save($product);
189-
} finally {
190-
$this->storeManager->setCurrentStore($currentStore);
191-
}
192-
}
193-
194-
/**
195-
* Assert configurable product config per stores
196-
*
197-
* @param array $expectedProducts
198-
* @param string $storeCode
199-
* @param bool $refreshBlock
200-
* @return void
201-
*/
202-
private function assertProductConfigPerStore(
203-
array $expectedProducts,
204-
string $storeCode = 'default',
205-
bool $refreshBlock = false
206-
): void {
207-
$currentStore = $this->storeManager->getStore();
208-
try {
209-
if ($currentStore->getCode() !== $storeCode) {
210-
$this->storeManager->setCurrentStore($storeCode);
211-
}
212-
$product = $this->productRepository->get('configurable', false, null, true);
213-
$config = $this->getBlockConfig($product, $refreshBlock)['index'] ?? null;
214-
$this->assertNotNull($config);
215-
$this->assertProductConfig($expectedProducts, $config);
216-
} finally {
217-
if ($currentStore->getCode() !== $storeCode) {
218-
$this->storeManager->setCurrentStore($currentStore);
219-
}
220-
}
221-
}
222-
223-
/**
224-
* Assert configurable product labels config per stores
225-
*
226-
* @param array $expectedStoreData
227-
* @param string $storeCode
228-
* @param bool $refreshBlock
229-
* @return void
230-
*/
231-
private function assertProductLabelConfigDataPerStore(
232-
array $expectedStoreData,
233-
string $storeCode = 'default',
234-
bool $refreshBlock = false
235-
): void {
236-
$currentStore = $this->storeManager->getStore();
237-
try {
238-
if ($currentStore->getCode() !== $storeCode) {
239-
$this->storeManager->setCurrentStore($storeCode);
240-
}
241-
$product = $this->productRepository->get('configurable', false, null, true);
242-
$config = $this->getBlockConfig($product, $refreshBlock)['attributes'] ?? null;
243-
$this->assertNotNull($config);
244-
$this->assertAttributeConfig($expectedStoreData, reset($config));
245-
} finally {
246-
if ($currentStore->getCode() !== $storeCode) {
247-
$this->storeManager->setCurrentStore($currentStore);
248-
}
249-
}
250-
}
251-
252-
/**
253-
* Get view block
254-
*
255-
* @param bool $refresh
256-
* @return Configurable
257-
*/
258-
private function getBlock(bool $refresh = false): Configurable
259-
{
260-
if ($refresh) {
261-
$this->block = $this->layout->createBlock(Configurable::class);
262-
}
263-
return $this->block;
222+
$product->setStatus(Status::STATUS_DISABLED);
223+
$this->productRepository->save($product);
264224
}
265225

266226
/**
267227
* Get block config
268228
*
269229
* @param ProductInterface $product
270-
* @param bool $refreshBlock
271230
* @return array
272231
*/
273-
private function getBlockConfig(ProductInterface $product, bool $refreshBlock): array
232+
private function getBlockConfig(ProductInterface $product): array
274233
{
275-
$this->getBlock($refreshBlock)->setProduct($product);
234+
$block = $this->layout->createBlock(Configurable::class);
235+
$block->setProduct($product);
276236

277-
return $this->serializer->unserialize($this->getBlock()->getJsonConfig());
237+
return $this->serializer->unserialize($block->getJsonConfig());
278238
}
279239

280240
/**

0 commit comments

Comments
 (0)