Skip to content

Commit 71bda17

Browse files
committed
Merge remote-tracking branch 'origin/2.3-develop' into 2.3-develop-mftf-pr23
2 parents 2072ba2 + 5b54f06 commit 71bda17

File tree

14 files changed

+1614
-18
lines changed

14 files changed

+1614
-18
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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;
9+
10+
use Magento\Eav\Api\AttributeSetRepositoryInterface;
11+
use Magento\Eav\Api\Data\AttributeSetInterface;
12+
use Magento\Framework\Api\SearchCriteriaBuilder;
13+
14+
/**
15+
* Search and return attribute set by name.
16+
*/
17+
class GetAttributeSetByName
18+
{
19+
/**
20+
* @var SearchCriteriaBuilder
21+
*/
22+
private $searchCriteriaBuilder;
23+
24+
/**
25+
* @var AttributeSetRepositoryInterface
26+
*/
27+
private $attributeSetRepository;
28+
29+
/**
30+
* @param SearchCriteriaBuilder $searchCriteriaBuilder
31+
* @param AttributeSetRepositoryInterface $attributeSetRepository
32+
*/
33+
public function __construct(
34+
SearchCriteriaBuilder $searchCriteriaBuilder,
35+
AttributeSetRepositoryInterface $attributeSetRepository
36+
) {
37+
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
38+
$this->attributeSetRepository = $attributeSetRepository;
39+
}
40+
41+
/**
42+
* Find attribute set by name and return it.
43+
*
44+
* @param string $attributeSetName
45+
* @return AttributeSetInterface|null
46+
*/
47+
public function execute(string $attributeSetName): ?AttributeSetInterface
48+
{
49+
$this->searchCriteriaBuilder->addFilter('attribute_set_name', $attributeSetName);
50+
$searchCriteria = $this->searchCriteriaBuilder->create();
51+
$result = $this->attributeSetRepository->getList($searchCriteria);
52+
$items = $result->getItems();
53+
54+
return array_pop($items);
55+
}
56+
}
Lines changed: 297 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
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\ListProduct;
9+
10+
use Magento\Catalog\Api\CategoryRepositoryInterface;
11+
use Magento\Catalog\Api\ProductRepositoryInterface;
12+
use Magento\Catalog\Block\Product\ListProduct;
13+
use Magento\Catalog\Model\Product\Visibility;
14+
use Magento\Eav\Model\Entity\Collection\AbstractCollection;
15+
use Magento\Framework\ObjectManagerInterface;
16+
use Magento\Framework\View\LayoutInterface;
17+
use Magento\Store\Model\StoreManagerInterface;
18+
use Magento\TestFramework\Helper\Bootstrap;
19+
use PHPUnit\Framework\TestCase;
20+
21+
/**
22+
* Checks products displaying on category page
23+
*
24+
* @magentoDbIsolation disabled
25+
* @magentoAppIsolation enabled
26+
*/
27+
class ProductInCategoriesViewTest extends TestCase
28+
{
29+
/** @var ObjectManagerInterface */
30+
private $objectManager;
31+
32+
/** @var ListProduct */
33+
private $block;
34+
35+
/** @var CategoryRepositoryInterface */
36+
private $categoryRepository;
37+
38+
/** @var ProductRepositoryInterface */
39+
private $productRepository;
40+
41+
/** @var StoreManagerInterface */
42+
private $storeManager;
43+
44+
/** @var LayoutInterface */
45+
private $layout;
46+
47+
/**
48+
* @inheritdoc
49+
*/
50+
protected function setUp()
51+
{
52+
parent::setUp();
53+
54+
$this->objectManager = Bootstrap::getObjectManager();
55+
$this->categoryRepository = $this->objectManager->create(CategoryRepositoryInterface::class);
56+
$this->productRepository = $this->objectManager->create(ProductRepositoryInterface::class);
57+
$this->storeManager = $this->objectManager->get(StoreManagerInterface::class);
58+
$this->layout = $this->objectManager->get(LayoutInterface::class);
59+
$this->block = $this->layout->createBlock(ListProduct::class);
60+
}
61+
62+
/**
63+
* @magentoDataFixture Magento/Catalog/_files/category_with_two_products.php
64+
* @dataProvider productDataProvider
65+
* @param array $data
66+
* @return void
67+
*/
68+
public function testCategoryProductView(array $data): void
69+
{
70+
$this->updateProduct($data['sku'], $data);
71+
$collection = $this->getCategoryProductCollection(333);
72+
73+
$this->assertEquals(1, $collection->getSize());
74+
$this->assertEquals('simple333', $collection->getFirstItem()->getSku());
75+
}
76+
77+
/**
78+
* @return array
79+
*/
80+
public function productDataProvider(): array
81+
{
82+
return [
83+
'simple_product_enabled_disabled' => [
84+
[
85+
'sku' => 'simple2',
86+
'status' => 0,
87+
],
88+
],
89+
'simple_product_in_stock_out_of_stock' => [
90+
[
91+
'sku' => 'simple2',
92+
'stock_data' => [
93+
'use_config_manage_stock' => 1,
94+
'qty' => 0,
95+
'is_qty_decimal' => 0,
96+
'is_in_stock' => 0,
97+
],
98+
],
99+
],
100+
];
101+
}
102+
103+
/**
104+
* @magentoDataFixture Magento/Catalog/_files/category_product.php
105+
* @dataProvider productVisibilityProvider
106+
* @param array $data
107+
* @return void
108+
*/
109+
public function testCategoryProductVisibility(array $data): void
110+
{
111+
$this->updateProduct($data['data']['sku'], $data['data']);
112+
$collection = $this->getCategoryProductCollection(333);
113+
114+
$this->assertEquals($data['expected_count'], $collection->getSize());
115+
}
116+
117+
/**
118+
* @return array
119+
*/
120+
public function productVisibilityProvider(): array
121+
{
122+
return [
123+
'not_visible' => [
124+
[
125+
'data' => [
126+
'sku' => 'simple333',
127+
'visibility' => Visibility::VISIBILITY_NOT_VISIBLE,
128+
],
129+
'expected_count' => 0,
130+
],
131+
132+
],
133+
'catalog_search' => [
134+
[
135+
'data' => [
136+
'sku' => 'simple333',
137+
'visibility' => Visibility::VISIBILITY_BOTH,
138+
],
139+
'expected_count' => 1,
140+
],
141+
142+
],
143+
'search' => [
144+
[
145+
'data' => [
146+
'sku' => 'simple333',
147+
'visibility' => Visibility::VISIBILITY_IN_SEARCH,
148+
],
149+
'expected_count' => 0,
150+
],
151+
],
152+
'catalog' => [
153+
[
154+
'data' => [
155+
'sku' => 'simple333',
156+
'visibility' => Visibility::VISIBILITY_IN_CATALOG,
157+
],
158+
'expected_count' => 1,
159+
],
160+
],
161+
];
162+
}
163+
164+
/**
165+
* @magentoDataFixture Magento/Catalog/_files/category_tree.php
166+
* @magentoDataFixture Magento/Catalog/_files/second_product_simple.php
167+
* @return void
168+
*/
169+
public function testAnchorCategoryProductVisibility(): void
170+
{
171+
$this->updateCategoryIsAnchor(400, true);
172+
$this->assignProductCategories('simple2', [402]);
173+
$parentCategoryCollection = $this->getCategoryProductCollection(400);
174+
$childCategoryCollection = $this->getCategoryProductCollection(402, true);
175+
176+
$this->assertEquals(1, $parentCategoryCollection->getSize());
177+
$this->assertEquals(
178+
$childCategoryCollection->getAllIds(),
179+
$parentCategoryCollection->getAllIds()
180+
);
181+
}
182+
183+
/**
184+
* @magentoDataFixture Magento/Catalog/_files/category_tree.php
185+
* @magentoDataFixture Magento/Catalog/_files/second_product_simple.php
186+
* @return void
187+
*/
188+
public function testNonAnchorCategoryProductVisibility(): void
189+
{
190+
$this->updateCategoryIsAnchor(400, false);
191+
$this->assignProductCategories('simple2', [402]);
192+
$parentCategoryCollectionSize = $this->getCategoryProductCollection(400)->getSize();
193+
$childCategoryCollectionSize = $this->getCategoryProductCollection(402, true)->getSize();
194+
195+
$this->assertEquals(0, $parentCategoryCollectionSize);
196+
$this->assertEquals(1, $childCategoryCollectionSize);
197+
}
198+
199+
/**
200+
* @magentoDataFixture Magento/Catalog/_files/products_with_websites_and_stores.php
201+
* @magentoDataFixture Magento/Catalog/_files/category.php
202+
* @return void
203+
*/
204+
public function testCategoryProductViewOnMultiWebsite(): void
205+
{
206+
$this->assignProductCategories(['simple-1', 'simple-2'], [3, 333]);
207+
$store = $this->storeManager->getStore('fixture_second_store');
208+
$currentStore = $this->storeManager->getStore();
209+
210+
try {
211+
$this->storeManager->setCurrentStore($store->getId());
212+
$collection = $this->block->getLoadedProductCollection();
213+
$collectionSize = $collection->getSize();
214+
} finally {
215+
$this->storeManager->setCurrentStore($currentStore);
216+
}
217+
218+
$this->assertEquals(1, $collectionSize);
219+
$this->assertNull($collection->getItemByColumnValue('sku', 'simple-1'));
220+
$this->assertNotNull($collection->getItemByColumnValue('sku', 'simple-2'));
221+
}
222+
223+
/**
224+
* Set categories to the products
225+
*
226+
* @param string|array $sku
227+
* @param $categoryIds
228+
* @return void
229+
*/
230+
private function assignProductCategories($sku, array $categoryIds): void
231+
{
232+
$skus = !is_array($sku) ? [$sku] : $sku;
233+
foreach ($skus as $sku) {
234+
$product = $this->productRepository->get($sku);
235+
$product->setCategoryIds($categoryIds);
236+
$this->productRepository->save($product);
237+
}
238+
}
239+
240+
/**
241+
* Update product
242+
*
243+
* @param string $sku
244+
* @param array $data
245+
* @return void
246+
*/
247+
private function updateProduct(string $sku, array $data): void
248+
{
249+
$product = $this->productRepository->get($sku);
250+
$product->addData($data);
251+
$this->productRepository->save($product);
252+
}
253+
254+
/**
255+
* Returns category collection by category id
256+
*
257+
* @param int $categoryId
258+
* @param bool $refreshBlock
259+
* @return AbstractCollection
260+
*/
261+
private function getCategoryProductCollection(int $categoryId, bool $refreshBlock = false): AbstractCollection
262+
{
263+
$block = $this->getListingBlock($refreshBlock);
264+
$block->getLayer()->setCurrentCategory($categoryId);
265+
266+
return $block->getLoadedProductCollection();
267+
}
268+
269+
/**
270+
* Update is_anchor attribute of the category
271+
*
272+
* @param int $categoryId
273+
* @param bool $isAnchor
274+
* @return void
275+
*/
276+
private function updateCategoryIsAnchor(int $categoryId, bool $isAnchor): void
277+
{
278+
$category = $this->categoryRepository->get($categoryId);
279+
$category->setIsAnchor($isAnchor);
280+
$this->categoryRepository->save($category);
281+
}
282+
283+
/**
284+
* Get product listing block
285+
*
286+
* @param bool $refresh
287+
* @return ListProduct
288+
*/
289+
private function getListingBlock(bool $refresh): ListProduct
290+
{
291+
if ($refresh) {
292+
$this->block = $this->layout->createBlock(ListProduct::class);
293+
}
294+
295+
return $this->block;
296+
}
297+
}

0 commit comments

Comments
 (0)