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.
21 * @coversDefaultClass \Drupal\Core\Template\TwigSandboxPolicy
23 class TwigSandboxTest extends UnitTestCase {
26 * The Twig environment loaded with the sandbox extension.
28 * @var \Twig_Environment
35 protected function setUp() {
38 $loader = new StringLoader();
39 $this->twig = new \Twig_Environment($loader);
40 $policy = new TwigSandboxPolicy();
41 $sandbox = new \Twig_Extension_Sandbox($policy, TRUE);
42 $this->twig->addExtension($sandbox);
46 * Tests that dangerous methods cannot be called in entity objects.
48 * @dataProvider getTwigEntityDangerousMethods
50 public function testEntityDangerousMethods($template) {
51 $entity = $this->getMock('Drupal\Core\Entity\EntityInterface');
52 $this->setExpectedException(\Twig_Sandbox_SecurityError::class);
53 $this->twig->render($template, ['entity' => $entity]);
57 * Data provider for ::testEntityDangerousMethods.
61 public function getTwigEntityDangerousMethods() {
63 ['{{ entity.delete }}'],
64 ['{{ entity.save }}'],
65 ['{{ entity.create }}'],
70 * Tests that white listed classes can be extended.
72 public function testExtendedClass() {
73 $this->assertEquals(' class="kitten"', $this->twig->render('{{ attribute.addClass("kitten") }}', ['attribute' => new TestAttribute()]));
77 * Tests that prefixed methods can be called from within Twig templates.
79 * Currently "get", "has", and "is" are the only allowed prefixes.
81 public function testEntitySafePrefixes() {
82 $entity = $this->getMock('Drupal\Core\Entity\EntityInterface');
83 $entity->expects($this->atLeastOnce())
84 ->method('hasLinkTemplate')
87 $result = $this->twig->render('{{ entity.hasLinkTemplate("test") }}', ['entity' => $entity]);
88 $this->assertTrue((bool) $result, 'Sandbox policy allows has* functions to be called.');
90 $entity = $this->getMock('Drupal\Core\Entity\EntityInterface');
91 $entity->expects($this->atLeastOnce())
94 $result = $this->twig->render('{{ entity.isNew }}', ['entity' => $entity]);
95 $this->assertTrue((bool) $result, 'Sandbox policy allows is* functions to be called.');
97 $entity = $this->getMock('Drupal\Core\Entity\EntityInterface');
98 $entity->expects($this->atLeastOnce())
99 ->method('getEntityType')
100 ->willReturn('test');
101 $result = $this->twig->render('{{ entity.getEntityType }}', ['entity' => $entity]);
102 $this->assertEquals($result, 'test', 'Sandbox policy allows get* functions to be called.');
106 * Tests that valid methods can be called from within Twig templates.
108 * Currently the following methods are whitelisted: id, label, bundle, and
111 public function testEntitySafeMethods() {
112 $entity = $this->getMockBuilder('Drupal\Core\Entity\ContentEntityBase')
113 ->disableOriginalConstructor()
115 $entity->expects($this->atLeastOnce())
118 ->willReturn('test');
119 $result = $this->twig->render('{{ entity.get("title") }}', ['entity' => $entity]);
120 $this->assertEquals($result, 'test', 'Sandbox policy allows get() to be called.');
122 $entity = $this->getMock('Drupal\Core\Entity\EntityInterface');
123 $entity->expects($this->atLeastOnce())
125 ->willReturn('1234');
126 $result = $this->twig->render('{{ entity.id }}', ['entity' => $entity]);
127 $this->assertEquals($result, '1234', 'Sandbox policy allows get() to be called.');
129 $entity = $this->getMock('Drupal\Core\Entity\EntityInterface');
130 $entity->expects($this->atLeastOnce())
132 ->willReturn('testing');
133 $result = $this->twig->render('{{ entity.label }}', ['entity' => $entity]);
134 $this->assertEquals($result, 'testing', 'Sandbox policy allows get() to be called.');
136 $entity = $this->getMock('Drupal\Core\Entity\EntityInterface');
137 $entity->expects($this->atLeastOnce())
139 ->willReturn('testing');
140 $result = $this->twig->render('{{ entity.bundle }}', ['entity' => $entity]);
141 $this->assertEquals($result, 'testing', 'Sandbox policy allows get() to be called.');
145 * Tests that safe methods inside Url objects can be called.
147 public function testUrlSafeMethods() {
148 $url = $this->getMockBuilder('Drupal\Core\Url')
149 ->disableOriginalConstructor()
151 $url->expects($this->once())
153 ->willReturn('http://kittens.cat/are/cute');
154 $result = $this->twig->render('{{ url.toString }}', ['url' => $url]);
155 $this->assertEquals($result, 'http://kittens.cat/are/cute', 'Sandbox policy allows toString() to be called.');
160 class TestAttribute extends Attribute {}