clean install

This commit is contained in:
2024-12-10 15:08:16 +01:00
commit e14eb2d8fd
31193 changed files with 3555714 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
<?php
namespace Drupal\Tests\inline_entity_form\FunctionalJavascript;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
/**
* IEF complex field widget containing an IEF simple field widget tests.
*
* @group inline_entity_form
*/
class ComplexSimpleWidgetTest extends InlineEntityFormTestBase {
/**
* Modules to enable.
*
* @var array
*/
protected static $modules = [
'inline_entity_form_test',
'field',
'field_ui',
];
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->user = $this->createUser([
'create ief_complex_simple content',
'create ief_simple_single content',
'create ief_test_custom content',
'view own unpublished content',
]);
$this->drupalLogin($this->user);
$this->fieldConfigStorage = $this->container
->get('entity_type.manager')
->getStorage('field_config');
}
/**
* Test a Simple IEF widget inside of Complex IEF widget.
*/
public function testSimpleInComplex() {
$page = $this->getSession()->getPage();
$assert_session = $this->assertSession();
$outer_required_options = [
TRUE,
FALSE,
];
$cardinality_options = [
1 => 1,
2 => 2,
FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED => 3,
];
$first_title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 1);
$outer_title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 2);
$inner_title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 3);
/** @var \Drupal\field\FieldStorageConfigInterface $field_storage */
$field_storage = $this->fieldStorageConfigStorage->load('node.ief_complex_outer');
/** @var \Drupal\Core\Field\FieldConfigInterface $field_config */
$field_config = $this->fieldConfigStorage->load('node.ief_complex_simple.ief_complex_outer');
foreach ($outer_required_options as $outer_required_option) {
$field_config->setRequired($outer_required_option);
$field_config->save();
foreach ($cardinality_options as $cardinality => $limit) {
$field_storage->setCardinality($cardinality);
$field_storage->save();
$this->drupalGet('node/add/ief_complex_simple');
if (!$outer_required_option) {
$assert_session->pageTextContains('Complex Outer');
// Field should not be available before ajax submit.
$assert_session->elementNotExists('xpath', $outer_title_field_xpath);
$assert_session
->elementExists('xpath', '//input[@type="submit" and @value="Add new node"]')
->press();
$this->assertNotEmpty($assert_session->waitForElement('xpath', $outer_title_field_xpath));
}
$outer_title = $this->randomMachineName();
$inner_title = $this->randomMachineName();
$assert_session->elementExists('xpath', $outer_title_field_xpath)->setValue($outer_title);
// Simple widget is required so should always show up. No need for
// add submit.
$assert_session->elementExists('xpath', $inner_title_field_xpath)->setValue($inner_title);
$create_outer_button_selector = '//input[@type="submit" and @value="Create node"]';
$assert_session->elementExists('xpath', $create_outer_button_selector)->press();
// After Ajax submit the ief title fields should be gone.
$this->assertNotEmpty($assert_session->waitForButton('Edit'));
$assert_session->elementNotExists('xpath', $outer_title_field_xpath);
$assert_session->elementNotExists('xpath', $inner_title_field_xpath);
$assert_session->elementNotExists('xpath', $create_outer_button_selector);
// The nodes should not actually be saved at this point.
$this->assertNoNodeByTitle($outer_title, 'Outer node was not created when widget submitted.');
$this->assertNoNodeByTitle($inner_title, 'Inner node was not created when widget submitted.');
$host_title = $this->randomMachineName();
$assert_session->elementExists('xpath', $first_title_field_xpath)->setValue($host_title);
$page->pressButton('Save');
$assert_session->pageTextContains("$host_title has been created.");
$assert_session->pageTextContains($outer_title);
// Check the nodes were created correctly.
$host_node = $this->drupalGetNodeByTitle($host_title);
$this->assertNotNull($host_node->ief_complex_outer->entity, 'Outer node was created.');
if (isset($host_node->ief_complex_outer->entity)) {
$outer_node = $host_node->ief_complex_outer->entity;
$this->assertEquals($outer_title, $outer_node->label(), "Outer node's title looks correct.");
$this->assertEquals('ief_simple_single', $outer_node->bundle(), "Outer node's type looks correct.");
$this->assertNotNull($outer_node->single->entity, 'Inner node was created');
if (isset($outer_node->single->entity)) {
$inner_node = $outer_node->single->entity;
$this->assertEquals($inner_title, $inner_node->label(), "Inner node's title looks correct.");
$this->assertEquals('ief_test_custom', $inner_node->bundle(), "Inner node's type looks correct.");
}
}
}
}
}
}

View File

