Update to drupal 8.0.0-rc1. For more information, see https://www.drupal.org/node/2582663
This commit is contained in:
parent
eb34d130a8
commit
f32e58e4b1
8476 changed files with 211648 additions and 170042 deletions
|
@ -31,12 +31,36 @@ class InspectorTest extends PHPUnit_Framework_TestCase {
|
|||
* Tests asserting all members are strings.
|
||||
*
|
||||
* @covers ::assertAllStrings
|
||||
* @dataProvider providerTestAssertAllStrings
|
||||
*/
|
||||
public function testAssertAllStrings() {
|
||||
$this->assertTrue(Inspector::assertAllStrings([]));
|
||||
$this->assertTrue(Inspector::assertAllStrings(['foo', 'bar']));
|
||||
$this->assertFalse(Inspector::assertAllStrings('foo'));
|
||||
$this->assertFalse(Inspector::assertAllStrings(['foo', new StringObject()]));
|
||||
public function testAssertAllStrings($input, $expected) {
|
||||
$this->assertSame($expected, Inspector::assertAllStrings($input));
|
||||
}
|
||||
|
||||
public function providerTestAssertAllStrings() {
|
||||
$data = [
|
||||
'empty-array' => [[], TRUE],
|
||||
'array-with-strings' => [['foo', 'bar'], TRUE],
|
||||
'string' => ['foo', FALSE],
|
||||
'array-with-strings-with-colon' => [['foo', 'bar', 'llama:2001988', 'baz', 'llama:14031991'], TRUE],
|
||||
|
||||
'with-FALSE' => [[FALSE], FALSE],
|
||||
'with-TRUE' => [[TRUE], FALSE],
|
||||
'with-string-and-boolean' => [['foo', FALSE], FALSE],
|
||||
'with-NULL' => [[NULL], FALSE],
|
||||
'string-with-NULL' => [['foo', NULL], FALSE],
|
||||
'integer' => [[1337], FALSE],
|
||||
'string-and-integer' => [['foo', 1337], FALSE],
|
||||
'double' => [[3.14], FALSE],
|
||||
'string-and-double' => [['foo', 3.14], FALSE],
|
||||
'array' => [[[]], FALSE],
|
||||
'string-and-array' => [['foo', []], FALSE],
|
||||
'string-and-nested-array' => [['foo', ['bar']], FALSE],
|
||||
'object' => [[new \stdClass()], FALSE],
|
||||
'string-and-object' => [['foo', new StringObject()], FALSE],
|
||||
];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,7 +7,11 @@
|
|||
|
||||
namespace Drupal\Tests\Component\Plugin;
|
||||
|
||||
use Drupal\Component\Plugin\Definition\PluginDefinitionInterface;
|
||||
use Drupal\Component\Plugin\Factory\DefaultFactory;
|
||||
use Drupal\plugin_test\Plugin\plugin_test\fruit\Cherry;
|
||||
use Drupal\plugin_test\Plugin\plugin_test\fruit\FruitInterface;
|
||||
use Drupal\plugin_test\Plugin\plugin_test\fruit\Kale;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
|
@ -17,41 +21,110 @@ use Drupal\Tests\UnitTestCase;
|
|||
class DefaultFactoryTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* Tests getPluginClass() with a valid plugin.
|
||||
* Tests getPluginClass() with a valid array plugin definition.
|
||||
*
|
||||
* @covers ::getPluginClass
|
||||
*/
|
||||
public function testGetPluginClassWithValidPlugin() {
|
||||
$plugin_class = 'Drupal\plugin_test\Plugin\plugin_test\fruit\Cherry';
|
||||
public function testGetPluginClassWithValidArrayPluginDefinition() {
|
||||
$plugin_class = Cherry::class;
|
||||
$class = DefaultFactory::getPluginClass('cherry', ['class' => $plugin_class]);
|
||||
|
||||
$this->assertEquals($plugin_class, $class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests getPluginClass() with a valid object plugin definition.
|
||||
*
|
||||
* @covers ::getPluginClass
|
||||
*/
|
||||
public function testGetPluginClassWithValidObjectPluginDefinition() {
|
||||
$plugin_class = Cherry::class;
|
||||
$plugin_definition = $this->getMock(PluginDefinitionInterface::class);
|
||||
$plugin_definition->expects($this->atLeastOnce())
|
||||
->method('getClass')
|
||||
->willReturn($plugin_class);
|
||||
$class = DefaultFactory::getPluginClass('cherry', $plugin_definition);
|
||||
|
||||
$this->assertEquals($plugin_class, $class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests getPluginClass() with a missing class definition.
|
||||
*
|
||||
* @covers ::getPluginClass
|
||||
*
|
||||
* @expectedException \Drupal\Component\Plugin\Exception\PluginException
|
||||
* @expectedExceptionMessage The plugin (cherry) did not specify an instance class.
|
||||
*/
|
||||
public function testGetPluginClassWithMissingClass() {
|
||||
public function testGetPluginClassWithMissingClassWithArrayPluginDefinition() {
|
||||
DefaultFactory::getPluginClass('cherry', []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests getPluginClass() with a missing class definition.
|
||||
*
|
||||
* @covers ::getPluginClass
|
||||
*
|
||||
* @expectedException \Drupal\Component\Plugin\Exception\PluginException
|
||||
* @expectedExceptionMessage The plugin (cherry) did not specify an instance class.
|
||||
*/
|
||||
public function testGetPluginClassWithMissingClassWithObjectPluginDefinition() {
|
||||
$plugin_definition = $this->getMock(PluginDefinitionInterface::class);
|
||||
DefaultFactory::getPluginClass('cherry', $plugin_definition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests getPluginClass() with a not existing class definition.
|
||||
*
|
||||
* @covers ::getPluginClass
|
||||
*
|
||||
* @expectedException \Drupal\Component\Plugin\Exception\PluginException
|
||||
* @expectedExceptionMessage Plugin (kiwifruit) instance class "\Drupal\plugin_test\Plugin\plugin_test\fruit\Kiwifruit" does not exist.
|
||||
*/
|
||||
public function testGetPluginClassWithNotExistingClass() {
|
||||
public function testGetPluginClassWithNotExistingClassWithArrayPluginDefinition() {
|
||||
DefaultFactory::getPluginClass('kiwifruit', ['class' => '\Drupal\plugin_test\Plugin\plugin_test\fruit\Kiwifruit']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests getPluginClass() with a required interface.
|
||||
* Tests getPluginClass() with a not existing class definition.
|
||||
*
|
||||
* @covers ::getPluginClass
|
||||
*
|
||||
* @expectedException \Drupal\Component\Plugin\Exception\PluginException
|
||||
*/
|
||||
public function testGetPluginClassWithInterface() {
|
||||
$plugin_class = 'Drupal\plugin_test\Plugin\plugin_test\fruit\Cherry';
|
||||
$class = DefaultFactory::getPluginClass('cherry', ['class' => $plugin_class], '\Drupal\plugin_test\Plugin\plugin_test\fruit\FruitInterface');
|
||||
public function testGetPluginClassWithNotExistingClassWithObjectPluginDefinition() {
|
||||
$plugin_class = '\Drupal\plugin_test\Plugin\plugin_test\fruit\Kiwifruit';
|
||||
$plugin_definition = $this->getMock(PluginDefinitionInterface::class);
|
||||
$plugin_definition->expects($this->atLeastOnce())
|
||||
->method('getClass')
|
||||
->willReturn($plugin_class);
|
||||
DefaultFactory::getPluginClass('kiwifruit', $plugin_definition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests getPluginClass() with a required interface.
|
||||
*
|
||||
* @covers ::getPluginClass
|
||||
*/
|
||||
public function testGetPluginClassWithInterfaceWithArrayPluginDefinition() {
|
||||
$plugin_class = Cherry::class;
|
||||
$class = DefaultFactory::getPluginClass('cherry', ['class' => $plugin_class], FruitInterface::class);
|
||||
|
||||
$this->assertEquals($plugin_class, $class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests getPluginClass() with a required interface.
|
||||
*
|
||||
* @covers ::getPluginClass
|
||||
*/
|
||||
public function testGetPluginClassWithInterfaceWithObjectPluginDefinition() {
|
||||
$plugin_class = Cherry::class;
|
||||
$plugin_definition = $this->getMock(PluginDefinitionInterface::class);
|
||||
$plugin_definition->expects($this->atLeastOnce())
|
||||
->method('getClass')
|
||||
->willReturn($plugin_class);
|
||||
$class = DefaultFactory::getPluginClass('cherry', $plugin_definition, FruitInterface::class);
|
||||
|
||||
$this->assertEquals($plugin_class, $class);
|
||||
}
|
||||
|
@ -59,12 +132,30 @@ class DefaultFactoryTest extends UnitTestCase {
|
|||
/**
|
||||
* Tests getPluginClass() with a required interface but no implementation.
|
||||
*
|
||||
* @covers ::getPluginClass
|
||||
*
|
||||
* @expectedException \Drupal\Component\Plugin\Exception\PluginException
|
||||
* @expectedExceptionMessage Plugin "cherry" (Drupal\plugin_test\Plugin\plugin_test\fruit\Kale) must implement interface \Drupal\plugin_test\Plugin\plugin_test\fruit\FruitInterface.
|
||||
* @expectedExceptionMessage Plugin "cherry" (Drupal\plugin_test\Plugin\plugin_test\fruit\Kale) must implement interface Drupal\plugin_test\Plugin\plugin_test\fruit\FruitInterface.
|
||||
*/
|
||||
public function testGetPluginClassWithInterfaceAndInvalidClass() {
|
||||
$plugin_class = 'Drupal\plugin_test\Plugin\plugin_test\fruit\Kale';
|
||||
DefaultFactory::getPluginClass('cherry', ['class' => $plugin_class, 'provider' => 'core'], '\Drupal\plugin_test\Plugin\plugin_test\fruit\FruitInterface');
|
||||
public function testGetPluginClassWithInterfaceAndInvalidClassWithArrayPluginDefinition() {
|
||||
$plugin_class = Kale::class;
|
||||
DefaultFactory::getPluginClass('cherry', ['class' => $plugin_class, 'provider' => 'core'], FruitInterface::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests getPluginClass() with a required interface but no implementation.
|
||||
*
|
||||
* @covers ::getPluginClass
|
||||
*
|
||||
* @expectedException \Drupal\Component\Plugin\Exception\PluginException
|
||||
*/
|
||||
public function testGetPluginClassWithInterfaceAndInvalidClassWithObjectPluginDefinition() {
|
||||
$plugin_class = Kale::class;
|
||||
$plugin_definition = $this->getMock(PluginDefinitionInterface::class);
|
||||
$plugin_definition->expects($this->atLeastOnce())
|
||||
->method('getClass')
|
||||
->willReturn($plugin_class);
|
||||
DefaultFactory::getPluginClass('cherry', $plugin_definition, FruitInterface::class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Component\Render\FormattableMarkupTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Component\Render;
|
||||
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* Tests the TranslatableMarkup class.
|
||||
*
|
||||
* @coversDefaultClass \Drupal\Component\Render\FormattableMarkup
|
||||
* @group utility
|
||||
*/
|
||||
class FormattableMarkupTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @covers ::__toString
|
||||
* @covers ::jsonSerialize
|
||||
*/
|
||||
public function testToString() {
|
||||
$string = 'Can I please have a @replacement';
|
||||
$formattable_string = new FormattableMarkup($string, ['@replacement' => 'kitten']);
|
||||
$text = (string) $formattable_string;
|
||||
$this->assertEquals('Can I please have a kitten', $text);
|
||||
$text = $formattable_string->jsonSerialize();
|
||||
$this->assertEquals('Can I please have a kitten', $text);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::count
|
||||
*/
|
||||
public function testCount() {
|
||||
$string = 'Can I please have a @replacement';
|
||||
$formattable_string = new FormattableMarkup($string, ['@replacement' => 'kitten']);
|
||||
$this->assertEquals(strlen($string), $formattable_string->count());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Component\Render\HtmlEscapedTextTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Component\Render;
|
||||
|
||||
use Drupal\Component\Render\HtmlEscapedText;
|
||||
use Drupal\Component\Render\MarkupInterface;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* Tests the HtmlEscapedText class.
|
||||
*
|
||||
* @coversDefaultClass \Drupal\Component\Render\HtmlEscapedText
|
||||
* @group utility
|
||||
*/
|
||||
class HtmlEscapedTextTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @covers ::__toString
|
||||
* @covers ::jsonSerialize
|
||||
*
|
||||
* @dataProvider providerToString
|
||||
*/
|
||||
public function testToString($text, $expected, $message) {
|
||||
$escapeable_string = new HtmlEscapedText($text);
|
||||
$this->assertEquals($expected, (string) $escapeable_string, $message);
|
||||
$this->assertEquals($expected, $escapeable_string->jsonSerialize());
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testToString().
|
||||
*
|
||||
* @see testToString()
|
||||
*/
|
||||
function providerToString() {
|
||||
// Checks that invalid multi-byte sequences are escaped.
|
||||
$tests[] = array("Foo\xC0barbaz", 'Foo<6F>barbaz', 'Escapes invalid sequence "Foo\xC0barbaz"');
|
||||
$tests[] = array("\xc2\"", '<27>"', 'Escapes invalid sequence "\xc2\""');
|
||||
$tests[] = array("Fooÿñ", "Fooÿñ", 'Does not escape valid sequence "Fooÿñ"');
|
||||
|
||||
// Checks that special characters are escaped.
|
||||
$script_tag = $this->prophesize(MarkupInterface::class);
|
||||
$script_tag->__toString()->willReturn('<script>');
|
||||
$script_tag = $script_tag->reveal();
|
||||
$tests[] = array($script_tag, '<script>', 'Escapes <script> even inside an object that implements MarkupInterface.');
|
||||
$tests[] = array("<script>", '<script>', 'Escapes <script>');
|
||||
$tests[] = array('<>&"\'', '<>&"'', 'Escapes reserved HTML characters.');
|
||||
$specialchars = $this->prophesize(MarkupInterface::class);
|
||||
$specialchars->__toString()->willReturn('<>&"\'');
|
||||
$specialchars = $specialchars->reveal();
|
||||
$tests[] = array($specialchars, '<>&"'', 'Escapes reserved HTML characters even inside an object that implements MarkupInterface.');
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::count
|
||||
*/
|
||||
public function testCount() {
|
||||
$string = 'Can I please have a <em>kitten</em>';
|
||||
$escapeable_string = new HtmlEscapedText($string);
|
||||
$this->assertEquals(strlen($string), $escapeable_string->count());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Component\Render\PlainTextOutputTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Component\Render;
|
||||
|
||||
use Drupal\Component\Render\PlainTextOutput;
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Render\MarkupInterface;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Component\Render\PlainTextOutput
|
||||
* @group Utility
|
||||
*/
|
||||
class PlainTextOutputTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* Tests ::renderFromHtml().
|
||||
*
|
||||
* @param $expected
|
||||
* The expected formatted value.
|
||||
* @param $string
|
||||
* A string to be formatted.
|
||||
* @param array $args
|
||||
* (optional) An associative array of replacements to make. Defaults to
|
||||
* none.
|
||||
*
|
||||
* @covers ::renderFromHtml
|
||||
* @dataProvider providerRenderFromHtml
|
||||
*/
|
||||
public function testRenderFromHtml($expected, $string, $args = []) {
|
||||
$markup = SafeMarkup::format($string, $args);
|
||||
$output = PlainTextOutput::renderFromHtml($markup);
|
||||
$this->assertSame($expected, $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for ::testRenderFromHtml()
|
||||
*/
|
||||
public function providerRenderFromHtml() {
|
||||
$data = [];
|
||||
|
||||
$data['simple-text'] = ['Giraffes and wombats', 'Giraffes and wombats'];
|
||||
$data['simple-html'] = ['Giraffes and wombats', '<a href="/muh">Giraffes</a> and <strong>wombats</strong>'];
|
||||
$data['html-with-quote'] = ['Giraffes and quote"s', '<a href="/muh">Giraffes</a> and <strong>quote"s</strong>'];
|
||||
|
||||
$expected = 'The <em> tag makes your text look like "this".';
|
||||
$string = 'The <em> tag makes your text look like <em>"this"</em>.';
|
||||
$data['escaped-html-with-quotes'] = [$expected, $string];
|
||||
|
||||
$safe_string = $this->prophesize(MarkupInterface::class);
|
||||
$safe_string->__toString()->willReturn('<em>"this"</em>');
|
||||
$safe_string = $safe_string->reveal();
|
||||
$data['escaped-html-with-quotes-and-placeholders'] = [$expected, 'The @tag tag makes your text look like @result.', ['@tag' =>'<em>', '@result' => $safe_string]];
|
||||
|
||||
$safe_string = $this->prophesize(MarkupInterface::class);
|
||||
$safe_string->__toString()->willReturn($string);
|
||||
$safe_string = $safe_string->reveal();
|
||||
$data['safe-string'] = [$expected, $safe_string];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
|
@ -79,7 +79,9 @@ class HtmlTest extends UnitTestCase {
|
|||
// replaced.
|
||||
array('__cssidentifier', '-1cssidentifier', array()),
|
||||
// Verify that an identifier starting with two hyphens is replaced.
|
||||
array('__cssidentifier', '--cssidentifier', array())
|
||||
array('__cssidentifier', '--cssidentifier', array()),
|
||||
// Verify that passing double underscores as a filter is processed.
|
||||
array('_cssidentifier', '__cssidentifier', array('__' => '_')),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -231,7 +233,7 @@ class HtmlTest extends UnitTestCase {
|
|||
/**
|
||||
* Data provider for testDecodeEntities().
|
||||
*
|
||||
* @see testCheckPlain()
|
||||
* @see testDecodeEntities()
|
||||
*/
|
||||
public function providerDecodeEntities() {
|
||||
return array(
|
||||
|
@ -272,7 +274,7 @@ class HtmlTest extends UnitTestCase {
|
|||
/**
|
||||
* Data provider for testEscape().
|
||||
*
|
||||
* @see testCheckPlain()
|
||||
* @see testEscape()
|
||||
*/
|
||||
public function providerEscape() {
|
||||
return array(
|
||||
|
@ -310,4 +312,17 @@ class HtmlTest extends UnitTestCase {
|
|||
$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);
|
||||
}
|
||||
}
|
|
@ -7,9 +7,11 @@
|
|||
|
||||
namespace Drupal\Tests\Component\Utility;
|
||||
|
||||
use Drupal\Component\Render\HtmlEscapedText;
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Utility\SafeStringInterface;
|
||||
use Drupal\Component\Utility\SafeStringTrait;
|
||||
use Drupal\Component\Render\MarkupInterface;
|
||||
use Drupal\Component\Render\MarkupTrait;
|
||||
use Drupal\Component\Utility\UrlHelper;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
|
@ -21,81 +23,12 @@ use Drupal\Tests\UnitTestCase;
|
|||
class SafeMarkupTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* Helper function to add a string to the safe list for testing.
|
||||
*
|
||||
* @param string $string
|
||||
* The content to be marked as secure.
|
||||
* @param string $strategy
|
||||
* The escaping strategy used for this string. Two values are supported
|
||||
* by default:
|
||||
* - 'html': (default) The string is safe for use in HTML code.
|
||||
* - 'all': The string is safe for all use cases.
|
||||
* See the
|
||||
* @link http://twig.sensiolabs.org/doc/filters/escape.html Twig escape documentation @endlink
|
||||
* for more information on escaping strategies in Twig.
|
||||
*
|
||||
* @return string
|
||||
* The input string that was marked as safe.
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function safeMarkupSet($string, $strategy = 'html') {
|
||||
$reflected_class = new \ReflectionClass('\Drupal\Component\Utility\SafeMarkup');
|
||||
$reflected_property = $reflected_class->getProperty('safeStrings');
|
||||
$reflected_property->setAccessible(true);
|
||||
$current_value = $reflected_property->getValue();
|
||||
$current_value[$string][$strategy] = TRUE;
|
||||
$reflected_property->setValue($current_value);
|
||||
return $string;
|
||||
}
|
||||
protected function tearDown() {
|
||||
parent::tearDown();
|
||||
|
||||
/**
|
||||
* Tests SafeMarkup::isSafe() with different providers.
|
||||
*
|
||||
* @covers ::isSafe
|
||||
*/
|
||||
public function testStrategy() {
|
||||
$returned = $this->safeMarkupSet('string0', 'html');
|
||||
$this->assertTrue(SafeMarkup::isSafe($returned), 'String set with "html" provider is safe for default (html)');
|
||||
$returned = $this->safeMarkupSet('string1', 'all');
|
||||
$this->assertTrue(SafeMarkup::isSafe($returned), 'String set with "all" provider is safe for default (html)');
|
||||
$returned = $this->safeMarkupSet('string2', 'css');
|
||||
$this->assertFalse(SafeMarkup::isSafe($returned), 'String set with "css" provider is not safe for default (html)');
|
||||
$returned = $this->safeMarkupSet('string3');
|
||||
$this->assertFalse(SafeMarkup::isSafe($returned, 'all'), 'String set with "html" provider is not safe for "all"');
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testSet().
|
||||
*/
|
||||
public function providerSet() {
|
||||
// Checks that invalid multi-byte sequences are escaped.
|
||||
$tests[] = array(
|
||||
'Foo<6F>barbaz',
|
||||
'SafeMarkup::setMarkup() functions with valid sequence "Foo<6F>barbaz"',
|
||||
TRUE
|
||||
);
|
||||
$tests[] = array(
|
||||
"Fooÿñ",
|
||||
'SafeMarkup::setMarkup() functions with valid sequence "Fooÿñ"'
|
||||
);
|
||||
$tests[] = array("<div>", 'SafeMarkup::setMultiple() does not escape HTML');
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests SafeMarkup::setMultiple().
|
||||
* @dataProvider providerSet
|
||||
*
|
||||
* @param string $text
|
||||
* The text or object to provide to SafeMarkup::setMultiple().
|
||||
* @param string $message
|
||||
* The message to provide as output for the test.
|
||||
*
|
||||
* @covers ::setMultiple
|
||||
*/
|
||||
public function testSet($text, $message) {
|
||||
SafeMarkup::setMultiple([$text => ['html' => TRUE]]);
|
||||
$this->assertTrue(SafeMarkup::isSafe($text), $message);
|
||||
UrlHelper::setAllowedProtocols(['http', 'https']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -104,44 +37,12 @@ class SafeMarkupTest extends UnitTestCase {
|
|||
* @covers ::isSafe
|
||||
*/
|
||||
public function testIsSafe() {
|
||||
$safe_string = $this->getMock('\Drupal\Component\Utility\SafeStringInterface');
|
||||
$safe_string = $this->getMock('\Drupal\Component\Render\MarkupInterface');
|
||||
$this->assertTrue(SafeMarkup::isSafe($safe_string));
|
||||
$string_object = new SafeMarkupTestString('test');
|
||||
$this->assertFalse(SafeMarkup::isSafe($string_object));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests SafeMarkup::setMultiple().
|
||||
*
|
||||
* @covers ::setMultiple
|
||||
*/
|
||||
public function testSetMultiple() {
|
||||
$texts = array(
|
||||
'multistring0' => array('html' => TRUE),
|
||||
'multistring1' => array('all' => TRUE),
|
||||
);
|
||||
SafeMarkup::setMultiple($texts);
|
||||
foreach ($texts as $string => $providers) {
|
||||
$this->assertTrue(SafeMarkup::isSafe($string), 'The value has been marked as safe for html');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests SafeMarkup::setMultiple().
|
||||
*
|
||||
* Only TRUE may be passed in as the value.
|
||||
*
|
||||
* @covers ::setMultiple
|
||||
*
|
||||
* @expectedException \UnexpectedValueException
|
||||
*/
|
||||
public function testInvalidSetMultiple() {
|
||||
$texts = array(
|
||||
'invalidstring0' => array('html' => 1),
|
||||
);
|
||||
SafeMarkup::setMultiple($texts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests SafeMarkup::checkPlain().
|
||||
*
|
||||
|
@ -154,28 +55,49 @@ class SafeMarkupTest extends UnitTestCase {
|
|||
* The expected output from the function.
|
||||
* @param string $message
|
||||
* The message to provide as output for the test.
|
||||
* @param bool $ignorewarnings
|
||||
* Whether or not to ignore PHP 5.3+ invalid multibyte sequence warnings.
|
||||
*/
|
||||
function testCheckPlain($text, $expected, $message, $ignorewarnings = FALSE) {
|
||||
$result = $ignorewarnings ? @SafeMarkup::checkPlain($text) : SafeMarkup::checkPlain($text);
|
||||
function testCheckPlain($text, $expected, $message) {
|
||||
$result = SafeMarkup::checkPlain($text);
|
||||
$this->assertTrue($result instanceof HtmlEscapedText);
|
||||
$this->assertEquals($expected, $result, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testCheckPlain().
|
||||
* Tests Drupal\Component\Render\HtmlEscapedText.
|
||||
*
|
||||
* Verifies that the result of SafeMarkup::checkPlain() is the same as using
|
||||
* HtmlEscapedText directly.
|
||||
*
|
||||
* @dataProvider providerCheckPlain
|
||||
*
|
||||
* @param string $text
|
||||
* The text to provide to the HtmlEscapedText constructor.
|
||||
* @param string $expected
|
||||
* The expected output from the function.
|
||||
* @param string $message
|
||||
* The message to provide as output for the test.
|
||||
*/
|
||||
function testHtmlEscapedText($text, $expected, $message) {
|
||||
$result = new HtmlEscapedText($text);
|
||||
$this->assertEquals($expected, $result, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testCheckPlain() and testEscapeString().
|
||||
*
|
||||
* @see testCheckPlain()
|
||||
*/
|
||||
function providerCheckPlain() {
|
||||
// Checks that invalid multi-byte sequences are escaped.
|
||||
$tests[] = array("Foo\xC0barbaz", 'Foo<6F>barbaz', 'SafeMarkup::checkPlain() escapes invalid sequence "Foo\xC0barbaz"', TRUE);
|
||||
$tests[] = array("\xc2\"", '<27>"', 'SafeMarkup::checkPlain() escapes invalid sequence "\xc2\""', TRUE);
|
||||
$tests[] = array("Fooÿñ", "Fooÿñ", 'SafeMarkup::checkPlain() does not escape valid sequence "Fooÿñ"');
|
||||
$tests[] = array("Foo\xC0barbaz", 'Foo<6F>barbaz', 'Escapes invalid sequence "Foo\xC0barbaz"');
|
||||
$tests[] = array("\xc2\"", '<27>"', 'Escapes invalid sequence "\xc2\""');
|
||||
$tests[] = array("Fooÿñ", "Fooÿñ", 'Does not escape valid sequence "Fooÿñ"');
|
||||
|
||||
// Checks that special characters are escaped.
|
||||
$tests[] = array("<script>", '<script>', 'SafeMarkup::checkPlain() escapes <script>');
|
||||
$tests[] = array('<>&"\'', '<>&"'', 'SafeMarkup::checkPlain() escapes reserved HTML characters.');
|
||||
$tests[] = array(SafeMarkupTestMarkup::create("<script>"), '<script>', 'Escapes <script> even inside an object that implements MarkupInterface.');
|
||||
$tests[] = array("<script>", '<script>', 'Escapes <script>');
|
||||
$tests[] = array('<>&"\'', '<>&"'', 'Escapes reserved HTML characters.');
|
||||
$tests[] = array(SafeMarkupTestMarkup::create('<>&"\''), '<>&"'', 'Escapes reserved HTML characters even inside an object that implements MarkupInterface.');
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
@ -198,12 +120,14 @@ class SafeMarkupTest extends UnitTestCase {
|
|||
* Whether the result is expected to be safe for HTML display.
|
||||
*/
|
||||
public function testFormat($string, array $args, $expected, $message, $expected_is_safe) {
|
||||
UrlHelper::setAllowedProtocols(['http', 'https', 'mailto']);
|
||||
|
||||
$result = SafeMarkup::format($string, $args);
|
||||
$this->assertEquals($expected, $result, $message);
|
||||
$this->assertEquals($expected_is_safe, SafeMarkup::isSafe($result), 'SafeMarkup::format correctly sets the result as safe or not safe.');
|
||||
|
||||
foreach ($args as $arg) {
|
||||
$this->assertSame($arg instanceof SafeMarkupTestSafeString, SafeMarkup::isSafe($arg));
|
||||
$this->assertSame($arg instanceof SafeMarkupTestMarkup, SafeMarkup::isSafe($arg));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,11 +139,23 @@ class SafeMarkupTest extends UnitTestCase {
|
|||
function providerFormat() {
|
||||
$tests[] = array('Simple text', array(), 'Simple text', 'SafeMarkup::format leaves simple text alone.', TRUE);
|
||||
$tests[] = array('Escaped text: @value', array('@value' => '<script>'), 'Escaped text: <script>', 'SafeMarkup::format replaces and escapes string.', TRUE);
|
||||
$tests[] = array('Escaped text: @value', array('@value' => SafeMarkupTestSafeString::create('<span>Safe HTML</span>')), 'Escaped text: <span>Safe HTML</span>', 'SafeMarkup::format does not escape an already safe string.', TRUE);
|
||||
$tests[] = array('Escaped text: @value', array('@value' => SafeMarkupTestMarkup::create('<span>Safe HTML</span>')), 'Escaped text: <span>Safe HTML</span>', 'SafeMarkup::format does not escape an already safe string.', TRUE);
|
||||
$tests[] = array('Placeholder text: %value', array('%value' => '<script>'), 'Placeholder text: <em class="placeholder"><script></em>', 'SafeMarkup::format replaces, escapes and themes string.', TRUE);
|
||||
$tests[] = array('Placeholder text: %value', array('%value' => SafeMarkupTestSafeString::create('<span>Safe HTML</span>')), 'Placeholder text: <em class="placeholder"><span>Safe HTML</span></em>', 'SafeMarkup::format does not escape an already safe string themed as a placeholder.', TRUE);
|
||||
$tests[] = array('Verbatim text: !value', array('!value' => '<script>'), 'Verbatim text: <script>', 'SafeMarkup::format replaces verbatim string as-is.', FALSE);
|
||||
$tests[] = array('Verbatim text: !value', array('!value' => SafeMarkupTestSafeString::create('<span>Safe HTML</span>')), 'Verbatim text: <span>Safe HTML</span>', 'SafeMarkup::format replaces verbatim string as-is.', TRUE);
|
||||
$tests[] = array('Placeholder text: %value', array('%value' => SafeMarkupTestMarkup::create('<span>Safe HTML</span>')), 'Placeholder text: <em class="placeholder"><span>Safe HTML</span></em>', 'SafeMarkup::format does not escape an already safe string themed as a placeholder.', TRUE);
|
||||
|
||||
$tests['javascript-protocol-url'] = ['Simple text <a href=":url">giraffe</a>', [':url' => 'javascript://example.com?foo&bar'], 'Simple text <a href="//example.com?foo&bar">giraffe</a>', 'Support for filtering bad protocols', TRUE];
|
||||
$tests['external-url'] = ['Simple text <a href=":url">giraffe</a>', [':url' => 'http://example.com?foo&bar'], 'Simple text <a href="http://example.com?foo&bar">giraffe</a>', 'Support for filtering bad protocols', TRUE];
|
||||
$tests['relative-url'] = ['Simple text <a href=":url">giraffe</a>', [':url' => '/node/1?foo&bar'], 'Simple text <a href="/node/1?foo&bar">giraffe</a>', 'Support for filtering bad protocols', TRUE];
|
||||
$tests['fragment-with-special-chars'] = ['Simple text <a href=":url">giraffe</a>', [':url' => 'http://example.com/#<'], 'Simple text <a href="http://example.com/#&lt;">giraffe</a>', 'Support for filtering bad protocols', TRUE];
|
||||
$tests['mailto-protocol'] = ['Hey giraffe <a href=":url">MUUUH</a>', [':url' => 'mailto:test@example.com'], 'Hey giraffe <a href="mailto:test@example.com">MUUUH</a>', '', TRUE];
|
||||
$tests['js-with-fromCharCode'] = ['Hey giraffe <a href=":url">MUUUH</a>', [':url' => "javascript:alert(String.fromCharCode(88,83,83))"], 'Hey giraffe <a href="alert(String.fromCharCode(88,83,83))">MUUUH</a>', '', TRUE];
|
||||
|
||||
// Test some "URL" values that are not RFC 3986 compliant URLs. The result
|
||||
// of SafeMarkup::format() should still be valid HTML (other than the
|
||||
// value of the "href" attribute not being a valid URL), and not
|
||||
// vulnerable to XSS.
|
||||
$tests['non-url-with-colon'] = ['Hey giraffe <a href=":url">MUUUH</a>', [':url' => "llamas: they are not URLs"], 'Hey giraffe <a href=" they are not URLs">MUUUH</a>', '', TRUE];
|
||||
$tests['non-url-with-html'] = ['Hey giraffe <a href=":url">MUUUH</a>', [':url' => "<span>not a url</span>"], 'Hey giraffe <a href="<span>not a url</span>">MUUUH</a>', '', TRUE];
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
@ -241,11 +177,8 @@ class SafeMarkupTestString {
|
|||
}
|
||||
|
||||
/**
|
||||
* Marks text as safe.
|
||||
*
|
||||
* SafeMarkupTestSafeString is used to mark text as safe because
|
||||
* SafeMarkup::$safeStrings is a global static that affects all tests.
|
||||
* Marks an object's __toString() method as returning markup.
|
||||
*/
|
||||
class SafeMarkupTestSafeString implements SafeStringInterface {
|
||||
use SafeStringTrait;
|
||||
class SafeMarkupTestMarkup implements MarkupInterface {
|
||||
use MarkupTrait;
|
||||
}
|
||||
|
|
|
@ -291,6 +291,7 @@ class UnicodeTest extends UnitTestCase {
|
|||
return array(
|
||||
array('tHe QUIcK bRoWn', 15),
|
||||
array('ÜBER-åwesome', 12),
|
||||
array('以呂波耳・ほへとち。リヌルヲ。', 15),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -529,4 +530,46 @@ class UnicodeTest extends UnitTestCase {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests multibyte strpos.
|
||||
*
|
||||
* @dataProvider providerStrpos
|
||||
* @covers ::strpos
|
||||
*/
|
||||
public function testStrpos($haystack, $needle, $offset, $expected) {
|
||||
// Run through multibyte code path.
|
||||
Unicode::setStatus(Unicode::STATUS_MULTIBYTE);
|
||||
$this->assertEquals($expected, Unicode::strpos($haystack, $needle, $offset));
|
||||
// Run through singlebyte code path.
|
||||
Unicode::setStatus(Unicode::STATUS_SINGLEBYTE);
|
||||
$this->assertEquals($expected, Unicode::strpos($haystack, $needle, $offset));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testStrpos().
|
||||
*
|
||||
* @see testStrpos()
|
||||
*
|
||||
* @return array
|
||||
* An array containing:
|
||||
* - The haystack string to be searched in.
|
||||
* - The needle string to search for.
|
||||
* - The offset integer to start at.
|
||||
* - The expected integer/FALSE result.
|
||||
*/
|
||||
public function providerStrpos() {
|
||||
return array(
|
||||
array('frànçAIS is über-åwesome', 'frànçAIS is über-åwesome', 0, 0),
|
||||
array('frànçAIS is über-åwesome', 'rànçAIS is über-åwesome', 0, 1),
|
||||
array('frànçAIS is über-åwesome', 'not in string', 0, FALSE),
|
||||
array('frànçAIS is über-åwesome', 'r', 0, 1),
|
||||
array('frànçAIS is über-åwesome', 'nçAIS', 0, 3),
|
||||
array('frànçAIS is über-åwesome', 'nçAIS', 2, 3),
|
||||
array('frànçAIS is über-åwesome', 'nçAIS', 3, 3),
|
||||
array('以呂波耳・ほへとち。リヌルヲ。', '波耳', 0, 2),
|
||||
array('以呂波耳・ほへとち。リヌルヲ。', '波耳', 1, 2),
|
||||
array('以呂波耳・ほへとち。リヌルヲ。', '波耳', 2, 2),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Reference in a new issue