Skip to content

Commit 9dacb50

Browse files
committed
MC-21456: Storefront: Product view in a category
1 parent 1de5f67 commit 9dacb50

File tree

2 files changed

+311
-0
lines changed

2 files changed

+311
-0
lines changed
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\CategoryLinkManagementInterface;
11+
use Magento\Catalog\Api\CategoryRepositoryInterface;
12+
use Magento\Catalog\Api\Data\CategoryInterface;
13+
use Magento\Catalog\Api\ProductRepositoryInterface;
14+
use Magento\Catalog\Block\Product\ListProduct;
15+
use Magento\Catalog\Model\Layer;
16+
use Magento\Catalog\Model\Layer\Resolver;
17+
use Magento\Catalog\Model\Product\Visibility;
18+
use Magento\Eav\Model\Entity\Collection\AbstractCollection;
19+
use Magento\Framework\ObjectManagerInterface;
20+
use Magento\Framework\Registry;
21+
use Magento\Framework\View\LayoutInterface;
22+
use Magento\Store\Api\StoreRepositoryInterface;
23+
use Magento\Store\Model\StoreManagerInterface;
24+
use Magento\TestFramework\Helper\Bootstrap;
25+
use PHPUnit\Framework\TestCase;
26+
27+
/**
28+
* Checks products displaying on category page
29+
*
30+
* @magentoDbIsolation disabled
31+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
32+
*/
33+
class AbstractTest extends TestCase
34+
{
35+
/** @var ObjectManagerInterface */
36+
private $objectManager;
37+
38+
/** @var ListProduct */
39+
private $block;
40+
41+
/** @var CategoryRepositoryInterface */
42+
private $categoryRepository;
43+
44+
/** @var Registry */
45+
private $registry;
46+
47+
/** @var ProductRepositoryInterface */
48+
private $productRepository;
49+
50+
/** @var CategoryLinkManagementInterface */
51+
private $categoryLinkManagement;
52+
53+
/** @var StoreManagerInterface */
54+
private $storeManager;
55+
56+
/** @var StoreRepositoryInterface */
57+
private $storeRepository;
58+
59+
/**
60+
* @inheritdoc
61+
*/
62+
protected function setUp()
63+
{
64+
parent::setUp();
65+
66+
$this->objectManager = Bootstrap::getObjectManager();
67+
$this->categoryRepository = $this->objectManager->create(CategoryRepositoryInterface::class);
68+
$this->block = $this->objectManager->get(LayoutInterface::class)->createBlock(ListProduct::class);
69+
$this->registry = $this->objectManager->get(Registry::class);
70+
$this->productRepository = $this->objectManager->create(ProductRepositoryInterface::class);
71+
$this->categoryLinkManagement = $this->objectManager->create(CategoryLinkManagementInterface::class);
72+
$this->storeManager = $this->objectManager->get(StoreManagerInterface::class);
73+
$this->storeRepository = $this->objectManager->create(StoreRepositoryInterface::class);
74+
}
75+
76+
/**
77+
* @magentoDataFixture Magento/Catalog/_files/category_with_two_products.php
78+
* @magentoAppIsolation enabled
79+
* @dataProvider productDataProvider
80+
* @param array $data
81+
* @return void
82+
*/
83+
public function testCategoryProductView(array $data): void
84+
{
85+
$collection = $this->processCategoryViewTest($data['sku'], $data);
86+
87+
$this->assertEquals(1, $collection->getSize());
88+
$this->assertEquals('simple333', $collection->getFirstItem()->getSku());
89+
}
90+
91+
/**
92+
* @return array
93+
*/
94+
public function productDataProvider(): array
95+
{
96+
return [
97+
'simple_product_enabled_disabled' => [
98+
[
99+
'sku' => 'simple2',
100+
'status' => 0,
101+
],
102+
],
103+
'simple_product_in_stock_out_of_stock' => [
104+
[
105+
'sku' => 'simple2',
106+
'stock_data' => [
107+
'use_config_manage_stock' => 1,
108+
'qty' => 0,
109+
'is_qty_decimal' => 0,
110+
'is_in_stock' => 0,
111+
],
112+
],
113+
],
114+
];
115+
}
116+
117+
/**
118+
* @magentoDataFixture Magento/Catalog/_files/category_product.php
119+
* @magentoAppIsolation enabled
120+
* @dataProvider productVisibilityProvider
121+
* @param array $data
122+
* @return void
123+
*/
124+
public function testCategoryProductVisibilityTest(array $data): void
125+
{
126+
$collection = $this->processCategoryViewTest($data['data']['sku'], $data['data']);
127+
128+
$this->assertEquals($data['expected_count'], $collection->getSize());
129+
}
130+
131+
/**
132+
* @return array
133+
*/
134+
public function productVisibilityProvider(): array
135+
{
136+
return [
137+
'not_visible' => [
138+
[
139+
'data' => [
140+
'sku' => 'simple333',
141+
'visibility' => Visibility::VISIBILITY_NOT_VISIBLE,
142+
],
143+
'expected_count' => 0,
144+
],
145+
146+
],
147+
'catalog_search' => [
148+
[
149+
'data' => [
150+
'sku' => 'simple333',
151+
'visibility' => Visibility::VISIBILITY_BOTH,
152+
],
153+
'expected_count' => 1,
154+
],
155+
156+
],
157+
'search' => [
158+
[
159+
'data' => [
160+
'sku' => 'simple333',
161+
'visibility' => Visibility::VISIBILITY_IN_SEARCH,
162+
],
163+
'expected_count' => 0,
164+
],
165+
],
166+
'catalog' => [
167+
[
168+
'data' => [
169+
'sku' => 'simple333',
170+
'visibility' => Visibility::VISIBILITY_IN_CATALOG,
171+
],
172+
'expected_count' => 1,
173+
],
174+
],
175+
];
176+
}
177+
178+
/**
179+
* @magentoAppIsolation enabled
180+
* @magentoDataFixture Magento/Catalog/_files/category_tree.php
181+
* @magentoDataFixture Magento/Catalog/_files/second_product_simple.php
182+
* @return void
183+
*/
184+
public function testAnchorCategoryProductVisibility(): void
185+
{
186+
$collections = $this->processAnchorTest(true);
187+
188+
$this->assertEquals(1, $collections['parent_collection']->getSize());
189+
$this->assertEquals(
190+
$collections['child_collection']->getAllIds(),
191+
$collections['parent_collection']->getAllIds()
192+
);
193+
}
194+
195+
/**
196+
* @magentoAppIsolation enabled
197+
* @magentoDataFixture Magento/Catalog/_files/category_tree.php
198+
* @magentoDataFixture Magento/Catalog/_files/second_product_simple.php
199+
* @return void
200+
*/
201+
public function testNonAnchorCategoryProductVisibility(): void
202+
{
203+
$collections = $this->processAnchorTest(false);
204+
205+
$this->assertCount(0, $collections['parent_collection']);
206+
$this->assertCount(1, $collections['child_collection']);
207+
}
208+
209+
/**
210+
* @magentoDataFixture Magento/Catalog/_files/products_with_websites_and_stores.php
211+
* @magentoDataFixture Magento/Catalog/_files/category.php
212+
* @return void
213+
*/
214+
public function testCategoryProductViewOnMultiWebsite(): void
215+
{
216+
$this->setCategoriesToProducts(['simple-1', 'simple-2']);
217+
$store = $this->storeRepository->get('fixture_second_store');
218+
$this->storeManager->setCurrentStore($store->getId());
219+
$category = $this->categoryRepository->get(333);
220+
$this->registerCategory($category);
221+
$collection = $this->block->getLoadedProductCollection();
222+
$this->assertEquals(1, $collection->getSize());
223+
$this->assertEquals('simple-2', $collection->getFirstItem()->getSku());
224+
}
225+
226+
/**
227+
* Set categories to the products
228+
*
229+
* @param array $skus
230+
* @return void
231+
*/
232+
private function setCategoriesToProducts(array $skus): void
233+
{
234+
foreach ($skus as $sku) {
235+
$product = $this->productRepository->get($sku);
236+
$product->setCategoryIds([2, 333]);
237+
$this->productRepository->save($product);
238+
}
239+
}
240+
241+
/**
242+
* Proccess for anchor and non anchor category test
243+
*
244+
* @param bool $isAnchor
245+
* @return array
246+
*/
247+
private function processAnchorTest(bool $isAnchor): array
248+
{
249+
$category = $this->categoryRepository->get(400);
250+
$category->setIsAnchor($isAnchor);
251+
$this->categoryRepository->save($category);
252+
$childCategory = $this->categoryRepository->get(402);
253+
$this->categoryLinkManagement->assignProductToCategories('simple2', [$childCategory->getId()]);
254+
$this->registerCategory($category);
255+
$parentCategoryCollection = $this->block->getLoadedProductCollection();
256+
$this->objectManager->removeSharedInstance(Resolver::class);
257+
$this->objectManager->removeSharedInstance(Layer::class);
258+
$this->registerCategory($childCategory);
259+
$newBlock = $this->objectManager->get(LayoutInterface::class)->createBlock(ListProduct::class);
260+
$childCategoryCollection = $newBlock->getLoadedProductCollection();
261+
262+
return [
263+
'parent_collection' => $parentCategoryCollection,
264+
'child_collection' => $childCategoryCollection,
265+
];
266+
}
267+
268+
/**
269+
* Proccess category view test
270+
*
271+
* @param string $sku
272+
* @param array $data
273+
* @return AbstractCollection
274+
*/
275+
private function processCategoryViewTest(string $sku, array $data): AbstractCollection
276+
{
277+
$product = $this->productRepository->get($sku);
278+
$product->addData($data);
279+
$this->productRepository->save($product);
280+
$category = $this->categoryRepository->get(333);
281+
$this->registerCategory($category);
282+
283+
return $this->block->getLoadedProductCollection();
284+
}
285+
286+
/**
287+
* Register current category
288+
*
289+
* @param CategoryInterface $category
290+
* @retun void
291+
*/
292+
private function registerCategory(CategoryInterface $category): void
293+
{
294+
$this->registry->unregister('current_category');
295+
$this->registry->register('current_category', $category);
296+
}
297+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
use Magento\Catalog\Api\CategoryLinkManagementInterface;
8+
use Magento\TestFramework\Helper\Bootstrap;
9+
10+
require __DIR__ . '/category_product.php';
11+
require __DIR__ . '/second_product_simple.php';
12+
13+
$categoryLinkManagement = Bootstrap::getObjectManager()->create(CategoryLinkManagementInterface::class);
14+
$categoryLinkManagement->assignProductToCategories('simple2', [333]);

0 commit comments

Comments
 (0)