You are here

public function EntityReferenceIntegrationTest::testSupportedEntityTypesAndWidgets in Drupal 10

Same name and namespace in other branches
  1. 8 core/modules/field/tests/src/Functional/EntityReference/EntityReferenceIntegrationTest.php \Drupal\Tests\field\Functional\EntityReference\EntityReferenceIntegrationTest::testSupportedEntityTypesAndWidgets()
  2. 9 core/modules/field/tests/src/Functional/EntityReference/EntityReferenceIntegrationTest.php \Drupal\Tests\field\Functional\EntityReference\EntityReferenceIntegrationTest::testSupportedEntityTypesAndWidgets()

Tests the entity reference field with all its supported field widgets.

File

core/modules/field/tests/src/Functional/EntityReference/EntityReferenceIntegrationTest.php, line 73

Class

EntityReferenceIntegrationTest
Tests various Entity reference UI components.

Namespace

Drupal\Tests\field\Functional\EntityReference

Code

public function testSupportedEntityTypesAndWidgets() {
  foreach ($this
    ->getTestEntities() as $key => $referenced_entities) {
    $this->fieldName = 'field_test_' . $referenced_entities[0]
      ->getEntityTypeId();

    // Create an Entity reference field.
    $this
      ->createEntityReferenceField($this->entityType, $this->bundle, $this->fieldName, $this->fieldName, $referenced_entities[0]
      ->getEntityTypeId(), 'default', [], 2);

    /** @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface $display_repository */
    $display_repository = \Drupal::service('entity_display.repository');

    // Test the default 'entity_reference_autocomplete' widget.
    $display_repository
      ->getFormDisplay($this->entityType, $this->bundle)
      ->setComponent($this->fieldName)
      ->save();
    $entity_name = $this
      ->randomMachineName();
    $edit = [
      'name[0][value]' => $entity_name,
      $this->fieldName . '[0][target_id]' => $referenced_entities[0]
        ->label() . ' (' . $referenced_entities[0]
        ->id() . ')',
      // Test an input of the entity label without an ' (entity_id)' suffix.
      $this->fieldName . '[1][target_id]' => $referenced_entities[1]
        ->label(),
    ];
    $this
      ->drupalGet($this->entityType . '/add');
    $this
      ->submitForm($edit, 'Save');
    $this
      ->assertFieldValues($entity_name, $referenced_entities);

    // Try to post the form again with no modification and check if the field
    // values remain the same.

    /** @var \Drupal\Core\Entity\EntityStorageInterface $storage */
    $storage = $this->container
      ->get('entity_type.manager')
      ->getStorage($this->entityType);
    $entity = current($storage
      ->loadByProperties([
      'name' => $entity_name,
    ]));
    $this
      ->drupalGet($this->entityType . '/manage/' . $entity
      ->id() . '/edit');
    $this
      ->assertSession()
      ->fieldValueEquals($this->fieldName . '[0][target_id]', $referenced_entities[0]
      ->label() . ' (' . $referenced_entities[0]
      ->id() . ')');
    $this
      ->assertSession()
      ->fieldValueEquals($this->fieldName . '[1][target_id]', $referenced_entities[1]
      ->label() . ' (' . $referenced_entities[1]
      ->id() . ')');
    $this
      ->submitForm([], 'Save');
    $this
      ->assertFieldValues($entity_name, $referenced_entities);

    // Test the 'entity_reference_autocomplete_tags' widget.
    $display_repository
      ->getFormDisplay($this->entityType, $this->bundle)
      ->setComponent($this->fieldName, [
      'type' => 'entity_reference_autocomplete_tags',
    ])
      ->save();
    $entity_name = $this
      ->randomMachineName();
    $target_id = $referenced_entities[0]
      ->label() . ' (' . $referenced_entities[0]
      ->id() . ')';

    // Test an input of the entity label without an ' (entity_id)' suffix.
    $target_id .= ', ' . $referenced_entities[1]
      ->label();
    $edit = [
      'name[0][value]' => $entity_name,
      $this->fieldName . '[target_id]' => $target_id,
    ];
    $this
      ->drupalGet($this->entityType . '/add');
    $this
      ->submitForm($edit, 'Save');
    $this
      ->assertFieldValues($entity_name, $referenced_entities);

    // Try to post the form again with no modification and check if the field
    // values remain the same.
    $entity = current($storage
      ->loadByProperties([
      'name' => $entity_name,
    ]));
    $this
      ->drupalGet($this->entityType . '/manage/' . $entity
      ->id() . '/edit');
    $this
      ->assertSession()
      ->fieldValueEquals($this->fieldName . '[target_id]', $target_id . ' (' . $referenced_entities[1]
      ->id() . ')');
    $this
      ->submitForm([], 'Save');
    $this
      ->assertFieldValues($entity_name, $referenced_entities);

    // Test all the other widgets supported by the entity reference field.
    // Since we don't know the form structure for these widgets, just test
    // that editing and saving an already created entity works.
    $exclude = [
      'entity_reference_autocomplete',
      'entity_reference_autocomplete_tags',
    ];
    $entity = current($storage
      ->loadByProperties([
      'name' => $entity_name,
    ]));
    $supported_widgets = \Drupal::service('plugin.manager.field.widget')
      ->getOptions('entity_reference');
    $supported_widget_types = array_diff(array_keys($supported_widgets), $exclude);
    foreach ($supported_widget_types as $widget_type) {
      $display_repository
        ->getFormDisplay($this->entityType, $this->bundle)
        ->setComponent($this->fieldName, [
        'type' => $widget_type,
      ])
        ->save();
      $this
        ->drupalGet($this->entityType . '/manage/' . $entity
        ->id() . '/edit');
      $this
        ->submitForm([], 'Save');
      $this
        ->assertFieldValues($entity_name, $referenced_entities);
    }

    // Reset to the default 'entity_reference_autocomplete' widget.
    $display_repository
      ->getFormDisplay($this->entityType, $this->bundle)
      ->setComponent($this->fieldName)
      ->save();

    // Set first entity as the default_value.
    $field_edit = [
      'default_value_input[' . $this->fieldName . '][0][target_id]' => $referenced_entities[0]
        ->label() . ' (' . $referenced_entities[0]
        ->id() . ')',
    ];
    if ($key == 'content') {
      $field_edit['settings[handler_settings][target_bundles][' . $referenced_entities[0]
        ->getEntityTypeId() . ']'] = TRUE;
    }
    $this
      ->drupalGet($this->entityType . '/structure/' . $this->bundle . '/fields/' . $this->entityType . '.' . $this->bundle . '.' . $this->fieldName);
    $this
      ->submitForm($field_edit, 'Save settings');

    // Ensure the configuration has the expected dependency on the entity that
    // is being used a default value.
    $field = FieldConfig::loadByName($this->entityType, $this->bundle, $this->fieldName);
    $this
      ->assertContains($referenced_entities[0]
      ->getConfigDependencyName(), $field
      ->getDependencies()[$key], new FormattableMarkup('Expected @type dependency @name found', [
      '@type' => $key,
      '@name' => $referenced_entities[0]
        ->getConfigDependencyName(),
    ]));

    // Ensure that the field can be imported without change even after the
    // default value deleted.
    $referenced_entities[0]
      ->delete();

    // Reload the field since deleting the default value can change the field.
    \Drupal::entityTypeManager()
      ->getStorage($field
      ->getEntityTypeId())
      ->resetCache([
      $field
        ->id(),
    ]);
    $field = FieldConfig::loadByName($this->entityType, $this->bundle, $this->fieldName);
    $this
      ->assertConfigEntityImport($field);

    // Once the default value has been removed after saving the dependency
    // should be removed.
    $field = FieldConfig::loadByName($this->entityType, $this->bundle, $this->fieldName);
    $field
      ->save();
    $dependencies = $field
      ->getDependencies();
    $this
      ->assertFalse(isset($dependencies[$key]) && in_array($referenced_entities[0]
      ->getConfigDependencyName(), $dependencies[$key]), new FormattableMarkup('@type dependency @name does not exist.', [
      '@type' => $key,
      '@name' => $referenced_entities[0]
        ->getConfigDependencyName(),
    ]));
  }
}