Skip to content

Commit c8d8302

Browse files
committed
Merge branch 'ACP2E-42' of https://github.com/magento-l3/magento2ce into L3-PR-20220202
2 parents 1c08100 + ab1900b commit c8d8302

File tree

7 files changed

+155
-10
lines changed

7 files changed

+155
-10
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
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\QuoteGraphQl\Model\Resolver;
9+
10+
use Magento\Framework\Exception\LocalizedException;
11+
use Magento\Framework\Exception\RuntimeException;
12+
use Magento\Framework\GraphQl\Config\Element\Field;
13+
use Magento\Framework\GraphQl\Query\ResolverInterface;
14+
use Magento\Framework\GraphQl\Query\EnumLookup;
15+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
16+
use Magento\Quote\Model\Quote\Item;
17+
18+
/**
19+
* @inheritdoc
20+
*/
21+
class CartItemErrors implements ResolverInterface
22+
{
23+
/**
24+
* Error code
25+
*/
26+
private const ERROR_UNDEFINED = 0;
27+
28+
/**
29+
* @var EnumLookup
30+
*/
31+
private $enumLookup;
32+
33+
/**
34+
* @param EnumLookup $enumLookup
35+
*/
36+
public function __construct(
37+
EnumLookup $enumLookup
38+
) {
39+
$this->enumLookup = $enumLookup;
40+
}
41+
42+
/**
43+
* @inheritdoc
44+
*/
45+
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
46+
{
47+
if (!isset($value['model'])) {
48+
throw new LocalizedException(__('"model" value should be specified'));
49+
}
50+
/** @var Item $cartItem */
51+
$cartItem = $value['model'];
52+
53+
return $this->getItemErrors($cartItem);
54+
}
55+
56+
/**
57+
* Get error messages for cart item
58+
*
59+
* @param Item $cartItem
60+
* @return string[]|null
61+
* @throws RuntimeException
62+
*/
63+
private function getItemErrors(Item $cartItem): ?array
64+
{
65+
$hasError = (bool) $cartItem->getData('has_error');
66+
if (!$hasError) {
67+
return null;
68+
}
69+
70+
$errors = [];
71+
foreach ($cartItem->getErrorInfos() as $error) {
72+
$errorType = $error['code'] ?? self::ERROR_UNDEFINED;
73+
$message = $error['message'] ?? $cartItem->getMessage();
74+
$errorEnumCode = $this->enumLookup->getEnumValueFromField(
75+
'CartItemErrorType',
76+
(string)$errorType
77+
);
78+
$errors[$message] = [
79+
'code' => $errorEnumCode,
80+
'message' => $message
81+
];
82+
}
83+
84+
return array_values($errors);
85+
}
86+
}

app/code/Magento/QuoteGraphQl/Model/Resolver/CartItems.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,6 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value
5454
$cart = $value['model'];
5555

5656
$itemsData = [];
57-
if ($cart->getData('has_error')) {
58-
$errors = $cart->getErrors();
59-
foreach ($errors as $error) {
60-
$itemsData[] = new GraphQlInputException(__($error->getText()));
61-
}
62-
}
63-
6457
$cartProductsData = $this->getCartProductsData($cart);
6558
$cartItems = $cart->getAllVisibleItems();
6659
/** @var QuoteItem $cartItem */

app/code/Magento/QuoteGraphQl/etc/graphql/di.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,15 @@
4949
<argument name="errorMessageFormatter" xsi:type="object">Magento\QuoteGraphQl\Helper\Error\PlaceOrderMessageFormatter</argument>
5050
</arguments>
5151
</type>
52+
<type name="Magento\Framework\GraphQl\Schema\Type\Enum\DefaultDataMapper">
53+
<arguments>
54+
<argument name="map" xsi:type="array">
55+
<item name="CartItemErrorType" xsi:type="array">
56+
<item name="undefined" xsi:type="string">0</item>
57+
<item name="item_qty" xsi:type="string">1</item>
58+
<item name="item_increment" xsi:type="string">2</item>
59+
</item>
60+
</argument>
61+
</arguments>
62+
</type>
5263
</config>

