From ebbe8131927704cbd27a381e1d160896a014786c Mon Sep 17 00:00:00 2001 From: Lena Orobei Date: Thu, 19 Dec 2019 14:38:42 -0600 Subject: [PATCH 1/4] Forward-port magento/graphql-ce#443 and magento/graphql-ce#1073 --- .../Model/Customer/ValidateCustomerData.php | 22 +- .../DataProvider/SwatchDataProvider.php | 250 ++++++++++++++++++ .../Resolver/Product/Options/SwatchData.php | 56 ++++ .../Options/SwatchDataTypeResolver.php | 34 +++ .../SwatchesGraphQl/etc/graphql/di.xml | 2 +- .../SwatchesGraphQl/etc/schema.graphqls | 20 ++ .../GraphQl/Customer/CreateCustomerTest.php | 43 ++- .../Swatches/ProductSwatchDataTest.php | 166 ++++++++++++ .../_files/text_swatch_attribute_rollback.php | 23 ++ .../_files/textual_swatch_attribute.php | 103 ++++++++ ..._attribute_with_different_options_type.php | 116 ++++++++ ...e_with_different_options_type_rollback.php | 34 +++ ..._with_enabled_product_image_for_swatch.php | 35 +++ ...bled_product_image_for_swatch_rollback.php | 11 + 14 files changed, 900 insertions(+), 15 deletions(-) create mode 100644 app/code/Magento/SwatchesGraphQl/Model/Resolver/Product/Options/DataProvider/SwatchDataProvider.php create mode 100644 app/code/Magento/SwatchesGraphQl/Model/Resolver/Product/Options/SwatchData.php create mode 100644 app/code/Magento/SwatchesGraphQl/Model/Resolver/Product/Options/SwatchDataTypeResolver.php create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Swatches/ProductSwatchDataTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Swatches/_files/text_swatch_attribute_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/Swatches/_files/textual_swatch_attribute.php create mode 100644 dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_different_options_type.php create mode 100644 dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_different_options_type_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_enabled_product_image_for_swatch.php create mode 100644 dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_enabled_product_image_for_swatch_rollback.php diff --git a/app/code/Magento/CustomerGraphQl/Model/Customer/ValidateCustomerData.php b/app/code/Magento/CustomerGraphQl/Model/Customer/ValidateCustomerData.php index 794cb0048592d..3861ce324ea7d 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Customer/ValidateCustomerData.php +++ b/app/code/Magento/CustomerGraphQl/Model/Customer/ValidateCustomerData.php @@ -8,9 +8,10 @@ namespace Magento\CustomerGraphQl\Model\Customer; use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Validator\EmailAddress as EmailAddressValidator; /** - * Class ValidateCustomerData + * Customer data validation used during customer account creation and updating */ class ValidateCustomerData { @@ -21,14 +22,23 @@ class ValidateCustomerData */ private $getAllowedCustomerAttributes; + /** + * @var EmailAddressValidator + */ + private $emailAddressValidator; + /** * ValidateCustomerData constructor. * * @param GetAllowedCustomerAttributes $getAllowedCustomerAttributes + * @param EmailAddressValidator $emailAddressValidator */ - public function __construct(GetAllowedCustomerAttributes $getAllowedCustomerAttributes) - { + public function __construct( + GetAllowedCustomerAttributes $getAllowedCustomerAttributes, + EmailAddressValidator $emailAddressValidator + ) { $this->getAllowedCustomerAttributes = $getAllowedCustomerAttributes; + $this->emailAddressValidator = $emailAddressValidator; } /** @@ -59,5 +69,11 @@ public function execute(array $customerData): void __('Required parameters are missing: %1', [implode(', ', $errorInput)]) ); } + + if (isset($customerData['email']) && !$this->emailAddressValidator->isValid($customerData['email'])) { + throw new GraphQlInputException( + __('"%1" is not a valid email address.', $customerData['email']) + ); + } } } diff --git a/app/code/Magento/SwatchesGraphQl/Model/Resolver/Product/Options/DataProvider/SwatchDataProvider.php b/app/code/Magento/SwatchesGraphQl/Model/Resolver/Product/Options/DataProvider/SwatchDataProvider.php new file mode 100644 index 0000000000000..9e62ae928fb53 --- /dev/null +++ b/app/code/Magento/SwatchesGraphQl/Model/Resolver/Product/Options/DataProvider/SwatchDataProvider.php @@ -0,0 +1,250 @@ +swatchHelper = $swatchHelper; + $this->swatchMediaHelper = $swatchMediaHelper; + $this->imageUrlBuilder = $imageUrlBuilder; + $this->enumLookup = $enumLookup; + } + + /** + * Get swatch data + * + * @param string $optionId + * @param ProductInterface $product + * + * @return array + * + * @throws LocalizedException + * @throws NoSuchEntityException + * @throws \LogicException + */ + public function getData(string $optionId, ProductInterface $product): array + { + $swatches = $this->swatchHelper->getSwatchesByOptionsId([$optionId]); + if (!isset($swatches[$optionId], $swatches[$optionId]['type'], $swatches[$optionId]['value'])) { + return null; + } + + $type = (int)$swatches[$optionId]['type']; + $value = $swatches[$optionId]['value']; + $thumbnail = null; + + // change value & thumbnail if type is 'visual' + if ($type === Swatch::SWATCH_TYPE_VISUAL_IMAGE) { + $thumbnail = $this->swatchMediaHelper->getSwatchAttributeImage(Swatch::SWATCH_THUMBNAIL_NAME, $value); + $value = $this->swatchMediaHelper->getSwatchAttributeImage(Swatch::SWATCH_IMAGE_NAME, $value); + } + + $attributeData = $this->getSwatchAttributeDataByOptionId($product, $optionId); + // check if swatch value should be getting from related product image + if (!$this->isUseProductImageForSwatch($attributeData)) { + return $this->getResultArray($value, $type, $thumbnail); + } + + // get product with existing image + $variationProduct = $this->getVariationProduct($attributeData, $optionId, $product); + if (null === $variationProduct) { + return $this->getResultArray($value, $type, $thumbnail); + } + + // set 'visual' type, because the product image is using as swatch value + $type = Swatch::SWATCH_TYPE_VISUAL_IMAGE; + + // get image from child product + $productImage = $this->getSwatchProductImage($variationProduct, Swatch::SWATCH_IMAGE_NAME); + if (null !== $productImage) { + $value = $productImage; + } + + // get thumbnail from child product + $productThumbnail = $this->getSwatchProductImage($variationProduct, Swatch::SWATCH_THUMBNAIL_NAME); + if (null !== $productThumbnail) { + $thumbnail = $productThumbnail; + } + + return $this->getResultArray($value, $type, $thumbnail); + } + + /** + * Get result array + * + * @param string $value + * @param int $type + * @param null|string $thumbnail + * + * @return array + * + * @throws RuntimeException + */ + private function getResultArray(string $value, int $type, ?string $thumbnail) + { + return [ + 'value' => $value, + 'type' => $this->enumLookup->getEnumValueFromField('SwatchTypeEnum', (string)$type), + 'thumbnail' => $thumbnail + ]; + } + + /** + * Is swatch images should be getting from related simple products + * + * @param array $attributeData + * + * @return bool + */ + private function isUseProductImageForSwatch(array $attributeData) : bool + { + return isset($attributeData['use_product_image_for_swatch']) && $attributeData['use_product_image_for_swatch']; + } + + /** + * Get simple product with first variation swatch image or image + * + * @param array $attributeData + * @param string $optionId + * @param ProductInterface $product + * + * @return ProductInterface|null + */ + private function getVariationProduct(array $attributeData, string $optionId, ProductInterface $product) : ?ProductInterface + { + $attributeCode = $attributeData['attribute_code']; + $requiredAttributes = [ + $attributeCode => $optionId + ]; + + $variationProduct = $this->swatchHelper->loadFirstVariationWithSwatchImage($product, $requiredAttributes); + if ($variationProduct instanceof ProductInterface) { + return $variationProduct; + } + + $variationProduct = $this->swatchHelper->loadFirstVariationWithImage($product, $requiredAttributes); + if ($variationProduct instanceof ProductInterface) { + return $variationProduct; + } + + return null; + } + + /** + * Get swatch product image + * + * @param ProductInterface $product + * @param string $imageType + * + * @return string|null + */ + private function getSwatchProductImage(ProductInterface $product, $imageType) : ?string + { + if ($this->isProductHasImage($product, Swatch::SWATCH_IMAGE_NAME)) { + $swatchImageId = $imageType; + $imageAttributes = ['type' => Swatch::SWATCH_IMAGE_NAME]; + } elseif ($this->isProductHasImage($product, 'image')) { + $swatchImageId = $imageType == Swatch::SWATCH_IMAGE_NAME ? 'swatch_image_base' : 'swatch_thumb_base'; + $imageAttributes = ['type' => 'image']; + } + + if (empty($swatchImageId) || empty($imageAttributes['type'])) { + return null; + } + + return $this->imageUrlBuilder->getUrl($product->getData($imageAttributes['type']), $swatchImageId); + } + + /** + * Is product has image + * + * @param ProductInterface $product + * @param string $imageType + * + * @return bool + */ + private function isProductHasImage(ProductInterface $product, string $imageType) : bool + { + return $product->getData($imageType) !== null && $product->getData($imageType) != SwatchData::EMPTY_IMAGE_VALUE; + } + + /** + * Get swatch attribute data by option id + * + * @param ProductInterface $product + * @param string $optionId + * + * @return array + * + * @throws LocalizedException + * @throws \LogicException + * @throws NoSuchEntityException + */ + private function getSwatchAttributeDataByOptionId(ProductInterface $product, string $optionId) : array + { + $attributesData = $this->swatchHelper->getSwatchAttributesAsArray($product); + foreach ($attributesData as $attributeData) { + if (!isset($attributeData['options']) || !is_array($attributeData['options'])) { + continue; + } + + if (array_key_exists($optionId, $attributeData['options'])) { + return $attributeData; + } + } + + throw new LocalizedException(__(sprintf('Cannot find the attribute with option id "%1".', $optionId))); + } +} diff --git a/app/code/Magento/SwatchesGraphQl/Model/Resolver/Product/Options/SwatchData.php b/app/code/Magento/SwatchesGraphQl/Model/Resolver/Product/Options/SwatchData.php new file mode 100644 index 0000000000000..9fea3b3ff59e5 --- /dev/null +++ b/app/code/Magento/SwatchesGraphQl/Model/Resolver/Product/Options/SwatchData.php @@ -0,0 +1,56 @@ +swatchDataProvider = $swatchDataProvider; + } + + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if (!array_key_exists('model', $value) || !$value['model'] instanceof ProductInterface) { + throw new LocalizedException(__('"model" value should be specified')); + } + + return $this->swatchDataProvider->getData($value['value_index'], $value['model']); + } +} diff --git a/app/code/Magento/SwatchesGraphQl/Model/Resolver/Product/Options/SwatchDataTypeResolver.php b/app/code/Magento/SwatchesGraphQl/Model/Resolver/Product/Options/SwatchDataTypeResolver.php new file mode 100644 index 0000000000000..96f584524fd27 --- /dev/null +++ b/app/code/Magento/SwatchesGraphQl/Model/Resolver/Product/Options/SwatchDataTypeResolver.php @@ -0,0 +1,34 @@ + - \ No newline at end of file + diff --git a/app/code/Magento/SwatchesGraphQl/etc/schema.graphqls b/app/code/Magento/SwatchesGraphQl/etc/schema.graphqls index bdd2631e7aa10..f986723a24545 100644 --- a/app/code/Magento/SwatchesGraphQl/etc/schema.graphqls +++ b/app/code/Magento/SwatchesGraphQl/etc/schema.graphqls @@ -26,4 +26,24 @@ type SwatchLayerFilterItem implements LayerFilterItemInterface, SwatchLayerFilte type SwatchData { type: String @doc(description: "Type of swatch filter item: 1 - text, 2 - image") value: String @doc(description: "Value for swatch item (text or image link)") +} + +type ConfigurableProductOptionsValues { + swatch_data: SwatchDataInterface @doc(description: "Swatch data for configurable product option") @resolver(class: "Magento\\SwatchesGraphQl\\Model\\Resolver\\Product\\Options\\SwatchData") +} + +interface SwatchDataInterface @typeResolver(class: "Magento\\SwatchesGraphQl\\Model\\Resolver\\Product\\Options\\SwatchDataTypeResolver") { + value: String @doc(description: "Value of swatch item (HEX color code, image link or textual value)") +} + +type ImageSwatchData implements SwatchDataInterface { + thumbnail: String @doc(description: "Thumbnail swatch image URL") +} + +type TextSwatchData implements SwatchDataInterface { + +} + +type ColorSwatchData implements SwatchDataInterface { + } \ No newline at end of file diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php index a6455a9728fec..3da51088f0af6 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php @@ -172,24 +172,25 @@ public function testCreateCustomerIfEmailMissed() } /** - * @expectedException \Exception - * @expectedExceptionMessage "Email" is not a valid email address. + * @dataProvider invalidEmailAddressDataProvider + * + * @param string $email + * @throws \Exception */ - public function testCreateCustomerIfEmailIsNotValid() + public function testCreateCustomerIfEmailIsNotValid(string $email) { - $newFirstname = 'Richard'; - $newLastname = 'Rowe'; - $currentPassword = 'test123#'; - $newEmail = 'email'; + $firstname = 'Richard'; + $lastname = 'Rowe'; + $password = 'test123#'; $query = <<expectExceptionMessage('"' . $email . '" is not a valid email address.'); $this->graphQlMutation($query); } + /** + * @return array + */ + public function invalidEmailAddressDataProvider(): array + { + return [ + ['plainaddress'], + ['jØrgen@somedomain.com'], + ['#@%^%#$@#$@#.com'], + ['@example.com'], + ['Joe Smith '], + ['email.example.com'], + ['email@example@example.com'], + ['email@example.com (Joe Smith)'], + ['email@example'], + ['“email”@example.com'], + ]; + } + /** * @expectedException \Exception * @expectedExceptionMessage Field "test123" is not defined by type CustomerInput. diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Swatches/ProductSwatchDataTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Swatches/ProductSwatchDataTest.php new file mode 100644 index 0000000000000..ab4e001e9d633 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Swatches/ProductSwatchDataTest.php @@ -0,0 +1,166 @@ +swatchMediaHelper = $objectManager->get(SwatchesMedia::class); + $this->imageUrlBuilder = $objectManager->get(UrlBuilder::class); + } + + /** + * @param string $productSku + * + * @return mixed + * @throws \PHPUnit\Framework\Exception + */ + private function getSwatchDataValues($productSku = 'configurable') + { + $query = <<graphQlQuery($query); + + $this->assertArrayHasKey('products', $response); + $this->assertArrayHasKey('items', $response['products']); + $this->assertArrayHasKey(0, $response['products']['items']); + + $product = $response['products']['items'][0]; + $this->assertArrayHasKey('configurable_options', $product); + $this->assertArrayHasKey(0, $product['configurable_options']); + + $option = $product['configurable_options'][0]; + $this->assertArrayHasKey('values', $option); + + return $option['values']; + } + + /** + * @magentoApiDataFixture Magento/Swatches/_files/visual_swatch_attribute_with_enabled_product_image_for_swatch.php + */ + public function testGetSwatchDataForVisualOptionsWithProductImage() + { + $productSku = 'configurable_12345'; + $productImage = '/m/a/magento_image.jpg'; + $swatchImageName = '/visual_swatch_attribute_option_type_image.jpg'; + $expectedValues = [ + 0 => [ + 'swatch_data' => [ + 'type' => 'IMAGE', + 'value' => $this->imageUrlBuilder->getUrl($productImage, Swatch::SWATCH_IMAGE_NAME), + 'thumbnail' => $this->imageUrlBuilder->getUrl($productImage, Swatch::SWATCH_THUMBNAIL_NAME), + ], + ], + 1 => [ + 'swatch_data' => [ + 'type' => 'IMAGE', + 'value' => $this->swatchMediaHelper->getSwatchAttributeImage(Swatch::SWATCH_IMAGE_NAME, $swatchImageName), + 'thumbnail' => $this->swatchMediaHelper->getSwatchAttributeImage(Swatch::SWATCH_THUMBNAIL_NAME, $swatchImageName), + ], + ], + 2 => [ + 'swatch_data' => NULL, + ], + ]; + + $values = $this->getSwatchDataValues($productSku); + $this->assertEquals($values, $expectedValues); + } + + /** + * @magentoApiDataFixture Magento/Swatches/_files/textual_swatch_attribute.php + * @magentoApiDataFixture Magento/ConfigurableProduct/_files/configurable_products.php + */ + public function testGetSwatchDataForTextualOptions() + { + $expectType = "TEXTUAL"; + $expectValue = "option 1"; + $expectThumbnail = null; + + $values = $this->getSwatchDataValues(); + $this->assertArrayHasKey(0, $values); + + $value = $values[0]; + $this->assertArrayHasKey('swatch_data', $value); + $this->assertEquals($expectType, $value['swatch_data']['type']); + $this->assertEquals($expectValue, $value['swatch_data']['value']); + $this->assertEquals($expectThumbnail, $value['swatch_data']['thumbnail']); + } + + /** + * @magentoApiDataFixture Magento/Swatches/_files/visual_swatch_attribute_with_different_options_type.php + * @magentoApiDataFixture Magento/ConfigurableProduct/_files/configurable_products.php + */ + public function testGetSwatchDataForVisualOptions() + { + $imageName = '/visual_swatch_attribute_option_type_image.jpg'; + $expectedValues = [ + 0 => [ + 'swatch_data' => [ + 'type' => 'COLOR', + 'value' => '#000000', + 'thumbnail' => NULL, + ], + ], + 1 => [ + 'swatch_data' => [ + 'type' => 'IMAGE', + 'value' => $this->swatchMediaHelper->getSwatchAttributeImage(Swatch::SWATCH_IMAGE_NAME, $imageName), + 'thumbnail' => $this->swatchMediaHelper->getSwatchAttributeImage(Swatch::SWATCH_THUMBNAIL_NAME, $imageName), + ], + ], + 2 => [ + 'swatch_data' => NULL, + ], + ]; + + $values = $this->getSwatchDataValues(); + $this->assertEquals($values, $expectedValues); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Swatches/_files/text_swatch_attribute_rollback.php b/dev/tests/integration/testsuite/Magento/Swatches/_files/text_swatch_attribute_rollback.php new file mode 100644 index 0000000000000..3b1810766c915 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Swatches/_files/text_swatch_attribute_rollback.php @@ -0,0 +1,23 @@ +get(\Magento\Framework\Registry::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute */ +$attribute = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class); + +$attribute->loadByCode(4, 'test_configurable'); + +if ($attribute->getId()) { + $attribute->delete(); +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Swatches/_files/textual_swatch_attribute.php b/dev/tests/integration/testsuite/Magento/Swatches/_files/textual_swatch_attribute.php new file mode 100644 index 0000000000000..26602d2b2e2f0 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Swatches/_files/textual_swatch_attribute.php @@ -0,0 +1,103 @@ +create(\Magento\Catalog\Setup\CategorySetup::class); +/** @var AttributeRepositoryInterface $attributeRepository */ +$attributeRepository = Bootstrap::getObjectManager()->create(AttributeRepositoryInterface::class); + +// Add attribute data +$data = [ + 'attribute_code' => 'test_configurable', + 'entity_type_id' => $installer->getEntityTypeId('catalog_product'), + 'is_global' => 1, + 'is_user_defined' => 1, + 'frontend_input' => 'select', + 'is_unique' => 0, + 'is_required' => 0, + 'is_searchable' => 0, + 'is_visible_in_advanced_search' => 0, + 'is_comparable' => 0, + 'is_filterable' => 0, + 'is_filterable_in_search' => 0, + 'is_used_for_promo_rules' => 0, + 'is_html_allowed_on_front' => 1, + 'is_visible_on_front' => 0, + 'used_in_product_listing' => 0, + 'used_for_sort_by' => 0, + 'frontend_label' => ['Test Configurable'], + 'backend_type' => 'int', +]; + +$optionsPerAttribute = 3; + +$data['frontend_input'] = 'select'; +$data['swatch_input_type'] = Swatch::SWATCH_INPUT_TYPE_TEXT; + +$data['swatchtext']['value'] = array_reduce( + range(1, $optionsPerAttribute), + function ($values, $index) use ($optionsPerAttribute) { + $values['option_' . $index] = ['option ' . $index]; + return $values; + }, + [] +); + +$data['optiontext']['value'] = array_reduce( + range(1, $optionsPerAttribute), + function ($values, $index) use ($optionsPerAttribute) { + $values['option_' . $index] = ['option ' . $index]; + return $values; + }, + [] +); + +$data['optiontext']['order'] = array_reduce( + range(1, $optionsPerAttribute), + function ($values, $index) use ($optionsPerAttribute) { + $values['option_' . $index] = $index; + return $values; + }, + [] +); + +$data['options']['option'] = array_reduce( + range(1, $optionsPerAttribute), + function ($values, $index) use ($optionsPerAttribute) { + $values[] = [ + 'label' => 'option ' . $index, + 'value' => 'option_' . $index, + ]; + return $values; + }, + [] +); + +$options = []; +foreach ($data['options']['option'] as $optionData) { + $options[] = Bootstrap::getObjectManager()->create(AttributeOptionInterface::class) + ->setLabel($optionData['label']) + ->setValue($optionData['value']); +} + +$attribute = Bootstrap::getObjectManager()->create( + ProductAttributeInterface::class, + ['data' => $data] +); + +$attribute->setOptions($options); +$attributeRepository->save($attribute); + +/* Assign attribute to attribute set */ +$installer->addAttributeToGroup('catalog_product', 'Default', 'General', $attribute->getId()); diff --git a/dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_different_options_type.php b/dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_different_options_type.php new file mode 100644 index 0000000000000..a4a755c4b92db --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_different_options_type.php @@ -0,0 +1,116 @@ +create(\Magento\Catalog\Setup\CategorySetup::class); +/** @var AttributeRepositoryInterface $attributeRepository */ +$attributeRepository = Bootstrap::getObjectManager()->create(AttributeRepositoryInterface::class); + +// Generate swatch image +/** @var ImagesGenerator $imagesGenerator */ +$imagesGenerator = Bootstrap::getObjectManager()->get(ImagesGenerator::class); +/** @var SwatchesMedia $swatchesMedia */ +$swatchesMedia = Bootstrap::getObjectManager()->get(SwatchesMedia::class); +$imageName = 'visual_swatch_attribute_option_type_image.jpg'; +$imagesGenerator->generate([ + 'image-width' => 110, + 'image-height' => 90, + 'image-name' => $imageName, +]); +$imagePath = substr($swatchesMedia->moveImageFromTmp($imageName), 1); +$swatchesMedia->generateSwatchVariations($imagePath); + +// Add attribute data +$data = [ + 'attribute_code' => 'test_configurable', + 'entity_type_id' => $installer->getEntityTypeId('catalog_product'), + 'is_global' => 1, + 'is_user_defined' => 1, + 'frontend_input' => 'select', + 'is_unique' => 0, + 'is_required' => 0, + 'is_searchable' => 0, + 'is_visible_in_advanced_search' => 0, + 'is_comparable' => 0, + 'is_filterable' => 0, + 'is_filterable_in_search' => 0, + 'is_used_for_promo_rules' => 0, + 'is_html_allowed_on_front' => 1, + 'is_visible_on_front' => 0, + 'used_in_product_listing' => 0, + 'used_for_sort_by' => 0, + 'frontend_label' => ['Test Configurable'], + 'backend_type' => 'int', +]; + +$optionsPerAttribute = 3; + +$data['frontend_input'] = 'select'; +$data['swatch_input_type'] = Swatch::SWATCH_INPUT_TYPE_VISUAL; + +$data['swatchvisual']['value'] = [ + 'option_1' => '#000000', // HEX color (color type) + 'option_2' => $imagePath, // image path (image type) + 'option_3' => null, // null (empty type) +]; + +$data['optionvisual']['value'] = array_reduce( + range(1, $optionsPerAttribute), + function ($values, $index) use ($optionsPerAttribute) { + $values['option_' . $index] = ['option ' . $index]; + return $values; + }, + [] +); + +$data['optionvisual']['order'] = array_reduce( + range(1, $optionsPerAttribute), + function ($values, $index) use ($optionsPerAttribute) { + $values['option_' . $index] = $index; + return $values; + }, + [] +); + +$data['options']['option'] = array_reduce( + range(1, $optionsPerAttribute), + function ($values, $index) use ($optionsPerAttribute) { + $values[] = [ + 'label' => 'option ' . $index, + 'value' => 'option_' . $index, + ]; + return $values; + }, + [] +); + +$options = []; +foreach ($data['options']['option'] as $optionData) { + $options[] = Bootstrap::getObjectManager()->create(AttributeOptionInterface::class) + ->setLabel($optionData['label']) + ->setValue($optionData['value']); +} + +$attribute = Bootstrap::getObjectManager()->create( + ProductAttributeInterface::class, + ['data' => $data] +); + +$attribute->setOptions($options); +$attributeRepository->save($attribute); + +/* Assign attribute to attribute set */ +$installer->addAttributeToGroup('catalog_product', 'Default', 'General', $attribute->getId()); diff --git a/dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_different_options_type_rollback.php b/dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_different_options_type_rollback.php new file mode 100644 index 0000000000000..ef1db34708fb3 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_different_options_type_rollback.php @@ -0,0 +1,34 @@ +get(Filesystem::class) + ->getDirectoryWrite( + DirectoryList::MEDIA + ); + +/** @var SwatchesMedia $swatchesMedia */ +$swatchesMedia = Bootstrap::getObjectManager()->get(SwatchesMedia::class); + +$testImageName = 'visual_swatch_attribute_option_type_image.jpg'; +$testImageSwatchPath = $swatchesMedia->getAttributeSwatchPath($testImageName); +$mediaDirectory->delete($testImageSwatchPath); + +$imageConfig = $swatchesMedia->getImageConfig(); +$swatchTypes = ['swatch_image', 'swatch_thumb']; + +foreach ($swatchTypes as $swatchType) { + $absolutePath = $mediaDirectory->getAbsolutePath($swatchesMedia->getSwatchCachePath($swatchType)); + $swatchTypePath = $absolutePath . $swatchesMedia->getFolderNameSize($swatchType, $imageConfig) . '/' . $testImageName; + $mediaDirectory->delete($swatchTypePath); +} diff --git a/dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_enabled_product_image_for_swatch.php b/dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_enabled_product_image_for_swatch.php new file mode 100644 index 0000000000000..0e171094516ba --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_enabled_product_image_for_swatch.php @@ -0,0 +1,35 @@ +setData('use_product_image_for_swatch', 1); +$attributeRepository->save($attribute); + +// get first child and set image +$childrenProducts = $product->getTypeInstance()->getUsedProducts($product); +/** @var Product $firstChildSimpleProduct */ +$firstChildSimpleProduct = array_shift($childrenProducts); +$firstChildSimpleProduct + ->setImage('/m/a/magento_image.jpg') + ->setSmallImage('/m/a/magento_image.jpg') + ->setThumbnail('/m/a/magento_image.jpg') + ->setData('media_gallery', ['images' => [ + [ + 'file' => '/m/a/magento_image.jpg', + 'position' => 1, + 'label' => 'Image Alt Text', + 'disabled' => 0, + 'media_type' => 'image' + ], + ]]) + ->save(); diff --git a/dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_enabled_product_image_for_swatch_rollback.php b/dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_enabled_product_image_for_swatch_rollback.php new file mode 100644 index 0000000000000..c708971326162 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_enabled_product_image_for_swatch_rollback.php @@ -0,0 +1,11 @@ + Date: Thu, 2 Jan 2020 11:56:13 -0600 Subject: [PATCH 2/4] Forward-port magento/graphql-ce#443 and magento/graphql-ce#1073 --- .../DataProvider/SwatchDataProvider.php | 208 +----------------- .../Resolver/Product/Options/SwatchData.php | 8 +- .../Options/SwatchDataTypeResolver.php | 9 +- .../SwatchesGraphQl/etc/schema.graphqls | 2 +- .../Swatches/ProductSwatchDataTest.php | 145 +++++------- ...e_with_different_options_type_rollback.php | 5 +- ...bled_product_image_for_swatch_rollback.php | 1 - 7 files changed, 75 insertions(+), 303 deletions(-) diff --git a/app/code/Magento/SwatchesGraphQl/Model/Resolver/Product/Options/DataProvider/SwatchDataProvider.php b/app/code/Magento/SwatchesGraphQl/Model/Resolver/Product/Options/DataProvider/SwatchDataProvider.php index 9e62ae928fb53..e7cd4c567da7f 100644 --- a/app/code/Magento/SwatchesGraphQl/Model/Resolver/Product/Options/DataProvider/SwatchDataProvider.php +++ b/app/code/Magento/SwatchesGraphQl/Model/Resolver/Product/Options/DataProvider/SwatchDataProvider.php @@ -7,18 +7,12 @@ namespace Magento\SwatchesGraphQl\Model\Resolver\Product\Options\DataProvider; -use Magento\Catalog\Api\Data\ProductInterface; -use Magento\Catalog\Model\Product\Image\UrlBuilder; -use Magento\Framework\Exception\LocalizedException; -use Magento\Framework\Exception\NoSuchEntityException; -use Magento\Framework\Exception\RuntimeException; -use Magento\Framework\GraphQl\Query\EnumLookup; use Magento\Swatches\Helper\Data as SwatchData; use Magento\Swatches\Helper\Media as SwatchesMedia; use Magento\Swatches\Model\Swatch; /** - * Swatch data provider + * Data provider for options swatches. */ class SwatchDataProvider { @@ -32,219 +26,41 @@ class SwatchDataProvider */ private $swatchMediaHelper; - /** - * @var UrlBuilder - */ - private $imageUrlBuilder; - - /** - * @var EnumLookup - */ - private $enumLookup; - /** * SwatchDataProvider constructor. * * @param SwatchData $swatchHelper * @param SwatchesMedia $swatchMediaHelper - * @param UrlBuilder $imageUrlBuilder - * @param EnumLookup $enumLookup */ public function __construct( SwatchData $swatchHelper, - SwatchesMedia $swatchMediaHelper, - UrlBuilder $imageUrlBuilder, - EnumLookup $enumLookup + SwatchesMedia $swatchMediaHelper ) { $this->swatchHelper = $swatchHelper; $this->swatchMediaHelper = $swatchMediaHelper; - $this->imageUrlBuilder = $imageUrlBuilder; - $this->enumLookup = $enumLookup; } /** - * Get swatch data + * Returns swatch data by option ID. * * @param string $optionId - * @param ProductInterface $product - * - * @return array - * - * @throws LocalizedException - * @throws NoSuchEntityException - * @throws \LogicException + * @return array|null */ - public function getData(string $optionId, ProductInterface $product): array + public function getData(string $optionId): ?array { $swatches = $this->swatchHelper->getSwatchesByOptionsId([$optionId]); - if (!isset($swatches[$optionId], $swatches[$optionId]['type'], $swatches[$optionId]['value'])) { + if (!isset($swatches[$optionId]['type'], $swatches[$optionId]['value'])) { return null; } - $type = (int)$swatches[$optionId]['type']; $value = $swatches[$optionId]['value']; - $thumbnail = null; - - // change value & thumbnail if type is 'visual' + $data = ['value' => $value, 'type' => $type]; if ($type === Swatch::SWATCH_TYPE_VISUAL_IMAGE) { - $thumbnail = $this->swatchMediaHelper->getSwatchAttributeImage(Swatch::SWATCH_THUMBNAIL_NAME, $value); - $value = $this->swatchMediaHelper->getSwatchAttributeImage(Swatch::SWATCH_IMAGE_NAME, $value); + $data['thumbnail'] = $this->swatchMediaHelper->getSwatchAttributeImage( + Swatch::SWATCH_THUMBNAIL_NAME, + $value + ); } - - $attributeData = $this->getSwatchAttributeDataByOptionId($product, $optionId); - // check if swatch value should be getting from related product image - if (!$this->isUseProductImageForSwatch($attributeData)) { - return $this->getResultArray($value, $type, $thumbnail); - } - - // get product with existing image - $variationProduct = $this->getVariationProduct($attributeData, $optionId, $product); - if (null === $variationProduct) { - return $this->getResultArray($value, $type, $thumbnail); - } - - // set 'visual' type, because the product image is using as swatch value - $type = Swatch::SWATCH_TYPE_VISUAL_IMAGE; - - // get image from child product - $productImage = $this->getSwatchProductImage($variationProduct, Swatch::SWATCH_IMAGE_NAME); - if (null !== $productImage) { - $value = $productImage; - } - - // get thumbnail from child product - $productThumbnail = $this->getSwatchProductImage($variationProduct, Swatch::SWATCH_THUMBNAIL_NAME); - if (null !== $productThumbnail) { - $thumbnail = $productThumbnail; - } - - return $this->getResultArray($value, $type, $thumbnail); - } - - /** - * Get result array - * - * @param string $value - * @param int $type - * @param null|string $thumbnail - * - * @return array - * - * @throws RuntimeException - */ - private function getResultArray(string $value, int $type, ?string $thumbnail) - { - return [ - 'value' => $value, - 'type' => $this->enumLookup->getEnumValueFromField('SwatchTypeEnum', (string)$type), - 'thumbnail' => $thumbnail - ]; - } - - /** - * Is swatch images should be getting from related simple products - * - * @param array $attributeData - * - * @return bool - */ - private function isUseProductImageForSwatch(array $attributeData) : bool - { - return isset($attributeData['use_product_image_for_swatch']) && $attributeData['use_product_image_for_swatch']; - } - - /** - * Get simple product with first variation swatch image or image - * - * @param array $attributeData - * @param string $optionId - * @param ProductInterface $product - * - * @return ProductInterface|null - */ - private function getVariationProduct(array $attributeData, string $optionId, ProductInterface $product) : ?ProductInterface - { - $attributeCode = $attributeData['attribute_code']; - $requiredAttributes = [ - $attributeCode => $optionId - ]; - - $variationProduct = $this->swatchHelper->loadFirstVariationWithSwatchImage($product, $requiredAttributes); - if ($variationProduct instanceof ProductInterface) { - return $variationProduct; - } - - $variationProduct = $this->swatchHelper->loadFirstVariationWithImage($product, $requiredAttributes); - if ($variationProduct instanceof ProductInterface) { - return $variationProduct; - } - - return null; - } - - /** - * Get swatch product image - * - * @param ProductInterface $product - * @param string $imageType - * - * @return string|null - */ - private function getSwatchProductImage(ProductInterface $product, $imageType) : ?string - { - if ($this->isProductHasImage($product, Swatch::SWATCH_IMAGE_NAME)) { - $swatchImageId = $imageType; - $imageAttributes = ['type' => Swatch::SWATCH_IMAGE_NAME]; - } elseif ($this->isProductHasImage($product, 'image')) { - $swatchImageId = $imageType == Swatch::SWATCH_IMAGE_NAME ? 'swatch_image_base' : 'swatch_thumb_base'; - $imageAttributes = ['type' => 'image']; - } - - if (empty($swatchImageId) || empty($imageAttributes['type'])) { - return null; - } - - return $this->imageUrlBuilder->getUrl($product->getData($imageAttributes['type']), $swatchImageId); - } - - /** - * Is product has image - * - * @param ProductInterface $product - * @param string $imageType - * - * @return bool - */ - private function isProductHasImage(ProductInterface $product, string $imageType) : bool - { - return $product->getData($imageType) !== null && $product->getData($imageType) != SwatchData::EMPTY_IMAGE_VALUE; - } - - /** - * Get swatch attribute data by option id - * - * @param ProductInterface $product - * @param string $optionId - * - * @return array - * - * @throws LocalizedException - * @throws \LogicException - * @throws NoSuchEntityException - */ - private function getSwatchAttributeDataByOptionId(ProductInterface $product, string $optionId) : array - { - $attributesData = $this->swatchHelper->getSwatchAttributesAsArray($product); - foreach ($attributesData as $attributeData) { - if (!isset($attributeData['options']) || !is_array($attributeData['options'])) { - continue; - } - - if (array_key_exists($optionId, $attributeData['options'])) { - return $attributeData; - } - } - - throw new LocalizedException(__(sprintf('Cannot find the attribute with option id "%1".', $optionId))); + return $data; } } diff --git a/app/code/Magento/SwatchesGraphQl/Model/Resolver/Product/Options/SwatchData.php b/app/code/Magento/SwatchesGraphQl/Model/Resolver/Product/Options/SwatchData.php index 9fea3b3ff59e5..980f779e8e9f6 100644 --- a/app/code/Magento/SwatchesGraphQl/Model/Resolver/Product/Options/SwatchData.php +++ b/app/code/Magento/SwatchesGraphQl/Model/Resolver/Product/Options/SwatchData.php @@ -7,8 +7,6 @@ namespace Magento\SwatchesGraphQl\Model\Resolver\Product\Options; -use Magento\Catalog\Api\Data\ProductInterface; -use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; @@ -47,10 +45,6 @@ public function resolve( array $value = null, array $args = null ) { - if (!array_key_exists('model', $value) || !$value['model'] instanceof ProductInterface) { - throw new LocalizedException(__('"model" value should be specified')); - } - - return $this->swatchDataProvider->getData($value['value_index'], $value['model']); + return $this->swatchDataProvider->getData($value['value_index']); } } diff --git a/app/code/Magento/SwatchesGraphQl/Model/Resolver/Product/Options/SwatchDataTypeResolver.php b/app/code/Magento/SwatchesGraphQl/Model/Resolver/Product/Options/SwatchDataTypeResolver.php index 96f584524fd27..add6f7123b921 100644 --- a/app/code/Magento/SwatchesGraphQl/Model/Resolver/Product/Options/SwatchDataTypeResolver.php +++ b/app/code/Magento/SwatchesGraphQl/Model/Resolver/Product/Options/SwatchDataTypeResolver.php @@ -7,6 +7,7 @@ namespace Magento\SwatchesGraphQl\Model\Resolver\Product\Options; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Query\Resolver\TypeResolverInterface; use Magento\Swatches\Model\Swatch; @@ -16,19 +17,19 @@ class SwatchDataTypeResolver implements TypeResolverInterface { /** - * {@inheritdoc} + * @inheritdoc */ public function resolveType(array $data): string { switch ($data['type']) { case Swatch::SWATCH_TYPE_TEXTUAL: return 'TextSwatchData'; - case Swatch::SWATCH_TYPE_VISUAL_COLOR; + case Swatch::SWATCH_TYPE_VISUAL_COLOR: return 'ColorSwatchData'; - case Swatch::SWATCH_TYPE_VISUAL_IMAGE; + case Swatch::SWATCH_TYPE_VISUAL_IMAGE: return 'ImageSwatchData'; default: - return ''; + throw new LocalizedException(__('Unsupported swatch type')); } } } diff --git a/app/code/Magento/SwatchesGraphQl/etc/schema.graphqls b/app/code/Magento/SwatchesGraphQl/etc/schema.graphqls index f986723a24545..c51468ccd2856 100644 --- a/app/code/Magento/SwatchesGraphQl/etc/schema.graphqls +++ b/app/code/Magento/SwatchesGraphQl/etc/schema.graphqls @@ -46,4 +46,4 @@ type TextSwatchData implements SwatchDataInterface { type ColorSwatchData implements SwatchDataInterface { -} \ No newline at end of file +} diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Swatches/ProductSwatchDataTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Swatches/ProductSwatchDataTest.php index ab4e001e9d633..c356012c71f47 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Swatches/ProductSwatchDataTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Swatches/ProductSwatchDataTest.php @@ -7,14 +7,13 @@ namespace Magento\GraphQl\Swatches; -use Magento\Catalog\Model\Product\Image\UrlBuilder; use Magento\Swatches\Helper\Media as SwatchesMedia; use Magento\Swatches\Model\Swatch; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\GraphQlAbstract; /** - * Class ProductSwatchDataTest + * Test for configurable product option swatch data */ class ProductSwatchDataTest extends GraphQlAbstract { @@ -23,11 +22,6 @@ class ProductSwatchDataTest extends GraphQlAbstract */ private $swatchMediaHelper; - /** - * @var UrlBuilder - */ - private $imageUrlBuilder; - /** * @inheritdoc */ @@ -35,28 +29,24 @@ protected function setUp() { $objectManager = Bootstrap::getObjectManager(); $this->swatchMediaHelper = $objectManager->get(SwatchesMedia::class); - $this->imageUrlBuilder = $objectManager->get(UrlBuilder::class); } /** - * @param string $productSku - * - * @return mixed - * @throws \PHPUnit\Framework\Exception + * @magentoApiDataFixture Magento/Swatches/_files/text_swatch_attribute.php + * @magentoApiDataFixture Magento/ConfigurableProduct/_files/configurable_products.php */ - private function getSwatchDataValues($productSku = 'configurable') + public function testTextSwatchDataValues() { + $productSku = 'configurable'; $query = <<assertArrayHasKey('values', $option); - - return $option['values']; - } - - /** - * @magentoApiDataFixture Magento/Swatches/_files/visual_swatch_attribute_with_enabled_product_image_for_swatch.php - */ - public function testGetSwatchDataForVisualOptionsWithProductImage() - { - $productSku = 'configurable_12345'; - $productImage = '/m/a/magento_image.jpg'; - $swatchImageName = '/visual_swatch_attribute_option_type_image.jpg'; - $expectedValues = [ - 0 => [ - 'swatch_data' => [ - 'type' => 'IMAGE', - 'value' => $this->imageUrlBuilder->getUrl($productImage, Swatch::SWATCH_IMAGE_NAME), - 'thumbnail' => $this->imageUrlBuilder->getUrl($productImage, Swatch::SWATCH_THUMBNAIL_NAME), - ], - ], - 1 => [ - 'swatch_data' => [ - 'type' => 'IMAGE', - 'value' => $this->swatchMediaHelper->getSwatchAttributeImage(Swatch::SWATCH_IMAGE_NAME, $swatchImageName), - 'thumbnail' => $this->swatchMediaHelper->getSwatchAttributeImage(Swatch::SWATCH_THUMBNAIL_NAME, $swatchImageName), - ], - ], - 2 => [ - 'swatch_data' => NULL, - ], - ]; - - $values = $this->getSwatchDataValues($productSku); - $this->assertEquals($values, $expectedValues); - } - - /** - * @magentoApiDataFixture Magento/Swatches/_files/textual_swatch_attribute.php - * @magentoApiDataFixture Magento/ConfigurableProduct/_files/configurable_products.php - */ - public function testGetSwatchDataForTextualOptions() - { - $expectType = "TEXTUAL"; - $expectValue = "option 1"; - $expectThumbnail = null; - - $values = $this->getSwatchDataValues(); - $this->assertArrayHasKey(0, $values); - - $value = $values[0]; - $this->assertArrayHasKey('swatch_data', $value); - $this->assertEquals($expectType, $value['swatch_data']['type']); - $this->assertEquals($expectValue, $value['swatch_data']['value']); - $this->assertEquals($expectThumbnail, $value['swatch_data']['thumbnail']); + $length = count($option['values']); + for ($i = 0; $i < $length; $i++) { + $this->assertEquals('option ' . ($i + 1), $option['values'][$i]['swatch_data']['value']); + } } /** * @magentoApiDataFixture Magento/Swatches/_files/visual_swatch_attribute_with_different_options_type.php * @magentoApiDataFixture Magento/ConfigurableProduct/_files/configurable_products.php */ - public function testGetSwatchDataForVisualOptions() + public function testVisualSwatchDataValues() { + $productSku = 'configurable'; $imageName = '/visual_swatch_attribute_option_type_image.jpg'; - $expectedValues = [ - 0 => [ - 'swatch_data' => [ - 'type' => 'COLOR', - 'value' => '#000000', - 'thumbnail' => NULL, - ], - ], - 1 => [ - 'swatch_data' => [ - 'type' => 'IMAGE', - 'value' => $this->swatchMediaHelper->getSwatchAttributeImage(Swatch::SWATCH_IMAGE_NAME, $imageName), - 'thumbnail' => $this->swatchMediaHelper->getSwatchAttributeImage(Swatch::SWATCH_THUMBNAIL_NAME, $imageName), - ], - ], - 2 => [ - 'swatch_data' => NULL, - ], - ]; + $color = '#000000'; + $query = <<graphQlQuery($query); + + $this->assertArrayHasKey('products', $response); + $this->assertArrayHasKey('items', $response['products']); + $this->assertArrayHasKey(0, $response['products']['items']); - $values = $this->getSwatchDataValues(); - $this->assertEquals($values, $expectedValues); + $product = $response['products']['items'][0]; + $this->assertArrayHasKey('configurable_options', $product); + $this->assertArrayHasKey(0, $product['configurable_options']); + + $option = $product['configurable_options'][0]; + $this->assertArrayHasKey('values', $option); + $this->assertEquals($color, $option['values'][0]['swatch_data']['value']); + $this->assertContains( + $option['values'][1]['swatch_data']['value'], + $this->swatchMediaHelper->getSwatchAttributeImage(Swatch::SWATCH_IMAGE_NAME, $imageName) + ); + $this->assertEquals( + $option['values'][1]['swatch_data']['thumbnail'], + $this->swatchMediaHelper->getSwatchAttributeImage(Swatch::SWATCH_THUMBNAIL_NAME, $imageName) + ); } } diff --git a/dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_different_options_type_rollback.php b/dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_different_options_type_rollback.php index ef1db34708fb3..7f9328368464e 100644 --- a/dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_different_options_type_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_different_options_type_rollback.php @@ -29,6 +29,7 @@ foreach ($swatchTypes as $swatchType) { $absolutePath = $mediaDirectory->getAbsolutePath($swatchesMedia->getSwatchCachePath($swatchType)); - $swatchTypePath = $absolutePath . $swatchesMedia->getFolderNameSize($swatchType, $imageConfig) . '/' . $testImageName; + $swatchTypePath = $absolutePath . $swatchesMedia->getFolderNameSize($swatchType, $imageConfig) . + '/' . $testImageName; $mediaDirectory->delete($swatchTypePath); -} +} \ No newline at end of file diff --git a/dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_enabled_product_image_for_swatch_rollback.php b/dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_enabled_product_image_for_swatch_rollback.php index c708971326162..85c02049a992a 100644 --- a/dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_enabled_product_image_for_swatch_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_enabled_product_image_for_swatch_rollback.php @@ -8,4 +8,3 @@ require __DIR__ . '/visual_swatch_attribute_with_different_options_type_rollback.php'; require __DIR__ . '/../../../Magento/ConfigurableProduct/_files/configurable_products_rollback.php'; require __DIR__ . '/../../../Magento/Catalog/_files/product_image_rollback.php'; - From aba1a24ee2146a85c6728fba78ee9c701792a40c Mon Sep 17 00:00:00 2001 From: Lena Orobei Date: Thu, 2 Jan 2020 12:51:42 -0600 Subject: [PATCH 3/4] Forward-port magento/graphql-ce#443 and magento/graphql-ce#1073 --- ...al_swatch_attribute_with_different_options_type_rollback.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_different_options_type_rollback.php b/dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_different_options_type_rollback.php index 7f9328368464e..c480906619a4a 100644 --- a/dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_different_options_type_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Swatches/_files/visual_swatch_attribute_with_different_options_type_rollback.php @@ -32,4 +32,4 @@ $swatchTypePath = $absolutePath . $swatchesMedia->getFolderNameSize($swatchType, $imageConfig) . '/' . $testImageName; $mediaDirectory->delete($swatchTypePath); -} \ No newline at end of file +} From 837675cf7299be85b90f8640166c7b8001e2d835 Mon Sep 17 00:00:00 2001 From: Lena Orobei Date: Fri, 3 Jan 2020 11:41:34 -0600 Subject: [PATCH 4/4] Forward-port magento/graphql-ce#443 and magento/graphql-ce#1073 --- .../{textual_swatch_attribute.php => text_swatch_attribute.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename dev/tests/integration/testsuite/Magento/Swatches/_files/{textual_swatch_attribute.php => text_swatch_attribute.php} (100%) diff --git a/dev/tests/integration/testsuite/Magento/Swatches/_files/textual_swatch_attribute.php b/dev/tests/integration/testsuite/Magento/Swatches/_files/text_swatch_attribute.php similarity index 100% rename from dev/tests/integration/testsuite/Magento/Swatches/_files/textual_swatch_attribute.php rename to dev/tests/integration/testsuite/Magento/Swatches/_files/text_swatch_attribute.php