diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Options/BundleEnteredOptionValueIdV2.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Options/BundleItemOptionUid.php similarity index 76% rename from app/code/Magento/BundleGraphQl/Model/Resolver/Options/BundleEnteredOptionValueIdV2.php rename to app/code/Magento/BundleGraphQl/Model/Resolver/Options/BundleItemOptionUid.php index c1a55d9db794a..ce5c12ce69675 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/Options/BundleEnteredOptionValueIdV2.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Options/BundleItemOptionUid.php @@ -14,9 +14,9 @@ use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; /** - * Format new option id_v2 in base64 encode for entered bundle options + * Format new option uid in base64 encode for entered bundle options */ -class BundleEnteredOptionValueIdV2 implements ResolverInterface +class BundleItemOptionUid implements ResolverInterface { /** * Option type name @@ -24,7 +24,7 @@ class BundleEnteredOptionValueIdV2 implements ResolverInterface private const OPTION_TYPE = 'bundle'; /** - * Create a option id_v2 for entered option in "///" format + * Create a option uid for entered option in "///" format * * @param Field $field * @param ContextInterface $context @@ -46,11 +46,11 @@ public function resolve( array $args = null ) { if (!isset($value['option_id']) || empty($value['option_id'])) { - throw new GraphQlInputException(__('Wrong format option data: option_id should not be empty.')); + throw new GraphQlInputException(__('"option_id" value should be specified.')); } if (!isset($value['selection_id']) || empty($value['selection_id'])) { - throw new GraphQlInputException(__('Wrong format option data: selection_id should not be empty.')); + throw new GraphQlInputException(__('"selection_id" value should be specified.')); } $optionDetails = [ diff --git a/app/code/Magento/BundleGraphQl/etc/schema.graphqls b/app/code/Magento/BundleGraphQl/etc/schema.graphqls index bab1a256f7f59..361c5fad6cf8f 100644 --- a/app/code/Magento/BundleGraphQl/etc/schema.graphqls +++ b/app/code/Magento/BundleGraphQl/etc/schema.graphqls @@ -66,7 +66,7 @@ type BundleItemOption @doc(description: "BundleItemOption defines characteristic price_type: PriceTypeEnum @doc(description: "One of FIXED, PERCENT, or DYNAMIC.") can_change_quantity: Boolean @doc(description: "Indicates whether the customer can change the number of items for this option.") product: ProductInterface @doc(description: "Contains details about this product option.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product") - id_v2: String @doc(description: "Base64 string, that encodes details for each option.") @resolver(class: "Magento\\BundleGraphQl\\Model\\Resolver\\Options\\BundleEnteredOptionValueIdV2") + uid: ID @doc(description: "An encoded string that encodes option details.") @resolver(class: "Magento\\BundleGraphQl\\Model\\Resolver\\Options\\BundleItemOptionUid") # A Base64 string that encodes option details. } type BundleProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface @doc(description: "BundleProduct defines basic features of a bundle product and contains multiple BundleItems.") { diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/CustomizableEnteredOptionValueIdV2.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/CustomizableEnteredOptionValueUid.php similarity index 80% rename from app/code/Magento/CatalogGraphQl/Model/Resolver/Product/CustomizableEnteredOptionValueIdV2.php rename to app/code/Magento/CatalogGraphQl/Model/Resolver/Product/CustomizableEnteredOptionValueUid.php index efc15d5d92ca3..69fafc49c9137 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/CustomizableEnteredOptionValueIdV2.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/CustomizableEnteredOptionValueUid.php @@ -14,9 +14,9 @@ use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; /** - * Format new option id_v2 in base64 encode for entered custom options + * Format new option uid in base64 encode for entered custom options */ -class CustomizableEnteredOptionValueIdV2 implements ResolverInterface +class CustomizableEnteredOptionValueUid implements ResolverInterface { /** * Option type name @@ -24,7 +24,7 @@ class CustomizableEnteredOptionValueIdV2 implements ResolverInterface private const OPTION_TYPE = 'custom-option'; /** - * Create a option id_v2 for entered option in "/" format + * Create a option uid for entered option in "/" format * * @param Field $field * @param ContextInterface $context @@ -46,7 +46,7 @@ public function resolve( array $args = null ) { if (!isset($value['option_id']) || empty($value['option_id'])) { - throw new GraphQlInputException(__('Wrong format option data: option_id should not be empty.')); + throw new GraphQlInputException(__('"option_id" value should be specified.')); } $optionDetails = [ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/CustomizableSelectedOptionValueIdV2.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/CustomizableSelectedOptionValueUid.php similarity index 76% rename from app/code/Magento/CatalogGraphQl/Model/Resolver/Product/CustomizableSelectedOptionValueIdV2.php rename to app/code/Magento/CatalogGraphQl/Model/Resolver/Product/CustomizableSelectedOptionValueUid.php index f1dff2680ba93..5fbd8a56bb570 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/CustomizableSelectedOptionValueIdV2.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/CustomizableSelectedOptionValueUid.php @@ -14,9 +14,9 @@ use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; /** - * Format new option id_v2 in base64 encode for selected custom options + * Format new option uid in base64 encode for selected custom options */ -class CustomizableSelectedOptionValueIdV2 implements ResolverInterface +class CustomizableSelectedOptionValueUid implements ResolverInterface { /** * Option type name @@ -24,7 +24,7 @@ class CustomizableSelectedOptionValueIdV2 implements ResolverInterface private const OPTION_TYPE = 'custom-option'; /** - * Create a option id_v2 for selected option in "//" format + * Create a option uid for selected option in "//" format * * @param Field $field * @param ContextInterface $context @@ -46,11 +46,11 @@ public function resolve( array $args = null ) { if (!isset($value['option_id']) || empty($value['option_id'])) { - throw new GraphQlInputException(__('Wrong format option data: option_id should not be empty.')); + throw new GraphQlInputException(__('"option_id" value should be specified.')); } if (!isset($value['option_type_id']) || empty($value['option_type_id'])) { - throw new GraphQlInputException(__('Wrong format option data: option_type_id should not be empty.')); + throw new GraphQlInputException(__('"option_type_id" value should be specified.')); } $optionDetails = [ diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 008ed729350cd..2f505f2441f31 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -132,7 +132,7 @@ type CustomizableAreaValue @doc(description: "CustomizableAreaValue defines the price_type: PriceTypeEnum @doc(description: "FIXED, PERCENT, or DYNAMIC.") sku: String @doc(description: "The Stock Keeping Unit for this option.") max_characters: Int @doc(description: "The maximum number of characters that can be entered for this customizable option.") - id_v2: String @doc(description: "Base64 string, that encodes details for each option.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CustomizableEnteredOptionValueIdV2") + uid: ID @doc(description: "An encoded string that encodes option details.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CustomizableEnteredOptionValueUid") # A Base64 string that encodes option details. } type CategoryTree implements CategoryInterface @doc(description: "Category Tree implementation.") { @@ -154,7 +154,7 @@ type CustomizableDateValue @doc(description: "CustomizableDateValue defines the price: Float @doc(description: "The price assigned to this option.") price_type: PriceTypeEnum @doc(description: "FIXED, PERCENT, or DYNAMIC.") sku: String @doc(description: "The Stock Keeping Unit for this option.") - id_v2: String @doc(description: "Base64 string, that encodes details for each option.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CustomizableEnteredOptionValueIdV2") + uid: ID @doc(description: "An encoded string that encodes option details.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CustomizableEnteredOptionValueUid") # A Base64 string that encodes option details. } type CustomizableDropDownOption implements CustomizableOptionInterface @doc(description: "CustomizableDropDownOption contains information about a drop down menu that is defined as part of a customizable option.") { @@ -168,7 +168,7 @@ type CustomizableDropDownValue @doc(description: "CustomizableDropDownValue defi sku: String @doc(description: "The Stock Keeping Unit for this option.") title: String @doc(description: "The display name for this option.") sort_order: Int @doc(description: "The order in which the option is displayed.") - id_v2: String @doc(description: "Base64 string, that encodes details for each option.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CustomizableSelectedOptionValueIdV2") + uid: ID @doc(description: "An encoded string that encodes option details.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CustomizableSelectedOptionValueUid") # A Base64 string that encodes option details. } type CustomizableMultipleOption implements CustomizableOptionInterface @doc(description: "CustomizableMultipleOption contains information about a multiselect that is defined as part of a customizable option.") { @@ -182,7 +182,7 @@ type CustomizableMultipleValue @doc(description: "CustomizableMultipleValue defi sku: String @doc(description: "The Stock Keeping Unit for this option.") title: String @doc(description: "The display name for this option.") sort_order: Int @doc(description: "The order in which the option is displayed.") - id_v2: String @doc(description: "Base64 string, that encodes details for each option.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CustomizableSelectedOptionValueIdV2") + uid: ID @doc(description: "An encoded string that encodes option details.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CustomizableSelectedOptionValueUid") } type CustomizableFieldOption implements CustomizableOptionInterface @doc(description: "CustomizableFieldOption contains information about a text field that is defined as part of a customizable option.") { @@ -195,7 +195,7 @@ type CustomizableFieldValue @doc(description: "CustomizableFieldValue defines th price_type: PriceTypeEnum @doc(description: "FIXED, PERCENT, or DYNAMIC.") sku: String @doc(description: "The Stock Keeping Unit for this option.") max_characters: Int @doc(description: "The maximum number of characters that can be entered for this customizable option.") - id_v2: String @doc(description: "Base64 string, that encodes details for each option.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CustomizableEnteredOptionValueIdV2") + uid: ID @doc(description: "An encoded string that encodes option details.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CustomizableEnteredOptionValueUid") # A Base64 string that encodes option details. } type CustomizableFileOption implements CustomizableOptionInterface @doc(description: "CustomizableFileOption contains information about a file picker that is defined as part of a customizable option.") { @@ -210,7 +210,7 @@ type CustomizableFileValue @doc(description: "CustomizableFileValue defines the file_extension: String @doc(description: "The file extension to accept.") image_size_x: Int @doc(description: "The maximum width of an image.") image_size_y: Int @doc(description: "The maximum height of an image.") - id_v2: String @doc(description: "Base64 string, that encodes details for each option.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CustomizableEnteredOptionValueIdV2") + uid: ID @doc(description: "An encoded string that encodes option details.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CustomizableEnteredOptionValueUid") # A Base64 string that encodes option details. } interface MediaGalleryInterface @doc(description: "Contains basic information about a product image or video.") @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\MediaGalleryTypeResolver") { @@ -280,7 +280,7 @@ type CustomizableRadioValue @doc(description: "CustomizableRadioValue defines th sku: String @doc(description: "The Stock Keeping Unit for this option.") title: String @doc(description: "The display name for this option.") sort_order: Int @doc(description: "The order in which the radio button is displayed.") - id_v2: String @doc(description: "Base64 string, that encodes details for each option.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CustomizableSelectedOptionValueIdV2") + uid: ID @doc(description: "An encoded string that encodes option details.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CustomizableSelectedOptionValueUid") # A Base64 string that encodes option details. } type CustomizableCheckboxOption implements CustomizableOptionInterface @doc(description: "CustomizableCheckbbixOption contains information about a set of checkbox values that are defined as part of a customizable option.") { @@ -294,7 +294,7 @@ type CustomizableCheckboxValue @doc(description: "CustomizableCheckboxValue defi sku: String @doc(description: "The Stock Keeping Unit for this option.") title: String @doc(description: "The display name for this option.") sort_order: Int @doc(description: "The order in which the checkbox value is displayed.") - id_v2: String @doc(description: "Base64 string, that encodes details for each option.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CustomizableSelectedOptionValueIdV2") + uid: ID @doc(description: "An encoded string that encodes option details.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CustomizableSelectedOptionValueUid") # A Base64 string that encodes option details. } type VirtualProduct implements ProductInterface, CustomizableProductInterface @doc(description: "A virtual product is non-tangible product that does not require shipping and is not kept in inventory.") { diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Variant/Attributes.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Variant/Attributes.php index faf666144422c..3a064f3399255 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Variant/Attributes.php +++ b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Variant/Attributes.php @@ -60,7 +60,8 @@ public function resolve( $option['options_map'] ?? [], $code, (int) $optionId, - (int) $model->getData($code) + (int) $model->getData($code), + (int) $option['attribute_id'] ); if (!empty($optionsFromMap)) { $data[] = $optionsFromMap; @@ -77,14 +78,20 @@ public function resolve( * @param string $code * @param int $optionId * @param int $attributeCodeId + * @param int $attributeId * @return array */ - private function getOptionsFromMap(array $optionMap, string $code, int $optionId, int $attributeCodeId): array - { + private function getOptionsFromMap( + array $optionMap, + string $code, + int $optionId, + int $attributeCodeId, + int $attributeId + ): array { $data = []; if (isset($optionMap[$optionId . ':' . $attributeCodeId])) { $optionValue = $optionMap[$optionId . ':' . $attributeCodeId]; - $data = $this->getOptionsArray($optionValue, $code); + $data = $this->getOptionsArray($optionValue, $code, $attributeId); } return $data; } @@ -94,15 +101,17 @@ private function getOptionsFromMap(array $optionMap, string $code, int $optionId * * @param array $optionValue * @param string $code + * @param int $attributeId * @return array */ - private function getOptionsArray(array $optionValue, string $code): array + private function getOptionsArray(array $optionValue, string $code, int $attributeId): array { return [ 'label' => $optionValue['label'] ?? null, 'code' => $code, 'use_default_value' => $optionValue['use_default_value'] ?? null, 'value_index' => $optionValue['value_index'] ?? null, + 'attribute_id' => $attributeId, ]; } } diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Variant/Attributes/ConfigurableAttributeIdV2.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Variant/Attributes/ConfigurableAttributeIdV2.php deleted file mode 100644 index 75cd1ade5b548..0000000000000 --- a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Variant/Attributes/ConfigurableAttributeIdV2.php +++ /dev/null @@ -1,83 +0,0 @@ -eavAttribute = $eavAttribute; - } - - /** - * @inheritdoc - * - * Create new option id_v2 that encodes details for each option and in most cases can be presented - * as base64("//") - * - * @param Field $field - * @param ContextInterface $context - * @param ResolveInfo $info - * @param array|null $value - * @param array|null $args - * @return Value|mixed|string - * @throws LocalizedException - */ - public function resolve( - Field $field, - $context, - ResolveInfo $info, - array $value = null, - array $args = null - ) { - $attribute_id = $this->eavAttribute->getIdByCode('catalog_product', $value['code']); - $optionDetails = [ - self::OPTION_TYPE, - $attribute_id, - $value['value_index'] - ]; - - if (empty($attribute_id)) { - throw new LocalizedException(__('Wrong format option data: attribute_id should not be empty.')); - } - - if (!isset($value['value_index']) || empty($value['value_index'])) { - throw new LocalizedException(__('Wrong format option data: value_index should not be empty.')); - } - - // phpcs:ignore Magento2.Functions.DiscouragedFunction - $content = \implode('/', $optionDetails); - - return base64_encode($content); - } -} diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Variant/Attributes/ConfigurableAttributeUid.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Variant/Attributes/ConfigurableAttributeUid.php new file mode 100644 index 0000000000000..13f31e7e2ce10 --- /dev/null +++ b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Variant/Attributes/ConfigurableAttributeUid.php @@ -0,0 +1,67 @@ +//" format + * + * @param Field $field + * @param ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * + * @return string + * + * @throws GraphQlInputException + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if (!isset($value['attribute_id']) || empty($value['attribute_id'])) { + throw new GraphQlInputException(__('"attribute_id" value should be specified.')); + } + + if (!isset($value['value_index']) || empty($value['value_index'])) { + throw new GraphQlInputException(__('"value_index" value should be specified.')); + } + + $optionDetails = [ + self::OPTION_TYPE, + $value['attribute_id'], + $value['value_index'] + ]; + + $content = implode('/', $optionDetails); + + // phpcs:ignore Magento2.Functions.DiscouragedFunction + return base64_encode($content); + } +} diff --git a/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphqls b/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphqls index 537987d6153bc..5ce6d61dc6a64 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphqls +++ b/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphqls @@ -18,7 +18,7 @@ type ConfigurableAttributeOption @doc(description: "ConfigurableAttributeOption label: String @doc(description: "A string that describes the configurable attribute option") code: String @doc(description: "The ID assigned to the attribute") value_index: Int @doc(description: "A unique index number assigned to the configurable product option") - id_v2: String @doc(description: "Base64 string, that encodes details for each option.") @resolver(class: "Magento\\ConfigurableProductGraphQl\\Model\\Resolver\\Variant\\Attributes\\ConfigurableAttributeIdV2") + uid: ID @doc(description: "An encoded string that encodes option details.") @resolver(class: "Magento\\ConfigurableProductGraphQl\\Model\\Resolver\\Variant\\Attributes\\ConfigurableAttributeUid") # A Base64 string that encodes option details. } type ConfigurableProductOptions @doc(description: "ConfigurableProductOptions defines configurable attributes for the specified product") { diff --git a/app/code/Magento/DownloadableGraphQl/Resolver/Product/DownloadableLinksValueIdV2.php b/app/code/Magento/DownloadableGraphQl/Resolver/Product/DownloadableLinksValueUid.php similarity index 81% rename from app/code/Magento/DownloadableGraphQl/Resolver/Product/DownloadableLinksValueIdV2.php rename to app/code/Magento/DownloadableGraphQl/Resolver/Product/DownloadableLinksValueUid.php index 62da0ba8530fc..03727597104fd 100644 --- a/app/code/Magento/DownloadableGraphQl/Resolver/Product/DownloadableLinksValueIdV2.php +++ b/app/code/Magento/DownloadableGraphQl/Resolver/Product/DownloadableLinksValueUid.php @@ -13,10 +13,13 @@ use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; /** - * Formatting the id_v2 for downloadable link + * Formatting the uid for downloadable link */ -class DownloadableLinksValueIdV2 implements ResolverInterface +class DownloadableLinksValueUid implements ResolverInterface { + /** + * Option type name + */ private const OPTION_TYPE = 'downloadable'; /** @@ -30,7 +33,7 @@ public function resolve( array $args = null ) { if (!isset($value['id']) || empty($value['id'])) { - throw new GraphQlInputException(__('Wrong format option data: `id` should not be empty.')); + throw new GraphQlInputException(__('"id" value should be specified.')); } $optionDetails = [ diff --git a/app/code/Magento/DownloadableGraphQl/etc/schema.graphqls b/app/code/Magento/DownloadableGraphQl/etc/schema.graphqls index 82249bf7701da..9e24ddf9ea71b 100644 --- a/app/code/Magento/DownloadableGraphQl/etc/schema.graphqls +++ b/app/code/Magento/DownloadableGraphQl/etc/schema.graphqls @@ -53,7 +53,7 @@ type DownloadableProductLinks @doc(description: "DownloadableProductLinks define link_type: DownloadableFileTypeEnum @deprecated(reason: "`sample_url` serves to get the downloadable sample") sample_type: DownloadableFileTypeEnum @deprecated(reason: "`sample_url` serves to get the downloadable sample") sample_file: String @deprecated(reason: "`sample_url` serves to get the downloadable sample") - id_v2: String @doc(description: "Base64 string, that encodes details for each option.") @resolver(class: "Magento\\DownloadableGraphQl\\Resolver\\Product\\DownloadableLinksValueIdV2") + uid: ID @doc(description: "An encoded string that encodes option details.") @resolver(class: "Magento\\DownloadableGraphQl\\Resolver\\Product\\DownloadableLinksValueUid") # A Base64 string that encodes option details. } type DownloadableProductSamples @doc(description: "DownloadableProductSamples defines characteristics of a downloadable product") { diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/Options/Uid/CustomizableOptionsUidTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/Options/Uid/CustomizableOptionsUidTest.php new file mode 100644 index 0000000000000..c5a44d5ff68b3 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/Options/Uid/CustomizableOptionsUidTest.php @@ -0,0 +1,156 @@ +getQuery($productSku); + $response = $this->graphQlQuery($query); + $responseProduct = $response['products']['items'][0]; + self::assertNotEmpty($responseProduct['options']); + + foreach ($responseProduct['options'] as $option) { + if (isset($option['entered_option'])) { + $enteredOption = $option['entered_option']; + $uid = $this->getUidForEnteredValue($option['option_id']); + + self::assertEquals($uid, $enteredOption['uid']); + } elseif (isset($option['selected_option'])) { + $this->assertNotEmpty($option['selected_option']); + + foreach ($option['selected_option'] as $selectedOption) { + $uid = $this->getUidForSelectedValue($option['option_id'], $selectedOption['option_type_id']); + self::assertEquals($uid, $selectedOption['uid']); + } + } + } + } + + /** + * Get uid for entered option + * + * @param int $optionId + * + * @return string + */ + private function getUidForEnteredValue(int $optionId): string + { + return base64_encode('custom-option/' . $optionId); + } + + /** + * Get uid for selected option + * + * @param int $optionId + * @param int $optionValueId + * + * @return string + */ + private function getUidForSelectedValue(int $optionId, int $optionValueId): string + { + return base64_encode('custom-option/' . $optionId . '/' . $optionValueId); + } + + /** + * Get query + * + * @param string $sku + * + * @return string + */ + private function getQuery(string $sku): string + { + return <<eavAttribute = $objectManager->get(Attribute::class); + } + + /** + * @magentoApiDataFixture Magento/ConfigurableProduct/_files/configurable_product_with_one_simple.php + */ + public function testQueryUidForConfigurableSuperAttributes() + { + $productSku = 'configurable'; + $query = $this->getQuery($productSku); + $response = $this->graphQlQuery($query); + $responseProduct = $response['products']['items'][0]; + self::assertNotEmpty($responseProduct['variants']); + + foreach ($responseProduct['variants'] as $variant) { + self::assertNotEmpty($variant['attributes']); + + foreach ($variant['attributes'] as $attribute) { + $attributeId = (int) $this->eavAttribute->getIdByCode(Product::ENTITY, $attribute['code']); + $uid = $this->getUidByOptionIds($attributeId, $attribute['value_index']); + self::assertEquals($uid, $attribute['uid']); + } + } + } + + /** + * Get Uid + * + * @param int $optionId + * @param int $optionValueId + * + * @return string + */ + private function getUidByOptionIds(int $optionId, int $optionValueId): string + { + return base64_encode('configurable/' . $optionId . '/' . $optionValueId); + } + + /** + * Get query + * + * @param string $sku + * + * @return string + */ + private function getQuery(string $sku): string + { + return <<getQuery($productSku); + $response = $this->graphQlQuery($query); + $responseProduct = $response['products']['items'][0]; + + self::assertNotEmpty($responseProduct['downloadable_product_links']); + + foreach ($responseProduct['downloadable_product_links'] as $productLink) { + $uid = $this->getUidByLinkId((int) $productLink['id']); + self::assertEquals($uid, $productLink['uid']); + } + } + + /** + * Get uid by link id + * + * @param int $linkId + * + * @return string + */ + private function getUidByLinkId(int $linkId): string + { + return base64_encode('downloadable/' . $linkId); + } + + /** + * Get query + * + * @param string $sku + * + * @return string + */ + private function getQuery(string $sku): string + { + return <<