diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CheckCategoryIsActive.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CheckCategoryIsActive.php new file mode 100644 index 0000000000000..16f816a967123 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CheckCategoryIsActive.php @@ -0,0 +1,67 @@ +collectionFactory = $collectionFactory; + $this->metadata = $metadata; + } + + /** + * Check if category is active. + * + * @param int $categoryId + * @throws GraphQlNoSuchEntityException + */ + public function execute(int $categoryId): void + { + $collection = $this->collectionFactory->create(); + $collection->addAttributeToFilter(CategoryInterface::KEY_IS_ACTIVE, ['eq' => 1]) + ->getSelect() + ->where( + $collection->getSelect() + ->getConnection() + ->quoteIdentifier( + 'e.' . + $this->metadata->getMetadata(CategoryInterface::class)->getIdentifierField() + ) . ' = ?', + $categoryId + ); + + if ($collection->count() === 0) { + throw new GraphQlNoSuchEntityException(__('Category doesn\'t exist')); + } + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryTree.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryTree.php index 1783a5cd9a7e5..89d3805383e1a 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryTree.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryTree.php @@ -7,6 +7,8 @@ namespace Magento\CatalogGraphQl\Model\Resolver; +use Magento\Catalog\Model\Category; +use Magento\CatalogGraphQl\Model\Resolver\Category\CheckCategoryIsActive; use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\ExtractDataFromCategoryTree; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\GraphQl\Config\Element\Field; @@ -34,16 +36,24 @@ class CategoryTree implements ResolverInterface */ private $extractDataFromCategoryTree; + /** + * @var CheckCategoryIsActive + */ + private $checkCategoryIsActive; + /** * @param \Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\CategoryTree $categoryTree * @param ExtractDataFromCategoryTree $extractDataFromCategoryTree + * @param CheckCategoryIsActive $checkCategoryIsActive */ public function __construct( \Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\CategoryTree $categoryTree, - ExtractDataFromCategoryTree $extractDataFromCategoryTree + ExtractDataFromCategoryTree $extractDataFromCategoryTree, + CheckCategoryIsActive $checkCategoryIsActive ) { $this->categoryTree = $categoryTree; $this->extractDataFromCategoryTree = $extractDataFromCategoryTree; + $this->checkCategoryIsActive = $checkCategoryIsActive; } /** @@ -72,6 +82,9 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value } $rootCategoryId = $this->getCategoryId($args); + if ($rootCategoryId !== Category::TREE_ROOT_ID) { + $this->checkCategoryIsActive->execute($rootCategoryId); + } $categoriesTree = $this->categoryTree->getTree($info, $rootCategoryId); if (empty($categoriesTree) || ($categoriesTree->count() == 0)) { diff --git a/app/code/Magento/GraphQl/etc/schema.graphqls b/app/code/Magento/GraphQl/etc/schema.graphqls index ab8472aa56cf0..a3211c44a2ef9 100644 --- a/app/code/Magento/GraphQl/etc/schema.graphqls +++ b/app/code/Magento/GraphQl/etc/schema.graphqls @@ -9,7 +9,7 @@ type Mutation { input FilterTypeInput @doc(description: "FilterTypeInput specifies which action will be performed in a query ") { eq: String @doc(description: "Equals") - finset: [String] @doc(description: "Find in set. The value can contain a set of comma-separated values") + finset: [String] @deprecated (reason: "The finset filter is deprecated. Magento doesn't recomend to store comma separated values, therefore finset filter is redundant.") from: String @doc(description: "From. Must be used with 'to'") gt: String @doc(description: "Greater than") gteq: String @doc(description: "Greater than or equal to") diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/AddSimpleProductToCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/AddSimpleProductToCart.php index b491b10730c10..3f6cc42614030 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/AddSimpleProductToCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/AddSimpleProductToCart.php @@ -8,8 +8,6 @@ namespace Magento\QuoteGraphQl\Model\Cart; use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\Framework\DataObject; -use Magento\Framework\DataObjectFactory; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; @@ -21,9 +19,9 @@ class AddSimpleProductToCart { /** - * @var DataObjectFactory + * @var CreateBuyRequest */ - private $dataObjectFactory; + private $createBuyRequest; /** * @var ProductRepositoryInterface @@ -31,15 +29,15 @@ class AddSimpleProductToCart private $productRepository; /** - * @param DataObjectFactory $dataObjectFactory * @param ProductRepositoryInterface $productRepository + * @param CreateBuyRequest $createBuyRequest */ public function __construct( - DataObjectFactory $dataObjectFactory, - ProductRepositoryInterface $productRepository + ProductRepositoryInterface $productRepository, + CreateBuyRequest $createBuyRequest ) { - $this->dataObjectFactory = $dataObjectFactory; $this->productRepository = $productRepository; + $this->createBuyRequest = $createBuyRequest; } /** @@ -56,7 +54,7 @@ public function execute(Quote $cart, array $cartItemData): void { $sku = $this->extractSku($cartItemData); $quantity = $this->extractQuantity($cartItemData); - $customizableOptions = $this->extractCustomizableOptions($cartItemData); + $customizableOptions = $cartItemData['customizable_options'] ?? []; try { $product = $this->productRepository->get($sku); @@ -65,7 +63,7 @@ public function execute(Quote $cart, array $cartItemData): void } try { - $result = $cart->addProduct($product, $this->createBuyRequest($quantity, $customizableOptions)); + $result = $cart->addProduct($product, $this->createBuyRequest->execute($quantity, $customizableOptions)); } catch (\Exception $e) { throw new GraphQlInputException( __( @@ -116,60 +114,4 @@ private function extractQuantity(array $cartItemData): float } return $quantity; } - - /** - * Extract Customizable Options from cart item data - * - * @param array $cartItemData - * @return array - */ - private function extractCustomizableOptions(array $cartItemData): array - { - if (!isset($cartItemData['customizable_options']) || empty($cartItemData['customizable_options'])) { - return []; - } - - $customizableOptionsData = []; - foreach ($cartItemData['customizable_options'] as $customizableOption) { - if (isset($customizableOption['value_string'])) { - $customizableOptionsData[$customizableOption['id']] = $this->convertCustomOptionValue( - $customizableOption['value_string'] - ); - } - } - return $customizableOptionsData; - } - - /** - * Format GraphQl input data to a shape that buy request has - * - * @param float $quantity - * @param array $customOptions - * @return DataObject - */ - private function createBuyRequest(float $quantity, array $customOptions): DataObject - { - return $this->dataObjectFactory->create([ - 'data' => [ - 'qty' => $quantity, - 'options' => $customOptions, - ], - ]); - } - - /** - * Convert custom options vakue - * - * @param string $value - * @return string|array - */ - private function convertCustomOptionValue(string $value) - { - $value = trim($value); - if (substr($value, 0, 1) === "[" && - substr($value, strlen($value) - 1, 1) === "]") { - return explode(',', substr($value, 1, -1)); - } - return $value; - } } diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/CreateBuyRequest.php b/app/code/Magento/QuoteGraphQl/Model/Cart/CreateBuyRequest.php new file mode 100644 index 0000000000000..b95be8db2dccd --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/CreateBuyRequest.php @@ -0,0 +1,75 @@ +dataObjectFactory = $dataObjectFactory; + } + + /** + * Returns buy request for working with cart items + * + * @param float $qty + * @param array $customizableOptionsData + * @return DataObject + */ + public function execute(float $qty, array $customizableOptionsData): DataObject + { + $customizableOptions = []; + foreach ($customizableOptionsData as $customizableOption) { + if (isset($customizableOption['value_string'])) { + $customizableOptions[$customizableOption['id']] = $this->convertCustomOptionValue( + $customizableOption['value_string'] + ); + } + } + + return $this->dataObjectFactory->create( + [ + 'data' => [ + 'qty' => $qty, + 'options' => $customizableOptions, + ], + ] + ); + } + + /** + * Convert custom options value + * + * @param string $value + * @return string|array + */ + private function convertCustomOptionValue(string $value) + { + $value = trim($value); + if (substr($value, 0, 1) === "[" && + substr($value, strlen($value) - 1, 1) === "]") { + return explode(',', substr($value, 1, -1)); + } + return $value; + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/UpdateCartItem.php b/app/code/Magento/QuoteGraphQl/Model/Cart/UpdateCartItem.php new file mode 100644 index 0000000000000..b18c6ad662335 --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/UpdateCartItem.php @@ -0,0 +1,147 @@ +cartItemRepository = $cartItemRepository; + $this->quoteRepository = $quoteRepository; + $this->createBuyRequest = $createBuyRequest; + } + + /** + * Update cart item + * + * @param Quote $cart + * @param int $cartItemId + * @param float $quantity + * @param array $customizableOptionsData + * @return void + * @throws GraphQlInputException + * @throws GraphQlNoSuchEntityException + * @throws NoSuchEntityException + */ + public function execute(Quote $cart, int $cartItemId, float $quantity, array $customizableOptionsData): void + { + if (count($customizableOptionsData) === 0) { // Update only item's qty + $this->updateItemQuantity($cartItemId, $cart, $quantity); + + return; + } + + try { + $result = $cart->updateItem( + $cartItemId, + $this->createBuyRequest->execute($quantity, $customizableOptionsData) + ); + } catch (LocalizedException $e) { + throw new GraphQlInputException( + __( + 'Could not update cart item: %message', + ['message' => $e->getMessage()] + ) + ); + } + + if ($result->getHasError()) { + throw new GraphQlInputException( + __( + 'Could not update cart item: %message', + ['message' => $result->getMessage()] + ) + ); + } + + $this->quoteRepository->save($cart); + } + + /** + * Updates item qty for the specified cart + * + * @param int $itemId + * @param Quote $cart + * @param float $quantity + * @throws GraphQlNoSuchEntityException + * @throws NoSuchEntityException + * @throws GraphQlNoSuchEntityException + */ + private function updateItemQuantity(int $itemId, Quote $cart, float $quantity) + { + $cartItem = $cart->getItemById($itemId); + if ($cartItem === false) { + throw new GraphQlNoSuchEntityException( + __('Could not find cart item with id: %1.', $itemId) + ); + } + $cartItem->setQty($quantity); + $this->validateCartItem($cartItem); + $this->cartItemRepository->save($cartItem); + } + + /** + * Validate cart item + * + * @param Item $cartItem + * @return void + * @throws GraphQlInputException + */ + private function validateCartItem(Item $cartItem): void + { + if ($cartItem->getHasError()) { + $errors = []; + foreach ($cartItem->getMessage(false) as $message) { + $errors[] = $message; + } + if (!empty($errors)) { + throw new GraphQlInputException( + __( + 'Could not update the product with SKU %sku: %message', + ['sku' => $cartItem->getSku(), 'message' => __(implode("\n", $errors))] + ) + ); + } + } + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php index fa115db144e32..db6a43513cc30 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php @@ -16,14 +16,19 @@ use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Quote\Api\CartItemRepositoryInterface; use Magento\Quote\Model\Quote; -use Magento\Quote\Model\Quote\Item; use Magento\QuoteGraphQl\Model\Cart\GetCartForUser; +use Magento\QuoteGraphQl\Model\Cart\UpdateCartItem; /** * @inheritdoc */ class UpdateCartItems implements ResolverInterface { + /** + * @var UpdateCartItem + */ + private $updateCartItem; + /** * @var GetCartForUser */ @@ -37,13 +42,16 @@ class UpdateCartItems implements ResolverInterface /** * @param GetCartForUser $getCartForUser * @param CartItemRepositoryInterface $cartItemRepository + * @param UpdateCartItem $updateCartItem */ public function __construct( GetCartForUser $getCartForUser, - CartItemRepositoryInterface $cartItemRepository + CartItemRepositoryInterface $cartItemRepository, + UpdateCartItem $updateCartItem ) { $this->getCartForUser = $getCartForUser; $this->cartItemRepository = $cartItemRepository; + $this->updateCartItem = $updateCartItem; } /** @@ -94,52 +102,18 @@ private function processCartItems(Quote $cart, array $items): void if (empty($item['cart_item_id'])) { throw new GraphQlInputException(__('Required parameter "cart_item_id" for "cart_items" is missing.')); } - $itemId = $item['cart_item_id']; + $itemId = (int)$item['cart_item_id']; + $customizableOptions = $item['customizable_options'] ?? []; - if (!isset($item['quantity'])) { + if (count($customizableOptions) === 0 && !isset($item['quantity'])) { throw new GraphQlInputException(__('Required parameter "quantity" for "cart_items" is missing.')); } $quantity = (float)$item['quantity']; - $cartItem = $cart->getItemById($itemId); - if ($cartItem === false) { - throw new GraphQlNoSuchEntityException( - __('Could not find cart item with id: %1.', $item['cart_item_id']) - ); - } - if ($quantity <= 0.0) { $this->cartItemRepository->deleteById((int)$cart->getId(), $itemId); } else { - $cartItem->setQty($quantity); - $this->validateCartItem($cartItem); - $this->cartItemRepository->save($cartItem); - } - } - } - - /** - * Validate cart item - * - * @param Item $cartItem - * @return void - * @throws GraphQlInputException - */ - private function validateCartItem(Item $cartItem): void - { - if ($cartItem->getHasError()) { - $errors = []; - foreach ($cartItem->getMessage(false) as $message) { - $errors[] = $message; - } - - if (!empty($errors)) { - throw new GraphQlInputException( - __( - 'Could not update the product with SKU %sku: %message', - ['sku' => $cartItem->getSku(), 'message' => __(implode("\n", $errors))] - ) - ); + $this->updateCartItem->execute($cart, $itemId, $quantity, $customizableOptions); } } } diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index ea5e34ff1e34a..893a0b9df458d 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -68,7 +68,8 @@ input UpdateCartItemsInput { input CartItemUpdateInput { cart_item_id: Int! - quantity: Float! + quantity: Float + customizable_options: [CustomizableOptionInput!] } input RemoveItemFromCartInput { diff --git a/app/code/Magento/SendFriendGraphQl/Model/Provider/GetVisibleProduct.php b/app/code/Magento/SendFriendGraphQl/Model/Provider/GetVisibleProduct.php new file mode 100644 index 0000000000000..9ff771afd57fe --- /dev/null +++ b/app/code/Magento/SendFriendGraphQl/Model/Provider/GetVisibleProduct.php @@ -0,0 +1,64 @@ +productRepository = $productRepository; + $this->visibility = $visibility; + } + + /** + * Get product + * + * @param int $productId + * @return ProductInterface + * @throws GraphQlNoSuchEntityException + */ + public function execute(int $productId): ProductInterface + { + try { + $product = $this->productRepository->getById($productId); + + if (!in_array( + $product->getVisibility(), + $this->visibility->getVisibleInCatalogIds() + )) { + throw new GraphQlNoSuchEntityException( + __("The product that was requested doesn't exist. Verify the product and try again.") + ); + } + } catch (NoSuchEntityException $e) { + throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e); + } + return $product; + } +} diff --git a/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php index c0c01c71df764..0a4fe1e3e5616 100644 --- a/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php +++ b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php @@ -7,18 +7,14 @@ namespace Magento\SendFriendGraphQl\Model\Resolver; -use Magento\Catalog\Api\Data\ProductInterface; -use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\Framework\DataObjectFactory; -use Magento\Framework\Event\ManagerInterface; -use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; use Magento\Framework\GraphQl\Exception\GraphQlInputException; -use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; -use Magento\SendFriend\Model\SendFriend; -use Magento\SendFriend\Model\SendFriendFactory; +use Magento\GraphQl\Model\Query\ContextInterface; +use Magento\SendFriend\Helper\Data as SendFriendHelper; +use Magento\SendFriendGraphQl\Model\SendFriend\SendEmail; /** * @inheritdoc @@ -26,41 +22,25 @@ class SendEmailToFriend implements ResolverInterface { /** - * @var SendFriendFactory + * @var SendFriendHelper */ - private $sendFriendFactory; + private $sendFriendHelper; /** - * @var ProductRepositoryInterface + * @var SendEmail */ - private $productRepository; + private $sendEmail; /** - * @var DataObjectFactory - */ - private $dataObjectFactory; - - /** - * @var ManagerInterface - */ - private $eventManager; - - /** - * @param SendFriendFactory $sendFriendFactory - * @param ProductRepositoryInterface $productRepository - * @param DataObjectFactory $dataObjectFactory - * @param ManagerInterface $eventManager + * @param SendEmail $sendEmail + * @param SendFriendHelper $sendFriendHelper */ public function __construct( - SendFriendFactory $sendFriendFactory, - ProductRepositoryInterface $productRepository, - DataObjectFactory $dataObjectFactory, - ManagerInterface $eventManager + SendEmail $sendEmail, + SendFriendHelper $sendFriendHelper ) { - $this->sendFriendFactory = $sendFriendFactory; - $this->productRepository = $productRepository; - $this->dataObjectFactory = $dataObjectFactory; - $this->eventManager = $eventManager; + $this->sendEmail = $sendEmail; + $this->sendFriendHelper = $sendFriendHelper; } /** @@ -68,77 +48,24 @@ public function __construct( */ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { - /** @var SendFriend $sendFriend */ - $sendFriend = $this->sendFriendFactory->create(); - - if ($sendFriend->getMaxSendsToFriend() && $sendFriend->isExceedLimit()) { - throw new GraphQlInputException( - __('You can\'t send messages more than %1 times an hour.', $sendFriend->getMaxSendsToFriend()) - ); + /** @var ContextInterface $context */ + if (!$this->sendFriendHelper->isAllowForGuest() + && false === $context->getExtensionAttributes()->getIsCustomer() + ) { + throw new GraphQlAuthorizationException(__('The current customer isn\'t authorized.')); } - $product = $this->getProduct($args['input']['product_id']); - $this->eventManager->dispatch('sendfriend_product', ['product' => $product]); - $sendFriend->setProduct($product); - $senderData = $this->extractSenderData($args); - $sendFriend->setSender($senderData); - $recipientsData = $this->extractRecipientsData($args); - $sendFriend->setRecipients($recipientsData); - - $this->validateSendFriendModel($sendFriend, $senderData, $recipientsData); - $sendFriend->send(); + $this->sendEmail->execute( + $args['input']['product_id'], + $senderData, + $recipientsData + ); return array_merge($senderData, $recipientsData); } - /** - * Validate send friend model - * - * @param SendFriend $sendFriend - * @param array $senderData - * @param array $recipientsData - * @return void - * @throws GraphQlInputException - */ - private function validateSendFriendModel(SendFriend $sendFriend, array $senderData, array $recipientsData): void - { - $sender = $this->dataObjectFactory->create()->setData($senderData['sender']); - $sendFriend->setData('_sender', $sender); - - $emails = array_column($recipientsData['recipients'], 'email'); - $recipients = $this->dataObjectFactory->create()->setData('emails', $emails); - $sendFriend->setData('_recipients', $recipients); - - $validationResult = $sendFriend->validate(); - if ($validationResult !== true) { - throw new GraphQlInputException(__(implode($validationResult))); - } - } - - /** - * Get product - * - * @param int $productId - * @return ProductInterface - * @throws GraphQlNoSuchEntityException - */ - private function getProduct(int $productId): ProductInterface - { - try { - $product = $this->productRepository->getById($productId); - if (!$product->isVisibleInCatalog()) { - throw new GraphQlNoSuchEntityException( - __("The product that was requested doesn't exist. Verify the product and try again.") - ); - } - } catch (NoSuchEntityException $e) { - throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e); - } - return $product; - } - /** * Extract recipients data * diff --git a/app/code/Magento/SendFriendGraphQl/Model/SendFriend/SendEmail.php b/app/code/Magento/SendFriendGraphQl/Model/SendFriend/SendEmail.php new file mode 100644 index 0000000000000..70df366fa173f --- /dev/null +++ b/app/code/Magento/SendFriendGraphQl/Model/SendFriend/SendEmail.php @@ -0,0 +1,130 @@ +dataObjectFactory = $dataObjectFactory; + $this->productRepository = $productRepository; + $this->sendFriendFactory = $sendFriendFactory; + $this->eventManager = $eventManager; + $this->visibleProductProvider = $visibleProductProvider; + } + + /** + * Send product email to friend(s) + * + * @param int $productId + * @param array $senderData + * @param array $recipientsData + * @throws GraphQlInputException + * @throws GraphQlNoSuchEntityException + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function execute(int $productId, array $senderData, array $recipientsData): void + { + /** @var SendFriend $sendFriend */ + $sendFriend = $this->sendFriendFactory->create(); + + if ($sendFriend->getMaxSendsToFriend() && $sendFriend->isExceedLimit()) { + throw new GraphQlInputException( + __('You can\'t send messages more than %1 times an hour.', $sendFriend->getMaxSendsToFriend()) + ); + } + + $product = $this->visibleProductProvider->execute($productId); + + $this->eventManager->dispatch('sendfriend_product', ['product' => $product]); + + $sendFriend->setProduct($product); + $sendFriend->setSender($senderData); + $sendFriend->setRecipients($recipientsData); + + $this->validateSendFriendModel($sendFriend, $senderData, $recipientsData); + + $sendFriend->send(); + } + + /** + * Validate send friend model + * + * @param SendFriend $sendFriend + * @param array $senderData + * @param array $recipientsData + * @return void + * @throws GraphQlInputException + */ + private function validateSendFriendModel(SendFriend $sendFriend, array $senderData, array $recipientsData): void + { + $sender = $this->dataObjectFactory->create()->setData($senderData['sender']); + $sendFriend->setData('_sender', $sender); + + $emails = array_column($recipientsData['recipients'], 'email'); + $recipients = $this->dataObjectFactory->create()->setData('emails', $emails); + $sendFriend->setData('_recipients', $recipients); + + $validationResult = $sendFriend->validate(); + if ($validationResult !== true) { + throw new GraphQlInputException(__(implode($validationResult))); + } + } +} diff --git a/app/code/Magento/SendFriendGraphQl/composer.json b/app/code/Magento/SendFriendGraphQl/composer.json index d401f57b2257a..091c684879129 100644 --- a/app/code/Magento/SendFriendGraphQl/composer.json +++ b/app/code/Magento/SendFriendGraphQl/composer.json @@ -6,9 +6,7 @@ "php": "~7.1.3||~7.2.0", "magento/framework": "*", "magento/module-catalog": "*", - "magento/module-send-friend": "*" - }, - "suggest": { + "magento/module-send-friend": "*", "magento/module-graph-ql": "*" }, "license": [ diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php index 63073a389f278..df8e399ce6c61 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php @@ -168,6 +168,25 @@ public function testGetCategoryById() self::assertEquals(13, $response['category']['id']); } + /** + * @magentoApiDataFixture Magento/Catalog/_files/categories.php + * @expectedException \Exception + * @expectedExceptionMessage Category doesn't exist + */ + public function testGetDisabledCategory() + { + $categoryId = 8; + $query = <<graphQlQuery($query); + } + public function testNonExistentCategoryWithProductCount() { $query = << [ 'cart_items: [{ cart_item_id: 1 }]', - 'Field CartItemUpdateInput.quantity of required type Float! was not provided.' + 'Required parameter "quantity" for "cart_items" is missing.' ], ]; } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/EditQuoteItemWithCustomOptionsTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/EditQuoteItemWithCustomOptionsTest.php new file mode 100644 index 0000000000000..62c1ae0dab3c7 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/EditQuoteItemWithCustomOptionsTest.php @@ -0,0 +1,273 @@ +getMaskedQuoteIdByReservedOrderId = $objectManager->get(GetMaskedQuoteIdByReservedOrderId::class); + $this->productCustomOptionsRepository = $objectManager->get(ProductCustomOptionRepositoryInterface::class); + $this->quoteFactory = $objectManager->get(QuoteFactory::class); + $this->quoteResource = $objectManager->get(QuoteResource::class); + $this->productRepository = $objectManager->get(ProductRepositoryInterface::class); + } + + /** + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/set_custom_options_simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product_with_options.php + */ + public function testChangeQuoteItemCustomOptions() + { + $sku = 'simple_product'; + $quoteItemId = $this->getQuoteItemIdBySku($sku); + $customOptionsValues = $this->getCustomOptionsValuesForQuery($sku); + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + $customizableOptionsQuery = preg_replace('/"([^"]+)"\s*:\s*/', '$1:', json_encode($customOptionsValues)); + + $query = $this->getQuery($maskedQuoteId, $quoteItemId, $customizableOptionsQuery); + $response = $this->graphQlMutation($query); + $itemOptionsResponse = $response['updateCartItems']['cart']['items'][0]['customizable_options']; + self::assertCount(2, $itemOptionsResponse); + self::assertEquals('test', $itemOptionsResponse[0]['values'][0]['value']); + self::assertEquals('test', $itemOptionsResponse[1]['values'][0]['value']); + } + + /** + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/set_custom_options_simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product_with_options.php + */ + public function testOptionsSetPersistsOnQtyChange() + { + $sku = 'simple_product'; + $newQuantity = 2; + $quoteItemId = $this->getQuoteItemIdBySku($sku); + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + + $query = <<graphQlMutation($query); + $cartItemResponse = $response['updateCartItems']['cart']['items'][0]; + + self::assertEquals($newQuantity, $cartItemResponse['quantity']); + self::assertCount(2, $cartItemResponse['customizable_options']); + self::assertEquals('initial value', $cartItemResponse['customizable_options'][0]['values'][0]['value']); + self::assertEquals('initial value', $cartItemResponse['customizable_options'][1]['values'][0]['value']); + } + + /** + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/set_custom_options_simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product_with_options.php + */ + public function testOptionsSetChangedOnChangeOneOption() + { + $sku = 'simple_product'; + $quoteItemId = $this->getQuoteItemIdBySku($sku); + + /* Get only the first option */ + $customOptionsValues = array_slice($this->getCustomOptionsValuesForQuery($sku), 0, 1); + + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + $customizableOptionsQuery = preg_replace('/"([^"]+)"\s*:\s*/', '$1:', json_encode($customOptionsValues)); + $query = $this->getQuery($maskedQuoteId, $quoteItemId, $customizableOptionsQuery); + + $response = $this->graphQlMutation($query); + $itemOptionsResponse = $response['updateCartItems']['cart']['items'][0]['customizable_options']; + self::assertCount(1, $itemOptionsResponse); + self::assertEquals('test', $itemOptionsResponse[0]['values'][0]['value']); + } + + /** + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/set_custom_options_simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product_with_options.php + */ + public function testOptionSetPersistsOnExtraOptionWithIncorrectId() + { + $sku = 'simple_product'; + $quoteItemId = $this->getQuoteItemIdBySku($sku); + $customOptionsValues = $this->getCustomOptionsValuesForQuery($sku); + + /* Add nonexistent option to the query */ + $customOptionsValues[] = ['id' => -10, 'value_string' => 'value']; + + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + $customizableOptionsQuery = preg_replace('/"([^"]+)"\s*:\s*/', '$1:', json_encode($customOptionsValues)); + $query = $this->getQuery($maskedQuoteId, $quoteItemId, $customizableOptionsQuery); + + $response = $this->graphQlMutation($query); + $itemOptionsResponse = $response['updateCartItems']['cart']['items'][0]['customizable_options']; + self::assertCount(2, $itemOptionsResponse); + } + + /** + * Returns GraphQl query for updating items in shopping cart + * + * @param string $maskedQuoteId + * @param int $quoteItemId + * @param $customizableOptionsQuery + * @return string + */ + private function getQuery(string $maskedQuoteId, int $quoteItemId, $customizableOptionsQuery): string + { + return <<quoteFactory->create(); + $product = $this->productRepository->get($sku); + $this->quoteResource->load($quote, 'test_quote', 'reserved_order_id'); + /** @var Item $quoteItem */ + $quoteItem = $quote->getItemByProduct($product); + + return (int)$quoteItem->getId(); + } + + /** + * Generate an array with test values for customizable options + * based on the option type + * + * @param string $sku + * @return array + */ + private function getCustomOptionsValuesForQuery(string $sku): array + { + $customOptions = $this->productCustomOptionsRepository->getList($sku); + $customOptionsValues = []; + + foreach ($customOptions as $customOption) { + $optionType = $customOption->getType(); + if ($optionType == 'field' || $optionType == 'area') { + $customOptionsValues[] = [ + 'id' => (int) $customOption->getOptionId(), + 'value_string' => 'test' + ]; + } elseif ($optionType == 'drop_down') { + $optionSelectValues = $customOption->getValues(); + $customOptionsValues[] = [ + 'id' => (int) $customOption->getOptionId(), + 'value_string' => reset($optionSelectValues)->getOptionTypeId() + ]; + } + } + + return $customOptionsValues; + } +} diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php index 1e1fb0a176992..988ead7d86df3 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php @@ -236,7 +236,7 @@ public function dataProviderUpdateWithMissedRequiredParameters(): array ], 'missed_cart_item_qty' => [ 'cart_items: [{ cart_item_id: 1 }]', - 'Field CartItemUpdateInput.quantity of required type Float! was not provided.' + 'Required parameter "quantity" for "cart_items" is missing.' ], ]; } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/SendFriend/SendFriendTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/SendFriend/SendFriendTest.php index e7401100b7860..200bae76e0ae6 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/SendFriend/SendFriendTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/SendFriend/SendFriendTest.php @@ -8,6 +8,8 @@ namespace Magento\GraphQl\SendFriend; use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\Exception\AuthenticationException; +use Magento\Integration\Api\CustomerTokenServiceInterface; use Magento\SendFriend\Model\SendFriend; use Magento\SendFriend\Model\SendFriendFactory; use Magento\TestFramework\Helper\Bootstrap; @@ -23,21 +25,29 @@ class SendFriendTest extends GraphQlAbstract * @var SendFriendFactory */ private $sendFriendFactory; + /** * @var ProductRepositoryInterface */ private $productRepository; + /** + * @var CustomerTokenServiceInterface + */ + private $customerTokenService; + protected function setUp() { $this->sendFriendFactory = Bootstrap::getObjectManager()->get(SendFriendFactory::class); $this->productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class); + $this->customerTokenService = Bootstrap::getObjectManager()->get(CustomerTokenServiceInterface::class); } /** * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/SendFriend/_files/enable_send_friend_guest.php */ - public function testSendFriend() + public function testSendFriendGuestEnable() { $productId = (int)$this->productRepository->get('simple_product')->getId(); $recipients = '{ @@ -51,15 +61,57 @@ public function testSendFriend() $query = $this->getQuery($productId, $recipients); $response = $this->graphQlMutation($query); - self::assertEquals('Name', $response['sendEmailToFriend']['sender']['name']); - self::assertEquals('e@mail.com', $response['sendEmailToFriend']['sender']['email']); - self::assertEquals('Lorem Ipsum', $response['sendEmailToFriend']['sender']['message']); - self::assertEquals('Recipient Name 1', $response['sendEmailToFriend']['recipients'][0]['name']); - self::assertEquals('recipient1@mail.com', $response['sendEmailToFriend']['recipients'][0]['email']); - self::assertEquals('Recipient Name 2', $response['sendEmailToFriend']['recipients'][1]['name']); - self::assertEquals('recipient2@mail.com', $response['sendEmailToFriend']['recipients'][1]['email']); + $this->assertResponse($response); + } + + /** + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/SendFriend/_files/disable_send_friend_guest.php + * @expectedException \Exception + * @expectedExceptionMessage The current customer isn't authorized. + */ + public function testSendFriendGuestDisableAsGuest() + { + $productId = (int)$this->productRepository->get('simple_product')->getId(); + $recipients = '{ + name: "Recipient Name 1" + email:"recipient1@mail.com" + }, + { + name: "Recipient Name 2" + email:"recipient2@mail.com" + }'; + $query = $this->getQuery($productId, $recipients); + + $response = $this->graphQlMutation($query); + $this->assertResponse($response); } + /** + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/SendFriend/_files/disable_send_friend_guest.php + */ + public function testSendFriendGuestDisableAsCustomer() + { + $productId = (int)$this->productRepository->get('simple_product')->getId(); + $recipients = '{ + name: "Recipient Name 1" + email:"recipient1@mail.com" + }, + { + name: "Recipient Name 2" + email:"recipient2@mail.com" + }'; + $query = $this->getQuery($productId, $recipients); + + $response = $this->graphQlMutation($query, [], '', $this->getHeaderMap()); + $this->assertResponse($response); + } + + /** + * @magentoApiDataFixture Magento/Customer/_files/customer.php + */ public function testSendWithoutExistProduct() { $productId = 2018; @@ -73,14 +125,14 @@ public function testSendWithoutExistProduct() }'; $query = $this->getQuery($productId, $recipients); - $this->expectException(\Exception::class); $this->expectExceptionMessage( 'The product that was requested doesn\'t exist. Verify the product and try again.' ); - $this->graphQlMutation($query); + $this->graphQlMutation($query, [], '', $this->getHeaderMap()); } /** + * @magentoApiDataFixture Magento/Customer/_files/customer.php * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php */ public function testMaxSendEmailToFriend() @@ -118,10 +170,11 @@ public function testMaxSendEmailToFriend() $this->expectException(\Exception::class); $this->expectExceptionMessage("No more than {$sendFriend->getMaxRecipients()} emails can be sent at a time."); - $this->graphQlMutation($query); + $this->graphQlMutation($query, [], '', $this->getHeaderMap()); } /** + * @magentoApiDataFixture Magento/Customer/_files/customer.php * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php * @dataProvider sendFriendsErrorsDataProvider * @param string $input @@ -151,10 +204,11 @@ public function testErrors(string $input, string $errorMessage) QUERY; $this->expectException(\Exception::class); $this->expectExceptionMessage($errorMessage); - $this->graphQlMutation($query); + $this->graphQlMutation($query, [], '', $this->getHeaderMap()); } /** + * @magentoApiDataFixture Magento/Customer/_files/customer.php * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php * TODO: use magentoApiConfigFixture (to be merged https://github.com/magento/graphql-ce/pull/351) * @magentoApiDataFixture Magento/SendFriend/Fixtures/sendfriend_configuration.php @@ -183,11 +237,12 @@ public function testLimitMessagesPerHour() $maxSendToFriends = $sendFriend->getMaxSendsToFriend(); for ($i = 0; $i <= $maxSendToFriends + 1; $i++) { - $this->graphQlMutation($query); + $this->graphQlMutation($query, [], '', $this->getHeaderMap()); } } /** + * @magentoApiDataFixture Magento/Customer/_files/customer.php * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php */ public function testSendProductWithoutSenderEmail() @@ -201,10 +256,11 @@ public function testSendProductWithoutSenderEmail() $this->expectException(\Exception::class); $this->expectExceptionMessage('GraphQL response contains errors: Please provide Email for all of recipients.'); - $this->graphQlMutation($query); + $this->graphQlMutation($query, [], '', $this->getHeaderMap()); } /** + * @magentoApiDataFixture Magento/Customer/_files/customer.php * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product_without_visibility.php */ public function testSendProductWithoutVisibility() @@ -219,15 +275,10 @@ public function testSendProductWithoutVisibility() email:"recipient2@mail.com" }'; $query = $this->getQuery($productId, $recipients); - - $response = $this->graphQlMutation($query); - self::assertEquals('Name', $response['sendEmailToFriend']['sender']['name']); - self::assertEquals('e@mail.com', $response['sendEmailToFriend']['sender']['email']); - self::assertEquals('Lorem Ipsum', $response['sendEmailToFriend']['sender']['message']); - self::assertEquals('Recipient Name 1', $response['sendEmailToFriend']['recipients'][0]['name']); - self::assertEquals('recipient1@mail.com', $response['sendEmailToFriend']['recipients'][0]['email']); - self::assertEquals('Recipient Name 2', $response['sendEmailToFriend']['recipients'][1]['name']); - self::assertEquals('recipient2@mail.com', $response['sendEmailToFriend']['recipients'][1]['email']); + $this->expectExceptionMessage( + 'The product that was requested doesn\'t exist. Verify the product and try again.' + ); + $this->graphQlMutation($query, [], '', $this->getHeaderMap()); } /** @@ -311,6 +362,37 @@ public function sendFriendsErrorsDataProvider() ]; } + /** + * Generic assertions for send a friend response + * + * @param array $response + */ + private function assertResponse(array $response): void + { + self::assertEquals('Name', $response['sendEmailToFriend']['sender']['name']); + self::assertEquals('e@mail.com', $response['sendEmailToFriend']['sender']['email']); + self::assertEquals('Lorem Ipsum', $response['sendEmailToFriend']['sender']['message']); + self::assertEquals('Recipient Name 1', $response['sendEmailToFriend']['recipients'][0]['name']); + self::assertEquals('recipient1@mail.com', $response['sendEmailToFriend']['recipients'][0]['email']); + self::assertEquals('Recipient Name 2', $response['sendEmailToFriend']['recipients'][1]['name']); + self::assertEquals('recipient2@mail.com', $response['sendEmailToFriend']['recipients'][1]['email']); + } + + /** + * Retrieve customer authorization headers + * + * @param string $username + * @param string $password + * @return array + * @throws AuthenticationException + */ + private function getHeaderMap(string $username = 'customer@example.com', string $password = 'password'): array + { + $customerToken = $this->customerTokenService->createCustomerAccessToken($username, $password); + $headerMap = ['Authorization' => 'Bearer ' . $customerToken]; + return $headerMap; + } + /** * @param int $productId * @param string $recipients diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaA.graphqls b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaA.graphqls index 6c832e5f122a6..0ebe4caa94a3f 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaA.graphqls +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaA.graphqls @@ -8,7 +8,6 @@ type Mutation { input FilterTypeInput @doc(description:"Comment for FilterTypeInput") { eq: String @doc(description:"Equal") - finset: [String] from: String gt: String gteq: String diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaC.graphqls b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaC.graphqls index 92682468c42be..d1d6987035511 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaC.graphqls +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaC.graphqls @@ -19,7 +19,6 @@ type Attribute @doc(description: "Attribute contains the attribute_type of the s } input FilterTypeInput @doc(description:"Comment for FilterTypeInput") { eq: String @doc(description:"Equal") - finset: [String] from: String gt: String gteq: String diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schema_response_sdl_description.php b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schema_response_sdl_description.php index 0a73b8ed445d5..03dbac447449d 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schema_response_sdl_description.php +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schema_response_sdl_description.php @@ -505,20 +505,6 @@ ], 'defaultValue' => null ], - [ - 'name' => 'finset', - 'description' => '', - 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ] - ], - 'defaultValue' => null - ], [ 'name' => 'from', 'description' => '', diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schema_with_description_sdl.php b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schema_with_description_sdl.php index 2aeb8f3d14430..969c2cceb0a49 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schema_with_description_sdl.php +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schema_with_description_sdl.php @@ -505,20 +505,6 @@ ], 'defaultValue' => null ], - [ - 'name' => 'finset', - 'description' => '', - 'type' => [ - 'kind' => 'LIST', - 'name' => null, - 'ofType' => [ - 'kind' => 'SCALAR', - 'name' => 'String', - 'ofType' => null - ] - ], - 'defaultValue' => null - ], [ 'name' => 'from', 'description' => '', diff --git a/dev/tests/integration/testsuite/Magento/GraphQl/Catalog/_files/set_custom_options_simple_product.php b/dev/tests/integration/testsuite/Magento/GraphQl/Catalog/_files/set_custom_options_simple_product.php new file mode 100644 index 0000000000000..618ed0e25602f --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GraphQl/Catalog/_files/set_custom_options_simple_product.php @@ -0,0 +1,54 @@ + 'test_option_code_1', + 'type' => 'field', + 'is_require' => false, + 'sort_order' => 1, + 'price' => -10.0, + 'price_type' => 'fixed', + 'sku' => 'sku1', + 'max_characters' => 100, + ], + [ + 'title' => 'area option', + 'type' => 'area', + 'is_require' => false, + 'sort_order' => 2, + 'price' => 20.0, + 'price_type' => 'percent', + 'sku' => 'sku2', + 'max_characters' => 100 + ] +]; + +/** @var ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->get(ProductRepositoryInterface::class); +$product = $productRepository->get('simple_product'); +/** @var ProductCustomOptionInterfaceFactory $customOptionFactory */ +$customOptionFactory = $objectManager->get(ProductCustomOptionInterfaceFactory::class); + +foreach ($optionsSet as $option) { + /** @var ProductCustomOptionInterface $customOption */ + $customOption = $customOptionFactory->create(['data' => $option]); + $customOption->setProductSku($product->getSku()); + + $productCustomOptions[] = $customOption; +} + +$product->setOptions($productCustomOptions); +$productRepository->save($product); diff --git a/dev/tests/integration/testsuite/Magento/GraphQl/Quote/_files/add_simple_product_with_options.php b/dev/tests/integration/testsuite/Magento/GraphQl/Quote/_files/add_simple_product_with_options.php new file mode 100644 index 0000000000000..ecd1428a5d617 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GraphQl/Quote/_files/add_simple_product_with_options.php @@ -0,0 +1,53 @@ +get(ProductRepositoryInterface::class); +/** @var QuoteFactory $quoteFactory */ +$quoteFactory = Bootstrap::getObjectManager()->get(QuoteFactory::class); +/** @var QuoteResource $quoteResource */ +$quoteResource = Bootstrap::getObjectManager()->get(QuoteResource::class); +/** @var CartRepositoryInterface $cartRepository */ +$cartRepository = Bootstrap::getObjectManager()->get(CartRepositoryInterface::class); +/** @var OptionFactory $productOptionFactory */ +$productOptionFactory = Bootstrap::getObjectManager()->get(OptionFactory::class); +/** @var DataObjectFactory $dataObjectFactory */ +$dataObjectFactory = Bootstrap::getObjectManager()->get(DataObjectFactory::class); + +/** @var ProductOption $productOption */ +$productOption = $productOptionFactory->create(); +$product = $productRepository->get('simple_product'); +$productOptions = $productOption->getProductOptionCollection($product); +$cartItemCustomOptions = []; + +/** @var ProductOption $productOption */ +foreach ($productOptions as $productOption) { + $cartItemCustomOptions[$productOption->getId()] = 'initial value'; +} + +$request = $dataObjectFactory->create( + [ + 'data' => [ + 'qty' => 1.0, + 'options' => $cartItemCustomOptions, + ], + ] +); + +$quote = $quoteFactory->create(); +$quoteResource->load($quote, 'test_quote', 'reserved_order_id'); +$quote->addProduct($product, $request); +$cartRepository->save($quote); diff --git a/dev/tests/integration/testsuite/Magento/GraphQl/SendFriend/_files/disable_send_friend_guest.php b/dev/tests/integration/testsuite/Magento/GraphQl/SendFriend/_files/disable_send_friend_guest.php new file mode 100644 index 0000000000000..80fcc2079a018 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GraphQl/SendFriend/_files/disable_send_friend_guest.php @@ -0,0 +1,21 @@ +get(WriterInterface::class); + +$configWriter->save('sendfriend/email/allow_guest', '0'); + +$scopeConfig = $objectManager->get(ScopeConfigInterface::class); +$scopeConfig->clean(); diff --git a/dev/tests/integration/testsuite/Magento/GraphQl/SendFriend/_files/enable_send_friend_guest.php b/dev/tests/integration/testsuite/Magento/GraphQl/SendFriend/_files/enable_send_friend_guest.php new file mode 100644 index 0000000000000..aaf9a447aeaa0 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GraphQl/SendFriend/_files/enable_send_friend_guest.php @@ -0,0 +1,21 @@ +get(WriterInterface::class); + +$configWriter->save('sendfriend/email/allow_guest', '1'); + +$scopeConfig = $objectManager->get(ScopeConfigInterface::class); +$scopeConfig->clean();