UrlResolverTest.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. declare(strict_types=1);
  7. namespace Magento\GraphQl\UrlRewrite;
  8. use Magento\Catalog\Api\ProductRepositoryInterface;
  9. use Magento\CmsUrlRewrite\Model\CmsPageUrlRewriteGenerator;
  10. use Magento\TestFramework\ObjectManager;
  11. use Magento\TestFramework\TestCase\GraphQlAbstract;
  12. use Magento\UrlRewrite\Model\UrlFinderInterface;
  13. use Magento\Cms\Helper\Page as PageHelper;
  14. use Magento\Store\Model\ScopeInterface;
  15. use Magento\Framework\App\Config\ScopeConfigInterface;
  16. /**
  17. * Test the GraphQL endpoint's URLResolver query to verify canonical URL's are correctly returned.
  18. */
  19. class UrlResolverTest extends GraphQlAbstract
  20. {
  21. /** @var ObjectManager */
  22. private $objectManager;
  23. protected function setUp()
  24. {
  25. $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
  26. }
  27. /**
  28. * Tests if target_path(canonical_url) is resolved for Product entity
  29. *
  30. * @magentoApiDataFixture Magento/CatalogUrlRewrite/_files/product_with_category.php
  31. */
  32. public function testProductUrlResolver()
  33. {
  34. $productSku = 'p002';
  35. $urlPath = 'p002.html';
  36. /** @var ProductRepositoryInterface $productRepository */
  37. $productRepository = $this->objectManager->get(ProductRepositoryInterface::class);
  38. $product = $productRepository->get($productSku, false, null, true);
  39. $storeId = $product->getStoreId();
  40. /** @var UrlFinderInterface $urlFinder */
  41. $urlFinder = $this->objectManager->get(UrlFinderInterface::class);
  42. $actualUrls = $urlFinder->findOneByData(
  43. [
  44. 'request_path' => $urlPath,
  45. 'store_id' => $storeId
  46. ]
  47. );
  48. $targetPath = $actualUrls->getTargetPath();
  49. $expectedType = $actualUrls->getEntityType();
  50. $query
  51. = <<<QUERY
  52. {
  53. urlResolver(url:"{$urlPath}")
  54. {
  55. id
  56. canonical_url
  57. type
  58. }
  59. }
  60. QUERY;
  61. $response = $this->graphQlQuery($query);
  62. $this->assertArrayHasKey('urlResolver', $response);
  63. $this->assertEquals($product->getEntityId(), $response['urlResolver']['id']);
  64. $this->assertEquals($targetPath, $response['urlResolver']['canonical_url']);
  65. $this->assertEquals(strtoupper($expectedType), $response['urlResolver']['type']);
  66. }
  67. /**
  68. * Tests the use case where canonical_url is provided as resolver input in the Query
  69. *
  70. * @magentoApiDataFixture Magento/CatalogUrlRewrite/_files/product_with_category.php
  71. */
  72. public function testProductUrlWithCanonicalUrlInput()
  73. {
  74. $productSku = 'p002';
  75. $urlPath = 'p002.html';
  76. /** @var ProductRepositoryInterface $productRepository */
  77. $productRepository = $this->objectManager->get(ProductRepositoryInterface::class);
  78. $product = $productRepository->get($productSku, false, null, true);
  79. $storeId = $product->getStoreId();
  80. $product->getUrlKey();
  81. /** @var UrlFinderInterface $urlFinder */
  82. $urlFinder = $this->objectManager->get(UrlFinderInterface::class);
  83. $actualUrls = $urlFinder->findOneByData(
  84. [
  85. 'request_path' => $urlPath,
  86. 'store_id' => $storeId
  87. ]
  88. );
  89. $targetPath = $actualUrls->getTargetPath();
  90. $expectedType = $actualUrls->getEntityType();
  91. $canonicalPath = $actualUrls->getTargetPath();
  92. $query
  93. = <<<QUERY
  94. {
  95. urlResolver(url:"{$canonicalPath}")
  96. {
  97. id
  98. canonical_url
  99. type
  100. }
  101. }
  102. QUERY;
  103. $response = $this->graphQlQuery($query);
  104. $this->assertArrayHasKey('urlResolver', $response);
  105. $this->assertEquals($product->getEntityId(), $response['urlResolver']['id']);
  106. $this->assertEquals($targetPath, $response['urlResolver']['canonical_url']);
  107. $this->assertEquals(strtoupper($expectedType), $response['urlResolver']['type']);
  108. }
  109. /**
  110. * Test for category entity
  111. *
  112. * @magentoApiDataFixture Magento/CatalogUrlRewrite/_files/product_with_category.php
  113. */
  114. public function testCategoryUrlResolver()
  115. {
  116. $productSku = 'p002';
  117. $urlPath2 = 'cat-1.html';
  118. /** @var ProductRepositoryInterface $productRepository */
  119. $productRepository = $this->objectManager->get(ProductRepositoryInterface::class);
  120. $product = $productRepository->get($productSku, false, null, true);
  121. $storeId = $product->getStoreId();
  122. /** @var UrlFinderInterface $urlFinder */
  123. $urlFinder = $this->objectManager->get(UrlFinderInterface::class);
  124. $actualUrls = $urlFinder->findOneByData(
  125. [
  126. 'request_path' => $urlPath2,
  127. 'store_id' => $storeId
  128. ]
  129. );
  130. $categoryId = $actualUrls->getEntityId();
  131. $targetPath = $actualUrls->getTargetPath();
  132. $expectedType = $actualUrls->getEntityType();
  133. $query
  134. = <<<QUERY
  135. {
  136. urlResolver(url:"{$urlPath2}")
  137. {
  138. id
  139. canonical_url
  140. type
  141. }
  142. }
  143. QUERY;
  144. $response = $this->graphQlQuery($query);
  145. $this->assertArrayHasKey('urlResolver', $response);
  146. $this->assertEquals($categoryId, $response['urlResolver']['id']);
  147. $this->assertEquals($targetPath, $response['urlResolver']['canonical_url']);
  148. $this->assertEquals(strtoupper($expectedType), $response['urlResolver']['type']);
  149. }
  150. /**
  151. * @magentoApiDataFixture Magento/Cms/_files/pages.php
  152. */
  153. public function testCMSPageUrlResolver()
  154. {
  155. /** @var \Magento\Cms\Model\Page $page */
  156. $page = $this->objectManager->get(\Magento\Cms\Model\Page::class);
  157. $page->load('page100');
  158. $cmsPageId = $page->getId();
  159. $requestPath = $page->getIdentifier();
  160. /** @var \Magento\CmsUrlRewrite\Model\CmsPageUrlPathGenerator $urlPathGenerator */
  161. $urlPathGenerator = $this->objectManager->get(\Magento\CmsUrlRewrite\Model\CmsPageUrlPathGenerator::class);
  162. /** @param \Magento\Cms\Api\Data\PageInterface $page */
  163. $targetPath = $urlPathGenerator->getCanonicalUrlPath($page);
  164. $expectedEntityType = CmsPageUrlRewriteGenerator::ENTITY_TYPE;
  165. $query
  166. = <<<QUERY
  167. {
  168. urlResolver(url:"{$requestPath}")
  169. {
  170. id
  171. canonical_url
  172. type
  173. }
  174. }
  175. QUERY;
  176. $response = $this->graphQlQuery($query);
  177. $this->assertEquals($cmsPageId, $response['urlResolver']['id']);
  178. $this->assertEquals($targetPath, $response['urlResolver']['canonical_url']);
  179. $this->assertEquals(strtoupper(str_replace('-', '_', $expectedEntityType)), $response['urlResolver']['type']);
  180. }
  181. /**
  182. * Tests the use case where the url_key of the existing product is changed
  183. *
  184. * @magentoApiDataFixture Magento/CatalogUrlRewrite/_files/product_with_category.php
  185. */
  186. public function testProductUrlRewriteResolver()
  187. {
  188. $productSku = 'p002';
  189. /** @var ProductRepositoryInterface $productRepository */
  190. $productRepository = $this->objectManager->get(ProductRepositoryInterface::class);
  191. $product = $productRepository->get($productSku, false, null, true);
  192. $storeId = $product->getStoreId();
  193. $product->setUrlKey('p002-new')->save();
  194. $urlPath = $product->getUrlKey() . '.html';
  195. $this->assertEquals($urlPath, 'p002-new.html');
  196. /** @var UrlFinderInterface $urlFinder */
  197. $urlFinder = $this->objectManager->get(UrlFinderInterface::class);
  198. $actualUrls = $urlFinder->findOneByData(
  199. [
  200. 'request_path' => $urlPath,
  201. 'store_id' => $storeId
  202. ]
  203. );
  204. $targetPath = $actualUrls->getTargetPath();
  205. $expectedType = $actualUrls->getEntityType();
  206. $query
  207. = <<<QUERY
  208. {
  209. urlResolver(url:"{$urlPath}")
  210. {
  211. id
  212. canonical_url
  213. type
  214. }
  215. }
  216. QUERY;
  217. $response = $this->graphQlQuery($query);
  218. $this->assertArrayHasKey('urlResolver', $response);
  219. $this->assertEquals($product->getEntityId(), $response['urlResolver']['id']);
  220. $this->assertEquals($targetPath, $response['urlResolver']['canonical_url']);
  221. $this->assertEquals(strtoupper($expectedType), $response['urlResolver']['type']);
  222. }
  223. /**
  224. * Tests if null is returned when an invalid request_path is provided as input to urlResolver
  225. *
  226. * @magentoApiDataFixture Magento/CatalogUrlRewrite/_files/product_with_category.php
  227. */
  228. public function testInvalidUrlResolverInput()
  229. {
  230. $productSku = 'p002';
  231. $urlPath = 'p002';
  232. /** @var ProductRepositoryInterface $productRepository */
  233. $productRepository = $this->objectManager->get(ProductRepositoryInterface::class);
  234. $product = $productRepository->get($productSku, false, null, true);
  235. $storeId = $product->getStoreId();
  236. /** @var UrlFinderInterface $urlFinder */
  237. $urlFinder = $this->objectManager->get(UrlFinderInterface::class);
  238. $urlFinder->findOneByData(
  239. [
  240. 'request_path' => $urlPath,
  241. 'store_id' => $storeId
  242. ]
  243. );
  244. $query
  245. = <<<QUERY
  246. {
  247. urlResolver(url:"{$urlPath}")
  248. {
  249. id
  250. canonical_url
  251. type
  252. }
  253. }
  254. QUERY;
  255. $response = $this->graphQlQuery($query);
  256. $this->assertArrayHasKey('urlResolver', $response);
  257. $this->assertNull($response['urlResolver']);
  258. }
  259. /**
  260. * Test for category entity with leading slash
  261. *
  262. * @magentoApiDataFixture Magento/CatalogUrlRewrite/_files/product_with_category.php
  263. */
  264. public function testCategoryUrlWithLeadingSlash()
  265. {
  266. $productSku = 'p002';
  267. $urlPath = 'cat-1.html';
  268. /** @var ProductRepositoryInterface $productRepository */
  269. $productRepository = $this->objectManager->get(ProductRepositoryInterface::class);
  270. $product = $productRepository->get($productSku, false, null, true);
  271. $storeId = $product->getStoreId();
  272. /** @var UrlFinderInterface $urlFinder */
  273. $urlFinder = $this->objectManager->get(UrlFinderInterface::class);
  274. $actualUrls = $urlFinder->findOneByData(
  275. [
  276. 'request_path' => $urlPath,
  277. 'store_id' => $storeId
  278. ]
  279. );
  280. $categoryId = $actualUrls->getEntityId();
  281. $targetPath = $actualUrls->getTargetPath();
  282. $expectedType = $actualUrls->getEntityType();
  283. $query = <<<QUERY
  284. {
  285. urlResolver(url:"/{$urlPath}")
  286. {
  287. id
  288. canonical_url
  289. type
  290. }
  291. }
  292. QUERY;
  293. $response = $this->graphQlQuery($query);
  294. $this->assertArrayHasKey('urlResolver', $response);
  295. $this->assertEquals($categoryId, $response['urlResolver']['id']);
  296. $this->assertEquals($targetPath, $response['urlResolver']['canonical_url']);
  297. $this->assertEquals(strtoupper($expectedType), $response['urlResolver']['type']);
  298. }
  299. /**
  300. * Test resolution of '/' path to home page
  301. */
  302. public function testResolveSlash()
  303. {
  304. /** @var \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfigInterface */
  305. $scopeConfigInterface = $this->objectManager->get(ScopeConfigInterface::class);
  306. $homePageIdentifier = $scopeConfigInterface->getValue(
  307. PageHelper::XML_PATH_HOME_PAGE,
  308. ScopeInterface::SCOPE_STORE
  309. );
  310. /** @var \Magento\Cms\Model\Page $page */
  311. $page = $this->objectManager->get(\Magento\Cms\Model\Page::class);
  312. $page->load($homePageIdentifier);
  313. $homePageId = $page->getId();
  314. /** @var \Magento\CmsUrlRewrite\Model\CmsPageUrlPathGenerator $urlPathGenerator */
  315. $urlPathGenerator = $this->objectManager->get(\Magento\CmsUrlRewrite\Model\CmsPageUrlPathGenerator::class);
  316. /** @param \Magento\Cms\Api\Data\PageInterface $page */
  317. $targetPath = $urlPathGenerator->getCanonicalUrlPath($page);
  318. $query
  319. = <<<QUERY
  320. {
  321. urlResolver(url:"/")
  322. {
  323. id
  324. canonical_url
  325. type
  326. }
  327. }
  328. QUERY;
  329. $response = $this->graphQlQuery($query);
  330. $this->assertArrayHasKey('urlResolver', $response);
  331. $this->assertEquals($homePageId, $response['urlResolver']['id']);
  332. $this->assertEquals($targetPath, $response['urlResolver']['canonical_url']);
  333. $this->assertEquals('CMS_PAGE', $response['urlResolver']['type']);
  334. }
  335. }