From d11fda51f8fcb4259f0d03e41728810cbb9f3448 Mon Sep 17 00:00:00 2001 From: Alexandr Voronoy Date: Thu, 15 Nov 2018 15:31:21 +0200 Subject: [PATCH 01/42] Access to related/up-sell/cross-sell product fields in graphql --- .../Model/Resolver/Product/Related.php | 43 +++++++++++ .../Product/Related/CrossSellProducts.php | 60 ++++++++++++++++ .../Product/Related/RelatedProducts.php | 71 +++++++++++++++++++ .../Product/Related/UpSellProducts.php | 70 ++++++++++++++++++ .../Related/AbstractDataProvider.php | 70 ++++++++++++++++++ .../Related/CrossSellDataProvider.php | 26 +++++++ .../Related/RelatedDataProvider.php | 18 +++++ .../Related/UpSellDataProvider.php | 25 +++++++ .../CatalogGraphQl/etc/schema.graphqls | 18 ++++- 9 files changed, 398 insertions(+), 3 deletions(-) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/CrossSellProducts.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/RelatedProducts.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/UpSellProducts.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/AbstractDataProvider.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/CrossSellDataProvider.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/RelatedDataProvider.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/UpSellDataProvider.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related.php new file mode 100644 index 0000000000000..bd0199db2c2d2 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related.php @@ -0,0 +1,43 @@ +getName(); + + return [ + 'model' => $product, + 'product_list_type' => $productListType + ]; + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/CrossSellProducts.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/CrossSellProducts.php new file mode 100644 index 0000000000000..59d619222399a --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/CrossSellProducts.php @@ -0,0 +1,60 @@ +dataProvider = $dataProvider; + } + + /** + * Fetches the data from persistence models and format it according to the GraphQL schema. + * + * @param \Magento\Framework\GraphQl\Config\Element\Field $field + * @param ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * @throws \Exception + * @return mixed|Value + */ + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) + { + $product = $value['model']; + $this->dataProvider->addFieldToSelect(self::FIELDS); + $collection = $this->dataProvider->getData($product); + + $count = 0; + foreach ($collection as $item) { + $data[$count] = $item->getData(); + $data[$count]['model'] = $item; + $count++; + } + return $data; + } + +} \ No newline at end of file diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/RelatedProducts.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/RelatedProducts.php new file mode 100644 index 0000000000000..bfaed0279b59c --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/RelatedProducts.php @@ -0,0 +1,71 @@ +dataProvider = $dataProvider; + } + + /** + * Fetches the data from persistence models and format it according to the GraphQL schema. + * + * @param \Magento\Framework\GraphQl\Config\Element\Field $field + * @param ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * @throws \Exception + * @return mixed|Value + */ + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) + { + $product = $value['model']; + $this->dataProvider->addFieldToSelect(self::FIELDS); + $collection = $this->dataProvider->getData($product); + + $count = 0; + $data = []; + foreach ($collection as $item) { + $data[$count] = $item->getData(); + $data[$count]['model'] = $item; + $count++; + } + return $data; + } + +} \ No newline at end of file diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/UpSellProducts.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/UpSellProducts.php new file mode 100644 index 0000000000000..82980eb338b47 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/UpSellProducts.php @@ -0,0 +1,70 @@ +dataProvider = $dataProvider; + } + + /** + * Fetches the data from persistence models and format it according to the GraphQL schema. + * + * @param \Magento\Framework\GraphQl\Config\Element\Field $field + * @param ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * @throws \Exception + * @return mixed|Value + */ + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) + { + $product = $value['model']; + $this->dataProvider->addFieldToSelect(self::FIELDS); + $collection = $this->dataProvider->getData($product); + + $count = 0; + $data = []; + foreach ($collection as $item) { + $data[$count] = $item->getData(); + $data[$count]['model'] = $item; + $count++; + } + return $data; + } + +} \ No newline at end of file diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/AbstractDataProvider.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/AbstractDataProvider.php new file mode 100644 index 0000000000000..4dcff69e07aaa --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/AbstractDataProvider.php @@ -0,0 +1,70 @@ +fields = $field; + } + + + /** + * @return array + */ + public function getFields(): array + { + return $this->fields; + } + + /** + * @return mixed + */ + public function getCollection() + { + return $this->collection; + } + + /** + * @param $product + * @return mixed + */ + public function getData($product) + { + $this->prepareCollection($product); + return $this->collection; + + } + + /** + * @param $product + */ + protected function prepareCollection($product): void + { + $this->collection = $product->getRelatedProducts(); + $this->collection->addAttributeToSelect($this->getFields()); + } + + +} \ No newline at end of file diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/CrossSellDataProvider.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/CrossSellDataProvider.php new file mode 100644 index 0000000000000..cc238d1179699 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/CrossSellDataProvider.php @@ -0,0 +1,26 @@ +collection = $product->getCrossSellProductCollection(); + $this->collection->addAttributeToSelect($this->getFields()); + } + +} \ No newline at end of file diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/RelatedDataProvider.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/RelatedDataProvider.php new file mode 100644 index 0000000000000..3adc193c1c2bb --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/RelatedDataProvider.php @@ -0,0 +1,18 @@ +collection = $product->getRelatedProductCollection(); + $this->collection->addAttributeToSelect($this->getFields()); + } + + +} \ No newline at end of file diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/UpSellDataProvider.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/UpSellDataProvider.php new file mode 100644 index 0000000000000..03bd7793fab32 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/UpSellDataProvider.php @@ -0,0 +1,25 @@ +collection = $product->getUpSellProductCollection(); + $this->collection->addAttributeToSelect($this->getFields()); + } +} \ No newline at end of file diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index e2eab9121e332..c56bfb4574c6d 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -225,10 +225,10 @@ type ProductPrices @doc(description: "The ProductPrices object contains the regu regularPrice: Price @doc(description: "The base price of a product.") } -type ProductLinks implements ProductLinksInterface @doc(description: "ProductLinks is an implementation of ProductLinksInterface.") { +type Related implements ProductLinksInterface @doc(description: "Related is an implementation of ProductLinksInterface.") { } -interface ProductLinksInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductLinkTypeResolverComposite") @doc(description:"ProductLinks contains information about linked products, including the link type and product type of each item.") { +interface ProductLinksInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductLinkTypeResolverComposite") @doc(description:"Related contains information about linked products, including the link type and product type of each item.") { sku: String @doc(description: "The identifier of the linked product") link_type: String @doc(description: "One of related, associated, upsell, or crosssell") linked_product_sku: String @doc(description: "The SKU of the linked product") @@ -269,8 +269,11 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ country_of_manufacture: String @doc(description: "The product's country of origin") type_id: String @doc(description: "One of simple, virtual, bundle, downloadable, grouped, or configurable") websites: [Website] @doc(description: "An array of websites in which the product is available") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Websites") - product_links: [ProductLinksInterface] @doc(description: "An array of ProductLinks objects") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductLinks") + product_links: [ProductLinksInterface] @doc(description: "An array of Related objects") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Related") media_gallery_entries: [MediaGalleryEntry] @doc(description: "An array of MediaGalleryEntry objects") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\MediaGalleryEntries") + related_products: RelatedProduct @doc(description: "RelatedProduct") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Related") + upsell_products: UpsellProduct @doc(description: "RelatedProduct") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Related") + crosssell_products: CrosssellProduct @doc(description: "RelatedProduct") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Related") tier_prices: [ProductTierPrices] @doc(description: "An array of ProductTierPrices objects") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\TierPrices") price: ProductPrices @doc(description: "A ProductPrices object, indicating the price of an item") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Price") gift_message_available: String @doc(description: "Indicates whether a gift message is available") @@ -526,6 +529,15 @@ type MediaGalleryEntry @doc(description: "MediaGalleryEntry defines characteris content: ProductMediaGalleryEntriesContent @doc(description: "Contains a ProductMediaGalleryEntriesContent object") video_content: ProductMediaGalleryEntriesVideoContent @doc(description: "Contains a ProductMediaGalleryEntriesVideoContent object") } +type RelatedProduct @doc(description: "RelatedProduct"){ + items: [ProductInterface] @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Related\\RelatedProducts") +} +type UpsellProduct @doc(description: "UpsellProduct"){ + items: [ProductInterface] @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Related\\UpSellProducts") +} +type CrosssellProduct @doc(description: "CrosssellProduct"){ + items: [ProductInterface] @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Related\\CrossSellProducts") +} type LayerFilter { name: String @doc(description: "Layered navigation filter name") From 094cf30bf8743808eff4ec228f8e1d2267a23773 Mon Sep 17 00:00:00 2001 From: Alexandr Voronoy Date: Thu, 15 Nov 2018 15:39:23 +0200 Subject: [PATCH 02/42] Fix schema @doc and type --- app/code/Magento/CatalogGraphQl/etc/schema.graphqls | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index c56bfb4574c6d..37641ab023f56 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -225,7 +225,7 @@ type ProductPrices @doc(description: "The ProductPrices object contains the regu regularPrice: Price @doc(description: "The base price of a product.") } -type Related implements ProductLinksInterface @doc(description: "Related is an implementation of ProductLinksInterface.") { +type ProductLinks implements ProductLinksInterface @doc(description: "ProductLinks is an implementation of ProductLinksInterface.") { } interface ProductLinksInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductLinkTypeResolverComposite") @doc(description:"Related contains information about linked products, including the link type and product type of each item.") { @@ -269,7 +269,7 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ country_of_manufacture: String @doc(description: "The product's country of origin") type_id: String @doc(description: "One of simple, virtual, bundle, downloadable, grouped, or configurable") websites: [Website] @doc(description: "An array of websites in which the product is available") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Websites") - product_links: [ProductLinksInterface] @doc(description: "An array of Related objects") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Related") + product_links: [ProductLinksInterface] @doc(description: "An array of ProductLinks objects") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductLinks") media_gallery_entries: [MediaGalleryEntry] @doc(description: "An array of MediaGalleryEntry objects") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\MediaGalleryEntries") related_products: RelatedProduct @doc(description: "RelatedProduct") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Related") upsell_products: UpsellProduct @doc(description: "RelatedProduct") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Related") From cb8221093b651f51f543f9c636f3ef6e5a06e7b7 Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko Date: Wed, 13 Feb 2019 20:34:06 +0200 Subject: [PATCH 03/42] graphQl-198: refactored upSell crossSell, adjusted tests --- .../CatalogGraphQl/Model/Resolver/Product.php | 49 ++--- .../Product/ProductFieldsSelector.php | 61 ++++++ .../Model/Resolver/Product/Related.php | 43 ----- .../Product/Related/CrossSellProducts.php | 46 ++--- .../Product/Related/RelatedProducts.php | 42 +---- .../Product/Related/UpSellProducts.php | 48 ++--- .../Related/AbstractDataProvider.php | 70 ------- .../Related/CrossSellDataProvider.php | 26 --- .../Products/LinkedProductsDataProvider.php | 56 ++++++ .../Related/RelatedDataProvider.php | 76 +++++++- .../Related/UpSellDataProvider.php | 25 --- .../Magento/CatalogGraphQl/etc/graphql/di.xml | 22 +++ .../CatalogGraphQl/etc/schema.graphqls | 15 +- .../Catalog/ProductRelatedProductsTest.php | 175 ++++++++++++++++++ 14 files changed, 434 insertions(+), 320 deletions(-) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductFieldsSelector.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/AbstractDataProvider.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/CrossSellDataProvider.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/Products/LinkedProductsDataProvider.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/UpSellDataProvider.php create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductRelatedProductsTest.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product.php index 40aa54fd93873..b3283883f5561 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product.php @@ -7,14 +7,15 @@ namespace Magento\CatalogGraphQl\Model\Resolver; -use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\CatalogGraphQl\Model\Resolver\Product\ProductFieldsSelector; use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Deferred\Product as ProductDataProvider; +use Magento\Framework\App\ObjectManager; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\FieldTranslator; -use Magento\Framework\GraphQl\Query\Resolver\Value; use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; /** * @inheritdoc @@ -32,23 +33,33 @@ class Product implements ResolverInterface private $valueFactory; /** + * @deprecated * @var FieldTranslator */ private $fieldTranslator; + /** + * @var ProductFieldsSelector + */ + private $productFieldsSelector; + /** * @param ProductDataProvider $productDataProvider * @param ValueFactory $valueFactory * @param FieldTranslator $fieldTranslator + * @param ProductFieldsSelector $productFieldsSelector */ public function __construct( ProductDataProvider $productDataProvider, ValueFactory $valueFactory, - FieldTranslator $fieldTranslator + FieldTranslator $fieldTranslator, + ProductFieldsSelector $productFieldsSelector ) { $this->productDataProvider = $productDataProvider; $this->valueFactory = $valueFactory; $this->fieldTranslator = $fieldTranslator; + $this->productFieldsSelector = $productFieldsSelector + ?? ObjectManager::getInstance()->get(ProductFieldsSelector::class); } /** @@ -60,7 +71,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value throw new GraphQlInputException(__('No child sku found for product link.')); } $this->productDataProvider->addProductSku($value['sku']); - $fields = $this->getProductFields($info); + $fields = $this->productFieldsSelector->getProductFieldsFromInfo($info); $this->productDataProvider->addEavAttributes($fields); $result = function () use ($value) { @@ -86,34 +97,4 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value return $this->valueFactory->create($result); } - - /** - * Return field names for all requested product fields. - * - * @param ResolveInfo $info - * @return string[] - */ - private function getProductFields(ResolveInfo $info) : array - { - $fieldNames = []; - foreach ($info->fieldNodes as $node) { - if ($node->name->value !== 'product') { - continue; - } - foreach ($node->selectionSet->selections as $selectionNode) { - if ($selectionNode->kind === 'InlineFragment') { - foreach ($selectionNode->selectionSet->selections as $inlineSelection) { - if ($inlineSelection->kind === 'InlineFragment') { - continue; - } - $fieldNames[] = $this->fieldTranslator->translate($inlineSelection->name->value); - } - continue; - } - $fieldNames[] = $this->fieldTranslator->translate($selectionNode->name->value); - } - } - - return $fieldNames; - } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductFieldsSelector.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductFieldsSelector.php new file mode 100644 index 0000000000000..9ddad4e6451fa --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductFieldsSelector.php @@ -0,0 +1,61 @@ +fieldTranslator = $fieldTranslator; + } + + /** + * Return field names for all requested product fields. + * + * @param ResolveInfo $info + * @param string $productNodeName + * @return string[] + */ + public function getProductFieldsFromInfo(ResolveInfo $info, string $productNodeName = 'product') : array + { + $fieldNames = []; + foreach ($info->fieldNodes as $node) { + if ($node->name->value !== $productNodeName) { + continue; + } + foreach ($node->selectionSet->selections as $selectionNode) { + if ($selectionNode->kind === 'InlineFragment') { + foreach ($selectionNode->selectionSet->selections as $inlineSelection) { + if ($inlineSelection->kind === 'InlineFragment') { + continue; + } + $fieldNames[] = $this->fieldTranslator->translate($inlineSelection->name->value); + } + continue; + } + $fieldNames[] = $this->fieldTranslator->translate($selectionNode->name->value); + } + } + + return $fieldNames; + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related.php deleted file mode 100644 index bd0199db2c2d2..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related.php +++ /dev/null @@ -1,43 +0,0 @@ -getName(); - - return [ - 'model' => $product, - 'product_list_type' => $productListType - ]; - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/CrossSellProducts.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/CrossSellProducts.php index 59d619222399a..2ae3d30a2b01f 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/CrossSellProducts.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/CrossSellProducts.php @@ -7,54 +7,38 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product\Related; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Related\CrossSellDataProvider; +use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Related\RelatedDataProvider; use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; -use Magento\Framework\GraphQl\Query\Resolver\Value; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; - +/** + * CrossSell Products Resolver + */ class CrossSellProducts implements ResolverInterface { /** - * Attribute to select fields - */ - public const FIELDS = ['sku', 'name', 'price', 'image', 'url_path', 'url_key']; - /** - * @var CrossSellDataProvider + * @see module di.xml + * @var RelatedDataProvider */ private $dataProvider; - public function __construct(CrossSellDataProvider $dataProvider) - { + /** + * @param RelatedDataProvider $dataProvider + */ + public function __construct( + RelatedDataProvider $dataProvider + ) { $this->dataProvider = $dataProvider; } /** - * Fetches the data from persistence models and format it according to the GraphQL schema. - * - * @param \Magento\Framework\GraphQl\Config\Element\Field $field - * @param ContextInterface $context - * @param ResolveInfo $info - * @param array|null $value - * @param array|null $args - * @throws \Exception - * @return mixed|Value + * @inheritdoc */ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { - $product = $value['model']; - $this->dataProvider->addFieldToSelect(self::FIELDS); - $collection = $this->dataProvider->getData($product); + $data = $this->dataProvider->getProducts($info, $value); - $count = 0; - foreach ($collection as $item) { - $data[$count] = $item->getData(); - $data[$count]['model'] = $item; - $count++; - } return $data; } - -} \ No newline at end of file +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/RelatedProducts.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/RelatedProducts.php index bfaed0279b59c..cb437a2202c88 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/RelatedProducts.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/RelatedProducts.php @@ -7,65 +7,37 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product\Related; - use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Related\RelatedDataProvider; use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; -use Magento\Framework\GraphQl\Query\Resolver\Value; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; - /** - * Class RelatedProducts - * @package Magento\CatalogGraphQl\Model\Resolver\Product\Related + * Related Products Resolver */ class RelatedProducts implements ResolverInterface { - - /** - * Attribute to select fields - */ - public const FIELDS = ['sku', 'name', 'price', 'image', 'url_path', 'url_key']; /** * @var RelatedDataProvider */ private $dataProvider; /** - * RelatedProducts constructor. * @param RelatedDataProvider $dataProvider */ - public function __construct(RelatedDataProvider $dataProvider) - { + public function __construct( + RelatedDataProvider $dataProvider + ) { $this->dataProvider = $dataProvider; } /** - * Fetches the data from persistence models and format it according to the GraphQL schema. - * - * @param \Magento\Framework\GraphQl\Config\Element\Field $field - * @param ContextInterface $context - * @param ResolveInfo $info - * @param array|null $value - * @param array|null $args - * @throws \Exception - * @return mixed|Value + * @inheritdoc */ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { - $product = $value['model']; - $this->dataProvider->addFieldToSelect(self::FIELDS); - $collection = $this->dataProvider->getData($product); + $data = $this->dataProvider->getProducts($info, $value); - $count = 0; - $data = []; - foreach ($collection as $item) { - $data[$count] = $item->getData(); - $data[$count]['model'] = $item; - $count++; - } return $data; } - -} \ No newline at end of file +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/UpSellProducts.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/UpSellProducts.php index 82980eb338b47..e43e0fe57de4b 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/UpSellProducts.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/UpSellProducts.php @@ -7,64 +7,38 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product\Related; - -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Related\UpSellDataProvider; +use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Related\RelatedDataProvider; use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; -use Magento\Framework\GraphQl\Query\Resolver\Value; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; - /** - * Class UpSellProducts - * @package Magento\CatalogGraphQl\Model\Resolver\Product\Related + * UpSell Products Resolver */ class UpSellProducts implements ResolverInterface { /** - * Attribute to select fields - */ - public const FIELDS = ['sku', 'name', 'price', 'image', 'url_path', 'url_key']; - /** - * @var UpSellDataProvider + * @see module di.xml + * @var RelatedDataProvider */ private $dataProvider; /** - * UpSellProducts constructor. - * @param UpSellDataProvider $dataProvider + * @param RelatedDataProvider $dataProvider */ - public function __construct(UpSellDataProvider $dataProvider) - { + public function __construct( + RelatedDataProvider $dataProvider + ) { $this->dataProvider = $dataProvider; } /** - * Fetches the data from persistence models and format it according to the GraphQL schema. - * - * @param \Magento\Framework\GraphQl\Config\Element\Field $field - * @param ContextInterface $context - * @param ResolveInfo $info - * @param array|null $value - * @param array|null $args - * @throws \Exception - * @return mixed|Value + * @inheritdoc */ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { - $product = $value['model']; - $this->dataProvider->addFieldToSelect(self::FIELDS); - $collection = $this->dataProvider->getData($product); + $data = $this->dataProvider->getProducts($info, $value); - $count = 0; - $data = []; - foreach ($collection as $item) { - $data[$count] = $item->getData(); - $data[$count]['model'] = $item; - $count++; - } return $data; } - -} \ No newline at end of file +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/AbstractDataProvider.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/AbstractDataProvider.php deleted file mode 100644 index 4dcff69e07aaa..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/AbstractDataProvider.php +++ /dev/null @@ -1,70 +0,0 @@ -fields = $field; - } - - - /** - * @return array - */ - public function getFields(): array - { - return $this->fields; - } - - /** - * @return mixed - */ - public function getCollection() - { - return $this->collection; - } - - /** - * @param $product - * @return mixed - */ - public function getData($product) - { - $this->prepareCollection($product); - return $this->collection; - - } - - /** - * @param $product - */ - protected function prepareCollection($product): void - { - $this->collection = $product->getRelatedProducts(); - $this->collection->addAttributeToSelect($this->getFields()); - } - - -} \ No newline at end of file diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/CrossSellDataProvider.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/CrossSellDataProvider.php deleted file mode 100644 index cc238d1179699..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/CrossSellDataProvider.php +++ /dev/null @@ -1,26 +0,0 @@ -collection = $product->getCrossSellProductCollection(); - $this->collection->addAttributeToSelect($this->getFields()); - } - -} \ No newline at end of file diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/Products/LinkedProductsDataProvider.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/Products/LinkedProductsDataProvider.php new file mode 100644 index 0000000000000..d2daefd128129 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/Products/LinkedProductsDataProvider.php @@ -0,0 +1,56 @@ +linkFactory = $linkFactory; + } + + /** + * Get Related Products by Product and Link Type + * + * @param Product $product + * @param array $fields + * @param int $linkType + * @return Product[] + */ + public function getRelatedProducts(Product $product, array $fields, int $linkType): array + { + /** @var Link $link */ + $link = $this->linkFactory->create([ 'data' => [ + 'link_type_id' => $linkType + ]]); + + $collection = $link->getProductCollection(); + $collection->setIsStrongMode(); + foreach ($fields as $field) { + $collection->addAttributeToSelect($field); + } + $collection->setProduct($product); + + return $collection->getItems(); + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/RelatedDataProvider.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/RelatedDataProvider.php index 3adc193c1c2bb..8f42cc8411a72 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/RelatedDataProvider.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/RelatedDataProvider.php @@ -1,18 +1,80 @@ collection = $product->getRelatedProductCollection(); - $this->collection->addAttributeToSelect($this->getFields()); + /** + * @var int + */ + private $linkType; + + /** + * @var string + */ + private $schemaNodeName; + + /** + * @param LinkedProductsDataProvider $dataProvider + * @param ProductFieldsSelector $productFieldsSelector + * @param int $linkType + * @param string $schemaNodeName + */ + public function __construct( + LinkedProductsDataProvider $dataProvider, + ProductFieldsSelector $productFieldsSelector, + int $linkType = Link::LINK_TYPE_RELATED, + string $schemaNodeName = 'related_products' + ) { + $this->dataProvider = $dataProvider; + $this->productFieldsSelector = $productFieldsSelector; + $this->linkType = $linkType; + $this->schemaNodeName = $schemaNodeName; } + /** + * Related Products Data + * + * @param ResolveInfo $info + * @param array $value + * @return array + */ + public function getProducts(ResolveInfo $info, array $value): array + { + $product = $value['model']; + $fields = $this->productFieldsSelector->getProductFieldsFromInfo($info, $this->schemaNodeName); + $products = $this->dataProvider->getRelatedProducts($product, $fields, $this->linkType); + + $data = []; + foreach ($products as $key => $product) { + $data[$key] = $product->getData(); + $data[$key]['model'] = $product; + } -} \ No newline at end of file + return $data; + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/UpSellDataProvider.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/UpSellDataProvider.php deleted file mode 100644 index 03bd7793fab32..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/UpSellDataProvider.php +++ /dev/null @@ -1,25 +0,0 @@ -collection = $product->getUpSellProductCollection(); - $this->collection->addAttributeToSelect($this->getFields()); - } -} \ No newline at end of file diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml index 7e18ac34f0fcc..db27e356784ac 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml @@ -74,4 +74,26 @@ + + + Magento\Catalog\Model\Product\Link::LINK_TYPE_CROSSSELL + crosssell_products + + + + + Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Related\CrossSellDataProvider + + + + + Magento\Catalog\Model\Product\Link::LINK_TYPE_UPSELL + upsell_products + + + + + Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Related\UpSellDataProvider + + diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 4c457333dec92..4b255afd3c67b 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -271,9 +271,9 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ websites: [Website] @doc(description: "An array of websites in which the product is available") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Websites") product_links: [ProductLinksInterface] @doc(description: "An array of ProductLinks objects") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductLinks") media_gallery_entries: [MediaGalleryEntry] @doc(description: "An array of MediaGalleryEntry objects") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\MediaGalleryEntries") - related_products: RelatedProduct @doc(description: "RelatedProduct") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Related") - upsell_products: UpsellProduct @doc(description: "RelatedProduct") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Related") - crosssell_products: CrosssellProduct @doc(description: "RelatedProduct") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Related") + related_products: [ProductInterface] @doc(description: "RelatedProduct") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Related\\RelatedProducts") + upsell_products: [ProductInterface] @doc(description: "RelatedProduct") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Related\\UpSellProducts") + crosssell_products: [ProductInterface] @doc(description: "RelatedProduct") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Related\\CrossSellProducts") tier_prices: [ProductTierPrices] @doc(description: "An array of ProductTierPrices objects") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\TierPrices") price: ProductPrices @doc(description: "A ProductPrices object, indicating the price of an item") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Price") gift_message_available: String @doc(description: "Indicates whether a gift message is available") @@ -530,15 +530,6 @@ type MediaGalleryEntry @doc(description: "MediaGalleryEntry defines characteris content: ProductMediaGalleryEntriesContent @doc(description: "Contains a ProductMediaGalleryEntriesContent object") video_content: ProductMediaGalleryEntriesVideoContent @doc(description: "Contains a ProductMediaGalleryEntriesVideoContent object") } -type RelatedProduct @doc(description: "RelatedProduct"){ - items: [ProductInterface] @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Related\\RelatedProducts") -} -type UpsellProduct @doc(description: "UpsellProduct"){ - items: [ProductInterface] @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Related\\UpSellProducts") -} -type CrosssellProduct @doc(description: "CrosssellProduct"){ - items: [ProductInterface] @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Related\\CrossSellProducts") -} type LayerFilter { name: String @doc(description: "Layered navigation filter name") diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductRelatedProductsTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductRelatedProductsTest.php new file mode 100644 index 0000000000000..2cc3f0c8530a8 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductRelatedProductsTest.php @@ -0,0 +1,175 @@ +graphQlQuery($query); + + $this->assertArrayHasKey('products', $response); + $this->assertArrayHasKey('items', $response['products']); + $this->assertEquals(1, count($response['products']['items'])); + $this->assertArrayHasKey(0, $response['products']['items']); + $this->assertArrayHasKey('related_products', $response['products']['items'][0]); + $relatedProducts = $response['products']['items'][0]['related_products']; + $this->assertCount(2, $relatedProducts); + $this->assertRelatedProducts($relatedProducts); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/products_crosssell.php + */ + public function testQueryCrossSellProducts() + { + $productSku = 'simple_with_cross'; + + $query = <<graphQlQuery($query); + + $this->assertArrayHasKey('products', $response); + $this->assertArrayHasKey('items', $response['products']); + $this->assertEquals(1, count($response['products']['items'])); + $this->assertArrayHasKey(0, $response['products']['items']); + $this->assertArrayHasKey('crosssell_products', $response['products']['items'][0]); + $crossSellProducts = $response['products']['items'][0]['crosssell_products']; + $this->assertCount(1, $crossSellProducts); + $crossSellProduct = $crossSellProducts[0]; + $this->assertArrayHasKey('sku', $crossSellProduct); + $this->assertArrayHasKey('name', $crossSellProduct); + $this->assertArrayHasKey('url_key', $crossSellProduct); + $this->assertArrayHasKey('id', $crossSellProduct); + $this->assertArrayHasKey('created_at', $crossSellProduct); + $this->assertEquals($crossSellProduct['sku'], 'simple'); + $this->assertEquals($crossSellProduct['name'], 'Simple Cross Sell'); + $this->assertEquals($crossSellProduct['url_key'], 'simple-cross-sell'); + $this->assertNotEmpty($crossSellProduct['created_at']); + $this->assertNotEmpty($crossSellProduct['id']); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/products_upsell.php + */ + public function testQueryUpSellProducts() + { + $productSku = 'simple_with_upsell'; + + $query = <<graphQlQuery($query); + + $this->assertArrayHasKey('products', $response); + $this->assertArrayHasKey('items', $response['products']); + $this->assertEquals(1, count($response['products']['items'])); + $this->assertArrayHasKey(0, $response['products']['items']); + $this->assertArrayHasKey('upsell_products', $response['products']['items'][0]); + $upSellProducts = $response['products']['items'][0]['upsell_products']; + $this->assertCount(1, $upSellProducts); + $upSellProduct = $upSellProducts[0]; + $this->assertArrayHasKey('sku', $upSellProduct); + $this->assertArrayHasKey('name', $upSellProduct); + $this->assertArrayHasKey('url_key', $upSellProduct); + $this->assertArrayHasKey('id', $upSellProduct); + $this->assertArrayHasKey('created_at', $upSellProduct); + $this->assertEquals($upSellProduct['sku'], 'simple'); + $this->assertEquals($upSellProduct['name'], 'Simple Up Sell'); + $this->assertEquals($upSellProduct['url_key'], 'simple-up-sell'); + $this->assertNotEmpty($upSellProduct['created_at']); + $this->assertNotEmpty($upSellProduct['id']); + } + + /** + * @param array $relatedProducts + */ + private function assertRelatedProducts(array $relatedProducts): void + { + $expectedData = [ + 'simple' => [ + 'name' => 'Simple Related Product', + 'url_key' => 'simple-related-product', + + ], + 'simple_with_cross_two' => [ + 'name' => 'Simple Product With Related Product Two', + 'url_key' => 'simple-product-with-related-product-two', + ] + ]; + + foreach ($relatedProducts as $product) { + $this->assertArrayHasKey('sku', $product); + $this->assertArrayHasKey('name', $product); + $this->assertArrayHasKey('url_key', $product); + $this->assertArrayHasKey('id', $product); + $this->assertArrayHasKey('created_at', $product); + + $this->assertArrayHasKey($product['sku'], $expectedData); + $productExpectedData = $expectedData[$product['sku']]; + + $this->assertEquals($product['name'], $productExpectedData['name']); + $this->assertEquals($product['url_key'], $productExpectedData['url_key']); + $this->assertNotEmpty($product['created_at']); + $this->assertNotEmpty($product['id']); + } + } +} From ad4efb807a6cff1a00ce138ad0726590a70217bd Mon Sep 17 00:00:00 2001 From: Yogesh Suhagiya Date: Wed, 6 Mar 2019 16:22:04 +0530 Subject: [PATCH 04/42] Fixed internal server error for query urlResolver --- .../UrlRewriteGraphQl/Model/Resolver/EntityUrl.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/EntityUrl.php b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/EntityUrl.php index 1c25ffd1e9ff7..71b31d112668b 100644 --- a/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/EntityUrl.php +++ b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/EntityUrl.php @@ -8,6 +8,7 @@ namespace Magento\UrlRewriteGraphQl\Model\Resolver; use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; @@ -73,6 +74,11 @@ public function resolve( $url = $customUrl ?: $url; $urlRewrite = $this->findCanonicalUrl($url); if ($urlRewrite) { + if (!$urlRewrite->getEntityId()) { + throw new GraphQlNoSuchEntityException( + __('No such entity found with matching URL key: %url', ['url' => $url]) + ); + } $result = [ 'id' => $urlRewrite->getEntityId(), 'canonical_url' => $urlRewrite->getTargetPath(), @@ -99,6 +105,9 @@ private function findCanonicalUrl(string $requestPath) : ?\Magento\UrlRewrite\Se if (!$urlRewrite) { $urlRewrite = $this->findUrlFromTargetPath($requestPath); } + if (!$urlRewrite->getEntityId() && !$urlRewrite->getIsAutogenerated()) { + $urlRewrite = $this->findUrlFromTargetPath($urlRewrite->getTargetPath()); + } return $urlRewrite; } From 8b39eccc987fcbc8da26b7a5069fa4d63f05ae66 Mon Sep 17 00:00:00 2001 From: Yogesh Suhagiya Date: Sat, 9 Mar 2019 14:20:21 +0530 Subject: [PATCH 05/42] Added testGetNonExistentUrlRewrite Test case to cover custom type URL rewrite rule --- .../Model/Resolver/EntityUrl.php | 2 +- .../GraphQl/UrlRewrite/UrlResolverTest.php | 39 +++++++++++++++++++ .../_files/product_with_category.php | 13 +++++++ .../_files/product_with_category_rollback.php | 6 +++ 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/EntityUrl.php b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/EntityUrl.php index 1577aca50121a..6e6c915959a16 100644 --- a/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/EntityUrl.php +++ b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/EntityUrl.php @@ -106,7 +106,7 @@ private function findCanonicalUrl(string $requestPath) : ?\Magento\UrlRewrite\Se if (!$urlRewrite) { $urlRewrite = $this->findUrlFromTargetPath($requestPath); } - if (!$urlRewrite->getEntityId() && !$urlRewrite->getIsAutogenerated()) { + if ($urlRewrite && !$urlRewrite->getEntityId() && !$urlRewrite->getIsAutogenerated()) { $urlRewrite = $this->findUrlFromTargetPath($urlRewrite->getTargetPath()); } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php index 370121a1dad78..cce26e145e454 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php @@ -15,6 +15,7 @@ use Magento\Cms\Helper\Page as PageHelper; use Magento\Store\Model\ScopeInterface; use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\UrlRewrite\Model\UrlRewrite; /** * Test the GraphQL endpoint's URLResolver query to verify canonical URL's are correctly returned. @@ -355,4 +356,42 @@ public function testResolveSlash() $this->assertEquals($targetPath, $response['urlResolver']['relative_url']); $this->assertEquals('CMS_PAGE', $response['urlResolver']['type']); } + + /** + * Test for custom type which point to the valid product/category/cms page. + * + * @magentoApiDataFixture Magento/CatalogUrlRewrite/_files/product_with_category.php + */ + public function testGetNonExistentUrlRewrite() + { + $urlPath = 'non-exist-product.html'; + /** @var UrlRewrite $urlRewrite */ + $urlRewrite = $this->objectManager->create(UrlRewrite::class); + $urlRewrite->load($urlPath, 'request_path'); + + /** @var UrlFinderInterface $urlFinder */ + $urlFinder = $this->objectManager->get(UrlFinderInterface::class); + $actualUrls = $urlFinder->findOneByData( + [ + 'request_path' => $urlPath, + 'store_id' => 1 + ] + ); + $targetPath = $actualUrls->getTargetPath(); + + $query = <<graphQlQuery($query); + $this->assertArrayHasKey('urlResolver', $response); + $this->assertEquals('PRODUCT', $response['urlResolver']['type']); + $this->assertEquals($targetPath, $response['urlResolver']['relative_url']); + } } diff --git a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_with_category.php b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_with_category.php index 2f3d4ea4c3e7f..3c03318942167 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_with_category.php +++ b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_with_category.php @@ -14,6 +14,7 @@ use Magento\Framework\Indexer\IndexerRegistry; use Magento\Store\Model\StoreManagerInterface; use Magento\TestFramework\Helper\Bootstrap; +use Magento\UrlRewrite\Model\UrlRewrite; /** * @var \Magento\Store\Model\Store $store @@ -80,3 +81,15 @@ /** @var CategoryLinkManagementInterface $linkManagement */ $linkManagement = $objectManager->get(CategoryLinkManagementInterface::class); $linkManagement->assignProductToCategories($product->getSku(), [Category::TREE_ROOT_ID, $category->getEntityId()]); + +/** @var UrlRewrite $urlRewrite */ +$urlRewrite = $objectManager->create(UrlRewrite::class); +$urlRewrite->setEntityType('custom') + ->setRequestPath('non-exist-product.html') + ->setTargetPath('catalog/product/view/id/' . $product->getId()) + ->setRedirectType(0) + ->setStoreId(1) + ->setDescription(null) + ->setIsAutogenerated(0); + +$urlRewrite->save(); diff --git a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_with_category_rollback.php b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_with_category_rollback.php index 2598dd6693500..3a1e379213342 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_with_category_rollback.php +++ b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_with_category_rollback.php @@ -9,6 +9,7 @@ use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\TestFramework\Helper\Bootstrap; +use Magento\UrlRewrite\Model\UrlRewrite; $objectManager = Bootstrap::getObjectManager(); /** @var \Magento\Framework\Registry $registry */ @@ -41,6 +42,11 @@ $categoryRepository->delete($category); } +/** @var UrlRewrite $urlRewrite */ +$urlRewrite = $objectManager->create(UrlRewrite::class); +$urlRewrite->load('non-exist-product.html', 'request_path'); +$urlRewrite->delete(); + $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); From 17b7c0a4b0c3f0732e51595fa9b53820e3b73f32 Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko Date: Wed, 20 Mar 2019 17:00:47 +0200 Subject: [PATCH 06/42] graphQl-309: added agreement coverage --- .../Model/Resolver/CheckoutAgreements.php | 48 +++++++++++++ .../DataProvider/CheckoutAgreements.php | 68 +++++++++++++++++++ .../CheckoutAgreementsGraphQl/README.md | 4 ++ .../CheckoutAgreementsGraphQl/composer.json | 26 +++++++ .../CheckoutAgreementsGraphQl/etc/module.xml | 14 ++++ .../etc/schema.graphqls | 15 ++++ .../registration.php | 10 +++ composer.json | 1 + composer.lock | 3 +- .../Api/CheckoutAgreementsListTest.php | 43 ++++++++++++ 10 files changed, 230 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/CheckoutAgreements.php create mode 100644 app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/DataProvider/CheckoutAgreements.php create mode 100644 app/code/Magento/CheckoutAgreementsGraphQl/README.md create mode 100644 app/code/Magento/CheckoutAgreementsGraphQl/composer.json create mode 100644 app/code/Magento/CheckoutAgreementsGraphQl/etc/module.xml create mode 100644 app/code/Magento/CheckoutAgreementsGraphQl/etc/schema.graphqls create mode 100644 app/code/Magento/CheckoutAgreementsGraphQl/registration.php create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/Api/CheckoutAgreementsListTest.php diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/CheckoutAgreements.php b/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/CheckoutAgreements.php new file mode 100644 index 0000000000000..985c30182886a --- /dev/null +++ b/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/CheckoutAgreements.php @@ -0,0 +1,48 @@ +checkoutAgreementsDataProvider = $checkoutAgreementsDataProvider; + } + + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + $checkoutAgreementsData = $this->checkoutAgreementsDataProvider->getData(); + + return $checkoutAgreementsData; + } +} diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/DataProvider/CheckoutAgreements.php b/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/DataProvider/CheckoutAgreements.php new file mode 100644 index 0000000000000..e8efde95ee380 --- /dev/null +++ b/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/DataProvider/CheckoutAgreements.php @@ -0,0 +1,68 @@ +checkoutAgreementsList = $checkoutAgreementsList; + $this->searchCriteriaBuilder = $searchCriteriaBuilder; + } + + /** + * Get All Active Checkout Agreements Data + * + * @return array + */ + public function getData(): array + { + $this->searchCriteriaBuilder->addFilter(AgreementInterface::IS_ACTIVE, true); + $searchCriteria = $this->searchCriteriaBuilder->create(); + $checkoutAgreements = $this->checkoutAgreementsList->getList($searchCriteria); + + $checkoutAgreementData = []; + foreach ($checkoutAgreements as $checkoutAgreement) { + $checkoutAgreementData[] = [ + AgreementInterface::AGREEMENT_ID => $checkoutAgreement->getAgreementId(), + AgreementInterface::CONTENT => $checkoutAgreement->getContent(), + AgreementInterface::NAME => $checkoutAgreement->getName(), + AgreementInterface::CONTENT_HEIGHT => $checkoutAgreement->getContentHeight(), + AgreementInterface::CHECKBOX_TEXT => $checkoutAgreement->getCheckboxText(), + AgreementInterface::IS_HTML => $checkoutAgreement->getIsHtml(), + ]; + } + + return $checkoutAgreementData; + } +} diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/README.md b/app/code/Magento/CheckoutAgreementsGraphQl/README.md new file mode 100644 index 0000000000000..3ef735e3937f5 --- /dev/null +++ b/app/code/Magento/CheckoutAgreementsGraphQl/README.md @@ -0,0 +1,4 @@ +# CheckoutAgreementsGraphQl + +**CheckoutAgreementsGraphQl** provides type information for the GraphQl module +to generate Checkout Agreements fields for Checkout Agreements information endpoints. diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/composer.json b/app/code/Magento/CheckoutAgreementsGraphQl/composer.json new file mode 100644 index 0000000000000..b4196a3008e54 --- /dev/null +++ b/app/code/Magento/CheckoutAgreementsGraphQl/composer.json @@ -0,0 +1,26 @@ +{ + "name": "magento/module-checkout-agreements-graph-ql", + "description": "N/A", + "type": "magento2-module", + "require": { + "php": "~7.1.3||~7.2.0", + "magento/framework": "*", + "magento/module-checkout-agreements": "*" + }, + "suggest": { + "magento/module-graph-ql": "*", + "magento/module-store-graph-ql": "*" + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\CheckoutAgreementsGraphQl\\": "" + } + } +} diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/etc/module.xml b/app/code/Magento/CheckoutAgreementsGraphQl/etc/module.xml new file mode 100644 index 0000000000000..55f09ccf7daee --- /dev/null +++ b/app/code/Magento/CheckoutAgreementsGraphQl/etc/module.xml @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/etc/schema.graphqls b/app/code/Magento/CheckoutAgreementsGraphQl/etc/schema.graphqls new file mode 100644 index 0000000000000..24bf75e2c379b --- /dev/null +++ b/app/code/Magento/CheckoutAgreementsGraphQl/etc/schema.graphqls @@ -0,0 +1,15 @@ +# Copyright © Magento, Inc. All rights reserved. +# See COPYING.txt for license details. + +type Query { + checkoutAgreements: [CheckoutAgreement] @resolver(class: "Magento\\CheckoutAgreementsGraphQl\\Model\\Resolver\\CheckoutAgreements") @doc(description: "The Checkout Agreements query returns information about a Checkout Agreements") +} + +type CheckoutAgreement @doc(description: "Defines all Checkout Agreement information") { + agreement_id: Int @doc(description: "Checkout Agreement identifier") + name: String @doc(description: "Checkout Agreement name") + content: String @doc(description: "Checkout Agreement content") + content_height: String @doc(description: "Checkout Agreement content height") + checkbox_text: String @doc(description: "Checkout Agreement checkbox tex") + is_html: Boolean @doc(description: "Is Checkout Agreement content in HTML format") +} diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/registration.php b/app/code/Magento/CheckoutAgreementsGraphQl/registration.php new file mode 100644 index 0000000000000..b0b4839f33d1f --- /dev/null +++ b/app/code/Magento/CheckoutAgreementsGraphQl/registration.php @@ -0,0 +1,10 @@ +graphQlQuery($query); + $this->assertArrayHasKey('checkoutAgreements', $response); + $agreements = $response['checkoutAgreements']; + $this->assertEquals(1, count($agreements)); + $this->assertEquals('Checkout Agreement (active)', $agreements[0]['name']); + $this->assertEquals('Checkout agreement content: HTML', $agreements[0]['content']); + $this->assertEquals('200px', $agreements[0]['content_height']); + $this->assertEquals('Checkout agreement checkbox text.', $agreements[0]['checkbox_text']); + $this->assertEquals(true, $agreements[0]['is_html']); + } +} From d3190fe74f44646f5e01ca64a5b1df026e491026 Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko Date: Thu, 21 Mar 2019 09:30:38 +0200 Subject: [PATCH 07/42] graphQl-309: static fixes --- .../Model/Resolver/DataProvider/CheckoutAgreements.php | 2 -- .../CheckoutAgreements/Api/CheckoutAgreementsListTest.php | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/DataProvider/CheckoutAgreements.php b/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/DataProvider/CheckoutAgreements.php index e8efde95ee380..2a8ac45ed65cc 100644 --- a/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/DataProvider/CheckoutAgreements.php +++ b/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/DataProvider/CheckoutAgreements.php @@ -9,9 +9,7 @@ use Magento\CheckoutAgreements\Api\CheckoutAgreementsListInterface; use Magento\CheckoutAgreements\Api\Data\AgreementInterface; -use Magento\Cms\Api\Data\PageInterface; use Magento\Framework\Api\SearchCriteriaBuilder; -use Magento\Framework\Exception\NoSuchEntityException; /** * Checkout Agreements data provider diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/Api/CheckoutAgreementsListTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/Api/CheckoutAgreementsListTest.php index 8e743674c38d1..4b419d939c183 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/Api/CheckoutAgreementsListTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/Api/CheckoutAgreementsListTest.php @@ -3,8 +3,9 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); -namespace Magento\GraphQL\CheckoutAgreements\Api; +namespace Magento\GraphQl\CheckoutAgreements\Api; use Magento\TestFramework\TestCase\GraphQlAbstract; From 43ba611c12bbfa99ba691c96ed33594c9220cca2 Mon Sep 17 00:00:00 2001 From: Yogesh Suhagiya Date: Thu, 4 Apr 2019 12:15:20 +0530 Subject: [PATCH 08/42] Covered testNonExistentEntityUrlRewrite case --- .../GraphQl/UrlRewrite/UrlResolverTest.php | 26 +++++++++++++++++++ .../url_rewrite_not_existing_entity.php | 25 ++++++++++++++++++ ...l_rewrite_not_existing_entity_rollback.php | 15 +++++++++++ 3 files changed, 66 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/UrlRewrite/_files/url_rewrite_not_existing_entity.php create mode 100644 dev/tests/integration/testsuite/Magento/UrlRewrite/_files/url_rewrite_not_existing_entity_rollback.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php index cce26e145e454..8eaf33483531d 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php @@ -394,4 +394,30 @@ public function testGetNonExistentUrlRewrite() $this->assertEquals('PRODUCT', $response['urlResolver']['type']); $this->assertEquals($targetPath, $response['urlResolver']['relative_url']); } + + /** + * Test for custom type which point to the invalid product/category/cms page. + * + * @magentoApiDataFixture Magento/UrlRewrite/_files/url_rewrite_not_existing_entity.php + */ + public function testNonExistentEntityUrlRewrite() + { + $urlPath = 'non-exist-entity.html'; + + $query = <<expectExceptionMessage( + "No such entity found with matching URL key: " . $urlPath + ); + $this->graphQlQuery($query); + } } diff --git a/dev/tests/integration/testsuite/Magento/UrlRewrite/_files/url_rewrite_not_existing_entity.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/_files/url_rewrite_not_existing_entity.php new file mode 100644 index 0000000000000..052eac6f79d48 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/_files/url_rewrite_not_existing_entity.php @@ -0,0 +1,25 @@ +create(UrlRewrite::class); +$urlRewrite->setEntityType('custom') + ->setRequestPath('non-exist-entity.html') + ->setTargetPath('catalog/product/view/id/' . $productId) + ->setRedirectType(0) + ->setStoreId(1) + ->setDescription(null) + ->setIsAutogenerated(0); + +$urlRewrite->save(); diff --git a/dev/tests/integration/testsuite/Magento/UrlRewrite/_files/url_rewrite_not_existing_entity_rollback.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/_files/url_rewrite_not_existing_entity_rollback.php new file mode 100644 index 0000000000000..12cbd2c704bfb --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/_files/url_rewrite_not_existing_entity_rollback.php @@ -0,0 +1,15 @@ +create(UrlRewrite::class); +$urlRewrite->load('non-exist-entity.html', 'request_path'); +$urlRewrite->delete(); From 7a905997efa240d577cdba6cdea9ff3aacd2ee34 Mon Sep 17 00:00:00 2001 From: Alex Taranovsky Date: Wed, 10 Apr 2019 14:48:14 +0300 Subject: [PATCH 09/42] magento/graphql-ce#387: Test coverage of getting IDs of CMS page/blocks by GraphQL API --- .../Model/Resolver/DataProvider/Page.php | 51 ++++++++++-- .../CmsGraphQl/Model/Resolver/Page.php | 45 ++++++++-- .../Magento/CmsGraphQl/etc/schema.graphqls | 2 + .../Magento/GraphQl/Cms/CmsPageTest.php | 82 ++++++++++++++++++- 4 files changed, 165 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php index 22009824452be..0745296822c3c 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php @@ -8,8 +8,10 @@ namespace Magento\CmsGraphQl\Model\Resolver\DataProvider; use Magento\Cms\Api\Data\PageInterface; +use Magento\Cms\Api\GetPageByIdentifierInterface; use Magento\Cms\Api\PageRepositoryInterface; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Store\Model\StoreManagerInterface; use Magento\Widget\Model\Template\FilterEmulate; /** @@ -18,9 +20,9 @@ class Page { /** - * @var FilterEmulate + * @var GetPageByIdentifierInterface */ - private $widgetFilter; + private $pageByIdentifier; /** * @var PageRepositoryInterface @@ -28,14 +30,30 @@ class Page private $pageRepository; /** - * @param PageRepositoryInterface $pageRepository + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @var FilterEmulate + */ + private $widgetFilter; + + /** + * @param GetPageByIdentifierInterface $getPageByIdentifier * @param FilterEmulate $widgetFilter + * @param PageRepositoryInterface $pageRepository + * @param StoreManagerInterface $storeManager */ public function __construct( + GetPageByIdentifierInterface $getPageByIdentifier, + FilterEmulate $widgetFilter, PageRepositoryInterface $pageRepository, - FilterEmulate $widgetFilter + StoreManagerInterface $storeManager ) { + $this->pageByIdentifier = $getPageByIdentifier; $this->pageRepository = $pageRepository; + $this->storeManager = $storeManager; $this->widgetFilter = $widgetFilter; } @@ -44,10 +62,32 @@ public function __construct( * @return array * @throws NoSuchEntityException */ - public function getData(int $pageId): array + public function getDataByPageId(int $pageId): array { $page = $this->pageRepository->getById($pageId); + return $this->convertPageData($page); + } + + /** + * @param string $pageIdentifier + * @return array + */ + public function getDataByPageIdentifier(string $pageIdentifier): array + { + $storeId = (int)$this->storeManager->getStore()->getId(); + $page = $this->pageByIdentifier->execute($pageIdentifier, $storeId); + + return $this->convertPageData($page); + } + + /** + * @param PageInterface $page + * @return array + * @throws NoSuchEntityException + */ + private function convertPageData(PageInterface $page) + { if (false === $page->isActive()) { throw new NoSuchEntityException(); } @@ -56,6 +96,7 @@ public function getData(int $pageId): array $pageData = [ 'url_key' => $page->getIdentifier(), + PageInterface::PAGE_ID => $page->getId(), PageInterface::TITLE => $page->getTitle(), PageInterface::CONTENT => $renderedContent, PageInterface::CONTENT_HEADING => $page->getContentHeading(), diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/Page.php b/app/code/Magento/CmsGraphQl/Model/Resolver/Page.php index 1077ab81551c2..41712889a1bfd 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/Page.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/Page.php @@ -26,6 +26,7 @@ class Page implements ResolverInterface private $pageDataProvider; /** + * * @param PageDataProvider $pageDataProvider */ public function __construct( @@ -44,8 +45,15 @@ public function resolve( array $value = null, array $args = null ) { - $pageId = $this->getPageId($args); - $pageData = $this->getPageData($pageId); + if (!isset($args['id']) && !isset($args['identifier'])) { + throw new GraphQlInputException(__('"Page id/identifier should be specified')); + } + + if (isset($args['id'])) { + $pageData = $this->getPageDataById($this->getPageId($args)); + } elseif (isset($args['identifier'])) { + $pageData = $this->getPageDataByIdentifier($this->getPageIdentifier($args)); + } return $pageData; } @@ -53,15 +61,19 @@ public function resolve( /** * @param array $args * @return int - * @throws GraphQlInputException */ private function getPageId(array $args): int { - if (!isset($args['id'])) { - throw new GraphQlInputException(__('"Page id should be specified')); - } + return isset($args['id']) ? (int)$args['id'] : 0; + } - return (int)$args['id']; + /** + * @param array $args + * @return string + */ + private function getPageIdentifier(array $args): string + { + return isset($args['identifier']) ? (string)$args['identifier'] : ''; } /** @@ -69,10 +81,25 @@ private function getPageId(array $args): int * @return array * @throws GraphQlNoSuchEntityException */ - private function getPageData(int $pageId): array + private function getPageDataById(int $pageId): array + { + try { + $pageData = $this->pageDataProvider->getDataByPageId($pageId); + } catch (NoSuchEntityException $e) { + throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e); + } + return $pageData; + } + + /** + * @param string $pageIdentifier + * @return array + * @throws GraphQlNoSuchEntityException + */ + private function getPageDataByIdentifier(string $pageIdentifier): array { try { - $pageData = $this->pageDataProvider->getData($pageId); + $pageData = $this->pageDataProvider->getDataByPageIdentifier($pageIdentifier); } catch (NoSuchEntityException $e) { throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e); } diff --git a/app/code/Magento/CmsGraphQl/etc/schema.graphqls b/app/code/Magento/CmsGraphQl/etc/schema.graphqls index e8abd2201b886..765e58849fc96 100644 --- a/app/code/Magento/CmsGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CmsGraphQl/etc/schema.graphqls @@ -13,6 +13,7 @@ type StoreConfig @doc(description: "The type contains information about a store type Query { cmsPage ( id: Int @doc(description: "Id of the CMS page") + identifier: String @doc(description: "Identifier of the CMS page") ): CmsPage @resolver(class: "Magento\\CmsGraphQl\\Model\\Resolver\\Page") @doc(description: "The CMS page query returns information about a CMS page") cmsBlocks ( identifiers: [String] @doc(description: "Identifiers of the CMS blocks") @@ -20,6 +21,7 @@ type Query { } type CmsPage @doc(description: "CMS page defines all CMS page information") { + page_id: Int @doc(description: "Entity ID of CMS page") url_key: String @doc(description: "URL key of CMS page") title: String @doc(description: "CMS page title") content: String @doc(description: "CMS page content") diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsPageTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsPageTest.php index 86145fafa62f1..8abcee8f22403 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsPageTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsPageTest.php @@ -50,6 +50,32 @@ public function testGetCmsPageById() $this->assertEquals($cmsPageData['meta_keywords'], $response['cmsPage']['meta_keywords']); } + /** + * Verify the fields of CMS Page selected by page_id + * + * @magentoApiDataFixture Magento/Cms/_files/pages.php + */ + public function testGetCmsPageByIdentifier() + { + $cmsPageIdentifier = 'page100'; + $storeId = 0; + + $cmsPage = ObjectManager::getInstance()->get(GetPageByIdentifier::class)->execute($cmsPageIdentifier, $storeId); + $pageId = $cmsPage->getPageId(); + + $query = + <<graphQlQuery($query); + $this->assertEquals($pageId, $response['cmsPage']['page_id']); + } + /** * Verify the message when page_id is not specified. */ @@ -72,7 +98,7 @@ public function testGetCmsPageWithoutId() QUERY; $this->expectException(\Exception::class); - $this->expectExceptionMessage('Page id should be specified'); + $this->expectExceptionMessage('Page id/identifier should be specified'); $this->graphQlQuery($query); } @@ -102,6 +128,32 @@ public function testGetCmsPageByNonExistentId() $this->graphQlQuery($query); } + /** + * Verify the message when identifier does not exist. + * + * @expectedException \Exception + * @expectedExceptionMessage The CMS page with the "" ID doesn't exist. + */ + public function testGetCmsPageByNonExistentIdentifier() + { + $query = + <<graphQlQuery($query); + } + /** * Verify the message when CMS Page selected by page_id is disabled * @@ -130,4 +182,32 @@ public function testGetDisabledCmsPageById() $this->expectExceptionMessage('No such entity.'); $this->graphQlQuery($query); } + + /** + * Verify the message when CMS Page selected by identifier is disabled + * + * @magentoApiDataFixture Magento/Cms/_files/noroute.php + * @expectedException \Exception + * @expectedExceptionMessage The CMS page with the "no-route" ID doesn't exist. + */ + public function testGetDisabledCmsPageByIdentifier() + { + $cmsPageIdentifier = 'no-route'; + $query = + <<graphQlQuery($query); + } } From 8a5b3b7bf87959c6ed9118fcd213cdc34c563ed7 Mon Sep 17 00:00:00 2001 From: Alex Taranovsky Date: Wed, 10 Apr 2019 15:11:08 +0300 Subject: [PATCH 10/42] magento/graphql-ce#387: Test coverage of getting IDs of CMS page/blocks by GraphQL API --- .../Model/Resolver/DataProvider/Block.php | 1 + .../Magento/CmsGraphQl/etc/schema.graphqls | 1 + .../Magento/GraphQl/Cms/CmsBlockTest.php | 38 +++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php index 47a2439c4fad0..fa4944381b858 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php @@ -59,6 +59,7 @@ public function getData(string $blockIdentifier): array $renderedContent = $this->widgetFilter->filter($block->getContent()); $blockData = [ + BlockInterface::BLOCK_ID => $block->getId(), BlockInterface::IDENTIFIER => $block->getIdentifier(), BlockInterface::TITLE => $block->getTitle(), BlockInterface::CONTENT => $renderedContent, diff --git a/app/code/Magento/CmsGraphQl/etc/schema.graphqls b/app/code/Magento/CmsGraphQl/etc/schema.graphqls index 765e58849fc96..5504c42b339f9 100644 --- a/app/code/Magento/CmsGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CmsGraphQl/etc/schema.graphqls @@ -37,6 +37,7 @@ type CmsBlocks @doc(description: "CMS blocks information") { } type CmsBlock @doc(description: "CMS block defines all CMS block information") { + block_id: Int @doc(description: "Entity ID of CMS block") identifier: String @doc(description: "CMS block identifier") title: String @doc(description: "CMS block title") content: String @doc(description: "CMS block content") diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsBlockTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsBlockTest.php index 57f526b1cb2f7..6e07f8cd7876a 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsBlockTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsBlockTest.php @@ -47,6 +47,7 @@ public function testGetCmsBlock() { cmsBlocks(identifiers: "enabled_block") { items { + block_id identifier title content @@ -59,6 +60,43 @@ public function testGetCmsBlock() self::assertArrayHasKey('cmsBlocks', $response); self::assertArrayHasKey('items', $response['cmsBlocks']); + self::assertEquals($cmsBlockData['block_id'], $response['cmsBlocks']['items'][0]['block_id']); + self::assertEquals($cmsBlockData['identifier'], $response['cmsBlocks']['items'][0]['identifier']); + self::assertEquals($cmsBlockData['title'], $response['cmsBlocks']['items'][0]['title']); + self::assertEquals($renderedContent, $response['cmsBlocks']['items'][0]['content']); + } + + /** + * Verify the fields of CMS Block selected by block_id + * + * @magentoApiDataFixture Magento/Cms/_files/blocks.php + */ + public function testGetCmsBlockByBlockId() + { + $cmsBlock = $this->blockRepository->getById('enabled_block'); + $cmsBlockData = $cmsBlock->getData(); + $blockId = $cmsBlockData['block_id']; + $renderedContent = $this->filterEmulate->setUseSessionInUrl(false)->filter($cmsBlock->getContent()); + + $query = + <<graphQlQuery($query); + + self::assertArrayHasKey('cmsBlocks', $response); + self::assertArrayHasKey('items', $response['cmsBlocks']); + + self::assertEquals($blockId, $response['cmsBlocks']['items'][0]['block_id']); self::assertEquals($cmsBlockData['identifier'], $response['cmsBlocks']['items'][0]['identifier']); self::assertEquals($cmsBlockData['title'], $response['cmsBlocks']['items'][0]['title']); self::assertEquals($renderedContent, $response['cmsBlocks']['items'][0]['content']); From b8d93d8533ba09e5d83cc119f3c7ab1dea5925b4 Mon Sep 17 00:00:00 2001 From: Alex Taranovsky Date: Thu, 11 Apr 2019 09:42:39 +0300 Subject: [PATCH 11/42] magento/graphql-ce#387: Test coverage of getting IDs of CMS page/blocks by GraphQL API 1. Set hard dependency --- app/code/Magento/CmsGraphQl/composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/CmsGraphQl/composer.json b/app/code/Magento/CmsGraphQl/composer.json index 6a2e3950f93d0..bea7ee1356d80 100644 --- a/app/code/Magento/CmsGraphQl/composer.json +++ b/app/code/Magento/CmsGraphQl/composer.json @@ -6,6 +6,7 @@ "php": "~7.1.3||~7.2.0", "magento/framework": "*", "magento/module-cms": "*", + "magento/module-store": "*", "magento/module-widget": "*" }, "suggest": { From 263588a28f1b529ce225f62cc87b4d4639614e39 Mon Sep 17 00:00:00 2001 From: Alex Taranovsky Date: Tue, 16 Apr 2019 09:22:28 +0300 Subject: [PATCH 12/42] magento/graphql-ce#387: Test coverage of getting IDs of CMS page/blocks by GraphQL API --- .../Model/Resolver/DataProvider/Page.php | 54 ++------- .../DataProvider/PageDataProvider.php | 110 ++++++++++++++++++ .../CmsGraphQl/Model/Resolver/Page.php | 2 +- 3 files changed, 119 insertions(+), 47 deletions(-) create mode 100644 app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/PageDataProvider.php diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php index 0745296822c3c..e943ba0c2fd5e 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php @@ -8,21 +8,22 @@ namespace Magento\CmsGraphQl\Model\Resolver\DataProvider; use Magento\Cms\Api\Data\PageInterface; -use Magento\Cms\Api\GetPageByIdentifierInterface; use Magento\Cms\Api\PageRepositoryInterface; use Magento\Framework\Exception\NoSuchEntityException; -use Magento\Store\Model\StoreManagerInterface; use Magento\Widget\Model\Template\FilterEmulate; /** + * @deprecated + * @see Magento\CmsGraphQl\Model\Resolver\DataProvider\PageDataProvider + * * Cms page data provider */ class Page { /** - * @var GetPageByIdentifierInterface + * @var FilterEmulate */ - private $pageByIdentifier; + private $widgetFilter; /** * @var PageRepositoryInterface @@ -30,30 +31,14 @@ class Page private $pageRepository; /** - * @var StoreManagerInterface - */ - private $storeManager; - - /** - * @var FilterEmulate - */ - private $widgetFilter; - - /** - * @param GetPageByIdentifierInterface $getPageByIdentifier - * @param FilterEmulate $widgetFilter * @param PageRepositoryInterface $pageRepository - * @param StoreManagerInterface $storeManager + * @param FilterEmulate $widgetFilter */ public function __construct( - GetPageByIdentifierInterface $getPageByIdentifier, - FilterEmulate $widgetFilter, PageRepositoryInterface $pageRepository, - StoreManagerInterface $storeManager + FilterEmulate $widgetFilter ) { - $this->pageByIdentifier = $getPageByIdentifier; $this->pageRepository = $pageRepository; - $this->storeManager = $storeManager; $this->widgetFilter = $widgetFilter; } @@ -62,32 +47,10 @@ public function __construct( * @return array * @throws NoSuchEntityException */ - public function getDataByPageId(int $pageId): array + public function getData(int $pageId): array { $page = $this->pageRepository->getById($pageId); - return $this->convertPageData($page); - } - - /** - * @param string $pageIdentifier - * @return array - */ - public function getDataByPageIdentifier(string $pageIdentifier): array - { - $storeId = (int)$this->storeManager->getStore()->getId(); - $page = $this->pageByIdentifier->execute($pageIdentifier, $storeId); - - return $this->convertPageData($page); - } - - /** - * @param PageInterface $page - * @return array - * @throws NoSuchEntityException - */ - private function convertPageData(PageInterface $page) - { if (false === $page->isActive()) { throw new NoSuchEntityException(); } @@ -96,7 +59,6 @@ private function convertPageData(PageInterface $page) $pageData = [ 'url_key' => $page->getIdentifier(), - PageInterface::PAGE_ID => $page->getId(), PageInterface::TITLE => $page->getTitle(), PageInterface::CONTENT => $renderedContent, PageInterface::CONTENT_HEADING => $page->getContentHeading(), diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/PageDataProvider.php b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/PageDataProvider.php new file mode 100644 index 0000000000000..7391f736e95e6 --- /dev/null +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/PageDataProvider.php @@ -0,0 +1,110 @@ +pageByIdentifier = $getPageByIdentifier; + $this->pageRepository = $pageRepository; + $this->storeManager = $storeManager; + $this->widgetFilter = $widgetFilter; + } + + /** + * @param int $pageId + * @return array + * @throws NoSuchEntityException + */ + public function getDataByPageId(int $pageId): array + { + $page = $this->pageRepository->getById($pageId); + + return $this->convertPageData($page); + } + + /** + * @param string $pageIdentifier + * @return array + */ + public function getDataByPageIdentifier(string $pageIdentifier): array + { + $storeId = (int)$this->storeManager->getStore()->getId(); + $page = $this->pageByIdentifier->execute($pageIdentifier, $storeId); + + return $this->convertPageData($page); + } + + /** + * @param PageInterface $page + * @return array + * @throws NoSuchEntityException + */ + private function convertPageData(PageInterface $page) + { + if (false === $page->isActive()) { + throw new NoSuchEntityException(); + } + + $renderedContent = $this->widgetFilter->filter($page->getContent()); + + $pageData = [ + 'url_key' => $page->getIdentifier(), + PageInterface::PAGE_ID => $page->getId(), + PageInterface::TITLE => $page->getTitle(), + PageInterface::CONTENT => $renderedContent, + PageInterface::CONTENT_HEADING => $page->getContentHeading(), + PageInterface::PAGE_LAYOUT => $page->getPageLayout(), + PageInterface::META_TITLE => $page->getMetaTitle(), + PageInterface::META_DESCRIPTION => $page->getMetaDescription(), + PageInterface::META_KEYWORDS => $page->getMetaKeywords(), + ]; + return $pageData; + } +} diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/Page.php b/app/code/Magento/CmsGraphQl/Model/Resolver/Page.php index 41712889a1bfd..544a09c780070 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/Page.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/Page.php @@ -7,7 +7,7 @@ namespace Magento\CmsGraphQl\Model\Resolver; -use Magento\CmsGraphQl\Model\Resolver\DataProvider\Page as PageDataProvider; +use Magento\CmsGraphQl\Model\Resolver\DataProvider\PageDataProvider as PageDataProvider; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Exception\GraphQlInputException; From 81984dc80fa1f436aecc752222efd588090d5a37 Mon Sep 17 00:00:00 2001 From: Alex Taranovsky Date: Tue, 16 Apr 2019 09:32:51 +0300 Subject: [PATCH 13/42] magento/graphql-ce#387: Test coverage of getting IDs of CMS page/blocks by GraphQL API --- .../CmsGraphQl/Model/Resolver/DataProvider/PageDataProvider.php | 1 + app/code/Magento/CmsGraphQl/etc/schema.graphqls | 1 + 2 files changed, 2 insertions(+) diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/PageDataProvider.php b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/PageDataProvider.php index 7391f736e95e6..fdcd0c88cd60c 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/PageDataProvider.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/PageDataProvider.php @@ -97,6 +97,7 @@ private function convertPageData(PageInterface $page) $pageData = [ 'url_key' => $page->getIdentifier(), PageInterface::PAGE_ID => $page->getId(), + PageInterface::IDENTIFIER => $page->getIdentifier(), PageInterface::TITLE => $page->getTitle(), PageInterface::CONTENT => $renderedContent, PageInterface::CONTENT_HEADING => $page->getContentHeading(), diff --git a/app/code/Magento/CmsGraphQl/etc/schema.graphqls b/app/code/Magento/CmsGraphQl/etc/schema.graphqls index 5504c42b339f9..8c0cb80f34269 100644 --- a/app/code/Magento/CmsGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CmsGraphQl/etc/schema.graphqls @@ -22,6 +22,7 @@ type Query { type CmsPage @doc(description: "CMS page defines all CMS page information") { page_id: Int @doc(description: "Entity ID of CMS page") + identifier: String @doc(description: "Identifier of the CMS page") url_key: String @doc(description: "URL key of CMS page") title: String @doc(description: "CMS page title") content: String @doc(description: "CMS page content") From 6a8c89ba4a791bb32a82e77463ec0f4d1f7cfcf0 Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko Date: Wed, 17 Apr 2019 16:27:07 +0300 Subject: [PATCH 14/42] graphQl-309: checkout agreements support multistore --- .../Model/Resolver/CheckoutAgreements.php | 2 +- .../DataProvider/CheckoutAgreements.php | 34 ++--- .../CheckoutAgreementsGraphQl/etc/module.xml | 6 +- .../etc/schema.graphqls | 2 +- .../Api/CheckoutAgreementsListTest.php | 124 ++++++++++++++++-- 5 files changed, 135 insertions(+), 33 deletions(-) diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/CheckoutAgreements.php b/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/CheckoutAgreements.php index 985c30182886a..7009e1e2d85e6 100644 --- a/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/CheckoutAgreements.php +++ b/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/CheckoutAgreements.php @@ -13,7 +13,7 @@ use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; /** - * CMS page field resolver, used for GraphQL request processing + * Checkout Agreements resolver, used for GraphQL request processing */ class CheckoutAgreements implements ResolverInterface { diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/DataProvider/CheckoutAgreements.php b/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/DataProvider/CheckoutAgreements.php index 2a8ac45ed65cc..c235d348375c5 100644 --- a/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/DataProvider/CheckoutAgreements.php +++ b/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/DataProvider/CheckoutAgreements.php @@ -7,9 +7,10 @@ namespace Magento\CheckoutAgreementsGraphQl\Model\Resolver\DataProvider; -use Magento\CheckoutAgreements\Api\CheckoutAgreementsListInterface; use Magento\CheckoutAgreements\Api\Data\AgreementInterface; -use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\CheckoutAgreements\Model\Agreement; +use Magento\CheckoutAgreements\Model\ResourceModel\Agreement\CollectionFactory; +use Magento\Store\Model\StoreManagerInterface; /** * Checkout Agreements data provider @@ -17,25 +18,25 @@ class CheckoutAgreements { /** - * @var SearchCriteriaBuilder + * @var CollectionFactory */ - private $searchCriteriaBuilder; + private $agreementCollectionFactory; /** - * @var CheckoutAgreementsListInterface + * @var StoreManagerInterface */ - private $checkoutAgreementsList; + private $storeManager; /** - * @param CheckoutAgreementsListInterface $checkoutAgreementsList - * @param SearchCriteriaBuilder $searchCriteriaBuilder + * @param CollectionFactory $agreementCollectionFactory + * @param StoreManagerInterface $storeManager */ public function __construct( - CheckoutAgreementsListInterface $checkoutAgreementsList, - SearchCriteriaBuilder $searchCriteriaBuilder + CollectionFactory $agreementCollectionFactory, + StoreManagerInterface $storeManager ) { - $this->checkoutAgreementsList = $checkoutAgreementsList; - $this->searchCriteriaBuilder = $searchCriteriaBuilder; + $this->agreementCollectionFactory = $agreementCollectionFactory; + $this->storeManager = $storeManager; } /** @@ -45,12 +46,13 @@ public function __construct( */ public function getData(): array { - $this->searchCriteriaBuilder->addFilter(AgreementInterface::IS_ACTIVE, true); - $searchCriteria = $this->searchCriteriaBuilder->create(); - $checkoutAgreements = $this->checkoutAgreementsList->getList($searchCriteria); + $agreementsCollection = $this->agreementCollectionFactory->create(); + $agreementsCollection->addStoreFilter($this->storeManager->getStore()->getId()); // TODO: store should be get from query context + $agreementsCollection->addFieldToFilter('is_active', 1); $checkoutAgreementData = []; - foreach ($checkoutAgreements as $checkoutAgreement) { + /** @var Agreement $checkoutAgreement */ + foreach ($agreementsCollection->getItems() as $checkoutAgreement) { $checkoutAgreementData[] = [ AgreementInterface::AGREEMENT_ID => $checkoutAgreement->getAgreementId(), AgreementInterface::CONTENT => $checkoutAgreement->getContent(), diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/etc/module.xml b/app/code/Magento/CheckoutAgreementsGraphQl/etc/module.xml index 55f09ccf7daee..d18e8ee17d097 100644 --- a/app/code/Magento/CheckoutAgreementsGraphQl/etc/module.xml +++ b/app/code/Magento/CheckoutAgreementsGraphQl/etc/module.xml @@ -6,9 +6,5 @@ */ --> - - - - - + diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/etc/schema.graphqls b/app/code/Magento/CheckoutAgreementsGraphQl/etc/schema.graphqls index 24bf75e2c379b..e63368bb3c884 100644 --- a/app/code/Magento/CheckoutAgreementsGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CheckoutAgreementsGraphQl/etc/schema.graphqls @@ -2,7 +2,7 @@ # See COPYING.txt for license details. type Query { - checkoutAgreements: [CheckoutAgreement] @resolver(class: "Magento\\CheckoutAgreementsGraphQl\\Model\\Resolver\\CheckoutAgreements") @doc(description: "The Checkout Agreements query returns information about a Checkout Agreements") + checkoutAgreements: [CheckoutAgreement] @resolver(class: "Magento\\CheckoutAgreementsGraphQl\\Model\\Resolver\\CheckoutAgreements") @doc(description: "The Checkout Agreements information") } type CheckoutAgreement @doc(description: "Defines all Checkout Agreement information") { diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/Api/CheckoutAgreementsListTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/Api/CheckoutAgreementsListTest.php index 4b419d939c183..38498fb016f3c 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/Api/CheckoutAgreementsListTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/Api/CheckoutAgreementsListTest.php @@ -7,17 +7,111 @@ namespace Magento\GraphQl\CheckoutAgreements\Api; +use Magento\CheckoutAgreements\Api\Data\AgreementInterface; +use Magento\CheckoutAgreements\Model\Agreement as AgreementModel; +use Magento\CheckoutAgreements\Model\AgreementFactory; +use Magento\CheckoutAgreements\Model\ResourceModel\Agreement; +use Magento\Framework\ObjectManagerInterface; +use Magento\Store\Model\StoreManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\GraphQlAbstract; class CheckoutAgreementsListTest extends GraphQlAbstract { + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + protected function setUp() + { + parent::setUp(); + $this->objectManager = Bootstrap::getObjectManager(); + } + /** * @magentoApiDataFixture Magento/CheckoutAgreements/_files/agreement_active_with_html_content.php * @magentoApiDataFixture Magento/CheckoutAgreements/_files/agreement_inactive_with_text_content.php */ public function testGetActiveAgreement() { - $query = + $query = $this->getQuery(); + + $response = $this->graphQlQuery($query); + + $this->assertArrayHasKey('checkoutAgreements', $response); + $agreements = $response['checkoutAgreements']; + $this->assertCount(1, $agreements); + $this->assertEquals('Checkout Agreement (active)', $agreements[0]['name']); + $this->assertEquals('Checkout agreement content: HTML', $agreements[0]['content']); + $this->assertEquals('200px', $agreements[0]['content_height']); + $this->assertEquals('Checkout agreement checkbox text.', $agreements[0]['checkbox_text']); + $this->assertEquals(true, $agreements[0]['is_html']); + } + + /** + * @magentoApiDataFixture Magento/CheckoutAgreements/_files/agreement_active_with_html_content.php + * @magentoApiDataFixture Magento/CheckoutAgreements/_files/agreement_inactive_with_text_content.php + * @magentoApiDataFixture Magento/Store/_files/second_store.php + */ + public function testGetActiveAgreementOnSecondStore() + { + $secondStoreCode = 'fixture_second_store'; + $agreementsName = 'Checkout Agreement (active)'; + + $query = $this->getQuery(); + $this->assignAgreementsToStore($secondStoreCode, $agreementsName); + + $headerMap['Store'] = $secondStoreCode; + $response = $this->graphQlQuery($query, [], '', $headerMap); + + $this->assertArrayHasKey('checkoutAgreements', $response); + $agreements = $response['checkoutAgreements']; + $this->assertCount(1, $agreements); + $this->assertEquals($agreementsName, $agreements[0]['name']); + $this->assertEquals('Checkout agreement content: HTML', $agreements[0]['content']); + $this->assertEquals('200px', $agreements[0]['content_height']); + $this->assertEquals('Checkout agreement checkbox text.', $agreements[0]['checkbox_text']); + $this->assertEquals(true, $agreements[0]['is_html']); + } + + /** + * @magentoApiDataFixture Magento/CheckoutAgreements/_files/agreement_active_with_html_content.php + * @magentoApiDataFixture Magento/CheckoutAgreements/_files/agreement_inactive_with_text_content.php + * @magentoApiDataFixture Magento/Store/_files/second_store.php + */ + public function testGetActiveAgreementFromSecondStoreOnDefaultStore() + { + $secondStoreCode = 'fixture_second_store'; + $agreementsName = 'Checkout Agreement (active)'; + + $query = $this->getQuery(); + $this->assignAgreementsToStore($secondStoreCode, $agreementsName); + + $response = $this->graphQlQuery($query); + + $this->assertArrayHasKey('checkoutAgreements', $response); + $agreements = $response['checkoutAgreements']; + $this->assertCount(0, $agreements); + } + + public function testGetAgreementNotSet() + { + $query = $this->getQuery(); + + $response = $this->graphQlQuery($query); + + $this->assertArrayHasKey('checkoutAgreements', $response); + $agreements = $response['checkoutAgreements']; + $this->assertCount(0, $agreements); + } + + /** + * @return string + */ + private function getQuery(): string + { + return <<graphQlQuery($query); - $this->assertArrayHasKey('checkoutAgreements', $response); - $agreements = $response['checkoutAgreements']; - $this->assertEquals(1, count($agreements)); - $this->assertEquals('Checkout Agreement (active)', $agreements[0]['name']); - $this->assertEquals('Checkout agreement content: HTML', $agreements[0]['content']); - $this->assertEquals('200px', $agreements[0]['content_height']); - $this->assertEquals('Checkout agreement checkbox text.', $agreements[0]['checkbox_text']); - $this->assertEquals(true, $agreements[0]['is_html']); + /** + * @param string $storeCode + * @param string $agreementsName + * @return void + */ + private function assignAgreementsToStore(string $storeCode, string $agreementsName): void + { + $agreementsFactory = $this->objectManager->get(AgreementFactory::class); + /** @var Agreement $agreementsResource */ + $agreementsResource = $this->objectManager->get(Agreement::class); + /** @var StoreManagerInterface $storeManager */ + $storeManager = $this->objectManager->get(StoreManagerInterface::class); + $store = $storeManager->getStore($storeCode); + /** @var AgreementModel $agreements */ + $agreements = $agreementsFactory->create(); + $agreementsResource->load($agreements, $agreementsName, AgreementInterface::NAME); + $agreements->setData('stores', [$store->getId()]); + $agreementsResource->save($agreements); } } From f90a6201fa294844ac9a06daf3187bf0ae9c8224 Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko Date: Wed, 17 Apr 2019 19:07:58 +0300 Subject: [PATCH 15/42] graphQl-309: checkout agreements support config --- .../DataProvider/CheckoutAgreements.php | 15 ++- .../Api/CheckoutAgreementsListTest.php | 91 +++++++++++++++++++ 2 files changed, 105 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/DataProvider/CheckoutAgreements.php b/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/DataProvider/CheckoutAgreements.php index c235d348375c5..3dab845627261 100644 --- a/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/DataProvider/CheckoutAgreements.php +++ b/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/DataProvider/CheckoutAgreements.php @@ -10,6 +10,8 @@ use Magento\CheckoutAgreements\Api\Data\AgreementInterface; use Magento\CheckoutAgreements\Model\Agreement; use Magento\CheckoutAgreements\Model\ResourceModel\Agreement\CollectionFactory; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Store\Model\ScopeInterface; use Magento\Store\Model\StoreManagerInterface; /** @@ -27,16 +29,24 @@ class CheckoutAgreements */ private $storeManager; + /** + * @var ScopeConfigInterface + */ + private $scopeConfig; + /** * @param CollectionFactory $agreementCollectionFactory * @param StoreManagerInterface $storeManager + * @param ScopeConfigInterface $scopeConfig */ public function __construct( CollectionFactory $agreementCollectionFactory, - StoreManagerInterface $storeManager + StoreManagerInterface $storeManager, + ScopeConfigInterface $scopeConfig ) { $this->agreementCollectionFactory = $agreementCollectionFactory; $this->storeManager = $storeManager; + $this->scopeConfig = $scopeConfig; } /** @@ -46,6 +56,9 @@ public function __construct( */ public function getData(): array { + if (!$this->scopeConfig->isSetFlag('checkout/options/enable_agreements', ScopeInterface::SCOPE_STORE)) { + return []; + } $agreementsCollection = $this->agreementCollectionFactory->create(); $agreementsCollection->addStoreFilter($this->storeManager->getStore()->getId()); // TODO: store should be get from query context $agreementsCollection->addFieldToFilter('is_active', 1); diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/Api/CheckoutAgreementsListTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/Api/CheckoutAgreementsListTest.php index 38498fb016f3c..17fa58be72fa2 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/Api/CheckoutAgreementsListTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/Api/CheckoutAgreementsListTest.php @@ -11,22 +11,37 @@ use Magento\CheckoutAgreements\Model\Agreement as AgreementModel; use Magento\CheckoutAgreements\Model\AgreementFactory; use Magento\CheckoutAgreements\Model\ResourceModel\Agreement; +use Magento\Config\Model\ResourceModel\Config; +use Magento\Framework\App\Config\ReinitableConfigInterface; +use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\ObjectManagerInterface; +use Magento\Store\Api\Data\StoreInterface; +use Magento\Store\Model\ScopeInterface; use Magento\Store\Model\StoreManagerInterface; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\GraphQlAbstract; class CheckoutAgreementsListTest extends GraphQlAbstract { + private $agreementsXmlConfigPath = 'checkout/options/enable_agreements'; + /** * @var ObjectManagerInterface */ private $objectManager; + /** + * @var Config + */ + private $config; + protected function setUp() { parent::setUp(); + $this->objectManager = Bootstrap::getObjectManager(); + $this->config = $this->objectManager->get(Config::class); + $this->saveAgreementConfig(1); } /** @@ -106,6 +121,34 @@ public function testGetAgreementNotSet() $this->assertCount(0, $agreements); } + /** + * @magentoApiDataFixture Magento/CheckoutAgreements/_files/agreement_active_with_html_content.php + * @magentoApiDataFixture Magento/CheckoutAgreements/_files/agreement_inactive_with_text_content.php + * @magentoApiDataFixture Magento/Store/_files/second_store.php + */ + public function testDisabledAgreements() + { + $secondStoreCode = 'fixture_second_store'; + $agreementsName = 'Checkout Agreement (active)'; + + $query = $this->getQuery(); + $this->assignAgreementsToStore($secondStoreCode, $agreementsName); + + /** @var StoreManagerInterface $storeManager */ + $storeManager = $this->objectManager->get(StoreManagerInterface::class); + $store = $storeManager->getStore($secondStoreCode); + $this->saveAgreementConfig(0, $store); + + $headerMap['Store'] = $secondStoreCode; + $response = $this->graphQlQuery($query, [], '', $headerMap); + + $this->assertArrayHasKey('checkoutAgreements', $response); + $agreements = $response['checkoutAgreements']; + $this->assertCount(0, $agreements); + + $this->deleteAgreementConfig($store); + } + /** * @return string */ @@ -145,4 +188,52 @@ private function assignAgreementsToStore(string $storeCode, string $agreementsNa $agreements->setData('stores', [$store->getId()]); $agreementsResource->save($agreements); } + + protected function tearDown() + { + parent::tearDown(); + + $this->deleteAgreementConfig(); + } + + /** + * @param int $value + * @param StoreInterface $store + */ + private function saveAgreementConfig(int $value, ?StoreInterface $store = null): void + { + $scopeId = $store ? $store->getId() : 0; + $scope = $store ? ScopeInterface::SCOPE_STORE : ScopeConfigInterface::SCOPE_TYPE_DEFAULT; + $this->config->saveConfig( + $this->agreementsXmlConfigPath, + $value, + $scope, + $scopeId + ); + + $this->reinitConfig(); + } + + /** + * @param StoreInterface $store + */ + private function deleteAgreementConfig(?StoreInterface $store = null): void + { + $scopeId = $store ? $store->getId() : 0; + $scope = $store ? ScopeInterface::SCOPE_STORE : ScopeConfigInterface::SCOPE_TYPE_DEFAULT; + $this->config->deleteConfig( + $this->agreementsXmlConfigPath, + $scope, + $scopeId + ); + + $this->reinitConfig(); + } + + private function reinitConfig(): void + { + /** @var ReinitableConfigInterface $config */ + $config = $this->objectManager->get(ReinitableConfigInterface::class); + $config->reinit(); + } } From 6b930331a8bc720d5e225f04a7aa25e5ed6ac01e Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko Date: Wed, 17 Apr 2019 21:43:54 +0300 Subject: [PATCH 16/42] graphQl-309: fixed tests --- composer.lock | 33 +++++++++++++++- .../Api/CheckoutAgreementsListTest.php | 39 +++++++------------ 2 files changed, 45 insertions(+), 27 deletions(-) diff --git a/composer.lock b/composer.lock index 8747ecc6d8d28..db753d6de6cff 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7d2484d86d4d31622f2427d46724ca6f", + "content-hash": "d5945e7c615def5bc906a9e876235934", "packages": [ { "name": "braintree/braintree_php", @@ -6618,6 +6618,36 @@ ], "time": "2018-02-14T22:37:14+00:00" }, + { + "name": "magento/magento-coding-standard", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/magento/magento-coding-standard.git", + "reference": "f7de26fb6add389d1b42286f67ee87424588a868" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/magento/magento-coding-standard/zipball/f7de26fb6add389d1b42286f67ee87424588a868", + "reference": "f7de26fb6add389d1b42286f67ee87424588a868", + "shasum": "" + }, + "require": { + "php": ">=5.6.0", + "squizlabs/php_codesniffer": "~3.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "type": "phpcodesniffer-standard", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "A set of Magento specific PHP CodeSniffer rules.", + "time": "2019-04-05T19:05:17+00:00" + }, { "name": "magento/magento2-functional-testing-framework", "version": "2.3.14", @@ -7842,6 +7872,7 @@ "mock", "xunit" ], + "abandoned": true, "time": "2018-08-09T05:50:03+00:00" }, { diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/Api/CheckoutAgreementsListTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/Api/CheckoutAgreementsListTest.php index 17fa58be72fa2..62491e5e8376b 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/Api/CheckoutAgreementsListTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/Api/CheckoutAgreementsListTest.php @@ -16,7 +16,6 @@ use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\ObjectManagerInterface; use Magento\Store\Api\Data\StoreInterface; -use Magento\Store\Model\ScopeInterface; use Magento\Store\Model\StoreManagerInterface; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\GraphQlAbstract; @@ -40,6 +39,8 @@ protected function setUp() parent::setUp(); $this->objectManager = Bootstrap::getObjectManager(); + + // TODO: remove usage of the Config, use ConfigFixture instead https://github.com/magento/graphql-ce/issues/167 $this->config = $this->objectManager->get(Config::class); $this->saveAgreementConfig(1); } @@ -124,29 +125,17 @@ public function testGetAgreementNotSet() /** * @magentoApiDataFixture Magento/CheckoutAgreements/_files/agreement_active_with_html_content.php * @magentoApiDataFixture Magento/CheckoutAgreements/_files/agreement_inactive_with_text_content.php - * @magentoApiDataFixture Magento/Store/_files/second_store.php */ public function testDisabledAgreements() { - $secondStoreCode = 'fixture_second_store'; - $agreementsName = 'Checkout Agreement (active)'; - $query = $this->getQuery(); - $this->assignAgreementsToStore($secondStoreCode, $agreementsName); + $this->saveAgreementConfig(0); - /** @var StoreManagerInterface $storeManager */ - $storeManager = $this->objectManager->get(StoreManagerInterface::class); - $store = $storeManager->getStore($secondStoreCode); - $this->saveAgreementConfig(0, $store); - - $headerMap['Store'] = $secondStoreCode; - $response = $this->graphQlQuery($query, [], '', $headerMap); + $response = $this->graphQlQuery($query); $this->assertArrayHasKey('checkoutAgreements', $response); $agreements = $response['checkoutAgreements']; $this->assertCount(0, $agreements); - - $this->deleteAgreementConfig($store); } /** @@ -200,31 +189,29 @@ protected function tearDown() * @param int $value * @param StoreInterface $store */ - private function saveAgreementConfig(int $value, ?StoreInterface $store = null): void + private function saveAgreementConfig(int $value): void { - $scopeId = $store ? $store->getId() : 0; - $scope = $store ? ScopeInterface::SCOPE_STORE : ScopeConfigInterface::SCOPE_TYPE_DEFAULT; $this->config->saveConfig( $this->agreementsXmlConfigPath, $value, - $scope, - $scopeId + ScopeConfigInterface::SCOPE_TYPE_DEFAULT, + 0 ); $this->reinitConfig(); } /** - * @param StoreInterface $store + * Delete config + * + * @return void */ - private function deleteAgreementConfig(?StoreInterface $store = null): void + private function deleteAgreementConfig(): void { - $scopeId = $store ? $store->getId() : 0; - $scope = $store ? ScopeInterface::SCOPE_STORE : ScopeConfigInterface::SCOPE_TYPE_DEFAULT; $this->config->deleteConfig( $this->agreementsXmlConfigPath, - $scope, - $scopeId + ScopeConfigInterface::SCOPE_TYPE_DEFAULT, + 0 ); $this->reinitConfig(); From cc5e2170467bb676e83e1fbad121f2ff51a7fb96 Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko Date: Thu, 18 Apr 2019 08:38:20 +0300 Subject: [PATCH 17/42] graphQl-309: fixed dependency --- app/code/Magento/CheckoutAgreementsGraphQl/composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/composer.json b/app/code/Magento/CheckoutAgreementsGraphQl/composer.json index b4196a3008e54..064e8f7c2ec94 100644 --- a/app/code/Magento/CheckoutAgreementsGraphQl/composer.json +++ b/app/code/Magento/CheckoutAgreementsGraphQl/composer.json @@ -5,6 +5,7 @@ "require": { "php": "~7.1.3||~7.2.0", "magento/framework": "*", + "magento/module-store": "*", "magento/module-checkout-agreements": "*" }, "suggest": { From f4a4a340b4983ad80a5ede504993ed8d753c5f9d Mon Sep 17 00:00:00 2001 From: Alex Taranovsky Date: Wed, 24 Apr 2019 12:31:05 +0300 Subject: [PATCH 18/42] magento/graphql-ce#387: Test coverage of getting IDs of CMS page/blocks by GraphQL API --- .../CmsGraphQl/Model/Resolver/DataProvider/Block.php | 1 - .../Model/Resolver/DataProvider/PageDataProvider.php | 1 - app/code/Magento/CmsGraphQl/etc/schema.graphqls | 4 +--- .../testsuite/Magento/GraphQl/Cms/CmsBlockTest.php | 5 ----- .../testsuite/Magento/GraphQl/Cms/CmsPageTest.php | 8 ++------ 5 files changed, 3 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php index fa4944381b858..47a2439c4fad0 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php @@ -59,7 +59,6 @@ public function getData(string $blockIdentifier): array $renderedContent = $this->widgetFilter->filter($block->getContent()); $blockData = [ - BlockInterface::BLOCK_ID => $block->getId(), BlockInterface::IDENTIFIER => $block->getIdentifier(), BlockInterface::TITLE => $block->getTitle(), BlockInterface::CONTENT => $renderedContent, diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/PageDataProvider.php b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/PageDataProvider.php index fdcd0c88cd60c..47fa4c08a9c31 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/PageDataProvider.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/PageDataProvider.php @@ -96,7 +96,6 @@ private function convertPageData(PageInterface $page) $pageData = [ 'url_key' => $page->getIdentifier(), - PageInterface::PAGE_ID => $page->getId(), PageInterface::IDENTIFIER => $page->getIdentifier(), PageInterface::TITLE => $page->getTitle(), PageInterface::CONTENT => $renderedContent, diff --git a/app/code/Magento/CmsGraphQl/etc/schema.graphqls b/app/code/Magento/CmsGraphQl/etc/schema.graphqls index 8c0cb80f34269..85bff91dea8a2 100644 --- a/app/code/Magento/CmsGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CmsGraphQl/etc/schema.graphqls @@ -12,7 +12,7 @@ type StoreConfig @doc(description: "The type contains information about a store type Query { cmsPage ( - id: Int @doc(description: "Id of the CMS page") + id: Int @doc(description: "Id of the CMS page") @deprecated(reason: "Use `identifier`") @doc(description: "The CMS page query returns information about a CMS page") identifier: String @doc(description: "Identifier of the CMS page") ): CmsPage @resolver(class: "Magento\\CmsGraphQl\\Model\\Resolver\\Page") @doc(description: "The CMS page query returns information about a CMS page") cmsBlocks ( @@ -21,7 +21,6 @@ type Query { } type CmsPage @doc(description: "CMS page defines all CMS page information") { - page_id: Int @doc(description: "Entity ID of CMS page") identifier: String @doc(description: "Identifier of the CMS page") url_key: String @doc(description: "URL key of CMS page") title: String @doc(description: "CMS page title") @@ -38,7 +37,6 @@ type CmsBlocks @doc(description: "CMS blocks information") { } type CmsBlock @doc(description: "CMS block defines all CMS block information") { - block_id: Int @doc(description: "Entity ID of CMS block") identifier: String @doc(description: "CMS block identifier") title: String @doc(description: "CMS block title") content: String @doc(description: "CMS block content") diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsBlockTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsBlockTest.php index 6e07f8cd7876a..542b00d434db0 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsBlockTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsBlockTest.php @@ -47,7 +47,6 @@ public function testGetCmsBlock() { cmsBlocks(identifiers: "enabled_block") { items { - block_id identifier title content @@ -60,7 +59,6 @@ public function testGetCmsBlock() self::assertArrayHasKey('cmsBlocks', $response); self::assertArrayHasKey('items', $response['cmsBlocks']); - self::assertEquals($cmsBlockData['block_id'], $response['cmsBlocks']['items'][0]['block_id']); self::assertEquals($cmsBlockData['identifier'], $response['cmsBlocks']['items'][0]['identifier']); self::assertEquals($cmsBlockData['title'], $response['cmsBlocks']['items'][0]['title']); self::assertEquals($renderedContent, $response['cmsBlocks']['items'][0]['content']); @@ -83,7 +81,6 @@ public function testGetCmsBlockByBlockId() { cmsBlocks(identifiers: "$blockId") { items { - block_id identifier title content @@ -95,8 +92,6 @@ public function testGetCmsBlockByBlockId() self::assertArrayHasKey('cmsBlocks', $response); self::assertArrayHasKey('items', $response['cmsBlocks']); - - self::assertEquals($blockId, $response['cmsBlocks']['items'][0]['block_id']); self::assertEquals($cmsBlockData['identifier'], $response['cmsBlocks']['items'][0]['identifier']); self::assertEquals($cmsBlockData['title'], $response['cmsBlocks']['items'][0]['title']); self::assertEquals($renderedContent, $response['cmsBlocks']['items'][0]['content']); diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsPageTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsPageTest.php index 8abcee8f22403..53e47185c9866 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsPageTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsPageTest.php @@ -58,22 +58,18 @@ public function testGetCmsPageById() public function testGetCmsPageByIdentifier() { $cmsPageIdentifier = 'page100'; - $storeId = 0; - - $cmsPage = ObjectManager::getInstance()->get(GetPageByIdentifier::class)->execute($cmsPageIdentifier, $storeId); - $pageId = $cmsPage->getPageId(); $query = <<graphQlQuery($query); - $this->assertEquals($pageId, $response['cmsPage']['page_id']); + $this->assertEquals($cmsPageIdentifier, $response['cmsPage']['identifier']); } /** From 9d240e3a52af09f32799ec52dc08e3dc89e707f0 Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko Date: Wed, 1 May 2019 11:49:53 +0300 Subject: [PATCH 19/42] graphQl-535: provided catalog configs --- .../Magento/CatalogGraphQl/etc/graphql/di.xml | 22 ++++++++ .../CatalogGraphQl/etc/schema.graphqls | 19 +++++++ .../GraphQl/Catalog/StoreConfigTest.php | 55 +++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/StoreConfigTest.php diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml index a5bd42860ded0..5d5c92edd3d57 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml @@ -80,4 +80,26 @@ + + + + catalog/seo/product_url_suffix + catalog/seo/category_url_suffix + catalog/seo/product_use_categories + catalog/seo/save_rewrites_history + catalog/seo/title_separator + catalog/seo/category_canonical_tag + catalog/seo/product_canonical_tag + catalog/frontend/list_mode + catalog/frontend/grid_per_page_values + catalog/frontend/list_per_page_values + catalog/frontend/grid_per_page + catalog/frontend/list_per_page + catalog/frontend/flat_catalog_category + catalog/frontend/default_sort_by + catalog/frontend/parse_url_directives + catalog/frontend/remember_pagination + + + diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 9f102a1c6a150..1b04e2b0ff6aa 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -401,3 +401,22 @@ type SortFields @doc(description: "SortFields contains a default value for sort default: String @doc(description: "Default value of sort fields") options: [SortField] @doc(description: "Available sort fields") } + +type StoreConfig @doc(description: "The type contains information about a store config") { + product_url_suffix : String @doc(description: "Product URL Suffix") + category_url_suffix : String @doc(description: "Category URL Suffix") + product_use_categories : Int @doc(description: "Use Categories Path for Product URLs") + save_rewrites_history : Int @doc(description: "Create Permanent Redirect for URLs if URL Key Changed") + title_separator : String @doc(description: "Page Title Separator") + category_canonical_tag : Int @doc(description: "Use Canonical Link Meta Tag For Categories") + product_canonical_tag : Int @doc(description: "Use Canonical Link Meta Tag For Products") + list_mode : String @doc(description: "List Mode") + grid_per_page_values : String @doc(description: "Products per Page on Grid Allowed Values") + list_per_page_values : String @doc(description: "Products per Page on List Allowed Values") + grid_per_page : Int @doc(description: "Products per Page on Grid Default Value") + list_per_page : Int @doc(description: "Products per Page on List Default Value") + flat_catalog_category : Int @doc(description: "Use Flat Catalog Category") + catalog_default_sort_by : String @doc(description: "Default Sort By") + parse_url_directives : Int @doc(description: "Parse URL directives") + remember_pagination : Int @doc(description: "Remember Pagination") +} diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/StoreConfigTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/StoreConfigTest.php new file mode 100644 index 0000000000000..813ed9faefa94 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/StoreConfigTest.php @@ -0,0 +1,55 @@ +markTestIncomplete('https://github.com/magento/graphql-ce/issues/167'); + } + + /** + * @magentoApiDataFixture Magento/Store/_files/store.php + */ + public function testGetStoreConfig() + { + $query + = <<graphQlQuery($query); + $this->assertArrayHasKey('storeConfig', $response); + + //TODO: provide assertions after unmarking test as incomplete + } +} From 8f36cf21b9fda33f031c9c42457c520b84548afe Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko Date: Wed, 1 May 2019 14:04:32 +0300 Subject: [PATCH 20/42] graphQl-535: fixed namespace --- .../testsuite/Magento/GraphQl/Catalog/StoreConfigTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/StoreConfigTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/StoreConfigTest.php index 813ed9faefa94..5932fd8b034e6 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/StoreConfigTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/StoreConfigTest.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\GraphQl\Store; +namespace Magento\GraphQl\Catalog; use Magento\TestFramework\TestCase\GraphQlAbstract; From c94a655fe9a5829a2721b293869cda3ae1be430a Mon Sep 17 00:00:00 2001 From: Valerii Naida Date: Thu, 2 May 2019 17:42:33 -0500 Subject: [PATCH 21/42] GraphQl-309: [Checkout] Checkout Agreements --- .../Model/Resolver/CheckoutAgreements.php | 54 +++++++++++-- .../DataProvider/CheckoutAgreements.php | 81 ------------------- .../CheckoutAgreementsGraphQl/composer.json | 3 +- ...Test.php => GetCheckoutAgreementsTest.php} | 50 +++++++----- 4 files changed, 75 insertions(+), 113 deletions(-) delete mode 100644 app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/DataProvider/CheckoutAgreements.php rename dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/{Api/CheckoutAgreementsListTest.php => GetCheckoutAgreementsTest.php} (79%) diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/CheckoutAgreements.php b/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/CheckoutAgreements.php index 7009e1e2d85e6..c312d8622a0a9 100644 --- a/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/CheckoutAgreements.php +++ b/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/CheckoutAgreements.php @@ -7,10 +7,14 @@ namespace Magento\CheckoutAgreementsGraphQl\Model\Resolver; -use Magento\CheckoutAgreementsGraphQl\Model\Resolver\DataProvider\CheckoutAgreements as CheckoutAgreementsDataProvider; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\CheckoutAgreements\Api\Data\AgreementInterface; +use Magento\CheckoutAgreements\Model\ResourceModel\Agreement\CollectionFactory; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Store\Model\ScopeInterface; +use Magento\Store\Model\StoreManagerInterface; /** * Checkout Agreements resolver, used for GraphQL request processing @@ -18,17 +22,33 @@ class CheckoutAgreements implements ResolverInterface { /** - * @var CheckoutAgreementsDataProvider + * @var CollectionFactory */ - private $checkoutAgreementsDataProvider; + private $agreementCollectionFactory; /** - * @param CheckoutAgreementsDataProvider $checkoutAgreementsDataProvider + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @var ScopeConfigInterface + */ + private $scopeConfig; + + /** + * @param CollectionFactory $agreementCollectionFactory + * @param StoreManagerInterface $storeManager + * @param ScopeConfigInterface $scopeConfig */ public function __construct( - CheckoutAgreementsDataProvider $checkoutAgreementsDataProvider + CollectionFactory $agreementCollectionFactory, + StoreManagerInterface $storeManager, + ScopeConfigInterface $scopeConfig ) { - $this->checkoutAgreementsDataProvider = $checkoutAgreementsDataProvider; + $this->agreementCollectionFactory = $agreementCollectionFactory; + $this->storeManager = $storeManager; + $this->scopeConfig = $scopeConfig; } /** @@ -41,8 +61,26 @@ public function resolve( array $value = null, array $args = null ) { - $checkoutAgreementsData = $this->checkoutAgreementsDataProvider->getData(); + if (!$this->scopeConfig->isSetFlag('checkout/options/enable_agreements', ScopeInterface::SCOPE_STORE)) { + return []; + } + + $agreementsCollection = $this->agreementCollectionFactory->create(); + $agreementsCollection->addStoreFilter($this->storeManager->getStore()->getId()); + $agreementsCollection->addFieldToFilter('is_active', 1); - return $checkoutAgreementsData; + $checkoutAgreementData = []; + /** @var AgreementInterface $checkoutAgreement */ + foreach ($agreementsCollection->getItems() as $checkoutAgreement) { + $checkoutAgreementData[] = [ + AgreementInterface::AGREEMENT_ID => $checkoutAgreement->getAgreementId(), + AgreementInterface::CONTENT => $checkoutAgreement->getContent(), + AgreementInterface::NAME => $checkoutAgreement->getName(), + AgreementInterface::CONTENT_HEIGHT => $checkoutAgreement->getContentHeight(), + AgreementInterface::CHECKBOX_TEXT => $checkoutAgreement->getCheckboxText(), + AgreementInterface::IS_HTML => $checkoutAgreement->getIsHtml(), + ]; + } + return $checkoutAgreementData; } } diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/DataProvider/CheckoutAgreements.php b/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/DataProvider/CheckoutAgreements.php deleted file mode 100644 index 3dab845627261..0000000000000 --- a/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/DataProvider/CheckoutAgreements.php +++ /dev/null @@ -1,81 +0,0 @@ -agreementCollectionFactory = $agreementCollectionFactory; - $this->storeManager = $storeManager; - $this->scopeConfig = $scopeConfig; - } - - /** - * Get All Active Checkout Agreements Data - * - * @return array - */ - public function getData(): array - { - if (!$this->scopeConfig->isSetFlag('checkout/options/enable_agreements', ScopeInterface::SCOPE_STORE)) { - return []; - } - $agreementsCollection = $this->agreementCollectionFactory->create(); - $agreementsCollection->addStoreFilter($this->storeManager->getStore()->getId()); // TODO: store should be get from query context - $agreementsCollection->addFieldToFilter('is_active', 1); - - $checkoutAgreementData = []; - /** @var Agreement $checkoutAgreement */ - foreach ($agreementsCollection->getItems() as $checkoutAgreement) { - $checkoutAgreementData[] = [ - AgreementInterface::AGREEMENT_ID => $checkoutAgreement->getAgreementId(), - AgreementInterface::CONTENT => $checkoutAgreement->getContent(), - AgreementInterface::NAME => $checkoutAgreement->getName(), - AgreementInterface::CONTENT_HEIGHT => $checkoutAgreement->getContentHeight(), - AgreementInterface::CHECKBOX_TEXT => $checkoutAgreement->getCheckboxText(), - AgreementInterface::IS_HTML => $checkoutAgreement->getIsHtml(), - ]; - } - - return $checkoutAgreementData; - } -} diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/composer.json b/app/code/Magento/CheckoutAgreementsGraphQl/composer.json index 064e8f7c2ec94..5972d48b35ea9 100644 --- a/app/code/Magento/CheckoutAgreementsGraphQl/composer.json +++ b/app/code/Magento/CheckoutAgreementsGraphQl/composer.json @@ -9,8 +9,7 @@ "magento/module-checkout-agreements": "*" }, "suggest": { - "magento/module-graph-ql": "*", - "magento/module-store-graph-ql": "*" + "magento/module-graph-ql": "*" }, "license": [ "OSL-3.0", diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/Api/CheckoutAgreementsListTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/GetCheckoutAgreementsTest.php similarity index 79% rename from dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/Api/CheckoutAgreementsListTest.php rename to dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/GetCheckoutAgreementsTest.php index 62491e5e8376b..663b314ffdb57 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/Api/CheckoutAgreementsListTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/GetCheckoutAgreementsTest.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\GraphQl\CheckoutAgreements\Api; +namespace Magento\GraphQl\CheckoutAgreements; use Magento\CheckoutAgreements\Api\Data\AgreementInterface; use Magento\CheckoutAgreements\Model\Agreement as AgreementModel; @@ -20,8 +20,14 @@ use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\GraphQlAbstract; -class CheckoutAgreementsListTest extends GraphQlAbstract +/** + * Get checkout agreements test + */ +class GetCheckoutAgreementsTest extends GraphQlAbstract { + /** + * @var string + */ private $agreementsXmlConfigPath = 'checkout/options/enable_agreements'; /** @@ -55,14 +61,14 @@ public function testGetActiveAgreement() $response = $this->graphQlQuery($query); - $this->assertArrayHasKey('checkoutAgreements', $response); + self::assertArrayHasKey('checkoutAgreements', $response); $agreements = $response['checkoutAgreements']; - $this->assertCount(1, $agreements); - $this->assertEquals('Checkout Agreement (active)', $agreements[0]['name']); - $this->assertEquals('Checkout agreement content: HTML', $agreements[0]['content']); - $this->assertEquals('200px', $agreements[0]['content_height']); - $this->assertEquals('Checkout agreement checkbox text.', $agreements[0]['checkbox_text']); - $this->assertEquals(true, $agreements[0]['is_html']); + self::assertCount(1, $agreements); + self::assertEquals('Checkout Agreement (active)', $agreements[0]['name']); + self::assertEquals('Checkout agreement content: HTML', $agreements[0]['content']); + self::assertEquals('200px', $agreements[0]['content_height']); + self::assertEquals('Checkout agreement checkbox text.', $agreements[0]['checkbox_text']); + self::assertEquals(true, $agreements[0]['is_html']); } /** @@ -81,14 +87,14 @@ public function testGetActiveAgreementOnSecondStore() $headerMap['Store'] = $secondStoreCode; $response = $this->graphQlQuery($query, [], '', $headerMap); - $this->assertArrayHasKey('checkoutAgreements', $response); + self::assertArrayHasKey('checkoutAgreements', $response); $agreements = $response['checkoutAgreements']; - $this->assertCount(1, $agreements); - $this->assertEquals($agreementsName, $agreements[0]['name']); - $this->assertEquals('Checkout agreement content: HTML', $agreements[0]['content']); - $this->assertEquals('200px', $agreements[0]['content_height']); - $this->assertEquals('Checkout agreement checkbox text.', $agreements[0]['checkbox_text']); - $this->assertEquals(true, $agreements[0]['is_html']); + self::assertCount(1, $agreements); + self::assertEquals($agreementsName, $agreements[0]['name']); + self::assertEquals('Checkout agreement content: HTML', $agreements[0]['content']); + self::assertEquals('200px', $agreements[0]['content_height']); + self::assertEquals('Checkout agreement checkbox text.', $agreements[0]['checkbox_text']); + self::assertEquals(true, $agreements[0]['is_html']); } /** @@ -106,9 +112,9 @@ public function testGetActiveAgreementFromSecondStoreOnDefaultStore() $response = $this->graphQlQuery($query); - $this->assertArrayHasKey('checkoutAgreements', $response); + self::assertArrayHasKey('checkoutAgreements', $response); $agreements = $response['checkoutAgreements']; - $this->assertCount(0, $agreements); + self::assertCount(0, $agreements); } public function testGetAgreementNotSet() @@ -117,9 +123,9 @@ public function testGetAgreementNotSet() $response = $this->graphQlQuery($query); - $this->assertArrayHasKey('checkoutAgreements', $response); + self::assertArrayHasKey('checkoutAgreements', $response); $agreements = $response['checkoutAgreements']; - $this->assertCount(0, $agreements); + self::assertCount(0, $agreements); } /** @@ -133,9 +139,9 @@ public function testDisabledAgreements() $response = $this->graphQlQuery($query); - $this->assertArrayHasKey('checkoutAgreements', $response); + self::assertArrayHasKey('checkoutAgreements', $response); $agreements = $response['checkoutAgreements']; - $this->assertCount(0, $agreements); + self::assertCount(0, $agreements); } /** From cc65d3e6fbb53de01cdd3cd36ba1b78ef0ca3bc1 Mon Sep 17 00:00:00 2001 From: Patrick McLain Date: Thu, 2 May 2019 22:34:42 -0400 Subject: [PATCH 22/42] Prevent Error When Getting Payment Method Before Setting Calling [`Magento\Quote\Model\Quote\Payment::getMethodInstance`](https://github.com/magento/graphql-ce/blob/b2ce2a37d921b5ad88fc38663fc0ff3dd6c582d1/app/code/Magento/Payment/Model/Info.php#L105) throws an exception when the method is not set. This would trigger and error when requsting the `selected_payment_method` cart property. This commit returns an empty string instead. --- .../Model/Resolver/SelectedPaymentMethod.php | 10 +++++++-- .../Customer/GetSelectedPaymentMethodTest.php | 21 +++++++++++++++++++ .../Guest/GetSelectedPaymentMethodTest.php | 20 ++++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/SelectedPaymentMethod.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/SelectedPaymentMethod.php index 8cda06eba3c91..44912d249cc24 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/SelectedPaymentMethod.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/SelectedPaymentMethod.php @@ -34,9 +34,15 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value return []; } + try { + $methodTitle = $payment->getMethodInstance()->getTitle(); + } catch (LocalizedException $e) { + $methodTitle = ''; + } + return [ - 'code' => $payment->getMethod(), - 'title' => $payment->getMethodInstance()->getTitle(), + 'code' => $payment->getMethod() ?? '', + 'title' => $methodTitle, 'purchase_order_number' => $payment->getPoNumber(), ]; } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetSelectedPaymentMethodTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetSelectedPaymentMethodTest.php index d876d74de661b..4432a233e96e7 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetSelectedPaymentMethodTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetSelectedPaymentMethodTest.php @@ -49,6 +49,27 @@ public function testGetSelectedPaymentMethod() $this->assertEquals('checkmo', $response['cart']['selected_payment_method']['code']); } + /** + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/enable_offline_payment_methods.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php + */ + public function testGetSelectedPaymentMethodBeforeSet() + { + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + + $query = $this->getQuery($maskedQuoteId); + $response = $this->graphQlQuery($query, [], '', $this->getHeaderMap()); + + $this->assertArrayHasKey('cart', $response); + $this->assertArrayHasKey('selected_payment_method', $response['cart']); + $this->assertArrayHasKey('code', $response['cart']['selected_payment_method']); + $this->assertEquals('', $response['cart']['selected_payment_method']['code']); + } + /** * @magentoApiDataFixture Magento/Customer/_files/customer.php * @expectedException \Exception diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetSelectedPaymentMethodTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetSelectedPaymentMethodTest.php index ef04da88ea67a..a918279bada65 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetSelectedPaymentMethodTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetSelectedPaymentMethodTest.php @@ -49,6 +49,26 @@ public function testGetSelectedPaymentMethod() $this->assertEquals('checkmo', $response['cart']['selected_payment_method']['code']); } + /** + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/enable_offline_payment_methods.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php + */ + public function testGetSelectedPaymentMethodBeforeSet() + { + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + + $query = $this->getQuery($maskedQuoteId); + $response = $this->graphQlQuery($query); + + $this->assertArrayHasKey('cart', $response); + $this->assertArrayHasKey('selected_payment_method', $response['cart']); + $this->assertArrayHasKey('code', $response['cart']['selected_payment_method']); + $this->assertEquals('', $response['cart']['selected_payment_method']['code']); + } + /** * @expectedException \Exception */ From 8b37ef75fd63eb797e71b65c64d650c1a896293c Mon Sep 17 00:00:00 2001 From: Patrick McLain Date: Thu, 2 May 2019 23:24:27 -0400 Subject: [PATCH 23/42] Prevent undefined index warning before setting shipping method `list` would cause and undefined index error when address rates had been collected and the shipping method was not set. This commit checks that the shipping method is set prior to resolving. Fixes magento/graphql-ce#657 --- .../SelectedShippingMethod.php | 2 +- .../GetSelectedShippingMethodTest.php | 38 +++++++++++++++++++ .../Guest/GetSelectedShippingMethodTest.php | 37 ++++++++++++++++++ 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SelectedShippingMethod.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SelectedShippingMethod.php index 05bc196acfc22..b359971880036 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SelectedShippingMethod.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SelectedShippingMethod.php @@ -49,7 +49,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $carrierTitle = null; $methodTitle = null; - if (count($rates) > 0) { + if (count($rates) > 0 && !empty($address->getShippingMethod())) { list($carrierCode, $methodCode) = explode('_', $address->getShippingMethod(), 2); /** @var Rate $rate */ diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetSelectedShippingMethodTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetSelectedShippingMethodTest.php index 5575830ea51cd..9bb36bf8f0929 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetSelectedShippingMethodTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetSelectedShippingMethodTest.php @@ -88,6 +88,40 @@ public function testGetSelectedShippingMethod() self::assertEquals('USD', $baseAmount['currency']); } + /** + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php + */ + public function testGetSelectedShippingMethodBeforeSet() + { + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + + $query = $this->getQuery($maskedQuoteId); + $response = $this->graphQlQuery($query, [], '', $this->getHeaderMap()); + + self::assertArrayHasKey('cart', $response); + self::assertArrayHasKey('shipping_addresses', $response['cart']); + self::assertCount(1, $response['cart']['shipping_addresses']); + + $shippingAddress = current($response['cart']['shipping_addresses']); + self::assertArrayHasKey('selected_shipping_method', $shippingAddress); + + self::assertArrayHasKey('carrier_code', $shippingAddress['selected_shipping_method']); + self::assertNull($shippingAddress['selected_shipping_method']['carrier_code']); + + self::assertArrayHasKey('method_code', $shippingAddress['selected_shipping_method']); + self::assertNull($shippingAddress['selected_shipping_method']['method_code']); + + self::assertArrayHasKey('carrier_title', $shippingAddress['selected_shipping_method']); + self::assertNull($shippingAddress['selected_shipping_method']['carrier_title']); + + self::assertArrayHasKey('method_title', $shippingAddress['selected_shipping_method']); + self::assertNull($shippingAddress['selected_shipping_method']['method_title']); + } + /** * _security * @magentoApiDataFixture Magento/Customer/_files/customer.php @@ -193,6 +227,10 @@ private function getQuery(string $maskedQuoteId): string { cart(cart_id: "$maskedQuoteId") { shipping_addresses { + available_shipping_methods { + carrier_code + method_code + } selected_shipping_method { carrier_code method_code diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetSelectedShippingMethodTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetSelectedShippingMethodTest.php index bd684a950b590..5d1033b39819e 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetSelectedShippingMethodTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetSelectedShippingMethodTest.php @@ -80,6 +80,39 @@ public function testGetSelectedShippingMethod() self::assertEquals('USD', $baseAmount['currency']); } + /** + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php + */ + public function testGetSelectedShippingMethodBeforeSet() + { + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + + $query = $this->getQuery($maskedQuoteId); + $response = $this->graphQlQuery($query); + + self::assertArrayHasKey('cart', $response); + self::assertArrayHasKey('shipping_addresses', $response['cart']); + self::assertCount(1, $response['cart']['shipping_addresses']); + + $shippingAddress = current($response['cart']['shipping_addresses']); + self::assertArrayHasKey('selected_shipping_method', $shippingAddress); + + self::assertArrayHasKey('carrier_code', $shippingAddress['selected_shipping_method']); + self::assertNull($shippingAddress['selected_shipping_method']['carrier_code']); + + self::assertArrayHasKey('method_code', $shippingAddress['selected_shipping_method']); + self::assertNull($shippingAddress['selected_shipping_method']['method_code']); + + self::assertArrayHasKey('carrier_title', $shippingAddress['selected_shipping_method']); + self::assertNull($shippingAddress['selected_shipping_method']['carrier_title']); + + self::assertArrayHasKey('method_title', $shippingAddress['selected_shipping_method']); + self::assertNull($shippingAddress['selected_shipping_method']['method_title']); + } + /** * _security * @magentoApiDataFixture Magento/Customer/_files/customer.php @@ -149,6 +182,10 @@ private function getQuery(string $maskedQuoteId): string { cart(cart_id: "$maskedQuoteId") { shipping_addresses { + available_shipping_methods { + carrier_code + method_code + } selected_shipping_method { carrier_code method_code From cf119bec073ba75239d72a3f737097d4f6a0aa28 Mon Sep 17 00:00:00 2001 From: Alex Taranovsky Date: Sat, 4 May 2019 01:11:04 +0300 Subject: [PATCH 24/42] 387-Test coverage of getting IDs of CMS page/blocks by GraphQL API --- .../Model/Resolver/DataProvider/Page.php | 84 +++++++++++-- .../DataProvider/PageDataProvider.php | 110 ------------------ .../CmsGraphQl/Model/Resolver/Page.php | 30 +++-- 3 files changed, 90 insertions(+), 134 deletions(-) delete mode 100644 app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/PageDataProvider.php diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php index 2cee9e8e9e44c..a9513b1a24932 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php @@ -8,22 +8,21 @@ namespace Magento\CmsGraphQl\Model\Resolver\DataProvider; use Magento\Cms\Api\Data\PageInterface; +use Magento\Cms\Api\GetPageByIdentifierInterface; use Magento\Cms\Api\PageRepositoryInterface; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Store\Model\StoreManagerInterface; use Magento\Widget\Model\Template\FilterEmulate; /** - * @deprecated - * @see Magento\CmsGraphQl\Model\Resolver\DataProvider\PageDataProvider - * * Cms page data provider */ class Page { /** - * @var FilterEmulate + * @var GetPageByIdentifierInterface */ - private $widgetFilter; + private $pageByIdentifier; /** * @var PageRepositoryInterface @@ -31,18 +30,37 @@ class Page private $pageRepository; /** - * @param PageRepositoryInterface $pageRepository + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @var FilterEmulate + */ + private $widgetFilter; + + /** + * @param GetPageByIdentifierInterface $getPageByIdentifier * @param FilterEmulate $widgetFilter + * @param PageRepositoryInterface $pageRepository + * @param StoreManagerInterface $storeManager */ public function __construct( + GetPageByIdentifierInterface $getPageByIdentifier, + FilterEmulate $widgetFilter, PageRepositoryInterface $pageRepository, - FilterEmulate $widgetFilter + StoreManagerInterface $storeManager ) { + $this->pageByIdentifier = $getPageByIdentifier; $this->pageRepository = $pageRepository; + $this->storeManager = $storeManager; $this->widgetFilter = $widgetFilter; } /** + * @deprecated + * @see getDataByPageId(int $pageId) + * * Get the page data * * @param int $pageId @@ -72,4 +90,56 @@ public function getData(int $pageId): array ]; return $pageData; } + + /** + * @param int $pageId + * @return array + * @throws NoSuchEntityException + */ + public function getDataByPageId(int $pageId): array + { + $page = $this->pageRepository->getById($pageId); + + return $this->convertPageData($page); + } + + /** + * @param string $pageIdentifier + * @return array + * @throws NoSuchEntityException + */ + public function getDataByPageIdentifier(string $pageIdentifier): array + { + $storeId = (int)$this->storeManager->getStore()->getId(); + $page = $this->pageByIdentifier->execute($pageIdentifier, $storeId); + + return $this->convertPageData($page); + } + + /** + * @param PageInterface $page + * @return array + * @throws NoSuchEntityException + */ + private function convertPageData(PageInterface $page) + { + if (false === $page->isActive()) { + throw new NoSuchEntityException(); + } + + $renderedContent = $this->widgetFilter->filter($page->getContent()); + + $pageData = [ + 'url_key' => $page->getIdentifier(), + PageInterface::IDENTIFIER => $page->getIdentifier(), + PageInterface::TITLE => $page->getTitle(), + PageInterface::CONTENT => $renderedContent, + PageInterface::CONTENT_HEADING => $page->getContentHeading(), + PageInterface::PAGE_LAYOUT => $page->getPageLayout(), + PageInterface::META_TITLE => $page->getMetaTitle(), + PageInterface::META_DESCRIPTION => $page->getMetaDescription(), + PageInterface::META_KEYWORDS => $page->getMetaKeywords(), + ]; + return $pageData; + } } diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/PageDataProvider.php b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/PageDataProvider.php deleted file mode 100644 index 47fa4c08a9c31..0000000000000 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/PageDataProvider.php +++ /dev/null @@ -1,110 +0,0 @@ -pageByIdentifier = $getPageByIdentifier; - $this->pageRepository = $pageRepository; - $this->storeManager = $storeManager; - $this->widgetFilter = $widgetFilter; - } - - /** - * @param int $pageId - * @return array - * @throws NoSuchEntityException - */ - public function getDataByPageId(int $pageId): array - { - $page = $this->pageRepository->getById($pageId); - - return $this->convertPageData($page); - } - - /** - * @param string $pageIdentifier - * @return array - */ - public function getDataByPageIdentifier(string $pageIdentifier): array - { - $storeId = (int)$this->storeManager->getStore()->getId(); - $page = $this->pageByIdentifier->execute($pageIdentifier, $storeId); - - return $this->convertPageData($page); - } - - /** - * @param PageInterface $page - * @return array - * @throws NoSuchEntityException - */ - private function convertPageData(PageInterface $page) - { - if (false === $page->isActive()) { - throw new NoSuchEntityException(); - } - - $renderedContent = $this->widgetFilter->filter($page->getContent()); - - $pageData = [ - 'url_key' => $page->getIdentifier(), - PageInterface::IDENTIFIER => $page->getIdentifier(), - PageInterface::TITLE => $page->getTitle(), - PageInterface::CONTENT => $renderedContent, - PageInterface::CONTENT_HEADING => $page->getContentHeading(), - PageInterface::PAGE_LAYOUT => $page->getPageLayout(), - PageInterface::META_TITLE => $page->getMetaTitle(), - PageInterface::META_DESCRIPTION => $page->getMetaDescription(), - PageInterface::META_KEYWORDS => $page->getMetaKeywords(), - ]; - return $pageData; - } -} diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/Page.php b/app/code/Magento/CmsGraphQl/Model/Resolver/Page.php index 544a09c780070..489a3e0a75c80 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/Page.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/Page.php @@ -7,7 +7,7 @@ namespace Magento\CmsGraphQl\Model\Resolver; -use Magento\CmsGraphQl\Model\Resolver\DataProvider\PageDataProvider as PageDataProvider; +use Magento\CmsGraphQl\Model\Resolver\DataProvider\Page as PageDataProvider; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Exception\GraphQlInputException; @@ -49,10 +49,16 @@ public function resolve( throw new GraphQlInputException(__('"Page id/identifier should be specified')); } - if (isset($args['id'])) { - $pageData = $this->getPageDataById($this->getPageId($args)); - } elseif (isset($args['identifier'])) { - $pageData = $this->getPageDataByIdentifier($this->getPageIdentifier($args)); + $pageData = []; + + try { + if (isset($args['id'])) { + $pageData = $this->getPageDataById($this->getPageId($args)); + } elseif (isset($args['identifier'])) { + $pageData = $this->getPageDataByIdentifier($this->getPageIdentifier($args)); + } + } catch (NoSuchEntityException $e) { + throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e); } return $pageData; @@ -83,12 +89,7 @@ private function getPageIdentifier(array $args): string */ private function getPageDataById(int $pageId): array { - try { - $pageData = $this->pageDataProvider->getDataByPageId($pageId); - } catch (NoSuchEntityException $e) { - throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e); - } - return $pageData; + return $this->pageDataProvider->getDataByPageId($pageId); } /** @@ -98,11 +99,6 @@ private function getPageDataById(int $pageId): array */ private function getPageDataByIdentifier(string $pageIdentifier): array { - try { - $pageData = $this->pageDataProvider->getDataByPageIdentifier($pageIdentifier); - } catch (NoSuchEntityException $e) { - throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e); - } - return $pageData; + return $this->pageDataProvider->getDataByPageIdentifier($pageIdentifier); } } From ff658b515ba18f6579e692935e195ad5d3cba99b Mon Sep 17 00:00:00 2001 From: Alex Taranovsky Date: Sat, 4 May 2019 01:18:19 +0300 Subject: [PATCH 25/42] 387-Test coverage of getting IDs of CMS page/blocks by GraphQL API --- app/code/Magento/CmsGraphQl/etc/schema.graphqls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CmsGraphQl/etc/schema.graphqls b/app/code/Magento/CmsGraphQl/etc/schema.graphqls index 26689c5d4c91d..3558d853aa4df 100644 --- a/app/code/Magento/CmsGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CmsGraphQl/etc/schema.graphqls @@ -12,7 +12,7 @@ type StoreConfig @doc(description: "The type contains information about a store type Query { cmsPage ( - id: Int @doc(description: "Id of the CMS page") @deprecated(reason: "Use `identifier`") @doc(description: "The CMS page query returns information about a CMS page") + id: Int @doc(description: "Id of the CMS page") @deprecated(reason: "The `id` is deprecated. Use `identifier` instead.") @doc(description: "The CMS page query returns information about a CMS page") identifier: String @doc(description: "Identifier of the CMS page") ): CmsPage @resolver(class: "Magento\\CmsGraphQl\\Model\\Resolver\\Page") @doc(description: "The CMS page query returns information about a CMS page") @cache(cacheTag: "cms_p", cacheIdentity: "Magento\\CmsGraphQl\\Model\\Resolver\\Page\\Identity") cmsBlocks ( From fed22e0af98c5571e65a30e05ef5c8c44dcb6b4a Mon Sep 17 00:00:00 2001 From: Alex Taranovsky Date: Mon, 6 May 2019 15:51:47 +0300 Subject: [PATCH 26/42] 387-Test coverage of getting IDs of CMS page/blocks by GraphQL API --- .../Model/Resolver/DataProvider/Page.php | 53 ++++++++++--------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php index a9513b1a24932..a67cc877e7db8 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php @@ -10,6 +10,7 @@ use Magento\Cms\Api\Data\PageInterface; use Magento\Cms\Api\GetPageByIdentifierInterface; use Magento\Cms\Api\PageRepositoryInterface; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Store\Model\StoreManagerInterface; use Magento\Widget\Model\Template\FilterEmulate; @@ -40,21 +41,22 @@ class Page private $widgetFilter; /** - * @param GetPageByIdentifierInterface $getPageByIdentifier - * @param FilterEmulate $widgetFilter * @param PageRepositoryInterface $pageRepository + * @param FilterEmulate $widgetFilter + * @param GetPageByIdentifierInterface $getPageByIdentifier * @param StoreManagerInterface $storeManager */ public function __construct( - GetPageByIdentifierInterface $getPageByIdentifier, - FilterEmulate $widgetFilter, PageRepositoryInterface $pageRepository, - StoreManagerInterface $storeManager + FilterEmulate $widgetFilter, + GetPageByIdentifierInterface $getPageByIdentifier = null, + StoreManagerInterface $storeManager = null ) { - $this->pageByIdentifier = $getPageByIdentifier; + $this->pageRepository = $pageRepository; - $this->storeManager = $storeManager; $this->widgetFilter = $widgetFilter; + $this->pageByIdentifier = $getPageByIdentifier ?: ObjectManager::getInstance()->get(GetPageByIdentifierInterface::class); + $this->storeManager = $storeManager ?: ObjectManager::getInstance()->get(StoreManagerInterface::class); } /** @@ -75,23 +77,12 @@ public function getData(int $pageId): array throw new NoSuchEntityException(); } - $renderedContent = $this->widgetFilter->filter($page->getContent()); - - $pageData = [ - PageInterface::PAGE_ID => $page->getId(), - 'url_key' => $page->getIdentifier(), - PageInterface::TITLE => $page->getTitle(), - PageInterface::CONTENT => $renderedContent, - PageInterface::CONTENT_HEADING => $page->getContentHeading(), - PageInterface::PAGE_LAYOUT => $page->getPageLayout(), - PageInterface::META_TITLE => $page->getMetaTitle(), - PageInterface::META_DESCRIPTION => $page->getMetaDescription(), - PageInterface::META_KEYWORDS => $page->getMetaKeywords(), - ]; - return $pageData; + return $this->convertPageData($page); } /** + * Returns page data by page_id + * * @param int $pageId * @return array * @throws NoSuchEntityException @@ -100,10 +91,12 @@ public function getDataByPageId(int $pageId): array { $page = $this->pageRepository->getById($pageId); - return $this->convertPageData($page); + return $this->convertPageData($page, false, true); } /** + * Returns page data by page identifier + * * @param string $pageIdentifier * @return array * @throws NoSuchEntityException @@ -113,15 +106,17 @@ public function getDataByPageIdentifier(string $pageIdentifier): array $storeId = (int)$this->storeManager->getStore()->getId(); $page = $this->pageByIdentifier->execute($pageIdentifier, $storeId); - return $this->convertPageData($page); + return $this->convertPageData($page, false, true); } /** * @param PageInterface $page + * @param bool $includePageId + * @param bool $includePageIdentifier * @return array * @throws NoSuchEntityException */ - private function convertPageData(PageInterface $page) + private function convertPageData(PageInterface $page, $includePageId = true, $includePageIdentifier = false) { if (false === $page->isActive()) { throw new NoSuchEntityException(); @@ -131,7 +126,6 @@ private function convertPageData(PageInterface $page) $pageData = [ 'url_key' => $page->getIdentifier(), - PageInterface::IDENTIFIER => $page->getIdentifier(), PageInterface::TITLE => $page->getTitle(), PageInterface::CONTENT => $renderedContent, PageInterface::CONTENT_HEADING => $page->getContentHeading(), @@ -140,6 +134,15 @@ private function convertPageData(PageInterface $page) PageInterface::META_DESCRIPTION => $page->getMetaDescription(), PageInterface::META_KEYWORDS => $page->getMetaKeywords(), ]; + + if ($includePageId) { + $pageData[PageInterface::PAGE_ID] = $page->getId(); + } + + if ($includePageIdentifier) { + $pageData[PageInterface::IDENTIFIER] = $page->getIdentifier(); + } + return $pageData; } } From b4ea6b93496342a51430694f3f3ca7d82d50f746 Mon Sep 17 00:00:00 2001 From: Alex Taranovsky Date: Mon, 6 May 2019 16:49:15 +0300 Subject: [PATCH 27/42] 387-Test coverage of getting IDs of CMS page/blocks by GraphQL API --- .../Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php index a67cc877e7db8..cfeecd402828e 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php @@ -72,11 +72,7 @@ public function __construct( public function getData(int $pageId): array { $page = $this->pageRepository->getById($pageId); - - if (false === $page->isActive()) { - throw new NoSuchEntityException(); - } - + return $this->convertPageData($page); } From 4ee64a57bbaaf8c4564c589b1c2f794869da8d74 Mon Sep 17 00:00:00 2001 From: Alex Taranovsky Date: Mon, 6 May 2019 16:56:42 +0300 Subject: [PATCH 28/42] 387-Test coverage of getting IDs of CMS page/blocks by GraphQL API --- .../CmsGraphQl/Model/Resolver/DataProvider/Page.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php index cfeecd402828e..2001bc006bbb8 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php @@ -10,7 +10,6 @@ use Magento\Cms\Api\Data\PageInterface; use Magento\Cms\Api\GetPageByIdentifierInterface; use Magento\Cms\Api\PageRepositoryInterface; -use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Store\Model\StoreManagerInterface; use Magento\Widget\Model\Template\FilterEmulate; @@ -49,14 +48,14 @@ class Page public function __construct( PageRepositoryInterface $pageRepository, FilterEmulate $widgetFilter, - GetPageByIdentifierInterface $getPageByIdentifier = null, - StoreManagerInterface $storeManager = null + GetPageByIdentifierInterface $getPageByIdentifier, + StoreManagerInterface $storeManager ) { $this->pageRepository = $pageRepository; $this->widgetFilter = $widgetFilter; - $this->pageByIdentifier = $getPageByIdentifier ?: ObjectManager::getInstance()->get(GetPageByIdentifierInterface::class); - $this->storeManager = $storeManager ?: ObjectManager::getInstance()->get(StoreManagerInterface::class); + $this->pageByIdentifier = $getPageByIdentifier; + $this->storeManager = $storeManager; } /** @@ -72,7 +71,7 @@ public function __construct( public function getData(int $pageId): array { $page = $this->pageRepository->getById($pageId); - + return $this->convertPageData($page); } From 9f2f5b605564465876b391883be3f19035b5f80a Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko Date: Wed, 8 May 2019 10:30:32 +0300 Subject: [PATCH 29/42] graphQl-535: removed unnecessary configs --- app/code/Magento/CatalogGraphQl/etc/graphql/di.xml | 7 ------- app/code/Magento/CatalogGraphQl/etc/schema.graphqls | 7 ------- .../Magento/GraphQl/Catalog/StoreConfigTest.php | 9 +-------- 3 files changed, 1 insertion(+), 22 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml index 5d5c92edd3d57..2292004f3cf01 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml @@ -85,20 +85,13 @@ catalog/seo/product_url_suffix catalog/seo/category_url_suffix - catalog/seo/product_use_categories - catalog/seo/save_rewrites_history catalog/seo/title_separator - catalog/seo/category_canonical_tag - catalog/seo/product_canonical_tag catalog/frontend/list_mode catalog/frontend/grid_per_page_values catalog/frontend/list_per_page_values catalog/frontend/grid_per_page catalog/frontend/list_per_page - catalog/frontend/flat_catalog_category catalog/frontend/default_sort_by - catalog/frontend/parse_url_directives - catalog/frontend/remember_pagination diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 1b04e2b0ff6aa..261d204cd19fc 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -405,18 +405,11 @@ type SortFields @doc(description: "SortFields contains a default value for sort type StoreConfig @doc(description: "The type contains information about a store config") { product_url_suffix : String @doc(description: "Product URL Suffix") category_url_suffix : String @doc(description: "Category URL Suffix") - product_use_categories : Int @doc(description: "Use Categories Path for Product URLs") - save_rewrites_history : Int @doc(description: "Create Permanent Redirect for URLs if URL Key Changed") title_separator : String @doc(description: "Page Title Separator") - category_canonical_tag : Int @doc(description: "Use Canonical Link Meta Tag For Categories") - product_canonical_tag : Int @doc(description: "Use Canonical Link Meta Tag For Products") list_mode : String @doc(description: "List Mode") grid_per_page_values : String @doc(description: "Products per Page on Grid Allowed Values") list_per_page_values : String @doc(description: "Products per Page on List Allowed Values") grid_per_page : Int @doc(description: "Products per Page on Grid Default Value") list_per_page : Int @doc(description: "Products per Page on List Default Value") - flat_catalog_category : Int @doc(description: "Use Flat Catalog Category") catalog_default_sort_by : String @doc(description: "Default Sort By") - parse_url_directives : Int @doc(description: "Parse URL directives") - remember_pagination : Int @doc(description: "Remember Pagination") } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/StoreConfigTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/StoreConfigTest.php index 5932fd8b034e6..2672431dbb56c 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/StoreConfigTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/StoreConfigTest.php @@ -30,20 +30,13 @@ public function testGetStoreConfig() storeConfig{ product_url_suffix, category_url_suffix, - product_use_categories, - save_rewrites_history, title_separator, - category_canonical_tag, - product_canonical_tag, list_mode, grid_per_page_values, list_per_page_values, grid_per_page, list_per_page, - flat_catalog_category, - catalog_default_sort_by, - parse_url_directives, - remember_pagination + catalog_default_sort_by } } QUERY; From 7305a43ce2b0b96dbf17621ca3a238463773f6e7 Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko Date: Wed, 8 May 2019 11:03:25 +0300 Subject: [PATCH 30/42] graphQl-309: added agreement mode --- .../Model/Resolver/DataProvider/CheckoutAgreements.php | 1 + app/code/Magento/CheckoutAgreementsGraphQl/etc/schema.graphqls | 1 + .../CheckoutAgreements/Api/CheckoutAgreementsListTest.php | 3 +++ 3 files changed, 5 insertions(+) diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/DataProvider/CheckoutAgreements.php b/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/DataProvider/CheckoutAgreements.php index 3dab845627261..2fa3fe9d1284d 100644 --- a/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/DataProvider/CheckoutAgreements.php +++ b/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/DataProvider/CheckoutAgreements.php @@ -73,6 +73,7 @@ public function getData(): array AgreementInterface::CONTENT_HEIGHT => $checkoutAgreement->getContentHeight(), AgreementInterface::CHECKBOX_TEXT => $checkoutAgreement->getCheckboxText(), AgreementInterface::IS_HTML => $checkoutAgreement->getIsHtml(), + AgreementInterface::MODE => $checkoutAgreement->getMode(), ]; } diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/etc/schema.graphqls b/app/code/Magento/CheckoutAgreementsGraphQl/etc/schema.graphqls index e63368bb3c884..3debdb2513c63 100644 --- a/app/code/Magento/CheckoutAgreementsGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CheckoutAgreementsGraphQl/etc/schema.graphqls @@ -12,4 +12,5 @@ type CheckoutAgreement @doc(description: "Defines all Checkout Agreement informa content_height: String @doc(description: "Checkout Agreement content height") checkbox_text: String @doc(description: "Checkout Agreement checkbox tex") is_html: Boolean @doc(description: "Is Checkout Agreement content in HTML format") + mode: Int @doc(description: "Is Checkout Agreement content in HTML format") } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/Api/CheckoutAgreementsListTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/Api/CheckoutAgreementsListTest.php index 62491e5e8376b..05f2afe0ed2cf 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/Api/CheckoutAgreementsListTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/Api/CheckoutAgreementsListTest.php @@ -63,6 +63,7 @@ public function testGetActiveAgreement() $this->assertEquals('200px', $agreements[0]['content_height']); $this->assertEquals('Checkout agreement checkbox text.', $agreements[0]['checkbox_text']); $this->assertEquals(true, $agreements[0]['is_html']); + $this->assertEquals(0, $agreements[0]['mode']); } /** @@ -89,6 +90,7 @@ public function testGetActiveAgreementOnSecondStore() $this->assertEquals('200px', $agreements[0]['content_height']); $this->assertEquals('Checkout agreement checkbox text.', $agreements[0]['checkbox_text']); $this->assertEquals(true, $agreements[0]['is_html']); + $this->assertEquals(0, $agreements[0]['mode']); } /** @@ -153,6 +155,7 @@ private function getQuery(): string content_height checkbox_text is_html + mode } } QUERY; From 3a88a354ad8d982f514dbbe3e88cb4259f9e4766 Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko Date: Wed, 8 May 2019 13:39:27 +0300 Subject: [PATCH 31/42] graphQl-198: refactor related products graph ql business logic to separate module --- .../Magento/CatalogGraphQl/etc/graphql/di.xml | 22 ------------- .../CatalogGraphQl/etc/schema.graphqls | 3 -- .../Products/LinkedProductsDataProvider.php | 2 +- .../DataProvider}/RelatedDataProvider.php | 4 +-- .../Model/Resolver}/CrossSellProducts.php | 4 +-- .../Model/Resolver}/RelatedProducts.php | 4 +-- .../Model/Resolver}/UpSellProducts.php | 4 +-- .../RelatedProductGraphQl/composer.json | 26 ++++++++++++++++ .../RelatedProductGraphQl/etc/graphql/di.xml | 31 +++++++++++++++++++ .../RelatedProductGraphQl/etc/module.xml | 10 ++++++ .../RelatedProductGraphQl/etc/schema.graphqls | 8 +++++ .../RelatedProductGraphQl/registration.php | 9 ++++++ composer.json | 1 + composer.lock | 2 +- .../ProductRelatedProductsTest.php | 2 +- 15 files changed, 96 insertions(+), 36 deletions(-) rename app/code/Magento/{CatalogGraphQl/Model/Resolver/Products/DataProvider/Related => RelatedProductGraphQl/Model/DataProvider}/Products/LinkedProductsDataProvider.php (93%) rename app/code/Magento/{CatalogGraphQl/Model/Resolver/Products/DataProvider/Related => RelatedProductGraphQl/Model/DataProvider}/RelatedDataProvider.php (91%) rename app/code/Magento/{CatalogGraphQl/Model/Resolver/Product/Related => RelatedProductGraphQl/Model/Resolver}/CrossSellProducts.php (85%) rename app/code/Magento/{CatalogGraphQl/Model/Resolver/Product/Related => RelatedProductGraphQl/Model/Resolver}/RelatedProducts.php (85%) rename app/code/Magento/{CatalogGraphQl/Model/Resolver/Product/Related => RelatedProductGraphQl/Model/Resolver}/UpSellProducts.php (85%) create mode 100644 app/code/Magento/RelatedProductGraphQl/composer.json create mode 100644 app/code/Magento/RelatedProductGraphQl/etc/graphql/di.xml create mode 100644 app/code/Magento/RelatedProductGraphQl/etc/module.xml create mode 100644 app/code/Magento/RelatedProductGraphQl/etc/schema.graphqls create mode 100644 app/code/Magento/RelatedProductGraphQl/registration.php rename dev/tests/api-functional/testsuite/Magento/GraphQl/{Catalog => RelatedProduct}/ProductRelatedProductsTest.php (99%) diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml index af8ce3e5442ac..a5bd42860ded0 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml @@ -78,28 +78,6 @@ - - - Magento\Catalog\Model\Product\Link::LINK_TYPE_CROSSSELL - crosssell_products - - - - - Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Related\CrossSellDataProvider - - - - - Magento\Catalog\Model\Product\Link::LINK_TYPE_UPSELL - upsell_products - - - - - Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Related\UpSellDataProvider - - diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 3e95e9672ab82..b436bdadebea0 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -93,9 +93,6 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ websites: [Website] @doc(description: "An array of websites in which the product is available") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Websites") product_links: [ProductLinksInterface] @doc(description: "An array of ProductLinks objects") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductLinks") media_gallery_entries: [MediaGalleryEntry] @doc(description: "An array of MediaGalleryEntry objects") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\MediaGalleryEntries") - related_products: [ProductInterface] @doc(description: "RelatedProduct") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Related\\RelatedProducts") - upsell_products: [ProductInterface] @doc(description: "RelatedProduct") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Related\\UpSellProducts") - crosssell_products: [ProductInterface] @doc(description: "RelatedProduct") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Related\\CrossSellProducts") tier_prices: [ProductTierPrices] @doc(description: "An array of ProductTierPrices objects") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\TierPrices") price: ProductPrices @doc(description: "A ProductPrices object, indicating the price of an item") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Price") gift_message_available: String @doc(description: "Indicates whether a gift message is available") diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/Products/LinkedProductsDataProvider.php b/app/code/Magento/RelatedProductGraphQl/Model/DataProvider/Products/LinkedProductsDataProvider.php similarity index 93% rename from app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/Products/LinkedProductsDataProvider.php rename to app/code/Magento/RelatedProductGraphQl/Model/DataProvider/Products/LinkedProductsDataProvider.php index d2daefd128129..9a62a6685a532 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/Products/LinkedProductsDataProvider.php +++ b/app/code/Magento/RelatedProductGraphQl/Model/DataProvider/Products/LinkedProductsDataProvider.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Related\Products; +namespace Magento\RelatedProductGraphQl\Model\DataProvider\Products; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\Link; diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/RelatedDataProvider.php b/app/code/Magento/RelatedProductGraphQl/Model/DataProvider/RelatedDataProvider.php similarity index 91% rename from app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/RelatedDataProvider.php rename to app/code/Magento/RelatedProductGraphQl/Model/DataProvider/RelatedDataProvider.php index 8f42cc8411a72..eb437ea31fce1 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Related/RelatedDataProvider.php +++ b/app/code/Magento/RelatedProductGraphQl/Model/DataProvider/RelatedDataProvider.php @@ -5,12 +5,12 @@ */ declare(strict_types=1); -namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Related; +namespace Magento\RelatedProductGraphQl\Model\DataProvider; use Magento\Catalog\Model\Product\Link; use Magento\Catalog\Model\Product\LinkFactory; use Magento\CatalogGraphQl\Model\Resolver\Product\ProductFieldsSelector; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Related\Products\LinkedProductsDataProvider; +use Magento\RelatedProductGraphQl\Model\DataProvider\Products\LinkedProductsDataProvider; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; /** diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/CrossSellProducts.php b/app/code/Magento/RelatedProductGraphQl/Model/Resolver/CrossSellProducts.php similarity index 85% rename from app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/CrossSellProducts.php rename to app/code/Magento/RelatedProductGraphQl/Model/Resolver/CrossSellProducts.php index 2ae3d30a2b01f..3a6fdb855b856 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/CrossSellProducts.php +++ b/app/code/Magento/RelatedProductGraphQl/Model/Resolver/CrossSellProducts.php @@ -5,9 +5,9 @@ */ declare(strict_types=1); -namespace Magento\CatalogGraphQl\Model\Resolver\Product\Related; +namespace Magento\RelatedProductGraphQl\Model\Resolver; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Related\RelatedDataProvider; +use Magento\RelatedProductGraphQl\Model\DataProvider\RelatedDataProvider; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/RelatedProducts.php b/app/code/Magento/RelatedProductGraphQl/Model/Resolver/RelatedProducts.php similarity index 85% rename from app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/RelatedProducts.php rename to app/code/Magento/RelatedProductGraphQl/Model/Resolver/RelatedProducts.php index cb437a2202c88..280e3d9d0ede6 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/RelatedProducts.php +++ b/app/code/Magento/RelatedProductGraphQl/Model/Resolver/RelatedProducts.php @@ -5,9 +5,9 @@ */ declare(strict_types=1); -namespace Magento\CatalogGraphQl\Model\Resolver\Product\Related; +namespace Magento\RelatedProductGraphQl\Model\Resolver; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Related\RelatedDataProvider; +use Magento\RelatedProductGraphQl\Model\DataProvider\RelatedDataProvider; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/UpSellProducts.php b/app/code/Magento/RelatedProductGraphQl/Model/Resolver/UpSellProducts.php similarity index 85% rename from app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/UpSellProducts.php rename to app/code/Magento/RelatedProductGraphQl/Model/Resolver/UpSellProducts.php index e43e0fe57de4b..5299b43f5f54f 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Related/UpSellProducts.php +++ b/app/code/Magento/RelatedProductGraphQl/Model/Resolver/UpSellProducts.php @@ -5,9 +5,9 @@ */ declare(strict_types=1); -namespace Magento\CatalogGraphQl\Model\Resolver\Product\Related; +namespace Magento\RelatedProductGraphQl\Model\Resolver; -use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Related\RelatedDataProvider; +use Magento\RelatedProductGraphQl\Model\DataProvider\RelatedDataProvider; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; diff --git a/app/code/Magento/RelatedProductGraphQl/composer.json b/app/code/Magento/RelatedProductGraphQl/composer.json new file mode 100644 index 0000000000000..0d314d433f177 --- /dev/null +++ b/app/code/Magento/RelatedProductGraphQl/composer.json @@ -0,0 +1,26 @@ +{ + "name": "magento/module-related-product-graph-ql", + "description": "N/A", + "type": "magento2-module", + "require": { + "php": "~7.1.3||~7.2.0", + "magento/module-catalog": "*", + "magento/module-catalog-graph-ql": "*", + "magento/framework": "*" + }, + "suggest": { + "magento/module-graph-ql": "*" + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\RelatedProductGraphQl\\": "" + } + } +} diff --git a/app/code/Magento/RelatedProductGraphQl/etc/graphql/di.xml b/app/code/Magento/RelatedProductGraphQl/etc/graphql/di.xml new file mode 100644 index 0000000000000..f64cf197b250f --- /dev/null +++ b/app/code/Magento/RelatedProductGraphQl/etc/graphql/di.xml @@ -0,0 +1,31 @@ + + + + + + Magento\Catalog\Model\Product\Link::LINK_TYPE_CROSSSELL + crosssell_products + + + + + Magento\RelatedProductGraphQl\Model\DataProvider\CrossSellDataProvider + + + + + Magento\Catalog\Model\Product\Link::LINK_TYPE_UPSELL + upsell_products + + + + + Magento\RelatedProductGraphQl\Model\DataProvider\UpSellDataProvider + + + diff --git a/app/code/Magento/RelatedProductGraphQl/etc/module.xml b/app/code/Magento/RelatedProductGraphQl/etc/module.xml new file mode 100644 index 0000000000000..e30775c253a45 --- /dev/null +++ b/app/code/Magento/RelatedProductGraphQl/etc/module.xml @@ -0,0 +1,10 @@ + + + + + diff --git a/app/code/Magento/RelatedProductGraphQl/etc/schema.graphqls b/app/code/Magento/RelatedProductGraphQl/etc/schema.graphqls new file mode 100644 index 0000000000000..240fc6c4496f0 --- /dev/null +++ b/app/code/Magento/RelatedProductGraphQl/etc/schema.graphqls @@ -0,0 +1,8 @@ +# Copyright © Magento, Inc. All rights reserved. +# See COPYING.txt for license details. + +interface ProductInterface { + related_products: [ProductInterface] @doc(description: "RelatedProduct") @resolver(class: "Magento\\RelatedProductGraphQl\\Model\\Resolver\\RelatedProducts") + upsell_products: [ProductInterface] @doc(description: "RelatedProduct") @resolver(class: "Magento\\RelatedProductGraphQl\\Model\\Resolver\\UpSellProducts") + crosssell_products: [ProductInterface] @doc(description: "RelatedProduct") @resolver(class: "Magento\\RelatedProductGraphQl\\Model\\Resolver\\CrossSellProducts") +} \ No newline at end of file diff --git a/app/code/Magento/RelatedProductGraphQl/registration.php b/app/code/Magento/RelatedProductGraphQl/registration.php new file mode 100644 index 0000000000000..d18dfc27cc7c6 --- /dev/null +++ b/app/code/Magento/RelatedProductGraphQl/registration.php @@ -0,0 +1,9 @@ + Date: Wed, 8 May 2019 13:52:27 +0300 Subject: [PATCH 32/42] graphQl-198: fixed description --- app/code/Magento/CatalogGraphQl/etc/schema.graphqls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index b436bdadebea0..9f102a1c6a150 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -50,7 +50,7 @@ type ProductPrices @doc(description: "The ProductPrices object contains the regu type ProductLinks implements ProductLinksInterface @doc(description: "ProductLinks is an implementation of ProductLinksInterface.") { } -interface ProductLinksInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductLinkTypeResolverComposite") @doc(description:"Related contains information about linked products, including the link type and product type of each item.") { +interface ProductLinksInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductLinkTypeResolverComposite") @doc(description:"ProductLinks contains information about linked products, including the link type and product type of each item.") { sku: String @doc(description: "The identifier of the linked product") link_type: String @doc(description: "One of related, associated, upsell, or crosssell") linked_product_sku: String @doc(description: "The SKU of the linked product") From 29d5b8843093acc63c902db3ad7ec896920adad5 Mon Sep 17 00:00:00 2001 From: Kajal Solanki Date: Wed, 8 May 2019 18:25:04 +0530 Subject: [PATCH 33/42] testBundleProductWithNotVisibleChildren fix misspelling --- .../testsuite/Magento/GraphQl/Bundle/BundleProductViewTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Bundle/BundleProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Bundle/BundleProductViewTest.php index 0621370972763..20d097906d7e7 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Bundle/BundleProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Bundle/BundleProductViewTest.php @@ -108,7 +108,7 @@ public function testAllFieldsBundleProducts() /** * @magentoApiDataFixture Magento/Bundle/_files/bundle_product_with_not_visible_children.php */ - public function testBundleProdutWithNotVisibleChildren() + public function testBundleProductWithNotVisibleChildren() { $productSku = 'bundle-product-1'; $query From c3040e682d56964b78c6e7a29388bea6c1a34c85 Mon Sep 17 00:00:00 2001 From: Valerii Naida Date: Wed, 8 May 2019 10:26:16 -0500 Subject: [PATCH 34/42] GraphQl-309: [Checkout] Checkout Agreements --- .../Model/Resolver/CheckoutAgreements.php | 8 ++++++-- .../etc/schema.graphqls | 17 +++++++++++------ .../GetCheckoutAgreementsTest.php | 14 +++++++------- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/CheckoutAgreements.php b/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/CheckoutAgreements.php index 02345f71681f8..670107aef73f2 100644 --- a/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/CheckoutAgreements.php +++ b/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/CheckoutAgreements.php @@ -7,6 +7,8 @@ namespace Magento\CheckoutAgreementsGraphQl\Model\Resolver; +use Magento\CheckoutAgreements\Model\AgreementModeOptions; +use Magento\CheckoutAgreements\Model\ResourceModel\Agreement\Collection; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; @@ -65,9 +67,10 @@ public function resolve( return []; } + /** @var Collection $agreementsCollection */ $agreementsCollection = $this->agreementCollectionFactory->create(); $agreementsCollection->addStoreFilter($this->storeManager->getStore()->getId()); - $agreementsCollection->addFieldToFilter('is_active', 1); + $agreementsCollection->addFieldToFilter(AgreementInterface::IS_ACTIVE, 1); $checkoutAgreementData = []; /** @var AgreementInterface $checkoutAgreement */ @@ -79,7 +82,8 @@ public function resolve( AgreementInterface::CONTENT_HEIGHT => $checkoutAgreement->getContentHeight(), AgreementInterface::CHECKBOX_TEXT => $checkoutAgreement->getCheckboxText(), AgreementInterface::IS_HTML => $checkoutAgreement->getIsHtml(), - AgreementInterface::MODE => $checkoutAgreement->getMode(), + AgreementInterface::MODE => + AgreementModeOptions::MODE_AUTO === $checkoutAgreement->getMode() ? 'AUTO' : 'MANUAL', ]; } return $checkoutAgreementData; diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/etc/schema.graphqls b/app/code/Magento/CheckoutAgreementsGraphQl/etc/schema.graphqls index 3debdb2513c63..64ef9411dfca6 100644 --- a/app/code/Magento/CheckoutAgreementsGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CheckoutAgreementsGraphQl/etc/schema.graphqls @@ -6,11 +6,16 @@ type Query { } type CheckoutAgreement @doc(description: "Defines all Checkout Agreement information") { - agreement_id: Int @doc(description: "Checkout Agreement identifier") - name: String @doc(description: "Checkout Agreement name") - content: String @doc(description: "Checkout Agreement content") + agreement_id: Int! @doc(description: "Checkout Agreement identifier") + name: String! @doc(description: "Checkout Agreement name") + content: String! @doc(description: "Checkout Agreement content") content_height: String @doc(description: "Checkout Agreement content height") - checkbox_text: String @doc(description: "Checkout Agreement checkbox tex") - is_html: Boolean @doc(description: "Is Checkout Agreement content in HTML format") - mode: Int @doc(description: "Is Checkout Agreement content in HTML format") + checkbox_text: String! @doc(description: "Checkout Agreement checkbox text") + is_html: Boolean! @doc(description: "Is Checkout Agreement content in HTML format") + mode: CheckoutAgreementMode! +} + +enum CheckoutAgreementMode { + AUTO + MANUAL } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/GetCheckoutAgreementsTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/GetCheckoutAgreementsTest.php index 8fdfd5cf0108d..3aa01d7994222 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/GetCheckoutAgreementsTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/CheckoutAgreements/GetCheckoutAgreementsTest.php @@ -68,8 +68,8 @@ public function testGetActiveAgreement() self::assertEquals('Checkout agreement content: HTML', $agreements[0]['content']); self::assertEquals('200px', $agreements[0]['content_height']); self::assertEquals('Checkout agreement checkbox text.', $agreements[0]['checkbox_text']); - self::assertEquals(true, $agreements[0]['is_html']); - self::assertEquals(0, $agreements[0]['mode']); + self::assertTrue($agreements[0]['is_html']); + self::assertEquals('AUTO', $agreements[0]['mode']); } /** @@ -95,8 +95,8 @@ public function testGetActiveAgreementOnSecondStore() self::assertEquals('Checkout agreement content: HTML', $agreements[0]['content']); self::assertEquals('200px', $agreements[0]['content_height']); self::assertEquals('Checkout agreement checkbox text.', $agreements[0]['checkbox_text']); - self::assertEquals(true, $agreements[0]['is_html']); - self::assertEquals(0, $agreements[0]['mode']); + self::assertTrue($agreements[0]['is_html']); + self::assertEquals('AUTO', $agreements[0]['mode']); } /** @@ -116,7 +116,7 @@ public function testGetActiveAgreementFromSecondStoreOnDefaultStore() self::assertArrayHasKey('checkoutAgreements', $response); $agreements = $response['checkoutAgreements']; - self::assertCount(0, $agreements); + self::assertEmpty($agreements); } public function testGetAgreementNotSet() @@ -127,7 +127,7 @@ public function testGetAgreementNotSet() self::assertArrayHasKey('checkoutAgreements', $response); $agreements = $response['checkoutAgreements']; - self::assertCount(0, $agreements); + self::assertEmpty($agreements); } /** @@ -143,7 +143,7 @@ public function testDisabledAgreements() self::assertArrayHasKey('checkoutAgreements', $response); $agreements = $response['checkoutAgreements']; - self::assertCount(0, $agreements); + self::assertEmpty($agreements); } /** From 4d7be93e831db12cc1c10c41651f6c36c3bb122e Mon Sep 17 00:00:00 2001 From: Valerii Naida Date: Wed, 8 May 2019 10:54:54 -0500 Subject: [PATCH 35/42] GraphQl-309: [Checkout] Checkout Agreements --- .../Model/Resolver/CheckoutAgreements.php | 2 +- composer.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/CheckoutAgreements.php b/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/CheckoutAgreements.php index 670107aef73f2..3daf88226d8e5 100644 --- a/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/CheckoutAgreements.php +++ b/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/CheckoutAgreements.php @@ -83,7 +83,7 @@ public function resolve( AgreementInterface::CHECKBOX_TEXT => $checkoutAgreement->getCheckboxText(), AgreementInterface::IS_HTML => $checkoutAgreement->getIsHtml(), AgreementInterface::MODE => - AgreementModeOptions::MODE_AUTO === $checkoutAgreement->getMode() ? 'AUTO' : 'MANUAL', + AgreementModeOptions::MODE_AUTO === (int)$checkoutAgreement->getMode() ? 'AUTO' : 'MANUAL', ]; } return $checkoutAgreementData; diff --git a/composer.lock b/composer.lock index 09ca8cd9f3f02..77783c00dd641 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6b0350be54f49186c1c9f55ac29bf1cb", + "content-hash": "24c95683a202b83c7f182921c0c88328", "packages": [ { "name": "braintree/braintree_php", @@ -6775,12 +6775,12 @@ "version": "v1.6.5", "source": { "type": "git", - "url": "https://github.com/bovigo/vfsStream.git", + "url": "https://github.com/mikey179/vfsStream.git", "reference": "d5fec95f541d4d71c4823bb5e30cf9b9e5b96145" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/d5fec95f541d4d71c4823bb5e30cf9b9e5b96145", + "url": "https://api.github.com/repos/mikey179/vfsStream/zipball/d5fec95f541d4d71c4823bb5e30cf9b9e5b96145", "reference": "d5fec95f541d4d71c4823bb5e30cf9b9e5b96145", "shasum": "" }, From d7b7a2e19fe376b30ac45df91c75b80c416e38bb Mon Sep 17 00:00:00 2001 From: Valerii Naida Date: Wed, 8 May 2019 11:49:58 -0500 Subject: [PATCH 36/42] GraphQl-387: Test coverage of getting IDs of CMS page/blocks by GraphQL API --- .../Model/Resolver/DataProvider/Page.php | 36 +++------------ .../CmsGraphQl/Model/Resolver/Page.php | 45 ++----------------- 2 files changed, 8 insertions(+), 73 deletions(-) diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php index 2001bc006bbb8..8b9766ca311c7 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php @@ -58,23 +58,6 @@ public function __construct( $this->storeManager = $storeManager; } - /** - * @deprecated - * @see getDataByPageId(int $pageId) - * - * Get the page data - * - * @param int $pageId - * @return array - * @throws NoSuchEntityException - */ - public function getData(int $pageId): array - { - $page = $this->pageRepository->getById($pageId); - - return $this->convertPageData($page); - } - /** * Returns page data by page_id * @@ -86,7 +69,7 @@ public function getDataByPageId(int $pageId): array { $page = $this->pageRepository->getById($pageId); - return $this->convertPageData($page, false, true); + return $this->convertPageData($page); } /** @@ -101,17 +84,15 @@ public function getDataByPageIdentifier(string $pageIdentifier): array $storeId = (int)$this->storeManager->getStore()->getId(); $page = $this->pageByIdentifier->execute($pageIdentifier, $storeId); - return $this->convertPageData($page, false, true); + return $this->convertPageData($page); } /** * @param PageInterface $page - * @param bool $includePageId - * @param bool $includePageIdentifier * @return array * @throws NoSuchEntityException */ - private function convertPageData(PageInterface $page, $includePageId = true, $includePageIdentifier = false) + private function convertPageData(PageInterface $page) { if (false === $page->isActive()) { throw new NoSuchEntityException(); @@ -128,16 +109,9 @@ private function convertPageData(PageInterface $page, $includePageId = true, $in PageInterface::META_TITLE => $page->getMetaTitle(), PageInterface::META_DESCRIPTION => $page->getMetaDescription(), PageInterface::META_KEYWORDS => $page->getMetaKeywords(), + PageInterface::PAGE_ID => $page->getId(), + PageInterface::IDENTIFIER => $page->getIdentifier(), ]; - - if ($includePageId) { - $pageData[PageInterface::PAGE_ID] = $page->getId(); - } - - if ($includePageIdentifier) { - $pageData[PageInterface::IDENTIFIER] = $page->getIdentifier(); - } - return $pageData; } } diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/Page.php b/app/code/Magento/CmsGraphQl/Model/Resolver/Page.php index 489a3e0a75c80..fbd8e26030952 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/Page.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/Page.php @@ -45,7 +45,7 @@ public function resolve( array $value = null, array $args = null ) { - if (!isset($args['id']) && !isset($args['identifier'])) { + if (!isset($args['id'], $args['identifier'])) { throw new GraphQlInputException(__('"Page id/identifier should be specified')); } @@ -53,52 +53,13 @@ public function resolve( try { if (isset($args['id'])) { - $pageData = $this->getPageDataById($this->getPageId($args)); + $pageData = $this->pageDataProvider->getDataByPageId((int)$args['id']); } elseif (isset($args['identifier'])) { - $pageData = $this->getPageDataByIdentifier($this->getPageIdentifier($args)); + $pageData = $this->pageDataProvider->getDataByPageIdentifier((string)$args['identifier']); } } catch (NoSuchEntityException $e) { throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e); } - return $pageData; } - - /** - * @param array $args - * @return int - */ - private function getPageId(array $args): int - { - return isset($args['id']) ? (int)$args['id'] : 0; - } - - /** - * @param array $args - * @return string - */ - private function getPageIdentifier(array $args): string - { - return isset($args['identifier']) ? (string)$args['identifier'] : ''; - } - - /** - * @param int $pageId - * @return array - * @throws GraphQlNoSuchEntityException - */ - private function getPageDataById(int $pageId): array - { - return $this->pageDataProvider->getDataByPageId($pageId); - } - - /** - * @param string $pageIdentifier - * @return array - * @throws GraphQlNoSuchEntityException - */ - private function getPageDataByIdentifier(string $pageIdentifier): array - { - return $this->pageDataProvider->getDataByPageIdentifier($pageIdentifier); - } } From 4835285066637047ef47af81759efb2f2fde29dd Mon Sep 17 00:00:00 2001 From: Valerii Naida Date: Wed, 8 May 2019 12:27:02 -0500 Subject: [PATCH 37/42] GraphQl-198: Products: access to related/up-sell/cross-sell product fields --- .../DataProvider/RelatedDataProvider.php | 80 -------- ...der.php => RelatedProductDataProvider.php} | 35 +++- .../Model/Resolver/CrossSellProducts.php | 31 ++- .../Model/Resolver/RelatedProducts.php | 30 ++- .../Model/Resolver/UpSellProducts.php | 31 ++- .../RelatedProductGraphQl/etc/graphql/di.xml | 31 --- .../RelatedProduct/GetRelatedProductsTest.php | 178 ++++++++++++++++++ .../ProductRelatedProductsTest.php | 175 ----------------- 8 files changed, 275 insertions(+), 316 deletions(-) delete mode 100644 app/code/Magento/RelatedProductGraphQl/Model/DataProvider/RelatedDataProvider.php rename app/code/Magento/RelatedProductGraphQl/Model/DataProvider/{Products/LinkedProductsDataProvider.php => RelatedProductDataProvider.php} (52%) delete mode 100644 app/code/Magento/RelatedProductGraphQl/etc/graphql/di.xml create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/RelatedProduct/GetRelatedProductsTest.php delete mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/RelatedProduct/ProductRelatedProductsTest.php diff --git a/app/code/Magento/RelatedProductGraphQl/Model/DataProvider/RelatedDataProvider.php b/app/code/Magento/RelatedProductGraphQl/Model/DataProvider/RelatedDataProvider.php deleted file mode 100644 index eb437ea31fce1..0000000000000 --- a/app/code/Magento/RelatedProductGraphQl/Model/DataProvider/RelatedDataProvider.php +++ /dev/null @@ -1,80 +0,0 @@ -dataProvider = $dataProvider; - $this->productFieldsSelector = $productFieldsSelector; - $this->linkType = $linkType; - $this->schemaNodeName = $schemaNodeName; - } - - /** - * Related Products Data - * - * @param ResolveInfo $info - * @param array $value - * @return array - */ - public function getProducts(ResolveInfo $info, array $value): array - { - $product = $value['model']; - $fields = $this->productFieldsSelector->getProductFieldsFromInfo($info, $this->schemaNodeName); - $products = $this->dataProvider->getRelatedProducts($product, $fields, $this->linkType); - - $data = []; - foreach ($products as $key => $product) { - $data[$key] = $product->getData(); - $data[$key]['model'] = $product; - } - - return $data; - } -} diff --git a/app/code/Magento/RelatedProductGraphQl/Model/DataProvider/Products/LinkedProductsDataProvider.php b/app/code/Magento/RelatedProductGraphQl/Model/DataProvider/RelatedProductDataProvider.php similarity index 52% rename from app/code/Magento/RelatedProductGraphQl/Model/DataProvider/Products/LinkedProductsDataProvider.php rename to app/code/Magento/RelatedProductGraphQl/Model/DataProvider/RelatedProductDataProvider.php index 9a62a6685a532..04a71da0337de 100644 --- a/app/code/Magento/RelatedProductGraphQl/Model/DataProvider/Products/LinkedProductsDataProvider.php +++ b/app/code/Magento/RelatedProductGraphQl/Model/DataProvider/RelatedProductDataProvider.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\RelatedProductGraphQl\Model\DataProvider\Products; +namespace Magento\RelatedProductGraphQl\Model\DataProvider; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\Link; @@ -14,7 +14,7 @@ /** * Related Products Data Provider */ -class LinkedProductsDataProvider +class RelatedProductDataProvider { /** * @var LinkFactory @@ -24,24 +24,45 @@ class LinkedProductsDataProvider /** * @param LinkFactory $linkFactory */ - public function __construct(LinkFactory $linkFactory) - { + public function __construct( + LinkFactory $linkFactory + ) { $this->linkFactory = $linkFactory; } /** - * Get Related Products by Product and Link Type + * Related Products Data + * + * @param Product $product + * @param array $fields + * @param int $linkType + * @return array + */ + public function getData(Product $product, array $fields, int $linkType): array + { + $relatedProducts = $this->getRelatedProducts($product, $fields, $linkType); + + $data = []; + foreach ($relatedProducts as $relatedProduct) { + $relatedProductData = $relatedProduct->getData(); + $relatedProductData['model'] = $relatedProduct; + } + return $data; + } + + /** + * Get Related Products * * @param Product $product * @param array $fields * @param int $linkType * @return Product[] */ - public function getRelatedProducts(Product $product, array $fields, int $linkType): array + private function getRelatedProducts(Product $product, array $fields, int $linkType): array { /** @var Link $link */ $link = $this->linkFactory->create([ 'data' => [ - 'link_type_id' => $linkType + 'link_type_id' => $linkType, ]]); $collection = $link->getProductCollection(); diff --git a/app/code/Magento/RelatedProductGraphQl/Model/Resolver/CrossSellProducts.php b/app/code/Magento/RelatedProductGraphQl/Model/Resolver/CrossSellProducts.php index 3a6fdb855b856..dcaa75b85f599 100644 --- a/app/code/Magento/RelatedProductGraphQl/Model/Resolver/CrossSellProducts.php +++ b/app/code/Magento/RelatedProductGraphQl/Model/Resolver/CrossSellProducts.php @@ -7,7 +7,10 @@ namespace Magento\RelatedProductGraphQl\Model\Resolver; -use Magento\RelatedProductGraphQl\Model\DataProvider\RelatedDataProvider; +use Magento\Catalog\Model\Product\Link; +use Magento\CatalogGraphQl\Model\Resolver\Product\ProductFieldsSelector; +use Magento\Framework\Exception\LocalizedException; +use Magento\RelatedProductGraphQl\Model\DataProvider\RelatedProductDataProvider; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; @@ -18,18 +21,25 @@ class CrossSellProducts implements ResolverInterface { /** - * @see module di.xml - * @var RelatedDataProvider + * @var ProductFieldsSelector */ - private $dataProvider; + private $productFieldsSelector; /** - * @param RelatedDataProvider $dataProvider + * @var RelatedProductDataProvider + */ + private $relatedProductDataProvider; + + /** + * @param ProductFieldsSelector $productFieldsSelector + * @param RelatedProductDataProvider $relatedProductDataProvider */ public function __construct( - RelatedDataProvider $dataProvider + ProductFieldsSelector $productFieldsSelector, + RelatedProductDataProvider $relatedProductDataProvider ) { - $this->dataProvider = $dataProvider; + $this->productFieldsSelector = $productFieldsSelector; + $this->relatedProductDataProvider = $relatedProductDataProvider; } /** @@ -37,8 +47,13 @@ public function __construct( */ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { - $data = $this->dataProvider->getProducts($info, $value); + if (!isset($value['model'])) { + throw new LocalizedException(__('"model" value should be specified')); + } + $product = $value['model']; + $fields = $this->productFieldsSelector->getProductFieldsFromInfo($info, 'crosssell_products'); + $data = $this->relatedProductDataProvider->getData($product, $fields, Link::LINK_TYPE_CROSSSELL); return $data; } } diff --git a/app/code/Magento/RelatedProductGraphQl/Model/Resolver/RelatedProducts.php b/app/code/Magento/RelatedProductGraphQl/Model/Resolver/RelatedProducts.php index 280e3d9d0ede6..568c3282a6ee8 100644 --- a/app/code/Magento/RelatedProductGraphQl/Model/Resolver/RelatedProducts.php +++ b/app/code/Magento/RelatedProductGraphQl/Model/Resolver/RelatedProducts.php @@ -7,7 +7,10 @@ namespace Magento\RelatedProductGraphQl\Model\Resolver; -use Magento\RelatedProductGraphQl\Model\DataProvider\RelatedDataProvider; +use Magento\Catalog\Model\Product\Link; +use Magento\CatalogGraphQl\Model\Resolver\Product\ProductFieldsSelector; +use Magento\Framework\Exception\LocalizedException; +use Magento\RelatedProductGraphQl\Model\DataProvider\RelatedProductDataProvider; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; @@ -18,17 +21,25 @@ class RelatedProducts implements ResolverInterface { /** - * @var RelatedDataProvider + * @var ProductFieldsSelector */ - private $dataProvider; + private $productFieldsSelector; /** - * @param RelatedDataProvider $dataProvider + * @var RelatedProductDataProvider + */ + private $relatedProductDataProvider; + + /** + * @param ProductFieldsSelector $productFieldsSelector + * @param RelatedProductDataProvider $relatedProductDataProvider */ public function __construct( - RelatedDataProvider $dataProvider + ProductFieldsSelector $productFieldsSelector, + RelatedProductDataProvider $relatedProductDataProvider ) { - $this->dataProvider = $dataProvider; + $this->productFieldsSelector = $productFieldsSelector; + $this->relatedProductDataProvider = $relatedProductDataProvider; } /** @@ -36,8 +47,13 @@ public function __construct( */ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { - $data = $this->dataProvider->getProducts($info, $value); + if (!isset($value['model'])) { + throw new LocalizedException(__('"model" value should be specified')); + } + $product = $value['model']; + $fields = $this->productFieldsSelector->getProductFieldsFromInfo($info, 'related_products'); + $data = $this->relatedProductDataProvider->getData($product, $fields, Link::LINK_TYPE_RELATED); return $data; } } diff --git a/app/code/Magento/RelatedProductGraphQl/Model/Resolver/UpSellProducts.php b/app/code/Magento/RelatedProductGraphQl/Model/Resolver/UpSellProducts.php index 5299b43f5f54f..df3a62408c53f 100644 --- a/app/code/Magento/RelatedProductGraphQl/Model/Resolver/UpSellProducts.php +++ b/app/code/Magento/RelatedProductGraphQl/Model/Resolver/UpSellProducts.php @@ -7,7 +7,10 @@ namespace Magento\RelatedProductGraphQl\Model\Resolver; -use Magento\RelatedProductGraphQl\Model\DataProvider\RelatedDataProvider; +use Magento\Catalog\Model\Product\Link; +use Magento\CatalogGraphQl\Model\Resolver\Product\ProductFieldsSelector; +use Magento\Framework\Exception\LocalizedException; +use Magento\RelatedProductGraphQl\Model\DataProvider\RelatedProductDataProvider; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; @@ -18,18 +21,25 @@ class UpSellProducts implements ResolverInterface { /** - * @see module di.xml - * @var RelatedDataProvider + * @var ProductFieldsSelector */ - private $dataProvider; + private $productFieldsSelector; /** - * @param RelatedDataProvider $dataProvider + * @var RelatedProductDataProvider + */ + private $relatedProductDataProvider; + + /** + * @param ProductFieldsSelector $productFieldsSelector + * @param RelatedProductDataProvider $relatedProductDataProvider */ public function __construct( - RelatedDataProvider $dataProvider + ProductFieldsSelector $productFieldsSelector, + RelatedProductDataProvider $relatedProductDataProvider ) { - $this->dataProvider = $dataProvider; + $this->productFieldsSelector = $productFieldsSelector; + $this->relatedProductDataProvider = $relatedProductDataProvider; } /** @@ -37,8 +47,13 @@ public function __construct( */ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { - $data = $this->dataProvider->getProducts($info, $value); + if (!isset($value['model'])) { + throw new LocalizedException(__('"model" value should be specified')); + } + $product = $value['model']; + $fields = $this->productFieldsSelector->getProductFieldsFromInfo($info, 'upsell_products'); + $data = $this->relatedProductDataProvider->getData($product, $fields, Link::LINK_TYPE_UPSELL); return $data; } } diff --git a/app/code/Magento/RelatedProductGraphQl/etc/graphql/di.xml b/app/code/Magento/RelatedProductGraphQl/etc/graphql/di.xml deleted file mode 100644 index f64cf197b250f..0000000000000 --- a/app/code/Magento/RelatedProductGraphQl/etc/graphql/di.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - Magento\Catalog\Model\Product\Link::LINK_TYPE_CROSSSELL - crosssell_products - - - - - Magento\RelatedProductGraphQl\Model\DataProvider\CrossSellDataProvider - - - - - Magento\Catalog\Model\Product\Link::LINK_TYPE_UPSELL - upsell_products - - - - - Magento\RelatedProductGraphQl\Model\DataProvider\UpSellDataProvider - - - diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/RelatedProduct/GetRelatedProductsTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/RelatedProduct/GetRelatedProductsTest.php new file mode 100644 index 0000000000000..3c0b578d850b9 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/RelatedProduct/GetRelatedProductsTest.php @@ -0,0 +1,178 @@ +graphQlQuery($query); + + self::assertArrayHasKey('products', $response); + self::assertArrayHasKey('items', $response['products']); + self::assertEquals(1, count($response['products']['items'])); + self::assertArrayHasKey(0, $response['products']['items']); + self::assertArrayHasKey('related_products', $response['products']['items'][0]); + $relatedProducts = $response['products']['items'][0]['related_products']; + self::assertCount(2, $relatedProducts); + self::assertRelatedProducts($relatedProducts); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/products_crosssell.php + */ + public function testQueryCrossSellProducts() + { + $productSku = 'simple_with_cross'; + + $query = <<graphQlQuery($query); + + self::assertArrayHasKey('products', $response); + self::assertArrayHasKey('items', $response['products']); + self::assertEquals(1, count($response['products']['items'])); + self::assertArrayHasKey(0, $response['products']['items']); + self::assertArrayHasKey('crosssell_products', $response['products']['items'][0]); + $crossSellProducts = $response['products']['items'][0]['crosssell_products']; + self::assertCount(1, $crossSellProducts); + $crossSellProduct = $crossSellProducts[0]; + self::assertArrayHasKey('sku', $crossSellProduct); + self::assertArrayHasKey('name', $crossSellProduct); + self::assertArrayHasKey('url_key', $crossSellProduct); + self::assertArrayHasKey('id', $crossSellProduct); + self::assertArrayHasKey('created_at', $crossSellProduct); + self::assertEquals($crossSellProduct['sku'], 'simple'); + self::assertEquals($crossSellProduct['name'], 'Simple Cross Sell'); + self::assertEquals($crossSellProduct['url_key'], 'simple-cross-sell'); + self::assertNotEmpty($crossSellProduct['created_at']); + self::assertNotEmpty($crossSellProduct['id']); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/products_upsell.php + */ + public function testQueryUpSellProducts() + { + $productSku = 'simple_with_upsell'; + + $query = <<graphQlQuery($query); + + self::assertArrayHasKey('products', $response); + self::assertArrayHasKey('items', $response['products']); + self::assertEquals(1, count($response['products']['items'])); + self::assertArrayHasKey(0, $response['products']['items']); + self::assertArrayHasKey('upsell_products', $response['products']['items'][0]); + $upSellProducts = $response['products']['items'][0]['upsell_products']; + self::assertCount(1, $upSellProducts); + $upSellProduct = $upSellProducts[0]; + self::assertArrayHasKey('sku', $upSellProduct); + self::assertArrayHasKey('name', $upSellProduct); + self::assertArrayHasKey('url_key', $upSellProduct); + self::assertArrayHasKey('id', $upSellProduct); + self::assertArrayHasKey('created_at', $upSellProduct); + self::assertEquals($upSellProduct['sku'], 'simple'); + self::assertEquals($upSellProduct['name'], 'Simple Up Sell'); + self::assertEquals($upSellProduct['url_key'], 'simple-up-sell'); + self::assertNotEmpty($upSellProduct['created_at']); + self::assertNotEmpty($upSellProduct['id']); + } + + /** + * @param array $relatedProducts + */ + private function assertRelatedProducts(array $relatedProducts): void + { + $expectedData = [ + 'simple' => [ + 'name' => 'Simple Related Product', + 'url_key' => 'simple-related-product', + + ], + 'simple_with_cross_two' => [ + 'name' => 'Simple Product With Related Product Two', + 'url_key' => 'simple-product-with-related-product-two', + ] + ]; + + foreach ($relatedProducts as $product) { + self::assertArrayHasKey('sku', $product); + self::assertArrayHasKey('name', $product); + self::assertArrayHasKey('url_key', $product); + self::assertArrayHasKey('id', $product); + self::assertArrayHasKey('created_at', $product); + + self::assertArrayHasKey($product['sku'], $expectedData); + $productExpectedData = $expectedData[$product['sku']]; + + self::assertEquals($product['name'], $productExpectedData['name']); + self::assertEquals($product['url_key'], $productExpectedData['url_key']); + self::assertNotEmpty($product['created_at']); + self::assertNotEmpty($product['id']); + } + } +} diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/RelatedProduct/ProductRelatedProductsTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/RelatedProduct/ProductRelatedProductsTest.php deleted file mode 100644 index 5317e88d7e118..0000000000000 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/RelatedProduct/ProductRelatedProductsTest.php +++ /dev/null @@ -1,175 +0,0 @@ -graphQlQuery($query); - - $this->assertArrayHasKey('products', $response); - $this->assertArrayHasKey('items', $response['products']); - $this->assertEquals(1, count($response['products']['items'])); - $this->assertArrayHasKey(0, $response['products']['items']); - $this->assertArrayHasKey('related_products', $response['products']['items'][0]); - $relatedProducts = $response['products']['items'][0]['related_products']; - $this->assertCount(2, $relatedProducts); - $this->assertRelatedProducts($relatedProducts); - } - - /** - * @magentoApiDataFixture Magento/Catalog/_files/products_crosssell.php - */ - public function testQueryCrossSellProducts() - { - $productSku = 'simple_with_cross'; - - $query = <<graphQlQuery($query); - - $this->assertArrayHasKey('products', $response); - $this->assertArrayHasKey('items', $response['products']); - $this->assertEquals(1, count($response['products']['items'])); - $this->assertArrayHasKey(0, $response['products']['items']); - $this->assertArrayHasKey('crosssell_products', $response['products']['items'][0]); - $crossSellProducts = $response['products']['items'][0]['crosssell_products']; - $this->assertCount(1, $crossSellProducts); - $crossSellProduct = $crossSellProducts[0]; - $this->assertArrayHasKey('sku', $crossSellProduct); - $this->assertArrayHasKey('name', $crossSellProduct); - $this->assertArrayHasKey('url_key', $crossSellProduct); - $this->assertArrayHasKey('id', $crossSellProduct); - $this->assertArrayHasKey('created_at', $crossSellProduct); - $this->assertEquals($crossSellProduct['sku'], 'simple'); - $this->assertEquals($crossSellProduct['name'], 'Simple Cross Sell'); - $this->assertEquals($crossSellProduct['url_key'], 'simple-cross-sell'); - $this->assertNotEmpty($crossSellProduct['created_at']); - $this->assertNotEmpty($crossSellProduct['id']); - } - - /** - * @magentoApiDataFixture Magento/Catalog/_files/products_upsell.php - */ - public function testQueryUpSellProducts() - { - $productSku = 'simple_with_upsell'; - - $query = <<graphQlQuery($query); - - $this->assertArrayHasKey('products', $response); - $this->assertArrayHasKey('items', $response['products']); - $this->assertEquals(1, count($response['products']['items'])); - $this->assertArrayHasKey(0, $response['products']['items']); - $this->assertArrayHasKey('upsell_products', $response['products']['items'][0]); - $upSellProducts = $response['products']['items'][0]['upsell_products']; - $this->assertCount(1, $upSellProducts); - $upSellProduct = $upSellProducts[0]; - $this->assertArrayHasKey('sku', $upSellProduct); - $this->assertArrayHasKey('name', $upSellProduct); - $this->assertArrayHasKey('url_key', $upSellProduct); - $this->assertArrayHasKey('id', $upSellProduct); - $this->assertArrayHasKey('created_at', $upSellProduct); - $this->assertEquals($upSellProduct['sku'], 'simple'); - $this->assertEquals($upSellProduct['name'], 'Simple Up Sell'); - $this->assertEquals($upSellProduct['url_key'], 'simple-up-sell'); - $this->assertNotEmpty($upSellProduct['created_at']); - $this->assertNotEmpty($upSellProduct['id']); - } - - /** - * @param array $relatedProducts - */ - private function assertRelatedProducts(array $relatedProducts): void - { - $expectedData = [ - 'simple' => [ - 'name' => 'Simple Related Product', - 'url_key' => 'simple-related-product', - - ], - 'simple_with_cross_two' => [ - 'name' => 'Simple Product With Related Product Two', - 'url_key' => 'simple-product-with-related-product-two', - ] - ]; - - foreach ($relatedProducts as $product) { - $this->assertArrayHasKey('sku', $product); - $this->assertArrayHasKey('name', $product); - $this->assertArrayHasKey('url_key', $product); - $this->assertArrayHasKey('id', $product); - $this->assertArrayHasKey('created_at', $product); - - $this->assertArrayHasKey($product['sku'], $expectedData); - $productExpectedData = $expectedData[$product['sku']]; - - $this->assertEquals($product['name'], $productExpectedData['name']); - $this->assertEquals($product['url_key'], $productExpectedData['url_key']); - $this->assertNotEmpty($product['created_at']); - $this->assertNotEmpty($product['id']); - } - } -} From 92d6feb32078960f3dce422482c351629bb87cf2 Mon Sep 17 00:00:00 2001 From: Valerii Naida Date: Wed, 8 May 2019 12:29:40 -0500 Subject: [PATCH 38/42] GraphQl-198: Products: access to related/up-sell/cross-sell product fields --- .../CatalogGraphQl/Model/Resolver/Product.php | 14 +------------- .../DataProvider/RelatedProductDataProvider.php | 9 +++++---- app/code/Magento/RelatedProductGraphQl/README.md | 3 +++ .../RelatedProduct/GetRelatedProductsTest.php | 9 --------- 4 files changed, 9 insertions(+), 26 deletions(-) create mode 100644 app/code/Magento/RelatedProductGraphQl/README.md diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product.php index b3283883f5561..86137990cc57d 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product.php @@ -9,10 +9,8 @@ use Magento\CatalogGraphQl\Model\Resolver\Product\ProductFieldsSelector; use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Deferred\Product as ProductDataProvider; -use Magento\Framework\App\ObjectManager; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Exception\GraphQlInputException; -use Magento\Framework\GraphQl\Query\FieldTranslator; use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; @@ -32,12 +30,6 @@ class Product implements ResolverInterface */ private $valueFactory; - /** - * @deprecated - * @var FieldTranslator - */ - private $fieldTranslator; - /** * @var ProductFieldsSelector */ @@ -46,20 +38,16 @@ class Product implements ResolverInterface /** * @param ProductDataProvider $productDataProvider * @param ValueFactory $valueFactory - * @param FieldTranslator $fieldTranslator * @param ProductFieldsSelector $productFieldsSelector */ public function __construct( ProductDataProvider $productDataProvider, ValueFactory $valueFactory, - FieldTranslator $fieldTranslator, ProductFieldsSelector $productFieldsSelector ) { $this->productDataProvider = $productDataProvider; $this->valueFactory = $valueFactory; - $this->fieldTranslator = $fieldTranslator; - $this->productFieldsSelector = $productFieldsSelector - ?? ObjectManager::getInstance()->get(ProductFieldsSelector::class); + $this->productFieldsSelector = $productFieldsSelector; } /** diff --git a/app/code/Magento/RelatedProductGraphQl/Model/DataProvider/RelatedProductDataProvider.php b/app/code/Magento/RelatedProductGraphQl/Model/DataProvider/RelatedProductDataProvider.php index 04a71da0337de..173c0a94312ee 100644 --- a/app/code/Magento/RelatedProductGraphQl/Model/DataProvider/RelatedProductDataProvider.php +++ b/app/code/Magento/RelatedProductGraphQl/Model/DataProvider/RelatedProductDataProvider.php @@ -42,12 +42,13 @@ public function getData(Product $product, array $fields, int $linkType): array { $relatedProducts = $this->getRelatedProducts($product, $fields, $linkType); - $data = []; + $productsData = []; foreach ($relatedProducts as $relatedProduct) { - $relatedProductData = $relatedProduct->getData(); - $relatedProductData['model'] = $relatedProduct; + $productData = $relatedProduct->getData(); + $productData['model'] = $relatedProduct; + $productsData[] = $productData; } - return $data; + return $productsData; } /** diff --git a/app/code/Magento/RelatedProductGraphQl/README.md b/app/code/Magento/RelatedProductGraphQl/README.md new file mode 100644 index 0000000000000..5b57af5af9884 --- /dev/null +++ b/app/code/Magento/RelatedProductGraphQl/README.md @@ -0,0 +1,3 @@ +# RelatedProductGraphQl + +**RelatedProductGraphQl** provides endpoints for getting Cross Sell / Related/ Up Sell products data. \ No newline at end of file diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/RelatedProduct/GetRelatedProductsTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/RelatedProduct/GetRelatedProductsTest.php index 3c0b578d850b9..dff1301e12f11 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/RelatedProduct/GetRelatedProductsTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/RelatedProduct/GetRelatedProductsTest.php @@ -31,7 +31,6 @@ public function testQueryRelatedProducts() sku name url_key - id created_at } } @@ -67,7 +66,6 @@ public function testQueryCrossSellProducts() sku name url_key - id created_at } } @@ -87,13 +85,11 @@ public function testQueryCrossSellProducts() self::assertArrayHasKey('sku', $crossSellProduct); self::assertArrayHasKey('name', $crossSellProduct); self::assertArrayHasKey('url_key', $crossSellProduct); - self::assertArrayHasKey('id', $crossSellProduct); self::assertArrayHasKey('created_at', $crossSellProduct); self::assertEquals($crossSellProduct['sku'], 'simple'); self::assertEquals($crossSellProduct['name'], 'Simple Cross Sell'); self::assertEquals($crossSellProduct['url_key'], 'simple-cross-sell'); self::assertNotEmpty($crossSellProduct['created_at']); - self::assertNotEmpty($crossSellProduct['id']); } /** @@ -113,7 +109,6 @@ public function testQueryUpSellProducts() sku name url_key - id created_at } } @@ -133,13 +128,11 @@ public function testQueryUpSellProducts() self::assertArrayHasKey('sku', $upSellProduct); self::assertArrayHasKey('name', $upSellProduct); self::assertArrayHasKey('url_key', $upSellProduct); - self::assertArrayHasKey('id', $upSellProduct); self::assertArrayHasKey('created_at', $upSellProduct); self::assertEquals($upSellProduct['sku'], 'simple'); self::assertEquals($upSellProduct['name'], 'Simple Up Sell'); self::assertEquals($upSellProduct['url_key'], 'simple-up-sell'); self::assertNotEmpty($upSellProduct['created_at']); - self::assertNotEmpty($upSellProduct['id']); } /** @@ -163,7 +156,6 @@ private function assertRelatedProducts(array $relatedProducts): void self::assertArrayHasKey('sku', $product); self::assertArrayHasKey('name', $product); self::assertArrayHasKey('url_key', $product); - self::assertArrayHasKey('id', $product); self::assertArrayHasKey('created_at', $product); self::assertArrayHasKey($product['sku'], $expectedData); @@ -172,7 +164,6 @@ private function assertRelatedProducts(array $relatedProducts): void self::assertEquals($product['name'], $productExpectedData['name']); self::assertEquals($product['url_key'], $productExpectedData['url_key']); self::assertNotEmpty($product['created_at']); - self::assertNotEmpty($product['id']); } } } From 787d31b2f9d7eba3de123c5bcb799f8ff016b9d0 Mon Sep 17 00:00:00 2001 From: Valerii Naida Date: Wed, 8 May 2019 13:16:42 -0500 Subject: [PATCH 39/42] GraphQl-387: Test coverage of getting IDs of CMS page/blocks by GraphQL API --- .../Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php | 2 ++ app/code/Magento/CmsGraphQl/Model/Resolver/Page.php | 2 +- .../testsuite/Magento/GraphQl/Cms/CmsBlockTest.php | 3 +++ .../testsuite/Magento/GraphQl/Cms/CmsPageTest.php | 3 +++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php index 8b9766ca311c7..40825e70a994e 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php @@ -88,6 +88,8 @@ public function getDataByPageIdentifier(string $pageIdentifier): array } /** + * Convert page data + * * @param PageInterface $page * @return array * @throws NoSuchEntityException diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/Page.php b/app/code/Magento/CmsGraphQl/Model/Resolver/Page.php index fbd8e26030952..64891cfeaa87a 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/Page.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/Page.php @@ -45,7 +45,7 @@ public function resolve( array $value = null, array $args = null ) { - if (!isset($args['id'], $args['identifier'])) { + if (!isset($args['id']) && !isset($args['identifier'])) { throw new GraphQlInputException(__('"Page id/identifier should be specified')); } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsBlockTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsBlockTest.php index 542b00d434db0..d598a463a48a7 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsBlockTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsBlockTest.php @@ -13,6 +13,9 @@ use Magento\TestFramework\TestCase\GraphQlAbstract; use Magento\Widget\Model\Template\FilterEmulate; +/** + * Get CMS Block test + */ class CmsBlockTest extends GraphQlAbstract { /** diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsPageTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsPageTest.php index 53e47185c9866..afbb3d40bc921 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsPageTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsPageTest.php @@ -11,6 +11,9 @@ use Magento\TestFramework\ObjectManager; use Magento\TestFramework\TestCase\GraphQlAbstract; +/** + * Get CMS Page test + */ class CmsPageTest extends GraphQlAbstract { /** From dcbf99bcc8c53879049ccdd4e03d957838ac68ac Mon Sep 17 00:00:00 2001 From: Valerii Naida Date: Wed, 8 May 2019 15:28:26 -0500 Subject: [PATCH 40/42] GraphQl-198: Products: access to related/up-sell/cross-sell product fields -- Update composer.lock --- composer.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.lock b/composer.lock index 77783c00dd641..4e052c61fd460 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "24c95683a202b83c7f182921c0c88328", + "content-hash": "33e7703ac47e1c27235b830825e14800", "packages": [ { "name": "braintree/braintree_php", @@ -6775,12 +6775,12 @@ "version": "v1.6.5", "source": { "type": "git", - "url": "https://github.com/mikey179/vfsStream.git", + "url": "https://github.com/bovigo/vfsStream.git", "reference": "d5fec95f541d4d71c4823bb5e30cf9b9e5b96145" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mikey179/vfsStream/zipball/d5fec95f541d4d71c4823bb5e30cf9b9e5b96145", + "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/d5fec95f541d4d71c4823bb5e30cf9b9e5b96145", "reference": "d5fec95f541d4d71c4823bb5e30cf9b9e5b96145", "shasum": "" }, From 06f04270b8c82c77e31faced16026ae52fe94dd6 Mon Sep 17 00:00:00 2001 From: Valerii Naida Date: Wed, 8 May 2019 15:39:55 -0500 Subject: [PATCH 41/42] GraphQl-689: testBundleProductWithNotVisibleChildren fix misspelling --- .../testsuite/Magento/GraphQl/Bundle/BundleProductViewTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Bundle/BundleProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Bundle/BundleProductViewTest.php index 20d097906d7e7..d5d34e48d77c3 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Bundle/BundleProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Bundle/BundleProductViewTest.php @@ -15,6 +15,9 @@ use Magento\TestFramework\ObjectManager; use Magento\TestFramework\TestCase\GraphQlAbstract; +/** + * Bundle product view test + */ class BundleProductViewTest extends GraphQlAbstract { const KEY_PRICE_TYPE_FIXED = 'FIXED'; From b0919e8422680d8893c66c8cd6025bc00083cb76 Mon Sep 17 00:00:00 2001 From: Valerii Naida Date: Wed, 8 May 2019 17:47:17 -0500 Subject: [PATCH 42/42] GraphQl-198: Products: access to related/up-sell/cross-sell product fields -- Update composer.lock --- .../CatalogUrlRewrite/_files/product_with_category_rollback.php | 1 - 1 file changed, 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_with_category_rollback.php b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_with_category_rollback.php index 3a1e379213342..61e2d84513f15 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_with_category_rollback.php +++ b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_with_category_rollback.php @@ -21,7 +21,6 @@ /** @var ProductRepositoryInterface $productRepository */ $productRepository = $objectManager->get(ProductRepositoryInterface::class); -//$productRepository->deleteById('p002'); $product = $productRepository->get('p002', false, null, true); $productRepository->delete($product);