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