Commit d70e577a authored by alexpott's avatar alexpott

Issue #2773733 by claudiu.cristea, klausi, dawehner: Fix...

Issue #2773733 by claudiu.cristea, klausi, dawehner: Fix AssertLegacyTrait::assert(No)Text to handle html encoded strings (part 3)
parent ffde2454
...@@ -88,4 +88,14 @@ public function error() { ...@@ -88,4 +88,14 @@ public function error() {
]; ];
} }
/**
* Renders a page with encoded markup.
*
* @return array
* A render array as expected by drupal_render()
*/
public function renderEncodedMarkup() {
return ['#plain_text' => 'Bad html <script>alert(123);</script>'];
}
} }
...@@ -58,3 +58,11 @@ test_page_test.error: ...@@ -58,3 +58,11 @@ test_page_test.error:
code: 200 code: 200
requirements: requirements:
_access: 'TRUE' _access: 'TRUE'
test_page_test.encoded:
path: '/test-encoded'
defaults:
_title: 'Page with encoded HTML'
_controller: '\Drupal\test_page_test\Controller\Test::renderEncodedMarkup'
requirements:
_access: 'TRUE'
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
namespace Drupal\FunctionalTests; namespace Drupal\FunctionalTests;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Component\Utility\Xss;
use Drupal\KernelTests\AssertLegacyTrait as BaseAssertLegacyTrait; use Drupal\KernelTests\AssertLegacyTrait as BaseAssertLegacyTrait;
/** /**
...@@ -53,10 +55,17 @@ protected function assertElementNotPresent($css_selector) { ...@@ -53,10 +55,17 @@ protected function assertElementNotPresent($css_selector) {
* Plain text to look for. * Plain text to look for.
* *
* @deprecated Scheduled for removal in Drupal 9.0.0. * @deprecated Scheduled for removal in Drupal 9.0.0.
* Use $this->assertSession()->pageTextContains() or * Use instead:
* $this->assertSession()->responseContains() instead. * - $this->assertSession()->responseContains() for non-HTML responses,
* like XML or Json.
* - $this->assertSession()->pageTextContains() for HTML responses. Unlike
* the deprecated assertText(), the passed text should be HTML decoded,
* exactly as a human sees it in the browser.
*/ */
protected function assertText($text) { protected function assertText($text) {
// Cast MarkupInterface to string.
$text = (string) $text;
$content_type = $this->getSession()->getResponseHeader('Content-type'); $content_type = $this->getSession()->getResponseHeader('Content-type');
// In case of a Non-HTML response (example: XML) check the original // In case of a Non-HTML response (example: XML) check the original
// response. // response.
...@@ -64,7 +73,7 @@ protected function assertText($text) { ...@@ -64,7 +73,7 @@ protected function assertText($text) {
$this->assertSession()->responseContains($text); $this->assertSession()->responseContains($text);
} }
else { else {
$this->assertSession()->pageTextContains($text); $this->assertTextHelper($text, FALSE);
} }
} }
...@@ -78,10 +87,17 @@ protected function assertText($text) { ...@@ -78,10 +87,17 @@ protected function assertText($text) {
* Plain text to look for. * Plain text to look for.
* *
* @deprecated Scheduled for removal in Drupal 9.0.0. * @deprecated Scheduled for removal in Drupal 9.0.0.
* Use $this->assertSession()->pageTextNotContains() or * Use instead:
* $this->assertSession()->responseNotContains() instead. * - $this->assertSession()->responseNotContains() for non-HTML responses,
* like XML or Json.
* - $this->assertSession()->pageTextNotContains() for HTML responses.
* Unlike the deprecated assertNoText(), the passed text should be HTML
* decoded, exactly as a human sees it in the browser.
*/ */
protected function assertNoText($text) { protected function assertNoText($text) {
// Cast MarkupInterface to string.
$text = (string) $text;
$content_type = $this->getSession()->getResponseHeader('Content-type'); $content_type = $this->getSession()->getResponseHeader('Content-type');
// In case of a Non-HTML response (example: XML) check the original // In case of a Non-HTML response (example: XML) check the original
// response. // response.
...@@ -89,10 +105,40 @@ protected function assertNoText($text) { ...@@ -89,10 +105,40 @@ protected function assertNoText($text) {
$this->assertSession()->responseNotContains($text); $this->assertSession()->responseNotContains($text);
} }
else { else {
$this->assertSession()->pageTextNotContains($text); $this->assertTextHelper($text);
} }
} }
/**
* Helper for assertText and assertNoText.
*
* @param string $text
* Plain text to look for.
* @param bool $not_exists
* (optional) TRUE if this text should not exist, FALSE if it should.
* Defaults to TRUE.
*
* @return bool
* TRUE on pass, FALSE on fail.
*/
protected function assertTextHelper($text, $not_exists = TRUE) {
$args = ['@text' => $text];
$message = $not_exists ? new FormattableMarkup('"@text" not found', $args) : new FormattableMarkup('"@text" found', $args);
$raw_content = $this->getSession()->getPage()->getContent();
// Trying to simulate what the user sees, given that it removes all text
// inside the head tags, removes inline Javascript, fix all HTML entities,
// removes dangerous protocols and filtering out all HTML tags, as they are
// not visible in a normal browser.
$raw_content = preg_replace('@<head>(.+?)</head>@si', '', $raw_content);
$page_text = Xss::filter($raw_content, []);
$actual = $not_exists == (strpos($page_text, (string) $text) === FALSE);
$this->assertTrue($actual, $message);
return $actual;
}
/** /**
* Passes if the text is found ONLY ONCE on the text version of the page. * Passes if the text is found ONLY ONCE on the text version of the page.
* *
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
namespace Drupal\FunctionalTests; namespace Drupal\FunctionalTests;
use Drupal\Component\Utility\Html;
use Drupal\Core\Url; use Drupal\Core\Url;
use Drupal\Tests\BrowserTestBase; use Drupal\Tests\BrowserTestBase;
...@@ -111,4 +112,15 @@ public function testError() { ...@@ -111,4 +112,15 @@ public function testError() {
$this->drupalGet('test-error'); $this->drupalGet('test-error');
} }
/**
* Tests legacy asserts.
*/
public function testLegacyAsserts() {
$this->drupalGet('test-encoded');
$dangerous = 'Bad html <script>alert(123);</script>';
$sanitized = Html::escape($dangerous);
$this->assertNoText($dangerous);
$this->assertText($sanitized);
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment