Skip to content

Commit e280215

Browse files
authored
Merge pull request #5333 from magento-tsg/2.4-develop-com-pr7
[TSG-Commerce] Tests for 2.4 (pr7)
2 parents ff70b28 + 569b34a commit e280215

File tree

50 files changed

+3709
-182
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+3709
-182
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
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\Bundle\Model;
9+
10+
use Magento\Bundle\Api\Data\LinkInterfaceFactory;
11+
use Magento\Bundle\Api\Data\OptionInterfaceFactory;
12+
use Magento\Bundle\Model\Product\Price;
13+
use Magento\Catalog\Api\Data\ProductExtensionFactory;
14+
use Magento\Catalog\Api\Data\ProductInterface;
15+
16+
/**
17+
* Prepare bundle product links
18+
*/
19+
class PrepareBundleLinks
20+
{
21+
/** @var LinkInterfaceFactory */
22+
private $linkFactory;
23+
24+
/** @var OptionInterfaceFactory */
25+
private $optionLinkFactory;
26+
27+
/** @var ProductExtensionFactory */
28+
private $extensionAttributesFactory;
29+
30+
/**
31+
* @param LinkInterfaceFactory $linkFactory
32+
* @param OptionInterfaceFactory $optionLinkFactory
33+
* @param ProductExtensionFactory $extensionAttributesFactory
34+
*/
35+
public function __construct(
36+
LinkInterfaceFactory $linkFactory,
37+
OptionInterfaceFactory $optionLinkFactory,
38+
ProductExtensionFactory $extensionAttributesFactory
39+
) {
40+
$this->linkFactory = $linkFactory;
41+
$this->optionLinkFactory = $optionLinkFactory;
42+
$this->extensionAttributesFactory = $extensionAttributesFactory;
43+
}
44+
45+
/**
46+
* Prepare bundle product links
47+
*
48+
* @param ProductInterface $product
49+
* @param array $bundleOptionsData
50+
* @param array $bundleSelectionsData
51+
* @return ProductInterface
52+
*/
53+
public function execute(
54+
ProductInterface $product,
55+
array $bundleOptionsData,
56+
array $bundleSelectionsData
57+
): ProductInterface {
58+
$product->setBundleOptionsData($bundleOptionsData)
59+
->setBundleSelectionsData($bundleSelectionsData);
60+
$options = [];
61+
foreach ($product->getBundleOptionsData() as $key => $optionData) {
62+
$option = $this->optionLinkFactory->create(['data' => $optionData]);
63+
$option->setSku($product->getSku());
64+
$option->setOptionId(null);
65+
$links = [];
66+
$bundleLinks = $product->getBundleSelectionsData();
67+
foreach ($bundleLinks[$key] as $linkData) {
68+
$link = $this->linkFactory->create(['data' => $linkData]);
69+
$link->setQty($linkData['selection_qty']);
70+
$priceType = $price = null;
71+
if ($product->getPriceType() === Price::PRICE_TYPE_FIXED) {
72+
$priceType = $linkData['selection_price_type'] ?? null;
73+
$price = $linkData['selection_price_value'] ?? null;
74+
}
75+
$link->setPriceType($priceType);
76+
$link->setPrice($price);
77+
$links[] = $link;
78+
}
79+
$option->setProductLinks($links);
80+
$options[] = $option;
81+
}
82+
/** @var ProductExtensionFactory $extensionAttributesFactory */
83+
$extensionAttributes = $product->getExtensionAttributes() ?? $this->extensionAttributesFactory->create();
84+
$extensionAttributes->setBundleProductOptions($options);
85+
$product->setExtensionAttributes($extensionAttributes);
86+
87+
return $product;
88+
}
89+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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\Directory\Model;
9+
10+
use Magento\Directory\Model\RegionFactory;
11+
12+
/**
13+
* Return region ID by region default name and country code.
14+
*/
15+
class GetRegionIdByName
16+
{
17+
/**
18+
* @var RegionFactory
19+
*/
20+
private $regionFactory;
21+
22+
/**
23+
* @var array
24+
*/
25+
private $regionIdsCache;
26+
27+
/**
28+
* @param RegionFactory $regionFactory
29+
*/
30+
public function __construct(
31+
RegionFactory $regionFactory
32+
) {
33+
$this->regionFactory = $regionFactory;
34+
}
35+
36+
/**
37+
* Get region ID from cache property if region id exist or load it.
38+
*
39+
* @param string $regionName
40+
* @param string $countryId
41+
* @return int|null
42+
*/
43+
public function execute(string $regionName, string $countryId): ?int
44+
{
45+
$cacheKey = "{$regionName}_{$countryId}";
46+
47+
if (!isset($this->regionIdsCache[$cacheKey])) {
48+
$region = $this->regionFactory->create()->loadByName($regionName, $countryId);
49+
$this->regionIdsCache[$cacheKey] = $region->getRegionId() ? (int)$region->getRegionId() : null;
50+
}
51+
52+
return $this->regionIdsCache[$cacheKey];
53+
}
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
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\Bundle\Block\Catalog\Product\View\Type;
9+
10+
use Magento\Catalog\Api\Data\ProductInterface;
11+
use Magento\Catalog\Api\ProductRepositoryInterface;
12+
use Magento\Catalog\Model\ResourceModel\Product as ProductResource;
13+
use Magento\Framework\ObjectManagerInterface;
14+
use Magento\Framework\Registry;
15+
use Magento\Framework\Serialize\SerializerInterface;
16+
use Magento\Framework\View\Result\PageFactory;
17+
use Magento\TestFramework\Helper\Bootstrap;
18+
use Magento\TestFramework\Helper\Xpath;
19+
use PHPUnit\Framework\TestCase;
20+
21+
/**
22+
* Class consist of basic logic for bundle options view
23+
*/
24+
abstract class AbstractBundleOptionsViewTest extends TestCase
25+
{
26+
/** @var ObjectManagerInterface */
27+
private $objectManager;
28+
29+
/** @var ProductRepositoryInterface */
30+
private $productRepository;
31+
32+
/** @var SerializerInterface */
33+
private $serializer;
34+
35+
/** @var Registry */
36+
private $registry;
37+
38+
/** @var PageFactory */
39+
private $pageFactory;
40+
41+
/** @var ProductResource */
42+
private $productResource;
43+
44+
/** @var string */
45+
private $selectLabelXpath = "//fieldset[contains(@class, 'fieldset-bundle-options')]"
46+
. "//label/span[normalize-space(text()) = '%s']";
47+
48+
/** @var string */
49+
private $backToProductDetailButtonXpath = "//button[contains(@class, 'back customization')]";
50+
51+
/** @var string */
52+
private $titleXpath = "//fieldset[contains(@class, 'bundle-options')]//span[contains(text(), 'Customize %s')]";
53+
54+
/** @var string */
55+
private $singleOptionXpath = "//input[contains(@class, 'bundle-option') and contains(@type, 'hidden')]";
56+
57+
/**
58+
* @inheritdoc
59+
*/
60+
protected function setUp()
61+
{
62+
parent::setUp();
63+
64+
$this->objectManager = Bootstrap::getObjectManager();
65+
$this->productRepository = $this->objectManager->get(ProductRepositoryInterface::class);
66+
$this->productRepository->cleanCache();
67+
$this->serializer = $this->objectManager->get(SerializerInterface::class);
68+
$this->registry = $this->objectManager->get(Registry::class);
69+
$this->pageFactory = $this->objectManager->get(PageFactory::class);
70+
$this->productResource = $this->objectManager->get(ProductResource::class);
71+
}
72+
73+
/**
74+
* @inheritdoc
75+
*/
76+
protected function tearDown()
77+
{
78+
$this->registry->unregister('product');
79+
$this->registry->unregister('current_product');
80+
81+
parent::tearDown();
82+
}
83+
84+
/**
85+
* Process bundle options view with few selections
86+
*
87+
* @param string $sku
88+
* @param string $optionsSelectLabel
89+
* @param array $expectedSelectionsNames
90+
* @param bool $requiredOption
91+
* @return void
92+
*/
93+
protected function processMultiSelectionsView(
94+
string $sku,
95+
string $optionsSelectLabel,
96+
array $expectedSelectionsNames,
97+
bool $requiredOption = false
98+
): void {
99+
$product = $this->productRepository->get($sku);
100+
$result = $this->renderProductOptionsBlock($product);
101+
$this->assertEquals(
102+
1,
103+
Xpath::getElementsCountForXpath($this->backToProductDetailButtonXpath, $result),
104+
"'Back to product details' button doesn't exist on the page"
105+
);
106+
$this->assertEquals(
107+
1,
108+
Xpath::getElementsCountForXpath(sprintf($this->selectLabelXpath, $optionsSelectLabel), $result),
109+
'Options select label does not exist on the page'
110+
);
111+
$this->assertEquals(
112+
1,
113+
Xpath::getElementsCountForXpath(sprintf($this->titleXpath, $product->getName()), $result),
114+
sprintf('Customize %s label does not exist on the page', $product->getName())
115+
);
116+
$selectPath = $requiredOption ? $this->getRequiredSelectXpath() : $this->getNotRequiredSelectXpath();
117+
foreach ($expectedSelectionsNames as $selection) {
118+
$this->assertEquals(
119+
1,
120+
Xpath::getElementsCountForXpath(sprintf($selectPath, $selection), $result),
121+
sprintf('Option for product named %s does not exist on the page', $selection)
122+
);
123+
}
124+
}
125+
126+
/**
127+
* Process bundle options view with single selection
128+
*
129+
* @param string $sku
130+
* @param string $optionsSelectLabel
131+
* @return void
132+
*/
133+
protected function processSingleSelectionView(string $sku, string $optionsSelectLabel): void
134+
{
135+
$product = $this->productRepository->get($sku);
136+
$result = $this->renderProductOptionsBlock($product);
137+
$this->assertEquals(1, Xpath::getElementsCountForXpath($this->backToProductDetailButtonXpath, $result));
138+
$this->assertEquals(
139+
1,
140+
Xpath::getElementsCountForXpath(sprintf($this->selectLabelXpath, $optionsSelectLabel), $result),
141+
'Options select label does not exist on the page'
142+
);
143+
$this->assertEquals(
144+
1,
145+
Xpath::getElementsCountForXpath($this->singleOptionXpath, $result),
146+
'Bundle product options select with single option does not display correctly'
147+
);
148+
}
149+
150+
/**
151+
* Register product
152+
*
153+
* @param ProductInterface $product
154+
* @return void
155+
*/
156+
private function registerProduct(ProductInterface $product): void
157+
{
158+
$this->registry->unregister('product');
159+
$this->registry->unregister('current_product');
160+
$this->registry->register('product', $product);
161+
$this->registry->register('current_product', $product);
162+
}
163+
164+
/**
165+
* Render bundle product options block
166+
*
167+
* @param ProductInterface $product
168+
* @return string
169+
*/
170+
private function renderProductOptionsBlock(ProductInterface $product): string
171+
{
172+
$this->registerProduct($product);
173+
$page = $this->pageFactory->create();
174+
$page->addHandle(['default', 'catalog_product_view', 'catalog_product_view_type_bundle']);
175+
$page->getLayout()->generateXml();
176+
$block = $page->getLayout()->getBlock('product.info.bundle.options');
177+
178+
return $block->toHtml();
179+
}
180+
181+
/**
182+
* Get required select Xpath
183+
*
184+
* @return string
185+
*/
186+
abstract protected function getRequiredSelectXpath(): string;
187+
188+
/**
189+
* Get not required select Xpath
190+
*
191+
* @return string
192+
*/
193+
abstract protected function getNotRequiredSelectXpath(): string;
194+
}

0 commit comments

Comments
 (0)