Skip to content

Commit e189a16

Browse files
authored
Merge branch '2.4-develop' into remove-legacy-code
2 parents e3cc512 + 597e991 commit e189a16

File tree

106 files changed

+20341
-20200
lines changed

Some content is hidden

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

106 files changed

+20341
-20200
lines changed

app/code/Magento/Backend/Test/Mftf/Data/BackenedData.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!--
33
/**
4-
* Copyright 2018 Adobe
4+
* Copyright 2025 Adobe
55
* All Rights Reserved.
66
*/
77
-->

app/code/Magento/Catalog/Helper/Category.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010
use Magento\Catalog\Model\CategoryFactory;
1111
use Magento\Framework\App\Helper\AbstractHelper;
1212
use Magento\Framework\App\Helper\Context;
13+
use Magento\Framework\App\ObjectManager;
1314
use Magento\Framework\Data\CollectionFactory;
1415
use Magento\Framework\Data\Tree\Node\Collection;
16+
use Magento\Framework\Escaper;
1517
use Magento\Framework\Exception\NoSuchEntityException;
1618
use Magento\Framework\ObjectManager\ResetAfterRequestInterface;
1719
use Magento\Store\Model\ScopeInterface;
@@ -63,24 +65,33 @@ class Category extends AbstractHelper implements ResetAfterRequestInterface
6365
*/
6466
protected $categoryRepository;
6567

68+
/**
69+
* @var Escaper|null
70+
*/
71+
private ?Escaper $escaper;
72+
6673
/**
6774
* @param Context $context
6875
* @param CategoryFactory $categoryFactory
6976
* @param StoreManagerInterface $storeManager
7077
* @param CollectionFactory $dataCollectionFactory
7178
* @param CategoryRepositoryInterface $categoryRepository
79+
* @param Escaper|null $escaper
7280
*/
7381
public function __construct(
7482
Context $context,
7583
CategoryFactory $categoryFactory,
7684
StoreManagerInterface $storeManager,
7785
CollectionFactory $dataCollectionFactory,
78-
CategoryRepositoryInterface $categoryRepository
86+
CategoryRepositoryInterface $categoryRepository,
87+
?Escaper $escaper = null
7988
) {
8089
$this->_categoryFactory = $categoryFactory;
8190
$this->_storeManager = $storeManager;
8291
$this->_dataCollectionFactory = $dataCollectionFactory;
8392
$this->categoryRepository = $categoryRepository;
93+
$this->escaper = $escaper ?: ObjectManager::getInstance()->get(Escaper::class);
94+
8495
parent::__construct($context);
8596
}
8697