@@ -0,0 +1,294 @@
<?php
namespace Drupal\Tests\inline_entity_form\FunctionalJavascript;
/**
* IEF complex entity reference revisions tests.
*
* @group inline_entity_form
*/
class ComplexWidgetRevisionsTest extends InlineEntityFormTestBase {
/**
* Modules to enable.
*
* @var array
*/
protected static $modules = [
'field',
'field_ui',
'entity_test',
'entity_reference_revisions',
'inline_entity_form_test',
];
/**
* URL to add new content.
*
* @var string
*/
protected $formContentAddUrl;
/**
* Entity form display storage.
*
* @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface
*/
protected $entityFormDisplayStorage;
/**
* Prepares environment for testing.
*/
protected function setUp(): void {
parent::setUp();
$this->user = $this->createUser([
'administer entity_test__without_bundle content',
'administer entity_test content',
'administer content types',
'create err_level_1 content',
'edit any err_level_1 content',
'delete any err_level_1 content',
'create err_level_2 content',
'edit any err_level_2 content',
'delete any err_level_2 content',
'create err_level_3 content',
'edit any err_level_3 content',
'delete any err_level_3 content',
'view own unpublished content',
]);
$this->drupalLogin($this->user);
$this->formContentAddUrl = 'node/add/err_level_1';
$this->entityFormDisplayStorage = $this->container->get('entity_type.manager')->getStorage('entity_form_display');
}
/**
* Data provider for ::testRevisionsAtDepth.
*/
public function revisionsAtDepthDataProvider(): array {
return [
[FALSE],
[TRUE],
];
}
/**
* Tests saving entity reference revisions' field types at depth.
*
* @dataProvider revisionsAtDepthDataProvider
*/
public function testRevisionsAtDepth(bool $inner_widget_adds_revisions) {
$level_2_display_config = $this->entityFormDisplayStorage->load('node.err_level_2.default');
$component = $level_2_display_config->getComponent('field_level_3_items');
$component['settings']['revision'] = $inner_widget_adds_revisions;
$level_2_display_config->setComponent('field_level_3_items', $component);
$level_2_display_config->save();
// Get the xpath selectors for the input fields in this test.
$top_title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 1);
$nested_title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 2);
$double_nested_title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 3);
// Get the xpath selectors for the buttons in this test.
$first_add_new_node_button_xpath = $this->getXpathForButtonWithValue('Add new node', 1);
$first_create_node_button_xpath = $this->getXpathForButtonWithValue('Create node', 1);
$first_edit_button_xpath = $this->getXpathForButtonWithValue('Edit', 1);
$first_update_button_xpath = $this->getXpathForButtonWithValue('Update node', 1);
$this->drupalGet($this->formContentAddUrl);
$page = $this->getSession()->getPage();
$assert_session = $this->assertSession();
// Open up level 2 and 3 IEF forms.
$assert_session->elementExists('xpath', $first_add_new_node_button_xpath)->press();
$assert_session->waitForElementRemoved('xpath', $first_add_new_node_button_xpath);
$assert_session->elementExists('xpath', $first_add_new_node_button_xpath)->press();
// Fill in and save level 3 IEF form.
$this->assertNotEmpty($assert_session->waitForElement('xpath', $double_nested_title_field_xpath));
$assert_session->elementExists('xpath', $double_nested_title_field_xpath)->setValue('Level 3');
$assert_session->elementExists('xpath', $first_create_node_button_xpath)->press();
$this->assertNotEmpty($assert_session->waitForElement('xpath', $first_edit_button_xpath));
// Fill in and save level 2 IEF form.
$assert_session->elementExists('xpath', $nested_title_field_xpath)->setValue('Level 2');
$assert_session->elementExists('xpath', $first_create_node_button_xpath)->press();
$this->assertNotEmpty($assert_session->waitForElement('xpath', $first_edit_button_xpath));
// Save the top level entity.
$assert_session->elementExists('xpath', $top_title_field_xpath)->setValue('Level 1');
$assert_session->waitForElementRemoved('xpath', $first_edit_button_xpath);
$page->pressButton('Save');
// Re-edit the created node to test for revisions.
$node = $this->drupalGetNodeByTitle('Level 1');
$this->drupalGet('node/' . $node->id() . '/edit');
// Open up level 2 and 3 IEF forms.
$assert_session->elementExists('xpath', $first_edit_button_xpath)->press();
$assert_session->waitForElementRemoved('xpath', $first_edit_button_xpath);
$assert_session->elementExists('xpath', $first_edit_button_xpath)->press();
// Change level 3 IEF node title.
$this->assertNotEmpty($assert_session->waitForElement('xpath', $double_nested_title_field_xpath));
$assert_session->elementExists('xpath', $double_nested_title_field_xpath)->setValue('Level 3.1');
$assert_session->elementExists('xpath', $first_update_button_xpath)->press();
$this->assertNotEmpty($assert_session->waitForElement('xpath', $first_edit_button_xpath));
// Change level 2 IEF node title.
$assert_session->elementExists('xpath', $nested_title_field_xpath)->setValue('Level 2.1');
$assert_session->elementExists('xpath', $first_update_button_xpath)->press();
$this->assertNotEmpty($assert_session->waitForElement('xpath', $first_edit_button_xpath));
// Save the top level entity.
$assert_session->elementExists('xpath', $top_title_field_xpath)->setValue('Level 1.1');
$assert_session->waitForElementRemoved('xpath', $first_edit_button_xpath);
$page->pressButton('Save');
// Assert that the entities are correctly saved.
$assert_session->pageTextContains('Level 1.1 has been updated.');
$assert_session->pageTextContains('Level 2.1');
$assert_session->pageTextContains('Level 3.1');
// Load the current revision id of the Level 2 node.
$node_level_2 = $this->drupalGetNodeByTitle('Level 2.1');
$node_level_2_vid = $node_level_2->getLoadedRevisionId();
// Load the current revision id of the Level 3 node.
$node_level_3 = $this->drupalGetNodeByTitle('Level 3.1');
$node_level_3_vid = $node_level_3->getLoadedRevisionId();
// Re-edit the created node to test for revisions.
$this->drupalGet('node/' . $node->id() . '/edit');
// Open up level 2 and 3 IEF forms.
$assert_session->elementExists('xpath', $first_edit_button_xpath)->press();
$assert_session->waitForElementRemoved('xpath', $first_edit_button_xpath);
$assert_session->elementExists('xpath', $first_edit_button_xpath)->press();
// Change level 3 IEF node title.
$this->assertNotEmpty($assert_session->waitForElement('xpath', $double_nested_title_field_xpath));
$assert_session->elementExists('xpath', $double_nested_title_field_xpath)->setValue('Level 3.2');
$assert_session->elementExists('xpath', $first_update_button_xpath)->press();
$this->assertNotEmpty($assert_session->waitForElement('xpath', $first_edit_button_xpath));
// Change level 2 IEF node title.
$assert_session->elementExists('xpath', $nested_title_field_xpath)->setValue('Level 2.2');
$assert_session->elementExists('xpath', $first_update_button_xpath)->press();
$this->assertNotEmpty($assert_session->waitForElement('xpath', $first_edit_button_xpath));
// Save the top level entity.
$assert_session->elementExists('xpath', $top_title_field_xpath)->setValue('Level 1.2');
$assert_session->waitForElementRemoved('xpath', $first_edit_button_xpath);
$page->pressButton('Save');
// Assert that the entities are correctly saved.
$assert_session->pageTextContains('Level 1.2 has been updated.');
$assert_session->pageTextContains('Level 2.2');
$assert_session->pageTextContains('Level 3.2');
// Clear node cache.
$this->container->get('entity_type.manager')
->getStorage('node')
->resetCache();
// Load the current revision id of the Level 2 node.
$node_level_2 = $this->drupalGetNodeByTitle('Level 2.2');
$node_level_2_vid_new = $node_level_2->getLoadedRevisionId();
// Assert that a new revision created.
$this->assertNotEquals($node_level_2_vid, $node_level_2_vid_new);
// Load the current revision id of the Level 3 node.
$node_level_3 = $this->drupalGetNodeByTitle('Level 3.2');
$node_level_3_vid_new = $node_level_3->getLoadedRevisionId();
// Assert that (no) new revision created.
if ($inner_widget_adds_revisions) {
$this->assertNotEquals($node_level_3_vid, $node_level_3_vid_new);
}
else {
$this->assertEquals($node_level_3_vid, $node_level_3_vid_new);
}
}
/**
* Tests saving entity revision with test entity that has no bundle.
*/
public function testRevisionsWithTestEntityNoBundle() {
// Get the xpath selectors for the fields in this test.
$title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 1);
$name_field_xpath = $this->getXpathForNthInputByLabelText('Name', 1);
// Get the xpath selectors for the buttons in this test.
$first_add_new_no_bundle_node_button = $this->getXpathForButtonWithValue('Add new entity test without bundle', 1);
$first_no_bundle_create_node_button = $this->getXpathForButtonWithValue('Create entity test without bundle', 1);
$first_no_bundle_node_edit_button = $this->getXpathForButtonWithValue('Edit', 1);
$first_no_bundle_update_node_button = $this->getXpathForButtonWithValue('Update entity test without bundle', 1);
$this->drupalGet($this->formContentAddUrl);
$page = $this->getSession()->getPage();
$assert_session = $this->assertSession();
// Open up test entity with no bundle IEF form.
$assert_session->elementExists('xpath', $first_add_new_no_bundle_node_button)->press();
$assert_session->waitForElementRemoved('xpath', $first_add_new_no_bundle_node_button);
$this->assertNotEmpty($assert_session->waitForElement('xpath', $first_no_bundle_create_node_button));
// Save level 2 test entity without bundle IEF form.
$assert_session->elementExists('xpath', $name_field_xpath)->setValue('Level 2 entity without bundle');
$assert_session->elementExists('xpath', $first_no_bundle_create_node_button)->press();
$assert_session->waitForElementRemoved('xpath', $first_add_new_no_bundle_node_button);
$this->assertNotEmpty($assert_session->waitForElement('xpath', $first_no_bundle_node_edit_button));
// Save the top level entity.
$assert_session->elementExists('xpath', $title_field_xpath)->setValue('Level 1');
$page->pressButton('Save');
// Assert that the entities are correctly saved.
$assert_session->pageTextContains('Level 1 has been created.');
$assert_session->pageTextContains('Level 2 entity without bundle');
// Load the new revision id of the entity.
$entity_no_bundle = $this->container->get('entity_type.manager')
->getStorage('entity_test_no_bundle')
->loadByProperties(['name' => 'Level 2 entity without bundle']);
$entity = reset($entity_no_bundle);
$entity_no_bundle_vid = $entity->getLoadedRevisionId();
// Re-edit the created node to test for revisions.
$node = $this->drupalGetNodeByTitle('Level 1');
$this->drupalGet('node/' . $node->id() . '/edit');
// Open up test entity with no bundle IEF form for editing.
$assert_session->elementExists('xpath', $first_no_bundle_node_edit_button)->press();
$this->assertNotEmpty($assert_session->waitForElement('xpath', $first_no_bundle_update_node_button));
// Change test entity with no bundle title.
$assert_session->elementExists('xpath', $name_field_xpath)->setValue('Level 2.1 entity without bundle');
$assert_session->elementExists('xpath', $first_no_bundle_update_node_button)->press();
$this->assertNotEmpty($assert_session->waitForElement('xpath', $first_no_bundle_node_edit_button));
// Save the top level entity.
$page->fillField('title[0][value]', 'Level 1.1');
$page->pressButton('Save');
// Assert that the entities are correctly saved.
$assert_session->pageTextContains('Level 1.1 has been updated.');
$assert_session->pageTextContains('Level 2.1 entity without bundle');
// Reload the new revision id of the entity.
$this->container->get('entity_type.manager')
->getStorage('entity_test_no_bundle')
->resetCache();
$entity_no_bundle = $this->container->get('entity_type.manager')
->getStorage('entity_test_no_bundle')
->load($entity->id());
$entity_no_bundle_vid_new = $entity_no_bundle->getLoadedRevisionId();
// Assert that new revision was created.
$this->assertNotEquals($entity_no_bundle_vid, $entity_no_bundle_vid_new);
}
}

