Skip to content

Commit a7302dd

Browse files
ENGCOM-6997: [Forward Port PR-14344] Fix generating product URL rewrites for anchor categories #26784
- Merge Pull Request #26784 from hostep/magento2:forward-port-pr-14344 - Merged commits: 1. cb685d1 2. acb8642 3. 97258e1 4. 6cf26dc 5. 0b94121 6. b0c0c59 7. 28fa345 8. bf514b0
2 parents 9f093a3 + bf514b0 commit a7302dd

12 files changed

+466
-21
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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="AdminChangeSeoUrlKeyForSubCategoryWithoutRedirectActionGroup" extends="ChangeSeoUrlKeyForSubCategoryActionGroup">
12+
<annotations>
13+
<description>Requires navigation to subcategory creation/edit. Updates the Search Engine Optimization with uncheck Redirect Checkbox .</description>
14+
</annotations>
15+
<arguments>
16+
<argument name="value" type="string"/>
17+
</arguments>
18+
19+
<uncheckOption selector="{{AdminCategorySEOSection.UrlKeyRedirectCheckbox}}" stepKey="uncheckRedirectCheckbox" after="enterURLKey"/>
20+
</actionGroup>
21+
</actionGroups>

app/code/Magento/Catalog/Test/Mftf/Data/CategoryData.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,22 @@
110110
<data key="is_active">false</data>
111111
<data key="include_in_menu">false</data>
112112
</entity>
113+
<entity name="_defaultCategoryDifferentUrlStore" type="category">
114+
<data key="name" unique="suffix">SimpleCategory</data>
115+
<data key="name_lwr" unique="suffix">simplecategory</data>
116+
<data key="is_active">true</data>
117+
<data key="url_key_default_store" unique="suffix">default-simplecategory</data>
118+
<data key="url_key_custom_store" unique="suffix">custom-simplecategory</data>
119+
</entity>
120+
<entity name="SimpleSubCategoryDifferentUrlStore" type="category">
121+
<data key="name" unique="suffix">SimpleSubCategory</data>
122+
<data key="name_lwr" unique="suffix">simplesubcategory</data>
123+
<data key="is_active">true</data>
124+
<data key="url_key_default_store" unique="suffix">default-simplesubcategory</data>
125+
<data key="url_key_custom_store" unique="suffix">custom-simplesubcategory</data>
126+
<data key="include_in_menu">true</data>
127+
<var key="parent_id" entityType="category" entityKey="id" />
128+
</entity>
113129
<!-- Category from file "prepared-for-sample-data.csv"-->
114130
<entity name="Gear" type="category">
115131
<data key="name">Gear</data>

