From a4f5580c8600a7cc774585d17f8cf36c118d7f8d Mon Sep 17 00:00:00 2001 From: Dave Long <dave@longwaveconsulting.com> Date: Thu, 22 Aug 2024 18:16:38 +0100 Subject: [PATCH] Issue #3342700 by quietone, pooja_sharma, AdamPS, jonathanshaw: Reinstate important testing NodeDisplayConfigurableTest (cherry picked from commit 41122f85dd52a3357842f7a6de3827295cda0371) --- .../node_display_configurable_test.info.yml | 5 + .../node_display_configurable_test.module | 29 +++ .../NodeDisplayConfigurableTest.php | 167 ++++++++++++++++++ 3 files changed, 201 insertions(+) create mode 100644 core/modules/node/tests/modules/node_display_configurable_test/node_display_configurable_test.info.yml create mode 100644 core/modules/node/tests/modules/node_display_configurable_test/node_display_configurable_test.module create mode 100644 core/modules/node/tests/src/Functional/NodeDisplayConfigurableTest.php diff --git a/core/modules/node/tests/modules/node_display_configurable_test/node_display_configurable_test.info.yml b/core/modules/node/tests/modules/node_display_configurable_test/node_display_configurable_test.info.yml new file mode 100644 index 000000000000..3ad5d21581fd --- /dev/null +++ b/core/modules/node/tests/modules/node_display_configurable_test/node_display_configurable_test.info.yml @@ -0,0 +1,5 @@ +name: 'Node configurable display module tests' +type: module +description: 'Support module for node \Drupal\Core\Field\BaseFieldDefinition::setDisplayConfigurable() testing.' +package: Testing +version: VERSION diff --git a/core/modules/node/tests/modules/node_display_configurable_test/node_display_configurable_test.module b/core/modules/node/tests/modules/node_display_configurable_test/node_display_configurable_test.module new file mode 100644 index 000000000000..df645c8b8c3a --- /dev/null +++ b/core/modules/node/tests/modules/node_display_configurable_test/node_display_configurable_test.module @@ -0,0 +1,29 @@ +<?php + +/** + * @file + * A module for testing making node base fields' displays configurable. + */ + +use Drupal\Core\Entity\EntityTypeInterface; + +/** + * Implements hook_entity_base_field_info_alter(). + */ +function node_display_configurable_test_entity_base_field_info_alter(&$base_field_definitions, EntityTypeInterface $entity_type) { + if ($entity_type->id() == 'node') { + foreach (['created', 'uid', 'title'] as $field) { + /** @var \Drupal\Core\Field\BaseFieldDefinition[] $base_field_definitions */ + $base_field_definitions[$field]->setDisplayConfigurable('view', TRUE); + } + } +} + +/** + * Implements hook_entity_type_build(). + */ +function node_display_configurable_test_entity_type_build(array &$entity_types) { + // Allow skipping of extra preprocessing for configurable display. + $entity_types['node']->set('enable_base_field_custom_preprocess_skipping', TRUE); + $entity_types['node']->set('enable_page_title_template', TRUE); +} diff --git a/core/modules/node/tests/src/Functional/NodeDisplayConfigurableTest.php b/core/modules/node/tests/src/Functional/NodeDisplayConfigurableTest.php new file mode 100644 index 000000000000..1d2602c18aac --- /dev/null +++ b/core/modules/node/tests/src/Functional/NodeDisplayConfigurableTest.php @@ -0,0 +1,167 @@ +<?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], + ]; + } + +} -- GitLab