EntityFilteringThemeTest.php

Same filename in other branches
  1. 9 core/modules/system/tests/src/Functional/Theme/EntityFilteringThemeTest.php
  2. 8.9.x core/modules/system/tests/src/Functional/Theme/EntityFilteringThemeTest.php
  3. 10 core/modules/system/tests/src/Functional/Theme/EntityFilteringThemeTest.php

Namespace

Drupal\Tests\system\Functional\Theme

File

core/modules/system/tests/src/Functional/Theme/EntityFilteringThemeTest.php

View source
<?php

declare (strict_types=1);
namespace Drupal\Tests\system\Functional\Theme;

use Drupal\comment\Tests\CommentTestTrait;
use Drupal\Core\Extension\ExtensionDiscovery;
use Drupal\comment\CommentInterface;
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
use Drupal\Core\Extension\ExtensionLifecycle;
use Drupal\node\NodeInterface;
use Drupal\comment\Entity\Comment;
use Drupal\taxonomy\Entity\Term;
use Drupal\Tests\BrowserTestBase;

/**
 * Tests XSS filtering for themed output for each entity type in all themes.
 *
 * @group Theme
 */
class EntityFilteringThemeTest extends BrowserTestBase {
    use CommentTestTrait;
    
    /**
     * {@inheritdoc}
     */
    protected static $modules = [
        'block',
        'taxonomy',
        'comment',
        'node',
        'views',
    ];
    
    /**
     * {@inheritdoc}
     */
    protected $defaultTheme = 'stark';
    
    /**
     * A list of all available themes.
     *
     * @var \Drupal\Core\Extension\Extension[]
     */
    protected $themes;
    
    /**
     * A test user.
     *
     * @var \Drupal\user\Entity\User
     */
    protected $user;
    
    /**
     * A test node.
     *
     * @var \Drupal\node\Entity\Node
     */
    protected $node;
    
    /**
     * A test taxonomy term.
     *
     * @var \Drupal\taxonomy\Entity\Term
     */
    protected $term;
    
    /**
     * A test comment.
     *
     * @var \Drupal\comment\Entity\Comment
     */
    protected $comment;
    
    /**
     * A string containing markup and JS.
     *
     * @var string
     */
    protected $xssLabel = "string with <em>HTML</em> and <script>alert('JS');</script>";
    
    /**
     * {@inheritdoc}
     */
    protected function setUp() : void {
        parent::setUp();
        // Install all available non-testing themes.
        $listing = new ExtensionDiscovery(\Drupal::root());
        $this->themes = $listing->scan('theme', FALSE);
        
        /** @var \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler */
        $theme_data = \Drupal::service('extension.list.theme')->reset()
            ->getList();
        foreach (array_keys($this->themes) as $theme) {
            // Skip obsolete and deprecated themes.
            $info = $theme_data[$theme]->info;
            if ($info[ExtensionLifecycle::LIFECYCLE_IDENTIFIER] === ExtensionLifecycle::OBSOLETE || $info[ExtensionLifecycle::LIFECYCLE_IDENTIFIER] === ExtensionLifecycle::DEPRECATED) {
                unset($this->themes[$theme]);
            }
        }
        \Drupal::service('theme_installer')->install(array_keys($this->themes));
        // Create a test user.
        $this->user = $this->drupalCreateUser([
            'access content',
            'access user profiles',
        ]);
        $this->user->name = $this->xssLabel;
        $this->user
            ->save();
        $this->drupalLogin($this->user);
        // Create a test term.
        $this->term = Term::create([
            'name' => $this->xssLabel,
            'vid' => 1,
        ]);
        $this->term
            ->save();
        $this->createContentType([
            'type' => 'article',
        ]);
        // Add a comment field.
        $this->addDefaultCommentField('node', 'article', 'comment', CommentItemInterface::OPEN);
        // Create a test node tagged with the test term.
        $this->node = $this->drupalCreateNode([
            'title' => $this->xssLabel,
            'type' => 'article',
            'promote' => NodeInterface::PROMOTED,
            'field_tags' => [
                [
                    'target_id' => $this->term
                        ->id(),
                ],
            ],
        ]);
        // Create a test comment on the test node.
        $this->comment = Comment::create([
            'entity_id' => $this->node
                ->id(),
            'entity_type' => 'node',
            'field_name' => 'comment',
            'status' => CommentInterface::PUBLISHED,
            'subject' => $this->xssLabel,
            'comment_body' => [
                $this->randomMachineName(),
            ],
        ]);
        $this->comment
            ->save();
    }
    
    /**
     * Checks each themed entity for XSS filtering in available themes.
     */
    public function testThemedEntity() : void {
        // Check paths where various view modes of the entities are rendered.
        $paths = [
            'user',
            'node',
            'node/' . $this->node
                ->id(),
            'taxonomy/term/' . $this->term
                ->id(),
        ];
        // Check each path in all available themes.
        foreach ($this->themes as $name => $theme) {
            $this->config('system.theme')
                ->set('default', $name)
                ->save();
            foreach ($paths as $path) {
                $this->drupalGet($path);
                $this->assertSession()
                    ->statusCodeEquals(200);
                $this->assertSession()
                    ->responseNotContains($this->xssLabel);
            }
        }
    }

}

Classes

Title Deprecated Summary
EntityFilteringThemeTest Tests XSS filtering for themed output for each entity type in all themes.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.