3 namespace Drupal\Tests\field\Kernel\EntityReference;
5 use Drupal\Component\Utility\Unicode;
6 use Drupal\Core\DependencyInjection\ContainerBuilder;
7 use Drupal\Core\Logger\RfcLogLevel;
8 use Drupal\field\Entity\FieldConfig;
9 use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
10 use Drupal\node\Entity\NodeType;
11 use Drupal\KernelTests\KernelTestBase;
12 use Drupal\taxonomy\Entity\Vocabulary;
13 use Symfony\Component\Debug\BufferingLogger;
16 * Tests entity reference field settings.
20 class EntityReferenceSettingsTest extends KernelTestBase {
22 use EntityReferenceTestTrait;
27 public static $modules = ['node', 'taxonomy', 'field', 'user', 'text', 'entity_reference', 'entity_test', 'system'];
32 * @var \Drupal\node\Entity\NodeType
39 * @var \Drupal\taxonomy\Entity\Vocabulary
41 protected $vocabulary;
44 * An entity bundle that is not stored as a configuration entity.
48 protected $customBundle;
51 * The service name for a logger implementation that collects anything logged.
55 protected $testLogServiceName = 'entity_reference_settings_test.logger';
60 protected function setUp() {
63 $this->installEntitySchema('node');
64 $this->installEntitySchema('taxonomy_term');
65 $this->installEntitySchema('entity_test');
67 $this->nodeType = NodeType::create([
68 'type' => Unicode::strtolower($this->randomMachineName()),
69 'name' => $this->randomString(),
71 $this->nodeType->save();
73 // Create a custom bundle.
74 $this->customBundle = 'test_bundle_' . Unicode::strtolower($this->randomMachineName());
75 entity_test_create_bundle($this->customBundle, NULL, 'entity_test');
77 // Prepare the logger for collecting the expected critical error.
78 $this->container->get($this->testLogServiceName)->cleanLogs();
82 * Tests that config bundle deletions are mirrored in field config settings.
84 public function testConfigTargetBundleDeletion() {
85 // Create two vocabularies.
86 /** @var \Drupal\taxonomy\Entity\Vocabulary[] $vocabularies */
88 for ($i = 0; $i < 2; $i++) {
89 $vid = Unicode::strtolower($this->randomMachineName());
90 $vocabularies[$i] = Vocabulary::create([
91 'name' => $this->randomString(),
94 $vocabularies[$i]->save();
96 // Attach an entity reference field to $this->nodeType.
97 $name = Unicode::strtolower($this->randomMachineName());
98 $label = $this->randomString();
100 'target_bundles' => [
101 $vocabularies[0]->id() => $vocabularies[0]->id(),
102 $vocabularies[1]->id() => $vocabularies[1]->id(),
105 $this->createEntityReferenceField('node', $this->nodeType->id(), $name, $label, 'taxonomy_term', 'default', $handler_settings);
107 // Check that the 'target_bundle' setting contains the vocabulary.
108 $field_config = FieldConfig::loadByName('node', $this->nodeType->id(), $name);
109 $actual_handler_settings = $field_config->getSetting('handler_settings');
110 $this->assertEqual($handler_settings, $actual_handler_settings);
112 // Delete the vocabulary.
113 $vocabularies[0]->delete();
114 // Ensure that noting is logged.
115 $this->assertEmpty($this->container->get($this->testLogServiceName)->cleanLogs());
117 // Check that the deleted vocabulary is no longer present in the
118 // 'target_bundles' field setting.
119 $field_config = FieldConfig::loadByName('node', $this->nodeType->id(), $name);
120 $handler_settings = $field_config->getSetting('handler_settings');
121 $this->assertEquals([$vocabularies[1]->id() => $vocabularies[1]->id()], $handler_settings['target_bundles']);
123 // Delete the other vocabulary.
124 $vocabularies[1]->delete();
125 // Ensure that field_field_config_presave() logs the expected critical
127 $log_message = $this->container->get($this->testLogServiceName)->cleanLogs()[0];
128 $this->assertEquals(RfcLogLevel::CRITICAL, $log_message[0]);
129 $this->assertEquals('The %field_name entity reference field (entity_type: %entity_type, bundle: %bundle) no longer has any valid bundle it can reference. The field is not working correctly anymore and has to be adjusted.', $log_message[1]);
130 $this->assertEquals($field_config->getName(), $log_message[2]['%field_name']);
131 $this->assertEquals('node', $log_message[2]['%entity_type']);
132 $this->assertEquals($this->nodeType->id(), $log_message[2]['%bundle']);
134 // Check that the deleted bundle is no longer present in the
135 // 'target_bundles' field setting.
136 $field_config = FieldConfig::loadByName('node', $this->nodeType->id(), $name);
137 $handler_settings = $field_config->getSetting('handler_settings');
138 $this->assertEquals([], $handler_settings['target_bundles']);
142 * Tests that deletions of custom bundles are mirrored in field settings.
144 public function testCustomTargetBundleDeletion() {
145 // Attach an entity reference field to $this->nodeType.
146 $name = Unicode::strtolower($this->randomMachineName());
147 $label = $this->randomString();
148 $handler_settings = ['target_bundles' => [$this->customBundle => $this->customBundle]];
149 $this->createEntityReferenceField('node', $this->nodeType->id(), $name, $label, 'entity_test', 'default', $handler_settings);
151 // Check that the 'target_bundle' setting contains the custom bundle.
152 $field_config = FieldConfig::loadByName('node', $this->nodeType->id(), $name);
153 $actual_handler_settings = $field_config->getSetting('handler_settings');
154 $this->assertEqual($handler_settings, $actual_handler_settings);
156 // Delete the custom bundle.
157 entity_test_delete_bundle($this->customBundle, 'entity_test');
159 // Ensure that field_field_config_presave() logs the expected critical
161 $log_message = $this->container->get($this->testLogServiceName)->cleanLogs()[0];
162 $this->assertEquals(RfcLogLevel::CRITICAL, $log_message[0]);
163 $this->assertEquals('The %field_name entity reference field (entity_type: %entity_type, bundle: %bundle) no longer has any valid bundle it can reference. The field is not working correctly anymore and has to be adjusted.', $log_message[1]);
164 $this->assertEquals($field_config->getName(), $log_message[2]['%field_name']);
165 $this->assertEquals('node', $log_message[2]['%entity_type']);
166 $this->assertEquals($this->nodeType->id(), $log_message[2]['%bundle']);
168 // Check that the deleted bundle is no longer present in the
169 // 'target_bundles' field setting.
170 $field_config = FieldConfig::loadByName('node', $this->nodeType->id(), $name);
171 $handler_settings = $field_config->getSetting('handler_settings');
172 $this->assertTrue(empty($handler_settings['target_bundles']));
178 public function register(ContainerBuilder $container) {
179 parent::register($container);
181 ->register($this->testLogServiceName, BufferingLogger::class)