class SafeMarkupTest in Zircon Profile 8
Same name and namespace in other branches
- 8.0 core/tests/Drupal/Tests/Component/Utility/SafeMarkupTest.php \Drupal\Tests\Component\Utility\SafeMarkupTest
Tests marking strings as safe.
@group Utility @coversDefaultClass \Drupal\Component\Utility\SafeMarkup
Hierarchy
- class \Drupal\Tests\UnitTestCase extends \Drupal\Tests\PHPUnit_Framework_TestCase
- class \Drupal\Tests\Component\Utility\SafeMarkupTest
Expanded class hierarchy of SafeMarkupTest
File
- core/
tests/ Drupal/ Tests/ Component/ Utility/ SafeMarkupTest.php, line 23 - Contains \Drupal\Tests\Component\Utility\SafeMarkupTest.
Namespace
Drupal\Tests\Component\UtilityView source
class SafeMarkupTest extends UnitTestCase {
/**
* The error message of the last error in the error handler.
*
* @var string
*/
protected $lastErrorMessage;
/**
* The error number of the last error in the error handler.
*
* @var int
*/
protected $lastErrorNumber;
/**
* {@inheritdoc}
*/
protected function tearDown() {
parent::tearDown();
UrlHelper::setAllowedProtocols([
'http',
'https',
]);
}
/**
* Tests SafeMarkup::isSafe() with different objects.
*
* @covers ::isSafe
*/
public function testIsSafe() {
$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::checkPlain().
*
* @dataProvider providerCheckPlain
* @covers ::checkPlain
*
* @param string $text
* The text to provide to SafeMarkup::checkPlain().
* @param string $expected
* The expected output from the function.
* @param string $message
* The message to provide as output for the test.
*/
function testCheckPlain($text, $expected, $message) {
$result = SafeMarkup::checkPlain($text);
$this
->assertTrue($result instanceof HtmlEscapedText);
$this
->assertEquals($expected, $result, $message);
}
/**
* 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�barbaz',
'Escapes invalid sequence "Foo\\xC0barbaz"',
);
$tests[] = array(
"",
'�"',
'Escapes invalid sequence "\\xc2\\""',
);
$tests[] = array(
"Fooÿñ",
"Fooÿñ",
'Does not escape valid sequence "Fooÿñ"',
);
// Checks that special characters are escaped.
$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;
}
/**
* Tests string formatting with SafeMarkup::format().
*
* @dataProvider providerFormat
* @covers ::format
*
* @param string $string
* The string to run through SafeMarkup::format().
* @param string[] $args
* The arguments to pass into SafeMarkup::format().
* @param string $expected
* The expected result from calling the function.
* @param string $message
* The message to display as output to the test.
* @param bool $expected_is_safe
* 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 SafeMarkupTestMarkup, SafeMarkup::isSafe($arg));
}
}
/**
* Data provider for testFormat().
*
* @see testFormat()
*/
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' => 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' => 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;
}
/**
* Custom error handler that saves the last error.
*
* We need this custom error handler because we cannot rely on the error to
* exception conversion as __toString is never allowed to leak any kind of
* exception.
*
* @param int $error_number
* The error number.
* @param string $error_message
* The error message.
*/
public function errorHandler($error_number, $error_message) {
$this->lastErrorNumber = $error_number;
$this->lastErrorMessage = $error_message;
}
/**
* String formatting with SafeMarkup::format() and an unsupported placeholder.
*
* When you call SafeMarkup::format() with an unsupported placeholder, an
* InvalidArgumentException should be thrown.
*/
public function testUnexpectedFormat() {
// We set a custom error handler because of https://github.com/sebastianbergmann/phpunit/issues/487
set_error_handler([
$this,
'errorHandler',
]);
// We want this to trigger an error.
$error = SafeMarkup::format('Broken placeholder: ~placeholder', [
'~placeholder' => 'broken',
])
->__toString();
restore_error_handler();
$this
->assertEquals(E_USER_ERROR, $this->lastErrorNumber);
$this
->assertEquals('Invalid placeholder: ~placeholder', $this->lastErrorMessage);
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
SafeMarkupTest:: |
protected | property | The error message of the last error in the error handler. | |
SafeMarkupTest:: |
protected | property | The error number of the last error in the error handler. | |
SafeMarkupTest:: |
public | function | Custom error handler that saves the last error. | |
SafeMarkupTest:: |
function | Data provider for testCheckPlain() and testEscapeString(). | ||
SafeMarkupTest:: |
function | Data provider for testFormat(). | ||
SafeMarkupTest:: |
protected | function | ||
SafeMarkupTest:: |
function | Tests SafeMarkup::checkPlain(). | ||
SafeMarkupTest:: |
public | function | Tests string formatting with SafeMarkup::format(). | |
SafeMarkupTest:: |
function | Tests Drupal\Component\Render\HtmlEscapedText. | ||
SafeMarkupTest:: |
public | function | Tests SafeMarkup::isSafe() with different objects. | |
SafeMarkupTest:: |
public | function | String formatting with SafeMarkup::format() and an unsupported placeholder. | |
UnitTestCase:: |
protected | property | The random generator. | |
UnitTestCase:: |
protected | property | The app root. | |
UnitTestCase:: |
protected | function | Asserts if two arrays are equal by sorting them first. | |
UnitTestCase:: |
protected | function | Mocks a block with a block plugin. | |
UnitTestCase:: |
protected | function | Returns a stub class resolver. | |
UnitTestCase:: |
public | function | Returns a stub config factory that behaves according to the passed in array. | |
UnitTestCase:: |
public | function | Returns a stub config storage that returns the supplied configuration. | |
UnitTestCase:: |
protected | function | Sets up a container with a cache tags invalidator. | |
UnitTestCase:: |
protected | function | Gets the random generator for the utility methods. | |
UnitTestCase:: |
public | function | Returns a stub translation manager that just returns the passed string. | |
UnitTestCase:: |
public | function | Generates a unique random string containing letters and numbers. | |
UnitTestCase:: |
protected | function | 259 |