View File

@@ -0,0 +1,88 @@
<?php
namespace Drupal\Tests\inline_entity_form\FunctionalJavascript;
/**
* Tests the IEF element on a custom form.
*
* @group inline_entity_form
*/
class ElementWebTest extends InlineEntityFormTestBase {
/**
* Modules to enable.
*
* @var array
*/
protected static $modules = ['inline_entity_form_test'];
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->user = $this->createUser([
'create ief_simple_single content',
'edit any ief_test_custom content',
'view own unpublished content',
'administer nodes',
]);
$this->drupalLogin($this->user);
$this->fieldStorageConfigStorage = $this->container
->get('entity_type.manager')
->getStorage('field_storage_config');
}
/**
* Tests IEF on a custom form.
*/
public function testCustomForm() {
// Get the xpath selectors for the fields in this test.
$title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 1);
$positive_int_field_xpath = $this->getXpathForNthInputByLabelText('Positive int', 1);
$assert_session = $this->assertSession();
$page = $this->getSession()->getPage();
foreach (['default', 'inline'] as $form_mode_possibility) {
$title = $this->randomMachineName();
$this->drupalGet("ief-test/$form_mode_possibility");
$assert_session->pageTextContains('Title');
$assert_session->pageTextContains('Positive int');
$this->checkFormDisplayFields("node.ief_test_custom.$form_mode_possibility", 'inline_entity_form');
$page->pressButton('Save');
$assert_session->pageTextNotContains("Created Content $title");
// @todo How do we test Chrome's HTML 5 validation?
// $assert_session->pageTextContains('Please fill out this field.');
// Fix in https://www.drupal.org/project/inline_entity_form/issues/3100883
$this->assertNoNodeByTitle($title);
$assert_session->elementExists('xpath', $title_field_xpath)->setValue($title);
$assert_session->elementExists('xpath', $positive_int_field_xpath)->setValue(-1);
$page->pressButton('Save');
$assert_session->pageTextNotContains("Created Content $title");
$this->assertNoNodeByTitle($title);
$assert_session->elementExists('xpath', $positive_int_field_xpath)->setValue(11);
$page->pressButton('Save');
$assert_session->pageTextContains("Created Content $title");
$this->assertNodeByTitle($title, 'ief_test_custom');
$node = $this->getNodeByTitle($title);
$this->drupalGet("ief-test/$form_mode_possibility/{$node->id()}");
// Assert node title appears in form.
$assert_session->elementExists('xpath', $title_field_xpath);
$this->checkFormDisplayFields("node.ief_test_custom.$form_mode_possibility", 'inline_entity_form');
$this->assertSame('11', $assert_session->elementExists('xpath', $positive_int_field_xpath)->getValue());
$assert_session->elementExists('xpath', $title_field_xpath)->setValue($title . ' - updated');
$page->pressButton('Update');
$this->assertNodeByTitle($title . ' - updated', 'ief_test_custom');
}
}
}

View File

