Skip to content

Commit bc60bdd

Browse files
Merge branch '2.3.0-release' of github.com:magento/magento2ce into MAGETWO-95501
2 parents 8789c0b + 63d01ca commit bc60bdd

File tree

324 files changed

+6406
-1621
lines changed

Some content is hidden

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

324 files changed

+6406
-1621
lines changed

app/code/Magento/Backend/view/adminhtml/web/js/validate-store.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ define([
6767
* 'Confirm' action handler.
6868
*/
6969
confirm: function () {
70+
$('body').trigger('processStart');
7071
dataPost().postData(requestData);
7172
}
7273
}

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@ public function __construct(array $blackList = [])
2727

2828
/**
2929
* Delete custom attribute
30-
* @param array $attributes
30+
*
31+
* @param array $attributes set objects attributes @example ['attribute_code'=>'attribute_object']
3132
* @return array
3233
*/
3334
public function execute(array $attributes): array
3435
{
35-
return array_diff($attributes, $this->blackList);
36+
return array_diff_key($attributes, array_flip($this->blackList));
3637
}
3738
}

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

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -498,21 +498,26 @@ protected function _getResource()
498498
}
499499

500500
/**
501-
* Get a list of custom attribute codes that belongs to product attribute set. If attribute set not specified for
502-
* product will return all product attribute codes
501+
* Get a list of custom attribute codes that belongs to product attribute set.
502+
*
503+
* If attribute set not specified for product will return all product attribute codes
503504
*
504505
* @return string[]
505506
*/
506507
protected function getCustomAttributesCodes()
507508
{
508509
if ($this->customAttributesCodes === null) {
509-
$this->customAttributesCodes = array_keys($this->eavConfig->getEntityAttributes(
510-
self::ENTITY,
511-
$this
512-
));
513-
514-
$this->customAttributesCodes = $this->filterCustomAttribute->execute($this->customAttributesCodes);
515-
$this->customAttributesCodes = array_diff($this->customAttributesCodes, ProductInterface::ATTRIBUTES);
510+
$this->customAttributesCodes = array_diff(
511+
array_keys(
512+
$this->filterCustomAttribute->execute(
513+
$this->eavConfig->getEntityAttributes(
514+
self::ENTITY,
515+
$this
516+
)
517+
)
518+
),
519+
ProductInterface::ATTRIBUTES
520+
);
516521
}
517522

518523
return $this->customAttributesCodes;
@@ -584,8 +589,9 @@ public function getPrice()
584589
}
585590

