View source
<?php
namespace Drupal\Tests\Core\Template;
use Drupal\Core\Render\RenderableInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Template\Loader\StringLoader;
use Drupal\Core\Template\TwigEnvironment;
use Drupal\Core\Template\TwigExtension;
use Drupal\Tests\UnitTestCase;
class TwigExtensionTest extends UnitTestCase {
public function testEscaping($template, $expected) {
$renderer = $this
->getMock('\\Drupal\\Core\\Render\\RendererInterface');
$twig = new \Twig_Environment(NULL, array(
'debug' => TRUE,
'cache' => FALSE,
'autoescape' => 'html',
'optimizations' => 0,
));
$twig
->addExtension((new TwigExtension($renderer))
->setUrlGenerator($this
->getMock('Drupal\\Core\\Routing\\UrlGeneratorInterface')));
$nodes = $twig
->parse($twig
->tokenize($template));
$this
->assertSame($expected, $nodes
->getNode('body')
->getNode(0)
->getNode('expr') instanceof \Twig_Node_Expression_Filter);
}
public function providerTestEscaping() {
return array(
array(
'{{ path("foo") }}',
FALSE,
),
array(
'{{ path("foo", {}) }}',
FALSE,
),
array(
'{{ path("foo", { foo: "foo" }) }}',
FALSE,
),
array(
'{{ path("foo", foo) }}',
TRUE,
),
array(
'{{ path("foo", { foo: foo }) }}',
TRUE,
),
array(
'{{ path("foo", { foo: ["foo", "bar"] }) }}',
TRUE,
),
array(
'{{ path("foo", { foo: "foo", bar: "bar" }) }}',
TRUE,
),
array(
'{{ path(name = "foo", parameters = {}) }}',
FALSE,
),
array(
'{{ path(name = "foo", parameters = { foo: "foo" }) }}',
FALSE,
),
array(
'{{ path(name = "foo", parameters = foo) }}',
TRUE,
),
array(
'{{ path(name = "foo", parameters = { foo: ["foo", "bar"] }) }}',
TRUE,
),
array(
'{{ path(name = "foo", parameters = { foo: foo }) }}',
TRUE,
),
array(
'{{ path(name = "foo", parameters = { foo: "foo", bar: "bar" }) }}',
TRUE,
),
);
}
public function testActiveTheme() {
$renderer = $this
->getMock('\\Drupal\\Core\\Render\\RendererInterface');
$extension = new TwigExtension($renderer);
$theme_manager = $this
->getMock('\\Drupal\\Core\\Theme\\ThemeManagerInterface');
$active_theme = $this
->getMockBuilder('\\Drupal\\Core\\Theme\\ActiveTheme')
->disableOriginalConstructor()
->getMock();
$active_theme
->expects($this
->once())
->method('getName')
->willReturn('test_theme');
$theme_manager
->expects($this
->once())
->method('getActiveTheme')
->willReturn($active_theme);
$extension
->setThemeManager($theme_manager);
$loader = new \Twig_Loader_String();
$twig = new \Twig_Environment($loader);
$twig
->addExtension($extension);
$result = $twig
->render('{{ active_theme() }}');
$this
->assertEquals('test_theme', $result);
}
public function testFormatDate() {
$date_formatter = $this
->getMockBuilder('\\Drupal\\Core\\Datetime\\DateFormatter')
->disableOriginalConstructor()
->getMock();
$date_formatter
->expects($this
->exactly(2))
->method('format')
->willReturn('1978-11-19');
$renderer = $this
->getMock('\\Drupal\\Core\\Render\\RendererInterface');
$extension = new TwigExtension($renderer);
$extension
->setDateFormatter($date_formatter);
$loader = new StringLoader();
$twig = new \Twig_Environment($loader);
$twig
->addExtension($extension);
$result = $twig
->render('{{ time|format_date("html_date") }}');
$this
->assertEquals($date_formatter
->format('html_date'), $result);
}
public function testActiveThemePath() {
$renderer = $this
->getMock('\\Drupal\\Core\\Render\\RendererInterface');
$extension = new TwigExtension($renderer);
$theme_manager = $this
->getMock('\\Drupal\\Core\\Theme\\ThemeManagerInterface');
$active_theme = $this
->getMockBuilder('\\Drupal\\Core\\Theme\\ActiveTheme')
->disableOriginalConstructor()
->getMock();
$active_theme
->expects($this
->once())
->method('getPath')
->willReturn('foo/bar');
$theme_manager
->expects($this
->once())
->method('getActiveTheme')
->willReturn($active_theme);
$extension
->setThemeManager($theme_manager);
$loader = new \Twig_Loader_String();
$twig = new \Twig_Environment($loader);
$twig
->addExtension($extension);
$result = $twig
->render('{{ active_theme_path() }}');
$this
->assertEquals('foo/bar', $result);
}
public function testSafeStringEscaping() {
$renderer = $this
->getMock('\\Drupal\\Core\\Render\\RendererInterface');
$twig = new \Twig_Environment(NULL, array(
'debug' => TRUE,
'cache' => FALSE,
'autoescape' => 'html',
'optimizations' => 0,
));
$twig_extension = new TwigExtension($renderer);
$safe_string = $this
->getMock('\\Drupal\\Component\\Render\\MarkupInterface');
$this
->assertSame($safe_string, $twig_extension
->escapeFilter($twig, $safe_string, 'html', 'UTF-8', TRUE));
$string_object = new TwigExtensionTestString("<script>alert('here');</script>");
$this
->assertSame('<script>alert('here');</script>', $twig_extension
->escapeFilter($twig, $string_object, 'html', 'UTF-8', TRUE));
}
public function testSafeJoin() {
$renderer = $this
->prophesize(RendererInterface::class);
$renderer
->render([
'#markup' => '<strong>will be rendered</strong>',
'#printed' => FALSE,
])
->willReturn('<strong>will be rendered</strong>');
$renderer = $renderer
->reveal();
$twig_extension = new TwigExtension($renderer);
$twig_environment = $this
->prophesize(TwigEnvironment::class)
->reveal();
$markup = $this
->prophesize(TranslatableMarkup::class);
$markup
->__toString()
->willReturn('<em>will be markup</em>');
$markup = $markup
->reveal();
$items = [
'<em>will be escaped</em>',
$markup,
[
'#markup' => '<strong>will be rendered</strong>',
],
];
$result = $twig_extension
->safeJoin($twig_environment, $items, '<br/>');
$this
->assertEquals('<em>will be escaped</em><br/><em>will be markup</em><br/><strong>will be rendered</strong>', $result);
$items = new \ArrayObject([
'<em>will be escaped</em>',
$markup,
[
'#markup' => '<strong>will be rendered</strong>',
],
]);
$result = $twig_extension
->safeJoin($twig_environment, $items, ', ');
$this
->assertEquals('<em>will be escaped</em>, <em>will be markup</em>, <strong>will be rendered</strong>', $result);
$items = NULL;
$result = $twig_extension
->safeJoin($twig_environment, $items, '<br>');
$this
->assertEmpty($result);
}
public function testRenderVar($result, $input) {
$renderer = $this
->prophesize(RendererInterface::class);
$renderer
->render($result += [
'#printed' => FALSE,
])
->willReturn('Rendered output');
$renderer = $renderer
->reveal();
$twig_extension = new TwigExtension($renderer);
$this
->assertEquals('Rendered output', $twig_extension
->renderVar($input));
}
public function providerTestRenderVar() {
$data = [];
$renderable = $this
->prophesize(RenderableInterface::class);
$render_array = [
'#type' => 'test',
'#var' => 'giraffe',
];
$renderable
->toRenderable()
->willReturn($render_array);
$data['renderable'] = [
$render_array,
$renderable
->reveal(),
];
return $data;
}
}
class TwigExtensionTestString {
protected $string;
public function __construct($string) {
$this->string = $string;
}
public function __toString() {
return $this->string;
}
}