app/code/Magento/CatalogUrlRewrite/Model/Product/AnchorUrlRewriteGenerator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public function generate($storeId, Product $product, ObjectRegistry $productCate
6767
$anchorCategoryIds = $category->getAnchorsAbove();
6868
if ($anchorCategoryIds) {
6969
foreach ($anchorCategoryIds as $anchorCategoryId) {
70-
$anchorCategory = $this->categoryRepository->get($anchorCategoryId);
70+
$anchorCategory = $this->categoryRepository->get($anchorCategoryId, $storeId);
7171
if ((int)$anchorCategory->getParentId() === Category::TREE_ROOT_ID) {
7272
continue;
7373
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
9+
<actionGroup name="AssertStorefrontProductRewriteUrlSubCategoryActionGroup">
10+
<annotations>
11+
<description>Validates that the provided Product Title is present on the Rewrite URL with a subcategory page.</description>
12+
</annotations>
13+
<arguments>
14+
<argument name="category" type="string" defaultValue="simplecategory"/>
15+
<argument name="product" defaultValue="SimpleProduct" />
16+
</arguments>
17+
18+
<amOnPage url="{{category}}/{{product.urlKey}}2.html" stepKey="goToProductPage"/>
19+
<see selector="{{StorefrontProductInfoMainSection.productName}}" userInput="{{product.name}}" stepKey="seeProductNameInStoreFront"/>
20+
</actionGroup>
21+
</actionGroups>

app/code/Magento/CatalogUrlRewrite/Test/Mftf/Data/GenerateCategoryProductUrlRewriteConfigData.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,12 @@
1919
<data key="label">No</data>
2020
<data key="value">0</data>
2121
</entity>
22+
<entity name="EnableCategoriesPathProductUrls">
23+
<data key="path">catalog/seo/product_use_categories</data>
24+
<data key="value">1</data>
25+
</entity>
26+
<entity name="DisableCategoriesPathProductUrls">
27+
<data key="path">catalog/seo/product_use_categories</data>
28+
<data key="value">0</data>
29+
</entity>
2230
</entities>
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
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+
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
9+
<test name="AdminRewriteProductWithTwoStoreTest">
10+
<annotations>
11+
<title value="Rewriting URL of product"/>
12+
<description value="Rewriting URL of product. Verify the full URL address"/>
13+
<group value="CatalogUrlRewrite"/>
14+
</annotations>
15+
16+
<before>
17+
<magentoCLI command="config:set {{EnableCategoriesPathProductUrls.path}} {{EnableCategoriesPathProductUrls.value}}" stepKey="enableUseCategoriesPath"/>
18+
<magentoCLI command="cache:flush" stepKey="flushCache"/>
19+
20+
<actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/>
21+
<actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createStoreView" />
22+
<createData entity="_defaultCategoryDifferentUrlStore" stepKey="defaultCategory"/>
23+
<createData entity="SimpleSubCategoryDifferentUrlStore" stepKey="subCategory">
24+
<requiredEntity createDataKey="defaultCategory"/>
25+
</createData>
26+
<createData entity="SimpleProduct" stepKey="simpleProduct">
27+
<requiredEntity createDataKey="subCategory"/>
28+
</createData>
29+
</before>
30+
31+
<after>
32+
<actionGroup ref="AdminDeleteStoreViewActionGroup" stepKey="deleteStoreView"/>
33+
<actionGroup ref="logout" stepKey="logout"/>
34+
<deleteData createDataKey="simpleProduct" stepKey="deleteSimpleProduct"/>
35+
<deleteData createDataKey="defaultCategory" stepKey="deleteNewRootCategory"/>
36+
<magentoCLI command="config:set {{DisableCategoriesPathProductUrls.path}} {{DisableCategoriesPathProductUrls.value}}" stepKey="disableUseCategoriesPath"/>
37+
<magentoCLI command="cache:flush" stepKey="flushCache"/>
38+
</after>
39+
40+
<actionGroup ref="NavigateToCreatedCategoryActionGroup" stepKey="navigateToCreatedDefaultCategory">
41+
<argument name="Category" value="$$defaultCategory$$"/>
42+
</actionGroup>
43+
<actionGroup ref="AdminSwitchStoreViewActionGroup" stepKey="AdminSwitchDefaultStoreViewForDefaultCategory">
44+
<argument name="storeView" value="_defaultStore.name"/>
45+
</actionGroup>
46+
<actionGroup ref="AdminChangeSeoUrlKeyForSubCategoryWithoutRedirectActionGroup" stepKey="changeSeoUrlKeyForDefaultCategoryDefaultStore">
47+
<argument name="value" value="{{_defaultCategoryDifferentUrlStore.url_key_default_store}}"/>
48+
</actionGroup>
49+
<actionGroup ref="AdminSwitchStoreViewActionGroup" stepKey="AdminSwitchCustomStoreViewForDefaultCategory">
50+
<argument name="storeView" value="customStore.name"/>
51+
</actionGroup>
52+
<actionGroup ref="AdminChangeSeoUrlKeyForSubCategoryWithoutRedirectActionGroup" stepKey="changeSeoUrlKeyForDefaultCategoryCustomStore">
53+
<argument name="value" value="{{_defaultCategoryDifferentUrlStore.url_key_custom_store}}"/>
54+
</actionGroup>
55+
56+
<actionGroup ref="NavigateToCreatedCategoryActionGroup" stepKey="navigateToCreatedSubCategory">
57+
<argument name="Category" value="$$subCategory$$"/>
58+
</actionGroup>
59+
<actionGroup ref="AdminSwitchStoreViewActionGroup" stepKey="AdminSwitchDefaultStoreViewForSubCategory">
60+
<argument name="storeView" value="_defaultStore.name"/>
61+
</actionGroup>
62+
<actionGroup ref="AdminChangeSeoUrlKeyForSubCategoryWithoutRedirectActionGroup" stepKey="changeSeoUrlKeyForSubCategoryDefaultStore">
63+
<argument name="value" value="{{SimpleSubCategoryDifferentUrlStore.url_key_default_store}}"/>
64+
</actionGroup>
65+
<actionGroup ref="AdminSwitchStoreViewActionGroup" stepKey="AdminSwitchCustomStoreViewForSubCategory">
66+
<argument name="storeView" value="customStore.name"/>
67+
</actionGroup>
68+
69+
<actionGroup ref="AdminChangeSeoUrlKeyForSubCategoryWithoutRedirectActionGroup" stepKey="changeSeoUrlKeyForSubCategoryCustomStore">
70+
<argument name="value" value="{{SimpleSubCategoryDifferentUrlStore.url_key_custom_store}}"/>
71+
</actionGroup>
72+
<actionGroup ref="AssertStorefrontProductRewriteUrlSubCategoryActionGroup" stepKey="validatesRewriteUrlDefaultStore">
73+
<argument name="category" value="{{_defaultCategoryDifferentUrlStore.url_key_default_store}}"/>
74+
<argument name="product" value="SimpleProduct" />
75+
</actionGroup>
76+
77+
<actionGroup ref="StorefrontSwitchStoreViewActionGroup" stepKey="switchStore">
78+
<argument name="storeView" value="customStore" />
79+
</actionGroup>
80+
<actionGroup ref="AssertStorefrontProductRewriteUrlSubCategoryActionGroup" stepKey="validatesRewriteUrlCustomStore">
81+
<argument name="category" value="{{_defaultCategoryDifferentUrlStore.url_key_custom_store}}"/>
82+
<argument name="product" value="SimpleProduct" />
83+
</actionGroup>
84+
85+
</test>
86+
</tests>

app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Product/AnchorUrlRewriteGeneratorTest.php

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,53 +3,67 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\CatalogUrlRewrite\Test\Unit\Model\Product;
79

10+
use Magento\Catalog\Api\CategoryRepositoryInterface;
11+
use Magento\Catalog\Model\Product;
12+
use Magento\CatalogUrlRewrite\Model\ObjectRegistry;
13+
use Magento\CatalogUrlRewrite\Model\Product\AnchorUrlRewriteGenerator;
14+
use Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator;
815
use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
916
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
17+
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
18+
use Magento\UrlRewrite\Service\V1\Data\UrlRewriteFactory;
19+
use PHPUnit\Framework\TestCase;
20+
use PHPUnit_Framework_MockObject_MockObject as MockObject;
1021

11-
class AnchorUrlRewriteGeneratorTest extends \PHPUnit\Framework\TestCase
22+
class AnchorUrlRewriteGeneratorTest extends TestCase
1223
{
13-
/** @var \Magento\CatalogUrlRewrite\Model\Product\AnchorUrlRewriteGenerator */
24+
/** @var AnchorUrlRewriteGenerator */
1425
protected $anchorUrlRewriteGenerator;
1526

16-
/** @var \Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator|\PHPUnit_Framework_MockObject_MockObject */
27+
/** @var ProductUrlPathGenerator|MockObject */
1728
protected $productUrlPathGenerator;
1829

19-
/** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject */
30+
/** @var Product|MockObject */
2031
protected $product;
2132

22-
/** @var \Magento\Catalog\Api\CategoryRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject */
33+
/** @var CategoryRepositoryInterface|MockObject */
2334
private $categoryRepositoryInterface;
2435

25-
/** @var \Magento\CatalogUrlRewrite\Model\ObjectRegistry|\PHPUnit_Framework_MockObject_MockObject */
36+
/** @var ObjectRegistry|MockObject */
2637
protected $categoryRegistry;
2738

28-
/** @var \Magento\UrlRewrite\Service\V1\Data\UrlRewriteFactory|\PHPUnit_Framework_MockObject_MockObject */
39+
/** @var UrlRewriteFactory|MockObject */
2940
protected $urlRewriteFactory;
3041

31-
/** @var \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|\PHPUnit_Framework_MockObject_MockObject */
42+
/** @var UrlRewrite|MockObject */
3243
protected $urlRewrite;
3344

45+
/**
46+
* @inheritDoc
47+
*/
3448
protected function setUp()
3549
{
36-
$this->urlRewriteFactory = $this->getMockBuilder(\Magento\UrlRewrite\Service\V1\Data\UrlRewriteFactory::class)
50+
$this->urlRewriteFactory = $this->getMockBuilder(UrlRewriteFactory::class)
3751
->setMethods(['create'])
3852
->disableOriginalConstructor()->getMock();
39-
$this->urlRewrite = $this->getMockBuilder(\Magento\UrlRewrite\Service\V1\Data\UrlRewrite::class)
53+
$this->urlRewrite = $this->getMockBuilder(UrlRewrite::class)
4054
->disableOriginalConstructor()->getMock();
41-
$this->product = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
55+
$this->product = $this->getMockBuilder(Product::class)
4256
->disableOriginalConstructor()->getMock();
4357
$this->categoryRepositoryInterface = $this->getMockBuilder(
44-
\Magento\Catalog\Api\CategoryRepositoryInterface::class
58+
CategoryRepositoryInterface::class
4559
)->disableOriginalConstructor()->getMock();
46-
$this->categoryRegistry = $this->getMockBuilder(\Magento\CatalogUrlRewrite\Model\ObjectRegistry::class)
60+
$this->categoryRegistry = $this->getMockBuilder(ObjectRegistry::class)
4761
->disableOriginalConstructor()->getMock();
4862
$this->productUrlPathGenerator = $this->getMockBuilder(
49-
\Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator::class
63+
ProductUrlPathGenerator::class
5064
)->disableOriginalConstructor()->getMock();
5165
$this->anchorUrlRewriteGenerator = (new ObjectManager($this))->getObject(
52-
\Magento\CatalogUrlRewrite\Model\Product\AnchorUrlRewriteGenerator::class,
66+
AnchorUrlRewriteGenerator::class,
5367
[
5468
'productUrlPathGenerator' => $this->productUrlPathGenerator,
5569
'urlRewriteFactory' => $this->urlRewriteFactory,
@@ -58,7 +72,12 @@ protected function setUp()
5872
);
5973
}
6074

61-
public function testGenerateEmpty()
75+
/**
76+
* Verify generate if category registry list is empty.
77+
*
78+
* @return void
79+
*/
80+
public function testGenerateEmpty(): void
6281
{
6382
$this->categoryRegistry->expects($this->any())->method('getList')->will($this->returnValue([]));
6483

@@ -68,7 +87,12 @@ public function testGenerateEmpty()
6887
);
6988
}
7089

71-
public function testGenerateCategories()
90+
/**
91+
* Verify generate product rewrites for anchor categories.
92+
*
93+
* @return void
94+
*/
95+
public function testGenerateCategories(): void
7296
{
7397
$urlPathWithCategory = 'category1/category2/category3/simple-product.html';
7498
$storeId = 10;
@@ -100,9 +124,9 @@ public function testGenerateCategories()
100124
->expects($this->any())
101125
->method('get')
102126
->withConsecutive(
103-
[ 'category_id' => $categoryIds[0]],
104-
[ 'category_id' => $categoryIds[1]],
105-
[ 'category_id' => $categoryIds[2]]
127+
[$categoryIds[0], $storeId],
128+
[$categoryIds[1], $storeId],
129+
[$categoryIds[2], $storeId]
106130
)
107131
->will($this->returnValue($category));
108132
$this->categoryRegistry->expects($this->any())->method('getList')
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\CatalogUrlRewrite\Model\Product;
9+
10+
use Magento\Catalog\Api\ProductRepositoryInterface;
11+
use Magento\CatalogUrlRewrite\Model\ObjectRegistryFactory;
12+
use Magento\Framework\ObjectManagerInterface;
13+
use Magento\Store\Model\Store;
14+
use Magento\TestFramework\Helper\Bootstrap;
15+
use PHPUnit\Framework\TestCase;
16+
17+
/**
18+
* Verify generate url rewrites for anchor categories.
19+
*/
20+
class AnchorUrlRewriteGeneratorTest extends TestCase
21+
{
22+
23+
/**
24+
* @var ObjectManagerInterface
25+
*/
26+
private $objectManager;
27+
28+
/**
29+
* @var ProductRepositoryInterface
30+
*/
31+
private $productRepository;
32+
33+
/**
34+
* @var ObjectRegistryFactory
35+
*/
36+
private $objectRegistryFactory;
37+
38+
/**
39+
* @inheritDoc
40+
*/
41+
public function setUp()
42+
{
43+
parent::setUp(); // TODO: Change the autogenerated stub
44+
45+
$this->objectManager = Bootstrap::getObjectManager();
46+
$this->productRepository = $this->objectManager->create(ProductRepositoryInterface::class);
47+
$this->objectRegistryFactory = $this->objectManager->create(ObjectRegistryFactory::class);
48+
}
49+
50+
/**
51+
* Verify correct generate of the relative "StoreId"
52+
*
53+
* @param string $expect
54+
* @return void
55+
* @throws \Magento\Framework\Exception\LocalizedException
56+
* @throws \Magento\Framework\Exception\NoSuchEntityException
57+
* @magentoDataFixture Magento/CatalogUrlRewrite/_files/product_with_stores.php
58+
* @magentoDbIsolation disabled
59+
* @dataProvider getConfigGenerate
60+
*/
61+
public function testGenerate(string $expect): void
62+
{
63+
$product = $this->productRepository->get('simple');
64+
$categories = $product->getCategoryCollection();
65+
$productCategories = $this->objectRegistryFactory->create(['entities' => $categories]);
66+
67+
/** @var AnchorUrlRewriteGenerator $generator */
68+
$generator = $this->objectManager->get(AnchorUrlRewriteGenerator::class);
69+
70+
/** @var $store Store */
71+
$store = Bootstrap::getObjectManager()->get(Store::class);
72+
$store->load('fixture_second_store', 'code');
73+
74+
$urls = $generator->generate($store->getId(), $product, $productCategories);
75+
76+
$this->assertEquals($expect, $urls[0]->getRequestPath());
77+
}
78+
79+
/**
80+
* Data provider for testGenerate
81+
*
82+
* @return array
83+
*/
84+
public function getConfigGenerate(): array
85+
{
86+
return [
87+
[
88+
'expect' => 'category-1-custom/simple-product.html'
89+
]
90+
];
91+
}
92+
}

0 commit comments

Comments
 (0)