EntityUrlTest.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  1. <?php
  2. namespace Drupal\Tests\Core\Entity;
  3. use Drupal\Core\DependencyInjection\ContainerBuilder;
  4. use Drupal\Core\Entity\EntityBase;
  5. use Drupal\Core\Entity\EntityMalformedException;
  6. use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
  7. use Drupal\Core\Entity\EntityTypeInterface;
  8. use Drupal\Core\Entity\Exception\UndefinedLinkTemplateException;
  9. use Drupal\Core\Entity\RevisionableInterface;
  10. use Drupal\Core\GeneratedUrl;
  11. use Drupal\Core\Link;
  12. use Drupal\Core\Routing\UrlGeneratorInterface;
  13. use Drupal\Core\Url;
  14. use Drupal\Tests\UnitTestCase;
  15. use Symfony\Component\Routing\Exception\MissingMandatoryParametersException;
  16. /**
  17. * Tests URL handling of the \Drupal\Core\Entity\Entity class.
  18. *
  19. * @coversDefaultClass \Drupal\Core\Entity\Entity
  20. *
  21. * @group Entity
  22. */
  23. class EntityUrlTest extends UnitTestCase {
  24. /**
  25. * The entity type bundle info service mock used in this test.
  26. *
  27. * @var \Prophecy\Prophecy\ProphecyInterface|\Drupal\Core\Entity\EntityTypeBundleInfoInterface
  28. */
  29. protected $entityTypeBundleInfo;
  30. /**
  31. * The ID of the entity type used in this test.
  32. *
  33. * @var string
  34. */
  35. protected $entityTypeId = 'test_entity';
  36. /**
  37. * The entity type mock used in this test.
  38. *
  39. * @var \Prophecy\Prophecy\ProphecyInterface|\Drupal\Core\Entity\EntityTypeInterface
  40. */
  41. protected $entityType;
  42. /**
  43. * The ID of the entity used in this test.
  44. *
  45. * @var int
  46. */
  47. protected $entityId = 1;
  48. /**
  49. * The revision ID of the entity used in this test.
  50. *
  51. * @var int
  52. */
  53. protected $revisionId = 2;
  54. /**
  55. * The language code of the entity used in this test.
  56. *
  57. * @var string
  58. */
  59. protected $langcode = 'en';
  60. /**
  61. * Indicator for default revisions.
  62. *
  63. * @var true
  64. */
  65. const DEFAULT_REVISION = TRUE;
  66. /**
  67. * Indicator for non-default revisions.
  68. *
  69. * @var false
  70. */
  71. const NON_DEFAULT_REVISION = FALSE;
  72. /**
  73. * Indicator that the test entity type has no bundle key.
  74. *
  75. * @var false
  76. */
  77. const HAS_NO_BUNDLE_KEY = FALSE;
  78. /**
  79. * Indicator that the test entity type has a bundle key.
  80. *
  81. * @var true
  82. */
  83. const HAS_BUNDLE_KEY = TRUE;
  84. /**
  85. * Tests the toUrl() method without an entity ID.
  86. *
  87. * @covers ::toUrl
  88. */
  89. public function testToUrlNoId() {
  90. $entity = $this->getEntity(EntityBase::class, []);
  91. $this->expectException(EntityMalformedException::class);
  92. $this->expectExceptionMessage('The "' . $this->entityTypeId . '" entity cannot have a URI as it does not have an ID');
  93. $entity->toUrl();
  94. }
  95. /**
  96. * Tests the toUrl() method with simple link templates.
  97. *
  98. * @param string $link_template
  99. * The link template to test.
  100. * @param string $expected_route_name
  101. * The expected route name of the generated URL.
  102. *
  103. * @dataProvider providerTestToUrlLinkTemplates
  104. *
  105. * @covers ::toUrl
  106. * @covers ::linkTemplates
  107. * @covers ::urlRouteParameters
  108. */
  109. public function testToUrlLinkTemplates($link_template, $expected_route_name) {
  110. $values = ['id' => $this->entityId, 'langcode' => $this->langcode];
  111. $entity = $this->getEntity(EntityBase::class, $values);
  112. $this->registerLinkTemplate($link_template);
  113. /** @var \Drupal\Core\Url $url */
  114. $url = $entity->toUrl($link_template);
  115. // The entity ID is the sole route parameter for the link templates tested
  116. // here.
  117. $this->assertUrl($expected_route_name, ['test_entity' => $this->entityId], $entity, TRUE, $url);
  118. }
  119. /**
  120. * Provides data for testToUrlLinkTemplates().
  121. *
  122. * @return array
  123. * An array of test cases for testToUrlLinkTemplates().
  124. */
  125. public function providerTestToUrlLinkTemplates() {
  126. $test_cases = [];
  127. $test_cases['canonical'] = ['canonical', 'entity.test_entity.canonical'];
  128. $test_cases['version-history'] = ['version-history', 'entity.test_entity.version_history'];
  129. $test_cases['edit-form'] = ['edit-form', 'entity.test_entity.edit_form'];
  130. $test_cases['delete-form'] = ['delete-form', 'entity.test_entity.delete_form'];
  131. $test_cases['revision'] = ['revision', 'entity.test_entity.revision'];
  132. return $test_cases;
  133. }
  134. /**
  135. * Tests the toUrl() method with the 'revision' link template.
  136. *
  137. * @param bool $is_default_revision
  138. * Whether or not the mock entity should be the default revision.
  139. * @param string $link_template
  140. * The link template to test.
  141. * @param string $expected_route_name
  142. * The expected route name of the generated URL.
  143. * @param array $expected_route_parameters
  144. * The expected route parameters of the generated URL.
  145. *
  146. * @dataProvider providerTestToUrlLinkTemplateRevision
  147. *
  148. * @covers ::toUrl
  149. * @covers ::linkTemplates
  150. * @covers ::urlRouteParameters
  151. */
  152. public function testToUrlLinkTemplateRevision($is_default_revision, $link_template, $expected_route_name, array $expected_route_parameters) {
  153. $values = ['id' => $this->entityId, 'langcode' => $this->langcode];
  154. $entity = $this->getEntity(RevisionableEntity::class, $values);
  155. $entity->method('getRevisionId')->willReturn($this->revisionId);
  156. $entity->method('isDefaultRevision')->willReturn($is_default_revision);
  157. $this->registerLinkTemplate($link_template);
  158. // Even though this is tested with both the 'canonical' and the 'revision'
  159. // template registered with the entity, we always ask for the 'revision'
  160. // link template, to test that it falls back to the 'canonical' link
  161. // template in case of the default revision.
  162. /** @var \Drupal\Core\Url $url */
  163. $url = $entity->toUrl('revision');
  164. $this->assertUrl($expected_route_name, $expected_route_parameters, $entity, TRUE, $url);
  165. }
  166. /**
  167. * Provides data for testToUrlLinkTemplateRevision().
  168. *
  169. * @return array
  170. * An array of test cases for testToUrlLinkTemplateRevision().
  171. */
  172. public function providerTestToUrlLinkTemplateRevision() {
  173. $test_cases = [];
  174. $route_parameters = ['test_entity' => $this->entityId];
  175. $test_cases['default_revision'] = [static::DEFAULT_REVISION, 'canonical', 'entity.test_entity.canonical', $route_parameters];
  176. // Add the revision ID to the expected route parameters.
  177. $route_parameters['test_entity_revision'] = $this->revisionId;
  178. $test_cases['non_default_revision'] = [static::NON_DEFAULT_REVISION, 'revision', 'entity.test_entity.revision', $route_parameters];
  179. return $test_cases;
  180. }
  181. /**
  182. * Tests the toUrl() method with link templates without an entity ID.
  183. *
  184. * @param string $link_template
  185. * The link template to test.
  186. * @param string $expected_route_name
  187. * The expected route name of the generated URL.
  188. *
  189. * @dataProvider providerTestToUrlLinkTemplateNoId
  190. *
  191. * @covers ::toUrl
  192. * @covers ::linkTemplates
  193. * @covers ::urlRouteParameters
  194. */
  195. public function testToUrlLinkTemplateNoId($link_template, $expected_route_name) {
  196. $entity = $this->getEntity(EntityBase::class, ['id' => $this->entityId]);
  197. $this->registerLinkTemplate($link_template);
  198. /** @var \Drupal\Core\Url $url */
  199. $url = $entity->toUrl($link_template);
  200. $this->assertUrl($expected_route_name, [], $entity, FALSE, $url);
  201. }
  202. /**
  203. * Provides data for testToUrlLinkTemplateNoId().
  204. *
  205. * @return array
  206. * An array of test cases for testToUrlLinkTemplateNoId().
  207. */
  208. public function providerTestToUrlLinkTemplateNoId() {
  209. $test_cases = [];
  210. $test_cases['collection'] = ['collection', 'entity.test_entity.collection'];
  211. $test_cases['add-page'] = ['add-page', 'entity.test_entity.add_page'];
  212. return $test_cases;
  213. }
  214. /**
  215. * Tests the toUrl() method with the 'revision' link template.
  216. *
  217. * @param bool $has_bundle_key
  218. * Whether or not the mock entity type should have a bundle key.
  219. * @param string|null $bundle_entity_type
  220. * The ID of the bundle entity type of the mock entity type, or NULL if the
  221. * mock entity type should not have a bundle entity type.
  222. * @param string $bundle_key
  223. * The bundle key of the mock entity type or FALSE if the entity type should
  224. * not have a bundle key.
  225. * @param array $expected_route_parameters
  226. * The expected route parameters of the generated URL.
  227. *
  228. * @dataProvider providerTestToUrlLinkTemplateAddForm
  229. *
  230. * @covers ::toUrl
  231. * @covers ::linkTemplates
  232. * @covers ::urlRouteParameters
  233. */
  234. public function testToUrlLinkTemplateAddForm($has_bundle_key, $bundle_entity_type, $bundle_key, $expected_route_parameters) {
  235. $values = ['id' => $this->entityId, 'langcode' => $this->langcode];
  236. $entity = $this->getEntity(EntityBase::class, $values);
  237. $this->entityType->hasKey('bundle')->willReturn($has_bundle_key);
  238. $this->entityType->getBundleEntityType()->willReturn($bundle_entity_type);
  239. $this->entityType->getKey('bundle')->willReturn($bundle_key);
  240. $link_template = 'add-form';
  241. $this->registerLinkTemplate($link_template);
  242. /** @var \Drupal\Core\Url $url */
  243. $url = $entity->toUrl($link_template);
  244. $this->assertUrl('entity.test_entity.add_form', $expected_route_parameters, $entity, FALSE, $url);
  245. }
  246. /**
  247. * Provides data for testToUrlLinkTemplateAddForm().
  248. *
  249. * @return array
  250. * An array of test cases for testToUrlLinkTemplateAddForm().
  251. */
  252. public function providerTestToUrlLinkTemplateAddForm() {
  253. $test_cases = [];
  254. $route_parameters = [];
  255. $test_cases['no_bundle_key'] = [static::HAS_NO_BUNDLE_KEY, NULL, FALSE, $route_parameters];
  256. $route_parameters = ['type' => $this->entityTypeId];
  257. $test_cases['bundle_entity_type'] = [static::HAS_BUNDLE_KEY, 'type', FALSE, $route_parameters];
  258. $test_cases['bundle_key'] = [static::HAS_BUNDLE_KEY, NULL, 'type', $route_parameters];
  259. return $test_cases;
  260. }
  261. /**
  262. * Tests the toUrl() method with neither link templates nor a URI callback.
  263. *
  264. * @param array $bundle_info
  265. * An array of bundle info to register.
  266. * @param string $uri_callback
  267. * The entity type URI callback to register.
  268. *
  269. * @dataProvider providerTestToUrlUriCallbackUndefined
  270. *
  271. * @covers ::toUrl
  272. * @covers ::linkTemplates
  273. */
  274. public function testToUrlUriCallbackUndefined(array $bundle_info, $uri_callback) {
  275. $entity = $this->getEntity(EntityBase::class, ['id' => $this->entityId]);
  276. $this->registerBundleInfo($bundle_info);
  277. $this->entityType->getUriCallback()->willReturn($uri_callback);
  278. $link_template = 'canonical';
  279. $this->expectException(UndefinedLinkTemplateException::class);
  280. $this->expectExceptionMessage("No link template '$link_template' found for the '$this->entityTypeId' entity type");
  281. $entity->toUrl($link_template);
  282. }
  283. /**
  284. * Provides data for testToUrlUriCallbackUndefined().
  285. *
  286. * @return array
  287. * An array of test cases for testToUrlUriCallbackUndefined().
  288. */
  289. public function providerTestToUrlUriCallbackUndefined() {
  290. $test_cases = [];
  291. $test_cases['no_callback'] = [[], NULL];
  292. $test_cases['uri_callback'] = [[], 'not_a_callable'];
  293. $test_cases['bundle_uri_callback'] = [['uri_callback' => 'not_a_callable'], NULL];
  294. return $test_cases;
  295. }
  296. /**
  297. * Tests the toUrl() method with a URI callback.
  298. *
  299. * @param array $bundle_info
  300. * An array of bundle info to register.
  301. * @param string $uri_callback
  302. * The entity type URI callback to register.
  303. *
  304. * @covers ::toUrl
  305. * @covers ::linkTemplates
  306. *
  307. * @dataProvider providerTestToUrlUriCallback
  308. */
  309. public function testToUrlUriCallback(array $bundle_info, $uri_callback) {
  310. $entity = $this->getEntity(EntityBase::class, ['id' => $this->entityId, 'langcode' => $this->langcode]);
  311. $this->registerBundleInfo($bundle_info);
  312. $this->entityType->getUriCallback()->willReturn($uri_callback);
  313. /** @var \Drupal\Core\Url $url */
  314. $url = $entity->toUrl('canonical');
  315. $this->assertUrl('<none>', [], $entity, TRUE, $url);
  316. }
  317. /**
  318. * Provides data for testToUrlUriCallback().
  319. *
  320. * @return array
  321. * An array of test cases for testToUrlUriCallback().
  322. */
  323. public function providerTestToUrlUriCallback() {
  324. $test_cases = [];
  325. $uri_callback = function () {
  326. return Url::fromRoute('<none>');
  327. };
  328. $test_cases['uri_callback'] = [[], $uri_callback];
  329. $test_cases['bundle_uri_callback'] = [['uri_callback' => $uri_callback], NULL];
  330. return $test_cases;
  331. }
  332. /**
  333. * Tests the urlInfo() method.
  334. *
  335. * @param string $rel
  336. * The link relation to test.
  337. * @param array $options
  338. * An array of URL options to test with.
  339. *
  340. * @covers ::urlInfo
  341. *
  342. * @dataProvider providerTestUrlInfo
  343. *
  344. * @group legacy
  345. * @expectedDeprecation EntityInterface::urlInfo() is deprecated in Drupal 8.0.0 and will be removed in Drupal 9.0.0. EntityInterface::toUrl() instead. See https://www.drupal.org/node/2614344
  346. */
  347. public function testUrlInfo($rel, $options) {
  348. $entity = $this->getEntity(EntityBase::class, [], ['toUrl']);
  349. $entity->expects($this->once())
  350. ->method('toUrl')
  351. ->with($rel, $options);
  352. $entity->urlInfo($rel, $options);
  353. }
  354. /**
  355. * Tests the link() method.
  356. *
  357. * @covers ::urlInfo
  358. *
  359. * @group legacy
  360. * @expectedDeprecation EntityInterface::link() is deprecated in Drupal 8.0.0 and will be removed in Drupal 9.0.0. Use EntityInterface::toLink()->toString() instead. Note, the default relationship for configuration entities changes from 'edit-form' to 'canonical'. See https://www.drupal.org/node/2614344
  361. */
  362. public function testLink() {
  363. $link = $this->createMock(Link::class);
  364. $link->expects($this->once())
  365. ->method('toString')
  366. ->willReturn('<a href="/foo">The link</a>');
  367. $entity = $this->getEntity(EntityBase::class, [], ['toLink']);
  368. $entity->expects($this->once())
  369. ->method('toLink')
  370. ->with(NULL, 'canonical')
  371. ->willReturn($link);
  372. $this->assertEquals('<a href="/foo">The link</a>', $entity->link());
  373. }
  374. /**
  375. * Provides data for testUrlInfo().
  376. *
  377. * @return array
  378. * An array of test cases for testUrlInfo().
  379. */
  380. public function providerTestUrlInfo() {
  381. $test_cases = [];
  382. $test_cases['default'] = ['canonical', []];
  383. $test_cases['with_option'] = ['canonical', ['absolute' => TRUE]];
  384. $test_cases['revision'] = ['revision', []];
  385. return $test_cases;
  386. }
  387. /**
  388. * Tests the url() method without an entity ID.
  389. *
  390. * @param string $rel
  391. * The link relation to test.
  392. *
  393. * @covers ::url
  394. * @covers ::hasLinkTemplate
  395. * @covers ::linkTemplates
  396. *
  397. * @dataProvider providerTestUrl
  398. *
  399. * @group legacy
  400. * @expectedDeprecation EntityInterface::url() is deprecated in Drupal 8.0.0 and will be removed in Drupal 9.0.0. EntityInterface::toUrl() instead. Note, a \Drupal\Core\Url object is returned. See https://www.drupal.org/node/2614344
  401. */
  402. public function testUrlEmpty($rel) {
  403. $entity = $this->getEntity(EntityBase::class, []);
  404. $this->assertEquals('', $entity->url($rel));
  405. }
  406. /**
  407. * Provides data for testUrlEmpty().
  408. *
  409. * @return array
  410. * An array of test cases for testUrlEmpty().
  411. */
  412. public function providerTestUrlEmpty() {
  413. $test_cases = [];
  414. $test_cases['default'] = ['canonical', []];
  415. $test_cases['revision'] = ['revision', []];
  416. return $test_cases;
  417. }
  418. /**
  419. * Tests the url() method.
  420. *
  421. * @param string $rel
  422. * The link relation to test.
  423. * @param array $options
  424. * An array of URL options to call url() with.
  425. * @param array $default_options
  426. * An array of URL options that toUrl() should generate.
  427. * @param array $expected_options
  428. * An array of combined URL options that should be set on the final URL.
  429. *
  430. * @covers ::url
  431. * @covers ::hasLinkTemplate
  432. * @covers ::linkTemplates
  433. *
  434. * @dataProvider providerTestUrl
  435. *
  436. * @group legacy
  437. * @expectedDeprecation EntityInterface::url() is deprecated in Drupal 8.0.0 and will be removed in Drupal 9.0.0. EntityInterface::toUrl() instead. Note, a \Drupal\Core\Url object is returned. See https://www.drupal.org/node/2614344
  438. */
  439. public function testUrl($rel, $options, $default_options, $expected_options) {
  440. $entity = $this->getEntity(EntityBase::class, ['id' => $this->entityId], ['toUrl']);
  441. $this->registerLinkTemplate($rel);
  442. $uri = $this->prophesize(Url::class);
  443. $uri->getOptions()->willReturn($default_options);
  444. $uri->setOptions($expected_options)->shouldBeCalled();
  445. $url_string = "/test-entity/{$this->entityId}/$rel";
  446. $uri->toString()->willReturn($url_string);
  447. $entity->expects($this->once())
  448. ->method('toUrl')
  449. ->with($rel)
  450. ->willReturn($uri->reveal());
  451. $this->assertEquals($url_string, $entity->url($rel, $options));
  452. }
  453. /**
  454. * Provides data for testUrl().
  455. *
  456. * @return array
  457. * An array of test cases for testUrl().
  458. */
  459. public function providerTestUrl() {
  460. $test_cases = [];
  461. $test_cases['default'] = ['canonical', [], [], []];
  462. $test_cases['revision'] = ['revision', [], [], []];
  463. $test_cases['option'] = ['canonical', ['absolute' => TRUE], [], ['absolute' => TRUE]];
  464. $test_cases['default_option'] = ['canonical', [], ['absolute' => TRUE], ['absolute' => TRUE]];
  465. $test_cases['option_merge'] = ['canonical', ['absolute' => TRUE], ['entity_type' => $this->entityTypeId], ['absolute' => TRUE, 'entity_type' => $this->entityTypeId]];
  466. $test_cases['option_override'] = ['canonical', ['absolute' => TRUE], ['absolute' => FALSE], ['absolute' => TRUE]];
  467. return $test_cases;
  468. }
  469. /**
  470. * Tests the uriRelationships() method.
  471. *
  472. * @covers ::uriRelationships
  473. */
  474. public function testUriRelationships() {
  475. $entity = $this->getEntity(EntityBase::class, ['id' => $this->entityId]);
  476. $container_builder = new ContainerBuilder();
  477. $url_generator = $this->createMock(UrlGeneratorInterface::class);
  478. $container_builder->set('url_generator', $url_generator);
  479. \Drupal::setContainer($container_builder);
  480. // Test route with no mandatory parameters.
  481. $this->registerLinkTemplate('canonical');
  482. $route_name_0 = 'entity.' . $this->entityTypeId . '.canonical';
  483. $url_generator->expects($this->at(0))
  484. ->method('generateFromRoute')
  485. ->with($route_name_0)
  486. ->willReturn((new GeneratedUrl())->setGeneratedUrl('/entity_test'));
  487. $this->assertEquals(['canonical'], $entity->uriRelationships());
  488. // Test route with non-default mandatory parameters.
  489. $this->registerLinkTemplate('{non_default_parameter}');
  490. $route_name_1 = 'entity.' . $this->entityTypeId . '.{non_default_parameter}';
  491. $url_generator->expects($this->at(0))
  492. ->method('generateFromRoute')
  493. ->with($route_name_1)
  494. ->willThrowException(new MissingMandatoryParametersException());
  495. $this->assertEquals([], $entity->uriRelationships());
  496. }
  497. /**
  498. * Returns a mock entity for testing.
  499. *
  500. * @param string $class
  501. * The class name to mock. Should be \Drupal\Core\Entity\Entity or a
  502. * subclass.
  503. * @param array $values
  504. * An array of entity values to construct the mock entity with.
  505. * @param array $methods
  506. * (optional) An array of additional methods to mock on the entity object.
  507. * The getEntityType() and entityTypeBundleInfo() methods are always mocked.
  508. *
  509. * @return \Drupal\Core\Entity\Entity|\PHPUnit\Framework\MockObject\MockObject
  510. */
  511. protected function getEntity($class, array $values, array $methods = []) {
  512. $methods = array_merge($methods, ['getEntityType', 'entityTypeBundleInfo']);
  513. // Prophecy does not allow prophesizing abstract classes while actually
  514. // calling their code. We use Prophecy below because that allows us to
  515. // add method prophecies later while still revealing the prophecy now.
  516. $entity = $this->getMockBuilder($class)
  517. ->setConstructorArgs([$values, $this->entityTypeId])
  518. ->setMethods($methods)
  519. ->getMockForAbstractClass();
  520. $this->entityType = $this->prophesize(EntityTypeInterface::class);
  521. $this->entityType->getLinkTemplates()->willReturn([]);
  522. $this->entityType->getKey('langcode')->willReturn(FALSE);
  523. $entity->method('getEntityType')->willReturn($this->entityType->reveal());
  524. $this->entityTypeBundleInfo = $this->prophesize(EntityTypeBundleInfoInterface::class);
  525. $entity->method('entityTypeBundleInfo')->willReturn($this->entityTypeBundleInfo->reveal());
  526. return $entity;
  527. }
  528. /**
  529. * Asserts that a given URL object matches the expectations.
  530. *
  531. * @param string $expected_route_name
  532. * The expected route name of the generated URL.
  533. * @param array $expected_route_parameters
  534. * The expected route parameters of the generated URL.
  535. * @param \Drupal\Core\Entity\Entity|\PHPUnit\Framework\MockObject\MockObject $entity
  536. * The entity that is expected to be set as a URL option.
  537. * @param bool $has_language
  538. * Whether or not the URL is expected to have a language option.
  539. * @param \Drupal\Core\Url $url
  540. * The URL option to make the assertions on.
  541. */
  542. protected function assertUrl($expected_route_name, array $expected_route_parameters, $entity, $has_language, Url $url) {
  543. $this->assertEquals($expected_route_name, $url->getRouteName());
  544. $this->assertEquals($expected_route_parameters, $url->getRouteParameters());
  545. $this->assertEquals($this->entityTypeId, $url->getOption('entity_type'));
  546. $this->assertEquals($entity, $url->getOption('entity'));
  547. if ($has_language) {
  548. $this->assertEquals($this->langcode, $url->getOption('language')->getId());
  549. }
  550. else {
  551. $this->assertNull($url->getOption('language'));
  552. }
  553. }
  554. /**
  555. * Registers a link template for the mock entity.
  556. *
  557. * @param string $link_template
  558. * The link template to register.
  559. */
  560. protected function registerLinkTemplate($link_template) {
  561. $link_templates = [
  562. // The path is actually never used because we never invoke the URL
  563. // generator but perform assertions on the URL object directly.
  564. $link_template => "/test-entity/{test_entity}/$link_template",
  565. ];
  566. $this->entityType->getLinkTemplates()->willReturn($link_templates);
  567. }
  568. /**
  569. * Registers bundle information for the mock entity type.
  570. *
  571. * @param array $bundle_info
  572. * The bundle information to register.
  573. */
  574. protected function registerBundleInfo($bundle_info) {
  575. $this->entityTypeBundleInfo
  576. ->getBundleInfo($this->entityTypeId)
  577. ->willReturn([$this->entityTypeId => $bundle_info]);
  578. }
  579. }
  580. abstract class RevisionableEntity extends EntityBase implements RevisionableInterface {}