e599463485a8f6f276d58a36c0af2aacb96d4001
[yaffs-website] / web / core / tests / Drupal / Tests / Core / Template / TwigSandboxTest.php
1 <?php
2
3 /**
4  * @file
5  * Contains \Drupal\Tests\Core\Template\TwigSandboxTest.
6  */
7
8 namespace Drupal\Tests\Core\Template;
9
10 use Drupal\Core\Template\Attribute;
11 use Drupal\Core\Template\TwigSandboxPolicy;
12 use Drupal\Core\Template\Loader\StringLoader;
13 use Drupal\Tests\UnitTestCase;
14
15 /**
16  * Tests the twig sandbox policy.
17  *
18  * @group Template
19  *
20  * @coversDefaultClass \Drupal\Core\Template\TwigSandboxPolicy
21  */
22 class TwigSandboxTest extends UnitTestCase {
23
24   /**
25    * The Twig environment loaded with the sandbox extension.
26    *
27    * @var \Twig_Environment
28    */
29   protected $twig;
30
31   /**
32    * {@inheritdoc}
33    */
34   protected function setUp() {
35     parent::setUp();
36
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);
42   }
43
44   /**
45    * Tests that dangerous methods cannot be called in entity objects.
46    *
47    * @dataProvider getTwigEntityDangerousMethods
48    */
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]);
53   }
54
55   /**
56    * Data provider for ::testEntityDangerousMethods.
57    *
58    * @return array
59    */
60   public function getTwigEntityDangerousMethods() {
61     return [
62       ['{{ entity.delete }}'],
63       ['{{ entity.save }}'],
64       ['{{ entity.create }}'],
65     ];
66   }
67
68   /**
69    * Tests that white listed classes can be extended.
70    */
71   public function testExtendedClass() {
72     $this->assertEquals(' class=&quot;kitten&quot;', $this->twig->render('{{ attribute.addClass("kitten") }}', ['attribute' => new TestAttribute()]));
73   }
74
75   /**
76    * Tests that prefixed methods can be called from within Twig templates.
77    *
78    * Currently "get", "has", and "is" are the only allowed prefixes.
79    */
80   public function testEntitySafePrefixes() {
81     $entity = $this->getMock('Drupal\Core\Entity\EntityInterface');
82     $entity->expects($this->atLeastOnce())
83       ->method('hasLinkTemplate')
84       ->with('test')
85       ->willReturn(TRUE);
86     $result = $this->twig->render('{{ entity.hasLinkTemplate("test") }}', ['entity' => $entity]);
87     $this->assertTrue((bool)$result, 'Sandbox policy allows has* functions to be called.');
88
89     $entity = $this->getMock('Drupal\Core\Entity\EntityInterface');
90     $entity->expects($this->atLeastOnce())
91       ->method('isNew')
92       ->willReturn(TRUE);
93     $result = $this->twig->render('{{ entity.isNew }}', ['entity' => $entity]);
94     $this->assertTrue((bool)$result, 'Sandbox policy allows is* functions to be called.');
95
96     $entity = $this->getMock('Drupal\Core\Entity\EntityInterface');
97     $entity->expects($this->atLeastOnce())
98       ->method('getEntityType')
99       ->willReturn('test');
100     $result = $this->twig->render('{{ entity.getEntityType }}', ['entity' => $entity]);
101     $this->assertEquals($result, 'test', 'Sandbox policy allows get* functions to be called.');
102   }
103
104   /**
105    * Tests that valid methods can be called from within Twig templates.
106    *
107    * Currently the following methods are whitelisted: id, label, bundle, and
108    * get.
109    */
110   public function testEntitySafeMethods() {
111     $entity = $this->getMockBuilder('Drupal\Core\Entity\ContentEntityBase')
112       ->disableOriginalConstructor()
113       ->getMock();
114     $entity->expects($this->atLeastOnce())
115       ->method('get')
116       ->with('title')
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.');
120
121     $entity = $this->getMock('Drupal\Core\Entity\EntityInterface');
122     $entity->expects($this->atLeastOnce())
123       ->method('id')
124       ->willReturn('1234');
125     $result = $this->twig->render('{{ entity.id }}', ['entity' => $entity]);
126     $this->assertEquals($result, '1234', 'Sandbox policy allows get() to be called.');
127
128     $entity = $this->getMock('Drupal\Core\Entity\EntityInterface');
129     $entity->expects($this->atLeastOnce())
130       ->method('label')
131       ->willReturn('testing');
132     $result = $this->twig->render('{{ entity.label }}', ['entity' => $entity]);
133     $this->assertEquals($result, 'testing', 'Sandbox policy allows get() to be called.');
134
135     $entity = $this->getMock('Drupal\Core\Entity\EntityInterface');
136     $entity->expects($this->atLeastOnce())
137       ->method('bundle')
138       ->willReturn('testing');
139     $result = $this->twig->render('{{ entity.bundle }}', ['entity' => $entity]);
140     $this->assertEquals($result, 'testing', 'Sandbox policy allows get() to be called.');
141   }
142
143   /**
144    * Tests that safe methods inside Url objects can be called.
145    */
146   public function testUrlSafeMethods() {
147     $url = $this->getMockBuilder('Drupal\Core\Url')
148       ->disableOriginalConstructor()
149       ->getMock();
150     $url->expects($this->once())
151       ->method('toString')
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.');
155   }
156
157 }
158
159 class TestAttribute extends Attribute {}