Skip to content

Commit d6e7a39

Browse files
committed
MAGETWO-64959: Grouped product is missing in category
1 parent f56188d commit d6e7a39

File tree

6 files changed

+299
-3
lines changed

6 files changed

+299
-3
lines changed

dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php

Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
namespace Magento\Framework\Search\Adapter\Mysql;
77

8+
use Magento\Catalog\Api\ProductRepositoryInterface;
89
use Magento\CatalogSearch\Model\ResourceModel\EngineInterface;
910
use Magento\Search\Model\EngineResolver;
1011
use Magento\TestFramework\Helper\Bootstrap;
@@ -39,6 +40,14 @@ class AdapterTest extends \PHPUnit_Framework_TestCase
3940
*/
4041
protected $searchEngine = EngineResolver::CATALOG_SEARCH_MYSQL_ENGINE;
4142

43+
/**
44+
* @var ProductRepositoryInterface
45+
*/
46+
protected $productRepository;
47+
48+
/**
49+
* @inheritdoc
50+
*/
4251
protected function setUp()
4352
{
4453
$this->objectManager = Bootstrap::getObjectManager();
@@ -60,6 +69,7 @@ protected function setUp()
6069
);
6170

6271
$this->adapter = $this->createAdapter();
72+
$this->productRepository = $this->objectManager->create(ProductRepositoryInterface::class);
6373
}
6474

6575
/**
@@ -113,15 +123,28 @@ private function executeQuery()
113123
* @return void
114124
*/
115125
private function assertProductIds($queryResponse, $expectedIds)
126+
{
127+
$actualIds = $this->getProductIds($queryResponse);
128+
sort($actualIds);
129+
sort($expectedIds);
130+
$this->assertEquals($expectedIds, $actualIds);
131+
}
132+
133+
/**
134+
* Returns document ids from query response.
135+
*
136+
* @param \Magento\Framework\Search\Response\QueryResponse $queryResponse
137+
* @return array
138+
*/
139+
protected function getProductIds(\Magento\Framework\Search\Response\QueryResponse $queryResponse)
116140
{
117141
$actualIds = [];
118142
foreach ($queryResponse as $document) {
119143
/** @var \Magento\Framework\Api\Search\Document $document */
120144
$actualIds[] = $document->getId();
121145
}
122-
sort($actualIds);
123-
sort($expectedIds);
124-
$this->assertEquals($expectedIds, $actualIds);
146+
147+
return $actualIds;
125148
}
126149

