From 5de8d9b20fc44d80b2ea1eced24a9e68e9439010 Mon Sep 17 00:00:00 2001 From: eduard13 Date: Mon, 11 May 2020 14:15:01 +0300 Subject: [PATCH 01/27] Adding Wishlist GraphQl support --- .../Model/Wishlist/AddProductsToWishlist.php | 162 ++++++++++++++++++ .../BuyRequest/BundleDataProvider.php | 55 ++++++ .../Wishlist/BuyRequest/BuyRequestBuilder.php | 63 +++++++ .../BuyRequestDataProviderInterface.php | 26 +++ .../CustomizableOptionDataProvider.php | 92 ++++++++++ .../DownloadableLinkDataProvider.php | 54 ++++++ .../BuyRequest/SuperAttributeDataProvider.php | 64 +++++++ .../BuyRequest/SuperGroupDataProvider.php | 64 +++++++ .../Wishlist/Model/Wishlist/Config.php | 46 +++++ .../Model/Wishlist/Data/EnteredOption.php | 54 ++++++ .../Wishlist/Model/Wishlist/Data/Error.php | 54 ++++++ .../Model/Wishlist/Data/SelectedOption.php | 37 ++++ .../Model/Wishlist/Data/WishlistItem.php | 146 ++++++++++++++++ .../Wishlist/Data/WishlistItemFactory.php | 75 ++++++++ .../Model/Wishlist/Data/WishlistOutput.php | 56 ++++++ .../Wishlist/RemoveProductsFromWishlist.php | 131 ++++++++++++++ .../Wishlist/UpdateProductsInWishlist.php | 136 +++++++++++++++ app/code/Magento/Wishlist/etc/graphql/di.xml | 20 +++ .../Mapper/WishlistDataMapper.php | 35 ++++ .../AddProductsToWishlistResolver.php | 129 ++++++++++++++ .../Resolver/CustomerWishlistResolver.php | 6 +- .../RemoveProductsFromWishlistResolver.php | 127 ++++++++++++++ .../UpdateProductsInWishlistResolver.php | 137 +++++++++++++++ .../Model/Resolver/WishlistResolver.php | 7 +- .../WishlistGraphQl/etc/schema.graphqls | 42 +++++ 25 files changed, 1814 insertions(+), 4 deletions(-) create mode 100644 app/code/Magento/Wishlist/Model/Wishlist/AddProductsToWishlist.php create mode 100644 app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/BundleDataProvider.php create mode 100644 app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/BuyRequestBuilder.php create mode 100644 app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/BuyRequestDataProviderInterface.php create mode 100644 app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/CustomizableOptionDataProvider.php create mode 100644 app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/DownloadableLinkDataProvider.php create mode 100644 app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/SuperAttributeDataProvider.php create mode 100644 app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/SuperGroupDataProvider.php create mode 100644 app/code/Magento/Wishlist/Model/Wishlist/Config.php create mode 100644 app/code/Magento/Wishlist/Model/Wishlist/Data/EnteredOption.php create mode 100644 app/code/Magento/Wishlist/Model/Wishlist/Data/Error.php create mode 100644 app/code/Magento/Wishlist/Model/Wishlist/Data/SelectedOption.php create mode 100644 app/code/Magento/Wishlist/Model/Wishlist/Data/WishlistItem.php create mode 100644 app/code/Magento/Wishlist/Model/Wishlist/Data/WishlistItemFactory.php create mode 100644 app/code/Magento/Wishlist/Model/Wishlist/Data/WishlistOutput.php create mode 100644 app/code/Magento/Wishlist/Model/Wishlist/RemoveProductsFromWishlist.php create mode 100644 app/code/Magento/Wishlist/Model/Wishlist/UpdateProductsInWishlist.php create mode 100644 app/code/Magento/Wishlist/etc/graphql/di.xml create mode 100644 app/code/Magento/WishlistGraphQl/Mapper/WishlistDataMapper.php create mode 100644 app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlistResolver.php create mode 100644 app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlistResolver.php create mode 100644 app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlistResolver.php diff --git a/app/code/Magento/Wishlist/Model/Wishlist/AddProductsToWishlist.php b/app/code/Magento/Wishlist/Model/Wishlist/AddProductsToWishlist.php new file mode 100644 index 0000000000000..6700f1585acb4 --- /dev/null +++ b/app/code/Magento/Wishlist/Model/Wishlist/AddProductsToWishlist.php @@ -0,0 +1,162 @@ +productRepository = $productRepository; + $this->buyRequestBuilder = $buyRequestBuilder; + $this->wishlistResource = $wishlistResource; + } + + /** + * Adding products to wishlist + * + * @param Wishlist $wishlist + * @param array $wishlistItems + * + * @return WishlistOutput + * + * @throws AlreadyExistsException + */ + public function execute(Wishlist $wishlist, array $wishlistItems): WishlistOutput + { + foreach ($wishlistItems as $wishlistItem) { + $this->addItemToWishlist($wishlist, $wishlistItem); + } + + $wishlistOutput = $this->prepareOutput($wishlist); + + if ($wishlist->isObjectNew() || count($wishlistOutput->getErrors()) !== count($wishlistItems)) { + $this->wishlistResource->save($wishlist); + } + + return $wishlistOutput; + } + + /** + * Add product item to wishlist + * + * @param Wishlist $wishlist + * @param WishlistItem $wishlistItem + */ + private function addItemToWishlist(Wishlist $wishlist, WishlistItem $wishlistItem) + { + $sku = $wishlistItem->getParentSku() ?? $wishlistItem->getSku(); + + try { + $product = $this->productRepository->get($sku, false, null, true); + } catch (NoSuchEntityException $e) { + $this->addError( + __('Could not find a product with SKU "%sku"', ['sku' => $sku])->render(), + self::ERROR_PRODUCT_NOT_FOUND + ); + + return; + } + + try { + $options = $this->buyRequestBuilder->build($wishlistItem, (int) $product->getId()); + $result = $wishlist->addNewItem($product, $options); + + if (is_string($result)) { + $this->addError($result); + } + } catch (LocalizedException $exception) { + $this->addError($exception->getMessage()); + } catch (\Throwable $e) { + $this->addError( + __( + 'Could not add the product with SKU "%sku" to the wishlist:: %message', + ['sku' => $sku, 'message' => $e->getMessage()] + )->render() + ); + } + } + + /** + * Add wishlist line item error + * + * @param string $message + * @param string|null $code + * + * @return void + */ + private function addError(string $message, string $code = null): void + { + $this->errors[] = new Data\Error( + $message, + $code ?? self::ERROR_UNDEFINED + ); + } + + /** + * Prepare output + * + * @param Wishlist $wishlist + * + * @return WishlistOutput + */ + private function prepareOutput(Wishlist $wishlist): WishlistOutput + { + $output = new WishlistOutput($wishlist, $this->errors); + $this->errors = []; + + return $output; + } +} diff --git a/app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/BundleDataProvider.php b/app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/BundleDataProvider.php new file mode 100644 index 0000000000000..1cfa316c3cd01 --- /dev/null +++ b/app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/BundleDataProvider.php @@ -0,0 +1,55 @@ +getSelectedOptions() as $optionData) { + $optionData = \explode('/', base64_decode($optionData->getId())); + + if ($this->isProviderApplicable($optionData) === false) { + continue; + } + + [, $optionId, $optionValueId, $optionQuantity] = $optionData; + + $bundleOptionsData['bundle_option'][$optionId] = $optionValueId; + $bundleOptionsData['bundle_option_qty'][$optionId] = $optionQuantity; + } + + return $bundleOptionsData; + } + + /** + * Checks whether this provider is applicable for the current option + * + * @param array $optionData + * + * @return bool + */ + private function isProviderApplicable(array $optionData): bool + { + return $optionData[0] === self::PROVIDER_OPTION_TYPE; + } +} diff --git a/app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/BuyRequestBuilder.php b/app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/BuyRequestBuilder.php new file mode 100644 index 0000000000000..1f7ddce345b1c --- /dev/null +++ b/app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/BuyRequestBuilder.php @@ -0,0 +1,63 @@ +dataObjectFactory = $dataObjectFactory; + $this->providers = $providers; + } + + /** + * Build product buy request for adding to wishlist + * + * @param WishlistItem $wishlistItemData + * @param int|null $productId + * + * @return DataObject + */ + public function build(WishlistItem $wishlistItemData, ?int $productId = null): DataObject + { + $requestData = [ + [ + 'qty' => $wishlistItemData->getQuantity(), + ] + ]; + + foreach ($this->providers as $provider) { + $requestData[] = $provider->execute($wishlistItemData, $productId); + } + + return $this->dataObjectFactory->create(['data' => array_merge(...$requestData)]); + } +} diff --git a/app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/BuyRequestDataProviderInterface.php b/app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/BuyRequestDataProviderInterface.php new file mode 100644 index 0000000000000..fac45d7f86c7c --- /dev/null +++ b/app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/BuyRequestDataProviderInterface.php @@ -0,0 +1,26 @@ +getSelectedOptions() as $optionData) { + $optionData = \explode('/', base64_decode($optionData->getId())); + + if ($this->isProviderApplicable($optionData) === false) { + continue; + } + + [, $optionId, $optionValue] = $optionData; + + $customizableOptionsData[$optionId][] = $optionValue; + } + + foreach ($wishlistItemData->getEnteredOptions() as $option) { + $optionData = \explode('/', base64_decode($option->getId())); + + if ($this->isProviderApplicable($optionData) === false) { + continue; + } + + [, $optionId] = $optionData; + + $customizableOptionsData[$optionId][] = $option->getValue(); + } + + if (empty($customizableOptionsData)) { + return $customizableOptionsData; + } + + $result = ['options' => $this->flattenOptionValues($customizableOptionsData)]; + + if ($productId) { + $result += ['product' => $productId]; + } + + return $result; + } + + /** + * Flatten option values for non-multiselect customizable options + * + * @param array $customizableOptionsData + * + * @return array + */ + private function flattenOptionValues(array $customizableOptionsData): array + { + foreach ($customizableOptionsData as $optionId => $optionValue) { + if (count($optionValue) === 1) { + $customizableOptionsData[$optionId] = $optionValue[0]; + } + } + + return $customizableOptionsData; + } + + /** + * Checks whether this provider is applicable for the current option + * + * @param array $optionData + * @return bool + */ + private function isProviderApplicable(array $optionData): bool + { + return $optionData[0] === self::PROVIDER_OPTION_TYPE; + } +} diff --git a/app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/DownloadableLinkDataProvider.php b/app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/DownloadableLinkDataProvider.php new file mode 100644 index 0000000000000..1ad1a0b64706a --- /dev/null +++ b/app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/DownloadableLinkDataProvider.php @@ -0,0 +1,54 @@ +getSelectedOptions() as $optionData) { + $optionData = \explode('/', base64_decode($optionData->getId())); + + if ($this->isProviderApplicable($optionData) === false) { + continue; + } + + [, $linkId] = $optionData; + + $linksData[] = $linkId; + } + + return $linksData ? ['links' => $linksData] : []; + } + + /** + * Checks whether this provider is applicable for the current option + * + * @param array $optionData + * + * @return bool + */ + private function isProviderApplicable(array $optionData): bool + { + return $optionData[0] === self::PROVIDER_OPTION_TYPE; + } +} diff --git a/app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/SuperAttributeDataProvider.php b/app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/SuperAttributeDataProvider.php new file mode 100644 index 0000000000000..01e29bcf80c0b --- /dev/null +++ b/app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/SuperAttributeDataProvider.php @@ -0,0 +1,64 @@ +getSelectedOptions() as $optionData) { + $optionData = \explode('/', base64_decode($optionData->getId())); + + if ($this->isProviderApplicable($optionData) === false) { + continue; + } + + [, $attributeId, $valueIndex] = $optionData; + + $configurableData[$attributeId] = $valueIndex; + } + + if (empty($configurableData)) { + return $configurableData; + } + + $result = ['super_attribute' => $configurableData]; + + if ($productId) { + $result += ['product' => $productId]; + } + + return $result; + } + + /** + * Checks whether this provider is applicable for the current option + * + * @param array $optionData + * + * @return bool + */ + private function isProviderApplicable(array $optionData): bool + { + return $optionData[0] === self::PROVIDER_OPTION_TYPE; + } +} diff --git a/app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/SuperGroupDataProvider.php b/app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/SuperGroupDataProvider.php new file mode 100644 index 0000000000000..a11f631f1f5aa --- /dev/null +++ b/app/code/Magento/Wishlist/Model/Wishlist/BuyRequest/SuperGroupDataProvider.php @@ -0,0 +1,64 @@ +getSelectedOptions() as $optionData) { + $optionData = \explode('/', base64_decode($optionData->getId())); + + if ($this->isProviderApplicable($optionData) === false) { + continue; + } + + [, $simpleProductId, $quantity] = $optionData; + + $groupedData[$simpleProductId] = $quantity; + } + + if (empty($groupedData)) { + return $groupedData; + } + + $result = ['super_group' => $groupedData]; + + if ($productId) { + $result += ['product' => $productId]; + } + + return $result; + } + + /** + * Checks whether this provider is applicable for the current option + * + * @param array $optionData + * + * @return bool + */ + private function isProviderApplicable(array $optionData): bool + { + return $optionData[0] === self::PROVIDER_OPTION_TYPE; + } +} diff --git a/app/code/Magento/Wishlist/Model/Wishlist/Config.php b/app/code/Magento/Wishlist/Model/Wishlist/Config.php new file mode 100644 index 0000000000000..041e9f1ca0a21 --- /dev/null +++ b/app/code/Magento/Wishlist/Model/Wishlist/Config.php @@ -0,0 +1,46 @@ +scopeConfig = $scopeConfig; + } + + /** + * Check whether the wishlist is enabled or not + * + * @return bool + */ + public function isEnabled(): bool + { + return $this->scopeConfig->isSetFlag( + self::XML_PATH_WISHLIST_ACTIVE, + ScopeInterface::SCOPE_STORES + ); + } +} diff --git a/app/code/Magento/Wishlist/Model/Wishlist/Data/EnteredOption.php b/app/code/Magento/Wishlist/Model/Wishlist/Data/EnteredOption.php new file mode 100644 index 0000000000000..0d6b2a2302540 --- /dev/null +++ b/app/code/Magento/Wishlist/Model/Wishlist/Data/EnteredOption.php @@ -0,0 +1,54 @@ +id = $id; + $this->value = $value; + } + + /** + * Get entered option id + * + * @return string + */ + public function getId(): string + { + return $this->id; + } + + /** + * Get entered option value + * + * @return string + */ + public function getValue(): string + { + return $this->value; + } +} diff --git a/app/code/Magento/Wishlist/Model/Wishlist/Data/Error.php b/app/code/Magento/Wishlist/Model/Wishlist/Data/Error.php new file mode 100644 index 0000000000000..cb8420169fa8a --- /dev/null +++ b/app/code/Magento/Wishlist/Model/Wishlist/Data/Error.php @@ -0,0 +1,54 @@ +message = $message; + $this->code = $code; + } + + /** + * Get error message + * + * @return string + */ + public function getMessage(): string + { + return $this->message; + } + + /** + * Get error code + * + * @return string + */ + public function getCode(): string + { + return $this->code; + } +} diff --git a/app/code/Magento/Wishlist/Model/Wishlist/Data/SelectedOption.php b/app/code/Magento/Wishlist/Model/Wishlist/Data/SelectedOption.php new file mode 100644 index 0000000000000..129a61c0a2a6c --- /dev/null +++ b/app/code/Magento/Wishlist/Model/Wishlist/Data/SelectedOption.php @@ -0,0 +1,37 @@ +id = $id; + } + + /** + * Get selected option id + * + * @return string + */ + public function getId(): string + { + return $this->id; + } +} diff --git a/app/code/Magento/Wishlist/Model/Wishlist/Data/WishlistItem.php b/app/code/Magento/Wishlist/Model/Wishlist/Data/WishlistItem.php new file mode 100644 index 0000000000000..236b7f1eee72d --- /dev/null +++ b/app/code/Magento/Wishlist/Model/Wishlist/Data/WishlistItem.php @@ -0,0 +1,146 @@ +quantity = $quantity; + $this->sku = $sku; + $this->parentSku = $parentSku; + $this->id = $id; + $this->description = $description; + $this->selectedOptions = $selectedOptions; + $this->enteredOptions = $enteredOptions; + } + + /** + * Get wishlist item id + * + * @return int|null + */ + public function getId(): ?int + { + return $this->id; + } + + /** + * Get wishlist item description + * + * @return string|null + */ + public function getDescription(): ?string + { + return $this->description; + } + + /** + * Get sku + * + * @return string|null + */ + public function getSku(): ?string + { + return $this->sku; + } + + /** + * Get quantity + * + * @return float + */ + public function getQuantity(): float + { + return $this->quantity; + } + + /** + * Get parent sku + * + * @return string|null + */ + public function getParentSku(): ?string + { + return $this->parentSku; + } + + /** + * Get selected options + * + * @return SelectedOption[]|null + */ + public function getSelectedOptions(): ?array + { + return $this->selectedOptions; + } + + /** + * Get entered options + * + * @return EnteredOption[]|null + */ + public function getEnteredOptions(): ?array + { + return $this->enteredOptions; + } +} diff --git a/app/code/Magento/Wishlist/Model/Wishlist/Data/WishlistItemFactory.php b/app/code/Magento/Wishlist/Model/Wishlist/Data/WishlistItemFactory.php new file mode 100644 index 0000000000000..153e8451bae31 --- /dev/null +++ b/app/code/Magento/Wishlist/Model/Wishlist/Data/WishlistItemFactory.php @@ -0,0 +1,75 @@ +createSelectedOptions($data['selected_options']) : [], + isset($data['entered_options']) ? $this->createEnteredOptions($data['entered_options']) : [] + ); + } + + /** + * Create array of Entered Options + * + * @param array $options + * + * @return EnteredOption[] + */ + private function createEnteredOptions(array $options): array + { + return \array_map( + function (array $option) { + if (!isset($option['id'], $option['value'])) { + throw new InputException( + __('Required fields are not present EnteredOption.id, EnteredOption.value') + ); + } + return new EnteredOption($option['id'], $option['value']); + }, + $options + ); + } + + /** + * Create array of Selected Options + * + * @param string[] $options + * + * @return SelectedOption[] + */ + private function createSelectedOptions(array $options): array + { + return \array_map( + function ($option) { + return new SelectedOption($option); + }, + $options + ); + } +} diff --git a/app/code/Magento/Wishlist/Model/Wishlist/Data/WishlistOutput.php b/app/code/Magento/Wishlist/Model/Wishlist/Data/WishlistOutput.php new file mode 100644 index 0000000000000..fc7db9ec910fb --- /dev/null +++ b/app/code/Magento/Wishlist/Model/Wishlist/Data/WishlistOutput.php @@ -0,0 +1,56 @@ +wishlist = $wishlist; + $this->errors = $errors; + } + + /** + * Get Wishlist + * + * @return Wishlist + */ + public function getWishlist(): Wishlist + { + return $this->wishlist; + } + + /** + * Get errors happened during adding products to wishlist + * + * @return Error[] + */ + public function getErrors(): array + { + return $this->errors; + } +} diff --git a/app/code/Magento/Wishlist/Model/Wishlist/RemoveProductsFromWishlist.php b/app/code/Magento/Wishlist/Model/Wishlist/RemoveProductsFromWishlist.php new file mode 100644 index 0000000000000..c213c048fd61a --- /dev/null +++ b/app/code/Magento/Wishlist/Model/Wishlist/RemoveProductsFromWishlist.php @@ -0,0 +1,131 @@ +wishlistItemFactory = $wishlistItemFactory; + $this->wishlistItemResource = $wishlistItemResource; + } + + /** + * Removing items from wishlist + * + * @param Wishlist $wishlist + * @param array $wishlistItemsIds + * + * @return WishlistOutput + */ + public function execute(Wishlist $wishlist, array $wishlistItemsIds): WishlistOutput + { + foreach ($wishlistItemsIds as $wishlistItemId) { + $this->removeItemFromWishlist((int) $wishlistItemId); + } + + return $this->prepareOutput($wishlist); + } + + /** + * Remove product item from wishlist + * + * @param int $wishlistItemId + */ + private function removeItemFromWishlist(int $wishlistItemId): void + { + try { + /** @var WishlistItem $wishlistItem */ + $wishlistItem = $this->wishlistItemFactory->create(); + $this->wishlistItemResource->load($wishlistItem, $wishlistItemId); + if (!$wishlistItem->getId()) { + $this->addError( + __('Could not find a wishlist item with ID "%id"', ['id' => $wishlistItemId])->render(), + self::ERROR_PRODUCT_NOT_FOUND + ); + } + + $this->wishlistItemResource->delete($wishlistItem); + } catch (\Exception $e) { + $this->addError( + __( + 'We can\'t delete the item with ID "%id" from the Wish List right now.', + ['id' => $wishlistItemId] + )->render() + ); + } + } + + /** + * Add wishlist line item error + * + * @param string $message + * @param string|null $code + * + * @return void + */ + private function addError(string $message, string $code = null): void + { + $this->errors[] = new Data\Error( + $message, + $code ?? self::ERROR_UNDEFINED + ); + } + + /** + * Prepare output + * + * @param Wishlist $wishlist + * + * @return WishlistOutput + */ + private function prepareOutput(Wishlist $wishlist): WishlistOutput + { + $output = new WishlistOutput($wishlist, $this->errors); + $this->errors = []; + + return $output; + } +} diff --git a/app/code/Magento/Wishlist/Model/Wishlist/UpdateProductsInWishlist.php b/app/code/Magento/Wishlist/Model/Wishlist/UpdateProductsInWishlist.php new file mode 100644 index 0000000000000..691e00090373a --- /dev/null +++ b/app/code/Magento/Wishlist/Model/Wishlist/UpdateProductsInWishlist.php @@ -0,0 +1,136 @@ +buyRequestBuilder = $buyRequestBuilder; + $this->wishlistItemFactory = $wishlistItemFactory; + $this->wishlistItemResource = $wishlistItemResource; + } + + /** + * Adding products to wishlist + * + * @param Wishlist $wishlist + * @param array $wishlistItems + * + * @return WishlistOutput + */ + public function execute(Wishlist $wishlist, array $wishlistItems): WishlistOutput + { + foreach ($wishlistItems as $wishlistItem) { + $this->updateItemInWishlist($wishlist, $wishlistItem); + } + + return $this->prepareOutput($wishlist); + } + + /** + * Update product item in wishlist + * + * @param Wishlist $wishlist + * @param WishlistItemData $wishlistItemData + */ + private function updateItemInWishlist(Wishlist $wishlist, WishlistItemData $wishlistItemData) + { + try { + $options = $this->buyRequestBuilder->build($wishlistItemData); + /** @var WishlistItem $wishlistItem */ + $wishlistItem = $this->wishlistItemFactory->create(); + $this->wishlistItemResource->load($wishlistItem, $wishlistItemData->getId()); + $wishlistItem->setDescription($wishlistItemData->getDescription()); + $resultItem = $wishlist->updateItem($wishlistItem, $options); + + if (is_string($resultItem)) { + $this->addError($resultItem); + } + } catch (LocalizedException $exception) { + $this->addError($exception->getMessage()); + } + } + + /** + * Add wishlist line item error + * + * @param string $message + * @param string|null $code + * + * @return void + */ + private function addError(string $message, string $code = null): void + { + $this->errors[] = new Data\Error( + $message, + $code ?? self::ERROR_UNDEFINED + ); + } + + /** + * Prepare output + * + * @param Wishlist $wishlist + * + * @return WishlistOutput + */ + private function prepareOutput(Wishlist $wishlist): WishlistOutput + { + $output = new WishlistOutput($wishlist, $this->errors); + $this->errors = []; + + return $output; + } +} diff --git a/app/code/Magento/Wishlist/etc/graphql/di.xml b/app/code/Magento/Wishlist/etc/graphql/di.xml new file mode 100644 index 0000000000000..9726376bf30be --- /dev/null +++ b/app/code/Magento/Wishlist/etc/graphql/di.xml @@ -0,0 +1,20 @@ + + + + + + + Magento\Wishlist\Model\Wishlist\BuyRequest\SuperAttributeDataProvider + Magento\Wishlist\Model\Wishlist\BuyRequest\CustomizableOptionDataProvider + Magento\Wishlist\Model\Wishlist\BuyRequest\BundleDataProvider + Magento\Wishlist\Model\Wishlist\BuyRequest\DownloadableLinkDataProvider + Magento\Wishlist\Model\Wishlist\BuyRequest\SuperGroupDataProvider + + + + diff --git a/app/code/Magento/WishlistGraphQl/Mapper/WishlistDataMapper.php b/app/code/Magento/WishlistGraphQl/Mapper/WishlistDataMapper.php new file mode 100644 index 0000000000000..9cc1404613e41 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/Mapper/WishlistDataMapper.php @@ -0,0 +1,35 @@ + $wishlist->getId(), + 'sharing_code' => $wishlist->getSharingCode(), + 'updated_at' => $wishlist->getUpdatedAt(), + 'items_count' => $wishlist->getItemsCount(), + 'name' => $wishlist->getName(), + 'model' => $wishlist, + ]; + } +} diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlistResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlistResolver.php new file mode 100644 index 0000000000000..cdcffa8aa2adc --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlistResolver.php @@ -0,0 +1,129 @@ +wishlistResource = $wishlistResource; + $this->wishlistFactory = $wishlistFactory; + $this->wishlistConfig = $wishlistConfig; + $this->addProductsToWishlist = $addProductsToWishlist; + $this->wishlistDataMapper = $wishlistDataMapper; + } + + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if (!$this->wishlistConfig->isEnabled()) { + throw new GraphQlInputException(__('The wishlist is not currently available.')); + } + + $customerId = $context->getUserId(); + + /* Guest checking */ + if (!$customerId && 0 === $customerId) { + throw new GraphQlAuthorizationException(__('The current user cannot perform operations on wishlist')); + } + + $wishlistId = $args['wishlist_id'] ?: null; + $wishlistItemsData = $args['wishlist_items']; + $wishlist = $this->wishlistFactory->create(); + + if ($wishlistId) { + $this->wishlistResource->load($wishlist, $wishlistId); + } elseif ($customerId) { + $wishlist->loadByCustomerId($customerId, true); + } + + if (null === $wishlist->getId()) { + throw new GraphQlInputException(__('Something went wrong while creating the wishlist')); + } + + $wishlistItems = []; + foreach ($wishlistItemsData as $wishlistItemData) { + $wishlistItems[] = (new WishlistItemFactory())->create($wishlistItemData); + } + + $wishlistOutput = $this->addProductsToWishlist->execute($wishlist, $wishlistItems); + + return [ + 'wishlist' => $this->wishlistDataMapper->map($wishlistOutput->getWishlist()), + 'userInputErrors' => \array_map( + function (Error $error) { + return [ + 'code' => $error->getCode(), + 'message' => $error->getMessage(), + ]; + }, + $wishlistOutput->getErrors() + ) + ]; + } +} diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/CustomerWishlistResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/CustomerWishlistResolver.php index a84ce0e965b6d..94d543d25aa7a 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/CustomerWishlistResolver.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/CustomerWishlistResolver.php @@ -27,8 +27,9 @@ class CustomerWishlistResolver implements ResolverInterface /** * @param WishlistFactory $wishlistFactory */ - public function __construct(WishlistFactory $wishlistFactory) - { + public function __construct( + WishlistFactory $wishlistFactory + ) { $this->wishlistFactory = $wishlistFactory; } @@ -42,6 +43,7 @@ public function resolve( array $value = null, array $args = null ) { + // Todo: Check if wishlist is enabled if (false === $context->getExtensionAttributes()->getIsCustomer()) { throw new GraphQlAuthorizationException(__('The current customer isn\'t authorized.')); } diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlistResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlistResolver.php new file mode 100644 index 0000000000000..8c8d3aea54993 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlistResolver.php @@ -0,0 +1,127 @@ +wishlistResource = $wishlistResource; + $this->wishlistConfig = $wishlistConfig; + $this->wishlistFactory = $wishlistFactory; + $this->wishlistDataMapper = $wishlistDataMapper; + $this->removeProductsFromWishlist = $removeProductsFromWishlist; + } + + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if (!$this->wishlistConfig->isEnabled()) { + throw new GraphQlInputException(__('The wishlist is not currently available.')); + } + + $customerId = $context->getUserId(); + + /* Guest checking */ + if (!$customerId && 0 === $customerId) { + throw new GraphQlAuthorizationException(__('The current user cannot perform operations on wishlist')); + } + + $wishlistId = $args['wishlist_id']; + + if (!$wishlistId) { + throw new GraphQlInputException(__('The wishlist id is missing.')); + } + + $wishlist = $this->wishlistFactory->create(); + $this->wishlistResource->load($wishlist, $wishlistId); + + if (!$wishlist) { + throw new GraphQlInputException(__('The wishlist was not found.')); + } + + $wishlistItemsIds = $args['wishlist_items_ids']; + $wishlistOutput = $this->removeProductsFromWishlist->execute($wishlist, $wishlistItemsIds); + + if (!empty($wishlistItemsIds)) { + $this->wishlistResource->save($wishlist); + } + + return [ + 'wishlist' => $this->wishlistDataMapper->map($wishlistOutput->getWishlist()), + 'userInputErrors' => \array_map( + function (Error $error) { + return [ + 'code' => $error->getCode(), + 'message' => $error->getMessage(), + ]; + }, + $wishlistOutput->getErrors() + ) + ]; + } +} diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlistResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlistResolver.php new file mode 100644 index 0000000000000..6ce074b3e8dc2 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlistResolver.php @@ -0,0 +1,137 @@ +wishlistResource = $wishlistResource; + $this->wishlistFactory = $wishlistFactory; + $this->wishlistConfig = $wishlistConfig; + $this->updateProductsInWishlist = $updateProductsInWishlist; + $this->wishlistDataMapper = $wishlistDataMapper; + } + + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if (!$this->wishlistConfig->isEnabled()) { + throw new GraphQlInputException(__('The wishlist is not currently available.')); + } + + $customerId = $context->getUserId(); + + /* Guest checking */ + if (!$customerId && 0 === $customerId) { + throw new GraphQlAuthorizationException(__('The current user cannot perform operations on wishlist')); + } + + $wishlistId = $args['wishlist_id']; + + if (!$wishlistId) { + throw new GraphQlInputException(__('The wishlist id is missing.')); + } + + $wishlist = $this->wishlistFactory->create(); + + if ($wishlistId) { + $this->wishlistResource->load($wishlist, $wishlistId); + } + + if (null === $wishlist->getId()) { + throw new GraphQlInputException(__('The wishlist was not found.')); + } + + $wishlistItems = []; + $wishlistItemsData = $args['wishlist_items']; + + foreach ($wishlistItemsData as $wishlistItemData) { + $wishlistItems[] = (new WishlistItemFactory())->create($wishlistItemData); + } + + $wishlistOutput = $this->updateProductsInWishlist->execute($wishlist, $wishlistItems); + + if (count($wishlistOutput->getErrors()) !== count($wishlistItems)) { + $this->wishlistResource->save($wishlist); + } + + return [ + 'wishlist' => $this->wishlistDataMapper->map($wishlistOutput->getWishlist()), + 'userInputErrors' => \array_map( + function (Error $error) { + return [ + 'code' => $error->getCode(), + 'message' => $error->getMessage(), + ]; + }, + $wishlistOutput->getErrors() + ) + ]; + } +} diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php index 792928ab61aaf..d0d409abd1698 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php @@ -34,8 +34,10 @@ class WishlistResolver implements ResolverInterface * @param WishlistResourceModel $wishlistResource * @param WishlistFactory $wishlistFactory */ - public function __construct(WishlistResourceModel $wishlistResource, WishlistFactory $wishlistFactory) - { + public function __construct( + WishlistResourceModel $wishlistResource, + WishlistFactory $wishlistFactory + ) { $this->wishlistResource = $wishlistResource; $this->wishlistFactory = $wishlistFactory; } @@ -50,6 +52,7 @@ public function resolve( array $value = null, array $args = null ) { + // Todo: Check if wishlist is enabled $customerId = $context->getUserId(); /* Guest checking */ diff --git a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls index deaa66921ba7c..1fcfc3b9488af 100644 --- a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls +++ b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls @@ -32,3 +32,45 @@ type WishlistItem { added_at: String @doc(description: "The time when the customer added the item to the wish list"), product: ProductInterface @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\ProductResolver") } + +type Mutation { + addProductsToWishlist(wishlist_id: ID!, wishlist_items: [WishlistItemInput!]!): AddProductsToWishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\AddProductsToWishlistResolver") + removeProductsFromWishlist(wishlist_id: ID!, wishlist_items_ids: [ID!]!): RemoveProductsFromWishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\RemoveProductsFromWishlistResolver") + updateProductsInWishlist(wishlist_id: ID!, wishlist_items: [WishlistItemUpdateInput!]!): UpdateProductsInWishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\UpdateProductsInWishlistResolver") +} + +input WishlistItemInput { + sku: String + quantity: Float + parent_sku: String, + selected_options: [String!] + entered_options: [EnteredOptionInput!] +} + +type AddProductsToWishlistOutput { + wishlist: Wishlist! + userInputErrors:[CheckoutUserInputError]! @doc(description: "An array of wishlist adding errors.") +} + +input EnteredOptionInput { + id: String! @doc(description: "base64 encoded id") + value: String! +} + +type RemoveProductsFromWishlistOutput { + wishlist: Wishlist! + userInputErrors:[CheckoutUserInputError]! @doc(description:"An array of wishlist removing errors.") +} + +input WishlistItemUpdateInput { + wishlist_item_id: ID + quantity: Float + description: String + selected_options: [String!] + entered_options: [EnteredOptionInput!] +} + +type UpdateProductsInWishlistOutput { + wishlist: Wishlist! + userInputErrors:[CheckoutUserInputError]! @doc(description:"An array of wishlist updating errors.") +} From 034af404deaa448c6ae660166912b0c40dfc7b12 Mon Sep 17 00:00:00 2001 From: Oleh Usik Date: Thu, 23 Apr 2020 18:49:13 +0300 Subject: [PATCH 02/27] PR 28072 Add coverage for cart items --- .../Model/Resolver/Cart/Item/GiftMessage.php | 79 +++++++++++++++++++ .../GiftMessageGraphQl/etc/schema.graphqls | 16 ++++ .../GiftMessage/Cart/Item/GiftMessageTest.php | 63 +++++++++++++++ .../_files/guest/quote_with_item_message.php | 63 +++++++++++++++ .../quote_with_item_message_rollback.php | 32 ++++++++ 5 files changed, 253 insertions(+) create mode 100644 app/code/Magento/GiftMessageGraphQl/Model/Resolver/Cart/Item/GiftMessage.php create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/GiftMessage/Cart/Item/GiftMessageTest.php create mode 100644 dev/tests/integration/testsuite/Magento/GiftMessage/_files/guest/quote_with_item_message.php create mode 100644 dev/tests/integration/testsuite/Magento/GiftMessage/_files/guest/quote_with_item_message_rollback.php diff --git a/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Cart/Item/GiftMessage.php b/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Cart/Item/GiftMessage.php new file mode 100644 index 0000000000000..34d3d3969835a --- /dev/null +++ b/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Cart/Item/GiftMessage.php @@ -0,0 +1,79 @@ +itemRepository = $itemRepository; + } + + /** + * Return information about Gift message for item cart + * + * @param Field $field + * @param ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * + * @return array|Value|mixed + * @throws GraphQlInputException + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if (!isset($value['model'])) { + throw new GraphQlInputException(__('"model" value should be specified')); + } + + $quoteItem = $value['model']; + + try { + $giftItemMessage = $this->itemRepository->get($quoteItem->getQuoteId(), $quoteItem->getItemId()); + } catch (LocalizedException $e) { + throw new GraphQlInputException(__('Can\'t load cart item')); + } + + return [ + 'to' => isset($giftItemMessage) ? $giftItemMessage->getRecipient() : '', + 'from' => isset($giftItemMessage) ? $giftItemMessage->getSender() : '', + 'message'=> isset($giftItemMessage) ? $giftItemMessage->getMessage() : '' + ]; + } +} diff --git a/app/code/Magento/GiftMessageGraphQl/etc/schema.graphqls b/app/code/Magento/GiftMessageGraphQl/etc/schema.graphqls index f0c0353cc6305..fc414b027e76a 100644 --- a/app/code/Magento/GiftMessageGraphQl/etc/schema.graphqls +++ b/app/code/Magento/GiftMessageGraphQl/etc/schema.graphqls @@ -5,6 +5,22 @@ type Cart { gift_message: GiftMessage @resolver (class: "\\Magento\\GiftMessageGraphQl\\Model\\Resolver\\Cart\\GiftMessage") @doc(description: "The entered gift message for the cart") } +type SimpleCartItem { + gift_message: GiftMessage @resolver (class: "\\Magento\\GiftMessageGraphQl\\Model\\Resolver\\Cart\\Item\\GiftMessage") @doc(description: "The entered gift message for the cart item") +} + +type ConfigurableCartItem { + gift_message: GiftMessage @resolver (class: "\\Magento\\GiftMessageGraphQl\\Model\\Resolver\\Cart\\Item\\GiftMessage") @doc(description: "The entered gift message for the cart item") +} + +type BundleCartItem { + gift_message: GiftMessage @resolver (class: "\\Magento\\GiftMessageGraphQl\\Model\\Resolver\\Cart\\Item\\GiftMessage") @doc(description: "The entered gift message for the cart item") +} + +type GiftCardCartItem { + gift_message: GiftMessage @resolver (class: "\\Magento\\GiftMessageGraphQl\\Model\\Resolver\\Cart\\Item\\GiftMessage") @doc(description: "The entered gift message for the cart item") +} + type GiftMessage { to: String! @doc(description: "Recepient name") from: String! @doc(description: "Sender name") diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/GiftMessage/Cart/Item/GiftMessageTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/GiftMessage/Cart/Item/GiftMessageTest.php new file mode 100644 index 0000000000000..7e5c0e15bd456 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/GiftMessage/Cart/Item/GiftMessageTest.php @@ -0,0 +1,63 @@ +getMaskedQuoteIdByReservedOrderId = $objectManager->get(GetMaskedQuoteIdByReservedOrderId::class); + } + + /** + * @magentoApiDataFixture Magento/GiftMessage/_files/guest/quote_with_item_message.php + * @throws NoSuchEntityException + * @throws Exception + */ + public function testGiftMessageCartForItem() + { + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_guest_order_with_gift_message'); + $query = <<graphQlQuery($query); + foreach ($response['cart']['items'] as $item) { + self::assertArrayHasKey('gift_message', $item); + self::assertArrayHasKey('to', $item['gift_message']); + self::assertArrayHasKey('from', $item['gift_message']); + self::assertArrayHasKey('message', $item['gift_message']); + } + } +} diff --git a/dev/tests/integration/testsuite/Magento/GiftMessage/_files/guest/quote_with_item_message.php b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/guest/quote_with_item_message.php new file mode 100644 index 0000000000000..36217ddbfac68 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/guest/quote_with_item_message.php @@ -0,0 +1,63 @@ +create(QuoteResource::class); + +/** @var Quote $quoteModel */ +$quoteModel = $objectManager->create(Quote::class); +$quoteModel->setData(['store_id' => 1, 'is_active' => 1, 'is_multi_shipping' => 0]); +$quote->save($quoteModel); + +$product = $objectManager->create(Product::class); +$quoteProduct = $product->load($product->getIdBySku('simple')); + +$quoteModel->setReservedOrderId('test_guest_order_with_gift_message') + ->addProduct($product->load($product->getIdBySku('simple')), 1); +$quoteModel->collectTotals(); +$quote->save($quoteModel); + +/** @var MessageResource $message */ +$message = $objectManager->create(MessageResource::class); + +/** @var Message $message */ +$messageModel = $objectManager->create(Message::class); + +$messageModel->setSender('John Doe'); +$messageModel->setRecipient('Jane Roe'); +$messageModel->setMessage('Gift Message Text'); +$message->save($messageModel); + +$quoteModel->getItemByProduct($quoteProduct)->setGiftMessageId($messageModel->getId()); +$quote->save($quoteModel); + +/** @var QuoteIdMaskResource $quoteIdMask */ +$quoteIdMask = Bootstrap::getObjectManager() + ->create(QuoteIdMaskFactory::class) + ->create(); + +/** @var QuoteIdMask $quoteIdMaskModel */ +$quoteIdMaskModel = $objectManager->create(QuoteIdMask::class); + +$quoteIdMaskModel->setQuoteId($quoteModel->getId()); +$quoteIdMaskModel->setDataChanges(true); +$quoteIdMask->save($quoteIdMaskModel); diff --git a/dev/tests/integration/testsuite/Magento/GiftMessage/_files/guest/quote_with_item_message_rollback.php b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/guest/quote_with_item_message_rollback.php new file mode 100644 index 0000000000000..9c215cb432b45 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/guest/quote_with_item_message_rollback.php @@ -0,0 +1,32 @@ +get(Registry::class); +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); +$objectManager = Bootstrap::getObjectManager(); +$quote = $objectManager->create(Quote::class); +$quote->load('test_guest_order_with_gift_message', 'reserved_order_id'); +$message = $objectManager->create(Message::class); +$product = $objectManager->create(Product::class); +foreach ($quote->getAllItems() as $item) { + $message->load($item->getGiftMessageId()); + $message->delete(); + $sku = $item->getSku(); + $product->load($product->getIdBySku($sku)); + if ($product->getId()) { + $product->delete(); + } +} +$quote->delete(); +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); From 7e6e0239c9895982b4bb1577412b0018beef1361 Mon Sep 17 00:00:00 2001 From: Oleh Usik Date: Wed, 20 May 2020 16:10:07 +0300 Subject: [PATCH 03/27] Added additional checks and test cases --- .../Model/Resolver/Cart/Item/GiftMessage.php | 32 +++++++++++--- .../GiftMessage/Cart/Item/GiftMessageTest.php | 44 +++++++++++++++---- 2 files changed, 60 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Cart/Item/GiftMessage.php b/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Cart/Item/GiftMessage.php index 34d3d3969835a..6d2f546e260e5 100644 --- a/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Cart/Item/GiftMessage.php +++ b/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Cart/Item/GiftMessage.php @@ -8,7 +8,6 @@ namespace Magento\GiftMessageGraphQl\Model\Resolver\Cart\Item; use Magento\Framework\Exception\LocalizedException; -use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; @@ -16,6 +15,7 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\GiftMessage\Api\ItemRepositoryInterface; +use Magento\GiftMessage\Helper\Message as GiftMessageHelper; /** * Class provides ability to get GiftMessage for cart item @@ -28,14 +28,20 @@ class GiftMessage implements ResolverInterface private $itemRepository; /** - * GiftMessageItem constructor. - * + * @var GiftMessageHelper + */ + private $giftMessageHelper; + + /** * @param ItemRepositoryInterface $itemRepository + * @param GiftMessageHelper $giftMessageHelper */ public function __construct( - ItemRepositoryInterface $itemRepository + ItemRepositoryInterface $itemRepository, + GiftMessageHelper $giftMessageHelper ) { $this->itemRepository = $itemRepository; + $this->giftMessageHelper = $giftMessageHelper; } /** @@ -64,16 +70,28 @@ public function resolve( $quoteItem = $value['model']; + if (!$this->giftMessageHelper->isMessagesAllowed('items', $quoteItem)) { + return null; + } + + if (!$this->giftMessageHelper->isMessagesAllowed('item', $quoteItem)) { + return null; + } + try { $giftItemMessage = $this->itemRepository->get($quoteItem->getQuoteId(), $quoteItem->getItemId()); } catch (LocalizedException $e) { throw new GraphQlInputException(__('Can\'t load cart item')); } + if (!isset($giftItemMessage)) { + return null; + } + return [ - 'to' => isset($giftItemMessage) ? $giftItemMessage->getRecipient() : '', - 'from' => isset($giftItemMessage) ? $giftItemMessage->getSender() : '', - 'message'=> isset($giftItemMessage) ? $giftItemMessage->getMessage() : '' + 'to' => $giftItemMessage->getRecipient() ?? '', + 'from' => $giftItemMessage->getSender() ?? '', + 'message'=> $giftItemMessage->getMessage() ?? '' ]; } } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/GiftMessage/Cart/Item/GiftMessageTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/GiftMessage/Cart/Item/GiftMessageTest.php index 7e5c0e15bd456..756caf0e228b4 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/GiftMessage/Cart/Item/GiftMessageTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/GiftMessage/Cart/Item/GiftMessageTest.php @@ -20,13 +20,14 @@ class GiftMessageTest extends GraphQlAbstract */ private $getMaskedQuoteIdByReservedOrderId; - protected function setUp() + protected function setUp(): void { $objectManager = Bootstrap::getObjectManager(); $this->getMaskedQuoteIdByReservedOrderId = $objectManager->get(GetMaskedQuoteIdByReservedOrderId::class); } /** + * @magentoConfigFixture default_store sales/gift_options/allow_items 1 * @magentoApiDataFixture Magento/GiftMessage/_files/guest/quote_with_item_message.php * @throws NoSuchEntityException * @throws Exception @@ -34,9 +35,40 @@ protected function setUp() public function testGiftMessageCartForItem() { $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_guest_order_with_gift_message'); + foreach ($this->requestCartResult($maskedQuoteId)['cart']['items'] as $item) { + self::assertArrayHasKey('gift_message', $item); + self::assertArrayHasKey('to', $item['gift_message']); + self::assertArrayHasKey('from', $item['gift_message']); + self::assertArrayHasKey('message', $item['gift_message']); + } + } + + /** + * @magentoConfigFixture default_store sales/gift_options/allow_items 0 + * @magentoApiDataFixture Magento/GiftMessage/_files/guest/quote_with_item_message.php + * @throws NoSuchEntityException + * @throws Exception + */ + public function testGiftMessageCartForItemNotAllow() + { + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_guest_order_with_gift_message'); + foreach ($this->requestCartResult($maskedQuoteId)['cart']['items'] as $item) { + self::assertArrayHasKey('gift_message', $item); + self::assertNull($item['gift_message']); + } + } + + /** + * @param string $quoteId + * + * @return array|bool|float|int|string + * @throws Exception + */ + private function requestCartResult(string $quoteId) + { $query = <<graphQlQuery($query); - foreach ($response['cart']['items'] as $item) { - self::assertArrayHasKey('gift_message', $item); - self::assertArrayHasKey('to', $item['gift_message']); - self::assertArrayHasKey('from', $item['gift_message']); - self::assertArrayHasKey('message', $item['gift_message']); - } + return $this->graphQlQuery($query); } } From 81737c084b0b80b48cf5b3359e3b145c64aa54f1 Mon Sep 17 00:00:00 2001 From: Oleh Usik Date: Wed, 20 May 2020 20:41:27 +0300 Subject: [PATCH 04/27] Remove redandant line from fixture --- .../GiftMessage/_files/guest/quote_with_item_message.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/GiftMessage/_files/guest/quote_with_item_message.php b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/guest/quote_with_item_message.php index 36217ddbfac68..d72a44e794927 100644 --- a/dev/tests/integration/testsuite/Magento/GiftMessage/_files/guest/quote_with_item_message.php +++ b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/guest/quote_with_item_message.php @@ -6,7 +6,6 @@ require __DIR__ . '/../../../../Magento/Catalog/_files/products.php'; -use Magento\Catalog\Model\Product; use Magento\Framework\ObjectManagerInterface; use Magento\GiftMessage\Model\Message; use Magento\GiftMessage\Model\ResourceModel\Message as MessageResource; @@ -28,7 +27,6 @@ $quoteModel->setData(['store_id' => 1, 'is_active' => 1, 'is_multi_shipping' => 0]); $quote->save($quoteModel); -$product = $objectManager->create(Product::class); $quoteProduct = $product->load($product->getIdBySku('simple')); $quoteModel->setReservedOrderId('test_guest_order_with_gift_message') From 120a105b5adb6fbc4d35a0067d72aa1975acccc5 Mon Sep 17 00:00:00 2001 From: Oleh Usik Date: Mon, 11 May 2020 19:16:39 +0300 Subject: [PATCH 05/27] PR 28194 Add ability to update Gift Message for cart item --- .../GiftMessageGraphQl/etc/graphql/di.xml | 18 ++++++++ .../GiftMessageGraphQl/etc/schema.graphqls | 15 +++++++ .../Model/Resolver/UpdateCartItems.php | 43 +++++++++++++++++-- app/code/Magento/QuoteGraphQl/composer.json | 3 +- 4 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 app/code/Magento/GiftMessageGraphQl/etc/graphql/di.xml diff --git a/app/code/Magento/GiftMessageGraphQl/etc/graphql/di.xml b/app/code/Magento/GiftMessageGraphQl/etc/graphql/di.xml new file mode 100644 index 0000000000000..bce5b7063e6b9 --- /dev/null +++ b/app/code/Magento/GiftMessageGraphQl/etc/graphql/di.xml @@ -0,0 +1,18 @@ + + + + + + + sales/gift_options/allow_order + sales/gift_options/allow_items + + + + diff --git a/app/code/Magento/GiftMessageGraphQl/etc/schema.graphqls b/app/code/Magento/GiftMessageGraphQl/etc/schema.graphqls index f0c0353cc6305..d383f900a3911 100644 --- a/app/code/Magento/GiftMessageGraphQl/etc/schema.graphqls +++ b/app/code/Magento/GiftMessageGraphQl/etc/schema.graphqls @@ -1,6 +1,11 @@ # Copyright © Magento, Inc. All rights reserved. # See COPYING.txt for license details. +type StoreConfig { + allow_order : String @doc(description: "Allow Gift Messages on order level") + allow_items : String @doc(description: "Allow Gift Messages for order items") +} + type Cart { gift_message: GiftMessage @resolver (class: "\\Magento\\GiftMessageGraphQl\\Model\\Resolver\\Cart\\GiftMessage") @doc(description: "The entered gift message for the cart") } @@ -10,3 +15,13 @@ type GiftMessage { from: String! @doc(description: "Sender name") message: String! @doc(description: "Gift message text") } + +input CartItemUpdateInput { + gift_message: GiftMessageInput @doc(description: "Gift message details for the cart item") +} + +input GiftMessageInput { + to: String! @doc(description: "Recepient name") + from: String! @doc(description: "Sender name") + message: String! @doc(description: "Gift message text") +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php index fa90f08e4b553..5e420e1c27016 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php @@ -14,6 +14,7 @@ use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\GiftMessage\Api\ItemRepositoryInterface; use Magento\Quote\Api\CartItemRepositoryInterface; use Magento\Quote\Api\CartRepositoryInterface; use Magento\Quote\Model\Quote; @@ -46,21 +47,29 @@ class UpdateCartItems implements ResolverInterface private $cartRepository; /** - * @param GetCartForUser $getCartForUser + * @var ItemRepositoryInterface + */ + private $itemRepository; + + /** + * @param GetCartForUser $getCartForUser * @param CartItemRepositoryInterface $cartItemRepository - * @param UpdateCartItem $updateCartItem - * @param CartRepositoryInterface $cartRepository + * @param UpdateCartItem $updateCartItem + * @param CartRepositoryInterface $cartRepository + * @param ItemRepositoryInterface $itemRepository */ public function __construct( GetCartForUser $getCartForUser, CartItemRepositoryInterface $cartItemRepository, UpdateCartItem $updateCartItem, - CartRepositoryInterface $cartRepository + CartRepositoryInterface $cartRepository, + ItemRepositoryInterface $itemRepository ) { $this->getCartForUser = $getCartForUser; $this->cartItemRepository = $cartItemRepository; $this->updateCartItem = $updateCartItem; $this->cartRepository = $cartRepository; + $this->itemRepository = $itemRepository; } /** @@ -131,6 +140,32 @@ private function processCartItems(Quote $cart, array $items): void } else { $this->updateCartItem->execute($cart, $itemId, $quantity, $customizableOptions); } + + if (!empty($item['gift_message'])) { + $this->updateGiftMessageForItem($cart, $item, $itemId); + } + } + } + + /** + * Update Gift Message for Quote item + * + * @param Quote $cart + * @param array $item + * @param int $itemId + * + * @throws GraphQlInputException + */ + private function updateGiftMessageForItem(Quote $cart, array $item, int $itemId) + { + try { + $giftItemMessage = $this->itemRepository->get($cart->getEntityId(), $itemId); + $giftItemMessage->setRecipient($item['gift_message']['to']); + $giftItemMessage->setSender($item['gift_message']['from']); + $giftItemMessage->setMessage($item['gift_message']['message']); + $this->itemRepository->save($cart->getEntityId(), $giftItemMessage, $itemId); + } catch (LocalizedException $exception) { + throw new GraphQlInputException(__('Gift Message can not be updated.')); } } } diff --git a/app/code/Magento/QuoteGraphQl/composer.json b/app/code/Magento/QuoteGraphQl/composer.json index 0652d39b5f426..25f089cf75a62 100644 --- a/app/code/Magento/QuoteGraphQl/composer.json +++ b/app/code/Magento/QuoteGraphQl/composer.json @@ -13,7 +13,8 @@ "magento/module-customer-graph-ql": "*", "magento/module-sales": "*", "magento/module-directory": "*", - "magento/module-graph-ql": "*" + "magento/module-graph-ql": "*", + "magento/module-gift-message": "*" }, "suggest": { "magento/module-graph-ql-cache": "*" From 035c1577d0e5dee7c102375cd2bdba0f1542c85f Mon Sep 17 00:00:00 2001 From: Oleh Usik Date: Thu, 21 May 2020 20:16:31 +0300 Subject: [PATCH 06/27] move part logic to other file --- .../CartItem/DataProvider/UpdateCartItems.php | 142 ++++++++++++++++++ .../Model/Resolver/UpdateCartItems.php | 101 ++----------- 2 files changed, 153 insertions(+), 90 deletions(-) create mode 100644 app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/UpdateCartItems.php diff --git a/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/UpdateCartItems.php b/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/UpdateCartItems.php new file mode 100644 index 0000000000000..5657e5f4587ec --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/UpdateCartItems.php @@ -0,0 +1,142 @@ +cartItemRepository = $cartItemRepository; + $this->updateCartItem = $updateCartItem; + $this->itemRepository = $itemRepository; + $this->giftMessageHelper = $giftMessageHelper; + } + + /** + * Process cart items + * + * @param Quote $cart + * @param array $items + * @throws GraphQlInputException + * @throws LocalizedException + */ + public function processCartItems(Quote $cart, array $items): void + { + foreach ($items as $item) { + if (empty($item['cart_item_id'])) { + throw new GraphQlInputException(__('Required parameter "cart_item_id" for "cart_items" is missing.')); + } + + $itemId = (int)$item['cart_item_id']; + $customizableOptions = $item['customizable_options'] ?? []; + $cartItem = $cart->getItemById($itemId); + + if ($cartItem && $cartItem->getParentItemId()) { + throw new GraphQlInputException(__('Child items may not be updated.')); + } + + if (count($customizableOptions) === 0 && !isset($item['quantity'])) { + throw new GraphQlInputException(__('Required parameter "quantity" for "cart_items" is missing.')); + } + + $quantity = (float)$item['quantity']; + + if ($quantity <= 0.0) { + $this->cartItemRepository->deleteById((int)$cart->getId(), $itemId); + } else { + $this->updateCartItem->execute($cart, $itemId, $quantity, $customizableOptions); + } + + if (!empty($item['gift_message'])) { + try { + if (!$this->giftMessageHelper->isMessagesAllowed('items', $cartItem)) { + continue; + } + if (!$this->giftMessageHelper->isMessagesAllowed('item', $cartItem)) { + continue; + } + + /** @var MessageInterface $giftItemMessage */ + $giftItemMessage = $this->itemRepository->get($cart->getEntityId(), $itemId); + + if (empty($giftItemMessage)) { + continue; + } + } catch (LocalizedException $exception) { + throw new GraphQlInputException(__('Gift Message can not be updated.')); + } + + $this->updateGiftMessageForItem($cart, $giftItemMessage, $item, $itemId); + } + } + } + + /** + * Update Gift Message for Quote item + * + * @param Quote $cart + * @param MessageInterface $giftItemMessage + * @param array $item + * @param int $itemId + * + * @throws GraphQlInputException + */ + private function updateGiftMessageForItem(Quote $cart, MessageInterface $giftItemMessage, array $item, int $itemId) + { + try { + $giftItemMessage->setRecipient($item['gift_message']['to']); + $giftItemMessage->setSender($item['gift_message']['from']); + $giftItemMessage->setMessage($item['gift_message']['message']); + $this->itemRepository->save($cart->getEntityId(), $giftItemMessage, $itemId); + } catch (LocalizedException $exception) { + throw new GraphQlInputException(__('Gift Message can not be updated')); + } + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php index 5e420e1c27016..005baaad0e1e5 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php @@ -14,62 +14,43 @@ use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; -use Magento\GiftMessage\Api\ItemRepositoryInterface; -use Magento\Quote\Api\CartItemRepositoryInterface; use Magento\Quote\Api\CartRepositoryInterface; -use Magento\Quote\Model\Quote; use Magento\QuoteGraphQl\Model\Cart\GetCartForUser; -use Magento\QuoteGraphQl\Model\Cart\UpdateCartItem; +use Magento\QuoteGraphQl\Model\CartItem\DataProvider\UpdateCartItems as UpdateCartItemsProvider; /** * @inheritdoc */ class UpdateCartItems implements ResolverInterface { - /** - * @var UpdateCartItem - */ - private $updateCartItem; - /** * @var GetCartForUser */ private $getCartForUser; - /** - * @var CartItemRepositoryInterface - */ - private $cartItemRepository; - /** * @var CartRepositoryInterface */ private $cartRepository; /** - * @var ItemRepositoryInterface + * @var UpdateCartItemsProvider */ - private $itemRepository; + private $updateCartItems; /** - * @param GetCartForUser $getCartForUser - * @param CartItemRepositoryInterface $cartItemRepository - * @param UpdateCartItem $updateCartItem - * @param CartRepositoryInterface $cartRepository - * @param ItemRepositoryInterface $itemRepository + * @param GetCartForUser $getCartForUser + * @param CartRepositoryInterface $cartRepository + * @param UpdateCartItemsProvider $updateCartItems */ public function __construct( GetCartForUser $getCartForUser, - CartItemRepositoryInterface $cartItemRepository, - UpdateCartItem $updateCartItem, CartRepositoryInterface $cartRepository, - ItemRepositoryInterface $itemRepository + UpdateCartItemsProvider $updateCartItems ) { $this->getCartForUser = $getCartForUser; - $this->cartItemRepository = $cartItemRepository; - $this->updateCartItem = $updateCartItem; $this->cartRepository = $cartRepository; - $this->itemRepository = $itemRepository; + $this->updateCartItems = $updateCartItems; } /** @@ -80,6 +61,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value if (empty($args['input']['cart_id'])) { throw new GraphQlInputException(__('Required parameter "cart_id" is missing.')); } + $maskedCartId = $args['input']['cart_id']; if (empty($args['input']['cart_items']) @@ -87,13 +69,13 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value ) { throw new GraphQlInputException(__('Required parameter "cart_items" is missing.')); } - $cartItems = $args['input']['cart_items']; + $cartItems = $args['input']['cart_items']; $storeId = (int)$context->getExtensionAttributes()->getStore()->getId(); $cart = $this->getCartForUser->execute($maskedCartId, $context->getUserId(), $storeId); try { - $this->processCartItems($cart, $cartItems); + $this->updateCartItems->processCartItems($cart, $cartItems); $this->cartRepository->save($cart); } catch (NoSuchEntityException $e) { throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e); @@ -107,65 +89,4 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value ], ]; } - - /** - * Process cart items - * - * @param Quote $cart - * @param array $items - * @throws GraphQlInputException - * @throws LocalizedException - */ - private function processCartItems(Quote $cart, array $items): void - { - foreach ($items as $item) { - if (empty($item['cart_item_id'])) { - throw new GraphQlInputException(__('Required parameter "cart_item_id" for "cart_items" is missing.')); - } - $itemId = (int)$item['cart_item_id']; - $customizableOptions = $item['customizable_options'] ?? []; - - $cartItem = $cart->getItemById($itemId); - if ($cartItem && $cartItem->getParentItemId()) { - throw new GraphQlInputException(__('Child items may not be updated.')); - } - - if (count($customizableOptions) === 0 && !isset($item['quantity'])) { - throw new GraphQlInputException(__('Required parameter "quantity" for "cart_items" is missing.')); - } - $quantity = (float)$item['quantity']; - - if ($quantity <= 0.0) { - $this->cartItemRepository->deleteById((int)$cart->getId(), $itemId); - } else { - $this->updateCartItem->execute($cart, $itemId, $quantity, $customizableOptions); - } - - if (!empty($item['gift_message'])) { - $this->updateGiftMessageForItem($cart, $item, $itemId); - } - } - } - - /** - * Update Gift Message for Quote item - * - * @param Quote $cart - * @param array $item - * @param int $itemId - * - * @throws GraphQlInputException - */ - private function updateGiftMessageForItem(Quote $cart, array $item, int $itemId) - { - try { - $giftItemMessage = $this->itemRepository->get($cart->getEntityId(), $itemId); - $giftItemMessage->setRecipient($item['gift_message']['to']); - $giftItemMessage->setSender($item['gift_message']['from']); - $giftItemMessage->setMessage($item['gift_message']['message']); - $this->itemRepository->save($cart->getEntityId(), $giftItemMessage, $itemId); - } catch (LocalizedException $exception) { - throw new GraphQlInputException(__('Gift Message can not be updated.')); - } - } } From cea930b4d7549bcf476e621ad11ffbfa4847e0e6 Mon Sep 17 00:00:00 2001 From: Oleh Usik Date: Fri, 22 May 2020 13:33:53 +0300 Subject: [PATCH 07/27] changes in test fixture --- .../_files/guest/quote_with_item_message.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/GiftMessage/_files/guest/quote_with_item_message.php b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/guest/quote_with_item_message.php index d72a44e794927..4cbe088893b03 100644 --- a/dev/tests/integration/testsuite/Magento/GiftMessage/_files/guest/quote_with_item_message.php +++ b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/guest/quote_with_item_message.php @@ -4,8 +4,7 @@ * See COPYING.txt for license details. */ -require __DIR__ . '/../../../../Magento/Catalog/_files/products.php'; - +use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Framework\ObjectManagerInterface; use Magento\GiftMessage\Model\Message; use Magento\GiftMessage\Model\ResourceModel\Message as MessageResource; @@ -15,6 +14,9 @@ use Magento\Quote\Model\ResourceModel\Quote\QuoteIdMask as QuoteIdMaskResource; use Magento\Quote\Model\ResourceModel\Quote\QuoteIdMaskFactory; use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Workaround\Override\Fixture\Resolver; + +Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/products.php'); /** @var ObjectManagerInterface $objectManager */ $objectManager = Bootstrap::getObjectManager(); @@ -27,10 +29,12 @@ $quoteModel->setData(['store_id' => 1, 'is_active' => 1, 'is_multi_shipping' => 0]); $quote->save($quoteModel); -$quoteProduct = $product->load($product->getIdBySku('simple')); +/** @var ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->create(ProductRepositoryInterface::class); +$product = $productRepository->get('simple'); $quoteModel->setReservedOrderId('test_guest_order_with_gift_message') - ->addProduct($product->load($product->getIdBySku('simple')), 1); + ->addProduct($product, 1); $quoteModel->collectTotals(); $quote->save($quoteModel); @@ -45,7 +49,7 @@ $messageModel->setMessage('Gift Message Text'); $message->save($messageModel); -$quoteModel->getItemByProduct($quoteProduct)->setGiftMessageId($messageModel->getId()); +$quoteModel->getItemByProduct($product)->setGiftMessageId($messageModel->getId()); $quote->save($quoteModel); /** @var QuoteIdMaskResource $quoteIdMask */ From 7488a36001628ec19b364ad08f7886f65b172da9 Mon Sep 17 00:00:00 2001 From: eduard13 Date: Fri, 22 May 2020 10:28:49 +0300 Subject: [PATCH 08/27] Test coverage for Wishlist GraphQl --- ...Resolver.php => AddProductsToWishlist.php} | 10 +- ...ver.php => RemoveProductsFromWishlist.php} | 10 +- ...olver.php => UpdateProductsInWishlist.php} | 10 +- .../WishlistGraphQl/etc/schema.graphqls | 6 +- .../AddBundleProductToWishlistTest.php | 176 ++++++++++++++ .../AddConfigurableProductToWishlistTest.php | 222 ++++++++++++++++++ .../AddDownloadableProductToWishlistTest.php | 216 +++++++++++++++++ .../DeleteProductsFromWishlistTest.php | 147 ++++++++++++ .../GetCustomOptionsWithIDV2ForQueryBySku.php | 97 ++++++++ .../UpdateProductsFromWishlistTest.php | 159 +++++++++++++ 10 files changed, 1035 insertions(+), 18 deletions(-) rename app/code/Magento/WishlistGraphQl/Model/Resolver/{AddProductsToWishlistResolver.php => AddProductsToWishlist.php} (92%) rename app/code/Magento/WishlistGraphQl/Model/Resolver/{RemoveProductsFromWishlistResolver.php => RemoveProductsFromWishlist.php} (91%) rename app/code/Magento/WishlistGraphQl/Model/Resolver/{UpdateProductsInWishlistResolver.php => UpdateProductsInWishlist.php} (92%) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/AddBundleProductToWishlistTest.php create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/AddConfigurableProductToWishlistTest.php create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/AddDownloadableProductToWishlistTest.php create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/DeleteProductsFromWishlistTest.php create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/GetCustomOptionsWithIDV2ForQueryBySku.php create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/UpdateProductsFromWishlistTest.php diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlistResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlist.php similarity index 92% rename from app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlistResolver.php rename to app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlist.php index cdcffa8aa2adc..7c2e7c304c53d 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlistResolver.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlist.php @@ -13,7 +13,7 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Wishlist\Model\ResourceModel\Wishlist as WishlistResourceModel; -use Magento\Wishlist\Model\Wishlist\AddProductsToWishlist; +use Magento\Wishlist\Model\Wishlist\AddProductsToWishlist as AddProductsToWishlistModel; use Magento\Wishlist\Model\Wishlist\Config as WishlistConfig; use Magento\Wishlist\Model\Wishlist\Data\Error; use Magento\Wishlist\Model\Wishlist\Data\WishlistItemFactory; @@ -23,10 +23,10 @@ /** * Adding products to wishlist resolver */ -class AddProductsToWishlistResolver implements ResolverInterface +class AddProductsToWishlist implements ResolverInterface { /** - * @var AddProductsToWishlist + * @var AddProductsToWishlistModel */ private $addProductsToWishlist; @@ -54,14 +54,14 @@ class AddProductsToWishlistResolver implements ResolverInterface * @param WishlistResourceModel $wishlistResource * @param WishlistFactory $wishlistFactory * @param WishlistConfig $wishlistConfig - * @param AddProductsToWishlist $addProductsToWishlist + * @param AddProductsToWishlistModel $addProductsToWishlist * @param WishlistDataMapper $wishlistDataMapper */ public function __construct( WishlistResourceModel $wishlistResource, WishlistFactory $wishlistFactory, WishlistConfig $wishlistConfig, - AddProductsToWishlist $addProductsToWishlist, + AddProductsToWishlistModel $addProductsToWishlist, WishlistDataMapper $wishlistDataMapper ) { $this->wishlistResource = $wishlistResource; diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlistResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlist.php similarity index 91% rename from app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlistResolver.php rename to app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlist.php index 8c8d3aea54993..01e60c21190fe 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlistResolver.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlist.php @@ -15,14 +15,14 @@ use Magento\Wishlist\Model\ResourceModel\Wishlist as WishlistResourceModel; use Magento\Wishlist\Model\Wishlist\Config as WishlistConfig; use Magento\Wishlist\Model\Wishlist\Data\Error; -use Magento\Wishlist\Model\Wishlist\RemoveProductsFromWishlist; +use Magento\Wishlist\Model\Wishlist\RemoveProductsFromWishlist as RemoveProductsFromWishlistModel; use Magento\Wishlist\Model\WishlistFactory; use Magento\WishlistGraphQl\Mapper\WishlistDataMapper; /** * Removing products from wishlist resolver */ -class RemoveProductsFromWishlistResolver implements ResolverInterface +class RemoveProductsFromWishlist implements ResolverInterface { /** * @var WishlistDataMapper @@ -30,7 +30,7 @@ class RemoveProductsFromWishlistResolver implements ResolverInterface private $wishlistDataMapper; /** - * @var RemoveProductsFromWishlist + * @var RemoveProductsFromWishlistModel */ private $removeProductsFromWishlist; @@ -54,14 +54,14 @@ class RemoveProductsFromWishlistResolver implements ResolverInterface * @param WishlistResourceModel $wishlistResource * @param WishlistConfig $wishlistConfig * @param WishlistDataMapper $wishlistDataMapper - * @param RemoveProductsFromWishlist $removeProductsFromWishlist + * @param RemoveProductsFromWishlistModel $removeProductsFromWishlist */ public function __construct( WishlistFactory $wishlistFactory, WishlistResourceModel $wishlistResource, WishlistConfig $wishlistConfig, WishlistDataMapper $wishlistDataMapper, - RemoveProductsFromWishlist $removeProductsFromWishlist + RemoveProductsFromWishlistModel $removeProductsFromWishlist ) { $this->wishlistResource = $wishlistResource; $this->wishlistConfig = $wishlistConfig; diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlistResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlist.php similarity index 92% rename from app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlistResolver.php rename to app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlist.php index 6ce074b3e8dc2..e8483cf6391b6 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlistResolver.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlist.php @@ -16,17 +16,17 @@ use Magento\Wishlist\Model\Wishlist\Config as WishlistConfig; use Magento\Wishlist\Model\Wishlist\Data\Error; use Magento\Wishlist\Model\Wishlist\Data\WishlistItemFactory; -use Magento\Wishlist\Model\Wishlist\UpdateProductsInWishlist; +use Magento\Wishlist\Model\Wishlist\UpdateProductsInWishlist as UpdateProductsInWishlistModel; use Magento\Wishlist\Model\WishlistFactory; use Magento\WishlistGraphQl\Mapper\WishlistDataMapper; /** * Update wishlist items resolver */ -class UpdateProductsInWishlistResolver implements ResolverInterface +class UpdateProductsInWishlist implements ResolverInterface { /** - * @var UpdateProductsInWishlist + * @var UpdateProductsInWishlistModel */ private $updateProductsInWishlist; @@ -54,14 +54,14 @@ class UpdateProductsInWishlistResolver implements ResolverInterface * @param WishlistResourceModel $wishlistResource * @param WishlistFactory $wishlistFactory * @param WishlistConfig $wishlistConfig - * @param UpdateProductsInWishlist $updateProductsInWishlist + * @param UpdateProductsInWishlistModel $updateProductsInWishlist * @param WishlistDataMapper $wishlistDataMapper */ public function __construct( WishlistResourceModel $wishlistResource, WishlistFactory $wishlistFactory, WishlistConfig $wishlistConfig, - UpdateProductsInWishlist $updateProductsInWishlist, + UpdateProductsInWishlistModel $updateProductsInWishlist, WishlistDataMapper $wishlistDataMapper ) { $this->wishlistResource = $wishlistResource; diff --git a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls index 1fcfc3b9488af..d7a22a52ee1d2 100644 --- a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls +++ b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls @@ -34,9 +34,9 @@ type WishlistItem { } type Mutation { - addProductsToWishlist(wishlist_id: ID!, wishlist_items: [WishlistItemInput!]!): AddProductsToWishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\AddProductsToWishlistResolver") - removeProductsFromWishlist(wishlist_id: ID!, wishlist_items_ids: [ID!]!): RemoveProductsFromWishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\RemoveProductsFromWishlistResolver") - updateProductsInWishlist(wishlist_id: ID!, wishlist_items: [WishlistItemUpdateInput!]!): UpdateProductsInWishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\UpdateProductsInWishlistResolver") + addProductsToWishlist(wishlist_id: ID!, wishlist_items: [WishlistItemInput!]!): AddProductsToWishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\AddProductsToWishlist") + removeProductsFromWishlist(wishlist_id: ID!, wishlist_items_ids: [ID!]!): RemoveProductsFromWishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\RemoveProductsFromWishlist") + updateProductsInWishlist(wishlist_id: ID!, wishlist_items: [WishlistItemUpdateInput!]!): UpdateProductsInWishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\UpdateProductsInWishlist") } input WishlistItemInput { diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/AddBundleProductToWishlistTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/AddBundleProductToWishlistTest.php new file mode 100644 index 0000000000000..f0862feed42ca --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/AddBundleProductToWishlistTest.php @@ -0,0 +1,176 @@ +customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class); + $this->wishlistFactory = $objectManager->get(WishlistFactory::class); + $this->productRepository = $objectManager->get(ProductRepositoryInterface::class); + } + + /** + * @magentoConfigFixture default_store wishlist/general/active 1 + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/Bundle/_files/product_1.php + * + * @throws Exception + */ + public function testAddBundleProductWithOptions(): void + { + $sku = 'bundle-product'; + $product = $this->productRepository->get($sku); + $customerId = 1; + $qty = 2; + $optionQty = 1; + + /** @var Type $typeInstance */ + $typeInstance = $product->getTypeInstance(); + $typeInstance->setStoreFilter($product->getStoreId(), $product); + /** @var Option $option */ + $option = $typeInstance->getOptionsCollection($product)->getFirstItem(); + /** @var Product $selection */ + $selection = $typeInstance->getSelectionsCollection([$option->getId()], $product)->getFirstItem(); + $optionId = $option->getId(); + $selectionId = $selection->getSelectionId(); + $bundleOptions = $this->generateBundleOptionIdV2((int) $optionId, (int) $selectionId, $optionQty); + + $query = $this->getQuery($sku, $qty, $bundleOptions); + $response = $this->graphQlMutation($query, [], '', $this->getHeaderMap()); + $wishlist = $this->wishlistFactory->create()->loadByCustomerId($customerId, true); + /** @var Item $item */ + $item = $wishlist->getItemCollection()->getFirstItem(); + + $this->assertArrayHasKey('addProductsToWishlist', $response); + $this->assertArrayHasKey('wishlist', $response['addProductsToWishlist']); + $response = $response['addProductsToWishlist']['wishlist']; + $this->assertEquals($wishlist->getItemsCount(), $response['items_count']); + $this->assertEquals($wishlist->getSharingCode(), $response['sharing_code']); + $this->assertEquals($wishlist->getUpdatedAt(), $response['updated_at']); + $this->assertEquals($item->getData('qty'), $response['items'][0]['qty']); + $this->assertEquals($item->getDescription(), $response['items'][0]['description']); + $this->assertEquals($item->getAddedAt(), $response['items'][0]['added_at']); + } + + /** + * Authentication header map + * + * @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); + + return ['Authorization' => 'Bearer ' . $customerToken]; + } + + /** + * Returns GraphQl mutation string + * + * @param string $sku + * @param int $qty + * @param string $bundleOptions + * @param int $wishlistId + * + * @return string + */ + private function getQuery( + string $sku, + int $qty, + string $bundleOptions, + int $wishlistId = 0 + ): string { + return <<customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class); + $this->wishlistFactory = $objectManager->get(WishlistFactory::class); + } + + /** + * @magentoConfigFixture default_store wishlist/general/active 1 + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php + * + * @throws Exception + */ + public function testAddDownloadableProductWithOptions(): void + { + $product = $this->getConfigurableProductInfo(); + $customerId = 1; + $qty = 2; + $attributeId = (int) $product['configurable_options'][0]['attribute_id']; + $valueIndex = $product['configurable_options'][0]['values'][0]['value_index']; + $childSku = $product['variants'][0]['product']['sku']; + $parentSku = $product['sku']; + $selectedConfigurableOptionsQuery = $this->generateSuperAttributesIdV2Query($attributeId, $valueIndex); + + $query = $this->getQuery($parentSku, $childSku, $qty, $selectedConfigurableOptionsQuery); + + $response = $this->graphQlMutation($query, [], '', $this->getHeadersMap()); + $wishlist = $this->wishlistFactory->create()->loadByCustomerId($customerId, true); + /** @var Item $wishlistItem */ + $wishlistItem = $wishlist->getItemCollection()->getFirstItem(); + + self::assertArrayHasKey('addProductsToWishlist', $response); + self::assertArrayHasKey('wishlist', $response['addProductsToWishlist']); + $wishlistResponse = $response['addProductsToWishlist']['wishlist']; + self::assertEquals($wishlist->getItemsCount(), $wishlistResponse['items_count']); + self::assertEquals($wishlist->getSharingCode(), $wishlistResponse['sharing_code']); + self::assertEquals($wishlist->getUpdatedAt(), $wishlistResponse['updated_at']); + self::assertEquals($wishlistItem->getId(), $wishlistResponse['items'][0]['id']); + self::assertEquals($wishlistItem->getData('qty'), $wishlistResponse['items'][0]['qty']); + self::assertEquals($wishlistItem->getDescription(), $wishlistResponse['items'][0]['description']); + self::assertEquals($wishlistItem->getAddedAt(), $wishlistResponse['items'][0]['added_at']); + } + + /** + * Authentication header map + * + * @param string $username + * @param string $password + * + * @return array + * + * @throws AuthenticationException + */ + private function getHeadersMap(string $username = 'customer@example.com', string $password = 'password'): array + { + $customerToken = $this->customerTokenService->createCustomerAccessToken($username, $password); + + return ['Authorization' => 'Bearer ' . $customerToken]; + } + + /** + * Returns GraphQl mutation string + * + * @param string $parentSku + * @param string $childSku + * @param int $qty + * @param string $customizableOptions + * @param int $wishlistId + * + * @return string + */ + private function getQuery( + string $parentSku, + string $childSku, + int $qty, + string $customizableOptions, + int $wishlistId = 0 + ): string { + return <<graphQlQuery($this->getFetchProductQuery('configurable')); + + return current($searchResponse['products']['items']); + } + + /** + * Returns GraphQl query for fetching configurable product information + * + * @param string $term + * + * @return string + */ + private function getFetchProductQuery(string $term): string + { + return <<objectManager = Bootstrap::getObjectManager(); + $this->customerTokenService = $this->objectManager->get(CustomerTokenServiceInterface::class); + $this->wishlistFactory = $this->objectManager->get(WishlistFactory::class); + $this->getCustomOptionsWithIDV2ForQueryBySku = + $this->objectManager->get(GetCustomOptionsWithIDV2ForQueryBySku::class); + } + + /** + * @magentoConfigFixture default_store wishlist/general/active 1 + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable_with_custom_options.php + */ + public function testAddDownloadableProductWithOptions(): void + { + $customerId = 1; + $sku = 'downloadable-product-with-purchased-separately-links'; + $qty = 2; + $links = $this->getProductsLinks($sku); + $linkId = key($links); + $itemOptions = $this->getCustomOptionsWithIDV2ForQueryBySku->execute($sku); + $itemOptions['selected_options'][] = $this->generateProductLinkSelectedOptions($linkId); + $productOptionsQuery = preg_replace( + '/"([^"]+)"\s*:\s*/', + '$1:', + json_encode($itemOptions) + ); + $query = $this->getQuery($qty, $sku, trim($productOptionsQuery, '{}')); + $response = $this->graphQlMutation($query, [], '', $this->getHeaderMap()); + $wishlist = $this->wishlistFactory->create(); + $wishlist->loadByCustomerId($customerId, true); + /** @var Item $wishlistItem */ + $wishlistItem = $wishlist->getItemCollection()->getFirstItem(); + + self::assertArrayHasKey('addProductsToWishlist', $response); + self::assertArrayHasKey('wishlist', $response['addProductsToWishlist']); + $wishlistResponse = $response['addProductsToWishlist']['wishlist']; + self::assertEquals($wishlist->getItemsCount(), $wishlistResponse['items_count']); + self::assertEquals($wishlist->getSharingCode(), $wishlistResponse['sharing_code']); + self::assertEquals($wishlist->getUpdatedAt(), $wishlistResponse['updated_at']); + self::assertEquals($wishlistItem->getId(), $wishlistResponse['items'][0]['id']); + self::assertEquals($wishlistItem->getData('qty'), $wishlistResponse['items'][0]['qty']); + self::assertEquals($wishlistItem->getDescription(), $wishlistResponse['items'][0]['description']); + self::assertEquals($wishlistItem->getAddedAt(), $wishlistResponse['items'][0]['added_at']); + } + + /** + * @magentoConfigFixture default_store wishlist/general/active 0 + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable_with_custom_options.php + */ + public function testAddDownloadableProductOnDisabledWishlist(): void + { + $qty = 2; + $sku = 'downloadable-product-with-purchased-separately-links'; + $links = $this->getProductsLinks($sku); + $linkId = key($links); + $itemOptions = $this->getCustomOptionsWithIDV2ForQueryBySku->execute($sku); + $itemOptions['selected_options'][] = $this->generateProductLinkSelectedOptions($linkId); + $productOptionsQuery = trim(preg_replace( + '/"([^"]+)"\s*:\s*/', + '$1:', + json_encode($itemOptions) + ), '{}'); + $query = $this->getQuery($qty, $sku, $productOptionsQuery); + $this->expectExceptionMessage('The wishlist is not currently available.'); + $this->graphQlMutation($query, [], '', $this->getHeaderMap()); + } + + /** + * Function returns array of all product's links + * + * @param string $sku + * + * @return array + */ + private function getProductsLinks(string $sku): array + { + $result = []; + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + $product = $productRepository->get($sku, false, null, true); + + foreach ($product->getDownloadableLinks() as $linkObject) { + $result[$linkObject->getLinkId()] = [ + 'title' => $linkObject->getTitle(), + 'price' => $linkObject->getPrice(), + ]; + } + + return $result; + } + + /** + * Authentication header map + * + * @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); + + return ['Authorization' => 'Bearer ' . $customerToken]; + } + + /** + * Returns GraphQl mutation string + * + * @param int $qty + * @param string $sku + * @param string $customizableOptions + * + * @return string + */ + private function getQuery( + int $qty, + string $sku, + string $customizableOptions + ): string { + return <<customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class); + } + + /** + * @magentoConfigFixture default_store wishlist/general/active 1 + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/Wishlist/_files/wishlist_with_simple_product.php + */ + public function testDeleteWishlistItemFromWishlist(): void + { + $wishlist = $this->getWishlist(); + $wishlistId = $wishlist['customer']['wishlist']['id']; + $wishlist = $wishlist['customer']['wishlist']; + $wishlistItems = $wishlist['items']; + self::assertEquals(1, $wishlist['items_count']); + + $query = $this->getQuery((int) $wishlistId, (int) $wishlistItems[0]['id']); + $response = $this->graphQlMutation($query, [], '', $this->getHeaderMap()); + + self::assertArrayHasKey('removeProductsFromWishlist', $response); + self::assertArrayHasKey('wishlist', $response['removeProductsFromWishlist']); + $wishlistResponse = $response['removeProductsFromWishlist']['wishlist']; + self::assertEquals(0, $wishlistResponse['items_count']); + self::assertEmpty($wishlistResponse['items']); + } + + /** + * Authentication header map + * + * @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); + + return ['Authorization' => 'Bearer ' . $customerToken]; + } + + /** + * Returns GraphQl mutation string + * + * @param int $wishlistId + * @param int $wishlistItemId + * + * @return string + */ + private function getQuery( + int $wishlistId, + int $wishlistItemId + ): string { + return <<graphQlQuery($this->getCustomerWishlistQuery(), [], '', $this->getHeaderMap()); + } + + /** + * Get customer wishlist query + * + * @return string + */ + private function getCustomerWishlistQuery(): string + { + return <<productCustomOptionRepository = $productCustomOptionRepository; + } + + /** + * Returns array of custom options for the product + * + * @param string $sku + * + * @return array + */ + public function execute(string $sku): array + { + $customOptions = $this->productCustomOptionRepository->getList($sku); + $selectedOptions = []; + $enteredOptions = []; + + foreach ($customOptions as $customOption) { + $optionType = $customOption->getType(); + + if ($optionType === 'field' || $optionType === 'area' || $optionType === 'date') { + $enteredOptions[] = [ + 'id' => $this->encodeEnteredOption((int)$customOption->getOptionId()), + 'value' => '2012-12-12' + ]; + } elseif ($optionType === 'drop_down') { + $optionSelectValues = $customOption->getValues(); + $selectedOptions[] = $this->encodeSelectedOption( + (int)$customOption->getOptionId(), + (int)reset($optionSelectValues)->getOptionTypeId() + ); + } elseif ($optionType === 'multiple') { + foreach ($customOption->getValues() as $optionValue) { + $selectedOptions[] = $this->encodeSelectedOption( + (int)$customOption->getOptionId(), + (int)$optionValue->getOptionTypeId() + ); + } + } + } + + return [ + 'selected_options' => $selectedOptions, + 'entered_options' => $enteredOptions + ]; + } + + /** + * Returns id_v2 of the selected custom option + * + * @param int $optionId + * @param int $optionValueId + * + * @return string + */ + private function encodeSelectedOption(int $optionId, int $optionValueId): string + { + return base64_encode("custom-option/$optionId/$optionValueId"); + } + + /** + * Returns id_v2 of the entered custom option + * + * @param int $optionId + * + * @return string + */ + private function encodeEnteredOption(int $optionId): string + { + return base64_encode("custom-option/$optionId"); + } +} diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/UpdateProductsFromWishlistTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/UpdateProductsFromWishlistTest.php new file mode 100644 index 0000000000000..2bd1f8bab4b1a --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/UpdateProductsFromWishlistTest.php @@ -0,0 +1,159 @@ +customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class); + } + + /** + * @magentoConfigFixture default_store wishlist/general/active 1 + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/Wishlist/_files/wishlist_with_simple_product.php + */ + public function testUpdateSimpleProductFromWishlist(): void + { + $wishlist = $this->getWishlist(); + $qty = 5; + $description = 'New Description'; + $wishlistId = $wishlist['customer']['wishlist']['id']; + $wishlistItem = $wishlist['customer']['wishlist']['items'][0]; + self::assertNotEquals($description, $wishlistItem['description']); + self::assertNotEquals($qty, $wishlistItem['qty']); + + $query = $this->getQuery((int) $wishlistId, (int) $wishlistItem['id'], $qty, $description); + $response = $this->graphQlMutation($query, [], '', $this->getHeaderMap()); + + self::assertArrayHasKey('updateProductsInWishlist', $response); + self::assertArrayHasKey('wishlist', $response['updateProductsInWishlist']); + $wishlistResponse = $response['updateProductsInWishlist']['wishlist']; + self::assertEquals($qty, $wishlistResponse['items'][0]['qty']); + self::assertEquals($description, $wishlistResponse['items'][0]['description']); + } + + /** + * Authentication header map + * + * @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); + + return ['Authorization' => 'Bearer ' . $customerToken]; + } + + /** + * Returns GraphQl mutation string + * + * @param int $wishlistId + * @param int $wishlistItemId + * @param int $qty + * @param string $description + * + * @return string + */ + private function getQuery( + int $wishlistId, + int $wishlistItemId, + int $qty, + string $description + ): string { + return <<graphQlQuery($this->getCustomerWishlistQuery(), [], '', $this->getHeaderMap()); + } + + /** + * Get customer wishlist query + * + * @return string + */ + private function getCustomerWishlistQuery(): string + { + return << Date: Fri, 22 May 2020 15:38:02 +0300 Subject: [PATCH 09/27] Added test and minor fix --- .../CartItem/DataProvider/UpdateCartItems.php | 3 + .../Quote/Guest/UpdateCartItemsTest.php | 78 ++++++++++++++++++- 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/UpdateCartItems.php b/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/UpdateCartItems.php index 5657e5f4587ec..8d98ec039dc94 100644 --- a/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/UpdateCartItems.php +++ b/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/UpdateCartItems.php @@ -64,8 +64,11 @@ public function __construct( * * @param Quote $cart * @param array $items + * * @throws GraphQlInputException * @throws LocalizedException + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) */ public function processCartItems(Quote $cart, array $items): void { 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 a17bc1aa3821a..f6b8cb6198bec 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 @@ -7,8 +7,9 @@ namespace Magento\GraphQl\Quote\Guest; -use Magento\Quote\Model\QuoteFactory; +use Exception; use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Quote\Model\QuoteFactory; use Magento\Quote\Model\QuoteIdToMaskedQuoteIdInterface; use Magento\Quote\Model\ResourceModel\Quote as QuoteResource; use Magento\TestFramework\Helper\Bootstrap; @@ -273,6 +274,81 @@ private function getCartQuery(string $maskedQuoteId) } } } +QUERY; + } + + /** + * @magentoConfigFixture default_store sales/gift_options/allow_items 1 + * @magentoApiDataFixture Magento/GiftMessage/_files/guest/quote_with_item_message.php + * @throws Exception + */ + public function testUpdateGiftMessageCartForItem() + { + $query = $this->getUpdateGiftMessageQuery(); + foreach ($this->graphQlMutation($query)['updateCartItems']['cart']['items'] as $item) { + self::assertArrayHasKey('gift_message', $item); + self::assertSame('Alex', $item['gift_message']['to']); + self::assertSame('Mike', $item['gift_message']['from']); + self::assertSame('Best regards.', $item['gift_message']['message']); + } + } + + /** + * @magentoConfigFixture default_store sales/gift_options/allow_items 0 + * @magentoApiDataFixture Magento/GiftMessage/_files/guest/quote_with_item_message.php + * @throws Exception + */ + public function testUpdateGiftMessageCartForItemNotAllow() + { + $query = $this->getUpdateGiftMessageQuery(); + foreach ($this->graphQlMutation($query)['updateCartItems']['cart']['items'] as $item) { + self::assertNull($item['gift_message']); + } + } + + private function getUpdateGiftMessageQuery() + { + $quote = $this->quoteFactory->create(); + $this->quoteResource->load($quote, 'test_guest_order_with_gift_message', 'reserved_order_id'); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$quote->getId()); + $itemId = (int)$quote->getItemByProduct($this->productRepository->get('simple'))->getId(); + + return << Date: Fri, 22 May 2020 18:34:20 +0300 Subject: [PATCH 10/27] Remove EE type from CA schema --- app/code/Magento/GiftMessageGraphQl/etc/schema.graphqls | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/code/Magento/GiftMessageGraphQl/etc/schema.graphqls b/app/code/Magento/GiftMessageGraphQl/etc/schema.graphqls index 053d2f2e8e8f0..0ca69a19b711c 100644 --- a/app/code/Magento/GiftMessageGraphQl/etc/schema.graphqls +++ b/app/code/Magento/GiftMessageGraphQl/etc/schema.graphqls @@ -22,10 +22,6 @@ type BundleCartItem { gift_message: GiftMessage @resolver (class: "\\Magento\\GiftMessageGraphQl\\Model\\Resolver\\Cart\\Item\\GiftMessage") @doc(description: "The entered gift message for the cart item") } -type GiftCardCartItem { - gift_message: GiftMessage @resolver (class: "\\Magento\\GiftMessageGraphQl\\Model\\Resolver\\Cart\\Item\\GiftMessage") @doc(description: "The entered gift message for the cart item") -} - type GiftMessage { to: String! @doc(description: "Recepient name") from: String! @doc(description: "Sender name") From 28b1d020546d8e3b1dd8297236b199686d8767fa Mon Sep 17 00:00:00 2001 From: eduard13 Date: Mon, 25 May 2020 13:12:31 +0300 Subject: [PATCH 11/27] Implementing Todos and adjusting the tests --- .../Model/Wishlist/AddProductsToWishlist.php | 4 ++- .../Wishlist/RemoveProductsFromWishlist.php | 2 ++ .../Wishlist/UpdateProductsInWishlist.php | 4 ++- .../Resolver/CustomerWishlistResolver.php | 17 ++++++++-- .../Model/Resolver/WishlistResolver.php | 17 ++++++++-- .../GraphQl/Wishlist/CustomerWishlistTest.php | 32 +++++++++++++++++++ .../Magento/GraphQl/Wishlist/WishlistTest.php | 2 ++ 7 files changed, 72 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Wishlist/Model/Wishlist/AddProductsToWishlist.php b/app/code/Magento/Wishlist/Model/Wishlist/AddProductsToWishlist.php index 6700f1585acb4..7acfb503a5ad0 100644 --- a/app/code/Magento/Wishlist/Model/Wishlist/AddProductsToWishlist.php +++ b/app/code/Magento/Wishlist/Model/Wishlist/AddProductsToWishlist.php @@ -94,8 +94,10 @@ public function execute(Wishlist $wishlist, array $wishlistItems): WishlistOutpu * * @param Wishlist $wishlist * @param WishlistItem $wishlistItem + * + * @return void */ - private function addItemToWishlist(Wishlist $wishlist, WishlistItem $wishlistItem) + private function addItemToWishlist(Wishlist $wishlist, WishlistItem $wishlistItem): void { $sku = $wishlistItem->getParentSku() ?? $wishlistItem->getSku(); diff --git a/app/code/Magento/Wishlist/Model/Wishlist/RemoveProductsFromWishlist.php b/app/code/Magento/Wishlist/Model/Wishlist/RemoveProductsFromWishlist.php index c213c048fd61a..d143830064752 100644 --- a/app/code/Magento/Wishlist/Model/Wishlist/RemoveProductsFromWishlist.php +++ b/app/code/Magento/Wishlist/Model/Wishlist/RemoveProductsFromWishlist.php @@ -73,6 +73,8 @@ public function execute(Wishlist $wishlist, array $wishlistItemsIds): WishlistOu * Remove product item from wishlist * * @param int $wishlistItemId + * + * @return void */ private function removeItemFromWishlist(int $wishlistItemId): void { diff --git a/app/code/Magento/Wishlist/Model/Wishlist/UpdateProductsInWishlist.php b/app/code/Magento/Wishlist/Model/Wishlist/UpdateProductsInWishlist.php index 691e00090373a..4abcada138362 100644 --- a/app/code/Magento/Wishlist/Model/Wishlist/UpdateProductsInWishlist.php +++ b/app/code/Magento/Wishlist/Model/Wishlist/UpdateProductsInWishlist.php @@ -84,8 +84,10 @@ public function execute(Wishlist $wishlist, array $wishlistItems): WishlistOutpu * * @param Wishlist $wishlist * @param WishlistItemData $wishlistItemData + * + * @return void */ - private function updateItemInWishlist(Wishlist $wishlist, WishlistItemData $wishlistItemData) + private function updateItemInWishlist(Wishlist $wishlist, WishlistItemData $wishlistItemData): void { try { $options = $this->buyRequestBuilder->build($wishlistItemData); diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/CustomerWishlistResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/CustomerWishlistResolver.php index 94d543d25aa7a..cad574ef56ed2 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/CustomerWishlistResolver.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/CustomerWishlistResolver.php @@ -9,9 +9,11 @@ use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Wishlist\Model\Wishlist; +use Magento\Wishlist\Model\Wishlist\Config as WishlistConfig; use Magento\Wishlist\Model\WishlistFactory; /** @@ -24,13 +26,21 @@ class CustomerWishlistResolver implements ResolverInterface */ private $wishlistFactory; + /** + * @var WishlistConfig + */ + private $wishlistConfig; + /** * @param WishlistFactory $wishlistFactory + * @param WishlistConfig $wishlistConfig */ public function __construct( - WishlistFactory $wishlistFactory + WishlistFactory $wishlistFactory, + WishlistConfig $wishlistConfig ) { $this->wishlistFactory = $wishlistFactory; + $this->wishlistConfig = $wishlistConfig; } /** @@ -43,7 +53,10 @@ public function resolve( array $value = null, array $args = null ) { - // Todo: Check if wishlist is enabled + if (!$this->wishlistConfig->isEnabled()) { + throw new GraphQlInputException(__('The wishlist is not currently available.')); + } + if (false === $context->getExtensionAttributes()->getIsCustomer()) { throw new GraphQlAuthorizationException(__('The current customer isn\'t authorized.')); } diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php index d0d409abd1698..09c0a8a935a6c 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php @@ -8,10 +8,12 @@ namespace Magento\WishlistGraphQl\Model\Resolver; use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Wishlist\Model\ResourceModel\Wishlist as WishlistResourceModel; use Magento\Wishlist\Model\Wishlist; +use Magento\Wishlist\Model\Wishlist\Config as WishlistConfig; use Magento\Wishlist\Model\WishlistFactory; use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; @@ -30,16 +32,24 @@ class WishlistResolver implements ResolverInterface */ private $wishlistFactory; + /** + * @var WishlistConfig + */ + private $wishlistConfig; + /** * @param WishlistResourceModel $wishlistResource * @param WishlistFactory $wishlistFactory + * @param WishlistConfig $wishlistConfig */ public function __construct( WishlistResourceModel $wishlistResource, - WishlistFactory $wishlistFactory + WishlistFactory $wishlistFactory, + WishlistConfig $wishlistConfig ) { $this->wishlistResource = $wishlistResource; $this->wishlistFactory = $wishlistFactory; + $this->wishlistConfig = $wishlistConfig; } /** @@ -52,7 +62,10 @@ public function resolve( array $value = null, array $args = null ) { - // Todo: Check if wishlist is enabled + if (!$this->wishlistConfig->isEnabled()) { + throw new GraphQlInputException(__('The wishlist is not currently available.')); + } + $customerId = $context->getUserId(); /* Guest checking */ diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/CustomerWishlistTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/CustomerWishlistTest.php index 2208f904320d9..0a8e1757a2ce2 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/CustomerWishlistTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/CustomerWishlistTest.php @@ -32,6 +32,7 @@ protected function setUp(): void } /** + * @magentoConfigFixture default_store wishlist/general/active 1 * @magentoApiDataFixture Magento/Wishlist/_files/wishlist.php */ public function testCustomerWishlist(): void @@ -74,6 +75,7 @@ public function testCustomerWishlist(): void } /** + * @magentoConfigFixture default_store wishlist/general/active 1 * @magentoApiDataFixture Magento/Customer/_files/customer.php */ public function testCustomerAlwaysHasWishlist(): void @@ -100,6 +102,7 @@ public function testCustomerAlwaysHasWishlist(): void } /** + * @magentoConfigFixture default_store wishlist/general/active 1 */ public function testGuestCannotGetWishlist() { @@ -121,6 +124,35 @@ public function testGuestCannotGetWishlist() $this->graphQlQuery($query); } + /** + * @magentoConfigFixture default_store wishlist/general/active 0 + * @magentoApiDataFixture Magento/Customer/_files/customer.php + */ + public function testCustomerCannotGetWishlistWhenDisabled() + { + $this->expectException(\Exception::class); + $this->expectExceptionMessage('The wishlist is not currently available.'); + + $query = + <<graphQlQuery( + $query, + [], + '', + $this->getCustomerAuthHeaders('customer@example.com', 'password') + ); + } + /** * @param string $email * @param string $password diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/WishlistTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/WishlistTest.php index bb353938239bc..88c59d6dd8428 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/WishlistTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/WishlistTest.php @@ -39,6 +39,7 @@ protected function setUp(): void } /** + * @magentoConfigFixture default_store wishlist/general/active 1 * @magentoApiDataFixture Magento/Wishlist/_files/wishlist.php */ public function testGetCustomerWishlist(): void @@ -94,6 +95,7 @@ public function testGetCustomerWishlist(): void } /** + * @magentoConfigFixture default_store wishlist/general/active 1 */ public function testGetGuestWishlist() { From 58215aafb22108ecc30337a87ccf80fd1ecb0270 Mon Sep 17 00:00:00 2001 From: eduard13 Date: Tue, 26 May 2020 08:45:07 +0300 Subject: [PATCH 12/27] Fixing Unit Test --- .../Test/Unit/CustomerWishlistResolverTest.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/WishlistGraphQl/Test/Unit/CustomerWishlistResolverTest.php b/app/code/Magento/WishlistGraphQl/Test/Unit/CustomerWishlistResolverTest.php index 8385d3ca852a4..d8d4545661978 100644 --- a/app/code/Magento/WishlistGraphQl/Test/Unit/CustomerWishlistResolverTest.php +++ b/app/code/Magento/WishlistGraphQl/Test/Unit/CustomerWishlistResolverTest.php @@ -14,6 +14,7 @@ use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\GraphQl\Model\Query\ContextExtensionInterface; use Magento\Wishlist\Model\Wishlist; +use Magento\Wishlist\Model\Wishlist\Config; use Magento\Wishlist\Model\WishlistFactory; use Magento\WishlistGraphQl\Model\Resolver\CustomerWishlistResolver; use PHPUnit\Framework\MockObject\MockObject; @@ -48,6 +49,11 @@ class CustomerWishlistResolverTest extends TestCase */ private $resolver; + /** + * @var Config|MockObject + */ + private $wishlistConfigMock; + /** * Build the Testing Environment */ @@ -74,9 +80,14 @@ protected function setUp(): void ->setMethods(['loadByCustomerId', 'getId', 'getSharingCode', 'getUpdatedAt', 'getItemsCount']) ->getMock(); + $this->wishlistConfigMock = $this->createMock(Config::class); + + $this->wishlistConfigMock = $this->getMockClass(); + $objectManager = new ObjectManager($this); $this->resolver = $objectManager->getObject(CustomerWishlistResolver::class, [ - 'wishlistFactory' => $this->wishlistFactoryMock + 'wishlistFactory' => $this->wishlistFactoryMock, + 'wishlistConfig' => $this->wishlistConfigMock ]); } @@ -85,6 +96,8 @@ protected function setUp(): void */ public function testThrowExceptionWhenUserNotAuthorized(): void { + $this->wishlistConfigMock->method('isEnabled')->willReturn(true); + // Given $this->extensionAttributesMock->method('getIsCustomer') ->willReturn(false); @@ -107,6 +120,8 @@ public function testThrowExceptionWhenUserNotAuthorized(): void */ public function testFactoryCreatesWishlistByAuthorizedCustomerId(): void { + $this->wishlistConfigMock->method('isEnabled')->willReturn(true); + // Given $this->extensionAttributesMock->method('getIsCustomer') ->willReturn(true); From 73650e3c4259dfe1c2bb29daa29d55cbc6462682 Mon Sep 17 00:00:00 2001 From: eduard13 Date: Tue, 26 May 2020 09:30:01 +0300 Subject: [PATCH 13/27] Fixing Unit Test --- .../WishlistGraphQl/Test/Unit/CustomerWishlistResolverTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/code/Magento/WishlistGraphQl/Test/Unit/CustomerWishlistResolverTest.php b/app/code/Magento/WishlistGraphQl/Test/Unit/CustomerWishlistResolverTest.php index d8d4545661978..017462b4c94c6 100644 --- a/app/code/Magento/WishlistGraphQl/Test/Unit/CustomerWishlistResolverTest.php +++ b/app/code/Magento/WishlistGraphQl/Test/Unit/CustomerWishlistResolverTest.php @@ -82,8 +82,6 @@ protected function setUp(): void $this->wishlistConfigMock = $this->createMock(Config::class); - $this->wishlistConfigMock = $this->getMockClass(); - $objectManager = new ObjectManager($this); $this->resolver = $objectManager->getObject(CustomerWishlistResolver::class, [ 'wishlistFactory' => $this->wishlistFactoryMock, From a5cc7903b1eeda59df56bb3683d2823fc7c880ad Mon Sep 17 00:00:00 2001 From: eduard13 Date: Tue, 2 Jun 2020 10:26:53 +0300 Subject: [PATCH 14/27] Improving checking the customer wishlist --- .../Model/Resolver/AddProductsToWishlist.php | 6 +++--- .../Resolver/RemoveProductsFromWishlist.php | 18 +++++++++++------- .../Resolver/UpdateProductsInWishlist.php | 15 ++++++++------- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlist.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlist.php index 7c2e7c304c53d..5a44242bdcd24 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlist.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlist.php @@ -88,7 +88,7 @@ public function resolve( $customerId = $context->getUserId(); /* Guest checking */ - if (!$customerId && 0 === $customerId) { + if (null === $customerId || 0 === $customerId) { throw new GraphQlAuthorizationException(__('The current user cannot perform operations on wishlist')); } @@ -102,8 +102,8 @@ public function resolve( $wishlist->loadByCustomerId($customerId, true); } - if (null === $wishlist->getId()) { - throw new GraphQlInputException(__('Something went wrong while creating the wishlist')); + if (null === $wishlist->getId() || $customerId !== (int) $wishlist->getCustomerId()) { + throw new GraphQlInputException(__('The wishlist was not found.')); } $wishlistItems = []; diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlist.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlist.php index 01e60c21190fe..d493c08dfb671 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlist.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlist.php @@ -87,20 +87,24 @@ public function resolve( $customerId = $context->getUserId(); /* Guest checking */ - if (!$customerId && 0 === $customerId) { + if (null === $customerId || 0 === $customerId) { throw new GraphQlAuthorizationException(__('The current user cannot perform operations on wishlist')); } - $wishlistId = $args['wishlist_id']; + $wishlistId = $args['wishlist_id'] ?: null; + $wishlist = $this->wishlistFactory->create(); - if (!$wishlistId) { - throw new GraphQlInputException(__('The wishlist id is missing.')); + if ($wishlistId) { + $this->wishlistResource->load($wishlist, $wishlistId); + } elseif ($customerId) { + $wishlist->loadByCustomerId($customerId, true); } - $wishlist = $this->wishlistFactory->create(); - $this->wishlistResource->load($wishlist, $wishlistId); + if ($wishlistId) { + $this->wishlistResource->load($wishlist, $wishlistId); + } - if (!$wishlist) { + if (null === $wishlist->getId() || $customerId !== (int) $wishlist->getCustomerId()) { throw new GraphQlInputException(__('The wishlist was not found.')); } diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlist.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlist.php index e8483cf6391b6..8a0411e71642f 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlist.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlist.php @@ -88,23 +88,24 @@ public function resolve( $customerId = $context->getUserId(); /* Guest checking */ - if (!$customerId && 0 === $customerId) { + if (null === $customerId || 0 === $customerId) { throw new GraphQlAuthorizationException(__('The current user cannot perform operations on wishlist')); } - $wishlistId = $args['wishlist_id']; + $wishlistId = $args['wishlist_id'] ?: null; + $wishlist = $this->wishlistFactory->create(); - if (!$wishlistId) { - throw new GraphQlInputException(__('The wishlist id is missing.')); + if ($wishlistId) { + $this->wishlistResource->load($wishlist, $wishlistId); + } elseif ($customerId) { + $wishlist->loadByCustomerId($customerId, true); } - $wishlist = $this->wishlistFactory->create(); - if ($wishlistId) { $this->wishlistResource->load($wishlist, $wishlistId); } - if (null === $wishlist->getId()) { + if (null === $wishlist->getId() || $customerId !== (int) $wishlist->getCustomerId()) { throw new GraphQlInputException(__('The wishlist was not found.')); } From a2f28d83e8ceab42e60505af371d3e5905ee1d65 Mon Sep 17 00:00:00 2001 From: Oleh Usik Date: Tue, 2 Jun 2020 14:00:21 +0300 Subject: [PATCH 15/27] minor fix --- .../Quote/Guest/UpdateCartItemsTest.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) 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 f6b8cb6198bec..0a22f3ca9721c 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 @@ -278,31 +278,31 @@ private function getCartQuery(string $maskedQuoteId) } /** - * @magentoConfigFixture default_store sales/gift_options/allow_items 1 + * @magentoConfigFixture default_store sales/gift_options/allow_items 0 * @magentoApiDataFixture Magento/GiftMessage/_files/guest/quote_with_item_message.php * @throws Exception */ - public function testUpdateGiftMessageCartForItem() + public function testUpdateGiftMessageCartForItemNotAllow() { $query = $this->getUpdateGiftMessageQuery(); foreach ($this->graphQlMutation($query)['updateCartItems']['cart']['items'] as $item) { - self::assertArrayHasKey('gift_message', $item); - self::assertSame('Alex', $item['gift_message']['to']); - self::assertSame('Mike', $item['gift_message']['from']); - self::assertSame('Best regards.', $item['gift_message']['message']); + self::assertNull($item['gift_message']); } } /** - * @magentoConfigFixture default_store sales/gift_options/allow_items 0 + * @magentoConfigFixture default_store sales/gift_options/allow_items 1 * @magentoApiDataFixture Magento/GiftMessage/_files/guest/quote_with_item_message.php * @throws Exception */ - public function testUpdateGiftMessageCartForItemNotAllow() + public function testUpdateGiftMessageCartForItem() { $query = $this->getUpdateGiftMessageQuery(); foreach ($this->graphQlMutation($query)['updateCartItems']['cart']['items'] as $item) { - self::assertNull($item['gift_message']); + self::assertArrayHasKey('gift_message', $item); + self::assertSame('Alex', $item['gift_message']['to']); + self::assertSame('Mike', $item['gift_message']['from']); + self::assertSame('Best regards.', $item['gift_message']['message']); } } From 08bd47efff266a548c4544062ed7544ca1ecde4b Mon Sep 17 00:00:00 2001 From: eduard13 Date: Tue, 2 Jun 2020 12:05:10 +0300 Subject: [PATCH 16/27] Fixing static tests --- .../Model/Resolver/AddProductsToWishlist.php | 59 ++++++++++++----- .../Resolver/RemoveProductsFromWishlist.php | 39 +++++++---- .../Resolver/UpdateProductsInWishlist.php | 65 +++++++++++++------ 3 files changed, 115 insertions(+), 48 deletions(-) diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlist.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlist.php index 5a44242bdcd24..bb36a3408f1f1 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlist.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlist.php @@ -13,6 +13,7 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Wishlist\Model\ResourceModel\Wishlist as WishlistResourceModel; +use Magento\Wishlist\Model\Wishlist; use Magento\Wishlist\Model\Wishlist\AddProductsToWishlist as AddProductsToWishlistModel; use Magento\Wishlist\Model\Wishlist\Config as WishlistConfig; use Magento\Wishlist\Model\Wishlist\Data\Error; @@ -92,30 +93,19 @@ public function resolve( throw new GraphQlAuthorizationException(__('The current user cannot perform operations on wishlist')); } - $wishlistId = $args['wishlist_id'] ?: null; - $wishlistItemsData = $args['wishlist_items']; - $wishlist = $this->wishlistFactory->create(); - - if ($wishlistId) { - $this->wishlistResource->load($wishlist, $wishlistId); - } elseif ($customerId) { - $wishlist->loadByCustomerId($customerId, true); - } + $wishlistId = ((int) $args['wishlist_id']) ?: null; + $wishlist = $this->getWishlist($wishlistId, $customerId); if (null === $wishlist->getId() || $customerId !== (int) $wishlist->getCustomerId()) { throw new GraphQlInputException(__('The wishlist was not found.')); } - $wishlistItems = []; - foreach ($wishlistItemsData as $wishlistItemData) { - $wishlistItems[] = (new WishlistItemFactory())->create($wishlistItemData); - } - + $wishlistItems = $this->getWishlistItems($args['wishlist_items']); $wishlistOutput = $this->addProductsToWishlist->execute($wishlist, $wishlistItems); return [ 'wishlist' => $this->wishlistDataMapper->map($wishlistOutput->getWishlist()), - 'userInputErrors' => \array_map( + 'userInputErrors' => array_map( function (Error $error) { return [ 'code' => $error->getCode(), @@ -126,4 +116,43 @@ function (Error $error) { ) ]; } + + /** + * Get wishlist items + * + * @param array $wishlistItemsData + * + * @return array + */ + private function getWishlistItems(array $wishlistItemsData): array + { + $wishlistItems = []; + + foreach ($wishlistItemsData as $wishlistItemData) { + $wishlistItems[] = (new WishlistItemFactory())->create($wishlistItemData); + } + + return $wishlistItems; + } + + /** + * Get customer wishlist + * + * @param int|null $wishlistId + * @param int|null $customerId + * + * @return Wishlist + */ + private function getWishlist(?int $wishlistId, ?int $customerId): Wishlist + { + $wishlist = $this->wishlistFactory->create(); + + if ($wishlistId !== null && $wishlistId > 0) { + $this->wishlistResource->load($wishlist, $wishlistId); + } elseif ($customerId !== null) { + $wishlist->loadByCustomerId($customerId, true); + } + + return $wishlist; + } } diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlist.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlist.php index d493c08dfb671..19c8b795b3d1c 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlist.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlist.php @@ -13,8 +13,10 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Wishlist\Model\ResourceModel\Wishlist as WishlistResourceModel; +use Magento\Wishlist\Model\Wishlist; use Magento\Wishlist\Model\Wishlist\Config as WishlistConfig; use Magento\Wishlist\Model\Wishlist\Data\Error; +use Magento\Wishlist\Model\Wishlist\Data\WishlistItemFactory; use Magento\Wishlist\Model\Wishlist\RemoveProductsFromWishlist as RemoveProductsFromWishlistModel; use Magento\Wishlist\Model\WishlistFactory; use Magento\WishlistGraphQl\Mapper\WishlistDataMapper; @@ -87,22 +89,12 @@ public function resolve( $customerId = $context->getUserId(); /* Guest checking */ - if (null === $customerId || 0 === $customerId) { + if ($customerId === null || 0 === $customerId) { throw new GraphQlAuthorizationException(__('The current user cannot perform operations on wishlist')); } - $wishlistId = $args['wishlist_id'] ?: null; - $wishlist = $this->wishlistFactory->create(); - - if ($wishlistId) { - $this->wishlistResource->load($wishlist, $wishlistId); - } elseif ($customerId) { - $wishlist->loadByCustomerId($customerId, true); - } - - if ($wishlistId) { - $this->wishlistResource->load($wishlist, $wishlistId); - } + $wishlistId = ((int) $args['wishlist_id']) ?: null; + $wishlist = $this->getWishlist($wishlistId, $customerId); if (null === $wishlist->getId() || $customerId !== (int) $wishlist->getCustomerId()) { throw new GraphQlInputException(__('The wishlist was not found.')); @@ -128,4 +120,25 @@ function (Error $error) { ) ]; } + + /** + * Get customer wishlist + * + * @param int|null $wishlistId + * @param int|null $customerId + * + * @return Wishlist + */ + private function getWishlist(?int $wishlistId, ?int $customerId): Wishlist + { + $wishlist = $this->wishlistFactory->create(); + + if ($wishlistId !== null && $wishlistId > 0) { + $this->wishlistResource->load($wishlist, $wishlistId); + } elseif ($customerId !== null) { + $wishlist->loadByCustomerId($customerId, true); + } + + return $wishlist; + } } diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlist.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlist.php index 8a0411e71642f..3f895fd87998c 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlist.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlist.php @@ -13,6 +13,7 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Wishlist\Model\ResourceModel\Wishlist as WishlistResourceModel; +use Magento\Wishlist\Model\Wishlist; use Magento\Wishlist\Model\Wishlist\Config as WishlistConfig; use Magento\Wishlist\Model\Wishlist\Data\Error; use Magento\Wishlist\Model\Wishlist\Data\WishlistItemFactory; @@ -88,34 +89,19 @@ public function resolve( $customerId = $context->getUserId(); /* Guest checking */ - if (null === $customerId || 0 === $customerId) { + if (null === $customerId || $customerId === 0) { throw new GraphQlAuthorizationException(__('The current user cannot perform operations on wishlist')); } - $wishlistId = $args['wishlist_id'] ?: null; - $wishlist = $this->wishlistFactory->create(); - - if ($wishlistId) { - $this->wishlistResource->load($wishlist, $wishlistId); - } elseif ($customerId) { - $wishlist->loadByCustomerId($customerId, true); - } - - if ($wishlistId) { - $this->wishlistResource->load($wishlist, $wishlistId); - } + $wishlistId = ((int) $args['wishlist_id']) ?: null; + $wishlist = $this->getWishlist($wishlistId, $customerId); if (null === $wishlist->getId() || $customerId !== (int) $wishlist->getCustomerId()) { throw new GraphQlInputException(__('The wishlist was not found.')); } - $wishlistItems = []; - $wishlistItemsData = $args['wishlist_items']; - - foreach ($wishlistItemsData as $wishlistItemData) { - $wishlistItems[] = (new WishlistItemFactory())->create($wishlistItemData); - } - + $wishlistItems = $args['wishlist_items']; + $wishlistItems = $this->getWishlistItems($wishlistItems); $wishlistOutput = $this->updateProductsInWishlist->execute($wishlist, $wishlistItems); if (count($wishlistOutput->getErrors()) !== count($wishlistItems)) { @@ -135,4 +121,43 @@ function (Error $error) { ) ]; } + + /** + * Get DTO wishlist items + * + * @param array $wishlistItemsData + * + * @return array + */ + private function getWishlistItems(array $wishlistItemsData): array + { + $wishlistItems = []; + + foreach ($wishlistItemsData as $wishlistItemData) { + $wishlistItems[] = (new WishlistItemFactory())->create($wishlistItemData); + } + + return $wishlistItems; + } + + /** + * Get customer wishlist + * + * @param int|null $wishlistId + * @param int|null $customerId + * + * @return Wishlist + */ + private function getWishlist(?int $wishlistId, ?int $customerId): Wishlist + { + $wishlist = $this->wishlistFactory->create(); + + if (null !== $wishlistId && 0 < $wishlistId) { + $this->wishlistResource->load($wishlist, $wishlistId); + } elseif ($customerId !== null) { + $wishlist->loadByCustomerId($customerId, true); + } + + return $wishlist; + } } From 233b695c4f55b1a4c14009ecc13ced4658d5b868 Mon Sep 17 00:00:00 2001 From: Oleh Usik Date: Mon, 8 Jun 2020 17:14:15 +0300 Subject: [PATCH 17/27] Add some changes for messages --- .../Model/Resolver/Cart/GiftMessage.php | 2 +- .../Model/Resolver/Cart/Item/GiftMessage.php | 2 +- app/code/Magento/GiftMessageGraphQl/README.md | 2 +- .../Magento/GiftMessageGraphQl/etc/schema.graphqls | 12 ++++++------ .../Model/CartItem/DataProvider/UpdateCartItems.php | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Cart/GiftMessage.php b/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Cart/GiftMessage.php index c317221fb6ef7..2ce51c8bbf19d 100644 --- a/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Cart/GiftMessage.php +++ b/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Cart/GiftMessage.php @@ -66,7 +66,7 @@ public function resolve( array $args = null ) { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new GraphQlInputException(__('"model" value must be specified')); } $cart = $value['model']; diff --git a/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Cart/Item/GiftMessage.php b/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Cart/Item/GiftMessage.php index 6d2f546e260e5..a9a8e682612cc 100644 --- a/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Cart/Item/GiftMessage.php +++ b/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Cart/Item/GiftMessage.php @@ -65,7 +65,7 @@ public function resolve( array $args = null ) { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new GraphQlInputException(__('"model" value must be specified')); } $quoteItem = $value['model']; diff --git a/app/code/Magento/GiftMessageGraphQl/README.md b/app/code/Magento/GiftMessageGraphQl/README.md index fa2e02116b66c..d73a058e0db9c 100644 --- a/app/code/Magento/GiftMessageGraphQl/README.md +++ b/app/code/Magento/GiftMessageGraphQl/README.md @@ -1,3 +1,3 @@ # GiftMessageGraphQl -**GiftMessageGraphQl** provides information about gift messages for cart, cart items, order and order items. +**GiftMessageGraphQl** provides information about gift messages for carts, cart items, orders and order items. diff --git a/app/code/Magento/GiftMessageGraphQl/etc/schema.graphqls b/app/code/Magento/GiftMessageGraphQl/etc/schema.graphqls index 0ca69a19b711c..d7dcbfd2b17dc 100644 --- a/app/code/Magento/GiftMessageGraphQl/etc/schema.graphqls +++ b/app/code/Magento/GiftMessageGraphQl/etc/schema.graphqls @@ -2,8 +2,8 @@ # See COPYING.txt for license details. type StoreConfig { - allow_order : String @doc(description: "Allow Gift Messages on order level") - allow_items : String @doc(description: "Allow Gift Messages for order items") + allow_order : String @doc(description: "The value of the Allow Gift Messages on Order Level option") + allow_items : String @doc(description: "The value of the Allow Gift Messages for Order Items option") } type Cart { @@ -22,8 +22,8 @@ type BundleCartItem { gift_message: GiftMessage @resolver (class: "\\Magento\\GiftMessageGraphQl\\Model\\Resolver\\Cart\\Item\\GiftMessage") @doc(description: "The entered gift message for the cart item") } -type GiftMessage { - to: String! @doc(description: "Recepient name") +type GiftMessage @doc(description: "Contains the text of a gift message, its sender, and recipient") { + to: String! @doc(description: "Recipient name") from: String! @doc(description: "Sender name") message: String! @doc(description: "Gift message text") } @@ -32,8 +32,8 @@ input CartItemUpdateInput { gift_message: GiftMessageInput @doc(description: "Gift message details for the cart item") } -input GiftMessageInput { - to: String! @doc(description: "Recepient name") +input GiftMessageInput @doc(description: "Contains the text of a gift message, its sender, and recipient") { + to: String! @doc(description: "Recipient name") from: String! @doc(description: "Sender name") message: String! @doc(description: "Gift message text") } diff --git a/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/UpdateCartItems.php b/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/UpdateCartItems.php index 8d98ec039dc94..c9016d7a322c1 100644 --- a/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/UpdateCartItems.php +++ b/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/UpdateCartItems.php @@ -113,7 +113,7 @@ public function processCartItems(Quote $cart, array $items): void continue; } } catch (LocalizedException $exception) { - throw new GraphQlInputException(__('Gift Message can not be updated.')); + throw new GraphQlInputException(__('Gift Message cannot be updated.')); } $this->updateGiftMessageForItem($cart, $giftItemMessage, $item, $itemId); @@ -139,7 +139,7 @@ private function updateGiftMessageForItem(Quote $cart, MessageInterface $giftIte $giftItemMessage->setMessage($item['gift_message']['message']); $this->itemRepository->save($cart->getEntityId(), $giftItemMessage, $itemId); } catch (LocalizedException $exception) { - throw new GraphQlInputException(__('Gift Message can not be updated')); + throw new GraphQlInputException(__('Gift Message cannot be updated')); } } } From d994276cbab26239732d64b8c313a38eac13f01c Mon Sep 17 00:00:00 2001 From: Oleh Usik Date: Wed, 10 Jun 2020 12:53:26 +0300 Subject: [PATCH 18/27] minor fix --- .../GiftMessage/Cart/Item/GiftMessageTest.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/GiftMessage/Cart/Item/GiftMessageTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/GiftMessage/Cart/Item/GiftMessageTest.php index 756caf0e228b4..fa0909d556b3a 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/GiftMessage/Cart/Item/GiftMessageTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/GiftMessage/Cart/Item/GiftMessageTest.php @@ -27,34 +27,34 @@ protected function setUp(): void } /** - * @magentoConfigFixture default_store sales/gift_options/allow_items 1 + * @magentoConfigFixture default_store sales/gift_options/allow_items 0 * @magentoApiDataFixture Magento/GiftMessage/_files/guest/quote_with_item_message.php * @throws NoSuchEntityException * @throws Exception */ - public function testGiftMessageCartForItem() + public function testGiftMessageCartForItemNotAllow() { $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_guest_order_with_gift_message'); foreach ($this->requestCartResult($maskedQuoteId)['cart']['items'] as $item) { self::assertArrayHasKey('gift_message', $item); - self::assertArrayHasKey('to', $item['gift_message']); - self::assertArrayHasKey('from', $item['gift_message']); - self::assertArrayHasKey('message', $item['gift_message']); + self::assertNull($item['gift_message']); } } /** - * @magentoConfigFixture default_store sales/gift_options/allow_items 0 + * @magentoConfigFixture default_store sales/gift_options/allow_items 1 * @magentoApiDataFixture Magento/GiftMessage/_files/guest/quote_with_item_message.php * @throws NoSuchEntityException * @throws Exception */ - public function testGiftMessageCartForItemNotAllow() + public function testGiftMessageCartForItem() { $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_guest_order_with_gift_message'); foreach ($this->requestCartResult($maskedQuoteId)['cart']['items'] as $item) { self::assertArrayHasKey('gift_message', $item); - self::assertNull($item['gift_message']); + self::assertArrayHasKey('to', $item['gift_message']); + self::assertArrayHasKey('from', $item['gift_message']); + self::assertArrayHasKey('message', $item['gift_message']); } } From 938e43bfae3774afde30523951aa9edd27778ec3 Mon Sep 17 00:00:00 2001 From: Oleh Usik Date: Wed, 10 Jun 2020 14:01:08 +0300 Subject: [PATCH 19/27] Set gift message if gift message missing for cart item --- .../CartItem/DataProvider/UpdateCartItems.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/UpdateCartItems.php b/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/UpdateCartItems.php index c9016d7a322c1..c2e94b215956e 100644 --- a/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/UpdateCartItems.php +++ b/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/UpdateCartItems.php @@ -10,6 +10,7 @@ use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\GiftMessage\Api\Data\MessageInterface; +use Magento\GiftMessage\Api\Data\MessageInterfaceFactory; use Magento\GiftMessage\Api\ItemRepositoryInterface; use Magento\GiftMessage\Helper\Message as GiftMessageHelper; use Magento\Quote\Api\CartItemRepositoryInterface; @@ -41,22 +42,30 @@ class UpdateCartItems */ private $giftMessageHelper; + /** + * @var MessageInterfaceFactory + */ + private $giftMessageFactory; + /** * @param CartItemRepositoryInterface $cartItemRepository * @param UpdateCartItem $updateCartItem * @param ItemRepositoryInterface $itemRepository * @param GiftMessageHelper $giftMessageHelper + * @param MessageInterfaceFactory $giftMessageFactory */ public function __construct( CartItemRepositoryInterface $cartItemRepository, UpdateCartItem $updateCartItem, ItemRepositoryInterface $itemRepository, - GiftMessageHelper $giftMessageHelper + GiftMessageHelper $giftMessageHelper, + MessageInterfaceFactory $giftMessageFactory ) { $this->cartItemRepository = $cartItemRepository; $this->updateCartItem = $updateCartItem; $this->itemRepository = $itemRepository; $this->giftMessageHelper = $giftMessageHelper; + $this->giftMessageFactory = $giftMessageFactory; } /** @@ -110,6 +119,9 @@ public function processCartItems(Quote $cart, array $items): void $giftItemMessage = $this->itemRepository->get($cart->getEntityId(), $itemId); if (empty($giftItemMessage)) { + /** @var MessageInterface $giftMessage */ + $giftMessage = $this->giftMessageFactory->create(); + $this->updateGiftMessageForItem($cart, $giftMessage, $item, $itemId); continue; } } catch (LocalizedException $exception) { From 476ea33acaaaff969ef41837ed68f1c4b2090d2f Mon Sep 17 00:00:00 2001 From: eduard13 Date: Thu, 11 Jun 2020 13:00:02 +0300 Subject: [PATCH 20/27] Converting the arguments in camelcase format --- .../Model/Resolver/AddProductsToWishlist.php | 4 ++-- .../Model/Resolver/RemoveProductsFromWishlist.php | 4 ++-- .../Model/Resolver/UpdateProductsInWishlist.php | 4 ++-- app/code/Magento/WishlistGraphQl/etc/schema.graphqls | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlist.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlist.php index bb36a3408f1f1..11c8446a72a9d 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlist.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlist.php @@ -93,14 +93,14 @@ public function resolve( throw new GraphQlAuthorizationException(__('The current user cannot perform operations on wishlist')); } - $wishlistId = ((int) $args['wishlist_id']) ?: null; + $wishlistId = ((int) $args['wishlistId']) ?: null; $wishlist = $this->getWishlist($wishlistId, $customerId); if (null === $wishlist->getId() || $customerId !== (int) $wishlist->getCustomerId()) { throw new GraphQlInputException(__('The wishlist was not found.')); } - $wishlistItems = $this->getWishlistItems($args['wishlist_items']); + $wishlistItems = $this->getWishlistItems($args['wishlistItems']); $wishlistOutput = $this->addProductsToWishlist->execute($wishlist, $wishlistItems); return [ diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlist.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlist.php index 19c8b795b3d1c..1c741361ea7b7 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlist.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlist.php @@ -93,14 +93,14 @@ public function resolve( throw new GraphQlAuthorizationException(__('The current user cannot perform operations on wishlist')); } - $wishlistId = ((int) $args['wishlist_id']) ?: null; + $wishlistId = ((int) $args['wishlistId']) ?: null; $wishlist = $this->getWishlist($wishlistId, $customerId); if (null === $wishlist->getId() || $customerId !== (int) $wishlist->getCustomerId()) { throw new GraphQlInputException(__('The wishlist was not found.')); } - $wishlistItemsIds = $args['wishlist_items_ids']; + $wishlistItemsIds = $args['wishlistItemsIds']; $wishlistOutput = $this->removeProductsFromWishlist->execute($wishlist, $wishlistItemsIds); if (!empty($wishlistItemsIds)) { diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlist.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlist.php index 3f895fd87998c..50a56863596c0 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlist.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlist.php @@ -93,14 +93,14 @@ public function resolve( throw new GraphQlAuthorizationException(__('The current user cannot perform operations on wishlist')); } - $wishlistId = ((int) $args['wishlist_id']) ?: null; + $wishlistId = ((int) $args['wishlistId']) ?: null; $wishlist = $this->getWishlist($wishlistId, $customerId); if (null === $wishlist->getId() || $customerId !== (int) $wishlist->getCustomerId()) { throw new GraphQlInputException(__('The wishlist was not found.')); } - $wishlistItems = $args['wishlist_items']; + $wishlistItems = $args['wishlistItems']; $wishlistItems = $this->getWishlistItems($wishlistItems); $wishlistOutput = $this->updateProductsInWishlist->execute($wishlist, $wishlistItems); diff --git a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls index d7a22a52ee1d2..2bd101d1ce21c 100644 --- a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls +++ b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls @@ -34,9 +34,9 @@ type WishlistItem { } type Mutation { - addProductsToWishlist(wishlist_id: ID!, wishlist_items: [WishlistItemInput!]!): AddProductsToWishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\AddProductsToWishlist") - removeProductsFromWishlist(wishlist_id: ID!, wishlist_items_ids: [ID!]!): RemoveProductsFromWishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\RemoveProductsFromWishlist") - updateProductsInWishlist(wishlist_id: ID!, wishlist_items: [WishlistItemUpdateInput!]!): UpdateProductsInWishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\UpdateProductsInWishlist") + addProductsToWishlist(wishlistId: ID!, wishlistItems: [WishlistItemInput!]!): AddProductsToWishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\AddProductsToWishlist") + removeProductsFromWishlist(wishlistId: ID!, wishlistItemsIds: [ID!]!): RemoveProductsFromWishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\RemoveProductsFromWishlist") + updateProductsInWishlist(wishlistId: ID!, wishlistItems: [WishlistItemUpdateInput!]!): UpdateProductsInWishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\UpdateProductsInWishlist") } input WishlistItemInput { From f1d13b7dc2177e4eeb5b776e438d76fcd7df9d32 Mon Sep 17 00:00:00 2001 From: eduard13 Date: Thu, 11 Jun 2020 13:33:17 +0300 Subject: [PATCH 21/27] Converting the arguments in camelcase format --- .../GraphQl/Wishlist/AddBundleProductToWishlistTest.php | 4 ++-- .../GraphQl/Wishlist/AddConfigurableProductToWishlistTest.php | 4 ++-- .../GraphQl/Wishlist/AddDownloadableProductToWishlistTest.php | 4 ++-- .../GraphQl/Wishlist/DeleteProductsFromWishlistTest.php | 4 ++-- .../GraphQl/Wishlist/UpdateProductsFromWishlistTest.php | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/AddBundleProductToWishlistTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/AddBundleProductToWishlistTest.php index f0862feed42ca..c0199e8908d0e 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/AddBundleProductToWishlistTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/AddBundleProductToWishlistTest.php @@ -129,8 +129,8 @@ private function getQuery( return << Date: Tue, 23 Jun 2020 09:02:03 +0300 Subject: [PATCH 22/27] Update schema.graphqls Adjusting schema's descriptions --- .../WishlistGraphQl/etc/schema.graphqls | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls index 2bd101d1ce21c..15d03818f6f03 100644 --- a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls +++ b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls @@ -6,7 +6,7 @@ type Query { } type Customer { - wishlist: Wishlist! @resolver(class:"\\Magento\\WishlistGraphQl\\Model\\Resolver\\CustomerWishlistResolver") @doc(description: "The wishlist query returns the contents of a customer's wish lists") @cache(cacheable: false) + wishlist: Wishlist! @resolver(class:"\\Magento\\WishlistGraphQl\\Model\\Resolver\\CustomerWishlistResolver") @doc(description: "Contains the contents of a customer's wish lists") @cache(cacheable: false) } type WishlistOutput @doc(description: "Deprecated: `Wishlist` type should be used instead") { @@ -34,43 +34,43 @@ type WishlistItem { } type Mutation { - addProductsToWishlist(wishlistId: ID!, wishlistItems: [WishlistItemInput!]!): AddProductsToWishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\AddProductsToWishlist") - removeProductsFromWishlist(wishlistId: ID!, wishlistItemsIds: [ID!]!): RemoveProductsFromWishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\RemoveProductsFromWishlist") - updateProductsInWishlist(wishlistId: ID!, wishlistItems: [WishlistItemUpdateInput!]!): UpdateProductsInWishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\UpdateProductsInWishlist") + addProductsToWishlist(wishlistId: ID!, wishlistItems: [WishlistItemInput!]!): AddProductsToWishlistOutput @doc(description: "Adds one or more products to the specified wish list. This mutation supports all product types") @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\AddProductsToWishlist") + removeProductsFromWishlist(wishlistId: ID!, wishlistItemsIds: [ID!]!): RemoveProductsFromWishlistOutput @doc(description: "Removes one or more products from the specified wish list") @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\RemoveProductsFromWishlist") + updateProductsInWishlist(wishlistId: ID!, wishlistItems: [WishlistItemUpdateInput!]!): UpdateProductsInWishlistOutput @doc(description: "Updates one or more products in the specified wish list") @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\UpdateProductsInWishlist") } -input WishlistItemInput { - sku: String - quantity: Float - parent_sku: String, - selected_options: [String!] - entered_options: [EnteredOptionInput!] +input WishlistItemInput @doc(description: "Defines the items to add to a wish list") { + sku: String @doc(description: "The SKU of the product to add. For complex product types, specify the child product SKU") + quantity: Float @doc(description: "The amount or number of items to add") + parent_sku: String @doc(description: "For complex product types, the SKU of the parent product") + selected_options: [String!] @doc(description: "An array of strings corresponding to options the customer selected") + entered_options: [EnteredOptionInput!] @doc(description: "An array of options that the customer entered") } -type AddProductsToWishlistOutput { - wishlist: Wishlist! - userInputErrors:[CheckoutUserInputError]! @doc(description: "An array of wishlist adding errors.") +type AddProductsToWishlistOutput @doc(description: "Contains the customer\`s wish list and any errors encountered") { + wishlist: Wishlist! @doc(description: "Contains the wish list with all items that were successfully added") + userInputErrors:[CheckoutUserInputError]! @doc(description: "An array of errors encountered while adding products to a wish list") } -input EnteredOptionInput { - id: String! @doc(description: "base64 encoded id") - value: String! +input EnteredOptionInput @doc(description: "Defines a customer-entered option") { + id: String! @doc(description: "A base64 encoded ID") + value: String! @doc(description: "Text the customer entered") } -type RemoveProductsFromWishlistOutput { - wishlist: Wishlist! - userInputErrors:[CheckoutUserInputError]! @doc(description:"An array of wishlist removing errors.") +type RemoveProductsFromWishlistOutput @doc(description: "Contains the customer\`s wish list and any errors encountered") { + wishlist: Wishlist! @doc(description: "Contains the wish list with after items were successfully deleted") + userInputErrors:[CheckoutUserInputError]! @doc(description:"An array of errors encountered while deleting products from a wish list") } -input WishlistItemUpdateInput { - wishlist_item_id: ID - quantity: Float - description: String - selected_options: [String!] - entered_options: [EnteredOptionInput!] +input WishlistItemUpdateInput @doc(description: "Defines updates to items in a wish list") { + wishlist_item_id: ID @doc(description: "The ID of the wishlist item to update") + quantity: Float @doc(description: "The new amount or number of this item") + description: String @doc(description: "Describes the update") + selected_options: [String!] @doc(description: "An array of strings corresponding to options the customer selected") + entered_options: [EnteredOptionInput!] @doc(description: "An array of options that the customer entered") } -type UpdateProductsInWishlistOutput { - wishlist: Wishlist! - userInputErrors:[CheckoutUserInputError]! @doc(description:"An array of wishlist updating errors.") +type UpdateProductsInWishlistOutput @doc(description: "Contains the customer\`s wish list and any errors encountered") { + wishlist: Wishlist! @doc(description: "Contains the wish list with all items that were successfully updated") + userInputErrors:[CheckoutUserInputError]! @doc(description:"An array of errors encountered while updating products in a wish list") } From c1ce77832287c34dbd5e5617191ac935696a1c28 Mon Sep 17 00:00:00 2001 From: Eduard Chitoraga Date: Tue, 23 Jun 2020 11:00:14 +0300 Subject: [PATCH 23/27] Small schema fix --- app/code/Magento/WishlistGraphQl/etc/schema.graphqls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls index 15d03818f6f03..88f1275a35d13 100644 --- a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls +++ b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls @@ -57,7 +57,7 @@ input EnteredOptionInput @doc(description: "Defines a customer-entered option") value: String! @doc(description: "Text the customer entered") } -type RemoveProductsFromWishlistOutput @doc(description: "Contains the customer\`s wish list and any errors encountered") { +type RemoveProductsFromWishlistOutput @doc(description: "Contains the customer's wish list and any errors encountered") { wishlist: Wishlist! @doc(description: "Contains the wish list with after items were successfully deleted") userInputErrors:[CheckoutUserInputError]! @doc(description:"An array of errors encountered while deleting products from a wish list") } From 487b29ed56b00ea783a631479fa4948dec0066f1 Mon Sep 17 00:00:00 2001 From: Eduard Chitoraga Date: Tue, 23 Jun 2020 11:59:58 +0300 Subject: [PATCH 24/27] Small schema fixes --- app/code/Magento/WishlistGraphQl/etc/schema.graphqls | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls index 88f1275a35d13..794e90ed9f9a9 100644 --- a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls +++ b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls @@ -47,7 +47,7 @@ input WishlistItemInput @doc(description: "Defines the items to add to a wish li entered_options: [EnteredOptionInput!] @doc(description: "An array of options that the customer entered") } -type AddProductsToWishlistOutput @doc(description: "Contains the customer\`s wish list and any errors encountered") { +type AddProductsToWishlistOutput @doc(description: "Contains the customer's wish list and any errors encountered") { wishlist: Wishlist! @doc(description: "Contains the wish list with all items that were successfully added") userInputErrors:[CheckoutUserInputError]! @doc(description: "An array of errors encountered while adding products to a wish list") } @@ -70,7 +70,7 @@ input WishlistItemUpdateInput @doc(description: "Defines updates to items in a w entered_options: [EnteredOptionInput!] @doc(description: "An array of options that the customer entered") } -type UpdateProductsInWishlistOutput @doc(description: "Contains the customer\`s wish list and any errors encountered") { +type UpdateProductsInWishlistOutput @doc(description: "Contains the customer's wish list and any errors encountered") { wishlist: Wishlist! @doc(description: "Contains the wish list with all items that were successfully updated") userInputErrors:[CheckoutUserInputError]! @doc(description:"An array of errors encountered while updating products in a wish list") } From 066e473ede35497efdee84e9eca3122dadc260ff Mon Sep 17 00:00:00 2001 From: Eduard Chitoraga Date: Tue, 23 Jun 2020 09:02:03 +0300 Subject: [PATCH 25/27] Update schema.graphqls Adjusting schema's descriptions --- .../WishlistGraphQl/etc/schema.graphqls | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls index 2bd101d1ce21c..15d03818f6f03 100644 --- a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls +++ b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls @@ -6,7 +6,7 @@ type Query { } type Customer { - wishlist: Wishlist! @resolver(class:"\\Magento\\WishlistGraphQl\\Model\\Resolver\\CustomerWishlistResolver") @doc(description: "The wishlist query returns the contents of a customer's wish lists") @cache(cacheable: false) + wishlist: Wishlist! @resolver(class:"\\Magento\\WishlistGraphQl\\Model\\Resolver\\CustomerWishlistResolver") @doc(description: "Contains the contents of a customer's wish lists") @cache(cacheable: false) } type WishlistOutput @doc(description: "Deprecated: `Wishlist` type should be used instead") { @@ -34,43 +34,43 @@ type WishlistItem { } type Mutation { - addProductsToWishlist(wishlistId: ID!, wishlistItems: [WishlistItemInput!]!): AddProductsToWishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\AddProductsToWishlist") - removeProductsFromWishlist(wishlistId: ID!, wishlistItemsIds: [ID!]!): RemoveProductsFromWishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\RemoveProductsFromWishlist") - updateProductsInWishlist(wishlistId: ID!, wishlistItems: [WishlistItemUpdateInput!]!): UpdateProductsInWishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\UpdateProductsInWishlist") + addProductsToWishlist(wishlistId: ID!, wishlistItems: [WishlistItemInput!]!): AddProductsToWishlistOutput @doc(description: "Adds one or more products to the specified wish list. This mutation supports all product types") @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\AddProductsToWishlist") + removeProductsFromWishlist(wishlistId: ID!, wishlistItemsIds: [ID!]!): RemoveProductsFromWishlistOutput @doc(description: "Removes one or more products from the specified wish list") @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\RemoveProductsFromWishlist") + updateProductsInWishlist(wishlistId: ID!, wishlistItems: [WishlistItemUpdateInput!]!): UpdateProductsInWishlistOutput @doc(description: "Updates one or more products in the specified wish list") @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\UpdateProductsInWishlist") } -input WishlistItemInput { - sku: String - quantity: Float - parent_sku: String, - selected_options: [String!] - entered_options: [EnteredOptionInput!] +input WishlistItemInput @doc(description: "Defines the items to add to a wish list") { + sku: String @doc(description: "The SKU of the product to add. For complex product types, specify the child product SKU") + quantity: Float @doc(description: "The amount or number of items to add") + parent_sku: String @doc(description: "For complex product types, the SKU of the parent product") + selected_options: [String!] @doc(description: "An array of strings corresponding to options the customer selected") + entered_options: [EnteredOptionInput!] @doc(description: "An array of options that the customer entered") } -type AddProductsToWishlistOutput { - wishlist: Wishlist! - userInputErrors:[CheckoutUserInputError]! @doc(description: "An array of wishlist adding errors.") +type AddProductsToWishlistOutput @doc(description: "Contains the customer\`s wish list and any errors encountered") { + wishlist: Wishlist! @doc(description: "Contains the wish list with all items that were successfully added") + userInputErrors:[CheckoutUserInputError]! @doc(description: "An array of errors encountered while adding products to a wish list") } -input EnteredOptionInput { - id: String! @doc(description: "base64 encoded id") - value: String! +input EnteredOptionInput @doc(description: "Defines a customer-entered option") { + id: String! @doc(description: "A base64 encoded ID") + value: String! @doc(description: "Text the customer entered") } -type RemoveProductsFromWishlistOutput { - wishlist: Wishlist! - userInputErrors:[CheckoutUserInputError]! @doc(description:"An array of wishlist removing errors.") +type RemoveProductsFromWishlistOutput @doc(description: "Contains the customer\`s wish list and any errors encountered") { + wishlist: Wishlist! @doc(description: "Contains the wish list with after items were successfully deleted") + userInputErrors:[CheckoutUserInputError]! @doc(description:"An array of errors encountered while deleting products from a wish list") } -input WishlistItemUpdateInput { - wishlist_item_id: ID - quantity: Float - description: String - selected_options: [String!] - entered_options: [EnteredOptionInput!] +input WishlistItemUpdateInput @doc(description: "Defines updates to items in a wish list") { + wishlist_item_id: ID @doc(description: "The ID of the wishlist item to update") + quantity: Float @doc(description: "The new amount or number of this item") + description: String @doc(description: "Describes the update") + selected_options: [String!] @doc(description: "An array of strings corresponding to options the customer selected") + entered_options: [EnteredOptionInput!] @doc(description: "An array of options that the customer entered") } -type UpdateProductsInWishlistOutput { - wishlist: Wishlist! - userInputErrors:[CheckoutUserInputError]! @doc(description:"An array of wishlist updating errors.") +type UpdateProductsInWishlistOutput @doc(description: "Contains the customer\`s wish list and any errors encountered") { + wishlist: Wishlist! @doc(description: "Contains the wish list with all items that were successfully updated") + userInputErrors:[CheckoutUserInputError]! @doc(description:"An array of errors encountered while updating products in a wish list") } From 6d36492eb7886c5450a670709608002496490244 Mon Sep 17 00:00:00 2001 From: Eduard Chitoraga Date: Tue, 23 Jun 2020 11:00:14 +0300 Subject: [PATCH 26/27] Small schema fix --- app/code/Magento/WishlistGraphQl/etc/schema.graphqls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls index 15d03818f6f03..88f1275a35d13 100644 --- a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls +++ b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls @@ -57,7 +57,7 @@ input EnteredOptionInput @doc(description: "Defines a customer-entered option") value: String! @doc(description: "Text the customer entered") } -type RemoveProductsFromWishlistOutput @doc(description: "Contains the customer\`s wish list and any errors encountered") { +type RemoveProductsFromWishlistOutput @doc(description: "Contains the customer's wish list and any errors encountered") { wishlist: Wishlist! @doc(description: "Contains the wish list with after items were successfully deleted") userInputErrors:[CheckoutUserInputError]! @doc(description:"An array of errors encountered while deleting products from a wish list") } From ac20903c47cc14b9df7ee509c31f11db70ad9ccd Mon Sep 17 00:00:00 2001 From: Eduard Chitoraga Date: Tue, 23 Jun 2020 11:59:58 +0300 Subject: [PATCH 27/27] Small schema fixes --- app/code/Magento/WishlistGraphQl/etc/schema.graphqls | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls index 88f1275a35d13..794e90ed9f9a9 100644 --- a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls +++ b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls @@ -47,7 +47,7 @@ input WishlistItemInput @doc(description: "Defines the items to add to a wish li entered_options: [EnteredOptionInput!] @doc(description: "An array of options that the customer entered") } -type AddProductsToWishlistOutput @doc(description: "Contains the customer\`s wish list and any errors encountered") { +type AddProductsToWishlistOutput @doc(description: "Contains the customer's wish list and any errors encountered") { wishlist: Wishlist! @doc(description: "Contains the wish list with all items that were successfully added") userInputErrors:[CheckoutUserInputError]! @doc(description: "An array of errors encountered while adding products to a wish list") } @@ -70,7 +70,7 @@ input WishlistItemUpdateInput @doc(description: "Defines updates to items in a w entered_options: [EnteredOptionInput!] @doc(description: "An array of options that the customer entered") } -type UpdateProductsInWishlistOutput @doc(description: "Contains the customer\`s wish list and any errors encountered") { +type UpdateProductsInWishlistOutput @doc(description: "Contains the customer's wish list and any errors encountered") { wishlist: Wishlist! @doc(description: "Contains the wish list with all items that were successfully updated") userInputErrors:[CheckoutUserInputError]! @doc(description:"An array of errors encountered while updating products in a wish list") }