FieldWidgetConstraintValidatorTest.php

Same filename and directory in other branches
  1. 9 core/tests/Drupal/KernelTests/Core/Entity/FieldWidgetConstraintValidatorTest.php
  2. 8.9.x core/tests/Drupal/KernelTests/Core/Entity/FieldWidgetConstraintValidatorTest.php
  3. 10 core/tests/Drupal/KernelTests/Core/Entity/FieldWidgetConstraintValidatorTest.php

Namespace

Drupal\KernelTests\Core\Entity

File

core/tests/Drupal/KernelTests/Core/Entity/FieldWidgetConstraintValidatorTest.php

View source
<?php

declare (strict_types=1);
namespace Drupal\KernelTests\Core\Entity;

use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormState;
use Drupal\entity_test\Entity\EntityTestCompositeConstraint;
use Drupal\KernelTests\KernelTestBase;

/**
 * Tests validation constraints for FieldWidgetConstraintValidatorTest.
 *
 * @group Entity
 */
class FieldWidgetConstraintValidatorTest extends KernelTestBase {
  
  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'entity_test',
    'field',
    'field_test',
    'user',
    'system',
  ];
  
  /**
   * {@inheritdoc}
   */
  protected function setUp() : void {
    parent::setUp();
    $this->installEntitySchema('user');
    $this->installEntitySchema('entity_test_composite_constraint');
  }
  
  /**
   * Tests widget constraint validation.
   */
  public function testValidation() : void {
    $entity_type = 'entity_test_constraint_violation';
    $entity = $this->container
      ->get('entity_type.manager')
      ->getStorage($entity_type)
      ->create([
      'id' => 1,
      'revision_id' => 1,
    ]);
    $display = \Drupal::service('entity_display.repository')->getFormDisplay($entity_type, $entity_type);
    $form = [];
    $form_state = new FormState();
    $display->buildForm($entity, $form, $form_state);
    // Pretend the form has been built.
    $form_state->setFormObject(\Drupal::entityTypeManager()->getFormObject($entity_type, 'default'));
    \Drupal::formBuilder()->prepareForm('field_test_entity_form', $form, $form_state);
    \Drupal::formBuilder()->processForm('field_test_entity_form', $form, $form_state);
    // Validate the field constraint.
    $form_state->getFormObject()
      ->setEntity($entity)
      ->setFormDisplay($display, $form_state);
    $entity = $form_state->getFormObject()
      ->buildEntity($form, $form_state);
    $display->validateFormValues($entity, $form, $form_state);
    $errors = $form_state->getErrors();
    $this->assertEquals('Widget constraint has failed.', $errors['name'], 'Constraint violation at the field items list level is generated correctly');
    $this->assertEquals('Widget constraint has failed.', $errors['test_field'], 'Constraint violation at the field items list level is generated correctly for an advanced widget');
  }
  
  /**
   * Gets the form errors for a given entity.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity.
   * @param array $hidden_fields
   *   (optional) A list of hidden fields.
   *
   * @return array
   *   The form errors.
   */
  protected function getErrorsForEntity(EntityInterface $entity, $hidden_fields = []) {
    $entity_type_id = 'entity_test_composite_constraint';
    $display = \Drupal::service('entity_display.repository')->getFormDisplay($entity_type_id, $entity_type_id);
    foreach ($hidden_fields as $hidden_field) {
      $display->removeComponent($hidden_field);
    }
    $form = [];
    $form_state = new FormState();
    $display->buildForm($entity, $form, $form_state);
    $form_state->setFormObject(\Drupal::entityTypeManager()->getFormObject($entity_type_id, 'default'));
    \Drupal::formBuilder()->prepareForm('field_test_entity_form', $form, $form_state);
    \Drupal::formBuilder()->processForm('field_test_entity_form', $form, $form_state);
    // Validate the field constraint.
    /** @var \Drupal\Core\Entity\ContentEntityFormInterface $form_object */
    $form_object = $form_state->getFormObject();
    $form_object->setEntity($entity)
      ->setFormDisplay($display, $form_state)
      ->validateForm($form, $form_state);
    return $form_state->getErrors();
  }
  
  /**
   * Tests widget constraint validation with composite constraints.
   */
  public function testValidationWithCompositeConstraint() : void {
    // First provide a valid value, this should cause no validation.
    $entity = EntityTestCompositeConstraint::create([
      'name' => 'valid-value',
    ]);
    $entity->save();
    $errors = $this->getErrorsForEntity($entity);
    $this->assertFalse(isset($errors['name']));
    $this->assertFalse(isset($errors['type']));
    // Provide an invalid value for the name field.
    $entity = EntityTestCompositeConstraint::create([
      'name' => 'failure-field-name',
    ]);
    $errors = $this->getErrorsForEntity($entity);
    $this->assertTrue(isset($errors['name']));
    $this->assertFalse(isset($errors['type']));
    // Hide the second field (type) and ensure the validation still happens. The
    // error message appears on the first field (name).
    $entity = EntityTestCompositeConstraint::create([
      'name' => 'failure-field-name',
    ]);
    $errors = $this->getErrorsForEntity($entity, [
      'type',
    ]);
    $this->assertTrue(isset($errors['name']));
    $this->assertFalse(isset($errors['type']));
    // Provide a violation again, but this time hide the first field (name).
    // Ensure that the validation still happens and the error message is moved
    // from the field to the second field and have a custom error message.
    $entity = EntityTestCompositeConstraint::create([
      'name' => 'failure-field-name',
    ]);
    $errors = $this->getErrorsForEntity($entity, [
      'name',
    ]);
    $this->assertFalse(isset($errors['name']));
    $this->assertTrue(isset($errors['type']));
    $this->assertEquals('The validation failed because the value conflicts with the value in name, which you cannot access.', $errors['type']);
  }
  
  /**
   * Tests entity level constraint validation.
   */
  public function testEntityLevelConstraintValidation() : void {
    $entity = EntityTestCompositeConstraint::create([
      'name' => 'entity-level-violation',
    ]);
    $entity->save();
    $errors = $this->getErrorsForEntity($entity);
    $this->assertEquals('Entity level validation', $errors['']);
    $entity->name->value = 'entity-level-violation-with-path';
    $errors = $this->getErrorsForEntity($entity);
    $this->assertEquals('Entity level validation', $errors['test][form][element']);
  }

}

Classes

Title Deprecated Summary
FieldWidgetConstraintValidatorTest Tests validation constraints for FieldWidgetConstraintValidatorTest.

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