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