127150
/**
@@ -524,4 +547,51 @@ public function priceDataProvider()
524547
[['from' => '', 'to' => '19.8900'], 1],
525548
];
526549
}
550+
551+
/**
552+
* Search grouped product.
553+
*
554+
* @magentoDataFixture Magento/Framework/Search/_files/grouped_product.php
555+
* @magentoConfigFixture current_store catalog/search/engine mysql
556+
*
557+
* @return void
558+
*/
559+
public function testSearchGroupedProduct()
560+
{
561+
$this->requestBuilder->bind('search_term', 'Grouped Product');
562+
$this->requestBuilder->setRequestName('quick_search_container');
563+
564+
$queryResponse = $this->executeQuery();
565+
$result = $this->getProductIds($queryResponse);
566+
567+
self::assertCount(3, $result);
568+
569+
$groupedProduct = $this->productRepository->get('grouped-product');
570+
self::assertContains($groupedProduct->getId(), $result, 'Grouped product not found by name.');
571+
}
572+
573+
/**
574+
* Filter by tax class.
575+
*
576+
* @magentoDataFixture Magento/Framework/Search/_files/grouped_product.php
577+
* @magentoConfigFixture current_store catalog/search/engine mysql
578+
*
579+
* @return void
580+
*/
581+
public function testFilterByTaxClass()
582+
{
583+
$groupedProduct = $this->productRepository->get('grouped-product');
584+
$simpleProduct = $this->productRepository->get('grouped-association-2');
585+
586+
$this->requestBuilder->bind('term', $simpleProduct->getTaxClassId());
587+
$this->requestBuilder->setRequestName('tax_class_id_filter_query');
588+
589+
$queryResponse = $this->executeQuery();
590+
$result = $this->getProductIds($queryResponse);
591+
592+
self::assertCount(2, $result);
593+
594+
self::assertContains($groupedProduct->getId(), $result, 'Grouped product not found by tax class.');
595+
self::assertContains($simpleProduct->getId(), $result, 'Simple product not found by tax class.');
596+
}
527597
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
/**
3+
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
use Magento\Catalog\Api\ProductRepositoryInterface;
8+
use Magento\Tax\Api\Data\TaxClassInterface;
9+
use Magento\Tax\Api\Data\TaxClassInterfaceFactory;
10+
use Magento\Tax\Api\TaxClassManagementInterface;
11+
use Magento\Tax\Api\TaxClassRepositoryInterface;
12+
use Magento\TestFramework\Helper\Bootstrap;
13+
14+
/** @var $objectManager \Magento\Framework\ObjectManagerInterface */
15+
$objectManager = Bootstrap::getObjectManager();
16+
17+
/** @var TaxClassInterfaceFactory $taxClassFactory */
18+
$taxClassFactory = $objectManager->get(TaxClassInterfaceFactory::class);
19+
20+
/** @var TaxClassRepositoryInterface $taxClassRepository */
21+
$taxClassRepository = $objectManager->get(TaxClassRepositoryInterface::class);
22+
23+
/** @var TaxClassInterface $taxClass */
24+
$taxClass = $taxClassFactory->create()
25+
->setClassType(TaxClassManagementInterface::TYPE_PRODUCT)
26+
->setClassName('Test');
27+
28+
$taxClass = $taxClassRepository->save($taxClass);
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
/**
3+
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
use Magento\Catalog\Api\ProductRepositoryInterface;
8+
use Magento\Framework\Api\SearchCriteriaBuilder;
9+
use Magento\Tax\Api\TaxClassManagementInterface;
10+
use Magento\Tax\Api\TaxClassRepositoryInterface;
11+
use Magento\TestFramework\Helper\Bootstrap;
12+
13+
/** @var $objectManager \Magento\Framework\ObjectManagerInterface */
14+
$objectManager = Bootstrap::getObjectManager();
15+
16+
/** @var TaxClassRepositoryInterface $taxClassRepository */
17+
$taxClassRepository = $objectManager->get(TaxClassRepositoryInterface::class);
18+
19+
/** @var SearchCriteriaBuilder $searchCriteriaBuilder */
20+
$searchCriteriaBuilder = $objectManager->create(SearchCriteriaBuilder::class);
21+
$searchCriteria = $searchCriteriaBuilder->addFilter(
22+
'class_type',
23+
TaxClassManagementInterface::TYPE_PRODUCT
24+
)
25+
->addFilter('class_name', 'Test')
26+
->create();
27+
28+
$productTaxClasses = $taxClassRepository->getList($searchCriteria);
29+
$taxClasses = $productTaxClasses->getItems();
30+
31+
if (!empty($taxClasses)) {
32+
foreach ($taxClasses as $taxClass) {
33+
try {
34+
$taxClassRepository->deleteById($taxClass->getClassId());
35+
} catch (Exception $e) {
36+
// Something went wrong.
37+
}
38+
}
39+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<?php
2+
/**
3+
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
require 'custom_product_tax_class.php';
8+
9+
use Magento\Catalog\Api\Data\ProductLinkInterfaceFactory;
10+
use Magento\Catalog\Api\ProductAttributeRepositoryInterface;
11+
use Magento\Catalog\Api\ProductRepositoryInterface;
12+
use Magento\Catalog\Model\Product;
13+
use Magento\Framework\Api\SearchCriteriaBuilder;
14+
use Magento\Tax\Api\TaxClassManagementInterface;
15+
use Magento\Tax\Api\TaxClassRepositoryInterface;
16+
use Magento\TestFramework\Helper\Bootstrap;
17+
18+
/** @var $objectManager \Magento\Framework\ObjectManagerInterface */
19+
$objectManager = Bootstrap::getObjectManager();
20+
21+
/** @var \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository */
22+
$attributeRepository = $objectManager->get(ProductAttributeRepositoryInterface::class);
23+
$attribute = $attributeRepository->get('tax_class_id');
24+
$attribute->setIsFilterableInSearch(true);
25+
$attributeRepository->save($attribute);
26+
27+
/** @var SearchCriteriaBuilder $searchCriteriaBuilder */
28+
$searchCriteriaBuilder = $objectManager->create(SearchCriteriaBuilder::class);
29+
$searchCriteria = $searchCriteriaBuilder->addFilter(
30+
'class_type',
31+
TaxClassManagementInterface::TYPE_PRODUCT
32+
)->create();
33+
34+
/** @var TaxClassRepositoryInterface $taxClassRepository */
35+
$taxClassRepository = $objectManager->get(TaxClassRepositoryInterface::class);
36+
$productTaxClasses = $taxClassRepository->getList($searchCriteria);
37+
$productTaxClasses = $productTaxClasses->getItems();
38+
39+
/** @var ProductRepositoryInterface $productRepository */
40+
$productRepository = $objectManager->create(ProductRepositoryInterface::class);
41+
$position = 1;
42+
43+
foreach ($productTaxClasses as $taxClass) {
44+
/** @var Product $product */
45+
$product = $objectManager->create(Product::class);
46+
$product->isObjectNew(true);
47+
$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)
48+
->setAttributeSetId(4)
49+
->setWebsiteIds([1])
50+
->setName('Grouped association ' . $position)
51+
->setSku('grouped-association-' . $position)
52+
->setPrice(10)
53+
->setTaxClassId($taxClass->getClassId())
54+
->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
55+
->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
56+
->setStockData(['is_in_stock' => 1, 'qty' => 10]);
57+
58+
$position++;
59+
60+
$productRepository->save($product);
61+
}
62+
63+
/** @var Product $product */
64+
$product = $objectManager->create(Product::class);
65+
$product->isObjectNew(true);
66+
$product->setTypeId(\Magento\GroupedProduct\Model\Product\Type\Grouped::TYPE_CODE)
67+
->setAttributeSetId(4)
68+
->setWebsiteIds([1])
69+
->setName('Grouped Product')
70+
->setSku('grouped-product')
71+
->setPrice(100)
72+
->setTaxClassId(0)
73+
->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
74+
->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
75+
->setStockData(['is_in_stock' => 1]);
76+
77+
$newLinks = [];
78+
$productLinkFactory = $objectManager->get(ProductLinkInterfaceFactory::class);
79+
80+
$associatedProducts = ['grouped-association-1', 'grouped-association-2'];
81+
$position = 1;
82+
83+
foreach ($associatedProducts as $sku) {
84+
$linkedProduct = $productRepository->get($sku, false, null, true);
85+
86+
/** @var \Magento\Catalog\Api\Data\ProductLinkInterface $productLink */
87+
$productLink = $productLinkFactory->create();
88+
89+
$productLink->setSku($product->getSku())
90+
->setLinkType('associated')
91+
->setLinkedProductSku($linkedProduct->getSku())
92+
->setLinkedProductType($linkedProduct->getTypeId())
93+
->setPosition($position)
94+
->getExtensionAttributes()
95+
->setQty(1);
96+
97+
$position++;
98+
$newLinks[] = $productLink;
99+
}
100+
101+
$product->setProductLinks($newLinks);
102+
$productRepository->save($product);
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
/**
3+
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
use Magento\Catalog\Api\ProductRepositoryInterface;
8+
use Magento\Framework\Exception\NoSuchEntityException;
9+
10+
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
11+
12+
/** @var \Magento\Framework\Registry $registry */
13+
$registry = $objectManager->get(\Magento\Framework\Registry::class);
14+
15+
/** @var ProductRepositoryInterface $productRepository */
16+
$productRepository = $objectManager->get(ProductRepositoryInterface::class);
17+
18+
$registry->unregister('isSecureArea');
19+
$registry->register('isSecureArea', true);
20+
21+
$products = ['grouped-association-1', 'grouped-association-2', 'grouped-product'];
22+
23+
foreach ($products as $sku) {
24+
try {
25+
/** @var \Magento\Catalog\Model\Product $simpleProduct */
26+
$simpleProduct = $productRepository->get($sku, false, null, true);
27+
$simpleProduct->delete();
28+
} catch (NoSuchEntityException $e) {
29+
//already deleted
30+
}
31+
}
32+
33+
$registry->unregister('isSecureArea');
34+
$registry->register('isSecureArea', false);
35+
36+
require 'custom_product_tax_class_rollback.php';

dev/tests/integration/testsuite/Magento/Framework/Search/_files/requests.xml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,4 +427,25 @@
427427
<from>0</from>
428428
<size>10</size>
429429
</request>
430+
<request query="tax_class_id_filter_query" index="catalogsearch_fulltext">
431+
<dimensions>
432+
<dimension name="scope" value="default"/>
433+
</dimensions>
434+
<queries>
435+
<query xsi:type="boolQuery" name="tax_class_id_filter_query" boost="1">
436+
<queryReference clause="must" ref="filter_query"/>
437+
</query>
438+
<query xsi:type="filteredQuery" name="filter_query">
439+
<filterReference clause="must" ref="tax_class_id_filter"/>
440+
</query>
441+
</queries>
442+
<filters>
443+
<filter name="tax_class_id_filter"
444+
xsi:type="termFilter"
445+
field="tax_class_id"
446+
value="$term$"/>
447+
</filters>
448+
<from>0</from>
449+
<size>10</size>
450+
</request>
430451
</requests>

0 commit comments

Comments
 (0)