Skip to content

Commit eff3d42

Browse files
committed
MC-30330: Storefront: View configurable product on storefront
1 parent f9a8884 commit eff3d42

9 files changed

+1098
-36
lines changed

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

Lines changed: 127 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,79 +3,102 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\ConfigurableProduct\Block\Product\View\Type;
79

10+
use Magento\Catalog\Api\ProductRepositoryInterface;
11+
use Magento\Catalog\Model\Product;
12+
use Magento\Catalog\Model\ResourceModel\Product as ProductResource;
13+
use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Attribute\Collection;
14+
use Magento\Framework\ObjectManagerInterface;
15+
use Magento\Framework\Serialize\SerializerInterface;
16+
use Magento\Framework\View\LayoutInterface;
17+
use Magento\TestFramework\Helper\Bootstrap;
18+
use PHPUnit\Framework\TestCase;
19+
820
/**
9-
* Test class for \Magento\ConfigurableProduct\Block\Product\View\Type\Configurable.
21+
* Test class to check configurable product view behaviour
22+
*
23+
* @see \Magento\ConfigurableProduct\Block\Product\View\Type\Configurable
1024
*
1125
* @magentoAppIsolation enabled
1226
* @magentoDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
1327
*/
14-
class ConfigurableTest extends \PHPUnit\Framework\TestCase
28+
class ConfigurableTest extends TestCase
1529
{
16-
/**
17-
* @var \Magento\ConfigurableProduct\Block\Product\View\Type\Configurable
18-
*/
19-
protected $_block;
30+
/** @var ObjectManagerInterface */
31+
private $objectManager;
32+
33+
/** @var Configurable */
34+
private $block;
35+
36+
/** @var Product */
37+
private $product;
38+
39+
/** @var LayoutInterface */
40+
private $layout;
41+
42+
/** @var ProductRepositoryInterface */
43+
private $productRepository;
44+
45+
/** @var SerializerInterface */
46+
private $json;
47+
48+
/** @var ProductResource */
49+
private $productResource;
2050

2151
/**
22-
* @var \Magento\Catalog\Model\Product
52+
* @inheritdoc
2353
*/
24-
protected $_product;
25-
2654
protected function setUp()
2755
{
28-
$this->_product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
29-
\Magento\Catalog\Model\Product::class
30-
);
31-
$this->_product->load(1);
32-
$this->_block = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
33-
\Magento\Framework\View\LayoutInterface::class
34-
)->createBlock(
35-
\Magento\ConfigurableProduct\Block\Product\View\Type\Configurable::class
36-
);
37-
$this->_block->setProduct($this->_product);
56+
$this->objectManager = Bootstrap::getObjectManager();
57+
$this->productRepository = $this->objectManager->create(ProductRepositoryInterface::class);
58+
$this->product = $this->productRepository->get('configurable');
59+
$this->layout = $this->objectManager->get(LayoutInterface::class);
60+
$this->block = $this->layout->createBlock(Configurable::class);
61+
$this->json = $this->objectManager->get(SerializerInterface::class);
62+
$this->block->setProduct($this->product);
63+
$this->productResource = $this->objectManager->create(ProductResource::class);
3864
}
3965

4066
/**
41-
* @magentoAppIsolation enabled
67+
* @return void
4268
*/
43-
public function testGetAllowAttributes()
69+
public function testGetAllowAttributes(): void
4470
{
45-
$attributes = $this->_block->getAllowAttributes();
46-
$this->assertInstanceOf(
47-
\Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Attribute\Collection::class,
48-
$attributes
49-
);
71+
$attributes = $this->block->getAllowAttributes();
72+
$this->assertInstanceOf(Collection::class, $attributes);
5073
$this->assertGreaterThanOrEqual(1, $attributes->getSize());
5174
}
5275

5376
/**
54-
* @magentoAppIsolation enabled
77+
* @return void
5578
*/
56-
public function testHasOptions()
79+
public function testHasOptions(): void
5780
{
58-
$this->assertTrue($this->_block->hasOptions());
81+
$this->assertTrue($this->block->hasOptions());
5982
}
6083

6184
/**
62-
* @magentoAppIsolation enabled
85+
* @return void
6386
*/
64-
public function testGetAllowProducts()
87+
public function testGetAllowProducts(): void
6588
{
66-
$products = $this->_block->getAllowProducts();
89+
$products = $this->block->getAllowProducts();
6790
$this->assertGreaterThanOrEqual(2, count($products));
6891
foreach ($products as $product) {
69-
$this->assertInstanceOf(\Magento\Catalog\Model\Product::class, $product);
92+
$this->assertInstanceOf(Product::class, $product);
7093
}
7194
}
7295

