From b6c4cdc074c9613d2180b2a50efe4b2a7b88f186 Mon Sep 17 00:00:00 2001 From: Dmitry Tsemma Date: Tue, 6 Aug 2024 16:05:39 +0300 Subject: [PATCH] FRW-8522 Adjusted product URL name. (#11025) FRW-8522 Adjusted product URL name. --- .../Product/Url/ProductUrlGenerator.php | 30 ++++++++++- .../Business/ProductBusinessFactory.php | 1 + src/Spryker/Zed/Product/ProductConfig.php | 13 +++++ .../Business/ProductUrlGeneratorTest.php | 47 +++++++++++++++-- .../Zed/Product/Business/UrlHandlingTest.php | 50 +++++++++++++++++-- 5 files changed, 132 insertions(+), 9 deletions(-) diff --git a/src/Spryker/Zed/Product/Business/Product/Url/ProductUrlGenerator.php b/src/Spryker/Zed/Product/Business/Product/Url/ProductUrlGenerator.php index 340494441d..f7a572558d 100644 --- a/src/Spryker/Zed/Product/Business/Product/Url/ProductUrlGenerator.php +++ b/src/Spryker/Zed/Product/Business/Product/Url/ProductUrlGenerator.php @@ -14,6 +14,7 @@ use Spryker\Zed\Product\Business\Product\NameGenerator\ProductAbstractNameGeneratorInterface; use Spryker\Zed\Product\Dependency\Facade\ProductToLocaleInterface; use Spryker\Zed\Product\Dependency\Service\ProductToUtilTextInterface; +use Spryker\Zed\Product\ProductConfig; class ProductUrlGenerator implements ProductUrlGeneratorInterface { @@ -32,19 +33,37 @@ class ProductUrlGenerator implements ProductUrlGeneratorInterface */ protected $utilTextService; + /** + * @var \Spryker\Zed\Product\ProductConfig + */ + protected ProductConfig $productConfig; + + /** + * @var string + */ + protected const STR_SEARCH = '_'; + + /** + * @var string + */ + protected const STR_REPLACE = '-'; + /** * @param \Spryker\Zed\Product\Business\Product\NameGenerator\ProductAbstractNameGeneratorInterface $productAbstractNameGenerator * @param \Spryker\Zed\Product\Dependency\Facade\ProductToLocaleInterface $localeFacade * @param \Spryker\Zed\Product\Dependency\Service\ProductToUtilTextInterface $utilTextService + * @param \Spryker\Zed\Product\ProductConfig $productConfig */ public function __construct( ProductAbstractNameGeneratorInterface $productAbstractNameGenerator, ProductToLocaleInterface $localeFacade, - ProductToUtilTextInterface $utilTextService + ProductToUtilTextInterface $utilTextService, + ProductConfig $productConfig ) { $this->productAbstractNameGenerator = $productAbstractNameGenerator; $this->localeFacade = $localeFacade; $this->utilTextService = $utilTextService; + $this->productConfig = $productConfig; } /** @@ -84,6 +103,13 @@ protected function generateUrlByLocale(ProductAbstractTransfer $productAbstractT $this->productAbstractNameGenerator->getLocalizedProductAbstractName($productAbstractTransfer, $localeTransfer), ); - return '/' . mb_substr($localeTransfer->getLocaleName(), 0, 2) . '/' . $productName . '-' . $productAbstractTransfer->getIdProductAbstract(); + return $this->productConfig->isFullLocaleNamesInUrlEnabled() ? + sprintf( + '/%s/%s-%s', + str_replace(static::STR_SEARCH, static::STR_REPLACE, strtolower($localeTransfer->getLocaleName())), + $productName, + $productAbstractTransfer->getIdProductAbstract(), + ) + : '/' . mb_substr($localeTransfer->getLocaleName(), 0, 2) . '/' . $productName . '-' . $productAbstractTransfer->getIdProductAbstract(); } } diff --git a/src/Spryker/Zed/Product/Business/ProductBusinessFactory.php b/src/Spryker/Zed/Product/Business/ProductBusinessFactory.php index 6bc75a48ae..8ed497dc9a 100644 --- a/src/Spryker/Zed/Product/Business/ProductBusinessFactory.php +++ b/src/Spryker/Zed/Product/Business/ProductBusinessFactory.php @@ -193,6 +193,7 @@ public function createProductUrlGenerator() $this->createProductAbstractNameGenerator(), $this->getLocaleFacade(), $this->getUtilTextService(), + $this->getConfig(), ); } diff --git a/src/Spryker/Zed/Product/ProductConfig.php b/src/Spryker/Zed/Product/ProductConfig.php index dccfa9fa0e..afed9cc65a 100644 --- a/src/Spryker/Zed/Product/ProductConfig.php +++ b/src/Spryker/Zed/Product/ProductConfig.php @@ -103,4 +103,17 @@ public function getTenantIdentifier(): string { return $this->get(ProductConstants::TENANT_IDENTIFIER, ''); } + + /** + * Specification: + * - Defines if full locale name in URL is enabled. + * + * @api + * + * @return bool + */ + public function isFullLocaleNamesInUrlEnabled(): bool + { + return false; + } } diff --git a/tests/SprykerTest/Zed/Product/Business/ProductUrlGeneratorTest.php b/tests/SprykerTest/Zed/Product/Business/ProductUrlGeneratorTest.php index 3cfcc4e41c..d83ae39e80 100644 --- a/tests/SprykerTest/Zed/Product/Business/ProductUrlGeneratorTest.php +++ b/tests/SprykerTest/Zed/Product/Business/ProductUrlGeneratorTest.php @@ -18,6 +18,7 @@ use Spryker\Zed\Product\Business\Product\Url\ProductUrlGenerator; use Spryker\Zed\Product\Dependency\Facade\ProductToLocaleBridge; use Spryker\Zed\Product\Dependency\Service\ProductToUtilTextBridge; +use Spryker\Zed\Product\ProductConfig; /** * Auto-generated group annotations @@ -167,11 +168,11 @@ public function testGetProductUrlShouldReturnTransfer(): void { $expectedDEUrl = (new LocalizedUrlTransfer()) ->setLocale($this->locales['de_DE']) - ->setUrl('/de/product-name-dede-1'); + ->setUrl('/de-de/product-name-dede-1'); $expectedENUrl = (new LocalizedUrlTransfer()) ->setLocale($this->locales['en_US']) - ->setUrl('/en/product-name-enus-1'); + ->setUrl('/en-us/product-name-enus-1'); $productUrlExpected = (new ProductUrlTransfer()) ->setAbstractSku( @@ -187,7 +188,47 @@ public function testGetProductUrlShouldReturnTransfer(): void ->withConsecutive([static::PRODUCT_NAME['de_DE']], [static::PRODUCT_NAME['en_US']]) ->willReturnOnConsecutiveCalls('product-name-dede', 'product-name-enus'); - $urlGenerator = new ProductUrlGenerator($this->productAbstractNameGenerator, $this->localeFacade, $this->utilTextService); + $configMock = $this->createMock(ProductConfig::class); + $configMock->method('isFullLocaleNamesInUrlEnabled')->willReturn(true); + + $urlGenerator = new ProductUrlGenerator($this->productAbstractNameGenerator, $this->localeFacade, $this->utilTextService, $configMock); + $productUrl = $urlGenerator->generateProductUrl($this->productAbstractTransfer); + + $this->assertSame($productUrlExpected->getAbstractSku(), $productUrl->getAbstractSku()); + $this->assertEquals($productUrlExpected, $productUrl); + } + + /** + * @return void + */ + public function testGetProductUrlShouldReturnTransferBCCheck(): void + { + $expectedDEUrl = (new LocalizedUrlTransfer()) + ->setLocale($this->locales['de_DE']) + ->setUrl('/de/product-name-dede-1'); + + $expectedENUrl = (new LocalizedUrlTransfer()) + ->setLocale($this->locales['en_US']) + ->setUrl('/en/product-name-enus-1'); + + $productUrlExpected = (new ProductUrlTransfer()) + ->setAbstractSku( + $this->productAbstractTransfer->getSku(), + ) + ->setUrls( + new ArrayObject([$expectedDEUrl, $expectedENUrl]), + ); + + $this->utilTextService + ->expects($this->exactly(2)) + ->method('generateSlug') + ->withConsecutive([static::PRODUCT_NAME['de_DE']], [static::PRODUCT_NAME['en_US']]) + ->willReturnOnConsecutiveCalls('product-name-dede', 'product-name-enus'); + + $configMock = $this->createMock(ProductConfig::class); + $configMock->method('isFullLocaleNamesInUrlEnabled')->willReturn(false); + + $urlGenerator = new ProductUrlGenerator($this->productAbstractNameGenerator, $this->localeFacade, $this->utilTextService, $configMock); $productUrl = $urlGenerator->generateProductUrl($this->productAbstractTransfer); $this->assertSame($productUrlExpected->getAbstractSku(), $productUrl->getAbstractSku()); diff --git a/tests/SprykerTest/Zed/Product/Business/UrlHandlingTest.php b/tests/SprykerTest/Zed/Product/Business/UrlHandlingTest.php index 37a3ec2a82..d850820048 100644 --- a/tests/SprykerTest/Zed/Product/Business/UrlHandlingTest.php +++ b/tests/SprykerTest/Zed/Product/Business/UrlHandlingTest.php @@ -11,6 +11,8 @@ use Generated\Shared\Transfer\ProductUrlTransfer; use Generated\Shared\Transfer\UrlTransfer; use Spryker\Shared\Url\UrlConfig; +use Spryker\Zed\Product\Business\ProductBusinessFactory; +use Spryker\Zed\Product\ProductConfig; use Spryker\Zed\Url\Business\Exception\UrlExistsException; /** @@ -28,11 +30,51 @@ class UrlHandlingTest extends FacadeTestAbstract /** * @return void */ + protected function setUp(): void + { + parent::setUp(); + + $configMock = $this->createMock(ProductConfig::class); + $configMock->method('isFullLocaleNamesInUrlEnabled')->willReturn(true); + $productBusinessFactory = new ProductBusinessFactory(); + $productBusinessFactory->setConfig($configMock); + $this->productFacade->setFactory($productBusinessFactory); + } + + /** + * @return void + */ public function testCreateProductUrlShouldCreateNewUrlForProductAbstract(): void { $idProductAbstract = $this->productAbstractManager->createProductAbstract($this->productAbstractTransfer); $this->productAbstractTransfer->setIdProductAbstract($idProductAbstract); + $expectedENUrl = (new LocalizedUrlTransfer()) + ->setLocale($this->locales['en_US']) + ->setUrl('/en-us/product-name-enus-' . $idProductAbstract); + $expectedDEUrl = (new LocalizedUrlTransfer()) + ->setLocale($this->locales['de_DE']) + ->setUrl('/de-de/product-name-dede-' . $idProductAbstract); + + $productUrl = $this->productFacade->createProductUrl($this->productAbstractTransfer); + + $this->assertProductUrl($productUrl, $expectedENUrl); + $this->assertProductUrl($productUrl, $expectedDEUrl); + } + + /** + * @return void + */ + public function testCreateProductUrlShouldCreateNewUrlForProductAbstractBCCheck(): void + { + $configMock = $this->createMock(ProductConfig::class); + $configMock->method('isFullLocaleNamesInUrlEnabled')->willReturn(false); + $productBusinessFactory = new ProductBusinessFactory(); + $productBusinessFactory->setConfig($configMock); + $this->productFacade->setFactory($productBusinessFactory); + $idProductAbstract = $this->productAbstractManager->createProductAbstract($this->productAbstractTransfer); + $this->productAbstractTransfer->setIdProductAbstract($idProductAbstract); + $expectedENUrl = (new LocalizedUrlTransfer()) ->setLocale($this->locales['en_US']) ->setUrl('/en/product-name-enus-' . $idProductAbstract); @@ -57,10 +99,10 @@ public function testUpdateProductUrlShouldSaveUrlForProductAbstract(): void $expectedENUrl = (new LocalizedUrlTransfer()) ->setLocale($this->locales['en_US']) - ->setUrl('/en/new-product-name-enus-' . $idProductAbstract); + ->setUrl('/en-us/new-product-name-enus-' . $idProductAbstract); $expectedDEUrl = (new LocalizedUrlTransfer()) ->setLocale($this->locales['de_DE']) - ->setUrl('/de/new-product-name-dede-' . $idProductAbstract); + ->setUrl('/de-de/new-product-name-dede-' . $idProductAbstract); foreach ($this->productAbstractTransfer->getLocalizedAttributes() as $localizedAttribute) { $localizedAttribute->setName('New ' . $localizedAttribute->getName()); @@ -152,10 +194,10 @@ public function testGetProductUrl(): void $expectedENUrl = (new LocalizedUrlTransfer()) ->setLocale($this->locales['en_US']) - ->setUrl('/en/product-name-enus-' . $idProductAbstract); + ->setUrl('/en-us/product-name-enus-' . $idProductAbstract); $expectedDEUrl = (new LocalizedUrlTransfer()) ->setLocale($this->locales['de_DE']) - ->setUrl('/de/product-name-dede-' . $idProductAbstract); + ->setUrl('/de-de/product-name-dede-' . $idProductAbstract); $productUrl = $this->productFacade->getProductUrl($this->productAbstractTransfer);