From 68cae355c1b336b9b4297e89f6ce50b45220e96b Mon Sep 17 00:00:00 2001
From: Axel Rutz <axel.rutz@machbarmacher.net>
Date: Sun, 16 Jun 2019 01:19:02 +0200
Subject: [PATCH] Issue #2367235 by axel.rutz, dawehner, Les Lim, harings_rob,
 webflo, lwalley, Arlina, m4olivei, sylus, frega, Jacine: Support entity
 revision references

---
 src/Element/InlineEntityForm.php              |  16 ++-
 src/Form/EntityInlineForm.php                 |  13 ++
 .../FieldWidget/InlineEntityFormBase.php      |  14 ++-
 .../FieldWidget/InlineEntityFormComplex.php   |   3 +-
 .../FieldWidget/InlineEntityFormSimple.php    |   3 +-
 src/Tests/ComplexWidgetRevisionsWebTest.php   | 115 ++++++++++++++++++
 ...ield_override.node.err_level_1.promote.yml |  21 ++++
 ...ield_override.node.err_level_2.promote.yml |  21 ++++
 ...ield_override.node.err_level_3.promote.yml |  21 ++++
 ..._form_display.node.err_level_1.default.yml |  38 ++++++
 ..._form_display.node.err_level_2.default.yml |  38 ++++++
 ..._form_display.node.err_level_3.default.yml |  23 ++++
 ..._view_display.node.err_level_1.default.yml |  25 ++++
 ...y_view_display.node.err_level_1.teaser.yml |  16 +++
 ..._view_display.node.err_level_2.default.yml |  25 ++++
 ...y_view_display.node.err_level_2.teaser.yml |  16 +++
 ..._view_display.node.err_level_3.default.yml |  15 +++
 ...y_view_display.node.err_level_3.teaser.yml |  16 +++
 ...d.node.err_level_1.field_level_2_items.yml |  29 +++++
 ...d.node.err_level_2.field_level_3_items.yml |  29 +++++
 ...field.storage.node.field_level_2_items.yml |  19 +++
 ...field.storage.node.field_level_3_items.yml |  19 +++
 .../config/optional/node.type.err_level_1.yml |   9 ++
 .../config/optional/node.type.err_level_2.yml |   9 ++
 .../config/optional/node.type.err_level_3.yml |   9 ++
 25 files changed, 558 insertions(+), 4 deletions(-)
 create mode 100644 src/Tests/ComplexWidgetRevisionsWebTest.php
 create mode 100644 tests/modules/inline_entity_form_test/config/optional/core.base_field_override.node.err_level_1.promote.yml
 create mode 100644 tests/modules/inline_entity_form_test/config/optional/core.base_field_override.node.err_level_2.promote.yml
 create mode 100644 tests/modules/inline_entity_form_test/config/optional/core.base_field_override.node.err_level_3.promote.yml
 create mode 100644 tests/modules/inline_entity_form_test/config/optional/core.entity_form_display.node.err_level_1.default.yml
 create mode 100644 tests/modules/inline_entity_form_test/config/optional/core.entity_form_display.node.err_level_2.default.yml
 create mode 100644 tests/modules/inline_entity_form_test/config/optional/core.entity_form_display.node.err_level_3.default.yml
 create mode 100644 tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_1.default.yml
 create mode 100644 tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_1.teaser.yml
 create mode 100644 tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_2.default.yml
 create mode 100644 tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_2.teaser.yml
 create mode 100644 tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_3.default.yml
 create mode 100644 tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_3.teaser.yml
 create mode 100644 tests/modules/inline_entity_form_test/config/optional/field.field.node.err_level_1.field_level_2_items.yml
 create mode 100644 tests/modules/inline_entity_form_test/config/optional/field.field.node.err_level_2.field_level_3_items.yml
 create mode 100644 tests/modules/inline_entity_form_test/config/optional/field.storage.node.field_level_2_items.yml
 create mode 100644 tests/modules/inline_entity_form_test/config/optional/field.storage.node.field_level_3_items.yml
 create mode 100644 tests/modules/inline_entity_form_test/config/optional/node.type.err_level_1.yml
 create mode 100644 tests/modules/inline_entity_form_test/config/optional/node.type.err_level_2.yml
 create mode 100644 tests/modules/inline_entity_form_test/config/optional/node.type.err_level_3.yml