@@ -0,0 +1,304 @@
<?php
namespace Drupal\Tests\inline_entity_form\FunctionalJavascript;
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
/**
* Base Class for Inline Entity Form Tests.
*/
abstract class InlineEntityFormTestBase extends WebDriverTestBase {
/**
* User with permissions to create content.
*
* @var \Drupal\user\Entity\User
*/
protected $user;
/**
* Field config storage.
*
* @var \Drupal\Core\Config\Entity\ConfigEntityStorage
*/
protected $fieldStorageConfigStorage;
/**
* Field config storage.
*
* @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface
*/
protected $fieldConfigStorage;
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->fieldStorageConfigStorage = $this->container->get('entity_type.manager')->getStorage('field_storage_config');
$this->fieldConfigStorage = $this->container->get('entity_type.manager')->getStorage('field_config');
}
/**
* {@inheritdoc}
*/
protected function prepareSettings() {
$drupal_version = (float) substr(\Drupal::VERSION, 0, 3);
if ($drupal_version < 8.8) {
// Fix entity_reference_autocomplete match_limit schema errors.
$this->strictConfigSchema = FALSE;
}
parent::prepareSettings();
}
/**
* Gets IEF button name.
*
* @param string $xpath
* Xpath of the button.
*
* @return string
* The name of the button.
*/
protected function getButtonName(string $xpath) {
$retval = '';
/** @var \SimpleXMLElement[] $elements */
if ($elements = $this->xpath($xpath)) {
foreach ($elements[0]->attributes() as $name => $value) {
if ($name === 'name') {
$retval = $value;
break;
}
}
}
return $retval;
}
/**
* Passes if no node is found for the title.
*
* @param string $title
* Node title to check.
* @param string $message
* Message to display.
*/
protected function assertNoNodeByTitle(string $title, $message = '') {
if (!$message) {
$message = "No node with title: $title";
}
$node = $this->getNodeByTitle($title, TRUE);
$this->assertEmpty($node, $message);
}
/**
* Passes if a node is found for the title.
*
* @param string $title
* Node title to check.
* @param string $content_type
* The content type to check.
* @param string $message
* Message to display.
*/
protected function assertNodeByTitle(string $title, $content_type = NULL, $message = '') {
if (!$message) {
$message = "Node with title found: $title";
}
$node = $this->getNodeByTitle($title, TRUE);
$this->assertNotEmpty($node, $message);
if ($content_type) {
$this->assertEquals($node->bundle(), $content_type, "Node is correct content type: $content_type");
}
}
/**
* Ensures that an entity with a specific label exists.
*
* @param string $label
* The label of the entity.
* @param string $entity_type_id
* The entity type ID.
* @param string $bundle
* (optional) The bundle this entity should have.
*/
protected function assertEntityByLabel(string $label, $entity_type_id = 'node', $bundle = NULL) {
$entity_type_manager = \Drupal::entityTypeManager();
$entity_type = $entity_type_manager->getDefinition($entity_type_id);
$label_key = $entity_type->getKey('label');
$bundle_key = $entity_type->getKey('bundle');
$query = $entity_type_manager->getStorage($entity_type_id)->getQuery()->accessCheck(FALSE);
$query->condition($label_key, $label);
if ($bundle && $bundle_key) {
$query->condition($bundle_key, $bundle);
}
$result = $query->execute();
$this->assertNotEmpty($result);
}
/**
* Checks for check correct fields on form displays.
*
* This checks based on exported config in the
* inline_entity_form_test module.
*
* @param string $form_display
* The form display to check.
* @param string $prefix
* The config prefix.
*/
protected function checkFormDisplayFields(string $form_display, string $prefix) {
$assert_session = $this->assertSession();
$form_display_fields = [
'node.ief_test_custom.default' => [
'expected' => [
'[title][0][value]',
'[uid][0][target_id]',
'[created][0][value][date]',
'[created][0][value][time]',
'[promote][value]',
'[sticky][value]',
'[positive_int][0][value]',
],
'unexpected' => [],
],
'node.ief_test_custom.inline' => [
'expected' => [
'[title][0][value]',
'[positive_int][0][value]',
],
'unexpected' => [
'[uid][0][target_id]',
'[created][0][value][date]',
'[created][0][value][time]',
'[promote][value]',
'[sticky][value]',
],
],
];
if (empty($form_display_fields[$form_display])) {
throw new \Exception('Form display not found: ' . $form_display);
}
$fields = $form_display_fields[$form_display];
foreach ($fields['expected'] as $expected_field) {
$assert_session->fieldExists($prefix . $expected_field);
}
foreach ($fields['unexpected'] as $unexpected_field) {
$assert_session->fieldNotExists($prefix . $unexpected_field);
}
}
/**
* Wait for an IEF table row to appear.
*
* @param string $title
* The title of the row for which to wait.
*/
protected function waitForRowByTitle(string $title) {
$this->assertNotEmpty($this->assertSession()->waitForElement('xpath', '//td[@class="inline-entity-form-node-label" and text()="' . $title . '"]'));
}
/**
* Wait for an IEF table row to disappear.
*
* @param string $title
* The title of the row for which to wait.
*/
protected function waitForRowRemovedByTitle(string $title) {
$this->assertNotEmpty($this->assertSession()->waitForElementRemoved('xpath', '//td[@class="inline-entity-form-node-label" and text()="' . $title . '"]'));
}
/**
* Asserts that an IEF table row exists.
*
* @param string $title
* The title of the row to check.
*
* @return \Behat\Mink\Element\NodeElement
* The <td> element containing the label for the IEF row.
*/
protected function assertRowByTitle(string $title) {
$this->assertNotEmpty($element = $this->assertSession()->elementExists('xpath', '//td[@class="inline-entity-form-node-label" and text()="' . $title . '"]'));
return $element;
}
/**
* Asserts that an IEF table row does not exist.
*
* @param string $title
* The title of the row to check.
*/
protected function assertNoRowByTitle(string $title) {
$this->assertSession()->elementNotExists('xpath', '//td[@class="inline-entity-form-node-label" and text()="' . $title . '"]');
}
/**
* Returns xpath selector to the index-th input with label.
*
* Note: index starts at 1.
*
* @param string $label
* The label text to select.
* @param int $index
* The index of the input to select.
*
* @return string
* The xpath selector for the input to select.
*/
protected function getXpathForNthInputByLabelText(string $label, int $index) {
return "(//*[@id=string((//label[.='$label']/@for)[$index])])";
}
/**
* Returns xpath selector to the first input with an auto-complete.
*
* @return string
* The xpath selector for the first input with an auto-complete.
*/
protected function getXpathForAutoCompleteInput() {
return '(//input[@data-autocomplete-path])';
}
/**
* Returns xpath selector to the index-th button with button text value.
*
* Note: index starts at 1.
*
* @param string $value
* The text on the button to select.
* @param int $index
* The index of the button to select.
*
* @return string
* The xpath selector for the button to select.
*/
protected function getXpathForButtonWithValue(string $value, int $index) {
return "(//input[@type='submit' and @value='$value'])[$index]";
}
/**
* Returns xpath selector for fieldset label.
*
* @param string $label
* The label text to select.
* @param int $index
* The index of the fieldset label to select.
*
* @return string
* The xpath selector for the fieldset label to select.
*/
protected function getXpathForFieldsetLabel(string $label, int $index) {
return "(//fieldset/legend/span[.='{$label}'])[$index]";
}
}

View File

