Skip to content

Commit 2635bd8

Browse files
authored
Merge pull request #5021 from magento-tsg/2.3-develop-com-pr5
[TSG-Commerce] Tests for 2.3 (pr5) (2.3-develop)
2 parents 29cbd2f + 9de1b9f commit 2635bd8

File tree

45 files changed

+3260
-372
lines changed

Some content is hidden

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

45 files changed

+3260
-372
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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\Eav\Model\ResourceModel;
9+
10+
use Magento\Eav\Model\ResourceModel\Entity\Attribute\Set as AttributeSetResource;
11+
12+
/**
13+
* Search and return attribute data from eav entity attribute table.
14+
*/
15+
class GetEntityIdByAttributeId
16+
{
17+
/**
18+
* @var AttributeSetResource
19+
*/
20+
private $attributeSetResource;
21+
22+
/**
23+
* @param AttributeSetResource $setResource
24+
*/
25+
public function __construct(
26+
AttributeSetResource $setResource
27+
) {
28+
$this->attributeSetResource = $setResource;
29+
}
30+
31+
/**
32+
* Returns entity attribute by id.
33+
*
34+
* @param int $setId
35+
* @param int $attributeId
36+
* @return int|null
37+
*/
38+
public function execute(int $setId, int $attributeId): ?int
39+
{
40+
$select = $this->attributeSetResource->getConnection()->select()
41+
->from($this->attributeSetResource->getTable('eav_entity_attribute'))
42+
->where('attribute_set_id = ?', $setId)
43+
->where('attribute_id = ?', $attributeId);
44+
45+
$result = $this->attributeSetResource->getConnection()->fetchOne($select);
46+
return $result ? (int)$result : null;
47+
}
48+
}
Lines changed: 323 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,323 @@
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\Catalog\Block\Product\ProductList;
9+
10+
use Magento\Catalog\Api\Data\ProductInterface;
11+
use Magento\Catalog\Api\Data\ProductLinkInterface;
12+
use Magento\Catalog\Api\Data\ProductLinkInterfaceFactory;
13+
use Magento\Catalog\Api\ProductRepositoryInterface;
14+
use Magento\Catalog\Block\Product\AbstractProduct;
15+
use Magento\Catalog\Model\Product;
16+
use Magento\Catalog\Model\Product\Attribute\Source\Status;
17+
use Magento\Catalog\Model\Product\Visibility;
18+
use Magento\Catalog\Model\ProductLink\Link;
19+
use Magento\Framework\View\LayoutInterface;
20+
use Magento\Store\Model\StoreManagerInterface;
21+
use Magento\TestFramework\Helper\Bootstrap;
22+
use Magento\TestFramework\ObjectManager;
23+
use PHPUnit\Framework\TestCase;
24+
25+
/**
26+
* Class AbstractLinks - abstract class when testing blocks of linked products
27+
*
28+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
29+
*/
30+
abstract class AbstractLinksTest extends TestCase
31+
{
32+
/** @var ObjectManager */
33+
protected $objectManager;
34+
35+
/** @var ProductRepositoryInterface */
36+
protected $productRepository;
37+
38+
/** @var LayoutInterface */
39+
protected $layout;
40+
41+
/** @var ProductInterface|Product */
42+
protected $product;
43+
44+
/** @var ProductLinkInterfaceFactory */
45+
protected $productLinkInterfaceFactory;
46+
47+
/** @var StoreManagerInterface */
48+
protected $storeManager;
49+
50+
/** @var array */
51+
protected $existingProducts = [
52+
'wrong-simple' => [
53+
'position' => 1,
54+
],
55+
'simple-249' => [
56+
'position' => 2,
57+
],
58+
'simple-156' => [
59+
'position' => 3,
60+
],
61+
];
62+
63+
/** @var AbstractProduct */
64+
protected $block;
65+
66+
/** @var string */
67+
protected $linkType;
68+
69+
/**
70+
* @inheritdoc
71+
*/
72+
protected function setUp()
73+
{
74+
$this->objectManager = Bootstrap::getObjectManager();
75+
$this->productRepository = $this->objectManager->create(ProductRepositoryInterface::class);
76+
$this->layout = $this->objectManager->get(LayoutInterface::class);
77+
$this->productLinkInterfaceFactory = $this->objectManager->get(ProductLinkInterfaceFactory::class);
78+
$this->storeManager = $this->objectManager->get(StoreManagerInterface::class);
79+
}
80+
81+
/**
82+
* Provide test data to verify the display of linked products.
83+
*
84+
* @return array
85+
*/
86+
public function displayLinkedProductsProvider(): array
87+
{
88+
return [
89+
'product_all_displayed' => [
90+
'data' => [
91+
'updateProducts' => [],
92+
'expectedProductLinks' => [
93+
'wrong-simple',
94+
'simple-249',
95+
'simple-156',
96+
],
97+
],
98+
],
99+
'product_disabled' => [
100+
'data' => [
101+
'updateProducts' => [
102+
'wrong-simple' => ['status' => Status::STATUS_DISABLED],
103+
],
104+
'expectedProductLinks' => [
105+
'simple-249',
106+
'simple-156',
107+
],
108+
],
109+
],
110+
'product_invisibility' => [
111+
'data' => [
112+
'updateProducts' => [
113+
'simple-249' => ['visibility' => Visibility::VISIBILITY_NOT_VISIBLE],
114+
],
115+
'expectedProductLinks' => [
116+
'wrong-simple',
117+
'simple-156',
118+
],
119+
],
120+
],
121+
'product_invisible_in_catalog' => [
122+
'data' => [
123+
'updateProducts' => [
124+
'simple-249' => ['visibility' => Visibility::VISIBILITY_IN_SEARCH],
125+
],
126+
'expectedProductLinks' => [
127+
'wrong-simple',
128+
'simple-156',
129+
],
130+
],
131+
],
132+
'product_out_of_stock' => [
133+
'data' => [
134+
'updateProducts' => [
135+
'simple-156' => [
136+
'stock_data' => [
137+
'use_config_manage_stock' => 1,
138+
'qty' => 0,
139+
'is_qty_decimal' => 0,
140+
'is_in_stock' => 0,
141+
],
142+
],
143+
],
144+
'expectedProductLinks' => [
145+
'wrong-simple',
146+
'simple-249',
147+
],
148+
],
149+
],
150+
];
151+
}
152+
153+
/**
154+
* Provide test data to verify the display of linked products on different websites.
155+
*
156+
* @return array
157+
*/
158+
public function multipleWebsitesLinkedProductsProvider(): array
159+
{
160+
return [
161+
'first_website' => [
162+
'data' => [
163+
'storeCode' => 'default',
164+
'productLinks' => [
165+
'simple-2' => ['position' => 4],
166+
],
167+
'expectedProductLinks' => [
168+
'wrong-simple',
169+
'simple-2',
170+
],
171+
],
172+
],
173+
'second_website' => [
174+
'data' => [
175+
'storeCode' => 'fixture_second_store',
176+
'productLinks' => [
177+
'simple-2' => ['position' => 4],
178+
],
179+
'expectedProductLinks' => [
180+
'simple-249',
181+
'simple-2',
182+
],
183+
],
184+
],
185+
];
186+
}
187+
188+
/**
189+
* Get test data to check position of related, up-sells and cross-sells products
190+
*
191+
* @return array
192+
*/
193+
protected function getPositionData(): array
194+
{
195+
return [
196+
'productLinks' => array_replace_recursive(
197+
$this->existingProducts,
198+
[
199+
'wrong-simple' => ['position' => 2],
200+
'simple-249' => ['position' => 3],
201+
'simple-156' => ['position' => 1],
202+
]
203+
),
204+
'expectedProductLinks' => [
205+
'simple-156',
206+
'wrong-simple',
207+
'simple-249',
208+
],
209+
];
210+
}
211+
212+
/**
213+
* Prepare a block of linked products
214+
*
215+
* @return void
216+
*/
217+
protected function prepareBlock(): void
218+
{
219+
$this->block->setLayout($this->layout);
220+
$this->block->setTemplate('Magento_Catalog::product/list/items.phtml');
221+
$this->block->setType($this->linkType);
222+
}
223+
224+
/**
225+
* Set linked products by link type for current product received from array
226+
*
227+
* @param ProductInterface $product
228+
* @param array $productData
229+
* @return void
230+
*/
231+
private function setCustomProductLinks(ProductInterface $product, array $productData): void
232+
{
233+
$productLinks = [];
234+
foreach ($productData as $sku => $data) {
235+
/** @var ProductLinkInterface|Link $productLink */
236+
$productLink = $this->productLinkInterfaceFactory->create();
237+
$productLink->setSku($product->getSku());
238+
$productLink->setLinkedProductSku($sku);
239+
if (isset($data['position'])) {
240+
$productLink->setPosition($data['position']);
241+
}
242+
$productLink->setLinkType($this->linkType);
243+
$productLinks[] = $productLink;
244+
}
245+
$product->setProductLinks($productLinks);
246+
}
247+
248+
/**
249+
* Update product attributes
250+
*
251+
* @param array $products
252+
* @return void
253+
*/
254+
protected function updateProducts(array $products): void
255+
{
256+
foreach ($products as $sku => $data) {
257+
/** @var ProductInterface|Product $product */
258+
$product = $this->productRepository->get($sku);
259+
$product->addData($data);
260+
$this->productRepository->save($product);
261+
}
262+
}
263+
264+
/**
265+
* Get an array of received linked products
266+
*
267+
* @param array $items
268+
* @return array
269+
*/
270+
protected function getActualLinks(array $items): array
271+
{
272+
$actualLinks = [];
273+
/** @var ProductInterface $productItem */
274+
foreach ($items as $productItem) {
275+
$actualLinks[] = $productItem->getSku();
276+
}
277+
278+
return $actualLinks;
279+
}
280+
281+
/**
282+
* Link products to an existing product
283+
*
284+
* @param string $sku
285+
* @param array $productLinks
286+
* @return void
287+
*/
288+
protected function linkProducts(string $sku, array $productLinks): void
289+
{
290+
$product = $this->productRepository->get($sku);
291+
$this->setCustomProductLinks($product, $productLinks);
292+
$this->productRepository->save($product);
293+
}
294+
295+
/**
296+
* Prepare the necessary websites for all products
297+
*
298+
* @return array
299+
*/
300+
protected function prepareWebsiteIdsProducts(): array
301+
{
302+
$websiteId = $this->storeManager->getWebsite('test')->getId();
303+
$defaultWebsiteId = $this->storeManager->getWebsite('base')->getId();
304+
305+
return [
306+
'simple-1' => [
307+
'website_ids' => [$defaultWebsiteId, $websiteId],
308+
],
309+
'simple-2' => [
310+
'website_ids' => [$defaultWebsiteId, $websiteId],
311+
],
312+
'wrong-simple' => [
313+
'website_ids' => [$defaultWebsiteId],
314+
],
315+
'simple-249' => [
316+
'website_ids' => [$websiteId],
317+
],
318+
'simple-156' => [
319+
'website_ids' => [],
320+
],
321+
];
322+
}
323+
}

0 commit comments

Comments
 (0)