@@ -204,6 +215,7 @@ public function getCanonicalUrl(string $categoryUrl): string
204215
if ($params && isset($params['p'])) {
205216
$categoryUrl = $categoryUrl . '?p=' . $params['p'];
206217
}
207-
return $categoryUrl;
218+
219+
return $this->escaper->escapeUrl($categoryUrl);
208220
}
209221
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright 2025 Adobe
5+
* All Rights Reserved.
6+
*/
7+
-->
8+
9+
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
11+
<test name="StorefrontAssertStockStatusForDisplayOutOfStockEnabledTest">
12+
<annotations>
13+
<features value="Catalog"/>
14+
<stories value="Manage Out Of Stock products In Storefront"/>
15+
<title value="Ensure Catalog Display with 'Out of Stock Products' Enabled"/>
16+
<description value="Verifying catalog data when display out of stock products is enabled In Storefront"/>
17+
<severity value="CRITICAL"/>
18+
<testCaseId value="AC-6393"/>
19+
</annotations>
20+
<before>
21+
<!--Create Category-->
22+
<createData entity="CategoryB" stepKey="createCategory"/>
23+
<!--Create Simple Product-->
24+
<createData entity="productA" stepKey="createOutStockProduct">
25+
<requiredEntity createDataKey="createCategory"/>
26+
<field key="price">15.00</field>
27+
<field key="quantity">0</field>
28+
</createData>
29+
<createData entity="productA" stepKey="createProduct">
30+
<requiredEntity createDataKey="createCategory"/>
31+
<field key="price">20.00</field>
32+
<field key="quantity">0</field>
33+
</createData>
34+
<createData entity="productA" stepKey="createSimpleOutStockProduct">
35+
<requiredEntity createDataKey="createCategory"/>
36+
<field key="price">25.00</field>
37+
<field key="quantity">0</field>
38+
</createData>
39+
<createData entity="productA" stepKey="createProductNoQuantity">
40+
<requiredEntity createDataKey="createCategory"/>
41+
<field key="price">30.00</field>
42+
<field key="quantity">0</field>
43+
</createData>
44+
</before>
45+
<after>
46+
<!-- Set Magento back to default configuration -->
47+
<magentoCLI command="config:set {{CatalogInventoryOptionsShowOutOfStockDisable.path}} {{CatalogInventoryOptionsShowOutOfStockDisable.value}}" stepKey="setConfigShowOutOfStockFalse"/>
48+
<!-- Delete created entity -->
49+
<deleteData createDataKey="createProduct" stepKey="deleteProduct"/>
50+
<deleteData createDataKey="createOutStockProduct" stepKey="deleteFirstProduct"/>
51+
<deleteData createDataKey="createSimpleOutStockProduct" stepKey="deleteSecondProduct"/>
52+
<deleteData createDataKey="createProductNoQuantity" stepKey="deleteThirdProduct"/>
53+
<deleteData createDataKey="createCategory" stepKey="deleteCategory"/>
54+
<!-- Logout From Customer and Admin -->
55+
<actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="logoutCustomer" />
56+
<actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/>
57+
</after>
58+
<!-- Step1: Login as admin -->
59+
<actionGroup ref="AdminLoginActionGroup" stepKey="login"/>
60+
<!-- Step2: Stores - Configuration - Catalog - Inventory - Stock options - Enable display out of stock products to yes -->
61+
<magentoCLI command="config:set {{CatalogInventoryOptionsShowOutOfStockEnable.path}} {{CatalogInventoryOptionsShowOutOfStockEnable.value}}" stepKey="setConfigShowOutOfStockTrue"/>
62+
<!-- Step3: Clear cache and verify catalog on front end all categories -->
63+
<actionGroup ref="CliCacheCleanActionGroup" stepKey="cleanInvalidatedCaches">
64+
<argument name="tags" value="config full_page"/>
65+
</actionGroup>
66+
<!-- Go to storefront category page -->
67+
<actionGroup ref="GoToStorefrontCategoryPageByParametersActionGroup" stepKey="GoToStorefrontCategoryPage3">
68+
<argument name="category" value="$$createCategory.custom_attributes[url_key]$$"/>
69+
<argument name="mode" value="list"/>
70+
<argument name="numOfProductsPerPage" value="10"/>
71+
<argument name="sortBy" value="price"/>
72+
<argument name="sort" value="desc"/>
73+
</actionGroup>
74+
<waitForText userInput="$$createProductNoQuantity.name$$" selector="{{StorefrontCategoryMainSection.lineProductName('1')}}" stepKey="seeFirstProductNameLine"/>
75+
<waitForText userInput="$$createSimpleOutStockProduct.name$$" selector="{{StorefrontCategoryMainSection.lineProductName('2')}}" stepKey="seeSecondProductNameLine"/>
76+
<waitForText userInput="$$createProduct.name$$" selector="{{StorefrontCategoryMainSection.lineProductName('3')}}" stepKey="seeThirdProductNameLine"/>
77+
<waitForText userInput="$$createOutStockProduct.name$$" selector="{{StorefrontCategoryMainSection.lineProductName('4')}}" stepKey="seeForthProductNameLine"/>
78+
<!-- Step4: Apply filters and verify catalog -->
79+
<actionGroup ref="OpenStoreFrontProductPageActionGroup" stepKey="goToFirstProductPage">
80+
<argument name="productUrlKey" value="$createProductNoQuantity.custom_attributes[url_key]$"/>
81+
</actionGroup>
82+
<actionGroup ref="AssertStorefrontProductStockStatusOnProductPageActionGroup" stepKey="seeFirstProductStatusInStoreFront">
83+
<argument name="productStockStatus" value="In Stock"/>
84+
</actionGroup>
85+
<actionGroup ref="OpenStoreFrontProductPageActionGroup" stepKey="goToSecondProductPage">
86+
<argument name="productUrlKey" value="$createSimpleOutStockProduct.custom_attributes[url_key]$"/>
87+
</actionGroup>
88+
<actionGroup ref="AssertStorefrontProductStockStatusOnProductPageActionGroup" stepKey="seeSecondProductStatusInStoreFront">
89+
<argument name="productStockStatus" value="In Stock"/>
90+
</actionGroup>
91+
<actionGroup ref="OpenStoreFrontProductPageActionGroup" stepKey="goToThirdProductPage">
92+
<argument name="productUrlKey" value="$createProduct.custom_attributes[url_key]$"/>
93+
</actionGroup>
94+
<actionGroup ref="AssertStorefrontProductStockStatusOnProductPageActionGroup" stepKey="seeThirdProductStatusInStoreFront">
95+
<argument name="productStockStatus" value="In Stock"/>
96+
</actionGroup>
97+
<actionGroup ref="OpenStoreFrontProductPageActionGroup" stepKey="goToProductPage">
98+
<argument name="productUrlKey" value="$createOutStockProduct.custom_attributes[url_key]$"/>
99+
</actionGroup>
100+
<actionGroup ref="AssertStorefrontProductStockStatusOnProductPageActionGroup" stepKey="seeProductStatusInStoreFront">
101+
<argument name="productStockStatus" value="In Stock"/>
102+
</actionGroup>
103+
</test>
104+
</tests>

