5 * Contains \Drupal\Tests\Core\Template\TwigSandboxTest.
8 namespace Drupal\Tests\Core\Template;
10 use Drupal\Core\Template\Attribute;
11 use Drupal\Core\Template\TwigSandboxPolicy;
12 use Drupal\Core\Template\Loader\StringLoader;
13 use Drupal\Tests\UnitTestCase;
16 * Tests the twig sandbox policy.
20 * @coversDefaultClass \Drupal\Core\Template\TwigSandboxPolicy
22 class TwigSandboxTest extends UnitTestCase {
25 * The Twig environment loaded with the sandbox extension.
27 * @var \Twig_Environment
34 protected function setUp() {
37 $loader = new StringLoader();
38 $this->twig = new \Twig_Environment($loader);
39 $policy = new TwigSandboxPolicy();
40 $sandbox = new \Twig_Extension_Sandbox($policy, TRUE);
41 $this->twig->addExtension($sandbox);
45 * Tests that dangerous methods cannot be called in entity objects.
47 * @dataProvider getTwigEntityDangerousMethods
49 public function testEntityDangerousMethods($template) {
50 $entity = $this->getMock('Drupal\Core\Entity\EntityInterface');
51 $this->setExpectedException(\Twig_Sandbox_SecurityError::class);
52 $this->twig->render($template, ['entity' => $entity]);
56 * Data provider for ::testEntityDangerousMethods.
60 public function getTwigEntityDangerousMethods() {
62 ['{{ entity.delete }}'],
63 ['{{ entity.save }}'],
64 ['{{ entity.create }}'],
69 * Tests that white listed classes can be extended.
71 public function testExtendedClass() {
72 $this->assertEquals(' class="kitten"', $this->twig->render('{{ attribute.addClass("kitten") }}', ['attribute' => new TestAttribute()]));
76 * Tests that prefixed methods can be called from within Twig templates.
78 * Currently "get", "has", and "is" are the only allowed prefixes.
80 public function testEntitySafePrefixes() {
81 $entity = $this->getMock('Drupal\Core\Entity\EntityInterface');
82 $entity->expects($this->atLeastOnce())
83 ->method('hasLinkTemplate')
86 $result = $this->twig->render('{{ entity.hasLinkTemplate("test") }}', ['entity' => $entity]);
87 $this->assertTrue((bool)$result, 'Sandbox policy allows has* functions to be called.');
89 $entity = $this->getMock('Drupal\Core\Entity\EntityInterface');
90 $entity->expects($this->atLeastOnce())
93 $result = $this->twig->render('{{ entity.isNew }}', ['entity' => $entity]);
94 $this->assertTrue((bool)$result, 'Sandbox policy allows is* functions to be called.');
96 $entity = $this->getMock('Drupal\Core\Entity\EntityInterface');
97 $entity->expects($this->atLeastOnce())
98 ->method('getEntityType')
100 $result = $this->twig->render('{{ entity.getEntityType }}', ['entity' => $entity]);
101 $this->assertEquals($result, 'test', 'Sandbox policy allows get* functions to be called.');
105 * Tests that valid methods can be called from within Twig templates.
107 * Currently the following methods are whitelisted: id, label, bundle, and
110 public function testEntitySafeMethods() {
111 $entity = $this->getMockBuilder('Drupal\Core\Entity\ContentEntityBase')
112 ->disableOriginalConstructor()
114 $entity->expects($this->atLeastOnce())
117 ->willReturn('test');
118 $result = $this->twig->render('{{ entity.get("title") }}', ['entity' => $entity]);
119 $this->assertEquals($result, 'test', 'Sandbox policy allows get() to be called.');
121 $entity = $this->getMock('Drupal\Core\Entity\EntityInterface');
122 $entity->expects($this->atLeastOnce())
124 ->willReturn('1234');
125 $result = $this->twig->render('{{ entity.id }}', ['entity' => $entity]);
126 $this->assertEquals($result, '1234', 'Sandbox policy allows get() to be called.');
128 $entity = $this->getMock('Drupal\Core\Entity\EntityInterface');
129 $entity->expects($this->atLeastOnce())
131 ->willReturn('testing');
132 $result = $this->twig->render('{{ entity.label }}', ['entity' => $entity]);
133 $this->assertEquals($result, 'testing', 'Sandbox policy allows get() to be called.');
135 $entity = $this->getMock('Drupal\Core\Entity\EntityInterface');
136 $entity->expects($this->atLeastOnce())
138 ->willReturn('testing');
139 $result = $this->twig->render('{{ entity.bundle }}', ['entity' => $entity]);
140 $this->assertEquals($result, 'testing', 'Sandbox policy allows get() to be called.');
144 * Tests that safe methods inside Url objects can be called.
146 public function testUrlSafeMethods() {
147 $url = $this->getMockBuilder('Drupal\Core\Url')
148 ->disableOriginalConstructor()
150 $url->expects($this->once())
152 ->willReturn('http://kittens.cat/are/cute');
153 $result = $this->twig->render('{{ url.toString }}', ['url' => $url]);
154 $this->assertEquals($result, 'http://kittens.cat/are/cute', 'Sandbox policy allows toString() to be called.');
159 class TestAttribute extends Attribute {}