Skip to content

Commit d976a2b

Browse files
🔃 [EngCom] Public Pull Requests - 2.3-develop
Accepted Public Pull Requests: - #21826: Flying Fists of Kung Fu Cleanup (by @lefte) - #21791: #19835 Fix admin header buttons flicker (by @OlehWolf) - #21795: [Wishlist] Covering the Wishlist classes by integration and unit tests (by @eduard13) Fixed GitHub Issues: - #19835: Admin grid button flicker issue after page load due to re-ordering (reported by @milindsingh) has been fixed in #21791 by @OlehWolf in 2.3-develop branch Related commits: 1. 68d793d
2 parents 0e8428c + 2bc2f5a commit d976a2b

File tree

12 files changed

+283
-9
lines changed

12 files changed

+283
-9
lines changed

app/code/Magento/Authorizenet/Model/Directpost/Request.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ public function setDataFromOrder(
194194
/**
195195
* Set sign hash into the request object.
196196
*
197-
* All needed fields should be placed in the object fist.
197+
* All needed fields should be placed in the object first.
198198
*
199199
* @return $this
200200
*/

app/code/Magento/Backend/view/adminhtml/templates/pageactions.phtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
?>
1010
<?php if ($block->getChildHtml()):?>
11-
<div data-mage-init='{"floatingHeader": {}}' class="page-actions" <?= /* @escapeNotVerified */ $block->getUiId('content-header') ?>>
11+
<div data-mage-init='{"floatingHeader": {}}' class="page-actions floating-header" <?= /* @escapeNotVerified */ $block->getUiId('content-header') ?>>
1212
<?= $block->getChildHtml() ?>
1313
</div>
1414
<?php endif; ?>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@
139139
</assertEquals>
140140

141141
<!--Verify we see customizable options are Required -->
142-
<seeElement selector="{{StorefrontProductInfoMainSection.requiredCustomInput(virtualProductCustomizableOption1.title)}}" stepKey="verifyFistCustomOptionIsRequired" />
142+
<seeElement selector="{{StorefrontProductInfoMainSection.requiredCustomInput(virtualProductCustomizableOption1.title)}}" stepKey="verifyFirstCustomOptionIsRequired" />
143143
<seeElement selector="{{StorefrontProductInfoMainSection.requiredCustomInput(virtualProductCustomizableOption2.title)}}" stepKey="verifySecondCustomOptionIsRequired" />
144144
<seeElement selector="{{StorefrontProductInfoMainSection.requiredCustomSelect(virtualProductCustomizableOption3.title)}}" stepKey="verifyThirdCustomOptionIsRequired" />
145145
<seeElement selector="{{StorefrontProductInfoMainSection.requiredCustomSelect(virtualProductCustomizableOption4.title)}}" stepKey="verifyFourthCustomOptionIsRequired" />

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@
135135
</assertEquals>
136136

137137
<!--Verify customer see customizable options are Required -->
138-
<seeElement selector="{{StorefrontProductInfoMainSection.requiredCustomSelect(simpleProductCustomizableOption.title)}}" stepKey="verifyFistCustomOptionIsRequired"/>
138+
<seeElement selector="{{StorefrontProductInfoMainSection.requiredCustomSelect(simpleProductCustomizableOption.title)}}" stepKey="verifyFirstCustomOptionIsRequired"/>
139139

140140
<!--Verify customer see customizable option titles and prices -->
141141
<grabAttributeFrom userInput="for" selector="{{StorefrontProductInfoMainSection.customOptionLabel(simpleProductCustomizableOption.title)}}" stepKey="simpleOptionId"/>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@
229229
<actualResult type="variable">productPriceAmount</actualResult>
230230
</assertEquals>
231231
<!--Verify we customer see customizable options are Required -->
232-
<seeElement selector="{{StorefrontProductInfoMainSection.requiredCustomInput(virtualProductCustomizableOption1.title)}}" stepKey="verifyFistCustomOptionIsRequired" />
232+
<seeElement selector="{{StorefrontProductInfoMainSection.requiredCustomInput(virtualProductCustomizableOption1.title)}}" stepKey="verifyFirstCustomOptionIsRequired" />
233233
<seeElement selector="{{StorefrontProductInfoMainSection.requiredCustomInput(virtualProductCustomizableOption2.title)}}" stepKey="verifySecondCustomOptionIsRequired" />
234234
<seeElement selector="{{StorefrontProductInfoMainSection.requiredCustomSelect(virtualProductCustomizableOption3.title)}}" stepKey="verifyThirdCustomOptionIsRequired" />
235235
<seeElement selector="{{StorefrontProductInfoMainSection.requiredCustomSelect(virtualProductCustomizableOption4.title)}}" stepKey="verifyFourthCustomOptionIsRequired" />

app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/AdminConfigurableProductActionGroup.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,8 @@
145145
<click selector="{{AdminCreateProductConfigurationsPanel.attributeCheckbox(secondAttributeCode)}}" stepKey="clickOnSecondAttributeCheckbox" after="clickOnFirstAttributeCheckbox"/>
146146
<grabTextFrom selector="{{AdminCreateProductConfigurationsPanel.defaultLabel(attributeCode)}}" stepKey="grabFirstAttributeDefaultLabel" after="clickOnSecondAttributeCheckbox"/>
147147
<grabTextFrom selector="{{AdminCreateProductConfigurationsPanel.defaultLabel(secondAttributeCode)}}" stepKey="grabSecondAttributeDefaultLabel" after="grabFirstAttributeDefaultLabel"/>
148-
<click selector="{{AdminCreateProductConfigurationsPanel.selectAllByAttribute({$grabFirstAttributeDefaultLabel})}}" stepKey="clickOnSelectAllForFistAttribute" after="clickOnNextButton1"/>
149-
<click selector="{{AdminCreateProductConfigurationsPanel.selectAllByAttribute({$grabSecondAttributeDefaultLabel})}}" stepKey="clickOnSelectAllForSecondAttribute" after="clickOnSelectAllForFistAttribute"/>
148+
<click selector="{{AdminCreateProductConfigurationsPanel.selectAllByAttribute({$grabFirstAttributeDefaultLabel})}}" stepKey="clickOnSelectAllForFirstAttribute" after="clickOnNextButton1"/>
149+
<click selector="{{AdminCreateProductConfigurationsPanel.selectAllByAttribute({$grabSecondAttributeDefaultLabel})}}" stepKey="clickOnSelectAllForSecondAttribute" after="clickOnSelectAllForFirstAttribute"/>
150150
<click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickOnSaveButton2"/>
151151
<click selector="{{AdminChooseAffectedAttributeSetPopup.confirm}}" stepKey="clickOnConfirmInPopup"/>
152152
</actionGroup>

app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithTwoOptionsAssignedToCategoryTest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@
144144
<waitForPageLoad stepKey="waitForStoreFrontPageLoad"/>
145145

146146
<!-- Quick search the storefront for the first attribute option -->
147-
<submitForm selector="{{StorefrontQuickSearchSection.searchMiniForm}}" parameterArray="['q' => {{colorConfigurableProductAttribute1.sku}}]" stepKey="searchStorefrontFistChildProduct"/>
147+
<submitForm selector="{{StorefrontQuickSearchSection.searchMiniForm}}" parameterArray="['q' => {{colorConfigurableProductAttribute1.sku}}]" stepKey="searchStorefrontFirstChildProduct"/>
148148
<dontSee selector="{{StorefrontCategoryProductSection.ProductTitleByName(colorConfigurableProductAttribute1.name)}}" stepKey="dontSeeConfigurableProductFirstChild"/>
149149

150150
<!-- Quick search the storefront for the second attribute option -->

app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithTwoOptionsWithoutAssignedToCategoryTest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@
126126
<waitForPageLoad stepKey="waitForStoreFrontPageLoad"/>
127127

128128
<!-- Quick search the storefront for the first attribute option -->
129-
<submitForm selector="{{StorefrontQuickSearchSection.searchMiniForm}}" parameterArray="['q' => {{colorConfigurableProductAttribute1.sku}}]" stepKey="searchStorefrontFistChildProduct"/>
129+
<submitForm selector="{{StorefrontQuickSearchSection.searchMiniForm}}" parameterArray="['q' => {{colorConfigurableProductAttribute1.sku}}]" stepKey="searchStorefrontFirstChildProduct"/>
130130
<dontSee selector="{{StorefrontCategoryProductSection.ProductTitleByName(colorConfigurableProductAttribute1.name)}}" stepKey="dontSeeConfigurableProductFirstChild"/>
131131

132132
<!-- Quick search the storefront for the second attribute option -->
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Wishlist\Test\Unit\Model\Product;
9+
10+
use Magento\Catalog\Model\Product;
11+
use Magento\Catalog\Model\ResourceModel\Product\Collection;
12+
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
13+
use Magento\Framework\DB\Adapter\AdapterInterface;
14+
use Magento\Wishlist\Model\Product\AttributeValueProvider;
15+
use PHPUnit\Framework\TestCase;
16+
use PHPUnit_Framework_MockObject_MockObject;
17+
18+
/**
19+
* AttributeValueProviderTest
20+
*/
21+
class AttributeValueProviderTest extends TestCase
22+
{
23+
/**
24+
* @var AttributeValueProvider|PHPUnit_Framework_MockObject_MockObject
25+
*/
26+
private $attributeValueProvider;
27+
28+
/**
29+
* @var CollectionFactory|PHPUnit_Framework_MockObject_MockObject
30+
*/
31+
private $productCollectionFactoryMock;
32+
33+
/**
34+
* @var Product|PHPUnit_Framework_MockObject_MockObject
35+
*/
36+
private $productMock;
37+
38+
/**
39+
* @var AdapterInterface|PHPUnit_Framework_MockObject_MockObject
40+
*/
41+
private $connectionMock;
42+
43+
/**
44+
* Set Up
45+
*
46+
* @return void
47+
*/
48+
protected function setUp()
49+
{
50+
$this->productCollectionFactoryMock = $this->createPartialMock(
51+
CollectionFactory::class,
52+
['create']
53+
);
54+
$this->attributeValueProvider = new AttributeValueProvider(
55+
$this->productCollectionFactoryMock
56+
);
57+
}
58+
59+
/**
60+
* Get attribute text when the flat table is disabled
61+
*
62+
* @param int $productId
63+
* @param string $attributeCode
64+
* @param string $attributeText
65+
* @return void
66+
* @dataProvider attributeDataProvider
67+
*/
68+
public function testGetAttributeTextWhenFlatIsDisabled(int $productId, string $attributeCode, string $attributeText)
69+
{
70+
$this->productMock = $this->getMockBuilder(Product::class)
71+
->disableOriginalConstructor()
72+
->setMethods(['getData'])
73+
->getMock();
74+
75+
$this->productMock->expects($this->any())
76+
->method('getData')
77+
->with($attributeCode)
78+
->willReturn($attributeText);
79+
80+
$productCollection = $this->getMockBuilder(Collection::class)
81+
->disableOriginalConstructor()
82+
->setMethods([
83+
'addIdFilter', 'addStoreFilter', 'addAttributeToSelect', 'isEnabledFlat', 'getFirstItem'
84+
])->getMock();
85+
86+
$productCollection->expects($this->any())
87+
->method('addIdFilter')
88+
->willReturnSelf();
89+
$productCollection->expects($this->any())
90+
->method('addStoreFilter')
91+
->willReturnSelf();
92+
$productCollection->expects($this->any())
93+
->method('addAttributeToSelect')
94+
->willReturnSelf();
95+
$productCollection->expects($this->any())
96+
->method('isEnabledFlat')
97+
->willReturn(false);
98+
$productCollection->expects($this->any())
99+
->method('getFirstItem')
100+
->willReturn($this->productMock);
101+
102+
$this->productCollectionFactoryMock->expects($this->atLeastOnce())
103+
->method('create')
104+
->willReturn($productCollection);
105+
106+
$actual = $this->attributeValueProvider->getRawAttributeValue($productId, $attributeCode);
107+
108+
$this->assertEquals($attributeText, $actual);
109+
}
110+
111+
/**
112+
* Get attribute text when the flat table is enabled
113+
*
114+
* @dataProvider attributeDataProvider
115+
* @param int $productId
116+
* @param string $attributeCode
117+
* @param string $attributeText
118+
* @return void
119+
*/
120+
public function testGetAttributeTextWhenFlatIsEnabled(int $productId, string $attributeCode, string $attributeText)
121+
{
122+
$this->connectionMock = $this->getMockBuilder(AdapterInterface::class)->getMockForAbstractClass();
123+
$this->connectionMock->expects($this->any())
124+
->method('fetchRow')
125+
->willReturn([
126+
$attributeCode => $attributeText
127+
]);
128+
$this->productMock = $this->getMockBuilder(Product::class)
129+
->disableOriginalConstructor()
130+
->setMethods(['getData'])
131+
->getMock();
132+
$this->productMock->expects($this->any())
133+
->method('getData')
134+
->with($attributeCode)
135+
->willReturn($attributeText);
136+
137+
$productCollection = $this->getMockBuilder(Collection::class)
138+
->disableOriginalConstructor()
139+
->setMethods([
140+
'addIdFilter', 'addStoreFilter', 'addAttributeToSelect', 'isEnabledFlat', 'getConnection'
141+
])->getMock();
142+
143+
$productCollection->expects($this->any())
144+
->method('addIdFilter')
145+
->willReturnSelf();
146+
$productCollection->expects($this->any())
147+
->method('addStoreFilter')
148+
->willReturnSelf();
149+
$productCollection->expects($this->any())
150+
->method('addAttributeToSelect')
151+
->willReturnSelf();
152+
$productCollection->expects($this->any())
153+
->method('isEnabledFlat')
154+
->willReturn(true);
155+
$productCollection->expects($this->any())
156+
->method('getConnection')
157+
->willReturn($this->connectionMock);
158+
159+
$this->productCollectionFactoryMock->expects($this->atLeastOnce())
160+
->method('create')
161+
->willReturn($productCollection);
162+
163+
$actual = $this->attributeValueProvider->getRawAttributeValue($productId, $attributeCode);
164+
165+
$this->assertEquals($attributeText, $actual);
166+
}
167+
168+
/**
169+
* @return array
170+
*/
171+
public function attributeDataProvider(): array
172+
{
173+
return [
174+
[1, 'attribute_code', 'Attribute Text']
175+
];
176+
}
177+
}

app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/_actions-bar.less

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@
4545
.page-actions {
4646
@_page-action__indent: 1.3rem;
4747

48+
&.floating-header {
49+
&:extend(.page-actions-buttons all);
50+
}
51+
4852
.page-main-actions & {
4953
&._fixed {
5054
left: @page-wrapper__indent-left;
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Wishlist\Controller;
9+
10+
use Magento\Customer\Model\Session;
11+
use Magento\Framework\App\Area;
12+
use Magento\Framework\Data\Form\FormKey;
13+
use Magento\Framework\Message\MessageInterface;
14+
use Magento\TestFramework\Helper\Bootstrap;
15+
use Magento\TestFramework\Request;
16+
use Magento\TestFramework\TestCase\AbstractController;
17+
18+
/**
19+
* @magentoAppIsolation enabled
20+
*/
21+
class ShareTest extends AbstractController
22+
{
23+
/**
24+
* Test share wishlist with correct data
25+
*
26+
* @magentoDataFixture Magento/Wishlist/_files/wishlist.php
27+
*/
28+
public function testSuccessfullyShareWishlist()
29+
{
30+
$this->login(1);
31+
$this->prepareRequestData();
32+
$this->dispatch('wishlist/index/send/');
33+
34+
$this->assertSessionMessages(
35+
$this->equalTo(['Your wish list has been shared.']),
36+
MessageInterface::TYPE_SUCCESS
37+
);
38+
}
39+
40+
/**
41+
* Test share wishlist with incorrect data
42+
*
43+
* @magentoDataFixture Magento/Wishlist/_files/wishlist.php
44+
*/
45+
public function testShareWishlistWithoutEmails()
46+
{
47+
$this->login(1);
48+
$this->prepareRequestData(true);
49+
$this->dispatch('wishlist/index/send/');
50+
51+
$this->assertSessionMessages(
52+
$this->equalTo(['Please enter an email address.']),
53+
MessageInterface::TYPE_ERROR
54+
);
55+
}
56+
57+
/**
58+
* Login the user
59+
*
60+
* @param string $customerId Customer to mark as logged in for the session
61+
* @return void
62+
*/
63+
protected function login($customerId)
64+
{
65+
/** @var Session $session */
66+
$session = $this->_objectManager->get(Session::class);
67+
$session->loginById($customerId);
68+
}
69+
70+
/**
71+
* Prepares the request with data
72+
*
73+
* @param bool $invalidData
74+
* @return void
75+
*/
76+
private function prepareRequestData($invalidData = false)
77+
{
78+
Bootstrap::getInstance()->loadArea(Area::AREA_FRONTEND);
79+
$emails = !$invalidData ? '[email protected],[email protected]' : '';
80+
81+
/** @var FormKey $formKey */
82+
$formKey = $this->_objectManager->get(FormKey::class);
83+
$post = [
84+
'emails' => $emails,
85+
'message' => '',
86+
'form_key' => $formKey->getFormKey(),
87+
];
88+
89+
$this->getRequest()->setMethod(Request::METHOD_POST);
90+
$this->getRequest()->setPostValue($post);
91+
}
92+
}

lib/web/mage/backend/floating-header.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ define([
4848
this.element.wrapInner($('<div/>', {
4949
'class': 'page-actions-inner', 'data-title': title
5050
}));
51+
this.element.removeClass('floating-header');
5152
},
5253

5354
/**

0 commit comments

Comments
 (0)