197 lines
6.9 KiB
PHP
197 lines
6.9 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace Esun3d\LanguageUrlStoreResolver\Test\Unit\Model;
|
|
|
|
use Magento\Store\Model\Store;
|
|
use Magento\Store\Model\StoreManagerInterface;
|
|
use Magento\Store\Model\Website;
|
|
use PHPUnit\Framework\TestCase;
|
|
use Esun3d\LanguageUrlStoreResolver\Model\Config;
|
|
use Esun3d\LanguageUrlStoreResolver\Model\StoreCodeMapper;
|
|
use Esun3d\LanguageUrlStoreResolver\Model\StoreViewRegistry;
|
|
use Esun3d\LanguageUrlStoreResolver\Model\UrlPathConverter;
|
|
|
|
class UrlPathConverterTest extends TestCase
|
|
{
|
|
/**
|
|
* @dataProvider productUrlProvider
|
|
*/
|
|
public function testConvertsGeneratedProductUrlsToLanguageUrls(
|
|
string $url,
|
|
string $language,
|
|
string $expectedUrl
|
|
): void {
|
|
$converter = new UrlPathConverter(
|
|
$this->createConfig(),
|
|
new StoreCodeMapper($this->createRegistry(), $this->createStoreManager('https://example.com/')),
|
|
$this->createRegistry(),
|
|
$this->createStoreManager('https://example.com/')
|
|
);
|
|
|
|
self::assertSame($expectedUrl, $converter->toLanguageUrl($url, $language));
|
|
}
|
|
|
|
/**
|
|
* @return mixed[]
|
|
*/
|
|
public static function productUrlProvider(): array
|
|
{
|
|
return [
|
|
'real english US store code product url' => [
|
|
'https://example.com/en_US/product-a',
|
|
'en',
|
|
'https://example.com/en/product-a',
|
|
],
|
|
'real german DE store code product url' => [
|
|
'https://example.com/de_DE/product-a',
|
|
'de',
|
|
'https://example.com/de/product-a',
|
|
],
|
|
'plain product url gets language prefix' => [
|
|
'https://example.com/product-a',
|
|
'en',
|
|
'https://example.com/en/product-a',
|
|
],
|
|
'language product url is not duplicated' => [
|
|
'https://example.com/en/product-a',
|
|
'en',
|
|
'https://example.com/en/product-a',
|
|
],
|
|
'query and fragment survive conversion' => [
|
|
'https://example.com/en_US/product-a?q=printer#reviews',
|
|
'en',
|
|
'https://example.com/en/product-a?q=printer#reviews',
|
|
],
|
|
];
|
|
}
|
|
|
|
public function testSkipsExternalProductUrl(): void
|
|
{
|
|
$converter = new UrlPathConverter(
|
|
$this->createConfig(),
|
|
new StoreCodeMapper($this->createRegistry(), $this->createStoreManager('https://example.com/')),
|
|
$this->createRegistry(),
|
|
$this->createStoreManager('https://example.com/')
|
|
);
|
|
|
|
self::assertSame(
|
|
'https://cdn.example.net/en_US/product-a',
|
|
$converter->toLanguageUrl('https://cdn.example.net/en_US/product-a', 'en')
|
|
);
|
|
}
|
|
|
|
public function testSkipsStaticProductAssetPath(): void
|
|
{
|
|
$converter = new UrlPathConverter(
|
|
$this->createConfig(),
|
|
new StoreCodeMapper($this->createRegistry(), $this->createStoreManager('https://example.com/')),
|
|
$this->createRegistry(),
|
|
$this->createStoreManager('https://example.com/')
|
|
);
|
|
|
|
self::assertSame(
|
|
'https://example.com/static/version123/frontend/product-a.jpg',
|
|
$converter->toLanguageUrl('https://example.com/static/version123/frontend/product-a.jpg', 'en')
|
|
);
|
|
}
|
|
|
|
public function testOmitsPrefixForWebsiteDefaultLanguage(): void
|
|
{
|
|
$mapper = $this->createMock(StoreCodeMapper::class);
|
|
$mapper->method('isRealStoreCodeInScope')->with('en_US')->willReturn(true);
|
|
$mapper->method('languageFromStoreCode')->with('en_US')->willReturn('en');
|
|
$mapper->method('isLanguageAllowed')->willReturn(false);
|
|
$mapper->method('isDefaultLanguage')->with('en')->willReturn(true);
|
|
|
|
$converter = new UrlPathConverter(
|
|
$this->createConfig(),
|
|
$mapper,
|
|
$this->createRegistry(),
|
|
$this->createStoreManager('https://example.com/')
|
|
);
|
|
|
|
self::assertSame(
|
|
'https://example.com/product-a',
|
|
$converter->toLanguageUrl('https://example.com/en_US/product-a', 'en')
|
|
);
|
|
}
|
|
|
|
private function createConfig(): Config
|
|
{
|
|
$config = $this->createMock(Config::class);
|
|
$config->method('shouldSkipPath')->willReturnCallback(static function (string $path): bool {
|
|
$path = strtolower(trim($path, '/'));
|
|
$skipPrefixes = [
|
|
'admin',
|
|
'rest',
|
|
'graphql',
|
|
'soap',
|
|
'static',
|
|
'media',
|
|
'pub',
|
|
'customer/section/load',
|
|
];
|
|
|
|
foreach ($skipPrefixes as $prefix) {
|
|
if ($path === $prefix || strpos($path, $prefix . '/') === 0) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
});
|
|
|
|
return $config;
|
|
}
|
|
|
|
private function createRegistry(): StoreViewRegistry
|
|
{
|
|
$registry = $this->createMock(StoreViewRegistry::class);
|
|
$registry->method('isKnownLanguage')->willReturnCallback(static function (string $language): bool {
|
|
return in_array($language, ['en', 'de'], true);
|
|
});
|
|
$registry->method('isKnownStoreCode')->willReturnCallback(static function (string $storeCode): bool {
|
|
return in_array($storeCode, ['en_US', 'en_DE', 'de_US', 'de_DE'], true);
|
|
});
|
|
$registry->method('getLanguageByStoreCode')->willReturnCallback(static function (string $storeCode): ?string {
|
|
$map = [
|
|
'en_US' => 'en',
|
|
'en_DE' => 'en',
|
|
'de_US' => 'de',
|
|
'de_DE' => 'de',
|
|
];
|
|
|
|
return $map[$storeCode] ?? null;
|
|
});
|
|
$registry->method('isStoreCodeInWebsite')->willReturnCallback(
|
|
static fn(string $storeCode, int $websiteId): bool =>
|
|
$websiteId === 1 && in_array($storeCode, ['en_US', 'en_DE', 'de_US', 'de_DE'], true)
|
|
);
|
|
$registry->method('isLanguageInWebsite')->willReturnCallback(
|
|
static fn(string $language, int $websiteId): bool =>
|
|
$websiteId === 1 && in_array($language, ['en', 'de'], true)
|
|
);
|
|
|
|
return $registry;
|
|
}
|
|
|
|
private function createStoreManager(string $baseUrl): StoreManagerInterface
|
|
{
|
|
$store = $this->getMockBuilder(Store::class)
|
|
->disableOriginalConstructor()
|
|
->onlyMethods(['getBaseUrl'])
|
|
->getMock();
|
|
$store->method('getBaseUrl')->willReturn($baseUrl);
|
|
|
|
$storeManager = $this->createMock(StoreManagerInterface::class);
|
|
$storeManager->method('getStore')->willReturn($store);
|
|
$website = $this->createMock(Website::class);
|
|
$website->method('getId')->willReturn(1);
|
|
$website->method('getDefaultStore')->willReturn($store);
|
|
$storeManager->method('getWebsite')->willReturn($website);
|
|
|
|
return $storeManager;
|
|
}
|
|
}
|