@@ -0,0 +1,323 @@
<?php
namespace Drupal\Tests\inline_entity_form\FunctionalJavascript;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\node\Entity\Node;
use Drupal\node\NodeInterface;
/**
* Tests the IEF simple widget.
*
* @group inline_entity_form
*/
class SimpleWidgetTest extends InlineEntityFormTestBase {
/**
* Modules to enable.
*
* @var array
*/
protected static $modules = ['inline_entity_form_test'];
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->user = $this->createUser([
'create ief_simple_single content',
'create ief_test_custom content',
'edit any ief_simple_single content',
'edit own ief_test_custom content',
'view own unpublished content',
'create ief_simple_entity_no_bundle content',
'administer entity_test__without_bundle content',
]);
}
/**
* Tests simple IEF widget with different cardinality options.
*/
public function testSimpleCardinalityOptions() {
// Get the xpath selectors for the fields in this test.
$title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 1);
$first_nested_title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 2);
$second_nested_title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 3);
$third_nested_title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 4);
$fourth_nested_title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 5);
$first_positive_int_field_xpath = $this->getXpathForNthInputByLabelText('Positive int', 1);
$second_positive_int_field_xpath = $this->getXpathForNthInputByLabelText('Positive int', 2);
$third_positive_int_field_xpath = $this->getXpathForNthInputByLabelText('Positive int', 3);
$page = $this->getSession()->getPage();
$assert_session = $this->assertSession();
$this->drupalLogin($this->user);
$cardinality_options = [
1 => 1,
2 => 2,
FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED => 3,
];
/** @var \Drupal\field\FieldStorageConfigInterface $field_storage */
$field_storage = $this->fieldStorageConfigStorage->load('node.single');
foreach ($cardinality_options as $cardinality => $number_of_items) {
$field_storage->setCardinality($cardinality);
$field_storage->save();
$this->drupalGet('node/add/ief_simple_single');
$assert_session->elementTextContains('css', 'span.fieldset-legend', 'Single node');
$assert_session->elementTextContains('css', 'div.description', 'Reference a single node.');
if ($cardinality === 1) {
// With cardinality 1, one item should already be on the page.
$assert_session->buttonNotExists('Add another item');
$assert_session->elementExists('xpath', $title_field_xpath)->setValue('Host node');
$assert_session->elementExists('xpath', $first_nested_title_field_xpath)->setValue('Nested single node');
$assert_session->elementExists('xpath', $first_positive_int_field_xpath)->setValue(42);
$page->pressButton('Save');
$assert_session->pageTextContains('IEF simple single Host node has been created.');
$host_node = $this->getNodeByTitle('Host node');
}
elseif ($cardinality === 2) {
// With cardinality 2, two items should already be on the page.
$assert_session->buttonNotExists('Add another item');
$assert_session->elementExists('xpath', $title_field_xpath)->setValue('Host node 2');
$assert_session->elementExists('xpath', $first_nested_title_field_xpath)->setValue('Nested single node 2');
$assert_session->elementExists('xpath', $first_positive_int_field_xpath)->setValue(42);
$assert_session->elementExists('xpath', $second_nested_title_field_xpath)->setValue('Nested single node 3');
$assert_session->elementExists('xpath', $second_positive_int_field_xpath)->setValue(42);
$page->pressButton('Save');
$assert_session->pageTextContains('IEF simple single Host node 2 has been created.');
$host_node = $this->getNodeByTitle('Host node 2');
}
elseif ($cardinality === FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) {
// With unlimited cardinality, one item should already be on the page,
// and an 'Add another item' button should appear.
$assert_session->elementExists('xpath', $title_field_xpath)->setValue('Host node 3');
$assert_session->elementExists('xpath', $first_nested_title_field_xpath)->setValue('Nested single node 4');
$assert_session->elementExists('xpath', $first_positive_int_field_xpath)->setValue(42);
$assert_session->elementNotExists('xpath', $second_positive_int_field_xpath);
// Press the 'add another item' button and add a second item.
$assert_session->buttonExists('Add another item')->press();
$this->assertNotEmpty($assert_session->waitForElement('xpath', $second_nested_title_field_xpath));
// Assert an extra item isn't added at the same time.
$assert_session->elementNotExists('xpath', $third_nested_title_field_xpath);
$assert_session->elementExists('xpath', $second_nested_title_field_xpath)->setValue('Nested single node 5');
$assert_session->elementExists('xpath', $second_positive_int_field_xpath)->setValue(42);
// Press the 'add another item' button and add a third item.
$assert_session->buttonExists('Add another item')->press();
$this->assertNotEmpty($assert_session->waitForElement('xpath', $third_nested_title_field_xpath));
// Assert an extra item isn't added at the same time.
$assert_session->elementNotExists('xpath', $fourth_nested_title_field_xpath);
$assert_session->elementExists('xpath', $third_nested_title_field_xpath)->setValue('Nested single node 6');
$assert_session->elementExists('xpath', $third_positive_int_field_xpath)->setValue(42);
$page->pressButton('Save');
$assert_session->pageTextContains('IEF simple single Host node 3 has been created.');
$host_node = $this->getNodeByTitle('Host node 3');
}
$this->checkEditAccess($host_node, $number_of_items, $cardinality);
}
}
/**
* Test Validation on Simple Widget.
*/
public function testSimpleValidation() {
// Get the xpath selectors for the fields in this test.
$title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 1);
$nested_title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 2);
$positive_int_field_xpath = $this->getXpathForNthInputByLabelText('Positive int', 1);
$page = $this->getSession()->getPage();
$assert_session = $this->assertSession();
$this->drupalLogin($this->user);
$host_node_title = 'Host Validation Node';
$this->drupalGet('node/add/ief_simple_single');
// Assert inline entity field widget title found.
$assert_session->pageTextContains('Single node');
// Assert inline entity field description found.
$assert_session->pageTextContains('Reference a single node.');
// Assert positive int field found.
$assert_session->pageTextContains('Positive int');
$assert_session->elementExists('xpath', $title_field_xpath)->setValue($host_node_title);
$page->pressButton('Save');
// Assert title validation fires on Inline Entity Form widget.
$assert_session->pageTextNotContains('IEF simple single Host Validation Node has been created.');
// Assert that we're still on form due to to validation error.
$this->assertSession()->addressEquals('node/add/ief_simple_single');
$child_title = 'Child node ' . $this->randomString();
$assert_session->elementExists('xpath', $nested_title_field_xpath)->setValue($child_title);
$assert_session->elementExists('xpath', $positive_int_field_xpath)->setValue(-1);
$page->pressButton('Save');
// Assert field validation fires on Inline Entity Form widget.
$assert_session->pageTextNotContains('IEF simple single Host Validation Node has been created.');
// Assert that we're still on form due to to validation error.
$this->assertSession()->addressEquals('node/add/ief_simple_single');
$assert_session->elementExists('xpath', $positive_int_field_xpath)->setValue(1);
$page->pressButton('Save');
// Assert title validation passes on Inline Entity Form widget.
$assert_session->pageTextNotContains('Title field is required.');
// Assert field validation fires on Inline Entity Form widget.
$assert_session->pageTextNotContains('Positive int must be higher than or equal to 1');
$assert_session->pageTextContains('IEF simple single Host Validation Node has been created.');
// Check that nodes were created correctly.
$host_node = $this->getNodeByTitle($host_node_title);
$this->assertNotNull($host_node, 'Host node created.');
if (isset($host_node)) {
// Assert that address is the canonical page after node add.
$this->assertSession()
->addressEquals($host_node->toUrl('canonical', ['absolute' => TRUE])
->toString());
$child_node = $this->getNodeByTitle($child_title);
$this->assertNotNull($child_node);
if (isset($child_node)) {
$this->assertSame($host_node->single[0]->target_id, $child_node->id(), 'Child node is referenced');
$this->assertSame($child_node->positive_int[0]->value, '1', 'Child node int field correct.');
$this->assertSame($child_node->bundle(), 'ief_test_custom', 'Child node is correct bundle.');
}
}
}
/**
* Tests if the entity create access works in the simple widget.
*/
public function testSimpleCreateAccess() {
// Get the xpath selectors for the fields in this test.
$nested_title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 2);
$assert_session = $this->assertSession();
// Create a user who does not have access to create ief_test_custom nodes.
$this->drupalLogin($this->createUser([
'create ief_simple_single content',
]));
$this->drupalGet('node/add/ief_simple_single');
$assert_session->elementNotExists('xpath', $nested_title_field_xpath);
// Now test with a user has access to create ief_test_custom nodes.
$this->drupalLogin($this->user);
$this->drupalGet('node/add/ief_simple_single');
$assert_session->elementExists('xpath', $nested_title_field_xpath);
}
/**
* Ensures that an entity without bundles can be used with the simple widget.
*/
public function testEntityWithoutBundle() {
// Get the xpath selectors for the fields in this test.
$title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 1);
$name_field_xpath = $this->getXpathForNthInputByLabelText('Name', 1);
$assert_session = $this->assertSession();
$page = $this->getSession()->getPage();
$this->drupalLogin($this->user);
$this->drupalGet('node/add/ief_simple_entity_no_bundle');
$assert_session->elementExists('xpath', $title_field_xpath)->setValue('Node title');
$assert_session->elementExists('xpath', $name_field_xpath)->setValue('Entity title');
$page->pressButton('Save');
$assert_session->pageTextContains('IEF simple entity no bundle Node title has been created.');
$this->assertNodeByTitle('Node title', 'ief_simple_entity_no_bundle');
$this->assertEntityByLabel('Entity title', 'entity_test__without_bundle');
}
/**
* Tests that user only has access to the their own nodes.
*
* @param \Drupal\node\NodeInterface $host_node
* The node of the type of ief_simple_single.
* @param int $number_of_items
* The number of entity reference values in the "single" field.
* @param int $cardinality
* The field cardinality with which to check.
*/
protected function checkEditAccess(NodeInterface $host_node, int $number_of_items, int $cardinality) {
$assert_session = $this->assertSession();
$page = $this->getSession()->getPage();
$other_user = $this->createUser([
'edit own ief_test_custom content',
'edit any ief_simple_single content',
]);
$first_child_node = $host_node->single[0]->entity;
$first_child_node->setOwner($other_user)->save();
$this->drupalGet("node/{$host_node->id()}/edit");
$assert_session->pageTextContains($first_child_node->label());
// Assert the form of child node without edit access is not found.
$assert_session->fieldNotExists('single[0][inline_entity_form][title][0][value]');
// Check that the forms for other child nodes (if any) appear on the form.
// If $number_of_items is greater than one, iterate through the other
// fields that should appear on the page.
$delta = 1;
while ($delta < $number_of_items) {
$child_node = $host_node->single[$delta]->entity;
// Assert the form of child node with edit access is found.
$delta_field = $assert_session->fieldExists("single[$delta][inline_entity_form][title][0][value]");
$this->assertStringContainsString($child_node->label(), $delta_field->getValue());
$delta++;
}
// Check that there is NOT an extra "add" form when editing.
$unexpected_item_number = $number_of_items;
// Assert no empty "add" entity form is found on edit.
$assert_session->fieldNotExists("single[$unexpected_item_number][inline_entity_form][title][0][value]");
if ($cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) {
$next_item_number = $number_of_items;
$page->pressButton('Add another item');
// Assert item $next_item_number does appear after 'Add More'
// clicked.
$this->assertNotEmpty($assert_session->waitForField("single[$next_item_number][inline_entity_form][title][0][value]"));
// Make sure only 1 item is added.
$unexpected_item_number = $next_item_number + 1;
// Assert extra item $unexpected_item_number is not added after
// 'Add More' clicked.
$assert_session->fieldNotExists("single[$unexpected_item_number][inline_entity_form][title][0][value]");
}
// Now that we have confirmed the correct fields appear, let's update the
// values and save them. We do not have access to the form for delta 0
// because it is owned by another user.
$delta = 1;
$new_titles = [];
$edit = [];
// Loop through an update all child node titles.
while ($delta < $number_of_items) {
/** @var \Drupal\node\Entity\Node $child_node */
$child_node = $host_node->single[$delta]->entity;
$new_titles[$delta] = $child_node->label() . ' - updated';
$edit["single[$delta][inline_entity_form][title][0][value]"] = $new_titles[$delta];
$delta++;
}
// If cardinality equals CARDINALITY_UNLIMITED then we should have 1 extra
// form open.
if ($cardinality === FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) {
$new_titles[$delta] = 'Title for new child';
$edit["single[$delta][inline_entity_form][title][0][value]"] = $new_titles[$delta];
}
$this->submitForm($edit, 'Save');
$assert_session->pageTextContains("IEF simple single {$host_node->label()} has been updated.");
// Reset cache for nodes.
$node_ids = [$host_node->id()];
foreach ($host_node->single as $item) {
$node_ids[] = $item->entity->id();
}
$this->container
->get('entity_type.manager')
->getStorage('node')
->resetCache($node_ids);
$host_node = Node::load($host_node->id());
// Check that titles were updated.
foreach ($new_titles as $delta => $new_title) {
$child_node = $host_node->single[$delta]->entity;
$this->assertSame($new_title, $child_node->label(), "Child $delta node title has been updated.");
}
}
}