7396
/**
74-
* @magentoAppIsolation enabled
97+
* @return void
7598
*/
76-
public function testGetJsonConfig()
99+
public function testGetJsonConfig(): void
77100
{
78-
$config = json_decode($this->_block->getJsonConfig(), true);
101+
$config = $this->json->unserialize($this->block->getJsonConfig());
79102
$this->assertNotEmpty($config);
80103
$this->assertArrayHasKey('productId', $config);
81104
$this->assertEquals(1, $config['productId']);
@@ -84,4 +107,72 @@ public function testGetJsonConfig()
84107
$this->assertArrayHasKey('prices', $config);
85108
$this->assertArrayHasKey('basePrice', $config['prices']);
86109
}
110+
111+
/**
112+
* @dataProvider expectedDataProvider
113+
*
114+
* @param string $label
115+
* @param array $expectedConfig
116+
* @return void
117+
*/
118+
public function testConfigurableProductView(string $label, array $expectedConfig): void
119+
{
120+
$attributes = $this->block->decorateArray($this->block->getAllowAttributes());
121+
$this->assertCount(1, $attributes);
122+
$attribute = $attributes->getFirstItem();
123+
$this->assertEquals($label, $attribute->getLabel());
124+
$config = $this->json->unserialize($this->block->getJsonConfig())['attributes'] ?? null;
125+
$this->assertNotNull($config);
126+
$this->assertConfig(reset($config), $expectedConfig);
127+
}
128+
129+
/**
130+
* @return array
131+
*/
132+
public function expectedDataProvider(): array
133+
{
134+
return [
135+
[
136+
'label' => 'Test Configurable',
137+
'config_data' => [
138+
'label' => 'Test Configurable',
139+
'options' => [
140+
[
141+
'label' => 'Option 1',
142+
'sku' => 'simple_10',
143+
],
144+
[
145+
'label' => 'Option 2',
146+
'sku' => 'simple_20',
147+
],
148+
],
149+
],
150+
],
151+
];
152+
}
153+
154+
/**
155+
* Assert that data was generated
156+
*
157+
* @param array $data
158+
* @param array $expectedData
159+
* @return void
160+
*/
161+
private function assertConfig($data, $expectedData): void
162+
{
163+
$this->assertEquals($expectedData['label'], $data['label']);
164+
$skus = array_column($expectedData['options'], 'sku');
165+
$idBySkuMap = $this->productResource->getProductsIdsBySkus($skus);
166+
foreach ($expectedData['options'] as &$option) {
167+
$sku = $option['sku'];
168+
unset($option['sku']);
169+
$option['products'] = [$idBySkuMap[$sku]];
170+
foreach ($data['options'] as $actualOption) {
171+
if ($option['label'] === $actualOption['label']) {
172+
unset($actualOption['id']);
173+
$this->assertEquals($option, $actualOption);
174+
}
175+
}
176+
}
177+
}
87178
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
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\Swatches\Block\Product\Renderer\Configurable\Listing;
9+
10+
use Magento\Swatches\Block\Product\Renderer\Configurable\ProductPageViewTest;
11+
use Magento\Swatches\Block\Product\Renderer\Listing\Configurable;
12+
13+
/**
14+
* Test class to check configurable product with swatch attributes view behaviour on category page
15+
*
16+
* @magentoDbIsolation enabled
17+
* @magentoAppIsolation enabled
18+
*/
19+
class CategoryPageViewTest extends ProductPageViewTest
20+
{
21+
/**
22+
* @inheritdoc
23+
*/
24+
protected function setUp()
25+
{
26+
parent::setUp();
27+
28+
$this->block = $this->layout->createBlock(Configurable::class);
29+
$this->template = 'Magento_Swatches::product/listing/renderer.phtml';
30+
}
31+
32+
/**
33+
* @magentoDataFixture Magento/Swatches/_files/configurable_product_visual_swatch_attribute.php
34+
*
35+
* @dataProvider expectedVisualSwatchDataProvider
36+
*
37+
* @param array $expectedConfig
38+
* @param array $expectedSwatchConfig
39+
* @return void
40+
*/
41+
public function testCategoryPageVisualSwatchAttributeView(array $expectedConfig, array $expectedSwatchConfig): void
42+
{
43+
$this->checkProductViewCategoryPage($expectedConfig, $expectedSwatchConfig, ['visual_swatch_attribute']);
44+
}
45+
46+
/**
47+
* @magentoDataFixture Magento/Swatches/_files/configurable_product_text_swatch_attribute.php
48+
*
49+
* @dataProvider expectedTextSwatchDataProvider
50+
*
51+
* @param array $expectedConfig
52+
* @param array $expectedSwatchConfig
53+
* @return void
54+
*/
55+
public function testCategoryPageTextSwatchAttributeView(array $expectedConfig, array $expectedSwatchConfig): void
56+
{
57+
$this->checkProductViewCategoryPage($expectedConfig, $expectedSwatchConfig, ['text_swatch_attribute']);
58+
}
59+
60+
/**
61+
* @magentoDataFixture Magento/Swatches/_files/configurable_product_two_attributes.php
62+
*
63+
* @dataProvider expectedTwoAttributesProvider
64+
*
65+
* @param array $expectedConfig
66+
* @param array $expectedSwatchConfig
67+
* @return void
68+
*/
69+
public function testCategoryPageTwoAttributesView(array $expectedConfig, array $expectedSwatchConfig): void
70+
{
71+
$this->checkProductViewCategoryPage(
72+
$expectedConfig,
73+
$expectedSwatchConfig,
74+
['visual_swatch_attribute', 'text_swatch_attribute']
75+
);
76+
}
77+
78+
/**
79+
* Check configurable product view on category view page
80+
*
81+
* @param array $expectedConfig
82+
* @param array $expectedSwatchConfig
83+
* @param array $attributes
84+
* @return void
85+
*/
86+
private function checkProductViewCategoryPage(
87+
array $expectedConfig,
88+
array $expectedSwatchConfig,
89+
array $attributes
90+
): void {
91+
$this->setAttributeUsedInProductListing($attributes);
92+
$this->checkProductView($expectedConfig, $expectedSwatchConfig);
93+
}
94+
95+
/**
96+
* Set used in product listing attributes value to true
97+
*
98+
* @param array $attributeCodes
99+
* @return void
100+
*/
101+
private function setAttributeUsedInProductListing(array $attributeCodes): void
102+
{
103+
foreach ($attributeCodes as $attributeCode) {
104+
$attribute = $this->productAttributeRepository->get($attributeCode);
105+
$attribute->setUsedInProductListing('1');
106+
$this->productAttributeRepository->save($attribute);
107+
}
108+
}
109+
}

0 commit comments

Comments
 (0)