Security update for Core, with self-updated composer
[yaffs-website] / web / core / tests / Drupal / Tests / Core / Render / Element / HtmlTagTest.php
1 <?php
2
3 namespace Drupal\Tests\Core\Render\Element;
4
5 use Drupal\Core\Render\Markup;
6 use Drupal\Tests\Core\Render\RendererTestBase;
7 use Drupal\Core\Render\Element\HtmlTag;
8
9 /**
10  * @coversDefaultClass \Drupal\Core\Render\Element\HtmlTag
11  * @group Render
12  */
13 class HtmlTagTest extends RendererTestBase {
14
15   /**
16    * @covers ::getInfo
17    */
18   public function testGetInfo() {
19     $htmlTag = new HtmlTag([], 'test', 'test');
20     $info = $htmlTag->getInfo();
21     $this->assertArrayHasKey('#pre_render', $info);
22     $this->assertArrayHasKey('#attributes', $info);
23     $this->assertArrayHasKey('#value', $info);
24   }
25
26   /**
27    * @covers ::preRenderHtmlTag
28    * @dataProvider providerPreRenderHtmlTag
29    */
30   public function testPreRenderHtmlTag($element, $expected) {
31     $result = HtmlTag::preRenderHtmlTag($element);
32     foreach ($result as &$child) {
33       if (is_array($child) && isset($child['#tag'])) {
34         $child = HtmlTag::preRenderHtmlTag($child);
35       }
36     }
37     $this->assertEquals($expected, (string) $this->renderer->renderRoot($result));
38   }
39
40   /**
41    * Data provider for preRenderHtmlTag test.
42    */
43   public function providerPreRenderHtmlTag() {
44     $tags = [];
45
46     // Value prefix/suffix.
47     $element = [
48       '#value' => 'value',
49       '#tag' => 'p',
50     ];
51     $tags['value'] = [$element, '<p>value</p>' . "\n"];
52
53     // Normal element without a value should not result in a void element.
54     $element = [
55       '#tag' => 'p',
56       '#value' => NULL,
57     ];
58     $tags['no-value'] = [$element, "<p></p>\n"];
59
60     // A void element.
61     $element = [
62       '#tag' => 'br',
63     ];
64     $tags['void-element'] = [$element, "<br />\n"];
65
66     // Attributes.
67     $element = [
68       '#tag' => 'div',
69       '#attributes' => ['class' => 'test', 'id' => 'id'],
70       '#value' => 'value',
71     ];
72     $tags['attributes'] = [$element, '<div class="test" id="id">value</div>' . "\n"];
73
74     // No script tags.
75     $element['#noscript'] = TRUE;
76     $tags['noscript'] = [$element, '<noscript><div class="test" id="id">value</div>' . "\n" . '</noscript>'];
77
78     // Ensure that #tag is sanitised.
79     $element = [
80       '#tag' => 'p><script>alert()</script><p',
81       '#value' => 'value',
82     ];
83     $tags['sanitized-tag'] = [$element, "<p&gt;&lt;script&gt;alert()&lt;/script&gt;&lt;p>value</p&gt;&lt;script&gt;alert()&lt;/script&gt;&lt;p>\n"];
84
85     // Ensure that #value is not filtered if it is marked as safe.
86     $element = [
87       '#tag' => 'p',
88       '#value' => Markup::create('<script>value</script>'),
89     ];
90     $tags['value-safe'] = [$element, "<p><script>value</script></p>\n"];
91
92     // Ensure that #value is filtered if it is not safe.
93     $element = [
94       '#tag' => 'p',
95       '#value' => '<script>value</script>',
96     ];
97     $tags['value-not-safe'] = [$element, "<p>value</p>\n"];
98
99     // Ensure that nested render arrays render properly.
100     $element = [
101       '#tag' => 'p',
102       '#value' => NULL,
103       [
104         ['#markup' => '<b>value1</b>'],
105         ['#markup' => '<b>value2</b>'],
106       ],
107     ];
108     $tags['nested'] = [$element, "<p><b>value1</b><b>value2</b></p>\n"];
109
110     // Ensure svg elements.
111     $element = [
112       '#tag' => 'rect',
113       '#attributes' => [
114         'width' => 25,
115         'height' => 25,
116         'x' => 5,
117         'y' => 10,
118       ],
119     ];
120     $tags['rect'] = [$element, '<rect width="25" height="25" x="5" y="10" />' . "\n"];
121
122     $element = [
123       '#tag' => 'circle',
124       '#attributes' => [
125         'cx' => 100,
126         'cy' => 100,
127         'r' => 100,
128       ],
129     ];
130     $tags['circle'] = [$element, '<circle cx="100" cy="100" r="100" />' . "\n"];
131
132     $element = [
133       '#tag' => 'polygon',
134       '#attributes' => [
135         'points' => '60,20 100,40 100,80 60,100 20,80 20,40',
136       ],
137     ];
138     $tags['polygon'] = [$element, '<polygon points="60,20 100,40 100,80 60,100 20,80 20,40" />' . "\n"];
139
140     $element = [
141       '#tag' => 'ellipse',
142       '#attributes' => [
143         'cx' => 60,
144         'cy' => 60,
145         'rx' => 50,
146         'ry' => 25,
147       ],
148     ];
149     $tags['ellipse'] = [$element, '<ellipse cx="60" cy="60" rx="50" ry="25" />' . "\n"];
150
151     $element = [
152       '#tag' => 'use',
153       '#attributes' => [
154         'x' => 50,
155         'y' => 10,
156         'width' => 50,
157         'height' => 50,
158       ],
159     ];
160     $tags['use'] = [$element, '<use x="50" y="10" width="50" height="50" />' . "\n"];
161
162     $element = [
163       '#tag' => 'path',
164       '#attributes' => [
165         'd' => 'M 100 100 L 300 100 L 200 300 z',
166         'fill' => 'orange',
167         'stroke' => 'black',
168         'stroke-width' => 3,
169       ],
170     ];
171     $tags['path'] = [$element, '<path d="M 100 100 L 300 100 L 200 300 z" fill="orange" stroke="black" stroke-width="3" />' . "\n"];
172
173     $element = [
174       '#tag' => 'stop',
175       '#attributes' => [
176         'offset' => '5%',
177         'stop-color' => '#F60',
178       ],
179     ];
180     $tags['stop'] = [$element, '<stop offset="5%" stop-color="#F60" />' . "\n"];
181
182     // Nested svg elements.
183     $element = [
184       '#tag' => 'linearGradient',
185       '#value' => NULL,
186       [
187         '#tag' => 'stop',
188         '#value' => NULL,
189         '#attributes' => [
190           'offset' => '5%',
191           'stop-color' => '#F60',
192         ],
193       ],
194       [
195         '#tag' => 'stop',
196         '#value' => NULL,
197         '#attributes' => [
198           'offset' => '95%',
199           'stop-color' => '#FF6',
200         ],
201       ],
202     ];
203     $tags['linearGradient'] = [$element, '<linearGradient><stop offset="5%" stop-color="#F60" />' . "\n" . '<stop offset="95%" stop-color="#FF6" />' . "\n" . '</linearGradient>' . "\n"];
204
205     // Simple link.
206     $element = [
207       '#tag' => 'link',
208     ];
209     $tags['link'] = [HtmlTag::preRenderConditionalComments($element), '<link />' . "\n"];
210
211     // Conditional link.
212     $element = [
213       '#tag' => 'link',
214       '#browsers' => [
215         'IE' => TRUE,
216         '!IE' => FALSE,
217       ],
218     ];
219     $tags['conditional-link'] = [HtmlTag::preRenderConditionalComments($element), "\n" . '<!--[if IE]>' . "\n" . '<link />' . "\n" . '<![endif]-->' . "\n"];
220
221     return $tags;
222   }
223
224   /**
225    * @covers ::preRenderConditionalComments
226    * @dataProvider providerPreRenderConditionalComments
227    */
228   public function testPreRenderConditionalComments($element, $expected, $set_safe = FALSE) {
229     if ($set_safe) {
230       $element['#prefix'] = Markup::create($element['#prefix']);
231       $element['#suffix'] = Markup::create($element['#suffix']);
232     }
233     $this->assertEquals($expected, HtmlTag::preRenderConditionalComments($element));
234   }
235
236   /**
237    * Data provider for conditional comments test.
238    */
239   public function providerPreRenderConditionalComments() {
240     // No browser specification.
241     $element = [
242       '#tag' => 'link',
243     ];
244     $tags['no-browser'] = [$element, $element];
245
246     // Specify all browsers.
247     $element['#browsers'] = [
248       'IE' => TRUE,
249       '!IE' => TRUE,
250     ];
251     $tags['all-browsers'] = [$element, $element];
252
253     // All IE.
254     $element = [
255       '#tag' => 'link',
256       '#browsers' => [
257         'IE' => TRUE,
258         '!IE' => FALSE,
259       ],
260     ];
261     $expected = $element;
262     $expected['#prefix'] = "\n<!--[if IE]>\n";
263     $expected['#suffix'] = "<![endif]-->\n";
264     $tags['all-ie'] = [$element, $expected];
265
266     // Exclude IE.
267     $element = [
268       '#tag' => 'link',
269       '#browsers' => [
270         'IE' => FALSE,
271       ],
272     ];
273     $expected = $element;
274     $expected['#prefix'] = "\n<!--[if !IE]><!-->\n";
275     $expected['#suffix'] = "<!--<![endif]-->\n";
276     $tags['no-ie'] = [$element, $expected];
277
278     // IE gt 8
279     $element = [
280       '#tag' => 'link',
281       '#browsers' => [
282         'IE' => 'gt IE 8',
283       ],
284     ];
285     $expected = $element;
286     $expected['#prefix'] = "\n<!--[if gt IE 8]><!-->\n";
287     $expected['#suffix'] = "<!--<![endif]-->\n";
288     $tags['ie9plus'] = [$element, $expected];
289
290     // Prefix and suffix filtering if not safe.
291     $element = [
292       '#tag' => 'link',
293       '#browsers' => [
294         'IE' => FALSE,
295       ],
296       '#prefix' => '<blink>prefix</blink>',
297       '#suffix' => '<blink>suffix</blink>',
298     ];
299     $expected = $element;
300     $expected['#prefix'] = "\n<!--[if !IE]><!-->\nprefix";
301     $expected['#suffix'] = "suffix<!--<![endif]-->\n";
302     $tags['non-ie-unsafe'] = [$element, $expected];
303
304     // Prefix and suffix filtering if marked as safe. This has to come after the
305     // previous test case.
306     $expected['#prefix'] = "\n<!--[if !IE]><!-->\n<blink>prefix</blink>";
307     $expected['#suffix'] = "<blink>suffix</blink><!--<![endif]-->\n";
308     $tags['non-ie-safe'] = [$element, $expected, TRUE];
309
310     return $tags;
311   }
312
313 }