Skip to content

Commit 523c44f

Browse files
committed
MAGETWO-89246: Product visibility is not considered in search
- added use case for bundle with non-visible children
1 parent 0411bb4 commit 523c44f

File tree

6 files changed

+298
-3
lines changed

6 files changed

+298
-3
lines changed

dev/tests/api-functional/testsuite/Magento/GraphQl/Bundle/BundleProductViewTest.php

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,19 @@
1111
use Magento\Catalog\Api\Data\ProductInterface;
1212
use Magento\Catalog\Api\ProductRepositoryInterface;
1313
use Magento\Framework\EntityManager\MetadataPool;
14+
use Magento\Framework\App\Config\ScopeConfigInterface;
1415
use Magento\TestFramework\ObjectManager;
1516
use Magento\TestFramework\TestCase\GraphQlAbstract;
1617

1718
class BundleProductViewTest extends GraphQlAbstract
1819
{
1920
const KEY_PRICE_TYPE_FIXED = 'FIXED';
21+
const KEY_PRICE_TYPE_DYNAMIC = 'DYNAMIC';
2022

2123
/**
2224
* @magentoApiDataFixture Magento/Bundle/_files/product_1.php
2325
*/
24-
public function testAllFielsBundleProducts()
26+
public function testAllFieldsBundleProducts()
2527
{
2628
$productSku = 'bundle-product';
2729
$query
@@ -104,6 +106,106 @@ public function testAllFielsBundleProducts()
104106
);
105107
}
106108

109+
/**
110+
* @magentoApiDataFixture Magento/Bundle/_files/bundle_product_with_not_visible_children.php
111+
*/
112+
public function testBundleProdutWithNotVisibleChildren()
113+
{
114+
$productSku = 'bundle-product-1';
115+
$query
116+
= <<<QUERY
117+
{
118+
products(filter: {sku: {eq: "{$productSku}"}})
119+
{
120+
items{
121+
sku
122+
type_id
123+
id
124+
name
125+
attribute_set_id
126+
... on PhysicalProductInterface {
127+
weight
128+
}
129+
category_ids
130+
... on BundleProduct {
131+
dynamic_sku
132+
dynamic_price
133+
dynamic_weight
134+
price_view
135+
ship_bundle_items
136+
items {
137+
option_id
138+
title
139+
required
140+
type
141+
position
142+
sku
143+
options {
144+
id
145+
qty
146+
position
147+
is_default
148+
price
149+
price_type
150+
can_change_quantity
151+
label
152+
product {
153+
id
154+
name
155+
sku
156+
type_id
157+
}
158+
}
159+
}
160+
}
161+
}
162+
}
163+
}
164+
QUERY;
165+
166+
/** @var \Magento\Config\Model\ResourceModel\Config $config */
167+
$config = ObjectManager::getInstance()->get(\Magento\Config\Model\ResourceModel\Config::class);
168+
$config->saveConfig(
169+
\Magento\CatalogInventory\Model\Configuration::XML_PATH_SHOW_OUT_OF_STOCK,
170+
0,
171+
ScopeConfigInterface::SCOPE_TYPE_DEFAULT,
172+
0
173+
);
174+
ObjectManager::getInstance()->get(\Magento\Framework\App\Cache::class)
175+
->clean(\Magento\Framework\App\Config::CACHE_TAG);
176+
$response = $this->graphQlQuery($query);
177+
$this->assertNotEmpty(
178+
$response['products']['items'],
179+
"Precondition failed: 'items' must not be empty"
180+
);
181+
182+
/** @var ProductRepositoryInterface $productRepository */
183+
$productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class);
184+
/** @var MetadataPool $metadataPool */
185+
$metadataPool = ObjectManager::getInstance()->get(MetadataPool::class);
186+
$bundleProduct = $productRepository->get($productSku, false, null, true);
187+
$bundleProduct->setId(
188+
$bundleProduct->getData($metadataPool->getMetadata(ProductInterface::class)->getLinkField())
189+
);
190+
if ((bool)$bundleProduct->getShipmentType()) {
191+
$this->assertEquals('SEPARATELY', $response['products']['items'][0]['ship_bundle_items']);
192+
} else {
193+
$this->assertEquals('TOGETHER', $response['products']['items'][0]['ship_bundle_items']);
194+
}
195+
if ((bool)$bundleProduct->getPriceView()) {
196+
$this->assertEquals('AS_LOW_AS', $response['products']['items'][0]['price_view']);
197+
} else {
198+
$this->assertEquals('PRICE_RANGE', $response['products']['items'][0]['price_view']);
199+
}
200+
$this->assertBundleBaseFields($bundleProduct, $response['products']['items'][0]);
201+
202+
$this->assertBundleProductOptions($bundleProduct, $response['products']['items'][0]);
203+
$this->assertNotEmpty(
204+
$response['products']['items'][0]['items'],
205+
"Precondition failed: 'items' must not be empty"
206+
);
207+
}
208+
107209
/**
108210
* @param ProductInterface $product
109211
* @param array $actualResponse
@@ -140,6 +242,7 @@ private function assertBundleProductOptions($product, $actualResponse)
140242
$optionList = ObjectManager::getInstance()->get(\Magento\Bundle\Model\Product\OptionList::class);
141243
$options = $optionList->getItems($product);
142244
$option = $options[0];
245+
/** @var \Magento\Bundle\Api\Data\LinkInterface $bundleProductLinks */
143246
$bundleProductLinks = $option->getProductLinks();
144247
$bundleProductLink = $bundleProductLinks[0];
145248
$childProductSku = $bundleProductLink->getSku();
@@ -168,7 +271,6 @@ private function assertBundleProductOptions($product, $actualResponse)
168271
'qty' => (int)$bundleProductLink->getQty(),
169272
'position' => $bundleProductLink->getPosition(),
170273
'is_default' => (bool)$bundleProductLink->getIsDefault(),
171-
'price' => $bundleProductLink->getPrice(),
172274
'price_type' => self::KEY_PRICE_TYPE_FIXED,
173275
'can_change_quantity' => $bundleProductLink->getCanChangeQuantity(),
174276
'label' => $childProduct->getName()

dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1162,7 +1162,6 @@ public function testQueryWithNoSearchOrFilterArgumentException()
11621162
*/
11631163
public function testFilterProductsThatAreOutOfStockWithConfigSettings()
11641164
{
1165-
$this->markTestSkipped('Skipped until visibility honors config settings is fixed in MAGETWO-89246');
11661165
$query
11671166
=<<<QUERY
11681167
{
@@ -1202,6 +1201,10 @@ public function testFilterProductsThatAreOutOfStockWithConfigSettings()
12021201
'simple_visible_in_stock',
12031202
$responseObject->getData('products/items/0/sku')
12041203
);
1204+
self::assertEquals(
1205+
'Simple Product Visible and InStock',
1206+
$responseObject->getData('products/items/0/name')
1207+
);
12051208
$this->assertEquals(1, $response['products']['total_count']);
12061209
}
12071210

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
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+
/*
9+
* Since the bundle product creation GUI doesn't allow to choose values for bundled products' custom options,
10+
* bundled items should not contain products with required custom options.
11+
* However, if to create such a bundle product, it will be always out of stock.
12+
*/
13+
require __DIR__ . '/../../../Magento/Catalog/_files/simple_products_not_visible_individually.php';
14+
15+
/** @var $objectManager \Magento\TestFramework\ObjectManager */
16+
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
17+
/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */
18+
$productRepository = $objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class);
19+
$sampleProduct = $productRepository->get('simple_not_visible_1');
20+
21+
/** @var $product \Magento\Catalog\Model\Product */
22+
$product = $objectManager->create(\Magento\Catalog\Model\Product::class);
23+
$product->setTypeId('bundle')
24+
->setId(3)
25+
->setAttributeSetId(4)
26+
->setWeight(2)
27+
->setWebsiteIds([1])
28+
->setName('Bundle Product')
29+
->setSku('bundle-product-1')
30+
->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
31+
->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
32+
->setStockData(['use_config_manage_stock' => 1, 'qty' => 100, 'is_qty_decimal' => 0, 'is_in_stock' => 1])
33+
->setPriceView(0)
34+
->setSkuType(1)
35+
->setWeightType(0)
36+
->setPriceType(0)
37+
->setShipmentType(0)
38+
->setPrice(10.0)
39+
->setBundleOptionsData(
40+
[
41+
[
42+
'title' => 'Bundle Product Items',
43+
'default_title' => 'Bundle Product Items',
44+
'type' => 'select', 'required' => 1,
45+
'delete' => '',
46+
],
47+
]
48+
)
49+
->setBundleSelectionsData(
50+
[
51+
[
52+
[
53+
'product_id' => $sampleProduct->getId(),
54+
'selection_price_value' => 2.75,
55+
'selection_qty' => 2,
56+
'selection_can_change_qty' => 1,
57+
'delete' => '',
58+
59+
],
60+
],
61+
]
62+
);
63+
64+
if ($product->getBundleOptionsData()) {
65+
$options = [];
66+
foreach ($product->getBundleOptionsData() as $key => $optionData) {
67+
if (!(bool)$optionData['delete']) {
68+
$option = $objectManager->create(\Magento\Bundle\Api\Data\OptionInterfaceFactory::class)
69+
->create(['data' => $optionData]);
70+
$option->setSku($product->getSku());
71+
$option->setOptionId(null);
72+
73+
$links = [];
74+
$bundleLinks = $product->getBundleSelectionsData();
75+
if (!empty($bundleLinks[$key])) {
76+
foreach ($bundleLinks[$key] as $linkData) {
77+
if (!(bool)$linkData['delete']) {
78+
/** @var \Magento\Bundle\Api\Data\LinkInterface$link */
79+
$link = $objectManager->create(\Magento\Bundle\Api\Data\LinkInterfaceFactory::class)
80+
->create(['data' => $linkData]);
81+
$linkProduct = $productRepository->getById($linkData['product_id']);
82+
$link->setSku($linkProduct->getSku());
83+
$link->setQty($linkData['selection_qty']);
84+
$link->setPrice($linkData['selection_price_value']);
85+
if (isset($linkData['selection_can_change_qty'])) {
86+
$link->setCanChangeQuantity($linkData['selection_can_change_qty']);
87+
}
88+
$links[] = $link;
89+
}
90+
}
91+
$option->setProductLinks($links);
92+
$options[] = $option;
93+
}
94+
}
95+
}
96+
$extension = $product->getExtensionAttributes();
97+
$extension->setBundleProductOptions($options);
98+
$product->setExtensionAttributes($extension);
99+
}
100+
//$product->save();
101+
$productRepository->save($product, true);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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+
/*
9+
* Since the bundle product creation GUI doesn't allow to choose values for bundled products' custom options,
10+
* bundled items should not contain products with required custom options.
11+
* However, if to create such a bundle product, it will be always out of stock.
12+
*/
13+
require __DIR__ . '/../../../Magento/Catalog/_files/simple_products_not_visible_individually_rollback.php';
14+
15+
/** @var \Magento\Framework\Registry $registry */
16+
$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class);
17+
$registry->unregister('isSecureArea');
18+
$registry->register('isSecureArea', true);
19+
20+
$productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
21+
->get(\Magento\Catalog\Api\ProductRepositoryInterface::class);
22+
try {
23+
$product = $productRepository->get('bundle-product-1', false, null, true);
24+
$productRepository->delete($product);
25+
} catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
26+
//Product already removed
27+
}
28+
29+
$registry->unregister('isSecureArea');
30+
$registry->register('isSecureArea', false);
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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+
/** @var $product \Magento\Catalog\Model\Product */
9+
$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class);
10+
$product->isObjectNew(true);
11+
$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)
12+
->setId(67)
13+
->setAttributeSetId(4)
14+
->setName('Simple Product Not visible 1')
15+
->setSku('simple_not_visible_1')
16+
->setTaxClassId('none')
17+
->setDescription('description')
18+
->setShortDescription('short description')
19+
->setOptionsContainer('container1')
20+
->setMsrpDisplayActualPriceType(\Magento\Msrp\Model\Product\Attribute\Source\Type::TYPE_IN_CART)
21+
->setPrice(10)
22+
->setWeight(1)
23+
->setMetaTitle('meta title product Not visible')
24+
->setMetaKeyword('meta keyword')
25+
->setMetaDescription('meta description')
26+
->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_NOT_VISIBLE)
27+
->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
28+
->setWebsiteIds([1])
29+
->setCategoryIds([300])
30+
->setStockData(['use_config_manage_stock' => 1, 'qty' => 30, 'is_qty_decimal' => 0, 'is_in_stock' => 1])
31+
->setSpecialPrice('5.99')
32+
->save();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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+
use Magento\Framework\Exception\NoSuchEntityException;
9+
10+
\Magento\TestFramework\Helper\Bootstrap::getInstance()->getInstance()->reinitialize();
11+
12+
/** @var \Magento\Framework\Registry $registry */
13+
$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class);
14+
15+
$registry->unregister('isSecureArea');
16+
$registry->register('isSecureArea', true);
17+
18+
/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */
19+
$productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
20+
->get(\Magento\Catalog\Api\ProductRepositoryInterface::class);
21+
try {
22+
$product = $productRepository->get('simple_not_visible_1', false, null, true);
23+
$productRepository->delete($product);
24+
} catch (NoSuchEntityException $e) {
25+
}
26+
$registry->unregister('isSecureArea');
27+
$registry->register('isSecureArea', false);

0 commit comments

Comments
 (0)