Skip to content

Commit 9db836a

Browse files
authored
LYNX-542: Change updateCartItems mutation response (#291)
1 parent 60bcc31 commit 9db836a

File tree

6 files changed

+164
-61
lines changed

6 files changed

+164
-61
lines changed

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

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -25,41 +25,24 @@
2525
class UpdateCartItems implements ResolverInterface
2626
{
2727
/**
28-
* @var GetCartForUser
28+
* Undefined error code
2929
*/
30-
private $getCartForUser;
31-
32-
/**
33-
* @var CartRepositoryInterface
34-
*/
35-
private $cartRepository;
36-
37-
/**
38-
* @var UpdateCartItemsProvider
39-
*/
40-
private $updateCartItems;
41-
42-
/**
43-
* @var ArgumentsProcessorInterface
44-
*/
45-
private $argsSelection;
30+
private const CODE_UNDEFINED = 'UNDEFINED';
4631

4732
/**
4833
* @param GetCartForUser $getCartForUser
4934
* @param CartRepositoryInterface $cartRepository
5035
* @param UpdateCartItemsProvider $updateCartItems
5136
* @param ArgumentsProcessorInterface $argsSelection
37+
* @param array $messageCodesMapper
5238
*/
5339
public function __construct(
54-
GetCartForUser $getCartForUser,
55-
CartRepositoryInterface $cartRepository,
56-
UpdateCartItemsProvider $updateCartItems,
57-
ArgumentsProcessorInterface $argsSelection
40+
private readonly GetCartForUser $getCartForUser,
41+
private readonly CartRepositoryInterface $cartRepository,
42+
private readonly UpdateCartItemsProvider $updateCartItems,
43+
private readonly ArgumentsProcessorInterface $argsSelection,
44+
private readonly array $messageCodesMapper,
5845
) {
59-
$this->getCartForUser = $getCartForUser;
60-
$this->cartRepository = $cartRepository;
61-
$this->updateCartItems = $updateCartItems;
62-
$this->argsSelection = $argsSelection;
6346
}
6447

6548
/**
@@ -75,10 +58,15 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value
7558

7659
$maskedCartId = $processedArgs['input']['cart_id'];
7760

61+
$errors = [];
7862
if (empty($processedArgs['input']['cart_items'])
7963
|| !is_array($processedArgs['input']['cart_items'])
8064
) {
81-
throw new GraphQlInputException(__('Required parameter "cart_items" is missing.'));
65+
$message = 'Required parameter "cart_items" is missing.';
66+
$errors[] = [
67+
'message' => __($message),
68+
'code' => $this->getErrorCode($message)
69+
];
8270
}
8371

8472
$cartItems = $processedArgs['input']['cart_items'];
@@ -87,18 +75,37 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value
8775

8876
try {
8977
$this->updateCartItems->processCartItems($cart, $cartItems);
90-
$updatedCart = $this->getCartForUser->execute($maskedCartId, $context->getUserId(), $storeId);
91-
$this->cartRepository->save($updatedCart);
92-
} catch (NoSuchEntityException $e) {
93-
throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e);
94-
} catch (LocalizedException $e) {
95-
throw new GraphQlInputException(__($e->getMessage()), $e);
78+
$this->cartRepository->save(
79+
$this->cartRepository->get((int)$cart->getId())
80+
);
81+
} catch (NoSuchEntityException | LocalizedException $e) {
82+
$errors[] = [
83+
'message' => __($e->getMessage()),
84+
'code' => $this->getErrorCode($e->getMessage())
85+
];
9686
}
9787

9888
return [
9989
'cart' => [
100-
'model' => $updatedCart,
90+
'model' => $cart,
10191
],
92+
'errors' => $errors,
10293
];
10394
}
95+
96+
/**
97+
* Returns error code based on error message
98+
*
99+
* @param string $message
100+
* @return string
101+
*/
102+
private function getErrorCode(string $message): string
103+
{
104+
foreach ($this->messageCodesMapper as $key => $code) {
105+
if (str_contains($message, $key)) {
106+
return $code;
107+
}
108+
}
109+
return self::CODE_UNDEFINED;
110+
}
104111
}

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,14 @@
7979
<plugin name="merge_guest_orders_with_customer_after_place"
8080
type="Magento\QuoteGraphQl\Plugin\Model\MergeGuestOrder" />
8181
</type>
82+
<type name="Magento\QuoteGraphQl\Model\Resolver\UpdateCartItems">
83+
<arguments>
84+
<argument name="messageCodesMapper" xsi:type="array">
85+
<item name="The requested qty" xsi:type="string">INSUFFICIENT_STOCK</item>
86+
<item name="Could not find cart item" xsi:type="string">COULD_NOT_FIND_CART_ITEM</item>
87+
<item name="Required parameter" xsi:type="string">REQUIRED_PARAMETER_MISSING</item>
88+
<item name="The fewest you may purchase" xsi:type="string">INVALID_PARAMETER_VALUE</item>
89+
</argument>
90+
</arguments>
91+
</type>
8292
</config>

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,7 @@ type AddVirtualProductsToCartOutput @doc(description: "Contains details about th
396396

397397
type UpdateCartItemsOutput @doc(description: "Contains details about the cart after updating items.") {
398398
cart: Cart! @doc(description: "The cart after updating products.")
399+
errors: [CartUserInputError!]! @doc(description: "Contains errors encountered while updating an item to the cart.")
399400
}
400401

401402
type RemoveItemFromCartOutput @doc(description: "Contains details about the cart after removing an item.") {
@@ -500,6 +501,9 @@ enum CartUserInputErrorType {
500501
PRODUCT_NOT_FOUND
501502
NOT_SALABLE
502503
INSUFFICIENT_STOCK
504+
COULD_NOT_FIND_CART_ITEM
505+
REQUIRED_PARAMETER_MISSING
506+
INVALID_PARAMETER_VALUE
503507
UNDEFINED
504508
}
505509
enum PlaceOrderErrorCodes {

dev/tests/api-functional/testsuite/Magento/GraphQl/CatalogInventory/UpdateCartItemsTest.php

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,18 @@ public function testUpdateCartItemDecimalQuantity()
4747
$itemId = $this->getQuoteItemIdByReservedQuoteIdAndSku->execute('test_quote', 'simple_product');
4848

4949
$quantity = 0.5;
50-
$this->expectExceptionMessage(
51-
"Could not update the product with SKU simple_product: The fewest you may purchase is 1"
52-
);
5350
$query = $this->getQuery($maskedQuoteId, $itemId, $quantity);
54-
$this->graphQlMutation($query);
51+
$response = $this->graphQlMutation($query);
52+
53+
$this->assertArrayHasKey('updateCartItems', $response);
54+
$this->assertArrayHasKey('errors', $response['updateCartItems']);
55+
56+
$responseError = $response['updateCartItems']['errors'][0];
57+
$this->assertEquals(
58+
"Could not update the product with SKU simple_product: The fewest you may purchase is 1.",
59+
$responseError['message']
60+
);
61+
$this->assertEquals('INVALID_PARAMETER_VALUE', $responseError['code']);
5562
}
5663

5764
/**
@@ -65,11 +72,18 @@ public function testUpdateCartItemSetUnavailableQuantity()
6572
$itemId = $this->getQuoteItemIdByReservedQuoteIdAndSku->execute('test_quote', 'simple_product');
6673

6774
$quantity = 100;
68-
$this->expectExceptionMessage(
69-
"Could not update the product with SKU simple_product: The requested qty is not available"
70-
);
7175
$query = $this->getQuery($maskedQuoteId, $itemId, $quantity);
72-
$this->graphQlMutation($query);
76+
$response = $this->graphQlMutation($query);
77+
78+
$this->assertArrayHasKey('updateCartItems', $response);
79+
$this->assertArrayHasKey('errors', $response['updateCartItems']);
80+
81+
$responseError = $response['updateCartItems']['errors'][0];
82+
$this->assertEquals(
83+
"Could not update the product with SKU simple_product: The requested qty is not available",
84+
$responseError['message']
85+
);
86+
$this->assertEquals('INSUFFICIENT_STOCK', $responseError['code']);
7387
}
7488

7589
/**
@@ -97,6 +111,10 @@ private function getQuery(string $maskedQuoteId, int $itemId, float $quantity):
97111
quantity
98112
}
99113
}
114+
errors {
115+
message
116+
code
117+
}
100118
}
101119
}
102120
QUERY;

dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/UpdateCartItemsTest.php

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,18 @@ public function testUpdateNonExistentItem()
122122
$maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$quote->getId());
123123
$notExistentItemId = 999;
124124

125-
$this->expectExceptionMessage("Could not find cart item with id: {$notExistentItemId}.");
126-
127125
$query = $this->getQuery($maskedQuoteId, $notExistentItemId, 2);
128-
$this->graphQlMutation($query, [], '', $this->getHeaderMap());
126+
$response = $this->graphQlMutation($query, [], '', $this->getHeaderMap());
127+
128+
$this->assertArrayHasKey('updateCartItems', $response);
129+
$this->assertArrayHasKey('errors', $response['updateCartItems']);
130+
131+
$responseError = $response['updateCartItems']['errors'][0];
132+
$this->assertEquals(
133+
"Could not find cart item with id: {$notExistentItemId}.",
134+
$responseError['message']
135+
);
136+
$this->assertEquals('COULD_NOT_FIND_CART_ITEM', $responseError['code']);
129137
}
130138

131139
/**
@@ -150,10 +158,18 @@ public function testUpdateItemIfItemIsNotBelongToCart()
150158
->getItemByProduct($this->productRepository->get('virtual-product'))
151159
->getId();
152160

153-
$this->expectExceptionMessage("Could not find cart item with id: {$secondQuoteItemId}.");
154-
155161
$query = $this->getQuery($firstQuoteMaskedId, $secondQuoteItemId, 2);
156-
$this->graphQlMutation($query, [], '', $this->getHeaderMap());
162+
$response = $this->graphQlMutation($query, [], '', $this->getHeaderMap());
163+
164+
$this->assertArrayHasKey('updateCartItems', $response);
165+
$this->assertArrayHasKey('errors', $response['updateCartItems']);
166+
167+
$responseError = $response['updateCartItems']['errors'][0];
168+
$this->assertEquals(
169+
"Could not find cart item with id: {$secondQuoteItemId}.",
170+
$responseError['message']
171+
);
172+
$this->assertEquals('COULD_NOT_FIND_CART_ITEM', $responseError['code']);
157173
}
158174

159175
/**
@@ -213,10 +229,11 @@ public function testUpdateItemInAnotherCustomerCart()
213229
/**
214230
* @param string $input
215231
* @param string $message
232+
* @param string $errorCode
216233
* @dataProvider dataProviderUpdateWithMissedRequiredParameters
217234
* @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php
218235
*/
219-
public function testUpdateWithMissedItemRequiredParameters(string $input, string $message)
236+
public function testUpdateWithMissedItemRequiredParameters(string $input, string $message, string $errorCode)
220237
{
221238
$quote = $this->quoteFactory->create();
222239
$this->quoteResource->load($quote, 'test_order_1', 'reserved_order_id');
@@ -234,11 +251,21 @@ public function testUpdateWithMissedItemRequiredParameters(string $input, string
234251
quantity
235252
}
236253
}
254+
errors {
255+
message
256+
code
257+
}
237258
}
238259
}
239260
QUERY;
240-
$this->expectExceptionMessage($message);
241-
$this->graphQlMutation($query, [], '', $this->getHeaderMap());
261+
$response = $this->graphQlMutation($query, [], '', $this->getHeaderMap());
262+
263+
$this->assertArrayHasKey('updateCartItems', $response);
264+
$this->assertArrayHasKey('errors', $response['updateCartItems']);
265+
266+
$responseError = $response['updateCartItems']['errors'][0];
267+
$this->assertEquals($message, $responseError['message']);
268+
$this->assertEquals($errorCode, $responseError['code']);
242269
}
243270

244271
/**
@@ -249,7 +276,8 @@ public static function dataProviderUpdateWithMissedRequiredParameters(): array
249276
return [
250277
'missed_cart_item_qty' => [
251278
'cart_items: [{ cart_item_id: 1 }]',
252-
'Required parameter "quantity" for "cart_items" is missing.'
279+
'Required parameter "quantity" for "cart_items" is missing.',
280+
'REQUIRED_PARAMETER_MISSING'
253281
],
254282
];
255283
}
@@ -279,6 +307,10 @@ private function getQuery(string $maskedQuoteId, int $itemId, float $quantity):
279307
quantity
280308
}
281309
}
310+
errors {
311+
message
312+
code
313+
}
282314
}
283315
}
284316
QUERY;

0 commit comments

Comments
 (0)