Skip to content

Commit fb2f1a7

Browse files
authored
Merge pull request #6524 from magento-tsg/2.4-develop-pr120
[Arrows] Fixes for 2.4 (pr120) (2.4-develop)
2 parents 3b860f5 + 0f69efe commit fb2f1a7

File tree

42 files changed

+1398
-118
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1398
-118
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="AdminToggleSwitchDynamicPriceOnProductEditPageActionGroup">
12+
<waitForElementVisible selector="{{AdminProductFormBundleSection.dynamicPriceToggle}}" stepKey="waitForToggleDynamicPrice"/>
13+
<checkOption selector="{{AdminProductFormBundleSection.dynamicPriceToggle}}" stepKey="switchDynamicPriceToggle"/>
14+
</actionGroup>
15+
</actionGroups>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<!-- Test XML Example -->
9+
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
10+
<test name="AdminBundleProductPriceValidationErrorDisappearedAfterSwitchToDynamicPriceTest">
11+
<annotations>
12+
<features value="Bundle"/>
13+
<stories value="Create/Edit bundle product in Admin"/>
14+
<title value="Assert error message for price field"/>
15+
<description value="Verify error message for price field is not visible when toggle Dynamic Price is disabled"/>
16+
<severity value="MAJOR"/>
17+
<testCaseId value="MC-40309"/>
18+
<useCaseId value="MC-30152"/>
19+
<group value="bundle"/>
20+
</annotations>
21+
22+
<before>
23+
<actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/>
24+
</before>
25+
<after>
26+
<actionGroup ref="AdminLogoutActionGroup" stepKey="logoutFromAdmin"/>
27+
</after>
28+
29+
<actionGroup ref="AdminOpenNewProductFormPageActionGroup" stepKey="openNewBundleProductPage">
30+
<argument name="productType" value="bundle"/>
31+
</actionGroup>
32+
<actionGroup ref="AdminToggleSwitchDynamicPriceOnProductEditPageActionGroup" stepKey="disableDynamicPrice"/>
33+
<actionGroup ref="AdminFillProductPriceFieldAndPressEnterOnProductEditPageActionGroup" stepKey="fillProductPriceField">
34+
<argument name="price" value="test"/>
35+
</actionGroup>
36+
<actionGroup ref="AssertAdminValidationErrorAppearedForPriceFieldOnProductEditPageActionGroup" stepKey="assertVisibleError">
37+
<argument name="errorMessage" value="Please enter a number 0 or greater in this field."/>
38+
</actionGroup>
39+
<actionGroup ref="AdminToggleSwitchDynamicPriceOnProductEditPageActionGroup" stepKey="enableDynamicPrice"/>
40+
<actionGroup ref="AssertAdminNoValidationErrorForPriceFieldOnProductEditPageActionGroup" stepKey="assertNotVisibleError"/>
41+
</test>
42+
</tests>

app/code/Magento/Catalog/Model/ProductOptionProcessor.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,15 @@ private function getUrlBuilder()
152152
*/
153153
private function isDateWithDateInternal(array $optionValue): bool
154154
{
155-
return array_key_exists('date_internal', $optionValue) && array_key_exists('date', $optionValue);
155+
$hasDate = !empty($optionValue['day'])
156+
&& !empty($optionValue['month'])
157+
&& !empty($optionValue['year']);
158+
159+
$hasTime = !empty($optionValue['hour'])
160+
&& isset($optionValue['minute']);
161+
162+
$hasDateInternal = !empty($optionValue['date_internal']);
163+
164+
return $hasDateInternal && ($hasDate || $hasTime || !empty($optionValue['date']));
156165
}
157166
}