View File

@@ -0,0 +1,167 @@
<?php
namespace Drupal\Tests\inline_entity_form\FunctionalJavascript;
use Drupal\node\Entity\Node;
/**
* Tests translating inline entities.
*
* @group inline_entity_form
*/
class TranslationTest extends InlineEntityFormTestBase {
/**
* Modules to enable.
*
* @var array
*/
protected static $modules = [
'content_translation',
'inline_entity_form_translation_test',
'language',
];
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->user = $this->createUser([
'create ief_reference_type content',
'edit any ief_reference_type content',
'delete any ief_reference_type content',
'create ief_test_complex content',
'edit any ief_test_complex content',
'delete any ief_test_complex content',
'view own unpublished content',
'administer content translation',
'translate any entity',
'create content translations',
'administer languages',
]);
$this->drupalLogin($this->user);
// Allow referencing existing entities.
$form_display_storage = $this->container->get('entity_type.manager')->getStorage('entity_form_display');
/** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $display */
$display = $form_display_storage->load('node.ief_test_complex.default');
$component = $display->getComponent('multi');
$component['settings']['allow_existing'] = TRUE;
$display->setComponent('multi', $component)->save();
}
/**
* Tests translating inline entities.
*/
public function testTranslation() {
// Get the xpath selectors for the fields in this test.
$first_nested_title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 2);
$first_name_field_xpath = $this->getXpathForNthInputByLabelText('First name', 1);
$last_name_field_xpath = $this->getXpathForNthInputByLabelText('Last name', 1);
$assert_session = $this->assertSession();
$page = $this->getSession()->getPage();
// Create a German node with a French translation.
$first_inline_node = Node::create([
'type' => 'ief_reference_type',
'langcode' => 'de',
'title' => 'Kann ein Känguru höher als ein Haus springen?',
'first_name' => 'Dieter',
]);
$translation = $first_inline_node->toArray();
$translation['title'][0]['value'] = "Un kangourou peut-il sauter plus haut qu'une maison?";
$translation['first_name'][0]['value'] = 'Pierre';
$first_inline_node->addTranslation('fr', $translation);
$first_inline_node->save();
$this->drupalGet('node/add/ief_test_complex');
$multi_fieldset = $assert_session->elementExists('css', 'fieldset[data-drupal-selector="edit-multi"]');
$multi_fieldset->pressButton('Add existing node');
// Reference the German node.
$this->assertNotEmpty($field = $assert_session->waitForElement('xpath', $this->getXpathForAutoCompleteInput()));
$field->setValue('Kann ein Känguru höher als ein Haus springen? (' . $first_inline_node->id() . ')');
$page->pressButton('Add node');
$this->waitForRowByTitle('Kann ein Känguru höher als ein Haus springen?');
// Add a new English inline node.
$multi_fieldset->pressButton('Add new node');
$this->assertNotEmpty($create_button = $assert_session->waitForButton('Create node'));
$assert_session->elementExists('xpath', $first_nested_title_field_xpath)->setValue('Can a kangaroo jump higher than a house?');
$assert_session->elementExists('xpath', $first_name_field_xpath)->setValue('John');
$assert_session->elementExists('xpath', $last_name_field_xpath)->setValue('Smith');
$create_button->press();
$this->waitForRowByTitle('Can a kangaroo jump higher than a house?');
$this->assertRowByTitle('Kann ein Känguru höher als ein Haus springen?');
$assert_session->elementsCount('css', 'tr.ief-row-entity', 2);
$page->fillField('title[0][value]', 'A node');
$page->selectFieldOption('langcode[0][value]', 'en');
$page->pressButton('Save');
$assert_session->pageTextContains('IEF test complex A node has been created.');
// Both inline nodes should now be in English.
$first_inline_node = $this->drupalGetNodeByTitle('Kann ein Känguru höher als ein Haus springen?');
$second_inline_node = $this->drupalGetNodeByTitle('Can a kangaroo jump higher than a house?');
$this->assertSame('en', $first_inline_node->get('langcode')->value, 'The first inline entity has the correct langcode.');
$this->assertEquals('en', $second_inline_node->get('langcode')->value, 'The second inline entity has the correct langcode.');
// Edit the parent node and change the source language to German.
$node = $this->drupalGetNodeByTitle('A node');
$this->drupalGet('node/' . $node->id() . '/edit');
$page->selectFieldOption('langcode[0][value]', 'de');
$page->pressButton('Save');
// Both inline nodes should now be in German.
$first_inline_node = $this->drupalGetNodeByTitle('Kann ein Känguru höher als ein Haus springen?', TRUE);
$second_inline_node = $this->drupalGetNodeByTitle('Can a kangaroo jump higher than a house?', TRUE);
$this->assertSame('de', $first_inline_node->get('langcode')->value, 'The first inline entity has the correct langcode.');
$this->assertSame('de', $second_inline_node->get('langcode')->value, 'The second inline entity has the correct langcode.');
// Add a German -> French translation of the parent node.
$this->drupalGet('node/' . $node->id() . '/translations/add/de/fr');
$assert_session->elementTextContains('xpath', '//fieldset[@id="edit-multi"]/legend/span', 'Multiple nodes');
// Confirm that the add and remove buttons are not present.
$multi_fieldset = $assert_session->elementExists('css', 'fieldset[data-drupal-selector="edit-multi"]');
$this->assertEquals(FALSE, $multi_fieldset->hasButton('Add new node'));
$this->assertEquals(FALSE, $multi_fieldset->hasButton('Remove'));
// Confirm the presence of the two node titles, in the expected languages.
$first_reference = $this->assertRowByTitle("Un kangourou peut-il sauter plus haut qu'une maison?");
$second_reference = $this->assertRowByTitle('Can a kangaroo jump higher than a house?');
$assert_session->elementsCount('css', 'tr.ief-row-entity', 2);
// Edit the first referenced translation.
$first_reference->getParent()->pressButton('Edit');
$this->assertNotEmpty($update_button = $assert_session->waitForButton('Update node'));
$assert_session->elementExists('xpath', $first_nested_title_field_xpath)->setValue("Un kangourou peut-il sauter plus haut qu'une maison? - mis à jour");
$assert_session->elementExists('xpath', $first_name_field_xpath)->setValue('Damien');
$update_button->press();
$this->waitForRowByTitle("Un kangourou peut-il sauter plus haut qu'une maison? - mis à jour");
// Edit the second referenced translation.
$second_reference->getParent()->pressButton('Edit');
$this->assertNotEmpty($update_button = $assert_session->waitForButton('Update node'));
$assert_session->elementExists('xpath', $first_nested_title_field_xpath)->setValue('tous les animaux qui sautent');
$assert_session->elementExists('xpath', $first_name_field_xpath)->setValue('Jacques');
$update_button->press();
$this->waitForRowByTitle('tous les animaux qui sautent');
$page->pressButton('Save (this translation)');
$assert_session->pageTextContains('IEF test complex A node has been updated.');
// Load using the original titles, confirming they haven't changed.
$first_inline_node = $this->drupalGetNodeByTitle('Kann ein Känguru höher als ein Haus springen?', TRUE);
$second_inline_node = $this->drupalGetNodeByTitle('Can a kangaroo jump higher than a house?', TRUE);
// Confirm that the expected translated values are present.
$this->assertEquals(TRUE, $first_inline_node->hasTranslation('fr'), 'The first inline entity has a FR translation');
$this->assertEquals(TRUE, $second_inline_node->hasTranslation('fr'), 'The second inline entity has a FR translation');
$first_translation = $first_inline_node->getTranslation('fr');
$this->assertSame("Un kangourou peut-il sauter plus haut qu'une maison? - mis à jour", $first_translation->title->value);
$this->assertSame('Damien', $first_translation->first_name->value);
$second_translation = $second_inline_node->getTranslation('fr');
$this->assertEquals('tous les animaux qui sautent', $second_translation->title->value);
$this->assertSame('Jacques', $second_translation->first_name->value);
}
}

