You are here

public function FieldWebTest::testAlterUrl in Drupal 10

Same name and namespace in other branches
  1. 8 core/modules/views/tests/src/Functional/Handler/FieldWebTest.php \Drupal\Tests\views\Functional\Handler\FieldWebTest::testAlterUrl()
  2. 9 core/modules/views/tests/src/Functional/Handler/FieldWebTest.php \Drupal\Tests\views\Functional\Handler\FieldWebTest::testAlterUrl()

Tests rewriting the output to a link.

File

core/modules/views/tests/src/Functional/Handler/FieldWebTest.php, line 218

Class

FieldWebTest
Tests fields from within a UI.

Namespace

Drupal\Tests\views\Functional\Handler

Code

public function testAlterUrl() {

  /** @var \Drupal\Core\Render\RendererInterface $renderer */
  $renderer = \Drupal::service('renderer');
  $view = Views::getView('test_view');
  $view
    ->setDisplay();
  $view
    ->initHandlers();
  $this
    ->executeView($view);
  $row = $view->result[0];
  $id_field = $view->field['id'];

  // Setup the general settings required to build a link.
  $id_field->options['alter']['make_link'] = TRUE;
  $id_field->options['alter']['path'] = $path = $this
    ->randomMachineName();

  // Tests that the suffix/prefix appears on the output.
  $id_field->options['alter']['prefix'] = $prefix = $this
    ->randomMachineName();
  $id_field->options['alter']['suffix'] = $suffix = $this
    ->randomMachineName();
  $output = $renderer
    ->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
    return $id_field
      ->theme($row);
  });
  $this
    ->assertSubString($output, $prefix);
  $this
    ->assertSubString($output, $suffix);
  unset($id_field->options['alter']['prefix']);
  unset($id_field->options['alter']['suffix']);
  $output = $renderer
    ->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
    return $id_field
      ->theme($row);
  });
  $this
    ->assertSubString($output, $path, 'Make sure that the path is part of the output');

  // Some generic test code adapted from the UrlTest class, which tests
  // mostly the different options for the path.
  foreach ([
    FALSE,
    TRUE,
  ] as $absolute) {
    $alter =& $id_field->options['alter'];
    $alter['path'] = 'node/123';
    $expected_result = Url::fromRoute('entity.node.canonical', [
      'node' => '123',
    ], [
      'absolute' => $absolute,
    ])
      ->toString();
    $alter['absolute'] = $absolute;
    $result = $renderer
      ->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
      return $id_field
        ->theme($row);
    });
    $this
      ->assertSubString($result, $expected_result);
    $expected_result = Url::fromRoute('entity.node.canonical', [
      'node' => '123',
    ], [
      'fragment' => 'foo',
      'absolute' => $absolute,
    ])
      ->toString();
    $alter['path'] = 'node/123#foo';
    $result = $renderer
      ->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
      return $id_field
        ->theme($row);
    });
    $this
      ->assertSubString($result, $expected_result);
    $expected_result = Url::fromRoute('entity.node.canonical', [
      'node' => '123',
    ], [
      'query' => [
        'foo' => NULL,
      ],
      'absolute' => $absolute,
    ])
      ->toString();
    $alter['path'] = 'node/123?foo';
    $result = $renderer
      ->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
      return $id_field
        ->theme($row);
    });
    $this
      ->assertSubString($result, $expected_result);
    $expected_result = Url::fromRoute('entity.node.canonical', [
      'node' => '123',
    ], [
      'query' => [
        'foo' => 'bar',
        'bar' => 'baz',
      ],
      'absolute' => $absolute,
    ])
      ->toString();
    $alter['path'] = 'node/123?foo=bar&bar=baz';
    $result = $renderer
      ->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
      return $id_field
        ->theme($row);
    });
    $this
      ->assertSubString(Html::decodeEntities($result), Html::decodeEntities($expected_result));

    // @todo The route-based URL generator strips out NULL attributes.
    // $expected_result = Url::fromRoute('entity.node.canonical', ['node' => '123'], ['query' => ['foo' => NULL], 'fragment' => 'bar', 'absolute' => $absolute])->toString();
    $expected_result = Url::fromUserInput('/node/123', [
      'query' => [
        'foo' => NULL,
      ],
      'fragment' => 'bar',
      'absolute' => $absolute,
    ])
      ->toString();
    $alter['path'] = 'node/123?foo#bar';
    $result = $renderer
      ->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
      return $id_field
        ->theme($row);
    });
    $this
      ->assertSubString(Html::decodeEntities($result), Html::decodeEntities($expected_result));
    $expected_result = Url::fromRoute('<front>', [], [
      'absolute' => $absolute,
    ])
      ->toString();
    $alter['path'] = '<front>';
    $result = $renderer
      ->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
      return $id_field
        ->theme($row);
    });
    $this
      ->assertSubString($result, $expected_result);
  }

  // Tests the replace spaces with dashes feature.
  $id_field->options['alter']['replace_spaces'] = TRUE;
  $id_field->options['alter']['path'] = $path = $this
    ->randomMachineName() . ' ' . $this
    ->randomMachineName();
  $output = $renderer
    ->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
    return $id_field
      ->theme($row);
  });
  $this
    ->assertSubString($output, str_replace(' ', '-', $path));
  $id_field->options['alter']['replace_spaces'] = FALSE;
  $output = $renderer
    ->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
    return $id_field
      ->theme($row);
  });

  // The url has a space in it, so to check we have to decode the url output.
  $this
    ->assertSubString(urldecode($output), $path);

  // Tests the external flag.
  // Switch on the external flag should output an external url as well.
  $id_field->options['alter']['external'] = TRUE;
  $id_field->options['alter']['path'] = $path = 'www.drupal.org';
  $output = $renderer
    ->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
    return $id_field
      ->theme($row);
  });
  $this
    ->assertSubString($output, 'http://www.drupal.org');

  // Setup a not external url, which shouldn't lead to an external url.
  $id_field->options['alter']['external'] = FALSE;
  $id_field->options['alter']['path'] = $path = 'www.drupal.org';
  $output = $renderer
    ->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
    return $id_field
      ->theme($row);
  });
  $this
    ->assertNotSubString($output, 'http://www.drupal.org');

  // Tests the transforming of the case setting.
  $id_field->options['alter']['path'] = $path = $this
    ->randomMachineName();
  $id_field->options['alter']['path_case'] = 'none';
  $output = $renderer
    ->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
    return $id_field
      ->theme($row);
  });
  $this
    ->assertSubString($output, $path);

  // Switch to uppercase and lowercase.
  $id_field->options['alter']['path_case'] = 'upper';
  $output = $renderer
    ->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
    return $id_field
      ->theme($row);
  });
  $this
    ->assertSubString($output, strtoupper($path));
  $id_field->options['alter']['path_case'] = 'lower';
  $output = $renderer
    ->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
    return $id_field
      ->theme($row);
  });
  $this
    ->assertSubString($output, strtolower($path));

  // Switch to ucfirst and ucwords.
  $id_field->options['alter']['path_case'] = 'ucfirst';
  $id_field->options['alter']['path'] = 'drupal has a great community';
  $output = $renderer
    ->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
    return $id_field
      ->theme($row);
  });
  $this
    ->assertSubString($output, UrlHelper::encodePath('Drupal has a great community'));
  $id_field->options['alter']['path_case'] = 'ucwords';
  $output = $renderer
    ->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
    return $id_field
      ->theme($row);
  });
  $this
    ->assertSubString($output, UrlHelper::encodePath('Drupal Has A Great Community'));
  unset($id_field->options['alter']['path_case']);

  // Tests the link_class setting and see whether it actually exists in the
  // output.
  $id_field->options['alter']['link_class'] = $class = $this
    ->randomMachineName();
  $output = $renderer
    ->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
    return $id_field
      ->theme($row);
  });
  $elements = $this
    ->xpathContent($output, '//a[contains(@class, :class)]', [
    ':class' => $class,
  ]);
  $this
    ->assertNotEmpty($elements);

  // @fixme link_class, alt, rel cannot be unset, which should be fixed.
  $id_field->options['alter']['link_class'] = '';

  // Tests the alt setting.
  $id_field->options['alter']['alt'] = $rel = $this
    ->randomMachineName();
  $output = $renderer
    ->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
    return $id_field
      ->theme($row);
  });
  $elements = $this
    ->xpathContent($output, '//a[contains(@title, :alt)]', [
    ':alt' => $rel,
  ]);
  $this
    ->assertNotEmpty($elements);
  $id_field->options['alter']['alt'] = '';

  // Tests the rel setting.
  $id_field->options['alter']['rel'] = $rel = $this
    ->randomMachineName();
  $output = $renderer
    ->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
    return $id_field
      ->theme($row);
  });
  $elements = $this
    ->xpathContent($output, '//a[contains(@rel, :rel)]', [
    ':rel' => $rel,
  ]);
  $this
    ->assertNotEmpty($elements);
  $id_field->options['alter']['rel'] = '';

  // Tests the target setting.
  $id_field->options['alter']['target'] = $target = $this
    ->randomMachineName();
  $output = $renderer
    ->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
    return $id_field
      ->theme($row);
  });
  $elements = $this
    ->xpathContent($output, '//a[contains(@target, :target)]', [
    ':target' => $target,
  ]);
  $this
    ->assertNotEmpty($elements);
  unset($id_field->options['alter']['target']);
}