586591
/**
587-
* @codeCoverageIgnoreStart
588592
* Get visibility status
593+
*
594+
* @codeCoverageIgnoreStart
589595
* @see \Magento\Catalog\Model\Product\Visibility
590596
*
591597
* @return int
@@ -662,6 +668,7 @@ public function getStatus()
662668

663669
/**
664670
* Retrieve type instance of the product.
671+
*
665672
* Type instance implements product type depended logic and is a singleton shared by all products of the same type.
666673
*
667674
* @return \Magento\Catalog\Model\Product\Type\AbstractType
@@ -822,9 +829,10 @@ public function getStoreIds()
822829

823830
/**
824831
* Retrieve product attributes
825-
* if $groupId is null - retrieve all product attributes
826832
*
827-
* @param int $groupId Retrieve attributes of the specified group
833+
* If $groupId is null - retrieve all product attributes
834+
*
835+
* @param int $groupId Retrieve attributes of the specified group
828836
* @param bool $skipSuper Not used
829837
* @return \Magento\Eav\Model\Entity\Attribute\AbstractAttribute[]
830838
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
@@ -916,6 +924,7 @@ public function beforeSave()
916924

917925
/**
918926
* Check/set if options can be affected when saving product
927+
*
919928
* If value specified, it will be set.
920929
*
921930
* @param bool $value
@@ -1036,9 +1045,11 @@ public function reindex()
10361045

10371046
/**
10381047
* Clear cache related with product and protect delete from not admin
1048+
*
10391049
* Register indexing event before delete product
10401050
*
10411051
* @return \Magento\Catalog\Model\Product
1052+
* @throws \Magento\Framework\Exception\LocalizedException
10421053
*/
10431054
public function beforeDelete()
10441055
{
@@ -1545,12 +1556,12 @@ public function hasGalleryAttribute()
15451556
/**
15461557
* Add image to media gallery
15471558
*
1548-
* @param string $file file path of image in file system
1549-
* @param string|array $mediaAttribute code of attribute with type 'media_image',
1550-
* leave blank if image should be only in gallery
1551-
* @param boolean $move if true, it will move source file
1552-
* @param boolean $exclude mark image as disabled in product page view
1559+
* @param string $file file path of image in file system
1560+
* @param string|array $mediaAttribute code of type 'media_image', leave blank if image should be only in gallery
1561+
* @param boolean $move if true, it will move source file
1562+
* @param boolean $exclude mark image as disabled in product page view
15531563
* @return \Magento\Catalog\Model\Product
1564+
* @throws \Magento\Framework\Exception\LocalizedException
15541565
*/
15551566
public function addImageToMediaGallery($file, $mediaAttribute = null, $move = false, $exclude = true)
15561567
{
@@ -1711,7 +1722,6 @@ public function getIsSalable()
17111722

17121723
/**
17131724
* Check is a virtual product
1714-
* Data helper wrapper
17151725
*
17161726
* @return bool
17171727
*/
@@ -1804,8 +1814,8 @@ public function formatUrlKey($str)
18041814
* Save current attribute with code $code and assign new value
18051815
*
18061816
* @param string $code Attribute code
1807-
* @param mixed $value New attribute value
1808-
* @param int $store Store ID
1817+
* @param mixed $value New attribute value
1818+
* @param int $store Store ID
18091819
* @return void
18101820
*/
18111821
public function addAttributeUpdate($code, $value, $store)
@@ -1875,6 +1885,7 @@ public function getRequestPath()
18751885

18761886
/**
18771887
* Custom function for other modules
1888+
*
18781889
* @return string
18791890
*/
18801891
public function getGiftMessageAvailable()
@@ -1993,6 +2004,8 @@ public function getOptions()
19932004
}
19942005

19952006
/**
2007+
* Set options for product
2008+
*
19962009
* @param \Magento\Catalog\Api\Data\ProductCustomOptionInterface[] $options
19972010
* @return $this
19982011
*/
@@ -2016,10 +2029,10 @@ public function getIsVirtual()
20162029
/**
20172030
* Add custom option information to product
20182031
*
2019-
* @param string $code Option code
2020-
* @param mixed $value Value of the option
2021-
* @param int|Product $product Product ID
2022-
* @return $this
2032+
* @param string $code Option code
2033+
* @param mixed $value Value of the option
2034+
* @param int|Product $product Product ID
2035+
* @return $this
20232036
*/
20242037
public function addCustomOption($code, $value, $product = null)
20252038
{
@@ -2213,6 +2226,7 @@ public function getPreconfiguredValues()
22132226

22142227
/**
22152228
* Prepare product custom options.
2229+
*
22162230
* To be sure that all product custom options does not has ID and has product instance
22172231
*
22182232
* @return \Magento\Catalog\Model\Product
@@ -2547,17 +2561,17 @@ public function setTypeId($typeId)
25472561
}
25482562

25492563
/**
2550-
* {@inheritdoc}
2564+
* Retrieve existing extension attributes object or create a new one.
25512565
*
2552-
* @return \Magento\Catalog\Api\Data\ProductExtensionInterface
2566+
* @return \Magento\Framework\Api\ExtensionAttributesInterface
25532567
*/
25542568
public function getExtensionAttributes()
25552569
{
25562570
return $this->_getExtensionAttributes();
25572571
}
25582572

25592573
/**
2560-
* {@inheritdoc}
2574+
* Set an extension attributes object.
25612575
*
25622576
* @param \Magento\Catalog\Api\Data\ProductExtensionInterface $extensionAttributes
25632577
* @return $this
@@ -2570,8 +2584,11 @@ public function setExtensionAttributes(\Magento\Catalog\Api\Data\ProductExtensio
25702584
//@codeCoverageIgnoreEnd
25712585

25722586
/**
2587+
* Convert to media gallery interface
2588+
*
25732589
* @param array $mediaGallery
25742590
* @return \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface[]
2591+
* @throws \Magento\Framework\Exception\LocalizedException
25752592
*/
25762593
protected function convertToMediaGalleryInterface(array $mediaGallery)
25772594
{
@@ -2587,7 +2604,10 @@ protected function convertToMediaGalleryInterface(array $mediaGallery)
25872604
}
25882605

25892606
/**
2607+
* Get media gallery entries
2608+
*
25902609
* @return \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface[]|null
2610+
* @throws \Magento\Framework\Exception\LocalizedException
25912611
*/
25922612
public function getMediaGalleryEntries()
25932613
{
@@ -2601,8 +2621,11 @@ public function getMediaGalleryEntries()
26012621
}
26022622

26032623
/**
2624+
* Set media gallery entries
2625+
*
26042626
* @param ProductAttributeMediaGalleryEntryInterface[] $mediaGalleryEntries
26052627
* @return $this
2628+
* @throws \Magento\Framework\Exception\LocalizedException
26062629
*/
26072630
public function setMediaGalleryEntries(array $mediaGalleryEntries = null)
26082631
{
@@ -2643,6 +2666,8 @@ public function setId($value)
26432666
}
26442667

26452668
/**
2669+
* Get link repository
2670+
*
26462671
* @return ProductLinkRepositoryInterface
26472672
*/
26482673
private function getLinkRepository()
@@ -2655,6 +2680,8 @@ private function getLinkRepository()
26552680
}
26562681

26572682
/**
2683+
* Get media gallery processor
2684+
*
26582685
* @return Product\Gallery\Processor
26592686
*/
26602687
private function getMediaGalleryProcessor()

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,11 @@
2020
<click selector="{{AdminProductAttributeGridSection.FirstRow}}" stepKey="clickOnAttributeRow"/>
2121
<waitForPageLoad stepKey="waitForPageLoad2" />
2222
</actionGroup>
23+
<actionGroup name="deleteProductAttribute" extends="navigateToCreatedProductAttribute">
24+
<click selector="{{AttributePropertiesSection.DeleteAttribute}}" stepKey="deleteAttribute"/>
25+
<click selector="{{ModalConfirmationSection.OkButton}}" stepKey="ClickOnDeleteButton"/>
26+
<waitForPageLoad stepKey="waitForPageLoad"/>
27+
<seeElement selector="{{AdminProductMessagesSection.successMessage}}"
28+
stepKey="waitForSuccessMessage"/>
29+
</actionGroup>
2330
</actionGroups>

app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryBasicFieldSection.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@
3232
<element name="DesignTab" type="button" selector="//strong[@class='admin__collapsible-title']//span[text()='Design']"/>
3333
<element name="LayoutDropdown" type="select" selector="select[name='page_layout']"/>
3434
</section>
35+
<section name="CategoryDisplaySettingsSection">
36+
<element name="DisplaySettingTab" type="button" selector="//strong[@class='admin__collapsible-title']//span[text()='Display Settings']"/>
37+
<element name="layeredNavigationPriceInput" type="input" selector="input[name='filter_price_range']"/>
38+
<element name="FieldError" type="text" selector=".admin__field-error[data-bind='attr: {for: {{field}}}, text: error']" parameterized="true"/>
39+
<element name="filterPriceRangeUseConfig" type="checkbox" selector="input[name='use_config[filter_price_range]']"/>
40+
<element name="RequiredFieldIndicator" type="text" selector=" return window.getComputedStyle(document.querySelector('._required[data-index={{arg1}}]&gt;.admin__field-label span'), ':after').getPropertyValue('content');" parameterized="true"/>
41+
</section>
3542
<section name="CatalogWYSIWYGSection">
3643
<element name="ShowHideBtn" type="button" selector="#togglecategory_form_description"/>
3744
<element name="TinyMCE4" type="text" selector=".mce-branding-powered-by"/>

app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
<element name="checkIfTabOpen" selector="//div[@id='advanced_fieldset-wrapper' and not(contains(@class,'opened'))]" type="button"/>
2424
<element name="useInLayeredNavigation" type="select" selector="#is_filterable"/>
2525
</section>
26+
<section name="AttributeOptionsSection">
27+
<element name="AddOption" type="button" selector="#add_new_option_button"/>
28+
</section>
2629
<section name="StorefrontPropertiesSection">
2730
<element name="PageTitle" type="text" selector="//span[text()='Storefront Properties']" />
2831
<element name="StoreFrontPropertiesTab" selector="#product_attribute_tabs_front" type="button"/>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
10+
<section name="DropdownAttributeOptionsSection">
11+
<element name="nthOptionAdminLabel" type="input"
12+
selector="(//*[@id='manage-options-panel']//tr[{{var}}]//input[contains(@name, 'option[value]')])[1]" parameterized="true"/>
13+
</section>
14+
</sections>

app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@
5050
<conditionalClick selector="{{ProductDescriptionWYSIWYGToolbarSection.WysiwygArrow}}" dependentSelector="{{ProductDescriptionWYSIWYGToolbarSection.checkIfWysiwygArrowExpand}}" stepKey="clickWysiwygArrowIfClosed" visible="true"/>
5151
<waitForText userInput="{{ImageFolder.name}}" stepKey="waitForNewFolder1" />
5252
<click userInput="{{ImageFolder.name}}" stepKey="clickOnCreatedFolder1" />
53-
<waitForLoadingMaskToDisappear stepKey="waitForLoading4" />
53+
<waitForLoadingMaskToDisappear stepKey="waitForLoading4" timeout="45"/>
5454
<attachFile selector="{{ProductDescriptionWYSIWYGToolbarSection.BrowseUploadImage}}" userInput="{{ImageUpload1.value}}" stepKey="uploadImage1"/>
55-
<waitForLoadingMaskToDisappear stepKey="waitForFileUpload1" />
55+
<waitForLoadingMaskToDisappear stepKey="waitForFileUpload1" timeout="30"/>
5656
<waitForElementVisible selector="{{ProductDescriptionWYSIWYGToolbarSection.image(ImageUpload1.value)}}" stepKey="waitForUploadImage1" />
5757
<seeElement selector="{{ProductDescriptionWYSIWYGToolbarSection.imageSelected(ImageUpload1.value)}}" stepKey="seeImageSelected1" />
5858
<see selector="{{ProductDescriptionWYSIWYGToolbarSection.DeleteSelectedBtn}}" userInput="Delete Selected" stepKey="seeDeleteBtn1"/>
@@ -63,7 +63,7 @@
6363
<dontSeeElement selector="{{ProductDescriptionWYSIWYGToolbarSection.image(ImageUpload1.value)}}" stepKey="dontSeeImage1" />
6464
<dontSeeElement selector="{{ProductDescriptionWYSIWYGToolbarSection.InsertFile}}" stepKey="dontSeeAddSelectedBtn2" />
6565
<attachFile selector="{{ProductDescriptionWYSIWYGToolbarSection.BrowseUploadImage}}" userInput="{{ImageUpload1.value}}" stepKey="uploadImage2"/>
66-
<waitForLoadingMaskToDisappear stepKey="waitForFileUpload2" />
66+
<waitForLoadingMaskToDisappear stepKey="waitForFileUpload2" timeout="45"/>
6767
<waitForElementVisible selector="{{ProductDescriptionWYSIWYGToolbarSection.image(ImageUpload1.value)}}" stepKey="waitForUploadImage2" />
6868
<click selector="{{ProductDescriptionWYSIWYGToolbarSection.InsertFile}}" stepKey="clickInsertBtn1" />
6969
<waitForElementVisible selector="{{ProductDescriptionWYSIWYGToolbarSection.ImageDescription}}" stepKey="waitForImageDescriptionButton1" />
@@ -75,10 +75,12 @@
7575
<click selector="{{ProductShortDescriptionWYSIWYGToolbarSection.Browse}}" stepKey="clickBrowse2" />
7676
<waitForElementVisible selector="{{ProductDescriptionWYSIWYGToolbarSection.CancelBtn}}" stepKey="waitForCancelButton2"/>
7777
<see selector="{{ProductShortDescriptionWYSIWYGToolbarSection.CancelBtn}}" userInput="Cancel" stepKey="seeCancelBtn2" />
78+
<waitForLoadingMaskToDisappear stepKey="waitForLoading13" timeout="30"/>
7879
<see selector="{{ProductShortDescriptionWYSIWYGToolbarSection.CreateFolder}}" userInput="Create Folder" stepKey="seeCreateFolderBtn2" />
80+
<waitForLoadingMaskToDisappear stepKey="waitForLoading14" timeout="40"/>
7981
<dontSeeElement selector="{{ProductShortDescriptionWYSIWYGToolbarSection.InsertFile}}" stepKey="dontSeeAddSelectedBtn3" />
8082
<attachFile selector="{{ProductShortDescriptionWYSIWYGToolbarSection.BrowseUploadImage}}" userInput="{{ImageUpload3.value}}" stepKey="uploadImage3"/>
81-
<waitForLoadingMaskToDisappear stepKey="waitForFileUpload3" />
83+
<waitForLoadingMaskToDisappear stepKey="waitForFileUpload3" timeout="45"/>
8284
<waitForElementVisible selector="{{ProductShortDescriptionWYSIWYGToolbarSection.image(ImageUpload3.value)}}" stepKey="waitForUploadImage3" />
8385
<waitForElement selector="{{ProductShortDescriptionWYSIWYGToolbarSection.DeleteSelectedBtn}}" stepKey="waitForDeletebtn" />
8486
<see selector="{{ProductShortDescriptionWYSIWYGToolbarSection.DeleteSelectedBtn}}" userInput="Delete Selected" stepKey="seeDeleteBtn2"/>
@@ -87,7 +89,7 @@
8789
<click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirmDelete2" />
8890
<dontSeeElement selector="{{ProductDescriptionWYSIWYGToolbarSection.InsertFile}}" stepKey="dontSeeAddSelectedBtn4" />
8991
<attachFile selector="{{ProductShortDescriptionWYSIWYGToolbarSection.BrowseUploadImage}}" userInput="{{ImageUpload3.value}}" stepKey="uploadImage4"/>
90-
<waitForLoadingMaskToDisappear stepKey="waitForFileUpload4" />
92+
<waitForLoadingMaskToDisappear stepKey="waitForFileUpload4" timeout="45"/>
9193
<waitForElementVisible selector="{{ProductShortDescriptionWYSIWYGToolbarSection.image(ImageUpload3.value)}}" stepKey="waitForUploadImage4" />
9294
<click selector="{{ProductShortDescriptionWYSIWYGToolbarSection.InsertFile}}" stepKey="clickInsertBtn" />
9395
<waitForLoadingMaskToDisappear stepKey="waitForLoading11" />

app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest.xml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,35 @@
6969
<waitForElementVisible selector="{{CategoryDesignSection.LayoutDropdown}}" stepKey="waitForLayoutDropDown" />
7070
<seeOptionIsSelected selector="{{CategoryDesignSection.LayoutDropdown}}" userInput="2 columns with right bar" stepKey="see2ColumnsSelected" />
7171
</test>
72+
<test name="AdminCategoryFormDisplaySettingsUIValidationTest">
73+
<annotations>
74+
<features value="Catalog"/>
75+
<stories value="Default layout configuration MAGETWO-88793"/>
76+
<title value="Category should not be saved once layered navigation price step field is left empty"/>
77+
<description value="Once the Config setting is unchecked Category should not be saved with layered navigation price field left empty"/>
78+
<severity value="AVERAGE"/>
79+
<testCaseId value="MAGETWO-95797"/>
80+
<group value="category"/>
81+
</annotations>
82+
<before>
83+
<actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/>
84+
</before>
85+
<after>
86+
<actionGroup ref="logout" stepKey="logout"/>
87+
</after>
88+
<amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPage"/>
89+
<waitForPageLoad time="30" stepKey="waitForPageLoad1"/>
90+
<click selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="clickOnAddSubCategory"/>
91+
<fillField selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" userInput="{{SimpleSubCategory.name}}" stepKey="enterCategoryName"/>
92+
<click selector="{{CategoryDisplaySettingsSection.DisplaySettingTab}}" stepKey="clickOnDisplaySettingsTab"/>
93+
<waitForElementVisible selector="{{CategoryDisplaySettingsSection.filterPriceRangeUseConfig}}" stepKey="wait"/>
94+
<scrollTo selector="{{CategoryDisplaySettingsSection.layeredNavigationPriceInput}}" stepKey="scrollToLayeredNavigationField"/>
95+
<uncheckOption selector="{{CategoryDisplaySettingsSection.filterPriceRangeUseConfig}}" stepKey="uncheckConfigSetting"/>
96+
<click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveCategory"/>
97+
<see selector="{{AdminCategoryBasicFieldSection.FieldError('uid')}}" userInput="This is a required field." stepKey="seeErrorMessage"/>
98+
<!-- Verify that the Layered navigation price step field has the required indicator -->
99+
<comment userInput="Check if Layered navigation price field has required indictor icon" stepKey="comment" />
100+
<executeJS function="{{CategoryDisplaySettingsSection.RequiredFieldIndicator('filter_price_range')}}" stepKey="getRequiredFieldIndicator"/>
101+
<assertEquals expected='"*"' expectedType="string" actualType="variable" actual="getRequiredFieldIndicator" message="pass" stepKey="assertRequiredFieldIndicator1"/>
102+
</test>
72103
</tests>

0 commit comments

Comments
 (0)