app/code/Magento/QuoteGraphQl/etc/schema.graphqls

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,18 @@ interface CartItemInterface @typeResolver(class: "Magento\\QuoteGraphQl\\Model\\
339339
quantity: Float! @doc(description: "The quantity of this item in the cart.")
340340
prices: CartItemPrices @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CartItemPrices") @doc(description: "Contains details about the price of the item, including taxes and discounts.")
341341
product: ProductInterface! @doc(description: "Details about an item in the cart.")
342+
errors: [CartItemError!] @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CartItemErrors") @doc(description: "An array of errors encountered while loading the cart item")
343+
}
344+
345+
type CartItemError {
346+
code: CartItemErrorType! @doc(description: "An error code that describes the error encountered")
347+
message: String! @doc(description: "A localized error message")
348+
}
349+
350+
enum CartItemErrorType {
351+
UNDEFINED
352+
ITEM_QTY
353+
ITEM_INCREMENTS
342354
}
343355

344356
type Discount @doc(description:"Defines an individual discount. A discount can be applied to the cart as a whole or to an item.") {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""model"" value should be specified","""model"" value should be specified"

dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/AddSimpleProductToCartTest.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,24 +209,25 @@ public function testAddDisabledProductToCart(): void
209209
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
210210
* @magentoApiDataFixture Magento/Catalog/_files/multiple_products.php
211211
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
212-
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php
213212
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/set_simple_product_out_of_stock.php
214213
* @return void
215214
* @throws NoSuchEntityException
216215
*/
217216
public function testAddOutOfStockProductToCart(): void
218217
{
219218
$sku = 'simple1';
219+
$skuOutOfStock = 'simple_product';
220220
$quantity = 1;
221221

222222
$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote');
223223
$query = $this->getQuery($maskedQuoteId, $sku, $quantity);
224+
$this->graphQlMutation($query);
224225

225226
$this->expectException(ResponseContainsErrorsException::class);
226227
$this->expectExceptionMessage(
227-
'Some of the products are out of stock.'
228+
'Product that you are trying to add is not available'
228229
);
229-
230+
$query = $this->getQuery($maskedQuoteId, $skuOutOfStock, $quantity);
230231
$this->graphQlMutation($query);
231232
}
232233

dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetCartTest.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,42 @@ public function testGetCart()
6262
self::assertEquals('virtual-product', $response['cart']['items'][1]['product']['sku']);
6363
}
6464

65+
/**
66+
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
67+
* @magentoApiDataFixture Magento/Catalog/_files/product_virtual.php
68+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
69+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php
70+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_virtual_product.php
71+
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/set_simple_product_out_of_stock.php
72+
*/
73+
public function testCartErrorWithOutOfStockItem()
74+
{
75+
$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote');
76+
$query = $this->getQuery($maskedQuoteId);
77+
78+
$response = $this->graphQlQuery($query);
79+
80+
self::assertArrayHasKey('cart', $response);
81+
self::assertArrayHasKey('items', $response['cart']);
82+
self::assertArrayHasKey('errors', $response['cart']['items'][0]);
83+
self::assertEquals(
84+
'There are no source items with the in stock status',
85+
$response['cart']['items'][0]['errors'][0]['message']
86+
);
87+
self::assertArrayHasKey('id', $response['cart']);
88+
self::assertEquals($maskedQuoteId, $response['cart']['id']);
89+
self::assertCount(2, $response['cart']['items']);
90+
91+
self::assertNotEmpty($response['cart']['items'][0]['id']);
92+
self::assertEquals(2, $response['cart']['items'][0]['quantity']);
93+
self::assertEquals('simple_product', $response['cart']['items'][0]['product']['sku']);
94+
self::assertEquals('OUT_OF_STOCK', $response['cart']['items'][0]['product']['stock_status']);
95+
96+
self::assertNotEmpty($response['cart']['items'][1]['id']);
97+
self::assertEquals(2, $response['cart']['items'][1]['quantity']);
98+
self::assertEquals('virtual-product', $response['cart']['items'][1]['product']['sku']);
99+
}
100+
65101
/**
66102
* _security
67103
* @magentoApiDataFixture Magento/Customer/_files/customer.php
@@ -272,13 +308,18 @@ private function getQuery(string $maskedQuoteId): string
272308
quantity
273309
product {
274310
sku
311+
stock_status
275312
}
276313
prices {
277314
price {
278315
value
279316
currency
280317
}
281318
}
319+
errors {
320+
code
321+
message
322+
}
282323
}
283324
}
284325
}

0 commit comments

Comments
 (0)