Security update for Core, with self-updated composer
[yaffs-website] / web / core / modules / field / tests / src / Functional / EntityReference / EntityReferenceIntegrationTest.php
1 <?php
2
3 namespace Drupal\Tests\field\Functional\EntityReference;
4
5 use Drupal\Component\Utility\SafeMarkup;
6 use Drupal\entity_test\Entity\EntityTest;
7 use Drupal\field\Entity\FieldConfig;
8 use Drupal\Tests\BrowserTestBase;
9 use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
10 use Drupal\Tests\config\Traits\AssertConfigEntityImportTrait;
11
12 /**
13  * Tests various Entity reference UI components.
14  *
15  * @group entity_reference
16  */
17 class EntityReferenceIntegrationTest extends BrowserTestBase {
18
19   use AssertConfigEntityImportTrait;
20   use EntityReferenceTestTrait;
21
22   /**
23    * The entity type used in this test.
24    *
25    * @var string
26    */
27   protected $entityType = 'entity_test';
28
29   /**
30    * The bundle used in this test.
31    *
32    * @var string
33    */
34   protected $bundle = 'entity_test';
35
36   /**
37    * The name of the field used in this test.
38    *
39    * @var string
40    */
41   protected $fieldName;
42
43   /**
44    * Modules to install.
45    *
46    * @var array
47    */
48   public static $modules = ['config_test', 'entity_test', 'field_ui'];
49
50   /**
51    * {@inheritdoc}
52    */
53   protected function setUp() {
54     parent::setUp();
55
56     // Create a test user.
57     $web_user = $this->drupalCreateUser(['administer entity_test content', 'administer entity_test fields', 'view test entity']);
58     $this->drupalLogin($web_user);
59   }
60
61   /**
62    * Tests the entity reference field with all its supported field widgets.
63    */
64   public function testSupportedEntityTypesAndWidgets() {
65     foreach ($this->getTestEntities() as $key => $referenced_entities) {
66       $this->fieldName = 'field_test_' . $referenced_entities[0]->getEntityTypeId();
67
68       // Create an Entity reference field.
69       $this->createEntityReferenceField($this->entityType, $this->bundle, $this->fieldName, $this->fieldName, $referenced_entities[0]->getEntityTypeId(), 'default', [], 2);
70
71       // Test the default 'entity_reference_autocomplete' widget.
72       entity_get_form_display($this->entityType, $this->bundle, 'default')->setComponent($this->fieldName)->save();
73
74       $entity_name = $this->randomMachineName();
75       $edit = [
76         'name[0][value]' => $entity_name,
77         $this->fieldName . '[0][target_id]' => $referenced_entities[0]->label() . ' (' . $referenced_entities[0]->id() . ')',
78         // Test an input of the entity label without a ' (entity_id)' suffix.
79         $this->fieldName . '[1][target_id]' => $referenced_entities[1]->label(),
80       ];
81       $this->drupalPostForm($this->entityType . '/add', $edit, t('Save'));
82       $this->assertFieldValues($entity_name, $referenced_entities);
83
84       // Try to post the form again with no modification and check if the field
85       // values remain the same.
86       /** @var \Drupal\Core\Entity\EntityStorageInterface $storage */
87       $storage = $this->container->get('entity_type.manager')->getStorage($this->entityType);
88       $entity = current($storage->loadByProperties(['name' => $entity_name]));
89       $this->drupalGet($this->entityType . '/manage/' . $entity->id() . '/edit');
90       $this->assertFieldByName($this->fieldName . '[0][target_id]', $referenced_entities[0]->label() . ' (' . $referenced_entities[0]->id() . ')');
91       $this->assertFieldByName($this->fieldName . '[1][target_id]', $referenced_entities[1]->label() . ' (' . $referenced_entities[1]->id() . ')');
92
93       $this->drupalPostForm(NULL, [], t('Save'));
94       $this->assertFieldValues($entity_name, $referenced_entities);
95
96       // Test the 'entity_reference_autocomplete_tags' widget.
97       entity_get_form_display($this->entityType, $this->bundle, 'default')->setComponent($this->fieldName, [
98         'type' => 'entity_reference_autocomplete_tags',
99       ])->save();
100
101       $entity_name = $this->randomMachineName();
102       $target_id = $referenced_entities[0]->label() . ' (' . $referenced_entities[0]->id() . ')';
103       // Test an input of the entity label without a ' (entity_id)' suffix.
104       $target_id .= ', ' . $referenced_entities[1]->label();
105       $edit = [
106         'name[0][value]' => $entity_name,
107         $this->fieldName . '[target_id]' => $target_id,
108       ];
109       $this->drupalPostForm($this->entityType . '/add', $edit, t('Save'));
110       $this->assertFieldValues($entity_name, $referenced_entities);
111
112       // Try to post the form again with no modification and check if the field
113       // values remain the same.
114       $entity = current($storage->loadByProperties(['name' => $entity_name]));
115       $this->drupalGet($this->entityType . '/manage/' . $entity->id() . '/edit');
116       $this->assertFieldByName($this->fieldName . '[target_id]', $target_id . ' (' . $referenced_entities[1]->id() . ')');
117
118       $this->drupalPostForm(NULL, [], t('Save'));
119       $this->assertFieldValues($entity_name, $referenced_entities);
120
121       // Test all the other widgets supported by the entity reference field.
122       // Since we don't know the form structure for these widgets, just test
123       // that editing and saving an already created entity works.
124       $exclude = ['entity_reference_autocomplete', 'entity_reference_autocomplete_tags'];
125       $entity = current($storage->loadByProperties(['name' => $entity_name]));
126       $supported_widgets = \Drupal::service('plugin.manager.field.widget')->getOptions('entity_reference');
127       $supported_widget_types = array_diff(array_keys($supported_widgets), $exclude);
128
129       foreach ($supported_widget_types as $widget_type) {
130         entity_get_form_display($this->entityType, $this->bundle, 'default')->setComponent($this->fieldName, [
131           'type' => $widget_type,
132         ])->save();
133
134         $this->drupalPostForm($this->entityType . '/manage/' . $entity->id() . '/edit', [], t('Save'));
135         $this->assertFieldValues($entity_name, $referenced_entities);
136       }
137
138       // Reset to the default 'entity_reference_autocomplete' widget.
139       entity_get_form_display($this->entityType, $this->bundle, 'default')->setComponent($this->fieldName)->save();
140
141       // Set first entity as the default_value.
142       $field_edit = [
143         'default_value_input[' . $this->fieldName . '][0][target_id]' => $referenced_entities[0]->label() . ' (' . $referenced_entities[0]->id() . ')',
144       ];
145       if ($key == 'content') {
146         $field_edit['settings[handler_settings][target_bundles][' . $referenced_entities[0]->getEntityTypeId() . ']'] = TRUE;
147       }
148       $this->drupalPostForm($this->entityType . '/structure/' . $this->bundle . '/fields/' . $this->entityType . '.' . $this->bundle . '.' . $this->fieldName, $field_edit, t('Save settings'));
149       // Ensure the configuration has the expected dependency on the entity that
150       // is being used a default value.
151       $field = FieldConfig::loadByName($this->entityType, $this->bundle, $this->fieldName);
152       $this->assertTrue(in_array($referenced_entities[0]->getConfigDependencyName(), $field->getDependencies()[$key]), SafeMarkup::format('Expected @type dependency @name found', ['@type' => $key, '@name' => $referenced_entities[0]->getConfigDependencyName()]));
153       // Ensure that the field can be imported without change even after the
154       // default value deleted.
155       $referenced_entities[0]->delete();
156       // Reload the field since deleting the default value can change the field.
157       \Drupal::entityManager()->getStorage($field->getEntityTypeId())->resetCache([$field->id()]);
158       $field = FieldConfig::loadByName($this->entityType, $this->bundle, $this->fieldName);
159       $this->assertConfigEntityImport($field);
160
161       // Once the default value has been removed after saving the dependency
162       // should be removed.
163       $field = FieldConfig::loadByName($this->entityType, $this->bundle, $this->fieldName);
164       $field->save();
165       $dependencies = $field->getDependencies();
166       $this->assertFalse(isset($dependencies[$key]) && in_array($referenced_entities[0]->getConfigDependencyName(), $dependencies[$key]), SafeMarkup::format('@type dependency @name does not exist.', ['@type' => $key, '@name' => $referenced_entities[0]->getConfigDependencyName()]));
167     }
168   }
169
170   /**
171    * Asserts that the reference field values are correct.
172    *
173    * @param string $entity_name
174    *   The name of the test entity.
175    * @param \Drupal\Core\Entity\EntityInterface[] $referenced_entities
176    *   An array of referenced entities.
177    */
178   protected function assertFieldValues($entity_name, $referenced_entities) {
179     $entity = current($this->container->get('entity_type.manager')->getStorage(
180     $this->entityType)->loadByProperties(['name' => $entity_name]));
181
182     $this->assertTrue($entity, format_string('%entity_type: Entity found in the database.', ['%entity_type' => $this->entityType]));
183
184     $this->assertEqual($entity->{$this->fieldName}->target_id, $referenced_entities[0]->id());
185     $this->assertEqual($entity->{$this->fieldName}->entity->id(), $referenced_entities[0]->id());
186     $this->assertEqual($entity->{$this->fieldName}->entity->label(), $referenced_entities[0]->label());
187
188     $this->assertEqual($entity->{$this->fieldName}[1]->target_id, $referenced_entities[1]->id());
189     $this->assertEqual($entity->{$this->fieldName}[1]->entity->id(), $referenced_entities[1]->id());
190     $this->assertEqual($entity->{$this->fieldName}[1]->entity->label(), $referenced_entities[1]->label());
191   }
192
193   /**
194    * Creates two content and two config test entities.
195    *
196    * @return array
197    *   An array of entity objects.
198    */
199   protected function getTestEntities() {
200     $storage = \Drupal::entityTypeManager()->getStorage('config_test');
201     $config_entity_1 = $storage->create(['id' => $this->randomMachineName(), 'label' => $this->randomMachineName()]);
202     $config_entity_1->save();
203     $config_entity_2 = $storage->create(['id' => $this->randomMachineName(), 'label' => $this->randomMachineName()]);
204     $config_entity_2->save();
205
206     $content_entity_1 = EntityTest::create(['name' => $this->randomMachineName()]);
207     $content_entity_1->save();
208     $content_entity_2 = EntityTest::create(['name' => $this->randomMachineName()]);
209     $content_entity_2->save();
210
211     return [
212       'config' => [
213         $config_entity_1,
214         $config_entity_2,
215       ],
216       'content' => [
217         $content_entity_1,
218         $content_entity_2,
219       ],
220     ];
221   }
222
223 }