Skip to content

Commit

Permalink
LYNX-542: Change updateCartItems mutation response (#291)
Browse files Browse the repository at this point in the history
  • Loading branch information
sumesh-GL authored Sep 19, 2024
1 parent 60bcc31 commit 9db836a
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 61 deletions.
73 changes: 40 additions & 33 deletions app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,41 +25,24 @@
class UpdateCartItems implements ResolverInterface
{
/**
* @var GetCartForUser
* Undefined error code
*/
private $getCartForUser;

/**
* @var CartRepositoryInterface
*/
private $cartRepository;

/**
* @var UpdateCartItemsProvider
*/
private $updateCartItems;

/**
* @var ArgumentsProcessorInterface
*/
private $argsSelection;
private const CODE_UNDEFINED = 'UNDEFINED';

/**
* @param GetCartForUser $getCartForUser
* @param CartRepositoryInterface $cartRepository
* @param UpdateCartItemsProvider $updateCartItems
* @param ArgumentsProcessorInterface $argsSelection
* @param array $messageCodesMapper
*/
public function __construct(
GetCartForUser $getCartForUser,
CartRepositoryInterface $cartRepository,
UpdateCartItemsProvider $updateCartItems,
ArgumentsProcessorInterface $argsSelection
private readonly GetCartForUser $getCartForUser,
private readonly CartRepositoryInterface $cartRepository,
private readonly UpdateCartItemsProvider $updateCartItems,
private readonly ArgumentsProcessorInterface $argsSelection,
private readonly array $messageCodesMapper,
) {
$this->getCartForUser = $getCartForUser;
$this->cartRepository = $cartRepository;
$this->updateCartItems = $updateCartItems;
$this->argsSelection = $argsSelection;
}

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

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

$errors = [];
if (empty($processedArgs['input']['cart_items'])
|| !is_array($processedArgs['input']['cart_items'])
) {
throw new GraphQlInputException(__('Required parameter "cart_items" is missing.'));
$message = 'Required parameter "cart_items" is missing.';
$errors[] = [
'message' => __($message),
'code' => $this->getErrorCode($message)
];
}

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

try {
$this->updateCartItems->processCartItems($cart, $cartItems);
$updatedCart = $this->getCartForUser->execute($maskedCartId, $context->getUserId(), $storeId);
$this->cartRepository->save($updatedCart);
} catch (NoSuchEntityException $e) {
throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e);
} catch (LocalizedException $e) {
throw new GraphQlInputException(__($e->getMessage()), $e);
$this->cartRepository->save(
$this->cartRepository->get((int)$cart->getId())
);
} catch (NoSuchEntityException | LocalizedException $e) {
$errors[] = [
'message' => __($e->getMessage()),
'code' => $this->getErrorCode($e->getMessage())
];
}

return [
'cart' => [
'model' => $updatedCart,
'model' => $cart,
],
'errors' => $errors,
];
}

