Skip to content

Commit d90b1b9

Browse files
committed
magento/graphql-ce#736: Configurable products with "out of stock" return as product: null
- added tests
1 parent 78c40ee commit d90b1b9

File tree

2 files changed

+113
-43
lines changed

2 files changed

+113
-43
lines changed

app/code/Magento/ConfigurableProductGraphQl/Model/Variant/Collection.php

Lines changed: 14 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,11 @@
99

1010
use Magento\Catalog\Api\Data\ProductInterface;
1111
use Magento\Catalog\Model\Product;
12-
use Magento\Catalog\Model\ProductFactory;
1312
use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\Collection as ChildCollection;
1413
use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\CollectionFactory;
1514
use Magento\Framework\EntityManager\MetadataPool;
1615
use Magento\Framework\Api\SearchCriteriaBuilder;
17-
use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product as DataProvider;
18-
use Magento\CatalogInventory\Helper\Stock;
19-
use Magento\CatalogInventory\Api\StockConfigurationInterface;
16+
use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\CollectionProcessorInterface;
2017

2118
/**
2219
* Collection for fetching configurable child product data.
@@ -28,31 +25,11 @@ class Collection
2825
*/
2926
private $childCollectionFactory;
3027

31-
/**
32-
* @var ProductFactory
33-
*/
34-
private $productFactory;
35-
3628
/**
3729
* @var SearchCriteriaBuilder
3830
*/
3931
private $searchCriteriaBuilder;
4032

41-
/**
42-
* @var DataProvider
43-
*/
44-
private $productDataProvider;
45-
46-
/**
47-
* @var Stock
48-
*/
49-
private $stockHelper;
50-
51-
/**
52-
* @var StockConfigurationInterface
53-
*/
54-
private $stockConfig;
55-
5633
/**
5734
* @var MetadataPool
5835
*/
@@ -73,31 +50,27 @@ class Collection
7350
*/
7451
private $attributeCodes = [];
7552

53+
/**
54+
* @var CollectionProcessorInterface
55+
*/
56+
private $collectionProcessor;
57+
7658
/**
7759
* @param CollectionFactory $childCollectionFactory
78-
* @param ProductFactory $productFactory
7960
* @param SearchCriteriaBuilder $searchCriteriaBuilder
80-
* @param DataProvider $productDataProvider
8161
* @param MetadataPool $metadataPool
82-
* @param Stock $stockHelper
83-
* @param StockConfigurationInterface $stockConfig
62+
* @param CollectionProcessorInterface $collectionProcessor
8463
*/
8564
public function __construct(
8665
CollectionFactory $childCollectionFactory,
87-
ProductFactory $productFactory,
8866
SearchCriteriaBuilder $searchCriteriaBuilder,
89-
DataProvider $productDataProvider,
9067
MetadataPool $metadataPool,
91-
Stock $stockHelper,
92-
StockConfigurationInterface $stockConfig
68+
CollectionProcessorInterface $collectionProcessor
9369
) {
9470
$this->childCollectionFactory = $childCollectionFactory;
95-
$this->productFactory = $productFactory;
9671
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
97-
$this->productDataProvider = $productDataProvider;
9872
$this->metadataPool = $metadataPool;
99-
$this->stockHelper = $stockHelper;
100-
$this->stockConfig = $stockConfig;
73+
$this->collectionProcessor = $collectionProcessor;
10174
}
10275

10376
/**
@@ -161,18 +134,16 @@ private function fetch() : array
161134
return $this->childrenMap;
162135
}
163136

164-
$showOutOfStock = $this->stockConfig->isShowOutOfStock();
165-
166137
foreach ($this->parentProducts as $product) {
167138
$attributeData = $this->getAttributesCodes($product);
168139
/** @var ChildCollection $childCollection */
169140
$childCollection = $this->childCollectionFactory->create();
170141
$childCollection->setProductFilter($product);
171-
$childCollection->addAttributeToSelect($attributeData);
172-
173-
if (!$showOutOfStock) {
174-
$this->stockHelper->addInStockFilterToCollection($childCollection);
175-
}
142+
$this->collectionProcessor->process(
143+
$childCollection,
144+
$this->searchCriteriaBuilder->create(),
145+
$attributeData
146+
);
176147

