NodeDisplayConfigurableTest.php

Same filename in other branches
  1. 9 core/modules/rdf/tests/src/Functional/Node/NodeDisplayConfigurableTest.php
  2. 8.9.x core/modules/node/tests/src/Functional/NodeDisplayConfigurableTest.php

Namespace

Drupal\Tests\node\Functional

File

core/modules/node/tests/src/Functional/NodeDisplayConfigurableTest.php

View source
<?php

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

use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\node\NodeInterface;
use Drupal\user\UserInterface;

/**
 * Tests making node base fields' displays configurable.
 *
 * @group node
 */
class NodeDisplayConfigurableTest extends NodeTestBase {
    
    /**
     * {@inheritdoc}
     */
    protected static $modules = [
        'block',
    ];
    
    /**
     * {@inheritdoc}
     */
    protected $defaultTheme = 'stark';
    
    /**
     * Sets base fields to configurable display and check settings are respected.
     *
     * @param string $theme
     *   The name of the theme being tested.
     * @param string $metadata_region
     *   The region of the node html content where meta data is expected.
     * @param bool $field_classes
     *   If TRUE, check for field--name-XXX classes.
     *
     * @dataProvider provideThemes
     */
    public function testDisplayConfigurable(string $theme, string $metadata_region, bool $field_classes) : void {
        \Drupal::service('theme_installer')->install([
            $theme,
        ]);
        $this->config('system.theme')
            ->set('default', $theme)
            ->save();
        $settings = [
            'theme' => $theme,
            'region' => 'content',
            'weight' => -100,
        ];
        $this->drupalPlaceBlock('page_title_block', $settings);
        // Change the node type setting to show submitted by information.
        $node_type = \Drupal::entityTypeManager()->getStorage('node_type')
            ->load('page');
        $node_type->setDisplaySubmitted(TRUE);
        $node_type->save();
        $user = $this->drupalCreateUser([
            'administer nodes',
        ], $this->randomMachineName(14));
        $this->drupalLogin($user);
        $node = $this->drupalCreateNode([
            'uid' => $user->id(),
        ]);
        $assert = $this->assertSession();
        // Check the node with Drupal default non-configurable display.
        $this->drupalGet($node->toUrl());
        $this->assertNodeHtml($node, $user, TRUE, $metadata_region, $field_classes, $field_classes);
        // Enable module to make base fields' displays configurable.
        \Drupal::service('module_installer')->install([
            'node_display_configurable_test',
        ]);
        // Configure display.
        $display = EntityViewDisplay::load('node.page.default');
        $display->setComponent('uid', [
            'type' => 'entity_reference_label',
            'label' => 'above',
            'settings' => [
                'link' => FALSE,
            ],
        ])
            ->removeComponent('title')
            ->save();
        // Recheck the node with configurable display.
        $this->drupalGet($node->toUrl());
        $this->assertNodeHtml($node, $user, FALSE, $metadata_region, $field_classes, FALSE);
        // Remove from display.
        $display->removeComponent('uid')
            ->removeComponent('created')
            ->save();
        $this->drupalGet($node->toUrl());
        $assert->elementTextNotContains('css', 'article', $user->getAccountName());
    }
    
    /**
     * Asserts that the node HTML is as expected.
     *
     * @param \Drupal\node\NodeInterface $node
     *   The node being tested.
     * @param \Drupal\user\UserInterface $user
     *   The logged in user.
     * @param bool $is_inline
     *   Whether the fields are rendered inline or not.
     * @param string $metadata_region
     *   The region of the node html content where meta data is expected.
     * @param bool $field_classes
     *   If TRUE, check for field--name-XXX classes on created/uid fields.
     * @param bool $title_classes
     *   If TRUE, check for field--name-XXX classes on title field.
     *
     * @internal
     */
    protected function assertNodeHtml(NodeInterface $node, UserInterface $user, bool $is_inline, string $metadata_region, bool $field_classes, bool $title_classes) : void {
        $assert = $this->assertSession();
        $html_element = $is_inline ? 'span' : 'div';
        $title_selector = 'h1 span' . ($title_classes ? '.field--name-title' : '');
        $assert->elementTextContains('css', $title_selector, $node->getTitle());
        // With field classes, the selector can be very specific.
        if ($field_classes) {
            $created_selector = 'article ' . $html_element . '.field--name-created';
            $assert->elementTextContains('css', $created_selector, \Drupal::service('date.formatter')->format($node->getCreatedTime()));
        }
        else {
            // When field classes aren't available, use HTML elements for testing.
            $formatted_time = \Drupal::service('date.formatter')->format($node->getCreatedTime());
            if ($is_inline) {
                $created_selector = sprintf('//article//%s//%s/time[text()="%s"]', $metadata_region, $html_element, $formatted_time);
            }
            else {
                $created_selector = sprintf('//article//%s//%s/time[text()="%s"]', $html_element, $html_element, $formatted_time);
            }
            $assert->elementExists('xpath', $created_selector);
        }
        $uid_selector = 'article ' . $html_element . ($field_classes ? '.field--name-uid' : '');
        if (!$is_inline) {
            $field_classes_selector = $field_classes ? "[contains(concat(' ', normalize-space(@class), ' '), ' field--name-uid ')]" : '';
            $assert->elementExists('xpath', sprintf('//article//%s//*%s//%s[text()="Authored by"]', $html_element, $field_classes_selector, $html_element));
            $assert->elementTextContains('css', $uid_selector, $user->getAccountName());
            $assert->elementNotExists('css', "{$uid_selector} a");
            if ($field_classes) {
                $assert->elementExists('css', $created_selector);
            }
        }
        else {
            $assert->elementTextContains('css', $uid_selector . ' a', $user->getAccountName());
            $assert->elementTextContains('css', 'article ' . $metadata_region, 'Submitted by');
        }
    }
    
    /**
     * Data provider for ::testDisplayConfigurable().
     *
     * @return array
     */
    public static function provideThemes() {
        return [
            [
                'claro',
                'footer',
                TRUE,
            ],
            // @todo Add coverage for olivero after fixing
            // https://www.drupal.org/project/drupal/issues/3215220.
            // ['olivero', 'footer', TRUE],
[
                'stable9',
                'footer',
                FALSE,
            ],
        ];
    }

}

Classes

Title Deprecated Summary
NodeDisplayConfigurableTest Tests making node base fields' displays configurable.

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