View File

@@ -0,0 +1,106 @@
<?php
namespace Drupal\Tests\inline_entity_form\Kernel\Migrate;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\FieldConfigInterface;
/**
* Tests migration of inline_entity_form field instances.
*
* @group inline_entity_form
*/
class MigrateFieldInstanceTest extends MigrateTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = [
'inline_entity_form',
'node',
'text',
];
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->installConfig('node');
$this->executeMigrations([
'd7_node_type',
'd7_field',
'd7_field_instance',
]);
}
/**
* Asserts various aspects of a field config entity.
*
* @param string $id
* The entity ID in the form ENTITY_TYPE.BUNDLE.FIELD_NAME.
* @param string $expected_label
* The expected field label.
* @param string $expected_field_type
* The expected field type.
* @param bool $is_required
* Whether or not the field is required.
* @param bool $expected_translatable
* Whether or not the field is expected to be translatable.
*/
protected function assertEntity($id, $expected_label, $expected_field_type, $is_required, $expected_translatable) {
[$expected_entity_type, $expected_bundle, $expected_name] = explode('.', $id);
/** @var \Drupal\field\FieldConfigInterface $field */
$field = FieldConfig::load($id);
$this->assertInstanceOf(FieldConfigInterface::class, $field);
$this->assertEquals($expected_label, $field->label());
$this->assertEquals($expected_field_type, $field->getType());
$this->assertEquals($expected_entity_type, $field->getTargetEntityTypeId());
$this->assertEquals($expected_bundle, $field->getTargetBundle());
$this->assertEquals($expected_name, $field->getName());
$this->assertEquals($is_required, $field->isRequired());
$this->assertEquals($expected_entity_type . '.' . $expected_name, $field->getFieldStorageDefinition()->id());
$this->assertEquals($expected_translatable, $field->isTranslatable());
}
/**
* Asserts the settings of an entity reference field config entity.
*
* @param string $id
* The entity ID in the form ENTITY_TYPE.BUNDLE.FIELD_NAME.
* @param string[] $target_bundles
* An array of expected target bundles.
* @param string[] $sort
* An array of expected sort parameters.
*/
protected function assertEntityReferenceFields($id, array $target_bundles, array $sort) {
$field = FieldConfig::load($id);
$handler_settings = $field->getSetting('handler_settings');
$this->assertArrayHasKey('target_bundles', $handler_settings);
foreach ($handler_settings['target_bundles'] as $target_bundle) {
$this->assertContains($target_bundle, $target_bundles);
}
$this->assertArrayHasKey('sort', $handler_settings);
$this->assertSame($sort, $handler_settings['sort']);
}
/**
* Tests migrating D7 field instances to field_config entities.
*/
public function testFieldInstances() {
$this->assertEntity('node.test.body', 'Body', 'text_with_summary', FALSE, FALSE);
$this->assertEntity('node.test.field_single', 'single', 'entity_reference', FALSE, FALSE);
$this->assertEntity('node.test.field_multiple', 'multiple', 'entity_reference', FALSE, FALSE);
$this->assertEntityReferenceFields(
'node.test.field_single',
['page'], ['field' => 'language', 'direction' => 'DESC']
);
$this->assertEntityReferenceFields(
'node.test.field_multiple',
['page', 'test'], ['field' => '_none', 'direction' => 'ASC']
);
}
}

