3 namespace Drupal\system\Tests\System;
5 use Drupal\Component\Utility\Html;
6 use Drupal\Component\Utility\Xss;
7 use Drupal\simpletest\WebTestBase;
10 * Tests HTML output escaping of page title, site name, and slogan.
14 class PageTitleTest extends WebTestBase {
21 public static $modules = ['node', 'test_page_test', 'form_test', 'block'];
23 protected $contentUser;
24 protected $savedTitle;
29 protected function setUp() {
32 $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']);
34 $this->drupalPlaceBlock('page_title_block');
36 $this->contentUser = $this->drupalCreateUser(['create page content', 'access content', 'administer themes', 'administer site configuration', 'link to any page']);
37 $this->drupalLogin($this->contentUser);
41 * Tests the handling of HTML in node titles.
43 public function testTitleTags() {
44 $title = "string with <em>HTML</em>";
45 // Generate node content.
47 'title[0][value]' => '!SimpleTest! ' . $title . $this->randomMachineName(20),
48 'body[0][value]' => '!SimpleTest! test body' . $this->randomMachineName(200),
50 // Create the node with HTML in the title.
51 $this->drupalPostForm('node/add/page', $edit, t('Save'));
53 $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
54 $this->assertNotNull($node, 'Node created and found in database');
55 $this->assertText(Html::escape($edit['title[0][value]']), 'Check to make sure tags in the node title are converted.');
56 $this->drupalGet("node/" . $node->id());
57 $this->assertText(Html::escape($edit['title[0][value]']), 'Check to make sure tags in the node title are converted.');
61 * Test if the title of the site is XSS proof.
63 public function testTitleXSS() {
64 // Set some title with JavaScript and HTML chars to escape.
65 $title = '</title><script type="text/javascript">alert("Title XSS!");</script> & < > " \' ';
66 $title_filtered = Html::escape($title);
68 $slogan = '<script type="text/javascript">alert("Slogan XSS!");</script>';
69 $slogan_filtered = Xss::filterAdmin($slogan);
71 // Set title and slogan.
73 'site_name' => $title,
74 'site_slogan' => $slogan,
76 $this->drupalPostForm('admin/config/system/site-information', $edit, t('Save configuration'));
78 // Place branding block with site name and slogan into header region.
79 $this->drupalPlaceBlock('system_branding_block', ['region' => 'header']);
85 $this->assertNoRaw($title, 'Check for the lack of the unfiltered version of the title.');
86 // Add </title> to make sure we're checking the title tag, rather than the
87 // first 'heading' on the page.
88 $this->assertRaw($title_filtered . '</title>', 'Check for the filtered version of the title in a <title> tag.');
91 $this->assertNoRaw($slogan, 'Check for the unfiltered version of the slogan.');
92 $this->assertRaw($slogan_filtered, 'Check for the filtered version of the slogan.');
96 * Tests the page title of render arrays.
98 * @see \Drupal\test_page_test\Controller\Test
100 public function testRoutingTitle() {
101 // Test the '#title' render array attribute.
102 $this->drupalGet('test-render-title');
104 $this->assertTitle('Foo | Drupal');
105 $result = $this->xpath('//h1[@class="page-title"]');
106 $this->assertEqual('Foo', (string) $result[0]);
109 $this->drupalGet('form-test/object-builder');
111 $this->assertTitle('Test dynamic title | Drupal');
112 $result = $this->xpath('//h1[@class="page-title"]');
113 $this->assertEqual('Test dynamic title', (string) $result[0]);
115 // Set some custom translated strings.
116 $this->addCustomTranslations('en', [
117 '' => ['Static title' => 'Static title translated'],
119 $this->writeCustomTranslations();
121 // Ensure that the title got translated.
122 $this->drupalGet('test-page-static-title');
124 $this->assertTitle('Static title translated | Drupal');
125 $result = $this->xpath('//h1[@class="page-title"]');
126 $this->assertEqual('Static title translated', (string) $result[0]);
128 // Test the dynamic '_title_callback' route option.
129 $this->drupalGet('test-page-dynamic-title');
131 $this->assertTitle('Dynamic title | Drupal');
132 $result = $this->xpath('//h1[@class="page-title"]');
133 $this->assertEqual('Dynamic title', (string) $result[0]);
135 // Ensure that titles are cacheable and are escaped normally if the
136 // controller does not escape them.
137 $this->drupalGet('test-page-cached-controller');
138 $this->assertTitle('Cached title | Drupal');
139 $this->assertRaw(Html::escape('<span>Cached title</span>') . '</h1>');
140 $this->drupalGet('test-page-cached-controller');
141 $this->assertTitle('Cached title | Drupal');
142 $this->assertRaw(Html::escape('<span>Cached title</span>') . '</h1>');