app/code/Magento/Catalog/Model/ProductRepository.php

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Magento\Framework\Api\ImageContentValidatorInterface;
1818
use Magento\Framework\Api\ImageProcessorInterface;
1919
use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface;
20+
use Magento\Framework\Api\SearchCriteriaInterface;
2021
use Magento\Framework\DB\Adapter\ConnectionException;
2122
use Magento\Framework\DB\Adapter\DeadlockException;
2223
use Magento\Framework\DB\Adapter\LockWaitException;
@@ -28,6 +29,8 @@
2829
use Magento\Framework\Exception\StateException;
2930
use Magento\Framework\Exception\TemporaryState\CouldNotSaveException as TemporaryCouldNotSaveException;
3031
use Magento\Framework\Exception\ValidatorException;
32+
use Magento\Store\Model\Store;
33+
use Magento\Catalog\Api\Data\EavAttributeInterface;
3134

3235
/**
3336
* @inheritdoc
@@ -514,9 +517,12 @@ public function save(ProductInterface $product, $saveOptions = false)
514517
{
515518
$assignToCategories = false;
516519
$tierPrices = $product->getData('tier_price');
520+
$productDataToChange = $product->getData();
517521

518522
try {
519-
$existingProduct = $product->getId() ? $this->getById($product->getId()) : $this->get($product->getSku());
523+
$existingProduct = $product->getId() ?
524+
$this->getById($product->getId()) :
525+
$this->get($product->getSku());
520526

521527
$product->setData(
522528
$this->resourceModel->getLinkField(),
@@ -548,7 +554,6 @@ public function save(ProductInterface $product, $saveOptions = false)
548554
$productDataArray['store_id'] = (int) $this->storeManager->getStore()->getId();
549555
}
550556
$product = $this->initializeProductData($productDataArray, empty($existingProduct));
551-
552557
$this->processLinks($product, $productLinks);
553558
if (isset($productDataArray['media_gallery'])) {
554559
$this->processMediaGallery($product, $productDataArray['media_gallery']['images']);
@@ -569,6 +574,42 @@ public function save(ProductInterface $product, $saveOptions = false)
569574
$product->setData('tier_price', $tierPrices);
570575
}
571576

577+
try {
578+
$stores = $product->getStoreIds();
579+
$websites = $product->getWebsiteIds();
580+
} catch (NoSuchEntityException $exception) {
581+
$stores = null;
582+
$websites = null;
583+
}
584+
585+
if (!empty($existingProduct) && is_array($stores) && is_array($websites)) {
586+
$hasDataChanged = false;
587+
$productAttributes = $product->getAttributes();
588+
if ($productAttributes !== null
589+
&& $product->getStoreId() !== Store::DEFAULT_STORE_ID
590+
&& (count($stores) > 1 || count($websites) === 1)
591+
) {
592+
foreach ($productAttributes as $attribute) {
593+
$attributeCode = $attribute->getAttributeCode();
594+
$value = $product->getData($attributeCode);
595+
if ($existingProduct->getData($attributeCode) === $value
596+
&& $attribute->getScope() !== EavAttributeInterface::SCOPE_GLOBAL_TEXT
597+
&& !is_array($value)
598+
&& $attribute->getData('frontend_input') !== 'media_image'
599+
&& !$attribute->isStatic()
600+
&& !array_key_exists($attributeCode, $productDataToChange)
601+
&& $value !== null
602+
) {
603+
$product->setData($attributeCode);
604+
$hasDataChanged = true;
605+
}
606+
}
607+
if ($hasDataChanged) {
608+
$product->setData('_edit_mode', true);
609+
}
610+
}
611+
}
612+
572613
$this->saveProduct($product);
573614
if ($assignToCategories === true && $product->getCategoryIds()) {
574615
$this->linkManagement->assignProductToCategories(
@@ -619,7 +660,7 @@ public function deleteById($sku)
619660
/**
620661
* @inheritdoc
621662
*/
622-
public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria)
663+
public function getList(SearchCriteriaInterface $searchCriteria)
623664
{
624665
/** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $collection */
625666
$collection = $this->collectionFactory->create();
@@ -628,6 +669,7 @@ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCr
628669
$collection->addAttributeToSelect('*');
629670
$collection->joinAttribute('status', 'catalog_product/status', 'entity_id', null, 'inner');
630671
$collection->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner');
672+
$this->joinPositionField($collection, $searchCriteria);
631673

632674
$this->collectionProcessor->process($searchCriteria, $collection);
633675

@@ -856,4 +898,36 @@ private function saveProduct($product): void
856898
);
857899
}
858900
}
901+
902+
/**
903+
* Join category position field to make sorting by position possible.
904+
*
905+
* @param Collection $collection
906+
* @param SearchCriteriaInterface $searchCriteria
907+
* @return void
908+
*/
909+
private function joinPositionField(
910+
Collection $collection,
911+
SearchCriteriaInterface $searchCriteria
912+
): void {
913+
$categoryIds = [[]];
914+
foreach ($searchCriteria->getFilterGroups() as $filterGroup) {
915+
foreach ($filterGroup->getFilters() as $filter) {
916+
if ($filter->getField() === 'category_id') {
917+
$categoryIds[] = explode(',', $filter->getValue());
918+
}
919+
}
920+
}
921+
$categoryIds = array_unique(array_merge(...$categoryIds));
922+
if (count($categoryIds) === 1) {
923+
$collection->joinField(
924+
'position',
925+
'catalog_category_product',
926+
'position',
927+
'product_id=entity_id',
928+
['category_id' => current($categoryIds)],
929+
'left'
930+
);
931+
}
932+
}
859933
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="AdminFillProductPriceFieldAndPressEnterOnProductEditPageActionGroup">
12+
<arguments>
13+
<argument name="price" type="string"/>
14+
</arguments>
15+
16+
<waitForElementVisible selector="{{AdminProductFormSection.productPrice}}" stepKey="waitForPriceField"/>
17+
<fillField selector="{{AdminProductFormSection.productPrice}}" userInput="{{price}}" stepKey="fillPriceField"/>
18+
<pressKey selector="{{AdminProductFormSection.productPrice}}" parameterArray="[\Facebook\WebDriver\WebDriverKeys::ENTER]" stepKey="pressEnterButton"/>
19+
</actionGroup>
20+
</actionGroups>

app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminOpenProductImagesSectionActionGroup.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
<description>Requires the navigation to the Product page. Opens 'Image and Videos' section.</description>
1414
</annotations>
1515
<conditionalClick selector="{{AdminProductImagesSection.productImagesToggle}}" dependentSelector="{{AdminProductImagesSection.imageUploadButton}}" visible="false" stepKey="openProductImagesSection"/>
16+
<scrollTo selector="{{AdminProductImagesSection.productImagesToggle}}" stepKey="scrollToProductImagesSection"/>
17+
<waitForPageLoad stepKey="waitForLoadingMediaContent"/>
1618
<waitForElementVisible selector="{{AdminProductImagesSection.imageUploadButton}}" stepKey="waitForImageUploadButton"/>
1719
</actionGroup>
1820
</actionGroups>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="AssertAdminNoValidationErrorForPriceFieldOnProductEditPageActionGroup">
12+
<dontSeeElement selector="{{AdminProductFormSection.priceFieldError}}" stepKey="dontSeeValidationError"/>
13+
</actionGroup>
14+
</actionGroups>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="AssertAdminValidationErrorAppearedForPriceFieldOnProductEditPageActionGroup">
12+
<arguments>
13+
<argument name="errorMessage" type="string" defaultValue="This is a required field."/>
14+
</arguments>
15+
16+
<waitForElementVisible selector="{{AdminProductFormSection.priceFieldError}}" stepKey="waitForValidationError"/>
17+
<see selector="{{AdminProductFormSection.priceFieldError}}" userInput="{{errorMessage}}" stepKey="seeElementValidationError"/>
18+
</actionGroup>
19+
</actionGroups>

app/code/Magento/Catalog/Test/Mftf/Page/StorefrontCategoryPage.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@
1111
<page name="StorefrontCategoryPage" url="/{{var1}}.html" area="storefront" module="Magento_Catalog" parameterized="true">
1212
<section name="StorefrontCategoryMainSection"/>
1313
<section name="WYSIWYGToolbarSection"/>
14+
<section name="StorefrontCategoryProductSection"/>
1415
</page>
1516
</pages>

0 commit comments

Comments
 (0)