177148
/** @var Product $childProduct */
178149
foreach ($childCollection->getItems() as $childProduct) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
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\GraphQl\ConfigurableProduct;
9+
10+
use Magento\TestFramework\TestCase\GraphQlAbstract;
11+
use Magento\TestFramework\Helper\Bootstrap;
12+
use Magento\CatalogInventory\Api\StockRegistryInterface;
13+
14+
/**
15+
* Checks if stock status correctly displays for configurable variants.
16+
*/
17+
class ConfigurableProductStockStatusTest extends GraphQlAbstract
18+
{
19+
/**
20+
* @var StockRegistryInterface
21+
*/
22+
private $stockRegistry;
23+
24+
/**
25+
* @inheritdoc
26+
*/
27+
protected function setUp()
28+
{
29+
$this->stockRegistry = Bootstrap::getObjectManager()->create(StockRegistryInterface::class);
30+
}
31+
32+
/**
33+
* @magentoApiDataFixture Magento/Framework/Search/_files/product_configurable.php
34+
* @magentoConfigFixture default_store cataloginventory/options/show_out_of_stock 1
35+
*/
36+
public function testConfigurableProductShowOutOfStock()
37+
{
38+
$parentSku = 'configurable';
39+
$childSkuOutOfStock = 'simple_1010';
40+
$stockItem = $this->stockRegistry->getStockItemBySku($childSkuOutOfStock);
41+
$stockItem->setQty(0);
42+
$this->stockRegistry->updateStockItemBySku($childSkuOutOfStock, $stockItem);
43+
$query = $this->getQuery($parentSku);
44+
$response = $this->graphQlQuery($query);
45+
46+
foreach ($response['products']['items'][0]['variants'] as $children) {
47+
if ($children['product']['sku'] === $childSkuOutOfStock) {
48+
$this->assertEquals('OUT_OF_STOCK', $children['product']['stock_status']);
49+
} else {
50+
$this->assertEquals('IN_STOCK', $children['product']['stock_status']);
51+
}
52+
}
53+
}
54+
55+
/**
56+
* @magentoApiDataFixture Magento/Framework/Search/_files/product_configurable.php
57+
* @magentoConfigFixture default_store cataloginventory/options/show_out_of_stock 0
58+
*/
59+
public function testConfigurableProductDoNotShowOutOfStock()
60+
{
61+
$parentSku = 'configurable';
62+
$childSkuOutOfStock = 'simple_1010';
63+
$stockItem = $this->stockRegistry->getStockItemBySku($childSkuOutOfStock);
64+
$stockItem->setQty(0);
65+
$this->stockRegistry->updateStockItemBySku($childSkuOutOfStock, $stockItem);
66+
$query = $this->getQuery($parentSku);
67+
$response = $this->graphQlQuery($query);
68+
$this->assertEquals(
69+
[['product' => ['sku' => 'simple_1020', 'stock_status' => 'IN_STOCK']]],
70+
$response['products']['items'][0]['variants']
71+
);
72+
}
73+
74+
/**
75+
* @param string $sku
76+
* @return string
77+
*/
78+
private function getQuery(string $sku)
79+
{
80+
return <<<QUERY
81+
{
82+
products(filter: {sku: {eq: "{$sku}"}})
83+
{
84+
items {
85+
sku
86+
... on ConfigurableProduct {
87+
variants {
88+
product {
89+
sku
90+
stock_status
91+
}
92+
}
93+
}
94+
}
95+
}
96+
}
97+
QUERY;
98+
}
99+
}

0 commit comments

Comments
 (0)