function ValidReferenceConstraintValidatorTest::testPreExistingItemsValidation

Same name in other branches
  1. 8.9.x core/tests/Drupal/KernelTests/Core/Entity/ValidReferenceConstraintValidatorTest.php \Drupal\KernelTests\Core\Entity\ValidReferenceConstraintValidatorTest::testPreExistingItemsValidation()
  2. 10 core/tests/Drupal/KernelTests/Core/Entity/ValidReferenceConstraintValidatorTest.php \Drupal\KernelTests\Core\Entity\ValidReferenceConstraintValidatorTest::testPreExistingItemsValidation()
  3. 11.x core/tests/Drupal/KernelTests/Core/Entity/ValidReferenceConstraintValidatorTest.php \Drupal\KernelTests\Core\Entity\ValidReferenceConstraintValidatorTest::testPreExistingItemsValidation()

Tests the validation of pre-existing items in an entity reference field.

File

core/tests/Drupal/KernelTests/Core/Entity/ValidReferenceConstraintValidatorTest.php, line 86

Class

ValidReferenceConstraintValidatorTest
Tests validation constraints for ValidReferenceConstraintValidator.

Namespace

Drupal\KernelTests\Core\Entity

Code

public function testPreExistingItemsValidation() {
    // Create two types of users, with and without access to bypass content
    // access.
    
    /** @var \Drupal\user\RoleInterface $role_with_access */
    $role_with_access = Role::create([
        'id' => 'role_with_access',
        'label' => 'With access',
    ]);
    $role_with_access->grantPermission('access content');
    $role_with_access->grantPermission('bypass node access');
    $role_with_access->save();
    
    /** @var \Drupal\user\RoleInterface $role_without_access */
    $role_without_access = Role::create([
        'id' => 'role_without_access',
        'label' => 'Without access',
    ]);
    $role_without_access->grantPermission('access content');
    $role_without_access->save();
    $user_with_access = User::create([
        'roles' => [
            'role_with_access',
        ],
    ]);
    $user_without_access = User::create([
        'roles' => [
            'role_without_access',
        ],
    ]);
    // Add an entity reference field.
    $this->createEntityReferenceField('entity_test', 'entity_test', 'field_test', 'Field test', 'node', 'default', [
        'target_bundles' => [
            'article',
            'page',
        ],
    ], FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
    // Create four test nodes.
    $published_node = Node::create([
        'title' => 'Test published node',
        'type' => 'article',
        'status' => NodeInterface::PUBLISHED,
    ]);
    $published_node->save();
    $unpublished_node = Node::create([
        'title' => 'Test unpublished node',
        'type' => 'article',
        'status' => NodeInterface::NOT_PUBLISHED,
    ]);
    $unpublished_node->save();
    $different_bundle_node = Node::create([
        'title' => 'Test page node',
        'type' => 'page',
        'status' => NodeInterface::PUBLISHED,
    ]);
    $different_bundle_node->save();
    $deleted_node = Node::create([
        'title' => 'Test deleted node',
        'type' => 'article',
        'status' => NodeInterface::PUBLISHED,
    ]);
    $deleted_node->save();
    $referencing_entity = EntityTest::create([
        'field_test' => [
            [
                'entity' => $published_node,
            ],
            [
                'entity' => $unpublished_node,
            ],
            [
                'entity' => $different_bundle_node,
            ],
            [
                'entity' => $deleted_node,
            ],
        ],
    ]);
    // Check that users with access are able pass the validation for fields
    // without pre-existing content.
    $this->container
        ->get('account_switcher')
        ->switchTo($user_with_access);
    $violations = $referencing_entity->field_test
        ->validate();
    $this->assertCount(0, $violations);
    // Check that users without access are not able pass the validation for
    // fields without pre-existing content.
    $this->container
        ->get('account_switcher')
        ->switchTo($user_without_access);
    $violations = $referencing_entity->field_test
        ->validate();
    $this->assertCount(1, $violations);
    $this->assertEquals(t('This entity (%type: %id) cannot be referenced.', [
        '%type' => 'node',
        '%id' => $unpublished_node->id(),
    ]), $violations[0]->getMessage());
    // Now save the referencing entity which will create a pre-existing state
    // for it and repeat the checks. This time, the user without access should
    // be able to pass the validation as well because it's not changing the
    // pre-existing state.
    $referencing_entity->save();
    $this->container
        ->get('account_switcher')
        ->switchTo($user_with_access);
    $violations = $referencing_entity->field_test
        ->validate();
    $this->assertCount(0, $violations);
    // Check that users without access are able pass the validation for fields
    // with pre-existing content.
    $this->container
        ->get('account_switcher')
        ->switchTo($user_without_access);
    $violations = $referencing_entity->field_test
        ->validate();
    $this->assertCount(0, $violations);
    // Re-save the referencing entity and check that the referenced entity is
    // not affected.
    $referencing_entity->name->value = $this->randomString();
    $referencing_entity->save();
    $this->assertEquals($published_node->id(), $referencing_entity->field_test[0]->target_id);
    $this->assertEquals($unpublished_node->id(), $referencing_entity->field_test[1]->target_id);
    $this->assertEquals($different_bundle_node->id(), $referencing_entity->field_test[2]->target_id);
    $this->assertEquals($deleted_node->id(), $referencing_entity->field_test[3]->target_id);
    $violations = $referencing_entity->field_test
        ->validate();
    $this->assertCount(0, $violations);
    // Remove one of the referenceable bundles and check that a pre-existing node
    // of that bundle can not be referenced anymore.
    $field = FieldConfig::loadByName('entity_test', 'entity_test', 'field_test');
    $field->setSetting('handler_settings', [
        'target_bundles' => [
            'article',
        ],
    ]);
    $field->save();
    $referencing_entity = $this->reloadEntity($referencing_entity);
    $violations = $referencing_entity->field_test
        ->validate();
    $this->assertCount(1, $violations);
    $this->assertEquals(t('This entity (%type: %id) cannot be referenced.', [
        '%type' => 'node',
        '%id' => $different_bundle_node->id(),
    ]), $violations[0]->getMessage());
    // Delete the last node and check that the pre-existing reference is not
    // valid anymore.
    $deleted_node->delete();
    $violations = $referencing_entity->field_test
        ->validate();
    $this->assertCount(2, $violations);
    $this->assertEquals(t('This entity (%type: %id) cannot be referenced.', [
        '%type' => 'node',
        '%id' => $different_bundle_node->id(),
    ]), $violations[0]->getMessage());
    $this->assertEquals(t('The referenced entity (%type: %id) does not exist.', [
        '%type' => 'node',
        '%id' => $deleted_node->id(),
    ]), $violations[1]->getMessage());
}

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