Commit 554598a5 authored by catch's avatar catch
Browse files

Issue #3409895 by acbramley, longwave, smustgrave: [regression] toUrl can...

Issue #3409895 by acbramley, longwave, smustgrave: [regression] toUrl can incorrectly return edit-form url when another link template shares the canonical url

(cherry picked from commit 9231c9cf)
parent 26c6621e
Loading
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -167,12 +167,13 @@ public function toUrl($rel = NULL, array $options = []) {
    // Use the canonical link template by default, or edit-form if there is not
    // a canonical one.
    if ($rel === NULL) {
      $rel_candidates = array_intersect(
        ['canonical', 'edit-form'],
        array_flip($link_templates),
      );
      $rel = array_shift($rel_candidates);
      if ($rel === NULL) {
      if (isset($link_templates['canonical'])) {
        $rel = 'canonical';
      }
      elseif (isset($link_templates['edit-form'])) {
        $rel = 'edit-form';
      }
      else {
        throw new UndefinedLinkTemplateException("Cannot generate default URL because no link template 'canonical' or 'edit-form' was found for the '{$this->getEntityTypeId()}' entity type");
      }
    }
+28 −4
Original line number Diff line number Diff line
@@ -110,27 +110,51 @@ public function testToUrlNoId() {
  }

  /**
   * Tests the toUrl() method without specifying the $rel parameter..
   * Tests the toUrl() method without specifying the $rel parameter.
   *
   * It should throw an exception when neither canonical and edit-form link
   * templates exist if no parameters are passed in.
   *
   * @covers ::toUrl
   */
  public function testToUrlDefault() {
  public function testToUrlDefaultException(): void {
    $values = ['id' => $this->entityId];
    $entity = $this->getEntity(UrlTestEntity::class, $values);

    $this->expectException(UndefinedLinkTemplateException::class);
    $this->expectExceptionMessage("Cannot generate default URL because no link template 'canonical' or 'edit-form' was found for the '" . $this->entityTypeId . "' entity type");
    $entity->toUrl();
  }

  /**
   * Tests the toUrl() method without specifying the $rel parameter.
   *
   * It should return the edit-form or canonical link templates by default if
   * they are registered.
   *
   * @covers ::toUrl
   */
  public function testToUrlDefaultFallback(): void {
    $values = ['id' => $this->entityId, 'langcode' => $this->langcode];
    $entity = $this->getEntity(UrlTestEntity::class, $values);
    $this->registerLinkTemplate('edit-form');
    /** @var \Drupal\Core\Url $url */
    $url = $entity->toUrl();
    $this->assertUrl('entity.test_entity.edit_form', ['test_entity' => $this->entityId], $entity, FALSE, $url);
    $this->assertUrl('entity.test_entity.edit_form', ['test_entity' => $this->entityId], $entity, TRUE, $url);

    $this->registerLinkTemplate('canonical');
    /** @var \Drupal\Core\Url $url */
    $url = $entity->toUrl();
    $this->assertUrl('entity.test_entity.canonical', ['test_entity' => $this->entityId], $entity, FALSE, $url);
    $this->assertUrl('entity.test_entity.canonical', ['test_entity' => $this->entityId], $entity, TRUE, $url);

    // Register multiple link templates with 2 that share the same path.
    $this->entityType->getLinkTemplates()->willReturn([
      'canonical' => "/test-entity/{test_entity}/canonical",
      'edit-form' => "/test-entity/{test_entity}/edit-form",
      'foobar' => "/test-entity/{test_entity}/canonical",
    ]);
    $url = $entity->toUrl();
    $this->assertUrl('entity.test_entity.canonical', ['test_entity' => $this->entityId], $entity, TRUE, $url);
  }

  /**