app/code/Magento/Catalog/Test/Unit/Helper/CategoryTest.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Magento\Framework\App\Helper\Context;
1515
use Magento\Framework\App\RequestInterface;
1616
use Magento\Framework\Data\CollectionFactory;
17+
use Magento\Framework\Escaper;
1718
use Magento\Store\Model\StoreManagerInterface;
1819
use PHPUnit\Framework\MockObject\MockObject;
1920
use PHPUnit\Framework\TestCase;
@@ -63,6 +64,11 @@ class CategoryTest extends TestCase
6364
*/
6465
private $requestMock;
6566

67+
/**
68+
* @var Escaper|MockObject
69+
*/
70+
private $escaper;
71+
6672
protected function setUp(): void
6773
{
6874
$this->mockContext();
@@ -78,12 +84,16 @@ protected function setUp(): void
7884
$this->categoryRepository = $this->getMockBuilder(CategoryRepositoryInterface::class)
7985
->disableOriginalConstructor()
8086
->getMock();
87+
$this->escaper = $this->getMockBuilder(Escaper::class)
88+
->disableOriginalConstructor()
89+
->getMock();
8190
$this->categoryHelper = new Category(
8291
$this->context,
8392
$this->categoryFactory,
8493
$this->storeManager,
8594
$this->collectionFactory,
86-
$this->categoryRepository
95+
$this->categoryRepository,
96+
$this->escaper
8797
);
8898
}
8999

@@ -101,6 +111,9 @@ public function testGetCanonicalUrl(mixed $params, string $categoryUrl, string $
101111
$this->requestMock->expects($this->any())
102112
->method('getParams')
103113
->willReturn($params);
114+
$this->escaper->expects($this->any())
115+
->method('escapeUrl')
116+
->willReturn($expectedCategoryUrl);
104117
$actualCategoryUrl = $this->categoryHelper->getCanonicalUrl($categoryUrl);
105118
$this->assertEquals($actualCategoryUrl, $expectedCategoryUrl);
106119
}