diff --git a/src/Element/InlineEntityForm.php b/src/Element/InlineEntityForm.php
index 0fbe233..d95197c 100644
--- a/src/Element/InlineEntityForm.php
+++ b/src/Element/InlineEntityForm.php
@@ -3,6 +3,8 @@
 namespace Drupal\inline_entity_form\Element;
 
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\RevisionableEntityBundleInterface;
+use Drupal\Core\Entity\RevisionLogInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\Element;
 use Drupal\Core\Render\Element\RenderElement;
@@ -45,6 +47,8 @@ class InlineEntityForm extends RenderElement {
       '#default_value' => NULL,
       // The form mode used to display the entity form.
       '#form_mode' => 'default',
+      // Will create a new revision if set to TRUE.
+      '#revision' => FALSE,
       // Will save entity on submit if set to TRUE.
       '#save_entity' => TRUE,
       // 'add', 'edit' or 'duplicate'.
@@ -97,6 +101,7 @@ class InlineEntityForm extends RenderElement {
       throw new \InvalidArgumentException('The inline_entity_form #default_value property must be an entity object.');
     }
 
+    $entity_type = \Drupal::entityTypeManager()->getDefinition($entity_form['#entity_type']);
     if (empty($entity_form['#ief_id'])) {
       $entity_form['#ief_id'] = \Drupal::service('uuid')->generate();
     }
@@ -106,7 +111,6 @@ class InlineEntityForm extends RenderElement {
     }
     else {
       // This is an add operation, create a new entity.
-      $entity_type = \Drupal::entityTypeManager()->getDefinition($entity_form['#entity_type']);
       $storage = \Drupal::entityTypeManager()->getStorage($entity_form['#entity_type']);
       $values = [];
       if ($langcode_key = $entity_type->getKey('langcode')) {
@@ -132,6 +136,16 @@ class InlineEntityForm extends RenderElement {
     $entity_form['#entity'] = TranslationHelper::prepareEntity($entity_form['#entity'], $form_state);
     $entity_form['#translating'] = TranslationHelper::isTranslating($form_state) && $entity_form['#entity']->isTranslatable();
 
+    // Set revision property if settings say so.
+    // @see \Drupal\Core\Entity\ContentEntityForm::addRevisionableFormFields
+    $new_revision = $entity_form['#revision'];
+    $entity_form['#entity']->setNewRevision($new_revision);
+    // @see \Drupal\Core\Entity\ContentEntityForm::buildEntity
+    if ($new_revision && $entity_form['#entity'] instanceof RevisionLogInterface) {
+      $entity_form['#entity']->setRevisionUserId(\Drupal::currentUser()->id());
+      $entity_form['#entity']->setRevisionCreationTime(\Drupal::time()->getRequestTime());
+    }
+
     $inline_form_handler = static::getInlineFormHandler($entity_form['#entity_type']);
     $entity_form = $inline_form_handler->entityForm($entity_form, $form_state);
     // The form element can't rely on inline_entity_form_form_alter() calling
diff --git a/src/Form/EntityInlineForm.php b/src/Form/EntityInlineForm.php
index 1ff5073..9bd26eb 100644
--- a/src/Form/EntityInlineForm.php
+++ b/src/Form/EntityInlineForm.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\inline_entity_form\Form;
 
+use Drupal\Component\Utility\DiffArray;
 use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\Core\Entity\Entity\EntityFormDisplay;
 use Drupal\Core\Entity\EntityInterface;
@@ -255,7 +256,19 @@ class EntityInlineForm implements InlineFormInterface {
     $form_state->cleanValues();
     /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
     $entity = $entity_form['#entity'];
+    $original_values = $entity->toArray();
     $this->buildEntity($entity_form, $entity, $form_state);
+    $current_values = $entity->toArray();
+    // Mark this entity for saving only if its values have changed.
+    // The entity changed flag that we add here is extracted in
+    // InlineEntityFormBase::submitSaveEntity and triggers saving in
+    // WidgetSubmit::doSubmit.
+    // Saving is not done in InlineEntityForm::submitEntityForm (it looks like
+    // the check of $entity_form['#save_entity'] is dead code).
+    // @todo Use EntityChangedAPI once this lands in
+    // @see https://www.drupal.org/project/drupal/issues/2862574
+    $entity_changed = (bool) DiffArray::diffAssocRecursive($original_values, $current_values);
+    $entity->_inline_entity_form_entity_changed = $entity_changed;
   }
 
   /**
diff --git a/src/Plugin/Field/FieldWidget/InlineEntityFormBase.php b/src/Plugin/Field/FieldWidget/InlineEntityFormBase.php
index 5598be4..af0e1b4 100644
--- a/src/Plugin/Field/FieldWidget/InlineEntityFormBase.php
+++ b/src/Plugin/Field/FieldWidget/InlineEntityFormBase.php
@@ -190,6 +190,7 @@ abstract class InlineEntityFormBase extends WidgetBase implements ContainerFacto
   public static function defaultSettings() {
     return [
       'form_mode' => 'default',
+      'revision' => FALSE,
       'override_labels' => FALSE,
       'label_singular' => '',
       'label_plural' => '',
@@ -212,6 +213,11 @@ abstract class InlineEntityFormBase extends WidgetBase implements ContainerFacto
       '#options' => $this->entityDisplayRepository->getFormModeOptions($entity_type_id),
       '#required' => TRUE,
     ];
+    $element['revision'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Create new revision'),
+      '#default_value' => $this->getSetting('revision'),
+    ];
     $element['override_labels'] = [
       '#type' => 'checkbox',
       '#title' => $this->t('Override labels'),
@@ -278,6 +284,10 @@ abstract class InlineEntityFormBase extends WidgetBase implements ContainerFacto
       $summary[] = $this->t('Default labels are used.');
     }
 
+    if ($this->getSetting('revision')) {
+      $summary[] = $this->t('Create new revision');
+    }
+
     if ($this->getSetting('collapsible')) {
       $summary[] = $this->t($this->getSetting('collapsed') ? 'Collapsible, collapsed by default' : 'Collapsible');
     }
@@ -395,6 +405,7 @@ abstract class InlineEntityFormBase extends WidgetBase implements ContainerFacto
       '#default_value' => $entity,
       '#op' => $operation,
       '#form_mode' => $this->getSetting('form_mode'),
+      '#revision' => $this->getSetting('revision'),
       '#save_entity' => FALSE,
       '#ief_row_delta' => $delta,
       // Used by Field API and controller methods to find the relevant
@@ -502,7 +513,8 @@ abstract class InlineEntityFormBase extends WidgetBase implements ContainerFacto
       $delta = $entity_form['#ief_row_delta'];
       $entities = $form_state->get(['inline_entity_form', $ief_id, 'entities']);
       $entities[$delta]['entity'] = $entity;
-      $entities[$delta]['needs_save'] = TRUE;
+      // @see \Drupal\inline_entity_form\Form\EntityInlineForm::entityFormSubmit
+      $entities[$delta]['needs_save'] = !empty($entity->_inline_entity_form_entity_changed);
       $form_state->set(['inline_entity_form', $ief_id, 'entities'], $entities);
     }
   }
diff --git a/src/Plugin/Field/FieldWidget/InlineEntityFormComplex.php b/src/Plugin/Field/FieldWidget/InlineEntityFormComplex.php
index 6d00451..71e8374 100644
--- a/src/Plugin/Field/FieldWidget/InlineEntityFormComplex.php
+++ b/src/Plugin/Field/FieldWidget/InlineEntityFormComplex.php
@@ -25,7 +25,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
  *   id = "inline_entity_form_complex",
  *   label = @Translation("Inline entity form - Complex"),
  *   field_types = {
- *     "entity_reference"
+ *     "entity_reference",
+ *     "entity_reference_revisions",
  *   },
  *   multiple_values = true
  * )
diff --git a/src/Plugin/Field/FieldWidget/InlineEntityFormSimple.php b/src/Plugin/Field/FieldWidget/InlineEntityFormSimple.php
index cc19ae8..a654660 100644
--- a/src/Plugin/Field/FieldWidget/InlineEntityFormSimple.php
+++ b/src/Plugin/Field/FieldWidget/InlineEntityFormSimple.php
@@ -18,7 +18,8 @@ use Drupal\inline_entity_form\TranslationHelper;
  *   id = "inline_entity_form_simple",
  *   label = @Translation("Inline entity form - Simple"),
  *   field_types = {
- *     "entity_reference"
+ *     "entity_reference",
+ *     "entity_reference_revisions",
  *   },
  *   multiple_values = false
  * )
diff --git a/src/Tests/ComplexWidgetRevisionsWebTest.php b/src/Tests/ComplexWidgetRevisionsWebTest.php
new file mode 100644
index 0000000..c24b9dd
--- /dev/null
+++ b/src/Tests/ComplexWidgetRevisionsWebTest.php
@@ -0,0 +1,115 @@
+<?php
+
+namespace Drupal\inline_entity_form\Tests;
+use Drupal\Component\Utility\SafeMarkup;
+use Drupal\Core\Extension\MissingDependencyException;
+
+/**
+ * IEF complex entity reference revisions tests.
+ *
+ * @group inline_entity_form
+ */
+class ComplexWidgetRevisionsWebTest extends InlineEntityFormTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = [
+    'field',
+    'field_ui',
+    'entity_reference_revisions',
+    'inline_entity_form_test',
+  ];
+
+  /**
+   * URL to add new content.
+   *
+   * @var string
+   */
+  protected $formContentAddUrl;
+
+  /**
+   * Prepares environment for
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->user = $this->createUser([
+      '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',
+      'administer content types',
+    ]);
+    $this->drupalLogin($this->user);
+
+    $this->formContentAddUrl = 'node/add/err_level_1';
+  }
+
+  /**
+   * Tests saving entity reference revisions' field types at depth.
+   */
+  public function testRevisionsAtDepth() {
+    $this->drupalGet($this->formContentAddUrl);
+
+    // Open up level 2 and 3 IEF forms.
+    $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @value="Add new node" and @data-drupal-selector="edit-field-level-2-items-actions-ief-add"]'));
+    $this->assertResponse(200, 'Opening level 2 items inline form was successful.');
+    $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @value="Add new node" and @data-drupal-selector="edit-field-level-2-items-form-inline-entity-form-field-level-3-items-actions-ief-add"]'));
+    $this->assertResponse(200, 'Opening level 3 items inline form was successful.');
+
+    // Save level 3 IEF form.
+    $edit = ['field_level_2_items[form][inline_entity_form][field_level_3_items][form][inline_entity_form][title][0][value]' => 'Level 3'];
+    $this->drupalPostAjaxForm(NULL, $edit, $this->getButtonName('//input[@type="submit" and @value="Create node" and @data-drupal-selector="edit-field-level-2-items-form-inline-entity-form-field-level-3-items-form-inline-entity-form-actions-ief-add-save"]'));
+    $this->assertResponse(200, 'Creating level 3 node via inline form was successful.');
+
+    // Save level 2 IEF form.
+    $edit = ['field_level_2_items[form][inline_entity_form][title][0][value]' => 'Level 2'];
+    $this->drupalPostAjaxForm(NULL, $edit, $this->getButtonName('//input[@type="submit" and @value="Create node" and @data-drupal-selector="edit-field-level-2-items-form-inline-entity-form-actions-ief-add-save"]'));
+    $this->assertResponse(200, 'Creating level 2 node via inline form was successful.');
+
+    // Save the top level entity.
+    $edit = ['title[0][value]' => 'Level 1'];
+    $this->drupalPostForm(NULL, $edit, t('Save'));
+    $this->assertResponse(200, 'Saving parent entity was successful.');
+
+    // 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.
+    $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @value="Edit" and @data-drupal-selector="edit-field-level-2-items-entities-0-actions-ief-entity-edit"]'));
+    $this->assertResponse(200, 'Opening level 2 items inline form was successful.');
+    $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @value="Edit" and @data-drupal-selector="edit-field-level-2-items-form-inline-entity-form-entities-0-form-field-level-3-items-entities-0-actions-ief-entity-edit"]'));
+    $this->assertResponse(200, 'Opening level 3 items inline form was successful.');
+
+    // Save level 3 IEF form.
+    $edit = ['field_level_2_items[form][inline_entity_form][entities][0][form][field_level_3_items][form][inline_entity_form][entities][0][form][title][0][value]' => 'Level 3.1'];
+    $this->drupalPostAjaxForm(NULL, $edit, $this->getButtonName('//input[@type="submit" and @value="Update node" and @data-drupal-selector="edit-field-level-2-items-form-inline-entity-form-entities-0-form-field-level-3-items-form-inline-entity-form-entities-0-form-actions-ief-edit-save"]'));
+    $this->assertResponse(200, 'Editing level 3 node via inline form was successful.');
+
+    // Save level 2 IEF form.
+    $edit = ['field_level_2_items[form][inline_entity_form][entities][0][form][title][0][value]' => 'Level 2.1'];
+    $this->drupalPostAjaxForm(NULL, $edit, $this->getButtonName('//input[@type="submit" and @value="Update node" and @data-drupal-selector="edit-field-level-2-items-form-inline-entity-form-entities-0-form-actions-ief-edit-save"]'));
+    $this->assertResponse(200, 'Editing level 2 node via inline form was successful.');
+
+    // Save the top level entity.
+    $edit = ['title[0][value]' => 'Level 1.1'];
+    $this->drupalPostForm(NULL, $edit, t('Save'));
+    $this->assertResponse(200, 'Saving parent entity was successful.');
+
+    // $this->drupalGet('node/' . $node->id());
+    // $this->assertText('Level 1.1', 'Top level node revision was saved and is active.');
+    // $this->assertText('Level 2.1', 'Second level node revisions was saved and is active');
+    // Issue #2721349: Nested inline entities should be saved in "inside-out" order
+    // $this->assertText('Level 3.1', 'Top level node revision was saved and is active.');
+  }
+}
diff --git a/tests/modules/inline_entity_form_test/config/optional/core.base_field_override.node.err_level_1.promote.yml b/tests/modules/inline_entity_form_test/config/optional/core.base_field_override.node.err_level_1.promote.yml
new file mode 100644
index 0000000..4ddf2df
--- /dev/null
+++ b/tests/modules/inline_entity_form_test/config/optional/core.base_field_override.node.err_level_1.promote.yml
@@ -0,0 +1,21 @@
+trimIefIdParentslangcode: en
+status: true
+dependencies:
+  config:
+    - node.type.err_level_1
+id: node.err_level_1.promote
+field_name: promote
+entity_type: node
+bundle: err_level_1
+label: 'Promoted to front page'
+description: ''
+required: false
+translatable: true
+default_value:
+  -
+    value: 0
+default_value_callback: ''
+settings:
+  on_label: 'On'
+  off_label: 'Off'
+field_type: boolean
diff --git a/tests/modules/inline_entity_form_test/config/optional/core.base_field_override.node.err_level_2.promote.yml b/tests/modules/inline_entity_form_test/config/optional/core.base_field_override.node.err_level_2.promote.yml
new file mode 100644
index 0000000..cb90dff
--- /dev/null
+++ b/tests/modules/inline_entity_form_test/config/optional/core.base_field_override.node.err_level_2.promote.yml
@@ -0,0 +1,21 @@
+trimIefIdParentslangcode: en
+status: true
+dependencies:
+  config:
+    - node.type.err_level_2
+id: node.err_level_2.promote
+field_name: promote
+entity_type: node
+bundle: err_level_2
+label: 'Promoted to front page'
+description: ''
+required: false
+translatable: true
+default_value:
+  -
+    value: 0
+default_value_callback: ''
+settings:
+  on_label: 'On'
+  off_label: 'Off'
+field_type: boolean
diff --git a/tests/modules/inline_entity_form_test/config/optional/core.base_field_override.node.err_level_3.promote.yml b/tests/modules/inline_entity_form_test/config/optional/core.base_field_override.node.err_level_3.promote.yml
new file mode 100644
index 0000000..39c23b6
--- /dev/null
+++ b/tests/modules/inline_entity_form_test/config/optional/core.base_field_override.node.err_level_3.promote.yml
@@ -0,0 +1,21 @@
+trimIefIdParentslangcode: en
+status: true
+dependencies:
+  config:
+    - node.type.err_level_3
+id: node.err_level_3.promote
+field_name: promote
+entity_type: node
+bundle: err_level_3
+label: 'Promoted to front page'
+description: ''
+required: false
+translatable: true
+default_value:
+  -
+    value: 0
+default_value_callback: ''
+settings:
+  on_label: 'On'
+  off_label: 'Off'
+field_type: boolean
diff --git a/tests/modules/inline_entity_form_test/config/optional/core.entity_form_display.node.err_level_1.default.yml b/tests/modules/inline_entity_form_test/config/optional/core.entity_form_display.node.err_level_1.default.yml
new file mode 100644
index 0000000..88114a6
--- /dev/null
+++ b/tests/modules/inline_entity_form_test/config/optional/core.entity_form_display.node.err_level_1.default.yml
@@ -0,0 +1,38 @@
+trimIefIdParentslangcode: en
+status: true
+dependencies:
+  config:
+    - field.field.node.err_level_1.field_level_2_items
+    - node.type.err_level_1
+  module:
+    - inline_entity_form
+id: node.err_level_1.default
+targetEntityType: node
+bundle: err_level_1
+mode: default
+content:
+  field_level_2_items:
+    weight: 31
+    settings:
+      match_operator: CONTAINS
+      form_mode: default
+      override_labels: false
+      label_singular: ''
+      label_plural: ''
+      allow_new: true
+      allow_existing: false
+    third_party_settings: {  }
+    type: inline_entity_form_complex
+  title:
+    type: string_textfield
+    weight: -5
+    settings:
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+hidden:
+  created: true
+  path: true
+  promote: true
+  sticky: true
+  uid: true
diff --git a/tests/modules/inline_entity_form_test/config/optional/core.entity_form_display.node.err_level_2.default.yml b/tests/modules/inline_entity_form_test/config/optional/core.entity_form_display.node.err_level_2.default.yml
new file mode 100644
index 0000000..849b2b4
--- /dev/null
+++ b/tests/modules/inline_entity_form_test/config/optional/core.entity_form_display.node.err_level_2.default.yml
@@ -0,0 +1,38 @@
+trimIefIdParentslangcode: en
+status: true
+dependencies:
+  config:
+    - field.field.node.err_level_2.field_level_3_items
+    - node.type.err_level_2
+  module:
+    - inline_entity_form
+id: node.err_level_2.default
+targetEntityType: node
+bundle: err_level_2
+mode: default
+content:
+  field_level_3_items:
+    weight: 1
+    settings:
+      match_operator: CONTAINS
+      form_mode: default
+      override_labels: false
+      label_singular: ''
+      label_plural: ''
+      allow_new: true
+      allow_existing: false
+    third_party_settings: {  }
+    type: inline_entity_form_complex
+  title:
+    type: string_textfield
+    weight: 0
+    settings:
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+hidden:
+  created: true
+  path: true
+  promote: true
+  sticky: true
+  uid: true
diff --git a/tests/modules/inline_entity_form_test/config/optional/core.entity_form_display.node.err_level_3.default.yml b/tests/modules/inline_entity_form_test/config/optional/core.entity_form_display.node.err_level_3.default.yml
new file mode 100644
index 0000000..7d94d96
--- /dev/null
+++ b/tests/modules/inline_entity_form_test/config/optional/core.entity_form_display.node.err_level_3.default.yml
@@ -0,0 +1,23 @@
+trimIefIdParentslangcode: en
+status: true
+dependencies:
+  config:
+    - node.type.err_level_3
+id: node.err_level_3.default
+targetEntityType: node
+bundle: err_level_3
+mode: default
+content:
+  title:
+    type: string_textfield
+    weight: -5
+    settings:
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+hidden:
+  created: true
+  path: true
+  promote: true
+  sticky: true
+  uid: true
diff --git a/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_1.default.yml b/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_1.default.yml
new file mode 100644
index 0000000..887fc62
--- /dev/null
+++ b/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_1.default.yml
@@ -0,0 +1,25 @@
+trimIefIdParentslangcode: en
+status: true
+dependencies:
+  config:
+    - field.field.node.err_level_1.field_level_2_items
+    - node.type.err_level_1
+  module:
+    - entity_reference_revisions
+    - user
+id: node.err_level_1.default
+targetEntityType: node
+bundle: err_level_1
+mode: default
+content:
+  field_level_2_items:
+    weight: 101
+    label: above
+    settings:
+      view_mode: default
+      link: ''
+    third_party_settings: {  }
+    type: entity_reference_revisions_entity_view
+  links:
+    weight: 100
+hidden: {  }
diff --git a/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_1.teaser.yml b/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_1.teaser.yml
new file mode 100644
index 0000000..ea334e8
--- /dev/null
+++ b/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_1.teaser.yml
@@ -0,0 +1,16 @@
+trimIefIdParentslangcode: en
+status: true
+dependencies:
+  config:
+    - core.entity_view_mode.node.teaser
+    - node.type.err_level_1
+  module:
+    - user
+id: node.err_level_1.teaser
+targetEntityType: node
+bundle: err_level_1
+mode: teaser
+content:
+  links:
+    weight: 100
+hidden: {  }
diff --git a/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_2.default.yml b/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_2.default.yml
new file mode 100644
index 0000000..7a2e001
--- /dev/null
+++ b/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_2.default.yml
@@ -0,0 +1,25 @@
+trimIefIdParentslangcode: en
+status: true
+dependencies:
+  config:
+    - field.field.node.err_level_2.field_level_3_items
+    - node.type.err_level_2
+  module:
+    - entity_reference_revisions
+    - user
+id: node.err_level_2.default
+targetEntityType: node
+bundle: err_level_2
+mode: default
+content:
+  field_level_3_items:
+    weight: 101
+    label: above
+    settings:
+      view_mode: default
+      link: ''
+    third_party_settings: {  }
+    type: entity_reference_revisions_entity_view
+  links:
+    weight: 100
+hidden: {  }
diff --git a/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_2.teaser.yml b/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_2.teaser.yml
new file mode 100644
index 0000000..8ccdf15
--- /dev/null
+++ b/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_2.teaser.yml
@@ -0,0 +1,16 @@
+trimIefIdParentslangcode: en
+status: true
+dependencies:
+  config:
+    - core.entity_view_mode.node.teaser
+    - node.type.err_level_2
+  module:
+    - user
+id: node.err_level_2.teaser
+targetEntityType: node
+bundle: err_level_2
+mode: teaser
+content:
+  links:
+    weight: 100
+hidden: {  }
diff --git a/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_3.default.yml b/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_3.default.yml
new file mode 100644
index 0000000..d3de6a5
--- /dev/null
+++ b/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_3.default.yml
@@ -0,0 +1,15 @@
+trimIefIdParentslangcode: en
+status: true
+dependencies:
+  config:
+    - node.type.err_level_3
+  module:
+    - user
+id: node.err_level_3.default
+targetEntityType: node
+bundle: err_level_3
+mode: default
+content:
+  links:
+    weight: 100
+hidden: {  }
diff --git a/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_3.teaser.yml b/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_3.teaser.yml
new file mode 100644
index 0000000..c119fd3
--- /dev/null
+++ b/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_3.teaser.yml
@@ -0,0 +1,16 @@
+trimIefIdParentslangcode: en
+status: true
+dependencies:
+  config:
+    - core.entity_view_mode.node.teaser
+    - node.type.err_level_3
+  module:
+    - user
+id: node.err_level_3.teaser
+targetEntityType: node
+bundle: err_level_3
+mode: teaser
+content:
+  links:
+    weight: 100
+hidden: {  }
diff --git a/tests/modules/inline_entity_form_test/config/optional/field.field.node.err_level_1.field_level_2_items.yml b/tests/modules/inline_entity_form_test/config/optional/field.field.node.err_level_1.field_level_2_items.yml
new file mode 100644
index 0000000..025d09c
--- /dev/null
+++ b/tests/modules/inline_entity_form_test/config/optional/field.field.node.err_level_1.field_level_2_items.yml
@@ -0,0 +1,29 @@
+trimIefIdParentslangcode: en
+status: true
+dependencies:
+  config:
+    - field.storage.node.field_level_2_items
+    - node.type.err_level_1
+    - node.type.err_level_2
+  module:
+    - entity_reference_revisions
+id: node.err_level_1.field_level_2_items
+field_name: field_level_2_items
+entity_type: node
+bundle: err_level_1
+label: 'Level 2 Items'
+description: ''
+required: false
+translatable: false
+default_value: {  }
+default_value_callback: ''
+settings:
+  handler: 'default:node'
+  handler_settings:
+    target_bundles:
+      err_level_2: err_level_2
+    sort:
+      field: _none
+    auto_create: false
+    auto_create_bundle: ''
+field_type: entity_reference_revisions
diff --git a/tests/modules/inline_entity_form_test/config/optional/field.field.node.err_level_2.field_level_3_items.yml b/tests/modules/inline_entity_form_test/config/optional/field.field.node.err_level_2.field_level_3_items.yml
new file mode 100644
index 0000000..e285cec
--- /dev/null
+++ b/tests/modules/inline_entity_form_test/config/optional/field.field.node.err_level_2.field_level_3_items.yml
@@ -0,0 +1,29 @@
+trimIefIdParentslangcode: en
+status: true
+dependencies:
+  config:
+    - field.storage.node.field_level_3_items
+    - node.type.err_level_2
+    - node.type.err_level_3
+  module:
+    - entity_reference_revisions
+id: node.err_level_2.field_level_3_items
+field_name: field_level_3_items
+entity_type: node
+bundle: err_level_2
+label: 'Level 3 Items'
+description: ''
+required: false
+translatable: false
+default_value: {  }
+default_value_callback: ''
+settings:
+  handler: 'default:node'
+  handler_settings:
+    target_bundles:
+      err_level_3: err_level_3
+    sort:
+      field: _none
+    auto_create: false
+    auto_create_bundle: ''
+field_type: entity_reference_revisions
diff --git a/tests/modules/inline_entity_form_test/config/optional/field.storage.node.field_level_2_items.yml b/tests/modules/inline_entity_form_test/config/optional/field.storage.node.field_level_2_items.yml
new file mode 100644
index 0000000..1070cc3
--- /dev/null
+++ b/tests/modules/inline_entity_form_test/config/optional/field.storage.node.field_level_2_items.yml
@@ -0,0 +1,19 @@
+trimIefIdParentslangcode: en
+status: true
+dependencies:
+  module:
+    - entity_reference_revisions
+    - node
+id: node.field_level_2_items
+field_name: field_level_2_items
+entity_type: node
+type: entity_reference_revisions
+settings:
+  target_type: node
+module: entity_reference_revisions
+locked: false
+cardinality: -1
+translatable: true
+indexes: {  }
+persist_with_no_fields: false
+custom_storage: false
diff --git a/tests/modules/inline_entity_form_test/config/optional/field.storage.node.field_level_3_items.yml b/tests/modules/inline_entity_form_test/config/optional/field.storage.node.field_level_3_items.yml
new file mode 100644
index 0000000..757c48a
--- /dev/null
+++ b/tests/modules/inline_entity_form_test/config/optional/field.storage.node.field_level_3_items.yml
@@ -0,0 +1,19 @@
+trimIefIdParentslangcode: en
+status: true
+dependencies:
+  module:
+    - entity_reference_revisions
+    - node
+id: node.field_level_3_items
+field_name: field_level_3_items
+entity_type: node
+type: entity_reference_revisions
+settings:
+  target_type: node
+module: entity_reference_revisions
+locked: false
+cardinality: -1
+translatable: true
+indexes: {  }
+persist_with_no_fields: false
+custom_storage: false
diff --git a/tests/modules/inline_entity_form_test/config/optional/node.type.err_level_1.yml b/tests/modules/inline_entity_form_test/config/optional/node.type.err_level_1.yml
new file mode 100644
index 0000000..4865eb9
--- /dev/null
+++ b/tests/modules/inline_entity_form_test/config/optional/node.type.err_level_1.yml
@@ -0,0 +1,9 @@
+trimIefIdParentslangcode: en
+status: true
+name: 'Entity Reference Revisions (Level 1)'
+type: err_level_1
+description: 'Top level content type with an entity_reference_revisions field type to another content type.'
+help: ''
+new_revision: true
+preview_mode: 1
+display_submitted: false
diff --git a/tests/modules/inline_entity_form_test/config/optional/node.type.err_level_2.yml b/tests/modules/inline_entity_form_test/config/optional/node.type.err_level_2.yml
new file mode 100644
index 0000000..289dc9d
--- /dev/null
+++ b/tests/modules/inline_entity_form_test/config/optional/node.type.err_level_2.yml
@@ -0,0 +1,9 @@
+trimIefIdParentslangcode: en
+status: true
+name: 'Entity Reference Revisions (Level 2)'
+type: err_level_2
+description: 'Second level content type with an entity_reference_revisions field type to another content type.'
+help: ''
+new_revision: true
+preview_mode: 1
+display_submitted: false
diff --git a/tests/modules/inline_entity_form_test/config/optional/node.type.err_level_3.yml b/tests/modules/inline_entity_form_test/config/optional/node.type.err_level_3.yml
new file mode 100644
index 0000000..b22f916
--- /dev/null
+++ b/tests/modules/inline_entity_form_test/config/optional/node.type.err_level_3.yml
@@ -0,0 +1,9 @@
+trimIefIdParentslangcode: en
+status: true
+name: 'Entity Reference Revisions (Level 3)'
+type: err_level_3
+description: 'Third level content type.'
+help: ''
+new_revision: true
+preview_mode: 1
+display_submitted: false
-- 
2.17.1

