View source
<?php
namespace Drupal\Tests\field\Functional\EntityReference;
use Behat\Mink\Element\NodeElement;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\node\Entity\Node;
use Drupal\taxonomy\Entity\Vocabulary;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\field_ui\Traits\FieldUiTestTrait;
class EntityReferenceAdminTest extends BrowserTestBase {
use FieldUiTestTrait;
protected static $modules = [
'node',
'field_ui',
'path',
'taxonomy',
'block',
'views_ui',
];
protected $defaultTheme = 'stark';
protected $type;
protected function setUp() : void {
parent::setUp();
$this
->drupalPlaceBlock('system_breadcrumb_block');
$type_name = strtolower($this
->randomMachineName(8)) . '_test';
$type = $this
->drupalCreateContentType([
'name' => $type_name,
'type' => $type_name,
]);
$this->type = $type
->id();
$admin_user = $this
->drupalCreateUser([
'access content',
'administer node fields',
'administer node display',
'administer views',
'create ' . $type_name . ' content',
'edit own ' . $type_name . ' content',
]);
$this
->drupalLogin($admin_user);
}
public function testFieldAdminHandler() {
$bundle_path = 'admin/structure/types/manage/' . $this->type;
$edit = [
'id' => 'node_test_view',
'label' => 'Node Test View',
'show[wizard_key]' => 'node',
'show[sort]' => 'none',
'page[create]' => 1,
'page[title]' => 'Test Node View',
'page[path]' => 'test/node/view',
'page[style][style_plugin]' => 'default',
'page[style][row_plugin]' => 'fields',
];
$this
->drupalGet('admin/structure/views/add');
$this
->submitForm($edit, 'Save and edit');
$this
->submitForm([], 'Duplicate as Entity Reference');
$this
->clickLink('Settings');
$edit = [
'style_options[search_fields][title]' => 'title',
];
$this
->submitForm($edit, 'Apply');
$edit = [
'name[node_field_data.nid]' => 1,
];
$this
->drupalGet('admin/structure/views/nojs/add-handler/node_test_view/entity_reference_1/sort');
$this
->submitForm($edit, 'Add and configure sort criteria');
$this
->submitForm([], 'Apply');
$this
->drupalGet('admin/structure/views/view/node_test_view/edit/entity_reference_1');
$this
->submitForm([], 'Save');
$this
->clickLink('Settings');
$field_name = 'test_entity_ref_field';
$edit = [
'new_storage_type' => 'field_ui:entity_reference:node',
'label' => 'Test Entity Reference Field',
'field_name' => $field_name,
];
$this
->drupalGet($bundle_path . '/fields/add-field');
$this
->submitForm($edit, 'Save and continue');
$edit = [
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
];
$this
->submitForm($edit, 'Save field settings');
$edit = [
'settings[handler]' => 'views',
];
$this
->submitForm($edit, 'Change handler');
$edit = [
'required' => FALSE,
'settings[handler_settings][view][view_and_display]' => 'node_test_view:entity_reference_1',
];
$this
->submitForm($edit, 'Save settings');
$node1 = Node::create([
'type' => $this->type,
'title' => 'Foo Node',
]);
$node1
->save();
$node2 = Node::create([
'type' => $this->type,
'title' => 'Foo Node',
]);
$node2
->save();
$this
->drupalGet('node/add/' . $this->type);
$field = $this
->assertSession()
->fieldExists('field_test_entity_ref_field[0][target_id]');
$this
->assertStringContainsString("/entity_reference_autocomplete/node/views/", $field
->getAttribute('data-autocomplete-path'));
$target_url = $this
->getAbsoluteUrl($field
->getAttribute('data-autocomplete-path'));
$this
->drupalGet($target_url, [
'query' => [
'q' => 'Foo',
],
]);
$this
->assertSession()
->pageTextContains($node1
->getTitle() . ' (' . $node1
->id() . ')');
$this
->assertSession()
->pageTextContains($node2
->getTitle() . ' (' . $node2
->id() . ')');
$this
->drupalGet('node/add/' . $this->type);
$this
->submitForm([], 'Add another item');
$edit = [
'title[0][value]' => 'Example',
'field_test_entity_ref_field[0][target_id]' => 'Foo Node (' . $node1
->id() . ')',
'field_test_entity_ref_field[1][target_id]' => 'Foo Node (' . $node2
->id() . ')',
];
$this
->submitForm($edit, 'Save');
$this
->assertSession()
->statusCodeEquals(200);
$edit = [
'title[0][value]' => 'Example',
'field_test_entity_ref_field[0][target_id]' => 'Test',
];
$this
->drupalGet('node/add/' . $this->type);
$this
->submitForm($edit, 'Save');
$this
->assertSession()
->pageTextContains('There are no content items matching "Test"');
$edit = [
'title[0][value]' => 'Test',
'field_test_entity_ref_field[0][target_id]' => $node1
->getTitle(),
];
$this
->drupalGet('node/add/' . $this->type);
$this
->submitForm($edit, 'Save');
$this
->assertSession()
->pageTextContains('Multiple content items match this reference;');
$this
->assertSession()
->pageTextContains($node1
->getTitle() . ' (' . $node1
->id() . ')');
$this
->assertSession()
->pageTextContains($node2
->getTitle() . ' (' . $node2
->id() . ')');
$this
->assertSession()
->pageTextContains('Specify the one you want by appending the id in parentheses, like "' . $node2
->getTitle() . ' (' . $node2
->id() . ')' . '".');
$edit = [
'title[0][value]' => 'Test',
'field_test_entity_ref_field[0][target_id]' => $node1
->getTitle() . ' (' . $node1
->id() . ')',
];
$this
->drupalGet('node/add/' . $this->type);
$this
->submitForm($edit, 'Save');
$this
->assertSession()
->linkExists($node1
->getTitle());
Vocabulary::create([
'vid' => 'tags',
'name' => 'tags',
])
->save();
$taxonomy_term_field_name = $this
->createEntityReferenceField('taxonomy_term', [
'tags',
]);
$field_path = 'node.' . $this->type . '.field_' . $taxonomy_term_field_name;
$this
->drupalGet($bundle_path . '/fields/' . $field_path . '/storage');
$edit = [
'cardinality' => -1,
];
$this
->submitForm($edit, 'Save field settings');
$this
->drupalGet($bundle_path . '/fields/' . $field_path);
$term_name = $this
->randomString();
$result = \Drupal::entityQuery('taxonomy_term')
->condition('name', $term_name)
->condition('vid', 'tags')
->accessCheck(FALSE)
->execute();
$this
->assertCount(0, $result, "No taxonomy terms exist with the name '{$term_name}'.");
$edit = [
'settings[handler_settings][auto_create]' => 1,
];
$this
->submitForm($edit, 'Save settings');
$this
->drupalGet($bundle_path . '/fields/' . $field_path);
$edit = [
'default_value_input[field_' . $taxonomy_term_field_name . '][0][target_id]' => $term_name,
];
$this
->submitForm($edit, 'Save settings');
$result = \Drupal::entityQuery('taxonomy_term')
->condition('name', $term_name)
->condition('vid', 'tags')
->accessCheck(FALSE)
->execute();
$this
->assertCount(1, $result, 'Taxonomy term was auto created when set as field default.');
}
public function testAvailableFormatters() {
Vocabulary::create([
'vid' => 'tags',
'name' => 'tags',
])
->save();
$taxonomy_term_field_name = $this
->createEntityReferenceField('taxonomy_term', [
'tags',
]);
$user_field_name = $this
->createEntityReferenceField('user');
$node_field_name = $this
->createEntityReferenceField('node', [
$this->type,
]);
$date_format_field_name = $this
->createEntityReferenceField('date_format');
$this
->drupalGet('admin/structure/types/manage/' . $this->type . '/display');
$this
->assertFieldSelectOptions('fields[field_' . $taxonomy_term_field_name . '][type]', [
'entity_reference_label',
'entity_reference_entity_id',
'entity_reference_rss_category',
'entity_reference_entity_view',
]);
$this
->assertFieldSelectOptions('fields[field_' . $user_field_name . '][type]', [
'author',
'entity_reference_entity_id',
'entity_reference_entity_view',
'entity_reference_label',
]);
$this
->assertFieldSelectOptions('fields[field_' . $node_field_name . '][type]', [
'entity_reference_label',
'entity_reference_entity_id',
'entity_reference_entity_view',
]);
$this
->assertFieldSelectOptions('fields[field_' . $date_format_field_name . '][type]', [
'entity_reference_label',
'entity_reference_entity_id',
]);
}
public function testMultipleTargetBundles() {
$vocabularies = [];
for ($i = 0; $i < 2; $i++) {
$vid = mb_strtolower($this
->randomMachineName());
$vocabularies[$i] = Vocabulary::create([
'name' => $this
->randomString(),
'vid' => $vid,
]);
$vocabularies[$i]
->save();
}
$field_name = $this
->createEntityReferenceField('taxonomy_term', [
$vocabularies[0]
->id(),
]);
$field_name = "field_{$field_name}";
$field_id = 'node.' . $this->type . '.' . $field_name;
$path = 'admin/structure/types/manage/' . $this->type . '/fields/' . $field_id;
$this
->drupalGet($path);
$this
->assertSession()
->fieldNotExists('settings[handler_settings][auto_create_bundle]');
$edit = [
'settings[handler_settings][target_bundles][' . $vocabularies[1]
->id() . ']' => TRUE,
];
$this
->drupalGet($path);
$this
->submitForm($edit, 'Save settings');
$this
->drupalGet($path);
$this
->assertSession()
->optionExists('settings[handler_settings][auto_create_bundle]', $vocabularies[0]
->id());
$this
->assertSession()
->optionExists('settings[handler_settings][auto_create_bundle]', $vocabularies[1]
->id());
$edit = [
'settings[handler_settings][auto_create]' => TRUE,
'settings[handler_settings][auto_create_bundle]' => $vocabularies[1]
->id(),
];
$this
->submitForm($edit, 'Save settings');
$field_config = FieldConfig::load($field_id);
$this
->assertEquals($vocabularies[1]
->id(), $field_config
->getSetting('handler_settings')['auto_create_bundle']);
$vocabularies[0]
->delete();
$field_config = FieldConfig::load($field_id);
$this
->assertTrue($field_config
->getSetting('handler_settings')['auto_create']);
$this
->assertSame($vocabularies[1]
->id(), $field_config
->getSetting('handler_settings')['auto_create_bundle']);
$vocabularies[1]
->delete();
$field_config = FieldConfig::load($field_id);
$this
->assertFalse($field_config
->getSetting('handler_settings')['auto_create']);
$this
->assertFalse(isset($field_config
->getSetting('handler_settings')['auto_create_bundle']));
}
protected function createEntityReferenceField($target_type, $bundles = []) {
$bundle_path = 'admin/structure/types/manage/' . $this->type;
$field_name = strtolower($this
->randomMachineName());
$storage_edit = $field_edit = [];
$storage_edit['settings[target_type]'] = $target_type;
foreach ($bundles as $bundle) {
$field_edit['settings[handler_settings][target_bundles][' . $bundle . ']'] = TRUE;
}
$this
->fieldUIAddNewField($bundle_path, $field_name, NULL, 'entity_reference', $storage_edit, $field_edit);
return $field_name;
}
protected function assertFieldSelectOptions(string $name, array $expected_options) : void {
$options = $this
->assertSession()
->selectExists($name)
->findAll('xpath', 'option');
array_walk($options, function (NodeElement &$option) {
$option = $option
->getValue();
});
$this
->assertEqualsCanonicalizing($expected_options, $options);
}
}