app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/DataProviderTest.php

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22
/**
3-
* Copyright 2016 Adobe
3+
* Copyright 2025 Adobe
44
* All Rights Reserved.
55
*/
66
declare(strict_types=1);
@@ -12,7 +12,7 @@
1212
use Magento\Framework\Api\Search\SearchCriteriaBuilder;
1313
use Magento\Framework\App\ObjectManager;
1414
use Magento\Framework\App\RequestInterface;
15-
use Magento\Framework\Authorization;
15+
use Magento\Framework\AuthorizationInterface;
1616
use Magento\Framework\ObjectManagerInterface;
1717
use Magento\Framework\View\Element\UiComponent\DataProvider\Reporting;
1818
use Magento\Ui\Component\Container;
@@ -23,49 +23,49 @@
2323
class DataProviderTest extends TestCase
2424
{
2525
/**
26-
* @var Authorization|MockObject
26+
* @var AuthorizationInterface|MockObject
2727
*/
28-
private $authorizationMock;
28+
private AuthorizationInterface|MockObject $authorizationMock;
2929

3030
/**
3131
* @var Reporting|MockObject
3232
*/
33-
private $reportingMock;
33+
private Reporting|MockObject $reportingMock;
3434

3535
/**
3636
* @var SearchCriteriaBuilder|MockObject
3737
*/
38-
private $searchCriteriaBuilderMock;
38+
private SearchCriteriaBuilder|MockObject $searchCriteriaBuilderMock;
3939

4040
/**
4141
* @var RequestInterface|MockObject
4242
*/
43-
private $requestInterfaceMock;
43+
private RequestInterface|MockObject $requestInterfaceMock;
4444

4545
/**
4646
* @var FilterBuilder|MockObject
4747
*/
48-
private $filterBuilderMock;
48+
private FilterBuilder|MockObject $filterBuilderMock;
4949

5050
/**
5151
* @var DataProvider
5252
*/
53-
private $dataProvider;
53+
private DataProvider $dataProvider;
5454

5555
/**
5656
* @var string
5757
*/
58-
private $name = 'cms_page_listing_data_source';
58+
private string $name = 'cms_page_listing_data_source';
5959

6060
/**
6161
* @var string
6262
*/
63-
private $primaryFieldName = 'page';
63+
private string $primaryFieldName = 'page';
6464

6565
/**
6666
* @var string
6767
*/
68-
private $requestFieldName = 'id';
68+
private string $requestFieldName = 'id';
6969

7070
/**
7171
* @var array
@@ -80,30 +80,20 @@ class DataProviderTest extends TestCase
8080

8181
protected function setUp(): void
8282
{
83-
$this->authorizationMock = $this->getMockBuilder(Authorization::class)
84-
->disableOriginalConstructor()
85-
->getMock();
83+
$this->authorizationMock = $this->createMock(AuthorizationInterface::class);
8684

87-
$this->reportingMock = $this->getMockBuilder(Reporting::class)
88-
->disableOriginalConstructor()
89-
->getMock();
85+
$this->reportingMock = $this->createMock(Reporting::class);
9086

91-
$this->searchCriteriaBuilderMock = $this->getMockBuilder(SearchCriteriaBuilder::class)
92-
->disableOriginalConstructor()
93-
->getMock();
87+
$this->searchCriteriaBuilderMock = $this->createMock(SearchCriteriaBuilder::class);
9488

95-
$this->requestInterfaceMock = $this->getMockBuilder(RequestInterface::class)
96-
->disableOriginalConstructor()
97-
->getMockForAbstractClass();
89+
$this->requestInterfaceMock = $this->createMock(RequestInterface::class);
9890

99-
$this->filterBuilderMock = $this->getMockBuilder(FilterBuilder::class)
100-
->disableOriginalConstructor()
101-
->getMock();
91+
$this->filterBuilderMock = $this->createMock(FilterBuilder::class);
10292

10393
/** @var ObjectManagerInterface|MockObject $objectManagerMock */
104-
$objectManagerMock = $this->getMockForAbstractClass(ObjectManagerInterface::class);
105-
$objectManagerMock->expects($this->once())
106-
->method('get')
94+
$objectManagerMock = $this->createMock(ObjectManagerInterface::class);
95+
$objectManagerMock->method('get')
96+
->with(AuthorizationInterface::class)
10797
->willReturn($this->authorizationMock);
10898
ObjectManager::setInstance($objectManagerMock);
10999

@@ -121,15 +111,14 @@ protected function setUp(): void
121111
/**
122112
* @covers \Magento\Cms\Ui\Component\DataProvider::prepareMetadata
123113
*/
124-
public function testPrepareMetadata()
114+
public function testPrepareMetadata(): void
125115
{
126116
$this->authorizationMock->expects($this->exactly(2))
127117
->method('isAllowed')
128118
->willReturnMap(
129119
[
130120
['Magento_Cms::save', null, false],
131121
['Magento_Cms::save_design', null, false],
132-
133122
]
134123
);
135124

@@ -168,4 +157,24 @@ public function testPrepareMetadata()
168157
$this->dataProvider->prepareMetadata()
169158
);
170159
}
160+
161+
/**
162+
* @covers \Magento\Cms\Ui\Component\DataProvider::prepareMetadata
163+
*/
164+
public function testPrepareMetadataForCmsBlockListing(): void
165+
{
166+
$name = 'cms_block_listing_data_source';
167+
168+
$this->dataProvider = new DataProvider(
169+
$name,
170+
$this->primaryFieldName,
171+
$this->requestFieldName,
172+
$this->reportingMock,
173+
$this->searchCriteriaBuilderMock,
174+
$this->requestInterfaceMock,
175+
$this->filterBuilderMock
176+
);
177+
178+
$this->assertEquals([], $this->dataProvider->prepareMetadata());
179+
}
171180
}

0 commit comments

Comments
 (0)