View File

@@ -0,0 +1,86 @@
<?php
namespace Drupal\Tests\inline_entity_form\Kernel\Migrate;
use Drupal\Core\Entity\Display\EntityFormDisplayInterface;
use Drupal\Core\Entity\Entity\EntityFormDisplay;
/**
* Tests migration of inline_entity_form widgets settings.
*
* @group inline_entity_form
*/
class MigrateFieldInstanceWidgetSettingsTest extends MigrateTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = [
'inline_entity_form',
'node',
'text',
];
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->installConfig('node');
$this->installEntitySchema('node');
$this->executeMigrations([
'd7_node_type',
'd7_field',
'd7_field_instance',
'd7_field_instance_widget_settings',
]);
}
/**
* Asserts various aspects of a form display entity.
*
* @param string $id
* The entity ID.
* @param string $expected_entity_type
* The expected entity type to which the display settings are attached.
* @param string $expected_bundle
* The expected bundle to which the display settings are attached.
*/
protected function assertEntity($id, $expected_entity_type, $expected_bundle) {
/** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $entity */
$entity = EntityFormDisplay::load($id);
$this->assertInstanceOf(EntityFormDisplayInterface::class, $entity);
$this->assertSame($expected_entity_type, $entity->getTargetEntityTypeId());
$this->assertSame($expected_bundle, $entity->getTargetBundle());
}
/**
* Asserts various aspects of a particular component of a form display.
*
* @param string $display_id
* The form display ID.
* @param string $component_id
* The component ID.
* @param string $widget_type
* The expected widget type.
* @param string $weight
* The expected weight of the component.
*/
protected function assertComponent($display_id, $component_id, $widget_type, $weight) {
$component = EntityFormDisplay::load($display_id)->getComponent($component_id);
$this->assertIsArray($component);
$this->assertSame($widget_type, $component['type']);
$this->assertSame($weight, $component['weight']);
}
/**
* Test that migrated view modes can be loaded using D8 APIs.
*/
public function testWidgetSettings() {
$this->assertEntity('node.test.default', 'node', 'test');
$this->assertComponent('node.test.default', 'body', 'text_textarea_with_summary', -4);
$this->assertComponent('node.test.default', 'field_single', 'inline_entity_form_simple', -3);
$this->assertComponent('node.test.default', 'field_multiple', 'inline_entity_form_complex', -2);
}
}

View File

@@ -0,0 +1,77 @@
<?php
namespace Drupal\Tests\inline_entity_form\Kernel\Migrate;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\field\FieldStorageConfigInterface;
/**
* Tests migration of inline_entity_form fields.
*
* @group inline_entity_form
*/
class MigrateFieldTest extends MigrateTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = [
'node',
'text',
];
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->executeMigration('d7_field');
}
/**
* Asserts various aspects of a field_storage_config entity.
*
* @param string $id
* The entity ID in the form ENTITY_TYPE.FIELD_NAME.
* @param string $expected_type
* The expected field type.
* @param bool $expected_translatable
* Whether or not the field is expected to be translatable.
* @param int $expected_cardinality
* The expected cardinality of the field.
*/
protected function assertEntity($id, $expected_type, $expected_translatable, $expected_cardinality) {
[$expected_entity_type, $expected_name] = explode('.', $id);
/** @var \Drupal\field\FieldStorageConfigInterface $field */
$field = FieldStorageConfig::load($id);
$this->assertInstanceOf(FieldStorageConfigInterface::class, $field);
$this->assertEquals($expected_name, $field->getName());
$this->assertEquals($expected_type, $field->getType());
$this->assertEquals($expected_translatable, $field->isTranslatable());
$this->assertEquals($expected_entity_type, $field->getTargetEntityTypeId());
if ($expected_cardinality === 1) {
$this->assertFalse($field->isMultiple());
}
else {
$this->assertTrue($field->isMultiple());
}
$this->assertEquals($expected_cardinality, $field->getCardinality());
}
/**
* Tests migrating D7 fields to field_storage_config entities.
*/
public function testFields() {
$this->assertEntity('node.body', 'text_with_summary', TRUE, 1);
$this->assertEntity('node.field_single', 'entity_reference', TRUE, 1);
$this->assertEntity('node.field_multiple', 'entity_reference', TRUE, 1);
$field = FieldStorageConfig::load('node.field_single');
$this->assertEquals('node', $field->getSetting('target_type'));
$field = FieldStorageConfig::load('node.field_multiple');
$this->assertEquals('node', $field->getSetting('target_type'));
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Drupal\Tests\inline_entity_form\Kernel\Migrate;
use Drupal\Tests\migrate_drupal\Kernel\MigrateDrupalTestBase;
/**
* Base class for migration tests.
*/
abstract class MigrateTestBase extends MigrateDrupalTestBase {
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->loadFixture($this->getFixtureFilePath());
}
/**
* Gets the path to the fixture file.
*/
protected function getFixtureFilePath() {
return __DIR__ . '/../../../fixtures/drupal7-small.php';
}
}