function FieldWebTest::testAlterUrl

Same name and namespace in other branches
  1. 9 core/modules/views/tests/src/Functional/Handler/FieldWebTest.php \Drupal\Tests\views\Functional\Handler\FieldWebTest::testAlterUrl()
  2. 8.9.x core/modules/views/tests/src/Functional/Handler/FieldWebTest.php \Drupal\Tests\views\Functional\Handler\FieldWebTest::testAlterUrl()
  3. 10 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 221

Class

FieldWebTest
Tests fields from within a UI.

Namespace

Drupal\Tests\views\Functional\Handler

Code

public function testAlterUrl() : void {
    
    /** @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 = (string) $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 = (string) $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 = (string) $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 = (string) $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 = (string) $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 = (string) $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 = (string) $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 = (string) $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 = (string) $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 = (string) $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.example.com';
    $output = (string) $renderer->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
        return $id_field->theme($row);
    });
    $this->assertSubString($output, 'http://www.example.com');
    // 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.example.com';
    $output = (string) $renderer->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
        return $id_field->theme($row);
    });
    $this->assertNotSubString($output, 'http://www.example.com');
    // Tests the transforming of the case setting.
    $id_field->options['alter']['path'] = $path = $this->randomMachineName();
    $id_field->options['alter']['path_case'] = 'none';
    $output = (string) $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 = (string) $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 = (string) $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 = (string) $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 = (string) $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 = (string) $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 = (string) $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 = (string) $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 = (string) $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']);
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.