/**
* Returns error code based on error message
*
* @param string $message
* @return string
*/
private function getErrorCode(string $message): string
{
foreach ($this->messageCodesMapper as $key => $code) {
if (str_contains($message, $key)) {
return $code;
}
}
return self::CODE_UNDEFINED;
}
}
10 changes: 10 additions & 0 deletions app/code/Magento/QuoteGraphQl/etc/graphql/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,14 @@
<plugin name="merge_guest_orders_with_customer_after_place"
type="Magento\QuoteGraphQl\Plugin\Model\MergeGuestOrder" />
</type>
<type name="Magento\QuoteGraphQl\Model\Resolver\UpdateCartItems">
<arguments>
<argument name="messageCodesMapper" xsi:type="array">
<item name="The requested qty" xsi:type="string">INSUFFICIENT_STOCK</item>
<item name="Could not find cart item" xsi:type="string">COULD_NOT_FIND_CART_ITEM</item>
<item name="Required parameter" xsi:type="string">REQUIRED_PARAMETER_MISSING</item>
<item name="The fewest you may purchase" xsi:type="string">INVALID_PARAMETER_VALUE</item>
</argument>
</arguments>
</type>
</config>
4 changes: 4 additions & 0 deletions app/code/Magento/QuoteGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,7 @@ type AddVirtualProductsToCartOutput @doc(description: "Contains details about th

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

type RemoveItemFromCartOutput @doc(description: "Contains details about the cart after removing an item.") {
Expand Down Expand Up @@ -500,6 +501,9 @@ enum CartUserInputErrorType {
PRODUCT_NOT_FOUND
NOT_SALABLE
INSUFFICIENT_STOCK
COULD_NOT_FIND_CART_ITEM
REQUIRED_PARAMETER_MISSING
INVALID_PARAMETER_VALUE
UNDEFINED
}
enum PlaceOrderErrorCodes {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,18 @@ public function testUpdateCartItemDecimalQuantity()
$itemId = $this->getQuoteItemIdByReservedQuoteIdAndSku->execute('test_quote', 'simple_product');

$quantity = 0.5;
$this->expectExceptionMessage(
"Could not update the product with SKU simple_product: The fewest you may purchase is 1"
);
$query = $this->getQuery($maskedQuoteId, $itemId, $quantity);
$this->graphQlMutation($query);
$response = $this->graphQlMutation($query);

$this->assertArrayHasKey('updateCartItems', $response);
$this->assertArrayHasKey('errors', $response['updateCartItems']);

$responseError = $response['updateCartItems']['errors'][0];
$this->assertEquals(
"Could not update the product with SKU simple_product: The fewest you may purchase is 1.",
$responseError['message']
);
$this->assertEquals('INVALID_PARAMETER_VALUE', $responseError['code']);
}

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

$quantity = 100;
$this->expectExceptionMessage(
"Could not update the product with SKU simple_product: The requested qty is not available"
);
$query = $this->getQuery($maskedQuoteId, $itemId, $quantity);
$this->graphQlMutation($query);
$response = $this->graphQlMutation($query);

$this->assertArrayHasKey('updateCartItems', $response);
$this->assertArrayHasKey('errors', $response['updateCartItems']);

$responseError = $response['updateCartItems']['errors'][0];
$this->assertEquals(
"Could not update the product with SKU simple_product: The requested qty is not available",
$responseError['message']
);
$this->assertEquals('INSUFFICIENT_STOCK', $responseError['code']);
}

/**
Expand Down Expand Up @@ -97,6 +111,10 @@ private function getQuery(string $maskedQuoteId, int $itemId, float $quantity):
quantity
}
}
errors {
message
code
}
}
}
QUERY;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,18 @@ public function testUpdateNonExistentItem()
$maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$quote->getId());
$notExistentItemId = 999;

$this->expectExceptionMessage("Could not find cart item with id: {$notExistentItemId}.");

$query = $this->getQuery($maskedQuoteId, $notExistentItemId, 2);
$this->graphQlMutation($query, [], '', $this->getHeaderMap());
$response = $this->graphQlMutation($query, [], '', $this->getHeaderMap());

$this->assertArrayHasKey('updateCartItems', $response);
$this->assertArrayHasKey('errors', $response['updateCartItems']);

$responseError = $response['updateCartItems']['errors'][0];
$this->assertEquals(
"Could not find cart item with id: {$notExistentItemId}.",
$responseError['message']
);
$this->assertEquals('COULD_NOT_FIND_CART_ITEM', $responseError['code']);
}

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

$this->expectExceptionMessage("Could not find cart item with id: {$secondQuoteItemId}.");

$query = $this->getQuery($firstQuoteMaskedId, $secondQuoteItemId, 2);
$this->graphQlMutation($query, [], '', $this->getHeaderMap());
$response = $this->graphQlMutation($query, [], '', $this->getHeaderMap());

$this->assertArrayHasKey('updateCartItems', $response);
$this->assertArrayHasKey('errors', $response['updateCartItems']);

$responseError = $response['updateCartItems']['errors'][0];
$this->assertEquals(
"Could not find cart item with id: {$secondQuoteItemId}.",
$responseError['message']
);
$this->assertEquals('COULD_NOT_FIND_CART_ITEM', $responseError['code']);
}

/**
Expand Down Expand Up @@ -213,10 +229,11 @@ public function testUpdateItemInAnotherCustomerCart()
/**
* @param string $input
* @param string $message
* @param string $errorCode
* @dataProvider dataProviderUpdateWithMissedRequiredParameters
* @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php
*/
public function testUpdateWithMissedItemRequiredParameters(string $input, string $message)
public function testUpdateWithMissedItemRequiredParameters(string $input, string $message, string $errorCode)
{
$quote = $this->quoteFactory->create();
$this->quoteResource->load($quote, 'test_order_1', 'reserved_order_id');
Expand All @@ -234,11 +251,21 @@ public function testUpdateWithMissedItemRequiredParameters(string $input, string
quantity
}
}
errors {
message
code
}
}
}
QUERY;
$this->expectExceptionMessage($message);
$this->graphQlMutation($query, [], '', $this->getHeaderMap());
$response = $this->graphQlMutation($query, [], '', $this->getHeaderMap());

$this->assertArrayHasKey('updateCartItems', $response);
$this->assertArrayHasKey('errors', $response['updateCartItems']);

$responseError = $response['updateCartItems']['errors'][0];
$this->assertEquals($message, $responseError['message']);
$this->assertEquals($errorCode, $responseError['code']);
}

/**
Expand All @@ -249,7 +276,8 @@ public static function dataProviderUpdateWithMissedRequiredParameters(): array
return [
'missed_cart_item_qty' => [
'cart_items: [{ cart_item_id: 1 }]',
'Required parameter "quantity" for "cart_items" is missing.'
'Required parameter "quantity" for "cart_items" is missing.',
'REQUIRED_PARAMETER_MISSING'
],
];
}
Expand Down Expand Up @@ -279,6 +307,10 @@ private function getQuery(string $maskedQuoteId, int $itemId, float $quantity):
quantity
}
}
errors {
message
code
}
}
}
QUERY;
Expand Down
Loading

0 comments on commit 9db836a

Please sign in to comment.