function FieldKernelTest::testFieldTokens

Same name in other branches
  1. 9 core/modules/views/tests/src/Kernel/Handler/FieldKernelTest.php \Drupal\Tests\views\Kernel\Handler\FieldKernelTest::testFieldTokens()
  2. 8.9.x core/modules/views/tests/src/Kernel/Handler/FieldKernelTest.php \Drupal\Tests\views\Kernel\Handler\FieldKernelTest::testFieldTokens()
  3. 11.x core/modules/views/tests/src/Kernel/Handler/FieldKernelTest.php \Drupal\Tests\views\Kernel\Handler\FieldKernelTest::testFieldTokens()

Tests the field tokens, row level and field level.

File

core/modules/views/tests/src/Kernel/Handler/FieldKernelTest.php, line 265

Class

FieldKernelTest
Tests the generic field handler.

Namespace

Drupal\Tests\views\Kernel\Handler

Code

public function testFieldTokens() : void {
    
    /** @var \Drupal\Core\Render\RendererInterface $renderer */
    $renderer = \Drupal::service('renderer');
    $view = Views::getView('test_field_tokens');
    $this->executeView($view);
    $name_field_0 = $view->field['name'];
    $name_field_1 = $view->field['name_1'];
    $name_field_2 = $view->field['name_2'];
    $row = $view->result[0];
    $name_field_0->options['alter']['alter_text'] = TRUE;
    $name_field_0->options['alter']['text'] = '{{ name }}';
    $name_field_1->options['alter']['alter_text'] = TRUE;
    $name_field_1->options['alter']['text'] = '{{ name_1 }} {{ name }}';
    $name_field_2->options['alter']['alter_text'] = TRUE;
    $name_field_2->options['alter']['text'] = '{% if name_2|length > 3 %}{{ name_2 }} {{ name_1 }}{% endif %}';
    foreach ($view->result as $row) {
        $expected_output_0 = $row->views_test_data_name;
        $expected_output_1 = "{$row->views_test_data_name} {$row->views_test_data_name}";
        $expected_output_2 = "{$row->views_test_data_name} {$row->views_test_data_name} {$row->views_test_data_name}";
        $output = (string) $renderer->executeInRenderContext(new RenderContext(), function () use ($name_field_0, $row) {
            return $name_field_0->advancedRender($row);
        });
        $this->assertEquals($expected_output_0, $output, sprintf('Test token replacement: "%s" gave "%s"', $name_field_0->options['alter']['text'], $output));
        $output = (string) $renderer->executeInRenderContext(new RenderContext(), function () use ($name_field_1, $row) {
            return $name_field_1->advancedRender($row);
        });
        $this->assertEquals($expected_output_1, $output, sprintf('Test token replacement: "%s" gave "%s"', $name_field_1->options['alter']['text'], $output));
        $output = (string) $renderer->executeInRenderContext(new RenderContext(), function () use ($name_field_2, $row) {
            return $name_field_2->advancedRender($row);
        });
        $this->assertEquals($expected_output_2, $output, sprintf('Test token replacement: "%s" gave %s"', $name_field_2->options['alter']['text'], $output));
    }
    $job_field = $view->field['job'];
    $job_field->options['alter']['alter_text'] = TRUE;
    $job_field->options['alter']['text'] = '{{ job }}';
    $random_text = $this->randomMachineName();
    $job_field->setTestValue($random_text);
    $output = (string) $renderer->executeInRenderContext(new RenderContext(), function () use ($job_field, $row) {
        return $job_field->advancedRender($row);
    });
    $this->assertSubString($output, $random_text, sprintf('Make sure the self token (%s => %s) appears in the output (%s)', $job_field->options['alter']['text'], $random_text, $output));
    // Verify the token format used in D7 and earlier does not get substituted.
    $old_token = '[job]';
    $job_field->options['alter']['text'] = $old_token;
    $random_text = $this->randomMachineName();
    $job_field->setTestValue($random_text);
    $output = (string) $renderer->executeInRenderContext(new RenderContext(), function () use ($job_field, $row) {
        return $job_field->advancedRender($row);
    });
    $this->assertEquals($old_token, $output, sprintf('Make sure the old token style (%s => %s) is not changed in the output (%s)', $job_field->options['alter']['text'], $random_text, $output));
    // Verify HTML tags are allowed in rewrite templates while token
    // replacements are escaped.
    $job_field->options['alter']['text'] = '<h1>{{ job }}</h1>';
    $random_text = $this->randomMachineName();
    $job_field->setTestValue('<span>' . $random_text . '</span>');
    $output = (string) $renderer->executeInRenderContext(new RenderContext(), function () use ($job_field, $row) {
        return $job_field->advancedRender($row);
    });
    $this->assertSame('<h1>&lt;span&gt;' . $random_text . '&lt;/span&gt;</h1>', (string) $output, 'Valid tags are allowed in rewrite templates and token replacements.');
    // Verify <script> tags are correctly removed from rewritten text.
    $rewrite_template = '<script>alert("malicious");</script>';
    $job_field->options['alter']['text'] = $rewrite_template;
    $random_text = $this->randomMachineName();
    $job_field->setTestValue($random_text);
    $output = (string) $renderer->executeInRenderContext(new RenderContext(), function () use ($job_field, $row) {
        return $job_field->advancedRender($row);
    });
    $this->assertNotSubString($output, '<script>', 'Ensure a script tag in the rewrite template is removed.');
    $rewrite_template = '<script>{{ job }}</script>';
    $job_field->options['alter']['text'] = $rewrite_template;
    $random_text = $this->randomMachineName();
    $job_field->setTestValue($random_text);
    $output = (string) $renderer->executeInRenderContext(new RenderContext(), function () use ($job_field, $row) {
        return $job_field->advancedRender($row);
    });
    $this->assertEquals($random_text, $output, "Make sure a script tag in the template ({$rewrite_template}) is removed, leaving only the replaced token in the output ({$output})");
}

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