Mercurial > hg > isophonics-drupal-site
comparison core/tests/Drupal/Tests/Component/Utility/HtmlTest.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 7a779792577d |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\Tests\Component\Utility; | |
4 | |
5 use Drupal\Component\Render\MarkupInterface; | |
6 use Drupal\Component\Render\MarkupTrait; | |
7 use Drupal\Component\Utility\Html; | |
8 use Drupal\Component\Utility\Random; | |
9 use PHPUnit\Framework\TestCase; | |
10 | |
11 /** | |
12 * Tests \Drupal\Component\Utility\Html. | |
13 * | |
14 * @group Common | |
15 * | |
16 * @coversDefaultClass \Drupal\Component\Utility\Html | |
17 */ | |
18 class HtmlTest extends TestCase { | |
19 | |
20 /** | |
21 * {@inheritdoc} | |
22 */ | |
23 protected function setUp() { | |
24 parent::setUp(); | |
25 | |
26 $property = new \ReflectionProperty('Drupal\Component\Utility\Html', 'seenIdsInit'); | |
27 $property->setAccessible(TRUE); | |
28 $property->setValue(NULL); | |
29 } | |
30 | |
31 /** | |
32 * Tests the Html::cleanCssIdentifier() method. | |
33 * | |
34 * @param string $expected | |
35 * The expected result. | |
36 * @param string $source | |
37 * The string being transformed to an ID. | |
38 * @param array|null $filter | |
39 * (optional) An array of string replacements to use on the identifier. If | |
40 * NULL, no filter will be passed and a default will be used. | |
41 * | |
42 * @dataProvider providerTestCleanCssIdentifier | |
43 * | |
44 * @covers ::cleanCssIdentifier | |
45 */ | |
46 public function testCleanCssIdentifier($expected, $source, $filter = NULL) { | |
47 if ($filter !== NULL) { | |
48 $this->assertSame($expected, Html::cleanCssIdentifier($source, $filter)); | |
49 } | |
50 else { | |
51 $this->assertSame($expected, Html::cleanCssIdentifier($source)); | |
52 } | |
53 } | |
54 | |
55 /** | |
56 * Provides test data for testCleanCssIdentifier(). | |
57 * | |
58 * @return array | |
59 * Test data. | |
60 */ | |
61 public function providerTestCleanCssIdentifier() { | |
62 $id1 = 'abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789'; | |
63 $id2 = '¡¢£¤¥'; | |
64 $id3 = 'css__identifier__with__double__underscores'; | |
65 return [ | |
66 // Verify that no valid ASCII characters are stripped from the identifier. | |
67 [$id1, $id1, []], | |
68 // Verify that valid UTF-8 characters are not stripped from the identifier. | |
69 [$id2, $id2, []], | |
70 // Verify that invalid characters (including non-breaking space) are stripped from the identifier. | |
71 [$id3, $id3], | |
72 // Verify that double underscores are not stripped from the identifier. | |
73 ['invalididentifier', 'invalid !"#$%&\'()*+,./:;<=>?@[\\]^`{|}~ identifier', []], | |
74 // Verify that an identifier starting with a digit is replaced. | |
75 ['_cssidentifier', '1cssidentifier', []], | |
76 // Verify that an identifier starting with a hyphen followed by a digit is | |
77 // replaced. | |
78 ['__cssidentifier', '-1cssidentifier', []], | |
79 // Verify that an identifier starting with two hyphens is replaced. | |
80 ['__cssidentifier', '--cssidentifier', []], | |
81 // Verify that passing double underscores as a filter is processed. | |
82 ['_cssidentifier', '__cssidentifier', ['__' => '_']], | |
83 ]; | |
84 } | |
85 | |
86 /** | |
87 * Tests that Html::getClass() cleans the class name properly. | |
88 * | |
89 * @coversDefaultClass ::getClass | |
90 */ | |
91 public function testHtmlClass() { | |
92 // Verify Drupal coding standards are enforced. | |
93 $this->assertSame('class-name--ü', Html::getClass('CLASS NAME_[Ü]'), 'Enforce Drupal coding standards.'); | |
94 | |
95 // Test Html::getClass() handles Drupal\Component\Render\MarkupInterface | |
96 // input. | |
97 $markup = HtmlTestMarkup::create('CLASS_FROM_OBJECT'); | |
98 $this->assertSame('class-from-object', Html::getClass($markup), 'Markup object is converted to CSS class.'); | |
99 } | |
100 | |
101 /** | |
102 * Tests the Html::getUniqueId() method. | |
103 * | |
104 * @param string $expected | |
105 * The expected result. | |
106 * @param string $source | |
107 * The string being transformed to an ID. | |
108 * @param bool $reset | |
109 * (optional) If TRUE, reset the list of seen IDs. Defaults to FALSE. | |
110 * | |
111 * @dataProvider providerTestHtmlGetUniqueId | |
112 * | |
113 * @covers ::getUniqueId | |
114 */ | |
115 public function testHtmlGetUniqueId($expected, $source, $reset = FALSE) { | |
116 if ($reset) { | |
117 Html::resetSeenIds(); | |
118 } | |
119 $this->assertSame($expected, Html::getUniqueId($source)); | |
120 } | |
121 | |
122 /** | |
123 * Provides test data for testHtmlGetId(). | |
124 * | |
125 * @return array | |
126 * Test data. | |
127 */ | |
128 public function providerTestHtmlGetUniqueId() { | |
129 $id = 'abcdefghijklmnopqrstuvwxyz-0123456789'; | |
130 return [ | |
131 // Verify that letters, digits, and hyphens are not stripped from the ID. | |
132 [$id, $id], | |
133 // Verify that invalid characters are stripped from the ID. | |
134 ['invalididentifier', 'invalid,./:@\\^`{Üidentifier'], | |
135 // Verify Drupal coding standards are enforced. | |
136 ['id-name-1', 'ID NAME_[1]'], | |
137 // Verify that a repeated ID is made unique. | |
138 ['test-unique-id', 'test-unique-id', TRUE], | |
139 ['test-unique-id--2', 'test-unique-id'], | |
140 ['test-unique-id--3', 'test-unique-id'], | |
141 ]; | |
142 } | |
143 | |
144 /** | |
145 * Tests the Html::getUniqueId() method. | |
146 * | |
147 * @param string $expected | |
148 * The expected result. | |
149 * @param string $source | |
150 * The string being transformed to an ID. | |
151 * | |
152 * @dataProvider providerTestHtmlGetUniqueIdWithAjaxIds | |
153 * | |
154 * @covers ::getUniqueId | |
155 */ | |
156 public function testHtmlGetUniqueIdWithAjaxIds($expected, $source) { | |
157 Html::setIsAjax(TRUE); | |
158 $id = Html::getUniqueId($source); | |
159 | |
160 // Note, we truncate two hyphens at the end. | |
161 // @see \Drupal\Component\Utility\Html::getId() | |
162 if (strpos($source, '--') !== FALSE) { | |
163 $random_suffix = substr($id, strlen($source) + 1); | |
164 } | |
165 else { | |
166 $random_suffix = substr($id, strlen($source) + 2); | |
167 } | |
168 $expected = $expected . $random_suffix; | |
169 $this->assertSame($expected, $id); | |
170 } | |
171 | |
172 /** | |
173 * Provides test data for testHtmlGetId(). | |
174 * | |
175 * @return array | |
176 * Test data. | |
177 */ | |
178 public function providerTestHtmlGetUniqueIdWithAjaxIds() { | |
179 return [ | |
180 ['test-unique-id1--', 'test-unique-id1'], | |
181 // Note, we truncate two hyphens at the end. | |
182 // @see \Drupal\Component\Utility\Html::getId() | |
183 ['test-unique-id1---', 'test-unique-id1--'], | |
184 ['test-unique-id2--', 'test-unique-id2'], | |
185 ]; | |
186 } | |
187 | |
188 /** | |
189 * Tests the Html::getUniqueId() method. | |
190 * | |
191 * @param string $expected | |
192 * The expected result. | |
193 * @param string $source | |
194 * The string being transformed to an ID. | |
195 * | |
196 * @dataProvider providerTestHtmlGetId | |
197 * | |
198 * @covers ::getId | |
199 */ | |
200 public function testHtmlGetId($expected, $source) { | |
201 Html::setIsAjax(FALSE); | |
202 $this->assertSame($expected, Html::getId($source)); | |
203 } | |
204 | |
205 /** | |
206 * Provides test data for testHtmlGetId(). | |
207 * | |
208 * @return array | |
209 * Test data. | |
210 */ | |
211 public function providerTestHtmlGetId() { | |
212 $id = 'abcdefghijklmnopqrstuvwxyz-0123456789'; | |
213 return [ | |
214 // Verify that letters, digits, and hyphens are not stripped from the ID. | |
215 [$id, $id], | |
216 // Verify that invalid characters are stripped from the ID. | |
217 ['invalididentifier', 'invalid,./:@\\^`{Üidentifier'], | |
218 // Verify Drupal coding standards are enforced. | |
219 ['id-name-1', 'ID NAME_[1]'], | |
220 // Verify that a repeated ID is made unique. | |
221 ['test-unique-id', 'test-unique-id'], | |
222 ['test-unique-id', 'test-unique-id'], | |
223 ]; | |
224 } | |
225 | |
226 /** | |
227 * Tests Html::decodeEntities(). | |
228 * | |
229 * @dataProvider providerDecodeEntities | |
230 * @covers ::decodeEntities | |
231 */ | |
232 public function testDecodeEntities($text, $expected) { | |
233 $this->assertEquals($expected, Html::decodeEntities($text)); | |
234 } | |
235 | |
236 /** | |
237 * Data provider for testDecodeEntities(). | |
238 * | |
239 * @see testDecodeEntities() | |
240 */ | |
241 public function providerDecodeEntities() { | |
242 return [ | |
243 ['Drupal', 'Drupal'], | |
244 ['<script>', '<script>'], | |
245 ['<script>', '<script>'], | |
246 ['<script>', '<script>'], | |
247 ['&lt;script&gt;', '<script>'], | |
248 ['"', '"'], | |
249 ['"', '"'], | |
250 ['&#34;', '"'], | |
251 ['"', '"'], | |
252 ['&quot;', '"'], | |
253 ["'", "'"], | |
254 [''', "'"], | |
255 ['&#39;', '''], | |
256 ['©', '©'], | |
257 ['©', '©'], | |
258 ['©', '©'], | |
259 ['→', '→'], | |
260 ['→', '→'], | |
261 ['➼', '➼'], | |
262 ['➼', '➼'], | |
263 ['€', '€'], | |
264 ]; | |
265 } | |
266 | |
267 /** | |
268 * Tests Html::escape(). | |
269 * | |
270 * @dataProvider providerEscape | |
271 * @covers ::escape | |
272 */ | |
273 public function testEscape($expected, $text) { | |
274 $this->assertEquals($expected, Html::escape($text)); | |
275 } | |
276 | |
277 /** | |
278 * Data provider for testEscape(). | |
279 * | |
280 * @see testEscape() | |
281 */ | |
282 public function providerEscape() { | |
283 return [ | |
284 ['Drupal', 'Drupal'], | |
285 ['<script>', '<script>'], | |
286 ['&lt;script&gt;', '<script>'], | |
287 ['&#34;', '"'], | |
288 ['"', '"'], | |
289 ['&quot;', '"'], | |
290 [''', "'"], | |
291 ['&#039;', '''], | |
292 ['©', '©'], | |
293 ['→', '→'], | |
294 ['➼', '➼'], | |
295 ['€', '€'], | |
296 ['Drup�al', "Drup\x80al"], | |
297 ]; | |
298 } | |
299 | |
300 /** | |
301 * Tests relationship between escaping and decoding HTML entities. | |
302 * | |
303 * @covers ::decodeEntities | |
304 * @covers ::escape | |
305 */ | |
306 public function testDecodeEntitiesAndEscape() { | |
307 $string = "<em>répété</em>"; | |
308 $escaped = Html::escape($string); | |
309 $this->assertSame('<em>répét&eacute;</em>', $escaped); | |
310 $decoded = Html::decodeEntities($escaped); | |
311 $this->assertSame('<em>répété</em>', $decoded); | |
312 $decoded = Html::decodeEntities($decoded); | |
313 $this->assertSame('<em>répété</em>', $decoded); | |
314 $escaped = Html::escape($decoded); | |
315 $this->assertSame('<em>répété</em>', $escaped); | |
316 } | |
317 | |
318 /** | |
319 * Tests Html::serialize(). | |
320 * | |
321 * Resolves an issue by where an empty DOMDocument object sent to serialization would | |
322 * cause errors in getElementsByTagName() in the serialization function. | |
323 * | |
324 * @covers ::serialize | |
325 */ | |
326 public function testSerialize() { | |
327 $document = new \DOMDocument(); | |
328 $result = Html::serialize($document); | |
329 $this->assertSame('', $result); | |
330 } | |
331 | |
332 /** | |
333 * @covers ::transformRootRelativeUrlsToAbsolute | |
334 * @dataProvider providerTestTransformRootRelativeUrlsToAbsolute | |
335 */ | |
336 public function testTransformRootRelativeUrlsToAbsolute($html, $scheme_and_host, $expected_html) { | |
337 $this->assertSame($expected_html ?: $html, Html::transformRootRelativeUrlsToAbsolute($html, $scheme_and_host)); | |
338 } | |
339 | |
340 /** | |
341 * @covers ::transformRootRelativeUrlsToAbsolute | |
342 * @dataProvider providerTestTransformRootRelativeUrlsToAbsoluteAssertion | |
343 */ | |
344 public function testTransformRootRelativeUrlsToAbsoluteAssertion($scheme_and_host) { | |
345 $this->setExpectedException(\AssertionError::class); | |
346 Html::transformRootRelativeUrlsToAbsolute('', $scheme_and_host); | |
347 } | |
348 | |
349 /** | |
350 * Provides test data for testTransformRootRelativeUrlsToAbsolute(). | |
351 * | |
352 * @return array | |
353 * Test data. | |
354 */ | |
355 public function providerTestTransformRootRelativeUrlsToAbsolute() { | |
356 $data = []; | |
357 | |
358 // Random generator. | |
359 $random = new Random(); | |
360 | |
361 // One random tag name. | |
362 $tag_name = strtolower($random->name(8, TRUE)); | |
363 | |
364 // A site installed either in the root of a domain or a subdirectory. | |
365 $base_paths = ['/', '/subdir/' . $random->name(8, TRUE) . '/']; | |
366 | |
367 foreach ($base_paths as $base_path) { | |
368 // The only attribute that has more than just a URL as its value, is | |
369 // 'srcset', so special-case it. | |
370 $data += [ | |
371 "$tag_name, srcset, $base_path: root-relative" => ["<$tag_name srcset=\"http://example.com{$base_path}already-absolute 200w, {$base_path}root-relative 300w\">root-relative test</$tag_name>", 'http://example.com', "<$tag_name srcset=\"http://example.com{$base_path}already-absolute 200w, http://example.com{$base_path}root-relative 300w\">root-relative test</$tag_name>"], | |
372 "$tag_name, srcset, $base_path: protocol-relative" => ["<$tag_name srcset=\"http://example.com{$base_path}already-absolute 200w, //example.com{$base_path}protocol-relative 300w\">protocol-relative test</$tag_name>", 'http://example.com', FALSE], | |
373 "$tag_name, srcset, $base_path: absolute" => ["<$tag_name srcset=\"http://example.com{$base_path}already-absolute 200w, http://example.com{$base_path}absolute 300w\">absolute test</$tag_name>", 'http://example.com', FALSE], | |
374 ]; | |
375 | |
376 foreach (['href', 'poster', 'src', 'cite', 'data', 'action', 'formaction', 'about'] as $attribute) { | |
377 $data += [ | |
378 "$tag_name, $attribute, $base_path: root-relative" => ["<$tag_name $attribute=\"{$base_path}root-relative\">root-relative test</$tag_name>", 'http://example.com', "<$tag_name $attribute=\"http://example.com{$base_path}root-relative\">root-relative test</$tag_name>"], | |
379 "$tag_name, $attribute, $base_path: protocol-relative" => ["<$tag_name $attribute=\"//example.com{$base_path}protocol-relative\">protocol-relative test</$tag_name>", 'http://example.com', FALSE], | |
380 "$tag_name, $attribute, $base_path: absolute" => ["<$tag_name $attribute=\"http://example.com{$base_path}absolute\">absolute test</$tag_name>", 'http://example.com', FALSE], | |
381 ]; | |
382 } | |
383 } | |
384 | |
385 return $data; | |
386 } | |
387 | |
388 /** | |
389 * Provides test data for testTransformRootRelativeUrlsToAbsoluteAssertion(). | |
390 * | |
391 * @return array | |
392 * Test data. | |
393 */ | |
394 public function providerTestTransformRootRelativeUrlsToAbsoluteAssertion() { | |
395 return [ | |
396 'only relative path' => ['llama'], | |
397 'only root-relative path' => ['/llama'], | |
398 'host and path' => ['example.com/llama'], | |
399 'scheme, host and path' => ['http://example.com/llama'], | |
400 ]; | |
401 } | |
402 | |
403 } | |
404 | |
405 /** | |
406 * Marks an object's __toString() method as returning markup. | |
407 */ | |
408 class HtmlTestMarkup implements MarkupInterface { | |
409 use MarkupTrait; | |
410 | |
411 } |