From 8aedb958f43bf714c934b677c90d4b74b9d1922b Mon Sep 17 00:00:00 2001 From: vitaliyboyko Date: Sun, 16 Sep 2018 20:24:39 +0000 Subject: [PATCH 01/13] GraphQl-44: prototype of format strategy Signed-off-by: vitaliyboyko --- ...ibute.php => ProductTextareaAttribute.php} | 25 ++++++---- .../FormatFactory.php | 43 +++++++++++++++++ .../FormatInterface.php | 23 +++++++++ .../Product/ProductTextareaAttribute/Html.php | 47 +++++++++++++++++++ .../CatalogGraphQl/etc/schema.graphqls | 41 +++++++++------- 5 files changed, 152 insertions(+), 27 deletions(-) rename app/code/Magento/CatalogGraphQl/Model/Resolver/Product/{ProductHtmlAttribute.php => ProductTextareaAttribute.php} (67%) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/FormatFactory.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/FormatInterface.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/Html.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductHtmlAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute.php similarity index 67% rename from app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductHtmlAttribute.php rename to app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute.php index 18d15088e6656..f04609f91c86d 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductHtmlAttribute.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute.php @@ -8,38 +8,40 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; use Magento\Catalog\Model\Product; +use Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute\FormatFactory; use Magento\Framework\GraphQl\Config\Element\Field; 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; -use Magento\Catalog\Helper\Output as OutputHelper; /** * Resolve rendered content for attributes where HTML content is allowed */ -class ProductHtmlAttribute implements ResolverInterface +class ProductTextareaAttribute implements ResolverInterface { + const DEFAULT_CONTENT_FORMAT_IDENTIFIER = 'html'; + /** * @var ValueFactory */ private $valueFactory; /** - * @var OutputHelper + * @var FormatFactory */ - private $outputHelper; + private $formatFactory; /** * @param ValueFactory $valueFactory - * @param OutputHelper $outputHelper + * @param FormatFactory $formatFactory */ public function __construct( ValueFactory $valueFactory, - OutputHelper $outputHelper + FormatFactory $formatFactory ) { $this->valueFactory = $valueFactory; - $this->outputHelper = $outputHelper; + $this->formatFactory = $formatFactory; } /** @@ -62,9 +64,12 @@ public function resolve( /* @var $product Product */ $product = $value['model']; $fieldName = $field->getName(); - $renderedValue = $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); - $result = function () use ($renderedValue) { - return $renderedValue; + $formatIdentifier = $args['format'] ?? self::DEFAULT_CONTENT_FORMAT_IDENTIFIER; + $format = $this->formatFactory->create($formatIdentifier); + $attribute = ['content' => $format->getContent($product, $fieldName)]; + + $result = function () use ($attribute) { + return $attribute; }; return $this->valueFactory->create($result); diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/FormatFactory.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/FormatFactory.php new file mode 100644 index 0000000000000..2aab2d5816083 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/FormatFactory.php @@ -0,0 +1,43 @@ +objectManager = $objectManager; + } + + /** + * @param string $formatIdentifier + * @param array $data + * @return FormatInterface + */ + public function create(string $formatIdentifier, $data = []) : FormatInterface + { + $formatClassName = 'Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute\\' . ucfirst($formatIdentifier); + $formatInstance = $this->objectManager->create($formatClassName, $data); + if (false == $formatInstance instanceof FormatInterface) { + throw new \InvalidArgumentException( + $formatInstance . ' is not instance of \Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute\FormatInterface' + ); + } + return $formatInstance; + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/FormatInterface.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/FormatInterface.php new file mode 100644 index 0000000000000..fae685b75c060 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/FormatInterface.php @@ -0,0 +1,23 @@ +valueFactory = $valueFactory; + $this->outputHelper = $outputHelper; + } + + /** + * @inheritdoc + */ + public function getContent( + ModelProduct $product, + string $fieldName + ): string { + return $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); + } +} \ 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 f63c1a96762c2..82bc262ecf3c3 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -3,16 +3,16 @@ type Query { products ( - search: String @doc(description: "Performs a full-text search using the specified key words."), - filter: ProductFilterInput @doc(description: "Identifies which product attributes to search for and return."), - pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), - currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), - sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") - ): Products - @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes") + search: String @doc(description: "Performs a full-text search using the specified key words."), + filter: ProductFilterInput @doc(description: "Identifies which product attributes to search for and return."), + pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), + currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), + sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") +): Products + @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes") category ( - id: Int @doc(description: "Id of the category") - ): CategoryTree + id: Int @doc(description: "Id of the category") +): CategoryTree @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryTree") } @@ -248,8 +248,8 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ id: Int @doc(description: "The ID number assigned to the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\EntityIdToId") name: String @doc(description: "The product name. Customers use this name to identify the product.") sku: String @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: String @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductHtmlAttribute") - short_description: String @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductHtmlAttribute") + description: ProductTextareaAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") + short_description: ProductTextareaAttribute @doc(description: "A short description of the product. Its use depends on the theme.") special_price: Float @doc(description: "The discounted price of the product") special_from_date: String @doc(description: "The beginning date that a product has a special price") special_to_date: String @doc(description: "The end date that a product has a special price") @@ -377,10 +377,10 @@ interface CategoryInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model product_count: Int @doc(description: "The number of products in the category") default_sort_by: String @doc(description: "The attribute to use for sorting") products( - pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), - currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), - sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") - ): CategoryProducts @doc(description: "The list of products assigned to the category") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Products") + pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), + currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), + sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") +): CategoryProducts @doc(description: "The list of products assigned to the category") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Products") breadcrumbs: [Breadcrumb] @doc(description: "Breadcrumbs, parent categories info") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Breadcrumbs") } @@ -408,8 +408,8 @@ type VirtualProduct implements ProductInterface, CustomizableProductInterface @d } type SimpleProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface @doc(description: "A simple product is tangible and are usually sold as single units or in fixed quantities") -{ -} + { + } type Products @doc(description: "The Products object is the top-level object returned in a product search") { items: [ProductInterface] @doc(description: "An array of products that match the specified search criteria") @@ -551,3 +551,10 @@ 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 ProductTextareaAttribute { + content ( + format: String! @doc(description: "The format of content") +): String + @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextareaAttribute") +} From cde04fc296154d8ade7c390b3eb3def76dcc4c02 Mon Sep 17 00:00:00 2001 From: vitaliyboyko Date: Sun, 16 Sep 2018 20:38:50 +0000 Subject: [PATCH 02/13] GraphQl-45: pretified schema Signed-off-by: vitaliyboyko --- .../CatalogGraphQl/etc/schema.graphqls | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 82bc262ecf3c3..a9c4a1b4bd8ae 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -3,16 +3,16 @@ type Query { products ( - search: String @doc(description: "Performs a full-text search using the specified key words."), - filter: ProductFilterInput @doc(description: "Identifies which product attributes to search for and return."), - pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), - currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), - sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") -): Products - @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes") + search: String @doc(description: "Performs a full-text search using the specified key words."), + filter: ProductFilterInput @doc(description: "Identifies which product attributes to search for and return."), + pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), + currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), + sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") + ): Products + @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes") category ( - id: Int @doc(description: "Id of the category") -): CategoryTree + id: Int @doc(description: "Id of the category") + ): CategoryTree @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryTree") } @@ -377,10 +377,10 @@ interface CategoryInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model product_count: Int @doc(description: "The number of products in the category") default_sort_by: String @doc(description: "The attribute to use for sorting") products( - pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), - currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), - sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") -): CategoryProducts @doc(description: "The list of products assigned to the category") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Products") + pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), + currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), + sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") + ): CategoryProducts @doc(description: "The list of products assigned to the category") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Products") breadcrumbs: [Breadcrumb] @doc(description: "Breadcrumbs, parent categories info") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Breadcrumbs") } @@ -408,8 +408,8 @@ type VirtualProduct implements ProductInterface, CustomizableProductInterface @d } type SimpleProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface @doc(description: "A simple product is tangible and are usually sold as single units or in fixed quantities") - { - } +{ +} type Products @doc(description: "The Products object is the top-level object returned in a product search") { items: [ProductInterface] @doc(description: "An array of products that match the specified search criteria") From 79a968ba6bbb54ce8c3e5714bba164f924fc74f3 Mon Sep 17 00:00:00 2001 From: vitaliyboyko Date: Sat, 22 Sep 2018 10:28:58 +0000 Subject: [PATCH 03/13] graphQl-44: refactoring of format strategy Signed-off-by: vitaliyboyko --- .../Resolver/Product/ProductTextAttribute.php | 33 +++++++++---------- .../ProductTextAttribute/FormatInterface.php | 2 +- .../ProductTextAttribute/FormatList.php | 28 +++++++++------- .../Product/ProductTextAttribute/Html.php | 2 +- .../Magento/CatalogGraphQl/etc/graphql/di.xml | 7 ++++ .../CatalogGraphQl/etc/schema.graphqls | 12 +++---- 6 files changed, 46 insertions(+), 38 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php index f04609f91c86d..9c1212667acf3 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php @@ -8,7 +8,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; use Magento\Catalog\Model\Product; -use Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute\FormatFactory; +use Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute\FormatList; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\Resolver\Value; use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; @@ -18,9 +18,12 @@ /** * Resolve rendered content for attributes where HTML content is allowed */ -class ProductTextareaAttribute implements ResolverInterface +class ProductTextAttribute implements ResolverInterface { - const DEFAULT_CONTENT_FORMAT_IDENTIFIER = 'html'; + /** + * @var FormatList + */ + private $formatList; /** * @var ValueFactory @@ -28,20 +31,20 @@ class ProductTextareaAttribute implements ResolverInterface private $valueFactory; /** - * @var FormatFactory + * @var string */ - private $formatFactory; + private $defaultFormat = 'html'; /** * @param ValueFactory $valueFactory - * @param FormatFactory $formatFactory + * @param FormatList $formatFactory */ public function __construct( ValueFactory $valueFactory, - FormatFactory $formatFactory + FormatList $formatFactory ) { $this->valueFactory = $valueFactory; - $this->formatFactory = $formatFactory; + $this->formatList = $formatFactory; } /** @@ -55,22 +58,16 @@ public function resolve( array $args = null ): Value { if (!isset($value['model'])) { - $result = function () { - return null; - }; + $result = []; return $this->valueFactory->create($result); } /* @var $product Product */ $product = $value['model']; $fieldName = $field->getName(); - $formatIdentifier = $args['format'] ?? self::DEFAULT_CONTENT_FORMAT_IDENTIFIER; - $format = $this->formatFactory->create($formatIdentifier); - $attribute = ['content' => $format->getContent($product, $fieldName)]; - - $result = function () use ($attribute) { - return $attribute; - }; + $formatIdentifier = $args['format'] ?? $this->defaultFormat; + $format = $this->formatList->create($formatIdentifier); + $result = ['content' => $format->getContent($product, $fieldName)]; return $this->valueFactory->create($result); } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatInterface.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatInterface.php index fae685b75c060..2cf702bf18466 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatInterface.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatInterface.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute; +namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute; use Magento\Catalog\Model\Product as ModelProduct; diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php index 97e0be3763f1d..2e2f21d643092 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php @@ -9,35 +9,39 @@ use Magento\Framework\ObjectManagerInterface; -class FormatFactory +class FormatList { /** * @var ObjectManagerInterface */ private $objectManager; + /** + * @var string + */ + private $formats; + /** * @param ObjectManagerInterface $objectManager + * @param array $formats */ - public function __construct(ObjectManagerInterface $objectManager) - { + public function __construct( + ObjectManagerInterface $objectManager, + array $formats + ) { $this->objectManager = $objectManager; + $this->formats = $formats; } /** * @param string $formatIdentifier - * @param array $data * @return FormatInterface */ - public function create(string $formatIdentifier, $data = []) : FormatInterface + public function create(string $formatIdentifier) : FormatInterface { - $formatClassName = 'Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute\\' . ucfirst($formatIdentifier); - $formatInstance = $this->objectManager->create($formatClassName, $data); - if (false == $formatInstance instanceof FormatInterface) { - throw new \InvalidArgumentException( - $formatInstance . ' is not instance of \Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute\FormatInterface' - ); - } + $formatClassName = 'Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute\\' . ucfirst($formatIdentifier); + $formatInstance = $this->objectManager->get($formatClassName); + return $formatInstance; } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php index 8201c40427dc9..75c29a3f78fac 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute; +namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute; use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; use Magento\Catalog\Helper\Output as OutputHelper; diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml index 68a292ede6b4a..8d4ca97001d3d 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml @@ -63,6 +63,13 @@ Magento\Catalog\Model\Api\SearchCriteria\ProductCollectionProcessor + + + + Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute\Html + + + diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index a9c4a1b4bd8ae..3f3282ed5f529 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -248,8 +248,8 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ id: Int @doc(description: "The ID number assigned to the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\EntityIdToId") name: String @doc(description: "The product name. Customers use this name to identify the product.") sku: String @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: ProductTextareaAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") - short_description: ProductTextareaAttribute @doc(description: "A short description of the product. Its use depends on the theme.") + description: ProductTextAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") + short_description: ProductTextAttribute @doc(description: "A short description of the product. Its use depends on the theme.") special_price: Float @doc(description: "The discounted price of the product") special_from_date: String @doc(description: "The beginning date that a product has a special price") special_to_date: String @doc(description: "The end date that a product has a special price") @@ -552,9 +552,9 @@ type SortFields @doc(description: "SortFields contains a default value for sort options: [SortField] @doc(description: "Available sort fields") } -type ProductTextareaAttribute { +type ProductTextAttribute { content ( - format: String! @doc(description: "The format of content") -): String - @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextareaAttribute") + format: String @doc(description: "The format of content") +): String @doc(description: "The format of content") + @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") } From 476f14ff89d6be14d1b3d8c950713c00d5802ec0 Mon Sep 17 00:00:00 2001 From: vitaliyboyko Date: Wed, 26 Sep 2018 16:35:20 +0000 Subject: [PATCH 04/13] graphQl-44: refactoring of resolver Signed-off-by: vitaliyboyko --- .../Resolver/Product/ProductTextAttribute.php | 24 ++++++------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php index 9c1212667acf3..7649464e2e1ca 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php @@ -10,8 +10,7 @@ use Magento\Catalog\Model\Product; use Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute\FormatList; use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Query\Resolver\Value; -use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; @@ -25,26 +24,18 @@ class ProductTextAttribute implements ResolverInterface */ private $formatList; - /** - * @var ValueFactory - */ - private $valueFactory; - /** * @var string */ private $defaultFormat = 'html'; /** - * @param ValueFactory $valueFactory - * @param FormatList $formatFactory + * @param FormatList $formatList */ public function __construct( - ValueFactory $valueFactory, - FormatList $formatFactory + FormatList $formatList ) { - $this->valueFactory = $valueFactory; - $this->formatList = $formatFactory; + $this->formatList = $formatList; } /** @@ -56,10 +47,9 @@ public function resolve( ResolveInfo $info, array $value = null, array $args = null - ): Value { + ) { if (!isset($value['model'])) { - $result = []; - return $this->valueFactory->create($result); + throw new GraphQlInputException(__('"model" value should be specified')); } /* @var $product Product */ @@ -69,6 +59,6 @@ public function resolve( $format = $this->formatList->create($formatIdentifier); $result = ['content' => $format->getContent($product, $fieldName)]; - return $this->valueFactory->create($result); + return $result; } } From 80669e3c52cd94ce60f5ee2e31eda78584bba97e Mon Sep 17 00:00:00 2001 From: vitaliyboyko Date: Sat, 20 Oct 2018 18:31:29 +0300 Subject: [PATCH 05/13] graphQl-44: added ProductTextAttributeInput --- .../Resolver/Product/ProductTextAttribute.php | 6 ++-- .../ProductTextAttribute/FormatList.php | 13 +++++-- .../Product/ProductTextAttribute/Html.php | 2 +- .../CatalogGraphQl/etc/schema.graphqls | 34 ++++++++++++++----- 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php index 7649464e2e1ca..2ff6faa0a74ee 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php @@ -39,7 +39,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function resolve( Field $field, @@ -55,8 +55,8 @@ public function resolve( /* @var $product Product */ $product = $value['model']; $fieldName = $field->getName(); - $formatIdentifier = $args['format'] ?? $this->defaultFormat; - $format = $this->formatList->create($formatIdentifier); + $formatIdentifier = $args['filter']['description']['format'] ?? $this->defaultFormat; + $format = $this->formatList->getFormatByIdentifier($formatIdentifier); $result = ['content' => $format->getContent($product, $fieldName)]; return $result; diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php index 2e2f21d643092..39f2074ed7592 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php @@ -7,8 +7,13 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\ObjectManagerInterface; +/** + * Class FormatList + * @package Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute + */ class FormatList { /** @@ -37,10 +42,12 @@ public function __construct( * @param string $formatIdentifier * @return FormatInterface */ - public function create(string $formatIdentifier) : FormatInterface + public function getFormatByIdentifier(string $formatIdentifier) : FormatInterface { - $formatClassName = 'Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute\\' . ucfirst($formatIdentifier); - $formatInstance = $this->objectManager->get($formatClassName); + if (!isset($this->formats[$formatIdentifier])) { + throw new GraphQlInputException(__('Format %1 does not exist.', [$formatIdentifier])); + } + $formatInstance = $this->objectManager->get($this->formats[$formatIdentifier]); return $formatInstance; } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php index 75c29a3f78fac..830fbf28e3373 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php @@ -44,4 +44,4 @@ public function getContent( ): string { return $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); } -} \ 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 944cae6537bb0..a7d9ab5483d46 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -248,8 +248,8 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ id: Int @doc(description: "The ID number assigned to the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\EntityIdToId") name: String @doc(description: "The product name. Customers use this name to identify the product.") sku: String @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: ProductTextAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") - short_description: ProductTextAttribute @doc(description: "A short description of the product. Its use depends on the theme.") + description: ProductTextAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") + short_description: ProductTextAttribute @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") special_price: Float @doc(description: "The discounted price of the product") special_from_date: String @doc(description: "The beginning date that a product has a special price") special_to_date: String @doc(description: "The end date that a product has a special price") @@ -433,8 +433,8 @@ type CategoryProducts @doc(description: "The category products object returned i input ProductFilterInput @doc(description: "ProductFilterInput defines the filters to be used in the search. A filter contains at least one attribute, a comparison operator, and the value that is being searched for.") { name: FilterTypeInput @doc(description: "The product name. Customers use this name to identify the product.") sku: FilterTypeInput @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: FilterTypeInput @doc(description: "Detailed information about the product. The value can include simple HTML tags.") - short_description: FilterTypeInput @doc(description: "A short description of the product. Its use depends on the theme.") + description: ProductTextAttributeTypeInput @doc(description: "Detailed information about the product. The value can include simple HTML tags.") + short_description: ProductTextAttributeTypeInput @doc(description: "A short description of the product. Its use depends on the theme.") price: FilterTypeInput @doc(description: "The price of an item") special_price: FilterTypeInput @doc(description: "The discounted price of the product") special_from_date: FilterTypeInput @doc(description: "The beginning date that a product has a special price") @@ -557,9 +557,25 @@ type SortFields @doc(description: "SortFields contains a default value for sort options: [SortField] @doc(description: "Available sort fields") } -type ProductTextAttribute { - content ( - format: String @doc(description: "The format of content") -): String @doc(description: "The format of content") - @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") +type ProductTextAttribute @doc(description: "Product text attribute.") { + content: String +} + +input ProductTextAttributeTypeInput @doc(description: "FilterTypeInput specifies which action will be performed in a query ") { + format: String @doc(description: "Format of the content") + eq: String @doc(description: "Equals") + finset: [String] @doc(description: "Find in set. The value can contain a set of comma-separated values") + from: String @doc(description: "From. Must be used with 'to'") + gt: String @doc(description: "Greater than") + gteq: String @doc(description: "Greater than or equal to") + in: [String] @doc(description: "In. The value can contain a set of comma-separated values") + like: String @doc(description: "Like. The specified value can contain % (percent signs) to allow matching of 0 or more characters") + lt: String @doc(description: "Less than") + lteq: String @doc(description: "Less than or equal to") + moreq: String @doc(description: "More than or equal to") + neq: String @doc(description: "Not equal to") + notnull: String @doc(description: "Not null") + null: String @doc(description: "Is null") + to: String@doc(description: "To. Must be used with 'from'") + nin: [String] @doc(description: "Not in. The value can contain a set of comma-separated values") } From a18a08792acf1d251c491894d0889783d3b73c02 Mon Sep 17 00:00:00 2001 From: vitaliyboyko Date: Tue, 23 Oct 2018 22:48:01 +0300 Subject: [PATCH 06/13] graphQl-44: added html content resolver --- .../Resolver/Product/ProductTextAttribute.php | 64 ------------------- .../ProductTextAttribute/FormatInterface.php | 23 ------- .../ProductTextAttribute/FormatList.php | 54 ---------------- .../Product/ProductTextAttribute/Html.php | 47 -------------- .../ProductTextAttribute/HtmlContent.php | 56 ++++++++++++++++ .../CatalogGraphQl/etc/schema.graphqls | 29 ++------- 6 files changed, 61 insertions(+), 212 deletions(-) delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatInterface.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php deleted file mode 100644 index 2ff6faa0a74ee..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php +++ /dev/null @@ -1,64 +0,0 @@ -formatList = $formatList; - } - - /** - * @inheritdoc - */ - public function resolve( - Field $field, - $context, - ResolveInfo $info, - array $value = null, - array $args = null - ) { - if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); - } - - /* @var $product Product */ - $product = $value['model']; - $fieldName = $field->getName(); - $formatIdentifier = $args['filter']['description']['format'] ?? $this->defaultFormat; - $format = $this->formatList->getFormatByIdentifier($formatIdentifier); - $result = ['content' => $format->getContent($product, $fieldName)]; - - return $result; - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatInterface.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatInterface.php deleted file mode 100644 index 2cf702bf18466..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatInterface.php +++ /dev/null @@ -1,23 +0,0 @@ -objectManager = $objectManager; - $this->formats = $formats; - } - - /** - * @param string $formatIdentifier - * @return FormatInterface - */ - public function getFormatByIdentifier(string $formatIdentifier) : FormatInterface - { - if (!isset($this->formats[$formatIdentifier])) { - throw new GraphQlInputException(__('Format %1 does not exist.', [$formatIdentifier])); - } - $formatInstance = $this->objectManager->get($this->formats[$formatIdentifier]); - - return $formatInstance; - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php deleted file mode 100644 index 830fbf28e3373..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php +++ /dev/null @@ -1,47 +0,0 @@ -valueFactory = $valueFactory; - $this->outputHelper = $outputHelper; - } - - /** - * @inheritdoc - */ - public function getContent( - ModelProduct $product, - string $fieldName - ): string { - return $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php new file mode 100644 index 0000000000000..c0b67889ecd74 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php @@ -0,0 +1,56 @@ +outputHelper = $outputHelper; + } + + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ): array { + if (!isset($value['model'])) { + return []; + } + + /* @var $product Product */ + $product = $value['model']; + $fieldName = $field->getName(); + $renderedValue = $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); + + return $renderedValue; + } +} diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index a7d9ab5483d46..3ffdc85a40d68 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -248,8 +248,8 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ id: Int @doc(description: "The ID number assigned to the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\EntityIdToId") name: String @doc(description: "The product name. Customers use this name to identify the product.") sku: String @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: ProductTextAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") - short_description: ProductTextAttribute @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") + description: ProductTextAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") + short_description: ProductTextAttribute @doc(description: "A short description of the product. Its use depends on the theme.") special_price: Float @doc(description: "The discounted price of the product") special_from_date: String @doc(description: "The beginning date that a product has a special price") special_to_date: String @doc(description: "The end date that a product has a special price") @@ -433,8 +433,8 @@ type CategoryProducts @doc(description: "The category products object returned i input ProductFilterInput @doc(description: "ProductFilterInput defines the filters to be used in the search. A filter contains at least one attribute, a comparison operator, and the value that is being searched for.") { name: FilterTypeInput @doc(description: "The product name. Customers use this name to identify the product.") sku: FilterTypeInput @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: ProductTextAttributeTypeInput @doc(description: "Detailed information about the product. The value can include simple HTML tags.") - short_description: ProductTextAttributeTypeInput @doc(description: "A short description of the product. Its use depends on the theme.") + description: FilterTypeInput @doc(description: "Detailed information about the product. The value can include simple HTML tags.") + short_description: FilterTypeInput @doc(description: "A short description of the product. Its use depends on the theme.") price: FilterTypeInput @doc(description: "The price of an item") special_price: FilterTypeInput @doc(description: "The discounted price of the product") special_from_date: FilterTypeInput @doc(description: "The beginning date that a product has a special price") @@ -558,24 +558,5 @@ type SortFields @doc(description: "SortFields contains a default value for sort } type ProductTextAttribute @doc(description: "Product text attribute.") { - content: String -} - -input ProductTextAttributeTypeInput @doc(description: "FilterTypeInput specifies which action will be performed in a query ") { - format: String @doc(description: "Format of the content") - eq: String @doc(description: "Equals") - finset: [String] @doc(description: "Find in set. The value can contain a set of comma-separated values") - from: String @doc(description: "From. Must be used with 'to'") - gt: String @doc(description: "Greater than") - gteq: String @doc(description: "Greater than or equal to") - in: [String] @doc(description: "In. The value can contain a set of comma-separated values") - like: String @doc(description: "Like. The specified value can contain % (percent signs) to allow matching of 0 or more characters") - lt: String @doc(description: "Less than") - lteq: String @doc(description: "Less than or equal to") - moreq: String @doc(description: "More than or equal to") - neq: String @doc(description: "Not equal to") - notnull: String @doc(description: "Not null") - null: String @doc(description: "Is null") - to: String@doc(description: "To. Must be used with 'from'") - nin: [String] @doc(description: "Not in. The value can contain a set of comma-separated values") + html: String @doc(description: "Attribute HTML content") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute\\HtmlContent") } From 0a4dc35bb14a28634a7b58e9fe12e68df7e86ea7 Mon Sep 17 00:00:00 2001 From: vitaliyboyko Date: Wed, 24 Oct 2018 14:21:40 +0300 Subject: [PATCH 07/13] graphQl-44: added ProductTextAttribute and fixed api functional test --- .../Resolver/Product/ProductTextAttribute.php | 33 +++++++++++++++++ .../ProductTextAttribute/HtmlContent.php | 10 ++++-- .../CatalogGraphQl/etc/schema.graphqls | 4 +-- .../GraphQl/Catalog/ProductViewTest.php | 36 ++++++++++++++++--- 4 files changed, 74 insertions(+), 9 deletions(-) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php new file mode 100644 index 0000000000000..171e84a65aba4 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php @@ -0,0 +1,33 @@ +getName(); + + return $value; + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php index c0b67889ecd74..724d0826dbb3d 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php @@ -9,6 +9,7 @@ use Magento\Catalog\Model\Product; use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Helper\Output as OutputHelper; @@ -41,14 +42,17 @@ public function resolve( ResolveInfo $info, array $value = null, array $args = null - ): array { + ): ?string { if (!isset($value['model'])) { - return []; + throw new GraphQlInputException(__('"model" value should be specified')); + } + if (!isset($value['field'])) { + throw new GraphQlInputException(__('"field" value should be specified')); } /* @var $product Product */ $product = $value['model']; - $fieldName = $field->getName(); + $fieldName = $value['field']; $renderedValue = $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); return $renderedValue; diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 3ffdc85a40d68..ad724c18a5c9a 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -248,8 +248,8 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ id: Int @doc(description: "The ID number assigned to the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\EntityIdToId") name: String @doc(description: "The product name. Customers use this name to identify the product.") sku: String @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: ProductTextAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") - short_description: ProductTextAttribute @doc(description: "A short description of the product. Its use depends on the theme.") + description: ProductTextAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") + short_description: ProductTextAttribute @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") special_price: Float @doc(description: "The discounted price of the product") special_from_date: String @doc(description: "The beginning date that a product has a special price") special_to_date: String @doc(description: "The end date that a product has a special price") diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php index 7c2cda3a4551b..615e50f640380 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -44,7 +44,9 @@ public function testQueryAllFieldsSimpleProduct() attribute_set_id country_of_manufacture created_at - description + description { + html + } gift_message_available id categories { @@ -203,7 +205,9 @@ public function testQueryAllFieldsSimpleProduct() position sku } - short_description + short_description { + html + } sku small_image { path @@ -262,6 +266,7 @@ public function testQueryAllFieldsSimpleProduct() $this->assertArrayHasKey(0, $response['products']['items']); $this->assertBaseFields($product, $response['products']['items'][0]); $this->assertEavAttributes($product, $response['products']['items'][0]); + $this->assertTextEavAttributes($product, $response['products']['items'][0]); $this->assertOptions($product, $response['products']['items'][0]); $this->assertTierPrices($product, $response['products']['items'][0]); $this->assertArrayHasKey('websites', $response['products']['items'][0]); @@ -917,11 +922,9 @@ private function assertEavAttributes($product, $actualResponse) { $eavAttributes = [ 'url_key', - 'description', 'meta_description', 'meta_keyword', 'meta_title', - 'short_description', 'country_of_manufacture', 'gift_message_available', 'news_from_date', @@ -943,6 +946,31 @@ private function assertEavAttributes($product, $actualResponse) $this->assertResponseFields($actualResponse, $assertionMap); } + /** + * @param ProductInterface $product + * @param array $actualResponse + */ + private function assertTextEavAttributes($product, $actualResponse) + { + $eavAttributes = [ + 'description', + 'short_description', + ]; + $assertionMap = []; + foreach ($eavAttributes as $attributeCode) { + $expectedAttribute = $product->getCustomAttribute($attributeCode); + + $assertionMap[] = [ + 'response_field' => $this->eavAttributesToGraphQlSchemaFieldTranslator($attributeCode), + 'expected_value' => $expectedAttribute ? [ + 'html' => $expectedAttribute->getValue() + ] : null + ]; + } + + $this->assertResponseFields($actualResponse, $assertionMap); + } + /** * @param string $eavAttributeCode * @return string From 2fcc1830d0a3a24dce25f986c46b97d15f3c4bae Mon Sep 17 00:00:00 2001 From: vitaliyboyko Date: Wed, 24 Oct 2018 22:36:36 +0300 Subject: [PATCH 08/13] graphQl-44: added ComplexTextValue to graphQl module --- .../Resolver/Product/ProductTextAttribute.php | 30 +++++++++- .../ProductTextAttribute/HtmlContent.php | 60 ------------------- .../Magento/CatalogGraphQl/etc/graphql/di.xml | 7 --- .../CatalogGraphQl/etc/schema.graphqls | 8 +-- .../Resolver/ComplexTextValue/HtmlFormat.php | 38 ++++++++++++ app/code/Magento/GraphQl/etc/schema.graphqls | 4 ++ 6 files changed, 71 insertions(+), 76 deletions(-) delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php create mode 100644 app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php index 171e84a65aba4..febcd12f0e96f 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php @@ -10,12 +10,29 @@ use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Catalog\Model\Product; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Catalog\Helper\Output as OutputHelper; /** - * Resolve rendered content for text attributes + * Resolve rendered content for attributes where HTML content is allowed */ class ProductTextAttribute implements ResolverInterface { + /** + * @var OutputHelper + */ + private $outputHelper; + + /** + * @param OutputHelper $outputHelper + */ + public function __construct( + OutputHelper $outputHelper + ) { + $this->outputHelper = $outputHelper; + } + /** * @inheritdoc */ @@ -26,8 +43,15 @@ public function resolve( array $value = null, array $args = null ): array { - $value['field'] = $field->getName(); + if (!isset($value['model'])) { + throw new GraphQlInputException(__('"model" value should be specified')); + } + + /* @var $product Product */ + $product = $value['model']; + $fieldName = $field->getName(); + $renderedValue = $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); - return $value; + return ['html' => $renderedValue]; } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php deleted file mode 100644 index 724d0826dbb3d..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php +++ /dev/null @@ -1,60 +0,0 @@ -outputHelper = $outputHelper; - } - - /** - * @inheritdoc - */ - public function resolve( - Field $field, - $context, - ResolveInfo $info, - array $value = null, - array $args = null - ): ?string { - if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); - } - if (!isset($value['field'])) { - throw new GraphQlInputException(__('"field" value should be specified')); - } - - /* @var $product Product */ - $product = $value['model']; - $fieldName = $value['field']; - $renderedValue = $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); - - return $renderedValue; - } -} diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml index 8d4ca97001d3d..68a292ede6b4a 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml @@ -63,13 +63,6 @@ Magento\Catalog\Model\Api\SearchCriteria\ProductCollectionProcessor - - - - Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute\Html - - - diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index ad724c18a5c9a..fb7dd4ee2c8f0 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -248,8 +248,8 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ id: Int @doc(description: "The ID number assigned to the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\EntityIdToId") name: String @doc(description: "The product name. Customers use this name to identify the product.") sku: String @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: ProductTextAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") - short_description: ProductTextAttribute @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") + description: ComplexTextValue @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") + short_description: ComplexTextValue @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") special_price: Float @doc(description: "The discounted price of the product") special_from_date: String @doc(description: "The beginning date that a product has a special price") special_to_date: String @doc(description: "The end date that a product has a special price") @@ -556,7 +556,3 @@ 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 ProductTextAttribute @doc(description: "Product text attribute.") { - html: String @doc(description: "Attribute HTML content") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute\\HtmlContent") -} diff --git a/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php b/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php new file mode 100644 index 0000000000000..2ec4d24017b0e --- /dev/null +++ b/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php @@ -0,0 +1,38 @@ + Date: Wed, 24 Oct 2018 23:13:05 +0300 Subject: [PATCH 09/13] graphQl-44: refactored resolver name --- ...oductTextAttribute.php => ProductComplexTextAttribute.php} | 2 +- app/code/Magento/CatalogGraphQl/etc/schema.graphqls | 4 ++-- .../testsuite/Magento/GraphQl/Catalog/ProductViewTest.php | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename app/code/Magento/CatalogGraphQl/Model/Resolver/Product/{ProductTextAttribute.php => ProductComplexTextAttribute.php} (95%) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php similarity index 95% rename from app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php rename to app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php index febcd12f0e96f..7cf7225d0f61c 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php @@ -17,7 +17,7 @@ /** * Resolve rendered content for attributes where HTML content is allowed */ -class ProductTextAttribute implements ResolverInterface +class ProductComplexTextAttribute implements ResolverInterface { /** * @var OutputHelper diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index fb7dd4ee2c8f0..423283bdda7b0 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -248,8 +248,8 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ id: Int @doc(description: "The ID number assigned to the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\EntityIdToId") name: String @doc(description: "The product name. Customers use this name to identify the product.") sku: String @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: ComplexTextValue @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") - short_description: ComplexTextValue @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") + description: ComplexTextValue @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductComplexTextAttribute") + short_description: ComplexTextValue @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductComplexTextAttribute") special_price: Float @doc(description: "The discounted price of the product") special_from_date: String @doc(description: "The beginning date that a product has a special price") special_to_date: String @doc(description: "The end date that a product has a special price") diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php index 615e50f640380..1ab7ed5890472 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -266,7 +266,7 @@ public function testQueryAllFieldsSimpleProduct() $this->assertArrayHasKey(0, $response['products']['items']); $this->assertBaseFields($product, $response['products']['items'][0]); $this->assertEavAttributes($product, $response['products']['items'][0]); - $this->assertTextEavAttributes($product, $response['products']['items'][0]); + $this->assertComplexTextAttributes($product, $response['products']['items'][0]); $this->assertOptions($product, $response['products']['items'][0]); $this->assertTierPrices($product, $response['products']['items'][0]); $this->assertArrayHasKey('websites', $response['products']['items'][0]); @@ -950,7 +950,7 @@ private function assertEavAttributes($product, $actualResponse) * @param ProductInterface $product * @param array $actualResponse */ - private function assertTextEavAttributes($product, $actualResponse) + private function assertComplexTextAttributes($product, $actualResponse) { $eavAttributes = [ 'description', From f82912dc75d57694b056ca6a7ca198fde1e6b108 Mon Sep 17 00:00:00 2001 From: vitaliyboyko Date: Thu, 25 Oct 2018 18:34:19 +0300 Subject: [PATCH 10/13] graphQl-44: fixed copyrights --- .../GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php b/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php index 2ec4d24017b0e..fffca765faba6 100644 --- a/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php +++ b/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php @@ -1,7 +1,7 @@ Date: Tue, 6 Nov 2018 19:19:55 +0200 Subject: [PATCH 11/13] GraphQl-45: Product textarea field format --- .../Product/ProductComplexTextAttribute.php | 2 +- .../Resolver/ComplexTextValue/HtmlFormat.php | 38 ----- app/code/Magento/GraphQl/etc/schema.graphqls | 2 +- .../Magento/GraphQl/Catalog/CategoryTest.php | 8 +- .../Catalog/ProductTextAttributesTest.php | 142 ++++++++++++++++++ .../GraphQl/Catalog/ProductViewTest.php | 34 ----- .../ProductWithDescriptionDirectivesTest.php | 65 -------- 7 files changed, 150 insertions(+), 141 deletions(-) delete mode 100644 app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductTextAttributesTest.php delete mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductWithDescriptionDirectivesTest.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php index 7cf7225d0f61c..96519d6191eee 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php @@ -52,6 +52,6 @@ public function resolve( $fieldName = $field->getName(); $renderedValue = $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); - return ['html' => $renderedValue]; + return ['html' => $renderedValue ?? '']; } } diff --git a/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php b/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php deleted file mode 100644 index fffca765faba6..0000000000000 --- a/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php +++ /dev/null @@ -1,38 +0,0 @@ -productRepository = Bootstrap::getObjectManager()::getInstance()->get(ProductRepositoryInterface::class); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php + */ + public function testProductTextAttributes() + { + $productSku = 'simple'; + + $query = <<graphQlQuery($query); + + $this->assertEquals( + $productSku, + $response['products']['items'][0]['sku'] + ); + $this->assertEquals( + 'Short description', + $response['products']['items'][0]['short_description']['html'] + ); + $this->assertEquals( + 'Description with html tag', + $response['products']['items'][0]['description']['html'] + ); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_virtual.php + */ + public function testProductWithoutFilledTextAttributes() + { + $productSku = 'virtual-product'; + + $query = <<graphQlQuery($query); + + $this->assertEquals( + $productSku, + $response['products']['items'][0]['sku'] + ); + $this->assertEquals( + '', + $response['products']['items'][0]['short_description']['html'] + ); + $this->assertEquals( + '', + $response['products']['items'][0]['description']['html'] + ); + } + + /** + * Test for checking that product fields with directives allowed are rendered correctly + * + * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php + * @magentoApiDataFixture Magento/Cms/_files/block.php + */ + public function testHtmlDirectivesRendering() + { + $productSku = 'simple'; + $cmsBlockId = 'fixture_block'; + $assertionCmsBlockText = 'Fixture Block Title'; + + $product = $this->productRepository->get($productSku, false, null, true); + $product->setDescription('Test: {{block id="' . $cmsBlockId . '"}}'); + $product->setShortDescription('Test: {{block id="' . $cmsBlockId . '"}}'); + $this->productRepository->save($product); + + $query = <<graphQlQuery($query); + + self::assertContains($assertionCmsBlockText, $response['products']['items'][0]['description']['html']); + self::assertNotContains('{{block id', $response['products']['items'][0]['description']['html']); + self::assertContains($assertionCmsBlockText, $response['products']['items'][0]['short_description']['html']); + self::assertNotContains('{{block id', $response['products']['items'][0]['short_description']['html']); + } +} diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php index 0ec63374be869..a3d0bb28da14a 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -44,9 +44,6 @@ public function testQueryAllFieldsSimpleProduct() attribute_set_id country_of_manufacture created_at - description { - html - } gift_message_available id categories { @@ -205,9 +202,6 @@ public function testQueryAllFieldsSimpleProduct() position sku } - short_description { - html - } sku small_image { path @@ -266,7 +260,6 @@ public function testQueryAllFieldsSimpleProduct() $this->assertArrayHasKey(0, $response['products']['items']); $this->assertBaseFields($product, $response['products']['items'][0]); $this->assertEavAttributes($product, $response['products']['items'][0]); - $this->assertComplexTextAttributes($product, $response['products']['items'][0]); $this->assertOptions($product, $response['products']['items'][0]); $this->assertTierPrices($product, $response['products']['items'][0]); $this->assertArrayHasKey('websites', $response['products']['items'][0]); @@ -306,7 +299,6 @@ public function testQueryMediaGalleryEntryFieldsSimpleProduct() } country_of_manufacture created_at - description gift_message_available id image @@ -457,7 +449,6 @@ public function testQueryMediaGalleryEntryFieldsSimpleProduct() position sku } - short_description sku small_image { path @@ -947,31 +938,6 @@ private function assertEavAttributes($product, $actualResponse) $this->assertResponseFields($actualResponse, $assertionMap); } - /** - * @param ProductInterface $product - * @param array $actualResponse - */ - private function assertComplexTextAttributes($product, $actualResponse) - { - $eavAttributes = [ - 'description', - 'short_description', - ]; - $assertionMap = []; - foreach ($eavAttributes as $attributeCode) { - $expectedAttribute = $product->getCustomAttribute($attributeCode); - - $assertionMap[] = [ - 'response_field' => $this->eavAttributesToGraphQlSchemaFieldTranslator($attributeCode), - 'expected_value' => $expectedAttribute ? [ - 'html' => $expectedAttribute->getValue() - ] : null - ]; - } - - $this->assertResponseFields($actualResponse, $assertionMap); - } - /** * @param string $eavAttributeCode * @return string diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductWithDescriptionDirectivesTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductWithDescriptionDirectivesTest.php deleted file mode 100644 index 8e9bc4dfa2825..0000000000000 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductWithDescriptionDirectivesTest.php +++ /dev/null @@ -1,65 +0,0 @@ -objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - } - - /** - * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php - * @magentoApiDataFixture Magento/Cms/_files/block.php - */ - public function testHtmlDirectivesRendered() - { - $productSku = 'simple'; - $cmsBlockId = 'fixture_block'; - $assertionCmsBlockText = 'Fixture Block Title'; - - /** @var ProductRepositoryInterface $productRepository */ - $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); - /** @var ProductInterface $product */ - $product = $productRepository->get($productSku, false, null, true); - $product->setDescription('Test: {{block id="' . $cmsBlockId . '"}}'); - $product->setShortDescription('Test: {{block id="' . $cmsBlockId . '"}}'); - $productRepository->save($product); - - $query = <<graphQlQuery($query); - - self::assertContains($assertionCmsBlockText, $response['products']['items'][0]['description']); - self::assertNotContains('{{block id', $response['products']['items'][0]['description']); - self::assertContains($assertionCmsBlockText, $response['products']['items'][0]['short_description']); - self::assertNotContains('{{block id', $response['products']['items'][0]['short_description']); - } -} From 6a20b98dd369a64ddfa6a08ea5e4f71ba94d8a50 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda Date: Fri, 9 Nov 2018 18:01:13 +0200 Subject: [PATCH 12/13] GraphQl-45: Product textarea field format -- Update benchmarks scenarios according to updated GraphQL Schema --- setup/performance-toolkit/benchmark.jmx | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/setup/performance-toolkit/benchmark.jmx b/setup/performance-toolkit/benchmark.jmx index 37e07d1319572..a13fe47a86532 100644 --- a/setup/performance-toolkit/benchmark.jmx +++ b/setup/performance-toolkit/benchmark.jmx @@ -40763,7 +40763,7 @@ vars.put("configurable_sku", "Configurable Product - ${__time(YMD)}-${__threadNu false - {"query":"{\n products(\n filter: {\n price: {gt: \"10\"}\n or: {\n sku:{like:\"%Product%\"}\n name:{like:\"%Configurable Product%\"}\n }\n }\n pageSize: 200\n currentPage: 1\n sort: {\n price: ASC\n name:DESC\n }\n ) {\n total_count\n items {\n attribute_set_id\n country_of_manufacture\n created_at\n description\n gift_message_available\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n short_description\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n \t... on PhysicalProductInterface {\n \tweight\n \t}\n }\n page_info {\n page_size\n current_page\n }\n }\n}\n","variables":null,"operationName":null} + {"query":"{\n products(\n filter: {\n price: {gt: \"10\"}\n or: {\n sku:{like:\"%Product%\"}\n name:{like:\"%Configurable Product%\"}\n }\n }\n pageSize: 200\n currentPage: 1\n sort: {\n price: ASC\n name:DESC\n }\n ) {\n total_count\n items {\n attribute_set_id\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n short_description {\n html\n }\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n \t... on PhysicalProductInterface {\n \tweight\n \t}\n }\n page_info {\n page_size\n current_page\n }\n }\n}\n","variables":null,"operationName":null} = @@ -40820,7 +40820,7 @@ vars.put("configurable_sku", "Configurable Product - ${__time(YMD)}-${__threadNu false - {"query":"{\n products(filter: {sku: { eq: \"${simple_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n }\n }\n}\n","variables":null,"operationName":null} + {"query":"{\n products(filter: {sku: { eq: \"${simple_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n }\n }\n}\n","variables":null,"operationName":null} = @@ -40896,7 +40896,7 @@ if (totalCount == null) { false - {"query":"{\n products(filter: {sku: {eq:\"${configurable_product_sku}\"} }) {\n total_count\n items {\n ... on PhysicalProductInterface {\n weight\n }\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null} + {"query":"{\n products(filter: {sku: {eq:\"${configurable_product_sku}\"} }) {\n total_count\n items {\n ... on PhysicalProductInterface {\n weight\n }\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null} = @@ -40965,7 +40965,7 @@ if (totalCount == null) { false - {"query":"{\n products(\n search: \"configurable\"\n filter: {price: {gteq: \"1\"} }\n ) {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t\t}\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null} + {"query":"{\n products(\n search: \"configurable\"\n filter: {price: {gteq: \"1\"} }\n ) {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t\t}\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null} = @@ -41025,7 +41025,7 @@ if (totalCount == null) { false - {"query":"{\n products(search: \"configurable\") {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t\t}\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null} + {"query":"{\n products(search: \"configurable\") {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t\t}\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null} = @@ -41085,7 +41085,7 @@ if (totalCount == null) { false - {"query":"{\n products(search: \"color\") {\n filters {\n name\n filter_items_count\n request_var\n filter_items {\n label\n value_string\n items_count\n ... on SwatchLayerFilterItemInterface {\n swatch_data {\n type\n value\n }\n }\n }\n }\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n weight\n }\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}","variables":null,"operationName":null} + {"query":"{\n products(search: \"color\") {\n filters {\n name\n filter_items_count\n request_var\n filter_items {\n label\n value_string\n items_count\n ... on SwatchLayerFilterItemInterface {\n swatch_data {\n type\n value\n }\n }\n }\n }\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n weight\n }\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}","variables":null,"operationName":null} = @@ -41145,7 +41145,7 @@ if (totalCount == null) { false - {"query":"{\nproducts(filter: {sku: {eq:\"${bundle_product_sku}\"} }) {\n total_count\n items {\n ... on PhysicalProductInterface {\n weight\n }\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on BundleProduct {\n weight\n price_view\n dynamic_price\n dynamic_sku\n ship_bundle_items\n dynamic_weight\n items {\n option_id\n title\n required\n type\n position\n sku\n options {\n id\n qty\n position\n is_default\n price\n price_type\n can_change_quantity\n product {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n }\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null} + {"query":"{\nproducts(filter: {sku: {eq:\"${bundle_product_sku}\"} }) {\n total_count\n items {\n ... on PhysicalProductInterface {\n weight\n }\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on BundleProduct {\n weight\n price_view\n dynamic_price\n dynamic_sku\n ship_bundle_items\n dynamic_weight\n items {\n option_id\n title\n required\n type\n position\n sku\n options {\n id\n qty\n position\n is_default\n price\n price_type\n can_change_quantity\n product {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n }\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null} = @@ -41214,7 +41214,7 @@ if (totalCount == null) { false - {"query":"{\n products(filter: {sku: { eq: \"${downloadable_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n ... on DownloadableProduct {\n links_purchased_separately\n links_title\n downloadable_product_samples {\n id\n title\n sort_order\n sample_type\n sample_file\n sample_url\n }\n downloadable_product_links {\n id\n title\n sort_order\n is_shareable\n price\n number_of_downloads\n link_type\n sample_type\n sample_file\n sample_url\n }\n }\n }\n }\n}\n","variables":null,"operationName":null} + {"query":"{\n products(filter: {sku: { eq: \"${downloadable_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n ... on DownloadableProduct {\n links_purchased_separately\n links_title\n downloadable_product_samples {\n id\n title\n sort_order\n sample_type\n sample_file\n sample_url\n }\n downloadable_product_links {\n id\n title\n sort_order\n is_shareable\n price\n number_of_downloads\n link_type\n sample_type\n sample_file\n sample_url\n }\n }\n }\n }\n}\n","variables":null,"operationName":null} = @@ -41301,7 +41301,7 @@ if (totalCount == null) { false - {"query":"{\n products(filter: {sku: { eq: \"${virtual_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n }\n }\n}\n","variables":null,"operationName":null} + {"query":"{\n products(filter: {sku: { eq: \"${virtual_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n }\n }\n}\n","variables":null,"operationName":null} = @@ -41368,7 +41368,7 @@ if (totalCount == null) { false - {"query":"{\nproducts(filter: {sku: {eq:\"${grouped_product_sku}\"} }) {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on GroupedProduct {\n weight\n items {\n qty\n position\n product {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null} + {"query":"{\nproducts(filter: {sku: {eq:\"${grouped_product_sku}\"} }) {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on GroupedProduct {\n weight\n items {\n qty\n position\n product {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null} = From 45d3742f7a7a3104dc756350c854da18e02a6189 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda Date: Fri, 9 Nov 2018 18:50:33 +0200 Subject: [PATCH 13/13] GraphQl-45: Product textarea field format -- Update benchmarks scenarios according to updated GraphQL Schema --- .../Magento/GraphQl/Catalog/UrlRewritesTest.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/UrlRewritesTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/UrlRewritesTest.php index c39b32e4bfa4f..43796d780646c 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/UrlRewritesTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/UrlRewritesTest.php @@ -33,8 +33,10 @@ public function testProductWithNoCategoriesAssigned() items { name, sku, - description, - url_rewrites { + description { + html + } + url_rewrites { url, parameters { name, @@ -87,8 +89,10 @@ public function testProductWithOneCategoryAssigned() items { name, sku, - description, - url_rewrites { + description { + html + } + url_rewrites { url, parameters { name,