function FilterKernelTest::testCaptionFilter
Same name in other branches
- 9 core/modules/filter/tests/src/Kernel/FilterKernelTest.php \Drupal\Tests\filter\Kernel\FilterKernelTest::testCaptionFilter()
- 10 core/modules/filter/tests/src/Kernel/FilterKernelTest.php \Drupal\Tests\filter\Kernel\FilterKernelTest::testCaptionFilter()
- 11.x core/modules/filter/tests/src/Kernel/FilterKernelTest.php \Drupal\Tests\filter\Kernel\FilterKernelTest::testCaptionFilter()
Tests the caption filter.
File
-
core/
modules/ filter/ tests/ src/ Kernel/ FilterKernelTest.php, line 100
Class
- FilterKernelTest
- Tests Filter module filters individually.
Namespace
Drupal\Tests\filter\KernelCode
public function testCaptionFilter() {
/** @var \Drupal\Core\Render\RendererInterface $renderer */
$renderer = \Drupal::service('renderer');
$filter = $this->filters['filter_caption'];
$test = function ($input) use ($filter, $renderer) {
return $renderer->executeInRenderContext(new RenderContext(), function () use ($input, $filter) {
return $filter->process($input, 'und');
});
};
$attached_library = [
'library' => [
'filter/caption',
],
];
// No data-caption attribute.
$input = '<img src="llama.jpg" />';
$expected = $input;
$this->assertIdentical($expected, $test($input)->getProcessedText());
// Data-caption attribute.
$input = '<img src="llama.jpg" data-caption="Loquacious llama!" />';
$expected = '<figure role="group"><img src="llama.jpg" /><figcaption>Loquacious llama!</figcaption></figure>';
$output = $test($input);
$this->assertIdentical($expected, $output->getProcessedText());
$this->assertIdentical($attached_library, $output->getAttachments());
// Empty data-caption attribute.
$input = '<img src="llama.jpg" data-caption="" />';
$expected = '<img src="llama.jpg" />';
$this->assertIdentical($expected, $test($input)->getProcessedText());
// HTML entities in the caption.
$input = '<img src="llama.jpg" data-caption="“Loquacious llama!”" />';
$expected = '<figure role="group"><img src="llama.jpg" /><figcaption>“Loquacious llama!”</figcaption></figure>';
$output = $test($input);
$this->assertIdentical($expected, $output->getProcessedText());
$this->assertIdentical($attached_library, $output->getAttachments());
// HTML encoded as HTML entities in data-caption attribute.
$input = '<img src="llama.jpg" data-caption="<em>Loquacious llama!</em>" />';
$expected = '<figure role="group"><img src="llama.jpg" /><figcaption><em>Loquacious llama!</em></figcaption></figure>';
$output = $test($input);
$this->assertIdentical($expected, $output->getProcessedText());
$this->assertIdentical($attached_library, $output->getAttachments());
// HTML (not encoded as HTML entities) in data-caption attribute, which is
// not allowed by the HTML spec, but may happen when people manually write
// HTML, so we explicitly support it.
$input = '<img src="llama.jpg" data-caption="<em>Loquacious llama!</em>" />';
$expected = '<figure role="group"><img src="llama.jpg" /><figcaption><em>Loquacious llama!</em></figcaption></figure>';
$output = $test($input);
$this->assertIdentical($expected, $output->getProcessedText());
$this->assertIdentical($attached_library, $output->getAttachments());
// Security test: attempt an XSS.
$input = '<img src="llama.jpg" data-caption="<script>alert(\'Loquacious llama!\')</script>" />';
$expected = '<figure role="group"><img src="llama.jpg" /><figcaption>alert(\'Loquacious llama!\')</figcaption></figure>';
$output = $test($input);
$this->assertIdentical($expected, $output->getProcessedText());
$this->assertIdentical($attached_library, $output->getAttachments());
// Ensure the filter also works with uncommon yet valid attribute quoting.
$input = '<img src=llama.jpg data-caption=\'Loquacious llama!\' />';
$expected = '<figure role="group"><img src="llama.jpg" /><figcaption>Loquacious llama!</figcaption></figure>';
$output = $test($input);
$this->assertIdentical($expected, $output->getProcessedText());
$this->assertIdentical($attached_library, $output->getAttachments());
// Finally, ensure that this also works on any other tag.
$input = '<video src="llama.jpg" data-caption="Loquacious llama!" />';
$expected = '<figure role="group"><video src="llama.jpg"></video><figcaption>Loquacious llama!</figcaption></figure>';
$output = $test($input);
$this->assertIdentical($expected, $output->getProcessedText());
$this->assertIdentical($attached_library, $output->getAttachments());
$input = '<foobar data-caption="Loquacious llama!">baz</foobar>';
$expected = '<figure role="group"><foobar>baz</foobar><figcaption>Loquacious llama!</figcaption></figure>';
$output = $test($input);
$this->assertIdentical($expected, $output->getProcessedText());
$this->assertIdentical($attached_library, $output->getAttachments());
// Ensure the caption filter works for linked images.
$input = '<a href="http://example.com/llamas/are/awesome/but/kittens/are/cool/too"><img src="llama.jpg" data-caption="Loquacious llama!" /></a>';
$expected = '<figure role="group"><a href="http://example.com/llamas/are/awesome/but/kittens/are/cool/too"><img src="llama.jpg" /></a>' . "\n" . '<figcaption>Loquacious llama!</figcaption></figure>';
$output = $test($input);
$this->assertIdentical($expected, $output->getProcessedText());
$this->assertIdentical($attached_library, $output->getAttachments());
// So far we've tested that the caption filter works correctly. But we also
// want to make sure that it works well in tandem with the "Limit allowed
// HTML tags" filter, which it is typically used with.
$html_filter = $this->filters['filter_html'];
$html_filter->setConfiguration([
'settings' => [
'allowed_html' => '<img src data-align data-caption>',
'filter_html_help' => 1,
'filter_html_nofollow' => 0,
],
]);
$test_with_html_filter = function ($input) use ($filter, $html_filter, $renderer) {
return $renderer->executeInRenderContext(new RenderContext(), function () use ($input, $filter, $html_filter) {
// 1. Apply HTML filter's processing step.
$output = $html_filter->process($input, 'und');
// 2. Apply caption filter's processing step.
$output = $filter->process($output, 'und');
return $output->getProcessedText();
});
};
// Editor XSS filter.
$test_editor_xss_filter = function ($input) {
$dummy_filter_format = FilterFormat::create();
return Standard::filterXss($input, $dummy_filter_format);
};
// All the tricky cases encountered at https://www.drupal.org/node/2105841.
// A plain URL preceded by text.
$input = '<img data-caption="See https://www.drupal.org" src="llama.jpg" />';
$expected = '<figure role="group"><img src="llama.jpg" /><figcaption>See https://www.drupal.org</figcaption></figure>';
$this->assertIdentical($expected, $test_with_html_filter($input));
$this->assertIdentical($input, $test_editor_xss_filter($input));
// An anchor.
$input = '<img data-caption="This is a <a href="https://www.drupal.org">quick</a> test…" src="llama.jpg" />';
$expected = '<figure role="group"><img src="llama.jpg" /><figcaption>This is a <a href="https://www.drupal.org">quick</a> test…</figcaption></figure>';
$this->assertIdentical($expected, $test_with_html_filter($input));
$this->assertIdentical($input, $test_editor_xss_filter($input));
// A plain URL surrounded by parentheses.
$input = '<img data-caption="(https://www.drupal.org)" src="llama.jpg" />';
$expected = '<figure role="group"><img src="llama.jpg" /><figcaption>(https://www.drupal.org)</figcaption></figure>';
$this->assertIdentical($expected, $test_with_html_filter($input));
$this->assertIdentical($input, $test_editor_xss_filter($input));
// A source being credited.
$input = '<img data-caption="Source: Wikipedia" src="llama.jpg" />';
$expected = '<figure role="group"><img src="llama.jpg" /><figcaption>Source: Wikipedia</figcaption></figure>';
$this->assertIdentical($expected, $test_with_html_filter($input));
$this->assertIdentical($input, $test_editor_xss_filter($input));
// A source being credited, without a space after the colon.
$input = '<img data-caption="Source:Wikipedia" src="llama.jpg" />';
$expected = '<figure role="group"><img src="llama.jpg" /><figcaption>Source:Wikipedia</figcaption></figure>';
$this->assertIdentical($expected, $test_with_html_filter($input));
$this->assertIdentical($input, $test_editor_xss_filter($input));
// A pretty crazy edge case where we have two colons.
$input = '<img data-caption="Interesting (Scope resolution operator ::)" src="llama.jpg" />';
$expected = '<figure role="group"><img src="llama.jpg" /><figcaption>Interesting (Scope resolution operator ::)</figcaption></figure>';
$this->assertIdentical($expected, $test_with_html_filter($input));
$this->assertIdentical($input, $test_editor_xss_filter($input));
// An evil anchor (to ensure XSS filtering is applied to the caption also).
$input = '<img data-caption="This is an <a href="javascript:alert();">evil</a> test…" src="llama.jpg" />';
$expected = '<figure role="group"><img src="llama.jpg" /><figcaption>This is an <a href="alert();">evil</a> test…</figcaption></figure>';
$this->assertIdentical($expected, $test_with_html_filter($input));
$expected_xss_filtered = '<img data-caption="This is an <a href="alert();">evil</a> test…" src="llama.jpg" />';
$this->assertIdentical($expected_xss_filtered, $test_editor_xss_filter($input));
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.