Mercurial > hg > isophonics-drupal-site
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/tests/Drupal/Tests/Component/Utility/HtmlTest.php Wed Nov 29 16:09:58 2017 +0000 @@ -0,0 +1,411 @@ +<?php + +namespace Drupal\Tests\Component\Utility; + +use Drupal\Component\Render\MarkupInterface; +use Drupal\Component\Render\MarkupTrait; +use Drupal\Component\Utility\Html; +use Drupal\Component\Utility\Random; +use PHPUnit\Framework\TestCase; + +/** + * Tests \Drupal\Component\Utility\Html. + * + * @group Common + * + * @coversDefaultClass \Drupal\Component\Utility\Html + */ +class HtmlTest extends TestCase { + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + + $property = new \ReflectionProperty('Drupal\Component\Utility\Html', 'seenIdsInit'); + $property->setAccessible(TRUE); + $property->setValue(NULL); + } + + /** + * Tests the Html::cleanCssIdentifier() method. + * + * @param string $expected + * The expected result. + * @param string $source + * The string being transformed to an ID. + * @param array|null $filter + * (optional) An array of string replacements to use on the identifier. If + * NULL, no filter will be passed and a default will be used. + * + * @dataProvider providerTestCleanCssIdentifier + * + * @covers ::cleanCssIdentifier + */ + public function testCleanCssIdentifier($expected, $source, $filter = NULL) { + if ($filter !== NULL) { + $this->assertSame($expected, Html::cleanCssIdentifier($source, $filter)); + } + else { + $this->assertSame($expected, Html::cleanCssIdentifier($source)); + } + } + + /** + * Provides test data for testCleanCssIdentifier(). + * + * @return array + * Test data. + */ + public function providerTestCleanCssIdentifier() { + $id1 = 'abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789'; + $id2 = '¡¢£¤¥'; + $id3 = 'css__identifier__with__double__underscores'; + return [ + // Verify that no valid ASCII characters are stripped from the identifier. + [$id1, $id1, []], + // Verify that valid UTF-8 characters are not stripped from the identifier. + [$id2, $id2, []], + // Verify that invalid characters (including non-breaking space) are stripped from the identifier. + [$id3, $id3], + // Verify that double underscores are not stripped from the identifier. + ['invalididentifier', 'invalid !"#$%&\'()*+,./:;<=>?@[\\]^`{|}~ identifier', []], + // Verify that an identifier starting with a digit is replaced. + ['_cssidentifier', '1cssidentifier', []], + // Verify that an identifier starting with a hyphen followed by a digit is + // replaced. + ['__cssidentifier', '-1cssidentifier', []], + // Verify that an identifier starting with two hyphens is replaced. + ['__cssidentifier', '--cssidentifier', []], + // Verify that passing double underscores as a filter is processed. + ['_cssidentifier', '__cssidentifier', ['__' => '_']], + ]; + } + + /** + * Tests that Html::getClass() cleans the class name properly. + * + * @coversDefaultClass ::getClass + */ + public function testHtmlClass() { + // Verify Drupal coding standards are enforced. + $this->assertSame('class-name--ü', Html::getClass('CLASS NAME_[Ü]'), 'Enforce Drupal coding standards.'); + + // Test Html::getClass() handles Drupal\Component\Render\MarkupInterface + // input. + $markup = HtmlTestMarkup::create('CLASS_FROM_OBJECT'); + $this->assertSame('class-from-object', Html::getClass($markup), 'Markup object is converted to CSS class.'); + } + + /** + * Tests the Html::getUniqueId() method. + * + * @param string $expected + * The expected result. + * @param string $source + * The string being transformed to an ID. + * @param bool $reset + * (optional) If TRUE, reset the list of seen IDs. Defaults to FALSE. + * + * @dataProvider providerTestHtmlGetUniqueId + * + * @covers ::getUniqueId + */ + public function testHtmlGetUniqueId($expected, $source, $reset = FALSE) { + if ($reset) { + Html::resetSeenIds(); + } + $this->assertSame($expected, Html::getUniqueId($source)); + } + + /** + * Provides test data for testHtmlGetId(). + * + * @return array + * Test data. + */ + public function providerTestHtmlGetUniqueId() { + $id = 'abcdefghijklmnopqrstuvwxyz-0123456789'; + return [ + // Verify that letters, digits, and hyphens are not stripped from the ID. + [$id, $id], + // Verify that invalid characters are stripped from the ID. + ['invalididentifier', 'invalid,./:@\\^`{Üidentifier'], + // Verify Drupal coding standards are enforced. + ['id-name-1', 'ID NAME_[1]'], + // Verify that a repeated ID is made unique. + ['test-unique-id', 'test-unique-id', TRUE], + ['test-unique-id--2', 'test-unique-id'], + ['test-unique-id--3', 'test-unique-id'], + ]; + } + + /** + * Tests the Html::getUniqueId() method. + * + * @param string $expected + * The expected result. + * @param string $source + * The string being transformed to an ID. + * + * @dataProvider providerTestHtmlGetUniqueIdWithAjaxIds + * + * @covers ::getUniqueId + */ + public function testHtmlGetUniqueIdWithAjaxIds($expected, $source) { + Html::setIsAjax(TRUE); + $id = Html::getUniqueId($source); + + // Note, we truncate two hyphens at the end. + // @see \Drupal\Component\Utility\Html::getId() + if (strpos($source, '--') !== FALSE) { + $random_suffix = substr($id, strlen($source) + 1); + } + else { + $random_suffix = substr($id, strlen($source) + 2); + } + $expected = $expected . $random_suffix; + $this->assertSame($expected, $id); + } + + /** + * Provides test data for testHtmlGetId(). + * + * @return array + * Test data. + */ + public function providerTestHtmlGetUniqueIdWithAjaxIds() { + return [ + ['test-unique-id1--', 'test-unique-id1'], + // Note, we truncate two hyphens at the end. + // @see \Drupal\Component\Utility\Html::getId() + ['test-unique-id1---', 'test-unique-id1--'], + ['test-unique-id2--', 'test-unique-id2'], + ]; + } + + /** + * Tests the Html::getUniqueId() method. + * + * @param string $expected + * The expected result. + * @param string $source + * The string being transformed to an ID. + * + * @dataProvider providerTestHtmlGetId + * + * @covers ::getId + */ + public function testHtmlGetId($expected, $source) { + Html::setIsAjax(FALSE); + $this->assertSame($expected, Html::getId($source)); + } + + /** + * Provides test data for testHtmlGetId(). + * + * @return array + * Test data. + */ + public function providerTestHtmlGetId() { + $id = 'abcdefghijklmnopqrstuvwxyz-0123456789'; + return [ + // Verify that letters, digits, and hyphens are not stripped from the ID. + [$id, $id], + // Verify that invalid characters are stripped from the ID. + ['invalididentifier', 'invalid,./:@\\^`{Üidentifier'], + // Verify Drupal coding standards are enforced. + ['id-name-1', 'ID NAME_[1]'], + // Verify that a repeated ID is made unique. + ['test-unique-id', 'test-unique-id'], + ['test-unique-id', 'test-unique-id'], + ]; + } + + /** + * Tests Html::decodeEntities(). + * + * @dataProvider providerDecodeEntities + * @covers ::decodeEntities + */ + public function testDecodeEntities($text, $expected) { + $this->assertEquals($expected, Html::decodeEntities($text)); + } + + /** + * Data provider for testDecodeEntities(). + * + * @see testDecodeEntities() + */ + public function providerDecodeEntities() { + return [ + ['Drupal', 'Drupal'], + ['<script>', '<script>'], + ['<script>', '<script>'], + ['<script>', '<script>'], + ['&lt;script&gt;', '<script>'], + ['"', '"'], + ['"', '"'], + ['&#34;', '"'], + ['"', '"'], + ['&quot;', '"'], + ["'", "'"], + [''', "'"], + ['&#39;', '''], + ['©', '©'], + ['©', '©'], + ['©', '©'], + ['→', '→'], + ['→', '→'], + ['➼', '➼'], + ['➼', '➼'], + ['€', '€'], + ]; + } + + /** + * Tests Html::escape(). + * + * @dataProvider providerEscape + * @covers ::escape + */ + public function testEscape($expected, $text) { + $this->assertEquals($expected, Html::escape($text)); + } + + /** + * Data provider for testEscape(). + * + * @see testEscape() + */ + public function providerEscape() { + return [ + ['Drupal', 'Drupal'], + ['<script>', '<script>'], + ['&lt;script&gt;', '<script>'], + ['&#34;', '"'], + ['"', '"'], + ['&quot;', '"'], + [''', "'"], + ['&#039;', '''], + ['©', '©'], + ['→', '→'], + ['➼', '➼'], + ['€', '€'], + ['Drup�al', "Drup\x80al"], + ]; + } + + /** + * Tests relationship between escaping and decoding HTML entities. + * + * @covers ::decodeEntities + * @covers ::escape + */ + public function testDecodeEntitiesAndEscape() { + $string = "<em>répété</em>"; + $escaped = Html::escape($string); + $this->assertSame('<em>répét&eacute;</em>', $escaped); + $decoded = Html::decodeEntities($escaped); + $this->assertSame('<em>répété</em>', $decoded); + $decoded = Html::decodeEntities($decoded); + $this->assertSame('<em>répété</em>', $decoded); + $escaped = Html::escape($decoded); + $this->assertSame('<em>répété</em>', $escaped); + } + + /** + * Tests Html::serialize(). + * + * Resolves an issue by where an empty DOMDocument object sent to serialization would + * cause errors in getElementsByTagName() in the serialization function. + * + * @covers ::serialize + */ + public function testSerialize() { + $document = new \DOMDocument(); + $result = Html::serialize($document); + $this->assertSame('', $result); + } + + /** + * @covers ::transformRootRelativeUrlsToAbsolute + * @dataProvider providerTestTransformRootRelativeUrlsToAbsolute + */ + public function testTransformRootRelativeUrlsToAbsolute($html, $scheme_and_host, $expected_html) { + $this->assertSame($expected_html ?: $html, Html::transformRootRelativeUrlsToAbsolute($html, $scheme_and_host)); + } + + /** + * @covers ::transformRootRelativeUrlsToAbsolute + * @dataProvider providerTestTransformRootRelativeUrlsToAbsoluteAssertion + */ + public function testTransformRootRelativeUrlsToAbsoluteAssertion($scheme_and_host) { + $this->setExpectedException(\AssertionError::class); + Html::transformRootRelativeUrlsToAbsolute('', $scheme_and_host); + } + + /** + * Provides test data for testTransformRootRelativeUrlsToAbsolute(). + * + * @return array + * Test data. + */ + public function providerTestTransformRootRelativeUrlsToAbsolute() { + $data = []; + + // Random generator. + $random = new Random(); + + // One random tag name. + $tag_name = strtolower($random->name(8, TRUE)); + + // A site installed either in the root of a domain or a subdirectory. + $base_paths = ['/', '/subdir/' . $random->name(8, TRUE) . '/']; + + foreach ($base_paths as $base_path) { + // The only attribute that has more than just a URL as its value, is + // 'srcset', so special-case it. + $data += [ + "$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>"], + "$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], + "$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], + ]; + + foreach (['href', 'poster', 'src', 'cite', 'data', 'action', 'formaction', 'about'] as $attribute) { + $data += [ + "$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>"], + "$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], + "$tag_name, $attribute, $base_path: absolute" => ["<$tag_name $attribute=\"http://example.com{$base_path}absolute\">absolute test</$tag_name>", 'http://example.com', FALSE], + ]; + } + } + + return $data; + } + + /** + * Provides test data for testTransformRootRelativeUrlsToAbsoluteAssertion(). + * + * @return array + * Test data. + */ + public function providerTestTransformRootRelativeUrlsToAbsoluteAssertion() { + return [ + 'only relative path' => ['llama'], + 'only root-relative path' => ['/llama'], + 'host and path' => ['example.com/llama'], + 'scheme, host and path' => ['http://example.com/llama'], + ]; + } + +} + +/** + * Marks an object's __toString() method as returning markup. + */ +class HtmlTestMarkup implements MarkupInterface { + use MarkupTrait; + +}