From 9a02500d9b97994e9d75c084d470987eb33edb03 Mon Sep 17 00:00:00 2001 From: Brian Canini <canini.16@osu.edu> Date: Thu, 25 Jun 2020 14:28:38 -0400 Subject: [PATCH] Updating drupal/inline_entity_form (1.0.0-rc1 => 1.0.0-rc6) --- composer.json | 2 +- composer.lock | 47 +- vendor/composer/installed.json | 47 +- .../.travis-before-script.sh | 0 web/modules/inline_entity_form/README | 4 +- web/modules/inline_entity_form/composer.json | 9 +- .../schema/inline_entity_form.schema.yml | 14 +- .../css/commerce-product.css | 11 - .../css/inline_entity_form.css | 38 - .../css/inline_entity_form.seven.css | 31 - .../inline_entity_form.info.yml | 11 +- .../inline_entity_form.libraries.yml | 15 - .../js/inline_entity_form.js | 29 - .../src/Element/InlineEntityForm.php | 17 +- .../inline_entity_form/src/ElementSubmit.php | 4 +- .../src/Form/EntityInlineForm.php | 21 +- .../src/Form/NodeInlineForm.php | 12 - .../src/InlineFormInterface.php | 18 +- .../FieldWidget/InlineEntityFormBase.php | 15 +- .../FieldWidget/InlineEntityFormComplex.php | 104 +- .../FieldWidget/InlineEntityFormSimple.php | 14 +- .../src/Tests/ComplexSimpleWidgetTest.php | 111 --- .../src/Tests/ComplexWidgetWebTest.php | 780 --------------- .../src/Tests/ElementWebTest.php | 82 -- .../src/Tests/InlineEntityFormTestBase.php | 188 ---- .../src/Tests/SimpleWidgetWebTest.php | 248 ----- .../src/Tests/TranslationTest.php | 173 ---- ...isplay.node.ief_complex_simple.default.yml | 1 + ...isplay.node.ief_reference_type.default.yml | 1 + ...de.ief_simple_entity_no_bundle.default.yml | 2 +- ...display.node.ief_simple_single.default.yml | 1 + ..._display.node.ief_test_complex.default.yml | 1 + ...m_display.node.ief_test_custom.default.yml | 1 + ..._display.node.ief_test_nested1.default.yml | 1 + ..._display.node.ief_test_nested2.default.yml | 1 + ..._display.node.ief_test_nested3.default.yml | 1 + ...y_no_bundle.field_ief_entity_no_bundle.yml | 1 - ...torage.node.field_ief_entity_no_bundle.yml | 1 - .../node.type.ief_simple_entity_no_bundle.yml | 1 - ...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 | 62 ++ ..._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 | 34 + ...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 + ...level_1.field_level_2_entity_no_bundle.yml | 27 + ...d.node.err_level_1.field_level_2_items.yml | 29 + ...d.node.err_level_2.field_level_3_items.yml | 29 + ...ge.node.field_level_2_entity_no_bundle.yml | 21 + ...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 + .../inline_entity_form_test.info.yml | 18 +- .../inline_entity_form_test/src/IefTest.php | 3 +- ...ntent_settings.node.ief_reference_type.yml | 17 + ...content_settings.node.ief_test_complex.yml | 17 + ...line_entity_form_translation_test.info.yml | 14 + .../ComplexSimpleWidgetTest.php | 124 +++ .../ComplexWidgetRevisionsTest.php | 263 +++++ .../ComplexWidgetTest.php | 909 ++++++++++++++++++ .../FunctionalJavascript/ElementWebTest.php | 88 ++ .../InlineEntityFormTestBase.php | 319 ++++++ .../FunctionalJavascript/SimpleWidgetTest.php | 323 +++++++ .../FunctionalJavascript/TranslationTest.php | 167 ++++ 72 files changed, 2981 insertions(+), 1818 deletions(-) mode change 100644 => 100755 web/modules/inline_entity_form/.travis-before-script.sh delete mode 100644 web/modules/inline_entity_form/css/commerce-product.css delete mode 100644 web/modules/inline_entity_form/css/inline_entity_form.css delete mode 100644 web/modules/inline_entity_form/css/inline_entity_form.seven.css delete mode 100644 web/modules/inline_entity_form/inline_entity_form.libraries.yml delete mode 100644 web/modules/inline_entity_form/js/inline_entity_form.js delete mode 100644 web/modules/inline_entity_form/src/Tests/ComplexSimpleWidgetTest.php delete mode 100644 web/modules/inline_entity_form/src/Tests/ComplexWidgetWebTest.php delete mode 100644 web/modules/inline_entity_form/src/Tests/ElementWebTest.php delete mode 100644 web/modules/inline_entity_form/src/Tests/InlineEntityFormTestBase.php delete mode 100644 web/modules/inline_entity_form/src/Tests/SimpleWidgetWebTest.php delete mode 100644 web/modules/inline_entity_form/src/Tests/TranslationTest.php create mode 100644 web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.base_field_override.node.err_level_1.promote.yml create mode 100644 web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.base_field_override.node.err_level_2.promote.yml create mode 100644 web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.base_field_override.node.err_level_3.promote.yml create mode 100644 web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_form_display.node.err_level_1.default.yml create mode 100644 web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_form_display.node.err_level_2.default.yml create mode 100644 web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_form_display.node.err_level_3.default.yml create mode 100644 web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_1.default.yml create mode 100644 web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_1.teaser.yml create mode 100644 web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_2.default.yml create mode 100644 web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_2.teaser.yml create mode 100644 web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_3.default.yml create mode 100644 web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_3.teaser.yml create mode 100644 web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/field.field.node.err_level_1.field_level_2_entity_no_bundle.yml create mode 100644 web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/field.field.node.err_level_1.field_level_2_items.yml create mode 100644 web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/field.field.node.err_level_2.field_level_3_items.yml create mode 100644 web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/field.storage.node.field_level_2_entity_no_bundle.yml create mode 100644 web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/field.storage.node.field_level_2_items.yml create mode 100644 web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/field.storage.node.field_level_3_items.yml create mode 100644 web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/node.type.err_level_1.yml create mode 100644 web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/node.type.err_level_2.yml create mode 100644 web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/node.type.err_level_3.yml create mode 100644 web/modules/inline_entity_form/tests/modules/inline_entity_form_translation_test/config/install/language.content_settings.node.ief_reference_type.yml create mode 100644 web/modules/inline_entity_form/tests/modules/inline_entity_form_translation_test/config/install/language.content_settings.node.ief_test_complex.yml create mode 100644 web/modules/inline_entity_form/tests/modules/inline_entity_form_translation_test/inline_entity_form_translation_test.info.yml create mode 100644 web/modules/inline_entity_form/tests/src/FunctionalJavascript/ComplexSimpleWidgetTest.php create mode 100644 web/modules/inline_entity_form/tests/src/FunctionalJavascript/ComplexWidgetRevisionsTest.php create mode 100644 web/modules/inline_entity_form/tests/src/FunctionalJavascript/ComplexWidgetTest.php create mode 100644 web/modules/inline_entity_form/tests/src/FunctionalJavascript/ElementWebTest.php create mode 100644 web/modules/inline_entity_form/tests/src/FunctionalJavascript/InlineEntityFormTestBase.php create mode 100644 web/modules/inline_entity_form/tests/src/FunctionalJavascript/SimpleWidgetTest.php create mode 100644 web/modules/inline_entity_form/tests/src/FunctionalJavascript/TranslationTest.php diff --git a/composer.json b/composer.json index 9a1fb922e5..bdc268f574 100644 --- a/composer.json +++ b/composer.json @@ -129,7 +129,7 @@ "drupal/google_tag": "1.4", "drupal/honeypot": "1.30", "drupal/image_popup": "1.1", - "drupal/inline_entity_form": "1.0-rc1", + "drupal/inline_entity_form": "1.0-rc6", "drupal/libraries": "3.0.0-alpha1", "drupal/link_attributes": "1.10", "drupal/linkit": "5.0-beta11", diff --git a/composer.lock b/composer.lock index 2e1c59c874..c2e27f1d56 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b92b53385fd085532a6ff33f1dc006cb", + "content-hash": "6a15808ea43555a7d6d68dd3386988f6", "packages": [ { "name": "alchemy/zippy", @@ -5321,32 +5321,29 @@ }, { "name": "drupal/inline_entity_form", - "version": "1.0.0-rc1", + "version": "1.0.0-rc6", "source": { "type": "git", "url": "https://git.drupalcode.org/project/inline_entity_form.git", - "reference": "8.x-1.0-rc1" + "reference": "8.x-1.0-rc6" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/inline_entity_form-8.x-1.0-rc1.zip", - "reference": "8.x-1.0-rc1", - "shasum": "898789fb6a0662fc2572b87f8d0654a0241473f9" + "url": "https://ftp.drupal.org/files/projects/inline_entity_form-8.x-1.0-rc6.zip", + "reference": "8.x-1.0-rc6", + "shasum": "9f7508f4cb88d5e7869c81b20b44d89bc1689fad" }, "require": { - "drupal/core": "~8.0" + "drupal/core": "^8.7.7 || ^9" }, "require-dev": { - "drupal/entity_reference_revisions": "*" + "drupal/entity_reference_revisions": "^1.0" }, "type": "drupal-module", "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - }, "drupal": { - "version": "8.x-1.0-rc1", - "datestamp": "1527030784", + "version": "8.x-1.0-rc6", + "datestamp": "1589280847", "security-coverage": { "status": "not-covered", "message": "RC releases are not covered by Drupal security advisories." @@ -5355,7 +5352,7 @@ }, "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "GPL-2.0+" + "GPL-2.0-or-later" ], "authors": [ { @@ -5366,6 +5363,26 @@ "name": "dawehner", "homepage": "https://www.drupal.org/user/99340" }, + { + "name": "geek-merlin", + "homepage": "https://www.drupal.org/user/229048" + }, + { + "name": "joachim", + "homepage": "https://www.drupal.org/user/107701" + }, + { + "name": "jsacksick", + "homepage": "https://www.drupal.org/user/972218" + }, + { + "name": "kaythay", + "homepage": "https://www.drupal.org/user/2182186" + }, + { + "name": "oknate", + "homepage": "https://www.drupal.org/user/471638" + }, { "name": "rszrama", "homepage": "https://www.drupal.org/user/49344" @@ -5382,7 +5399,7 @@ "description": "Provides a widget for inline management (creation, modification, removal) of referenced entities.", "homepage": "https://www.drupal.org/project/inline_entity_form", "support": { - "source": "http://cgit.drupalcode.org/inline_entity_form" + "source": "https://git.drupalcode.org/project/inline_entity_form" } }, { diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index b65f2ce7a2..fdf14cf5db 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -5481,33 +5481,30 @@ }, { "name": "drupal/inline_entity_form", - "version": "1.0.0-rc1", - "version_normalized": "1.0.0.0-RC1", + "version": "1.0.0-rc6", + "version_normalized": "1.0.0.0-RC6", "source": { "type": "git", "url": "https://git.drupalcode.org/project/inline_entity_form.git", - "reference": "8.x-1.0-rc1" + "reference": "8.x-1.0-rc6" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/inline_entity_form-8.x-1.0-rc1.zip", - "reference": "8.x-1.0-rc1", - "shasum": "898789fb6a0662fc2572b87f8d0654a0241473f9" + "url": "https://ftp.drupal.org/files/projects/inline_entity_form-8.x-1.0-rc6.zip", + "reference": "8.x-1.0-rc6", + "shasum": "9f7508f4cb88d5e7869c81b20b44d89bc1689fad" }, "require": { - "drupal/core": "~8.0" + "drupal/core": "^8.7.7 || ^9" }, "require-dev": { - "drupal/entity_reference_revisions": "*" + "drupal/entity_reference_revisions": "^1.0" }, "type": "drupal-module", "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - }, "drupal": { - "version": "8.x-1.0-rc1", - "datestamp": "1527030784", + "version": "8.x-1.0-rc6", + "datestamp": "1589280847", "security-coverage": { "status": "not-covered", "message": "RC releases are not covered by Drupal security advisories." @@ -5517,7 +5514,7 @@ "installation-source": "dist", "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "GPL-2.0+" + "GPL-2.0-or-later" ], "authors": [ { @@ -5528,6 +5525,26 @@ "name": "dawehner", "homepage": "https://www.drupal.org/user/99340" }, + { + "name": "geek-merlin", + "homepage": "https://www.drupal.org/user/229048" + }, + { + "name": "joachim", + "homepage": "https://www.drupal.org/user/107701" + }, + { + "name": "jsacksick", + "homepage": "https://www.drupal.org/user/972218" + }, + { + "name": "kaythay", + "homepage": "https://www.drupal.org/user/2182186" + }, + { + "name": "oknate", + "homepage": "https://www.drupal.org/user/471638" + }, { "name": "rszrama", "homepage": "https://www.drupal.org/user/49344" @@ -5544,7 +5561,7 @@ "description": "Provides a widget for inline management (creation, modification, removal) of referenced entities.", "homepage": "https://www.drupal.org/project/inline_entity_form", "support": { - "source": "http://cgit.drupalcode.org/inline_entity_form" + "source": "https://git.drupalcode.org/project/inline_entity_form" } }, { diff --git a/web/modules/inline_entity_form/.travis-before-script.sh b/web/modules/inline_entity_form/.travis-before-script.sh old mode 100644 new mode 100755 diff --git a/web/modules/inline_entity_form/README b/web/modules/inline_entity_form/README index c9e7a6e2af..b90bc86ef1 100644 --- a/web/modules/inline_entity_form/README +++ b/web/modules/inline_entity_form/README @@ -32,9 +32,9 @@ Integrating with Inline Entity Form An entity type can add support for this module by declaring the inline entity form controller class in its entity info: -$entity_info['commerce_line_item']['inline_form'] = array( +$entity_info['commerce_line_item']['inline_form'] = [ 'controller' => 'CommerceLineItemInlineEntityFormController', -); +]; The controller needs to extend EntityInlineEntityFormController and at least override entityForm() to provide a functioning entity form. diff --git a/web/modules/inline_entity_form/composer.json b/web/modules/inline_entity_form/composer.json index 098227624b..3d5471ab42 100644 --- a/web/modules/inline_entity_form/composer.json +++ b/web/modules/inline_entity_form/composer.json @@ -2,7 +2,12 @@ "name": "drupal/inline_entity_form", "description": "Provides a widget for inline management (creation, modification, removal) of referenced entities.", "type": "drupal-module", - "license": "GPL-2.0+", + "license": "GPL-2.0-or-later", "minimum-stability": "dev", - "require": { } + "require": { + "drupal/core": "^8.7.7 || ^9" + }, + "require-dev": { + "drupal/entity_reference_revisions": "^1.0" + } } diff --git a/web/modules/inline_entity_form/config/schema/inline_entity_form.schema.yml b/web/modules/inline_entity_form/config/schema/inline_entity_form.schema.yml index aef7d466ed..b962119ea2 100644 --- a/web/modules/inline_entity_form/config/schema/inline_entity_form.schema.yml +++ b/web/modules/inline_entity_form/config/schema/inline_entity_form.schema.yml @@ -11,10 +11,10 @@ field.widget.settings.inline_entity_form_simple: type: boolean label: "Override labels" label_singular: - type: string + type: label label: "Label (singular)" label_plural: - type: string + type: label label: "Label (plural)" allow_new: type: boolean @@ -31,6 +31,9 @@ field.widget.settings.inline_entity_form_simple: collapsed: type: boolean label: "Collapsed by default" + revision: + type: boolean + label: "Create new revision" field.widget.settings.inline_entity_form_complex: type: mapping @@ -43,10 +46,10 @@ field.widget.settings.inline_entity_form_complex: type: boolean label: "Override labels" label_singular: - type: string + type: label label: "Label (singular)" label_plural: - type: string + type: label label: "Label (plural)" allow_new: type: boolean @@ -66,3 +69,6 @@ field.widget.settings.inline_entity_form_complex: collapsed: type: boolean label: "Collapsed by default" + revision: + type: boolean + label: "Create new revision" diff --git a/web/modules/inline_entity_form/css/commerce-product.css b/web/modules/inline_entity_form/css/commerce-product.css deleted file mode 100644 index 92ef167a03..0000000000 --- a/web/modules/inline_entity_form/css/commerce-product.css +++ /dev/null @@ -1,11 +0,0 @@ - -.ief-product-attributes .fieldset-wrapper { - margin-top: 15px; -} -.ief-product-attributes .fieldset-wrapper > div { - margin-right: 20px; -} - -.ief-product-details .field-type-commerce-price .form-item { - margin-right: 15px; -} diff --git a/web/modules/inline_entity_form/css/inline_entity_form.css b/web/modules/inline_entity_form/css/inline_entity_form.css deleted file mode 100644 index cfb561951b..0000000000 --- a/web/modules/inline_entity_form/css/inline_entity_form.css +++ /dev/null @@ -1,38 +0,0 @@ -.ief-cardinality-count { - text-align: right; - font-size: 0.9em; -} - -.ief-tabledrag-header { - border-right: none; -} - -.ief-sort-order-header { - border-left: none; -} - -.ief-first-column-header { - border-left: none; -} - -.ief-tabledrag-handle { - padding-right: 0; - width: 20px; -} - -.ief-tabledrag-handle a.tabledrag-handle { - padding-right: .5em; -} - -fieldset.ief-entity-fieldset { - margin: 0; -} - -.ief-row-form > td { - padding: 0; -} - -.ief-row-form .ief-form-row { - border-bottom: 10px solid #ccc; - padding: 20px; -} diff --git a/web/modules/inline_entity_form/css/inline_entity_form.seven.css b/web/modules/inline_entity_form/css/inline_entity_form.seven.css deleted file mode 100644 index a2d3c53ff2..0000000000 --- a/web/modules/inline_entity_form/css/inline_entity_form.seven.css +++ /dev/null @@ -1,31 +0,0 @@ - -.ief-row-entity-form { - background-color: #D5E9F2 !important; -} - -.field-widget-inline-entity-form fieldset.form-wrapper { - border: 0; -} -.ief-entity-fieldset, .ief-entity-fieldset fieldset { - background-color: transparent; -} -.ief-form > .fieldset-wrapper { - background: #f2f2f2; - border: 1px solid #ccc !important; -} - -.ief-form > .fieldset-wrapper { - border: 1px solid #ccc !important; -} - -.ief-entity-fieldset > legend span.fieldset-legend { - border-bottom: 1px solid #E4E4E4; - font-weight: 600; - margin-top: 10px; - padding: 3px 0; - width: 100%; -} - -.ief-entity-fieldset > .fieldset-wrapper { - margin-top: 5px; -} diff --git a/web/modules/inline_entity_form/inline_entity_form.info.yml b/web/modules/inline_entity_form/inline_entity_form.info.yml index d4b6a49d2c..5958676d6f 100644 --- a/web/modules/inline_entity_form/inline_entity_form.info.yml +++ b/web/modules/inline_entity_form/inline_entity_form.info.yml @@ -2,12 +2,9 @@ name: Inline Entity Form description: "Provides a widget for inline management (creation, modification, removal) of referenced entities. " type: module package: Fields -# core: 8.x -test_dependencies: - - entity_reference_revisions:entity_reference_revisions +core_version_requirement: ^8.7.7 || ^9 -# Information added by Drupal.org packaging script on 2018-05-22 -version: '8.x-1.0-rc1' -core: '8.x' +# Information added by Drupal.org packaging script on 2020-05-12 +version: '8.x-1.0-rc6' project: 'inline_entity_form' -datestamp: 1527030788 +datestamp: 1589280849 diff --git a/web/modules/inline_entity_form/inline_entity_form.libraries.yml b/web/modules/inline_entity_form/inline_entity_form.libraries.yml deleted file mode 100644 index 30e27f614a..0000000000 --- a/web/modules/inline_entity_form/inline_entity_form.libraries.yml +++ /dev/null @@ -1,15 +0,0 @@ -widget: - version: VERSION - js: - js/inline_entity_form.js: {} - dependencies: - - core/jquery - - core/jquery.once - - core/drupal - - core/drupalSettings - -commerce_product.base: - version: VERSION - css: - theme: - css/commerce-product.css: {} diff --git a/web/modules/inline_entity_form/js/inline_entity_form.js b/web/modules/inline_entity_form/js/inline_entity_form.js deleted file mode 100644 index f6965eb8fd..0000000000 --- a/web/modules/inline_entity_form/js/inline_entity_form.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * @file - * Provides JavaScript for Inline Entity Form. - */ - -(function ($) { - -/** - * Allows submit buttons in entity forms to trigger uploads by undoing - * work done by Drupal.behaviors.fileButtons. - */ -Drupal.behaviors.inlineEntityForm = { - attach: function (context) { - /* - if (Drupal.file) { - $('input.ief-entity-submit', context).unbind('mousedown', Drupal.file.disableFields); - } - */ - }, - detach: function (context) { - /* - if (Drupal.file) { - $('input.form-submit', context).bind('mousedown', Drupal.file.disableFields); - } - */ - } -}; - -})(jQuery); diff --git a/web/modules/inline_entity_form/src/Element/InlineEntityForm.php b/web/modules/inline_entity_form/src/Element/InlineEntityForm.php index 0fbe2335ab..7de4012344 100644 --- a/web/modules/inline_entity_form/src/Element/InlineEntityForm.php +++ b/web/modules/inline_entity_form/src/Element/InlineEntityForm.php @@ -3,8 +3,8 @@ namespace Drupal\inline_entity_form\Element; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\RevisionLogInterface; use Drupal\Core\Form\FormStateInterface; -use Drupal\Core\Render\Element; use Drupal\Core\Render\Element\RenderElement; use Drupal\inline_entity_form\ElementSubmit; use Drupal\inline_entity_form\TranslationHelper; @@ -45,6 +45,8 @@ public function getInfo() { '#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 +99,7 @@ public static function processEntityForm($entity_form, FormStateInterface $form_ 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 +109,6 @@ public static function processEntityForm($entity_form, FormStateInterface $form_ } 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 +134,17 @@ public static function processEntityForm($entity_form, FormStateInterface $form_ $entity_form['#entity'] = TranslationHelper::prepareEntity($entity_form['#entity'], $form_state); $entity_form['#translating'] = TranslationHelper::isTranslating($form_state) && $entity_form['#entity']->isTranslatable(); + // Handle revisioning if the entity supports it. + if ($entity_type->isRevisionable() && $entity_form['#revision']) { + $entity_form['#entity']->setNewRevision($entity_form['#revision']); + + // @see \Drupal\Core\Entity\ContentEntityForm::buildEntity + if ($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/web/modules/inline_entity_form/src/ElementSubmit.php b/web/modules/inline_entity_form/src/ElementSubmit.php index 0abde9bb08..72e08a1228 100644 --- a/web/modules/inline_entity_form/src/ElementSubmit.php +++ b/web/modules/inline_entity_form/src/ElementSubmit.php @@ -72,7 +72,7 @@ public static function addCallback(&$element, $complete_form) { * @param \Drupal\Core\Form\FormStateInterface $form_state * The form state. */ - public static function trigger($form, FormStateInterface $form_state) { + public static function trigger(&$form, FormStateInterface $form_state) { $triggered_element = $form_state->getTriggeringElement(); if (!empty($triggered_element['#ief_submit_trigger_all'])) { // The parent form was submitted, process all IEFs and their children. @@ -95,7 +95,7 @@ public static function trigger($form, FormStateInterface $form_state) { * @param \Drupal\Core\Form\FormStateInterface $form_state * The form state. */ - public static function doSubmit($element, FormStateInterface $form_state) { + public static function doSubmit(&$element, FormStateInterface $form_state) { // Recurse through all children. foreach (Element::children($element) as $key) { if (!empty($element[$key])) { diff --git a/web/modules/inline_entity_form/src/Form/EntityInlineForm.php b/web/modules/inline_entity_form/src/Form/EntityInlineForm.php index 1ff5073792..22533e62f2 100644 --- a/web/modules/inline_entity_form/src/Form/EntityInlineForm.php +++ b/web/modules/inline_entity_form/src/Form/EntityInlineForm.php @@ -3,6 +3,7 @@ namespace Drupal\inline_entity_form\Form; use Drupal\Core\Entity\ContentEntityInterface; +use Drupal\Core\Entity\ContentEntityTypeInterface; use Drupal\Core\Entity\Entity\EntityFormDisplay; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityFieldManagerInterface; @@ -11,6 +12,8 @@ use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Field\WidgetBase; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\StringTranslation\TranslationInterface; +use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\Render\Element; use Drupal\inline_entity_form\InlineFormInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -20,6 +23,8 @@ */ class EntityInlineForm implements InlineFormInterface { + use StringTranslationTrait; + /** * The entity field manager. * @@ -90,10 +95,10 @@ public function getEntityType() { * {@inheritdoc} */ public function getEntityTypeLabels() { - $lowercase_label = $this->entityType->getLowercaseLabel(); + $lowercase_label = $this->entityType->getSingularLabel(); return [ 'singular' => $lowercase_label, - 'plural' => t('@entity_type entities', ['@entity_type' => $lowercase_label]), + 'plural' => $this->t('@entity_type entities', ['@entity_type' => $lowercase_label]), ]; } @@ -110,12 +115,12 @@ public function getEntityLabel(EntityInterface $entity) { public function getTableFields($bundles) { $definitions = $this->entityFieldManager->getBaseFieldDefinitions($this->entityType->id()); $label_key = $this->entityType->getKey('label'); - $label_field_label = t('Label'); + $label_field_label = $this->t('Label'); if ($label_key && isset($definitions[$label_key])) { $label_field_label = $definitions[$label_key]->getLabel(); } $bundle_key = $this->entityType->getKey('bundle'); - $bundle_field_label = t('Type'); + $bundle_field_label = $this->t('Type'); if ($bundle_key && isset($definitions[$bundle_key])) { $bundle_field_label = $definitions[$bundle_key]->getLabel(); } @@ -183,6 +188,14 @@ public function entityForm(array $entity_form, FormStateInterface $form_state) { } } + // Hide the log message field for revisionable entity types. It cannot be + // disabled in UI and does not make sense in inline entity form context. + if (($this->entityType instanceof ContentEntityTypeInterface)) { + if ($log_message_key = $this->entityType->getRevisionMetadataKey('revision_log_message')) { + $entity_form[$log_message_key]['#access'] = FALSE; + } + } + // Determine the children of the entity form before it has been altered. $children_before = Element::children($entity_form); diff --git a/web/modules/inline_entity_form/src/Form/NodeInlineForm.php b/web/modules/inline_entity_form/src/Form/NodeInlineForm.php index 4f6c377001..1c00b6acdf 100644 --- a/web/modules/inline_entity_form/src/Form/NodeInlineForm.php +++ b/web/modules/inline_entity_form/src/Form/NodeInlineForm.php @@ -45,16 +45,4 @@ public function getTableFields($bundles) { return $fields; } - /** - * {@inheritdoc} - */ - public function entityForm(array $entity_form, FormStateInterface $form_state) { - $entity_form = parent::entityForm($entity_form, $form_state); - // Remove the "Revision log" textarea, it can't be disabled in the - // form display and doesn't make sense in the inline form context. - $entity_form['revision_log']['#access'] = FALSE; - - return $entity_form; - } - } diff --git a/web/modules/inline_entity_form/src/InlineFormInterface.php b/web/modules/inline_entity_form/src/InlineFormInterface.php index fe56c160f7..f7b0b2a552 100644 --- a/web/modules/inline_entity_form/src/InlineFormInterface.php +++ b/web/modules/inline_entity_form/src/InlineFormInterface.php @@ -43,7 +43,7 @@ public function getEntityTypeLabels(); public function getEntityLabel(EntityInterface $entity); /** - * Gets the fields used to represent an entity in the IEF table. + * Gets the columns used to represent an entity in the IEF table. * * Modules can alter the output of this method through * hook_inline_entity_form_table_fields_alter(). @@ -52,14 +52,20 @@ public function getEntityLabel(EntityInterface $entity); * An array of allowed bundles for this widget. * * @return array - * An array of fields keyed by field name. Each field is represented by an - * associative array containing the following keys: - * - type: 'label', 'field' or 'callback'. + * An array of data about table columns keyed by column name. Each column is + * represented by an associative array containing the following keys: + * - type: One of 'label', 'field' or 'callback', which indicates how this + * column should be handled: + * - 'label': The entity's label. + * - 'field': A field value from the entity. The name of the field is + * given by the key in this array. + * - 'callback': A callback, given by the 'callback' property. + * See theme_inline_entity_form_entity_table() for the handling of these. * - label: the title of the table field's column in the IEF table. * - weight: the sort order of the column in the IEF table. - * - display_options: (optional) used for 'field' type table fields, an + * - display_options: (optional) used for 'field' type table columns, an * array of display settings. See EntityViewBuilderInterface::viewField(). - * - callback: for 'callback' type table fields, a callable that returns a + * - callback: for 'callback' type table columns, a callable that returns a * renderable array. * - callback_arguments: (optional) an array of additional arguments to pass * to the callback. The entity and the theme variables are always passed diff --git a/web/modules/inline_entity_form/src/Plugin/Field/FieldWidget/InlineEntityFormBase.php b/web/modules/inline_entity_form/src/Plugin/Field/FieldWidget/InlineEntityFormBase.php index 1e69c7c9fb..471afb3426 100644 --- a/web/modules/inline_entity_form/src/Plugin/Field/FieldWidget/InlineEntityFormBase.php +++ b/web/modules/inline_entity_form/src/Plugin/Field/FieldWidget/InlineEntityFormBase.php @@ -57,7 +57,7 @@ abstract class InlineEntityFormBase extends WidgetBase implements ContainerFacto /** * Constructs an InlineEntityFormBase object. * - * @param array $plugin_id + * @param string $plugin_id * The plugin_id for the widget. * @param mixed $plugin_definition * The plugin implementation definition. @@ -190,6 +190,7 @@ protected function getCreateBundles() { public static function defaultSettings() { return [ 'form_mode' => 'default', + 'revision' => FALSE, 'override_labels' => FALSE, 'label_singular' => '', 'label_plural' => '', @@ -212,6 +213,11 @@ public function settingsForm(array $form, FormStateInterface $form_state) { '#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'), @@ -267,7 +273,7 @@ public function settingsSummary() { else { $form_mode_label = $this->t('Default'); } - $summary[] = t('Form mode: @mode', ['@mode' => $form_mode_label]); + $summary[] = $this->t('Form mode: @mode', ['@mode' => $form_mode_label]); if ($this->getSetting('override_labels')) { $summary[] = $this->t( 'Overriden labels are used: %singular and %plural', @@ -278,6 +284,10 @@ public function settingsSummary() { $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 @@ protected function getInlineEntityForm($operation, $bundle, $langcode, $delta, a '#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 diff --git a/web/modules/inline_entity_form/src/Plugin/Field/FieldWidget/InlineEntityFormComplex.php b/web/modules/inline_entity_form/src/Plugin/Field/FieldWidget/InlineEntityFormComplex.php index b8424be3b6..a4b2c306b8 100644 --- a/web/modules/inline_entity_form/src/Plugin/Field/FieldWidget/InlineEntityFormComplex.php +++ b/web/modules/inline_entity_form/src/Plugin/Field/FieldWidget/InlineEntityFormComplex.php @@ -3,7 +3,10 @@ namespace Drupal\inline_entity_form\Plugin\Field\FieldWidget; use Drupal\Component\Utility\NestedArray; +use Drupal\Component\Utility\Tags; +use Drupal\Core\Entity\Element\EntityAutocomplete; use Drupal\Core\Entity\EntityDisplayRepositoryInterface; +use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface; use Drupal\Core\Entity\EntityTypeBundleInfoInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Extension\ModuleHandlerInterface; @@ -14,6 +17,7 @@ use Drupal\Core\Render\Element; use Drupal\inline_entity_form\TranslationHelper; use Symfony\Component\DependencyInjection\ContainerInterface; +use Drupal\Component\Utility\Crypt; /** * Complex inline widget. @@ -22,7 +26,8 @@ * id = "inline_entity_form_complex", * label = @Translation("Inline entity form - Complex"), * field_types = { - * "entity_reference" + * "entity_reference", + * "entity_reference_revisions", * }, * multiple_values = true * ) @@ -36,10 +41,17 @@ class InlineEntityFormComplex extends InlineEntityFormBase implements ContainerF */ protected $moduleHandler; + /** + * Selection Plugin Manager service. + * + * @var \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface + */ + protected $selectionManager; + /** * Constructs a InlineEntityFormComplex object. * - * @param array $plugin_id + * @param string $plugin_id * The plugin_id for the widget. * @param mixed $plugin_definition * The plugin implementation definition. @@ -57,10 +69,13 @@ class InlineEntityFormComplex extends InlineEntityFormBase implements ContainerF * The entity display repository. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * Module handler service. + * @param \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface $selection_manager + * The selection plugin manager. */ - public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, EntityTypeBundleInfoInterface $entity_type_bundle_info, EntityTypeManagerInterface $entity_type_manager, EntityDisplayRepositoryInterface $entity_display_repository, ModuleHandlerInterface $module_handler) { + public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, EntityTypeBundleInfoInterface $entity_type_bundle_info, EntityTypeManagerInterface $entity_type_manager, EntityDisplayRepositoryInterface $entity_display_repository, ModuleHandlerInterface $module_handler, SelectionPluginManagerInterface $selection_manager) { parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings, $entity_type_bundle_info, $entity_type_manager, $entity_display_repository); $this->moduleHandler = $module_handler; + $this->selectionManager = $selection_manager; } /** @@ -76,7 +91,8 @@ public static function create(ContainerInterface $container, array $configuratio $container->get('entity_type.bundle.info'), $container->get('entity_type.manager'), $container->get('entity_display.repository'), - $container->get('module_handler') + $container->get('module_handler'), + $container->get('plugin.manager.entity_reference_selection') ); } @@ -198,9 +214,9 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen ]); // Assign a unique identifier to each IEF widget. - // Since $parents can get quite long, sha1() ensures that every id has + // Since $parents can get quite long, hashing ensures that every id has // a consistent and relatively short length while maintaining uniqueness. - $this->setIefId(sha1(implode('-', $parents))); + $this->setIefId(Crypt::hashBase64(implode('-', $parents))); // Get the langcode of the parent entity. $parent_langcode = $items->getEntity()->language()->getId(); @@ -226,8 +242,6 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen $element['#open'] = !$this->getSetting('collapsed'); } - $element['#attached']['library'][] = 'inline_entity_form/widget'; - $this->prepareFormState($form_state, $items, $element['#translating']); $entities = $form_state->get(['inline_entity_form', $this->getIefId(), 'entities']); @@ -510,6 +524,9 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen } } else { + // Make a delta key bigger than all existing ones, without assuming that + // the keys are strictly consecutive. + $new_key = $entities ? max(array_keys($entities)) + 1 : 0; // There's a form open, show it. if ($form_state->get(['inline_entity_form', $this->getIefId(), 'form']) == 'add') { $element['form'] = [ @@ -519,9 +536,9 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen 'add', $this->determineBundle($form_state), $parent_langcode, - NULL, - array_merge($parents, ['inline_entity_form']) - ) + $new_key, + array_merge($parents, [$new_key]) + ), ]; $element['form']['inline_entity_form']['#process'] = [ ['\Drupal\inline_entity_form\Element\InlineEntityForm', 'processEntityForm'], @@ -537,7 +554,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen '#ief_id' => $this->getIefId(), // Used by Field API and controller methods to find the relevant // values in $form_state. - '#parents' => array_merge($parents), + '#parents' => array_merge($parents, [$new_key]), '#entity_type' => $target_type, '#ief_labels' => $this->getEntityTypeLabels(), '#match_operator' => $this->getSetting('match_operator'), @@ -583,7 +600,7 @@ public function extractFormValues(FieldItemListInterface $items, array $form, Fo $field_name = $this->fieldDefinition->getName(); $parents = array_merge($form['#parents'], [$field_name, 'form']); - $ief_id = sha1(implode('-', $parents)); + $ief_id = Crypt::hashBase64(implode('-', $parents)); $this->setIefId($ief_id); $widget_state = &$form_state->get(['inline_entity_form', $ief_id]); foreach ($widget_state['entities'] as $key => $value) { @@ -598,12 +615,68 @@ public function extractFormValues(FieldItemListInterface $items, array $form, Fo // If the inline entity form is still open, then its entity hasn't // been transferred to the IEF form state yet. if (empty($values) && !empty($widget_state['form'])) { - // @todo Do the same for reference forms. if ($widget_state['form'] == 'add') { $element = NestedArray::getValue($form, [$field_name, 'widget', 'form']); $entity = $element['inline_entity_form']['#entity']; $values[] = ['entity' => $entity]; } + elseif ($widget_state['form'] == 'ief_add_existing') { + $parent = NestedArray::getValue($form, [$field_name, 'widget', 'form']); + $element = isset($parent['entity_id']) ? $parent['entity_id'] : []; + if (!empty($element['#value'])) { + $options = [ + 'target_type' => $element['#target_type'], + 'handler' => $element['#selection_handler'], + ] + $element['#selection_settings']; + /** @var \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface $handler */ + $handler = $this->selectionManager->getInstance($options); + $input_values = $element['#tags'] ? Tags::explode($element['#value']) : [$element['#value']]; + + foreach ($input_values as $input) { + $match = EntityAutocomplete::extractEntityIdFromAutocompleteInput($input); + if ($match === NULL) { + // Try to get a match from the input string when the user didn't use + // the autocomplete but filled in a value manually. + $entities_by_bundle = $handler->getReferenceableEntities($input, '='); + $entities = array_reduce($entities_by_bundle, function ($flattened, $bundle_entities) { + return $flattened + $bundle_entities; + }, []); + $params = [ + '%value' => $input, + '@value' => $input, + ]; + if (empty($entities)) { + $form_state->setError($element, $this->t('There are no entities matching "%value".', $params)); + } + elseif (count($entities) > 5) { + $params['@id'] = key($entities); + // Error if there are more than 5 matching entities. + $form_state->setError($element, $this->t('Many entities are called %value. Specify the one you want by appending the id in parentheses, like "@value (@id)".', $params)); + } + elseif (count($entities) > 1) { + // More helpful error if there are only a few matching entities. + $multiples = []; + foreach ($entities as $id => $name) { + $multiples[] = $name . ' (' . $id . ')'; + } + $params['@id'] = $id; + $form_state->setError($element, $this->t('Multiple entities match this reference; "%multiple". Specify the one you want by appending the id in parentheses, like "@value (@id)".', ['%multiple' => implode('", "', $multiples)] + $params)); + } + else { + // Take the one and only matching entity. + $values += [ + 'target_id' => key($entities), + ]; + } + } + else { + $values += [ + 'target_id' => $match, + ]; + } + } + } + } } // Sort values by weight. uasort($values, '\Drupal\Component\Utility\SortArray::sortByWeightElement'); @@ -809,9 +882,6 @@ public static function submitConfirmRemove($form, FormStateInterface $form_state $remove_button = $form_state->getTriggeringElement(); $delta = $remove_button['#ief_row_delta']; - /** @var \Drupal\Core\Field\FieldDefinitionInterface $instance */ - $instance = $form_state->get(['inline_entity_form', $element['#ief_id'], 'instance']); - /** @var \Drupal\Core\Entity\EntityInterface $entity */ $entity = $element['entities'][$delta]['form']['#entity']; $entity_id = $entity->id(); diff --git a/web/modules/inline_entity_form/src/Plugin/Field/FieldWidget/InlineEntityFormSimple.php b/web/modules/inline_entity_form/src/Plugin/Field/FieldWidget/InlineEntityFormSimple.php index 985e06bc6f..03eef594d2 100644 --- a/web/modules/inline_entity_form/src/Plugin/Field/FieldWidget/InlineEntityFormSimple.php +++ b/web/modules/inline_entity_form/src/Plugin/Field/FieldWidget/InlineEntityFormSimple.php @@ -10,6 +10,7 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Element; use Drupal\inline_entity_form\TranslationHelper; +use Drupal\Component\Utility\Crypt; /** * Simple inline widget. @@ -18,7 +19,8 @@ * id = "inline_entity_form_simple", * label = @Translation("Inline entity form - Simple"), * field_types = { - * "entity_reference" + * "entity_reference", + * "entity_reference_revisions", * }, * multiple_values = false * ) @@ -32,7 +34,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen // Trick inline_entity_form_form_alter() into attaching the handlers, // WidgetSubmit will be needed once extractFormValues fills the $form_state. $parents = array_merge($element['#field_parents'], [$items->getName()]); - $ief_id = sha1(implode('-', $parents)); + $ief_id = Crypt::hashBase64(implode('-', $parents)); $form_state->set(['inline_entity_form', $ief_id], []); $element = [ @@ -85,9 +87,9 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen protected function formMultipleElements(FieldItemListInterface $items, array &$form, FormStateInterface $form_state) { $element = parent::formMultipleElements($items, $form, $form_state); - // If we're using ulimited cardinality we don't display one empty item. Form - // validation will kick in if left empty which esentially means people won't - // be able to submit w/o creating another entity. + // If we're using unlimited cardinality we don't display one empty item. + // Form validation will kick in if left empty which essentially means + // people won't be able to submit without creating another entity. if (!$form_state->isSubmitted() && $element['#cardinality'] == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED && $element['#max_delta'] > 0) { $max = $element['#max_delta']; unset($element[$max]); @@ -152,7 +154,7 @@ public function extractFormValues(FieldItemListInterface $items, array $form, Fo // Populate the IEF form state with $items so that WidgetSubmit can // perform the necessary saves. - $ief_id = sha1(implode('-', $parents)); + $ief_id = Crypt::hashBase64(implode('-', $parents)); $widget_state = [ 'instance' => $this->fieldDefinition, 'delete' => [], diff --git a/web/modules/inline_entity_form/src/Tests/ComplexSimpleWidgetTest.php b/web/modules/inline_entity_form/src/Tests/ComplexSimpleWidgetTest.php deleted file mode 100644 index 115a8793d6..0000000000 --- a/web/modules/inline_entity_form/src/Tests/ComplexSimpleWidgetTest.php +++ /dev/null @@ -1,111 +0,0 @@ -<?php - -namespace Drupal\inline_entity_form\Tests; - -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 - */ - public static $modules = [ - 'inline_entity_form_test', - 'field', - 'field_ui', - ]; - - protected function setUp() { - 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() { - $outer_required_options = [ - TRUE, - FALSE, - ]; - $cardinality_options = [ - 1 => 1, - 2 => 2, - FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED => 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) { - $edit = []; - $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'); - $outer_title_field = 'ief_complex_outer[form][inline_entity_form][title][0][value]'; - $inner_title_field = 'ief_complex_outer[form][inline_entity_form][single][0][inline_entity_form][title][0][value]'; - if (!$outer_required_option) { - $this->assertText('Complex Outer', 'Complex Inline entity field widget title found.'); - // Field should not be available before ajax submit. - $this->assertNoFieldByName($outer_title_field, NULL); - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @value="Add new node" and @data-drupal-selector="edit-ief-complex-outer-actions-ief-add"]')); - } - $this->assertFieldByName($outer_title_field, NULL); - // Simple widget is required so should always show up. No need for add submit. - $this->assertFieldByName($inner_title_field, NULL); - - $edit[$outer_title_field] = $outer_title = $this->randomMachineName(8); - $edit[$inner_title_field] = $inner_title = $this->randomMachineName(8); - $create_outer_button_selector = '//input[@type="submit" and @value="Create node" and @data-drupal-selector="edit-ief-complex-outer-form-inline-entity-form-actions-ief-add-save"]'; - $this->drupalPostAjaxForm(NULL, $edit, $this->getButtonName($create_outer_button_selector)); - // After ajax submit the ief title fields should be gone. - $this->assertNoFieldByName($outer_title_field, NULL); - $this->assertNoFieldByName($inner_title_field, NULL); - $this->assertEqual('', $this->getButtonName($create_outer_button_selector), 'Create node button not found after Ajax submit.'); - - // 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(8); - $edit = ['title[0][value]' => $host_title]; - $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertText("$host_title has been created."); - $this->assertText($outer_title); - - // Check the nodes were created correctly. - $host_node = $this->drupalGetNodeByTitle($host_title); - if ($this->assertNotNull($host_node->ief_complex_outer->entity, 'Outer node was created.')) { - $outer_node = $host_node->ief_complex_outer->entity; - $this->assertEqual($outer_title, $outer_node->label(), "Outer node's title looks correct."); - $this->assertEqual('ief_simple_single', $outer_node->bundle(), "Outer node's type looks correct."); - if ($this->assertNotNull($outer_node->single->entity, 'Inner node was created')) { - $inner_node = $outer_node->single->entity; - $this->assertEqual($inner_title, $inner_node->label(), "Inner node's title looks correct."); - $this->assertEqual('ief_test_custom', $inner_node->bundle(), "Inner node's type looks correct."); - } - } - } - } - } - -} diff --git a/web/modules/inline_entity_form/src/Tests/ComplexWidgetWebTest.php b/web/modules/inline_entity_form/src/Tests/ComplexWidgetWebTest.php deleted file mode 100644 index d606c841b1..0000000000 --- a/web/modules/inline_entity_form/src/Tests/ComplexWidgetWebTest.php +++ /dev/null @@ -1,780 +0,0 @@ -<?php - -namespace Drupal\inline_entity_form\Tests; - -use Drupal\node\Entity\Node; - -/** - * IEF complex field widget tests. - * - * @group inline_entity_form - */ -class ComplexWidgetWebTest extends InlineEntityFormTestBase { - - /** - * Modules to enable. - * - * @var array - */ - public static $modules = [ - 'inline_entity_form_test', - 'field', - 'field_ui', - ]; - - /** - * URL to add new content. - * - * @var string - */ - protected $formContentAddUrl; - - /** - * Entity form display storage. - * - * @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface - */ - protected $entityFormDisplayStorage; - - /** - * Prepares environment for - */ - protected function setUp() { - 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', - 'edit any ief_test_nested1 content', - 'edit any ief_test_nested2 content', - 'edit any ief_test_nested3 content', - 'view own unpublished content', - 'administer content types', - ]); - $this->drupalLogin($this->user); - - $this->formContentAddUrl = 'node/add/ief_test_complex'; - $this->entityFormDisplayStorage = $this->container->get('entity_type.manager')->getStorage('entity_form_display'); - } - - /** - * Tests if form behaves correctly when field is empty. - */ - public function testEmptyFieldIEF() { - // Don't allow addition of existing nodes. - $this->updateSetting('allow_existing', FALSE); - $this->drupalGet($this->formContentAddUrl); - - $this->assertFieldByName('multi[form][inline_entity_form][title][0][value]', NULL, 'Title field on inline form exists.'); - $this->assertFieldByName('multi[form][inline_entity_form][first_name][0][value]', NULL, 'First name field on inline form exists.'); - $this->assertFieldByName('multi[form][inline_entity_form][last_name][0][value]', NULL, 'Last name field on inline form exists.'); - $this->assertFieldByXpath('//input[@type="submit" and @value="Create node"]', NULL, 'Found "Create node" submit button'); - - // Allow addition of existing nodes. - $this->updateSetting('allow_existing', TRUE); - $this->drupalGet($this->formContentAddUrl); - - $this->assertNoFieldByName('multi[form][inline_entity_form][title][0][value]', NULL, 'Title field does not appear.'); - $this->assertNoFieldByName('multi[form][inline_entity_form][first_name][0][value]', NULL, 'First name field does not appear.'); - $this->assertNoFieldByName('multi[form][inline_entity_form][last_name][0][value]', NULL, 'Last name field does not appear.'); - $this->assertFieldByXpath('//input[@type="submit" and @value="Add new node"]', NULL, 'Found "Add new node" submit button'); - $this->assertFieldByXpath('//input[@type="submit" and @value="Add existing node"]', NULL, 'Found "Add existing node" submit button'); - - // Now submit 'Add new node' button. - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @value="Add new node" and @data-drupal-selector="edit-multi-actions-ief-add"]')); - - $this->assertFieldByName('multi[form][inline_entity_form][title][0][value]', NULL, 'Title field on inline form exists.'); - $this->assertFieldByName('multi[form][inline_entity_form][first_name][0][value]', NULL, 'First name field on inline form exists.'); - $this->assertFieldByName('multi[form][inline_entity_form][last_name][0][value]', NULL, 'Second name field on inline form exists.'); - $this->assertFieldByXpath('//input[@type="submit" and @value="Create node"]', NULL, 'Found "Create node" submit button'); - $this->assertFieldByXpath('//input[@type="submit" and @value="Cancel"]', NULL, 'Found "Cancel" submit button'); - - // Now submit 'Add Existing node' button. - $this->drupalGet($this->formContentAddUrl); - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @value="Add existing node" and @data-drupal-selector="edit-multi-actions-ief-add-existing"]')); - - $this->assertFieldByName('multi[form][entity_id]', NULL, 'Existing entity reference autocomplete field found.'); - $this->assertFieldByXpath('//input[@type="submit" and @value="Add node"]', NULL, 'Found "Add node" submit button'); - $this->assertFieldByXpath('//input[@type="submit" and @value="Cancel"]', NULL, 'Found "Cancel" submit button'); - } - - /** - * Tests creation of entities. - */ - public function testEntityCreation() { - // Allow addition of existing nodes. - $this->updateSetting('allow_existing', TRUE); - $this->drupalGet($this->formContentAddUrl); - - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @value="Add new node" and @data-drupal-selector="edit-multi-actions-ief-add"]')); - $this->assertResponse(200, 'Opening new inline form was successful.'); - - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @value="Create node" and @data-drupal-selector="edit-multi-form-inline-entity-form-actions-ief-add-save"]')); - $this->assertResponse(200, 'Submitting empty form was successful.'); - $this->assertText('First name field is required.', 'Validation failed for empty "First name" field.'); - $this->assertText('Last name field is required.', 'Validation failed for empty "Last name" field.'); - $this->assertText('Title field is required.', 'Validation failed for empty "Title" field.'); - - // Create ief_reference_type node in IEF. - $this->drupalGet($this->formContentAddUrl); - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @value="Add new node" and @data-drupal-selector="edit-multi-actions-ief-add"]')); - $this->assertResponse(200, 'Opening new inline form was successful.'); - - $edit = [ - 'multi[form][inline_entity_form][title][0][value]' => 'Some reference', - 'multi[form][inline_entity_form][first_name][0][value]' => 'John', - 'multi[form][inline_entity_form][last_name][0][value]' => 'Doe', - ]; - $this->drupalPostAjaxForm(NULL, $edit, $this->getButtonName('//input[@type="submit" and @value="Create node" and @data-drupal-selector="edit-multi-form-inline-entity-form-actions-ief-add-save"]')); - $this->assertResponse(200, 'Creating node via inline form was successful.'); - - // Tests if correct fields appear in the table. - $this->assertTrue((bool) $this->xpath('//td[@class="inline-entity-form-node-label" and contains(.,"Some reference")]'), 'Node title field appears in the table'); - $this->assertTrue((bool) $this->xpath('//td[@class="inline-entity-form-node-status" and ./div[contains(.,"Published")]]'), 'Node status field appears in the table'); - - // Tests if edit and remove buttons appear. - $this->assertTrue((bool) $this->xpath('//input[@type="submit" and @value="Edit"]'), 'Edit button appears in the table.'); - $this->assertTrue((bool) $this->xpath('//input[@type="submit" and @value="Remove"]'), 'Remove button appears in the table.'); - - // Test edit functionality. - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @value="Edit"]')); - $edit = [ - 'multi[form][inline_entity_form][entities][0][form][title][0][value]' => 'Some changed reference', - ]; - $this->drupalPostAjaxForm(NULL, $edit, $this->getButtonName('//input[@type="submit" and @value="Update node"]')); - $this->assertTrue((bool) $this->xpath('//td[@class="inline-entity-form-node-label" and contains(.,"Some changed reference")]'), 'Node title field appears in the table'); - $this->assertTrue((bool) $this->xpath('//td[@class="inline-entity-form-node-status" and ./div[contains(.,"Published")]]'), 'Node status field appears in the table'); - - // Make sure unrelated AJAX submit doesn't save the referenced entity. - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @value="Upload"]')); - $node = $this->drupalGetNodeByTitle('Some changed reference'); - $this->assertFalse($node, 'Referenced node was not saved during unrelated AJAX submit.'); - - // Create ief_test_complex node. - $edit = ['title[0][value]' => 'Some title']; - $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertResponse(200, 'Saving parent entity was successful.'); - - // Checks values of created entities. - $node = $this->drupalGetNodeByTitle('Some changed reference'); - $this->assertTrue($node, 'Created ief_reference_type node ' . $node->label()); - $this->assertTrue($node->get('first_name')->value == 'John', 'First name in reference node set to John'); - $this->assertTrue($node->get('last_name')->value == 'Doe', 'Last name in reference node set to Doe'); - - $parent_node = $this->drupalGetNodeByTitle('Some title'); - $this->assertTrue($parent_node, 'Created ief_test_complex node ' . $parent_node->label()); - $this->assertTrue($parent_node->multi->target_id == $node->id(), 'Refererence node id set to ' . $node->id()); - } - - /** - * Tests the entity creation with different bundles nested in each other. - * - * ief_test_nested1 -> ief_test_nested2 -> ief_test_nested3 - */ - public function testNestedEntityCreationWithDifferentBundlesAjaxSubmit() { - $required_possibilities = [ - FALSE, - TRUE, - ]; - foreach ($required_possibilities as $required) { - $this->setupNestedComplexForm($required); - - $nested3_title = 'nested3 title steps ' . ($required ? 'required' : 'not required'); - $nested2_title = 'nested2 title steps ' . ($required ? 'required' : 'not required'); - $nested1_title = 'nested1 title steps ' . ($required ? 'required' : 'not required'); - $edit = [ - 'test_ref_nested1[form][inline_entity_form][test_ref_nested2][form][inline_entity_form][title][0][value]' => $nested3_title, - ]; - $this->drupalPostAjaxForm(NULL, $edit, $this->getButtonName('//input[@type="submit" and @value="Create node 3"]')); - $this->assertText($nested3_title, 'Title of second nested node found.'); - $this->assertNoNodeByTitle($nested3_title, 'Second nested entity is not saved yet.'); - - $edit = [ - 'test_ref_nested1[form][inline_entity_form][title][0][value]' => $nested2_title, - ]; - $this->drupalPostAjaxForm(NULL, $edit, $this->getButtonName('//input[@type="submit" and @value="Create node 2"]')); - $this->assertText($nested2_title, 'Title of first nested node found.'); - $this->assertNoNodeByTitle($nested2_title, 'First nested entity is not saved yet.'); - - $edit = [ - 'title[0][value]' => $nested1_title, - ]; - $this->drupalPostForm(NULL, $edit, t('Save')); - $this->checkNestedNodes($nested1_title, $nested2_title, $nested3_title); - } - } - - /** - * Checks that nested IEF entity references can be edit and saved. - * - * @param \Drupal\node\Entity\Node $node - * Top level node of type ief_test_nested1 to check. - * @param bool $ajax_submit - * Whether IEF form widgets should be submitted via AJAX or left open. - */ - protected function checkNestedEntityEditing(Node $node, $ajax_submit = TRUE) { - $this->drupalGet("node/{$node->id()}/edit"); - /** @var \Drupal\node\Entity\Node $level_1_node */ - $level_1_node = $node->test_ref_nested1->entity; - /** @var \Drupal\node\Entity\Node $level_2_node */ - $level_2_node = $node->test_ref_nested1->entity->test_ref_nested2->entity; - $level_2_node_update_title = $level_2_node->getTitle() . ' - updated'; - // edit-test-ref-nested1-entities-0-actions-ief-entity-edit - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @data-drupal-selector="edit-test-ref-nested1-entities-0-actions-ief-entity-edit"]')); - // edit-test-ref-nested1-form-inline-entity-form-entities-0-form-test-ref-nested2-entities-0-actions-ief-entity-edit - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @data-drupal-selector="edit-test-ref-nested1-form-inline-entity-form-entities-0-form-test-ref-nested2-entities-0-actions-ief-entity-edit"]')); - $edit['test_ref_nested1[form][inline_entity_form][entities][0][form][test_ref_nested2][form][inline_entity_form][entities][0][form][title][0][value]'] = $level_2_node_update_title; - if ($ajax_submit) { - // Close IEF Forms with AJAX posts - // edit-test-ref-nested1-form-inline-entity-form-entities-0-form-test-ref-nested2-form-inline-entity-form-entities-0-form-actions-ief-edit-save - $this->drupalPostAjaxForm(NULL, $edit, $this->getButtonName('//input[@type="submit" and @data-drupal-selector="edit-test-ref-nested1-form-inline-entity-form-entities-0-form-test-ref-nested2-form-inline-entity-form-entities-0-form-actions-ief-edit-save"]')); - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @data-drupal-selector="edit-test-ref-nested1-form-inline-entity-form-entities-0-form-actions-ief-edit-save"]')); - $this->drupalPostForm(NULL, [], t('Save')); - } - else { - $this->drupalPostForm(NULL, $edit, t('Save')); - } - $this->nodeStorage->resetCache([$level_2_node->id()]); - $level_2_node = $this->nodeStorage->load($level_2_node->id()); - $this->assertEqual($level_2_node_update_title, $level_2_node->getTitle()); - } - - /** - * Tests the entity creation with different bundles nested in each other. - * - * ief_test_nested1 -> ief_test_nested2 -> ief_test_nested3 - */ - public function testNestedEntityCreationWithDifferentBundlesNoAjaxSubmit() { - $required_possibilities = [ - FALSE, - TRUE, - ]; - - foreach ($required_possibilities as $required) { - $this->setupNestedComplexForm($required); - - $nested3_title = 'nested3 title single ' . ($required ? 'required' : 'not required'); - $nested2_title = 'nested2 title single ' . ($required ? 'required' : 'not required'); - $nested1_title = 'nested1 title single ' . ($required ? 'required' : 'not required'); - - $edit = [ - 'title[0][value]' => $nested1_title, - 'test_ref_nested1[form][inline_entity_form][title][0][value]' => $nested2_title, - 'test_ref_nested1[form][inline_entity_form][test_ref_nested2][form][inline_entity_form][title][0][value]' => $nested3_title, - ]; - $this->drupalPostForm(NULL, $edit, t('Save')); - $this->checkNestedNodes($nested1_title, $nested2_title, $nested3_title); - } - } - - /** - * Tests if editing and removing entities work. - */ - public function testEntityEditingAndRemoving() { - // Allow addition of existing nodes. - $this->updateSetting('allow_existing', TRUE); - - // Create three ief_reference_type entities. - $referenceNodes = $this->createReferenceContent(3); - $this->drupalCreateNode([ - 'type' => 'ief_test_complex', - 'title' => 'Some title', - 'multi' => array_values($referenceNodes), - ]); - /** @var \Drupal\node\NodeInterface $node */ - $parent_node = $this->drupalGetNodeByTitle('Some title'); - - // Edit the second entity. - $this->drupalGet('node/' . $parent_node->id() . '/edit'); - $cell = $this->xpath('//table[@id="ief-entity-table-edit-multi-entities"]/tbody/tr[@class="ief-row-entity draggable even"]/td[@class="inline-entity-form-node-label"]'); - $title = (string) $cell[0]; - - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @id="edit-multi-entities-1-actions-ief-entity-edit"]')); - $this->assertResponse(200, 'Opening inline edit form was successful.'); - - $edit = [ - 'multi[form][inline_entity_form][entities][1][form][first_name][0][value]' => 'John', - 'multi[form][inline_entity_form][entities][1][form][last_name][0][value]' => 'Doe', - ]; - $this->drupalPostAjaxForm(NULL, $edit, $this->getButtonName('//input[@type="submit" and @data-drupal-selector="edit-multi-form-inline-entity-form-entities-1-form-actions-ief-edit-save"]')); - $this->assertResponse(200, 'Saving inline edit form was successful.'); - - // Save the ief_test_complex node. - $this->drupalPostForm(NULL, [], t('Save')); - $this->assertResponse(200, 'Saving parent entity was successful.'); - - // Checks values of changed entities. - $node = $this->drupalGetNodeByTitle($title, TRUE); - $this->assertTrue($node->first_name->value == 'John', 'First name in reference node changed to John'); - $this->assertTrue($node->last_name->value == 'Doe', 'Last name in reference node changed to Doe'); - - // Delete the second entity. - $this->drupalGet('node/' . $parent_node->id() . '/edit'); - $cell = $this->xpath('//table[@id="ief-entity-table-edit-multi-entities"]/tbody/tr[@class="ief-row-entity draggable even"]/td[@class="inline-entity-form-node-label"]'); - $title = (string) $cell[0]; - - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @id="edit-multi-entities-1-actions-ief-entity-remove"]')); - $this->assertResponse(200, 'Opening inline remove confirm form was successful.'); - $this->assertText('Are you sure you want to remove', 'Remove warning message is displayed.'); - - $this->drupalPostAjaxForm(NULL, ['multi[form][entities][1][form][delete]' => TRUE], $this->getButtonName('//input[@type="submit" and @data-drupal-selector="edit-multi-form-entities-1-form-actions-ief-remove-confirm"]')); - $this->assertResponse(200, 'Removing inline entity was successful.'); - $this->assertNoText($title, 'Deleted inline entity is not present on the page.'); - - // Save the ief_test_complex node. - $this->drupalPostForm(NULL, [], t('Save')); - $this->assertResponse(200, 'Saving parent node was successful.'); - - $deleted_node = $this->drupalGetNodeByTitle($title); - $this->assertTrue(empty($deleted_node), 'The inline entity was deleted from the site.'); - - // Checks that entity does nor appear in IEF. - $this->drupalGet('node/' . $parent_node->id() . '/edit'); - $this->assertNoText($title, 'Deleted inline entity is not present on the page after saving parent.'); - - // Delete the third entity reference only, don't delete the node. The third - // entity now is second referenced entity because the second one was deleted - // in previous step. - $this->drupalGet('node/' . $parent_node->id() . '/edit'); - $cell = $this->xpath('//table[@id="ief-entity-table-edit-multi-entities"]/tbody/tr[@class="ief-row-entity draggable even"]/td[@class="inline-entity-form-node-label"]'); - $title = (string) $cell[0]; - - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @id="edit-multi-entities-1-actions-ief-entity-remove"]')); - $this->assertResponse(200, 'Opening inline remove confirm form was successful.'); - - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @data-drupal-selector="edit-multi-form-entities-1-form-actions-ief-remove-confirm"]')); - $this->assertResponse(200, 'Removing inline entity was successful.'); - - // Save the ief_test_complex node. - $this->drupalPostForm(NULL, [], t('Save')); - $this->assertResponse(200, 'Saving parent node was successful.'); - - // Checks that entity does nor appear in IEF. - $this->drupalGet('node/' . $parent_node->id() . '/edit'); - $this->assertNoText($title, 'Deleted inline entity is not present on the page after saving parent.'); - - // Checks that entity is not deleted. - $node = $this->drupalGetNodeByTitle($title, TRUE); - $this->assertTrue($node, 'Reference node not deleted'); - } - - /** - * Tests if referencing existing entities work. - */ - public function testReferencingExistingEntities() { - // Allow addition of existing nodes. - $this->updateSetting('allow_existing', TRUE); - - // Create three ief_reference_type entities. - $referenceNodes = $this->createReferenceContent(3); - - // Create a node for every bundle available. - $bundle_nodes = $this->createNodeForEveryBundle(); - - // Create ief_test_complex node with first ief_reference_type node and first - // node from bundle nodes. - $this->drupalCreateNode([ - 'type' => 'ief_test_complex', - 'title' => 'Some title', - 'multi' => [1], - 'all_bundles' => key($bundle_nodes), - ]); - // Remove first node since we already added it. - unset($bundle_nodes[key($bundle_nodes)]); - - $parent_node = $this->drupalGetNodeByTitle('Some title', TRUE); - - // Add remaining existing reference nodes. - $this->drupalGet('node/' . $parent_node->id() . '/edit'); - for ($i = 2; $i <= 3; $i++) { - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @value="Add existing node" and @data-drupal-selector="edit-multi-actions-ief-add-existing"]')); - $this->assertResponse(200, 'Opening reference form was successful.'); - $title = 'Some reference ' . $i; - $edit = [ - 'multi[form][entity_id]' => $title . ' (' . $referenceNodes[$title] . ')', - ]; - $this->drupalPostAjaxForm(NULL, $edit, $this->getButtonName('//input[@type="submit" and @data-drupal-selector="edit-multi-form-actions-ief-reference-save"]')); - $this->assertResponse(200, 'Adding new referenced entity was successful.'); - } - // Add all remaining nodes from all bundles. - foreach ($bundle_nodes as $id => $title) { - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @value="Add existing node" and @data-drupal-selector="edit-all-bundles-actions-ief-add-existing"]')); - $this->assertResponse(200, 'Opening reference form was successful.'); - $edit = [ - 'all_bundles[form][entity_id]' => $title . ' (' . $id . ')', - ]; - $this->drupalPostAjaxForm(NULL, $edit, $this->getButtonName('//input[@type="submit" and @data-drupal-selector="edit-all-bundles-form-actions-ief-reference-save"]')); - $this->assertResponse(200, 'Adding new referenced entity was successful.'); - } - // Save the node. - $this->drupalPostForm(NULL, [], t('Save')); - $this->assertResponse(200, 'Saving parent for was successful.'); - - // Check if entities are referenced. - $this->drupalGet('node/' . $parent_node->id() . '/edit'); - for ($i = 2; $i <= 3; $i++) { - $cell = $this->xpath('//table[@id="ief-entity-table-edit-multi-entities"]/tbody/tr[' . $i . ']/td[@class="inline-entity-form-node-label"]'); - $this->assertTrue($cell[0] == 'Some reference ' . $i, 'Found reference node title "Some reference ' . $i . '" in the IEF table.'); - } - // Check if all remaining nodes from all bundles are referenced. - $count = 2; - foreach ($bundle_nodes as $id => $title) { - $cell = $this->xpath('//table[@id="ief-entity-table-edit-all-bundles-entities"]/tbody/tr[' . $count . ']/td[@class="inline-entity-form-node-label"]'); - $this->assertTrue($cell[0] == $title, 'Found reference node title "' . $title . '" in the IEF table.'); - $count++; - } - } - - /** - * Test if invalid values get correct validation messages in reference existing entity form. - * - * Also checks if existing entity reference form can be canceled. - */ - public function testReferenceExistingValidation() { - $this->updateSetting('allow_existing', TRUE); - - $this->drupalGet('node/add/ief_test_complex'); - $this->checkExistingValidationExpectation('', 'Node field is required.'); - $this->checkExistingValidationExpectation('Fake Title', "There are no entities matching \"Fake Title\""); - // Check adding nodes that cannot be referenced by this field. - $bundle_nodes = $this->createNodeForEveryBundle(); - foreach ($bundle_nodes as $id => $title) { - $node = $this->nodeStorage->load($id); - if ($node->bundle() != 'ief_reference_type') { - $this->checkExistingValidationExpectation("$title ($id)", "The referenced entity (node: $id) does not exist."); - } - } - - $nodes = $this->createReferenceContent(2); - foreach ($nodes as $title => $id) { - $this->openMultiExistingForm(); - $edit = [ - 'multi[form][entity_id]' => "$title ($id)", - ]; - // Add a node successfully. - $this->drupalPostAjaxForm(NULL, $edit, $this->getButtonName('//input[@type="submit" and @data-drupal-selector="edit-multi-form-actions-ief-reference-save"]')); - $this->assertNoFieldByName('multi[form][entity_id]', NULL, 'Existing entity reference autocomplete field removed.'); - // Try to add the same node again. - $this->checkExistingValidationExpectation("$title ($id)", 'The selected node has already been added.'); - } - } - - /** - * Tests if duplicating entities works. - */ - public function testDuplicatingEntities() { - $this->updateSetting('allow_duplicate', TRUE); - - $referenceNodes = $this->createReferenceContent(2); - $this->drupalCreateNode([ - 'type' => 'ief_test_complex', - 'title' => 'Some title', - 'multi' => array_values($referenceNodes), - ]); - /** @var \Drupal\node\NodeInterface $node */ - $parent_node = $this->drupalGetNodeByTitle('Some title'); - - $this->drupalGet('node/' . $parent_node->id() . '/edit'); - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @id="edit-multi-entities-0-actions-ief-entity-duplicate"]')); - $this->assertResponse(200, 'Opening inline duplicate form was successful.'); - - $edit = [ - 'multi[form][inline_entity_form][entities][0][form][title][0][value]' => 'Duplicate!', - 'multi[form][inline_entity_form][entities][0][form][first_name][0][value]' => 'Bojan', - ]; - $this->drupalPostAjaxForm(NULL, $edit, $this->getButtonName('//input[@type="submit" and @data-drupal-selector="edit-multi-form-inline-entity-form-entities-0-form-actions-ief-duplicate-save"]')); - $this->assertResponse(200, 'Saving inline duplicate form was successful.'); - - $this->assertText('Some reference 1'); - $this->assertText('Some reference 2'); - $this->assertText('Duplicate!'); - $this->drupalPostForm(NULL, [], t('Save')); - $this->assertResponse(200, 'Saving parent entity was successful.'); - - // Confirm a duplicate was made. - $duplicate = Node::load(4); - $this->assertEqual($duplicate->label(), 'Duplicate!'); - $this->assertEqual($duplicate->first_name->value, 'Bojan'); - } - - /** - * Tests if a referenced content can be edited while the referenced content is - * newer than the referencing parent node. - */ - public function testEditedInlineEntityValidation() { - $this->updateSetting('allow_existing', TRUE); - - // Create referenced content. - $referenced_nodes = $this->createReferenceContent(1); - - // Create first referencing node. - $this->drupalCreateNode([ - 'type' => 'ief_test_complex', - 'title' => 'First referencing node', - 'multi' => array_values($referenced_nodes), - ]); - $first_node = $this->drupalGetNodeByTitle('First referencing node'); - - // Create second referencing node. - $this->drupalCreateNode([ - 'type' => 'ief_test_complex', - 'title' => 'Second referencing node', - 'multi' => array_values($referenced_nodes), - ]); - $second_node = $this->drupalGetNodeByTitle('Second referencing node'); - - // Edit referenced content in first node. - $this->drupalGet('node/' . $first_node->id() . '/edit'); - - // Edit referenced node. - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @value="Edit" and @data-drupal-selector="edit-multi-entities-0-actions-ief-entity-edit"]')); - $edit = [ - 'multi[form][inline_entity_form][entities][0][form][title][0][value]' => 'Some reference updated', - ]; - $this->drupalPostAjaxForm(NULL, $edit, $this->getButtonName('//input[@type="submit" and @value="Update node" and @data-drupal-selector="edit-multi-form-inline-entity-form-entities-0-form-actions-ief-edit-save"]')); - - // Save the first node after editing the reference. - $edit = ['title[0][value]' => 'First node updated']; - $this->drupalPostForm(NULL, $edit, t('Save')); - - // The changed value of the referenced content is now newer than the - // changed value of the second node. - - // Edit referenced content in second node. - $this->drupalGet('node/' . $second_node->id() . '/edit'); - - // Edit referenced node. - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @value="Edit" and @data-drupal-selector="edit-multi-entities-0-actions-ief-entity-edit"]')); - $edit = [ - 'multi[form][inline_entity_form][entities][0][form][title][0][value]' => 'Some reference updated the second time', - ]; - $this->drupalPostAjaxForm(NULL, $edit, $this->getButtonName('//input[@type="submit" and @value="Update node" and @data-drupal-selector="edit-multi-form-inline-entity-form-entities-0-form-actions-ief-edit-save"]')); - - // Save the second node after editing the reference. - $edit = ['title[0][value]' => 'Second node updated']; - $this->drupalPostForm(NULL, $edit, t('Save')); - - // Check if the referenced content could be edited. - $this->assertNoText('The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.', 'The referenced content could be edited.'); - } - - /** - * Creates ief_reference_type nodes which shall serve as reference nodes. - * - * @param int $numNodes - * The number of nodes to create - * @return array - * Array of created node ids keyed by labels. - */ - protected function createReferenceContent($numNodes = 3) { - $retval = []; - for ($i = 1; $i <= $numNodes; $i++) { - $this->drupalCreateNode([ - 'type' => 'ief_reference_type', - 'title' => 'Some reference ' . $i, - 'first_name' => 'First Name ' . $i, - 'last_name' => 'Last Name ' . $i, - ]); - $node = $this->drupalGetNodeByTitle('Some reference ' . $i); - $this->assertTrue($node, 'Created ief_reference_type node "' . $node->label() . '"'); - $retval[$node->label()] = $node->id(); - } - return $retval; - } - - /** - * Updates an IEF setting and saves the underlying entity display. - * - * @param string $name - * The name of the setting. - * @param mixed $value - * The value to set. - */ - protected function updateSetting($name, $value) { - /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $display */ - $display = $this->entityFormDisplayStorage->load('node.ief_test_complex.default'); - $component = $display->getComponent('multi'); - $component['settings'][$name] = $value; - $display->setComponent('multi', $component)->save(); - } - - /** - * Creates a node for every node bundle. - * - * @return array - * Array of node titles keyed by ids. - */ - protected function createNodeForEveryBundle() { - $retval = []; - $bundles = $this->container->get('entity.manager')->getBundleInfo('node'); - foreach ($bundles as $id => $value) { - $this->drupalCreateNode(['type' => $id, 'title' => $value['label']]); - $node = $this->drupalGetNodeByTitle($value['label']); - $this->assertTrue($node, 'Created node "' . $node->label() . '"'); - $retval[$node->id()] = $value['label']; - } - return $retval; - } - - /** - * Set up the ief_test_nested1 node add form. - * - * Sets the nested fields' required settings. - * Gets the form. - * Opens the inline entity forms if they are not required. - * - * @param bool $required - * Whether the fields are required. - * @param array $permissions - * (optional) Permissions to sign testing user in with. You may pass in an - * empty array (default) to use the all the permissions necessary create and - * edit nodes on the form. - */ - protected function setupNestedComplexForm($required, $permissions = []) { - /** @var \Drupal\Core\Field\FieldConfigInterface $ief_test_nested1 */ - $ief_test_nested1 = $this->fieldConfigStorage->load('node.ief_test_nested1.test_ref_nested1'); - $ief_test_nested1->setRequired($required); - $ief_test_nested1->save(); - /** @var \Drupal\Core\Field\FieldConfigInterface $ief_test_nested2 */ - $ief_test_nested2 = $this->fieldConfigStorage->load('node.ief_test_nested2.test_ref_nested2'); - $ief_test_nested2->setRequired($required); - $ief_test_nested2->save(); - - if (!$permissions) { - $permissions = [ - 'create ief_test_nested1 content', - 'create ief_test_nested2 content', - 'create ief_test_nested3 content', - 'edit any ief_test_nested1 content', - 'edit any ief_test_nested2 content', - 'edit any ief_test_nested3 content', - ]; - } - $this->user = $this->createUser($permissions); - $this->drupalLogin($this->user); - - $this->drupalGet('node/add/ief_test_nested1'); - - if (!$required) { - // Open inline forms if not required. - if (in_array('create ief_test_nested2 content', $permissions)) { - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @value="Add new node 2"]')); - } - if (in_array('create ief_test_nested3 content', $permissions)) { - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @value="Add new node 3"]')); - } - } - } - - /** - * Closes the existing node form on the "multi" field. - */ - protected function cancelExistingMultiForm($edit) { - $this->drupalPostAjaxForm(NULL, $edit, $this->getButtonName('//input[@type="submit" and @data-drupal-selector="edit-multi-form-actions-ief-reference-cancel"]')); - $this->assertNoFieldByName('multi[form][entity_id]', NULL, 'Existing entity reference autocomplete field removed.'); - } - - /** - * Opens the existing node form on the "multi" field. - */ - protected function openMultiExistingForm() { - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @value="Add existing node" and @data-drupal-selector="edit-multi-actions-ief-add-existing"]')); - $this->assertResponse(200, 'Opening reference form was successful.'); - $this->assertFieldByName('multi[form][entity_id]', NULL, 'Existing entity reference autocomplete field found.'); - } - - /** - * Checks that an invalid value for an existing node will be display the expected error. - * - * @param $existing_node_text - * The text to enter into the existing node text field. - * @param $expected_error - * The error message that is expected to be shown. - */ - protected function checkExistingValidationExpectation($existing_node_text, $expected_error) { - $edit = [ - 'multi[form][entity_id]' => $existing_node_text, - ]; - $this->openMultiExistingForm(); - - $this->drupalPostAjaxForm(NULL, $edit, $this->getButtonName('//input[@type="submit" and @data-drupal-selector="edit-multi-form-actions-ief-reference-save"]')); - $this->assertText($expected_error); - $this->cancelExistingMultiForm($edit); - } - - /** - * Tests entity create access is correct on nested IEF forms. - */ - public function testNestedEntityCreateAccess() { - $permissions = [ - 'create ief_test_nested1 content', - 'create ief_test_nested2 content', - ]; - $this->setupNestedComplexForm(TRUE, $permissions); - $this->assertFieldByName('title[0][value]'); - $this->assertFieldByName('test_ref_nested1[form][inline_entity_form][title][0][value]'); - $this->assertNoFieldByName('test_ref_nested1[form][inline_entity_form][test_ref_nested2][form][inline_entity_form][title][0][value]', NULL); - - $this->setupNestedComplexForm(FALSE, $permissions); - $this->assertNoFieldByXPath('//input[@type="submit" and @value="Add new node 3"]'); - } - - /** - * Tests create access on IEF Complex content type. - */ - public function testComplexEntityCreate() { - $user = $this->createUser([ - 'create ief_test_complex content', - ]); - $this->drupalLogin($user); - - $this->drupalGet('node/add/ief_test_complex'); - $this->assertNoFieldByName('all_bundles[actions][bundle]', NULL, 'Bundle select is not shown when only one bundle is available.'); - $this->assertNoFieldByName('multi[form][inline_entity_form][title][0][value]', NULL); - - $user = $this->createUser([ - 'create ief_test_complex content', - 'create ief_reference_type content' - ]); - $this->drupalLogin($user); - - $this->drupalGet('node/add/ief_test_complex'); - $this->assertFieldByName('all_bundles[actions][bundle]', NULL, 'Bundle select is shown when more than one bundle is available.'); - $this->assertOption('edit-all-bundles-actions-bundle', 'ief_reference_type'); - $this->assertOption('edit-all-bundles-actions-bundle', 'ief_test_complex'); - $this->assertFieldByName('multi[form][inline_entity_form][title][0][value]'); - } - - /** - * Checks if nested nodes for ief_test_nested1 content were created correctly. - * - * @param $nested1_title - * Expected title of top level node of the type ief_test_nested1 - * @param $nested2_title - * Expected title of second level node - * @param $nested3_title - * Expected title of third level node - */ - protected function checkNestedNodes($nested1_title, $nested2_title, $nested3_title) { - $nested1_node = $this->drupalGetNodeByTitle($nested1_title); - $this->assertEqual($nested1_title, $nested1_node->label(), "First node's title looks correct."); - $this->assertEqual('ief_test_nested1', $nested1_node->bundle(), "First node's type looks correct."); - if ($this->assertNotNull($nested1_node->test_ref_nested1->entity, 'Second node was created.')) { - $this->assertEqual($nested1_node->test_ref_nested1->count(), 1, 'Only 1 node created at first level.'); - $this->assertEqual($nested2_title, $nested1_node->test_ref_nested1->entity->label(), "Second node's title looks correct."); - $this->assertEqual('ief_test_nested2', $nested1_node->test_ref_nested1->entity->bundle(), "Second node's type looks correct."); - if ($this->assertNotNull($nested1_node->test_ref_nested1->entity->test_ref_nested2->entity, 'Third node was created')) { - $this->assertEqual($nested1_node->test_ref_nested1->entity->test_ref_nested2->count(), 1, 'Only 1 node created at second level.'); - $this->assertEqual($nested3_title, $nested1_node->test_ref_nested1->entity->test_ref_nested2->entity->label(), "Third node's title looks correct."); - $this->assertEqual('ief_test_nested3', $nested1_node->test_ref_nested1->entity->test_ref_nested2->entity->bundle(), "Third node's type looks correct."); - - $this->checkNestedEntityEditing($nested1_node, TRUE); - } - } - } - -} diff --git a/web/modules/inline_entity_form/src/Tests/ElementWebTest.php b/web/modules/inline_entity_form/src/Tests/ElementWebTest.php deleted file mode 100644 index 44686e884c..0000000000 --- a/web/modules/inline_entity_form/src/Tests/ElementWebTest.php +++ /dev/null @@ -1,82 +0,0 @@ -<?php - -namespace Drupal\inline_entity_form\Tests; - -/** - * Tests the IEF element on a custom form. - * - * @group inline_entity_form - */ -class ElementWebTest extends InlineEntityFormTestBase { - - /** - * Modules to enable. - * - * @var array - */ - public static $modules = ['inline_entity_form_test']; - - /** - * Prepares environment for - */ - protected function setUp() { - 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 testCustomFormIEF() { - $form_mode_possibilities = [ - 'default', - 'inline', - ]; - foreach ($form_mode_possibilities as $form_mode_possibility) { - $title = $this->randomMachineName(); - $this->drupalGet("ief-test/$form_mode_possibility"); - $this->assertText(t('Title'), 'Title field found on the form.'); - $this->assertText(t('Positive int'), 'Positive int field found on form.'); - $this->checkFormDisplayFields("node.ief_test_custom.$form_mode_possibility", 'inline_entity_form'); - - $edit = []; - $this->drupalPostForm('ief-test', $edit, t('Save')); - $this->assertText('Title field is required.'); - $this->assertNoNodeByTitle($title); - - $edit['inline_entity_form[title][0][value]'] = $title; - $edit['inline_entity_form[positive_int][0][value]'] = -1; - $this->drupalPostForm('ief-test', $edit, t('Save')); - $this->assertText('Positive int must be higher than or equal to 1'); - $this->assertNoNodeByTitle($title); - - $edit['inline_entity_form[positive_int][0][value]'] = 11; - $this->drupalPostForm('ief-test', $edit, t('Save')); - $message = t('Created @entity_type @label.', ['@entity_type' => t('Content'), '@label' => $edit['inline_entity_form[title][0][value]']]); - $this->assertText($message, 'Status message found on the page.'); - $this->assertNodeByTitle($title, 'ief_test_custom'); - - if ($node = $this->getNodeByTitle($title)) { - $this->drupalGet("ief-test/$form_mode_possibility/{$node->id()}"); - $this->assertFieldByName('inline_entity_form[title][0][value]', $title, 'Node title appears in form.'); - $this->checkFormDisplayFields("node.ief_test_custom.$form_mode_possibility", 'inline_entity_form'); - $this->assertFieldByName('inline_entity_form[positive_int][0][value]', 11, 'Positive int field appears in form.'); - $updated_title = $title . ' - updated'; - $edit['inline_entity_form[title][0][value]'] = $updated_title; - $this->drupalPostForm(NULL, $edit, t('Update')); - $this->assertNodeByTitle($updated_title, 'ief_test_custom'); - } - } - } - -} diff --git a/web/modules/inline_entity_form/src/Tests/InlineEntityFormTestBase.php b/web/modules/inline_entity_form/src/Tests/InlineEntityFormTestBase.php deleted file mode 100644 index d3a399f05e..0000000000 --- a/web/modules/inline_entity_form/src/Tests/InlineEntityFormTestBase.php +++ /dev/null @@ -1,188 +0,0 @@ -<?php - -namespace Drupal\inline_entity_form\Tests; - -use Drupal\simpletest\WebTestBase; - -/** - * Base Class for Inline Entity Form Tests. - */ -abstract class InlineEntityFormTestBase extends WebTestBase { - - /** - * User with permissions to create content. - * - * @var \Drupal\user\Entity\User - */ - protected $user; - - /** - * Node storage. - * - * @var \Drupal\Core\Entity\ContentEntityStorageInterface; - */ - protected $nodeStorage; - - /** - * Field config storage. - * - * @var \Drupal\Core\Config\Entity\ConfigEntityStorage - */ - protected $fieldStorageConfigStorage; - - /** - * Field config storage. - * - * @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface - */ - protected $fieldConfigStorage; - - /** - * {@inheritdoc} - */ - protected function setUp() { - parent::setUp(); - $this->nodeStorage = $this->container->get('entity_type.manager')->getStorage('node'); - $this->fieldStorageConfigStorage = $this->container->get('entity_type.manager')->getStorage('field_storage_config'); - $this->fieldConfigStorage = $this->container->get('entity_type.manager')->getStorage('field_config'); - } - - - /** - * Gets IEF button name. - * - * @param array $xpath - * Xpath of the button. - * - * @return string - * The name of the button. - */ - protected function getButtonName($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 $title - * Node title to check. - * @param $message - * Message to display. - */ - protected function assertNoNodeByTitle($title, $message = '') { - if (!$message) { - $message = "No node with title: $title"; - } - $node = $this->getNodeByTitle($title); - - $this->assertTrue(empty($node), $message); - } - - /** - * Passes if node is found for the title. - * - * @param $title - * Node title to check. - * @param $message - * Message to display. - */ - protected function assertNodeByTitle($title, $bundle = NULL, $message = '') { - if (!$message) { - $message = "Node with title found: $title"; - } - $node = $this->getNodeByTitle($title); - if ($this->assertTrue(!empty($node), $message)) { - if ($bundle) { - $this->assertEqual($node->bundle(), $bundle, "Node is correct bundle: $bundle"); - } - } - } - - /** - * 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($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(); - $query->condition($label_key, $label); - - if ($bundle && $bundle_key) { - $query->condition($bundle_key, $bundle); - } - - $result = $query->execute(); - $this->assertTrue(!empty($result)); - } - - /** - * Checks for check correct fields on form displays based on exported config - * in inline_entity_form_test module. - * - * @param $form_display - * The form display to check. - */ - protected function checkFormDisplayFields($form_display, $prefix) { - $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 ($fields = $form_display_fields[$form_display]) { - $this->assert('debug', 'Checking form dispaly: ' . $form_display); - foreach ($fields['expected'] as $expected_field) { - $this->assertFieldByName($prefix . $expected_field); - } - foreach ($fields['unexpected'] as $unexpected_field) { - $this->assertNoFieldByName($prefix . $unexpected_field, NULL); - } - } - else { - // Test calling unexported form display if we are here. - throw new \Exception('Form display not found: ' . $form_display); - } - } - -} diff --git a/web/modules/inline_entity_form/src/Tests/SimpleWidgetWebTest.php b/web/modules/inline_entity_form/src/Tests/SimpleWidgetWebTest.php deleted file mode 100644 index 531c602129..0000000000 --- a/web/modules/inline_entity_form/src/Tests/SimpleWidgetWebTest.php +++ /dev/null @@ -1,248 +0,0 @@ -<?php - -namespace Drupal\inline_entity_form\Tests; - -use Drupal\Core\Field\FieldStorageDefinitionInterface; -use Drupal\node\NodeInterface; - -/** - * Tests the IEF simple widget. - * - * @group inline_entity_form - */ -class SimpleWidgetWebTest extends InlineEntityFormTestBase { - - /** - * Modules to enable. - * - * @var array - */ - public static $modules = ['inline_entity_form_test']; - - /** - * Prepares environment for - */ - protected function setUp() { - 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. - * - * @throws \Exception - */ - protected function testSimpleCardinalityOptions() { - $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 => $limit) { - $field_storage->setCardinality($cardinality); - $field_storage->save(); - - $this->drupalGet('node/add/ief_simple_single'); - - $this->assertText('Single node', 'Inline entity field widget title found.'); - $this->assertText('Reference a single node.', 'Inline entity field description found.'); - - $add_more_xpath = '//input[@data-drupal-selector="edit-single-add-more"]'; - if ($cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) { - $this->assertFieldByXPath($add_more_xpath, NULL, 'Add more button exists'); - } - else { - $this->assertNoFieldByXPath($add_more_xpath, NULL, 'Add more button does NOT exist'); - } - - $host_title = 'Host node cardinality: ' . $cardinality; - $edit = ['title[0][value]' => $host_title]; - for ($item_number = 0; $item_number < $limit; $item_number++) { - $edit["single[$item_number][inline_entity_form][title][0][value]"] = 'Child node nr.' . $item_number; - if ($cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) { - $next_item_number = $item_number + 1; - $this->assertNoFieldByName("single[$next_item_number][inline_entity_form][title][0][value]", NULL, "Item $next_item_number does not appear before 'Add More' clicked"); - if ($item_number < $limit - 1) { - $this->drupalPostAjaxForm(NULL, $edit, 'single_add_more'); - $this->assertFieldByName("single[$next_item_number][inline_entity_form][title][0][value]", NULL, "Item $next_item_number does appear after 'Add More' clicked"); - // Make sure only 1 item is added. - $unexpected_item_number = $next_item_number + 1; - $this->assertNoFieldByName("single[$unexpected_item_number][inline_entity_form][title][0][value]", NULL, "Extra Item $unexpected_item_number is not added after 'Add More' clicked"); - } - } - } - $this->drupalPostForm(NULL, $edit, t('Save')); - - for ($item_number = 0; $item_number < $limit; $item_number++) { - $this->assertText('Child node nr.' . $item_number, 'Label of referenced entity found.'); - } - - $host_node = $this->getNodeByTitle($host_title); - $this->checkEditAccess($host_node, $limit, $cardinality); - } - } - - /** - * Test Validation on Simple Widget. - * - * @throws \Exception - */ - protected function testSimpleValidation() { - $this->drupalLogin($this->user); - $host_node_title = 'Host Validation Node'; - $this->drupalGet('node/add/ief_simple_single'); - - $this->assertText('Single node', 'Inline entity field widget title found.'); - $this->assertText('Reference a single node.', 'Inline entity field description found.'); - $this->assertText('Positive int', 'Positive int field found.'); - - $edit = ['title[0][value]' => $host_node_title]; - $this->drupalPostForm(NULL, $edit, t('Save')); - - $this->assertText('Title field is required.', 'Title validation fires on Inline Entity Form widget.'); - $this->assertUrl('node/add/ief_simple_single', [], 'On add page after validation error.'); - - $child_title = 'Child node ' . $this->randomString(); - $edit['single[0][inline_entity_form][title][0][value]'] = $child_title; - $edit['single[0][inline_entity_form][positive_int][0][value]'] = -1; - $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertNoText('Title field is required.', 'Title validation passes on Inline Entity Form widget.'); - $this->assertText('Positive int must be higher than or equal to 1', 'Field validation fires on Inline Entity Form widget.'); - $this->assertUrl('node/add/ief_simple_single', [], 'On add page after validation error.'); - - $edit['single[0][inline_entity_form][positive_int][0][value]'] = 1; - $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertNoText('Title field is required.', 'Title validation passes on Inline Entity Form widget.'); - $this->assertNoText('Positive int must be higher than or equal to 1', 'Field validation fires on Inline Entity Form widget.'); - - // Check that nodes were created correctly. - $host_node = $this->getNodeByTitle($host_node_title); - if ($this->assertNotNull($host_node, 'Host node created.')) { - $this->assertUrl('node/' . $host_node->id(), [], 'On node view page after node add.'); - $child_node = $this->getNodeByTitle($child_title); - if ($this->assertNotNull($child_node)) { - $this->assertEqual($host_node->single[0]->target_id, $child_node->id(), 'Child node is referenced'); - $this->assertEqual($child_node->positive_int[0]->value, 1, 'Child node int field correct.'); - $this->assertEqual($child_node->bundle(), 'ief_test_custom', 'Child node is correct bundle.'); - } - } - } - - /** - * Tests if the entity create access works in simple widget. - */ - public function testSimpleCreateAccess() { - // Create a user who does not have access to create ief_test_custom nodes. - $this->user = $this->createUser([ - 'create ief_simple_single content', - ]); - $this->drupalLogin($this->user); - $this->drupalGet('node/add/ief_simple_single'); - $this->assertNoFieldByName('single[0][inline_entity_form][title][0][value]', NULL); - } - - /** - * Tests that user only has access to the their own nodes. - * - * @param \Drupal\node\Entity\Node $host_node - * The node of the type of ief_simple_single - * @param int $child_count - * The number of entity reference values in the "single" field. - */ - protected function checkEditAccess(NodeInterface $host_node, $child_count, $cardinality) { - $other_user = $this->createUser([ - 'edit own ief_test_custom content', - 'edit any ief_simple_single content', - ]); - /** @var \Drupal\node\Entity\Node $first_child_node */ - $first_child_node = $host_node->single[0]->entity; - $first_child_node->setOwner($other_user); - $first_child_node->save(); - $this->drupalGet("node/{$host_node->id()}/edit"); - $this->assertText($first_child_node->label()); - $this->assertNoFieldByName('single[0][inline_entity_form][title][0][value]', NULL, 'Form of child node with no edit access is not found.'); - // Check that the forms for other child nodes(if any) appear on the form. - $delta = 1; - while ($delta < $child_count) { - /** @var \Drupal\node\Entity\Node $child_node */ - $child_node = $host_node->single[$delta]->entity; - $this->assertFieldByName("single[$delta][inline_entity_form][title][0][value]", $child_node->label(), 'Form of child node with edit access is found.'); - $delta++; - } - // Check that there is NOT an extra "add" form when editing. - $unexpected_item_number = $child_count; - $this->assertNoFieldByName("single[$unexpected_item_number][inline_entity_form][title][0][value]", NULL, 'No empty "add" entity form is found on edit.'); - if ($cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) { - $next_item_number = $child_count; - $this->drupalPostAjaxForm(NULL, [], 'single_add_more'); - $this->assertFieldByName("single[$next_item_number][inline_entity_form][title][0][value]", NULL, "Item $next_item_number does appear after 'Add More' clicked"); - // Make sure only 1 item is added. - $unexpected_item_number = $next_item_number + 1; - $this->assertNoFieldByName("single[$unexpected_item_number][inline_entity_form][title][0][value]", NULL, "Extra Item $unexpected_item_number is not added after 'Add More' clicked"); - } - - // Now that we have confirmed the correct fields appear, lets update the - // values and save them. We do not have access to 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 < $child_count) { - /** @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_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->drupalPostForm(NULL, $edit, t('Save')); - $this->assertText("IEF single simple {$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->nodeStorage->resetCache($node_ids); - $host_node = $this->nodeStorage->load($host_node->id()); - // Check that titles were updated. - foreach ($new_titles as $delta => $new_title) { - $child_node = $host_node->single[$delta]->entity; - $this->assertEqual($child_node->label(), $new_title, "Child $delta node title updated"); - } - } - - /** - * Ensures that an entity without bundles can be used with the simple widget. - */ - public function testEntityWithoutBundle() { - $this->drupalLogin($this->user); - - $edit = [ - 'title[0][value]' => 'Node title', - 'field_ief_entity_no_bundle[0][inline_entity_form][name][0][value]' => 'Entity title', - ]; - $this->drupalPostForm('node/add/ief_simple_entity_no_bundle', $edit, 'Save'); - - $this->assertNodeByTitle('Node title', 'ief_simple_entity_no_bundle'); - $this->assertEntityByLabel('Entity title', 'entity_test__without_bundle'); - } - -} diff --git a/web/modules/inline_entity_form/src/Tests/TranslationTest.php b/web/modules/inline_entity_form/src/Tests/TranslationTest.php deleted file mode 100644 index b58949702b..0000000000 --- a/web/modules/inline_entity_form/src/Tests/TranslationTest.php +++ /dev/null @@ -1,173 +0,0 @@ -<?php - -namespace Drupal\inline_entity_form\Tests; - -use Drupal\node\Entity\Node; - -/** - * Tests translating inline entities. - * - * @group inline_entity_form - */ -class TranslationTest extends InlineEntityFormTestBase { - - /** - * Modules to enable. - * - * @var array - */ - public static $modules = [ - 'content_translation', 'inline_entity_form_test', 'language', - ]; - - /** - * {@inheritdoc} - */ - protected function setUp() { - 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); - - // Enable translations for both entity types. - $edit = [ - 'entity_types[node]' => TRUE, - ]; - foreach (['ief_test_complex', 'ief_reference_type'] as $node_type) { - $edit['settings[node][' . $node_type . '][translatable]'] = TRUE; - $edit['settings[node][' . $node_type . '][settings][language][language_alterable]'] = TRUE; - } - $this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration')); - - // 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. - */ - protected function testTranslation() { - // Create a German node with a French translation. - $first_inline_node = Node::create([ - 'type' => 'ief_reference_type', - 'langcode' => 'de', - 'title' => 'An inline node', - 'first_name' => 'Dieter', - ]); - $translation = $first_inline_node->toArray(); - $translation['title'][0]['value'] = 'An inline node in French'; - $translation['first_name'][0]['value'] = 'Pierre'; - $first_inline_node->addTranslation('fr', $translation); - $first_inline_node->save(); - - $this->drupalGet('node/add/ief_test_complex'); - // Reference the German node. - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @value="Add existing node" and @data-drupal-selector="edit-multi-actions-ief-add-existing"]')); - $edit = [ - 'multi[form][entity_id]' => 'An inline node (' . $first_inline_node->id() . ')', - ]; - $this->drupalPostAjaxForm(NULL, $edit, $this->getButtonName('//input[@type="submit" and @data-drupal-selector="edit-multi-form-actions-ief-reference-save"]')); - $this->assertResponse(200, 'Adding a new referenced entity was successful.'); - - // Add a new English inline node. - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @value="Add new node" and @data-drupal-selector="edit-multi-actions-ief-add"]')); - $edit = [ - 'multi[form][inline_entity_form][title][0][value]' => 'Another inline node', - 'multi[form][inline_entity_form][first_name][0][value]' => 'John', - 'multi[form][inline_entity_form][last_name][0][value]' => 'Smith', - ]; - $this->drupalPostAjaxForm(NULL, $edit, $this->getButtonName('//input[@type="submit" and @value="Create node" and @data-drupal-selector="edit-multi-form-inline-entity-form-actions-ief-add-save"]')); - $this->assertResponse(200, 'Creating a new inline entity was successful.'); - - $edit = [ - 'title[0][value]' => 'A node', - 'langcode[0][value]' => 'en', - ]; - $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertResponse(200, 'Saving the parent entity was successful.'); - - // Both inline nodes should now be in English. - $first_inline_node = $this->drupalGetNodeByTitle('An inline node'); - $second_inline_node = $this->drupalGetNodeByTitle('Another inline node'); - $this->assertEqual($first_inline_node->get('langcode')->value, 'en', 'The first inline entity has the correct langcode.'); - $this->assertEqual($second_inline_node->get('langcode')->value, 'en', 'The second inline entity has the correct langcode.'); - - // Edit the node, change the source language to German. - $node = $this->drupalGetNodeByTitle('A node'); - $this->drupalGet('node/' . $node->id() . '/edit'); - $edit = [ - 'langcode[0][value]' => 'de', - ]; - $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertResponse(200, 'Saving the parent entity was successful.'); - - // Both inline nodes should now be in German. - $first_inline_node = $this->drupalGetNodeByTitle('An inline node', TRUE); - $second_inline_node = $this->drupalGetNodeByTitle('Another inline node', TRUE); - $this->assertEqual($first_inline_node->get('langcode')->value, 'de', 'The first inline entity has the correct langcode.'); - $this->assertEqual($second_inline_node->get('langcode')->value, 'de', 'The second inline entity has the correct langcode.'); - - // Add a German -> French translation. - $this->drupalGet('node/' . $node->id() . '/translations/add/de/fr'); - - // Confirm that the translatability clue has been removed. - $widget_title_element = $this->xpath('//fieldset[@id="edit-multi"]/legend/span'); - $this->assertEqual((string) $widget_title_element[0], 'Multiple nodes', 'The widget has the expected title.'); - // Confirm that the add and remove buttons are not present. - $this->assertFalse((bool) $this->xpath('//input[@type="submit" and @value="Add new node" and @data-drupal-selector="edit-multi-actions-ief-add"]'), 'Add new node button does not appear in the table.'); - $this->assertFalse((bool) $this->xpath('//input[@type="submit" and @value="Remove"]'), 'Remove button does not appear in the table.'); - // Confirm the presence of the two node titles, in the expected languages. - $this->assertTrue((bool) $this->xpath('//td[@class="inline-entity-form-node-label" and contains(.,"An inline node in French")]'), 'First inline node title appears in the table'); - $this->assertTrue((bool) $this->xpath('//td[@class="inline-entity-form-node-label" and contains(.,"Another inline node")]'), 'Second node title appears in the table'); - - // Edit the translations of both inline entities. - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @value="Edit" and @data-drupal-selector="edit-multi-entities-0-actions-ief-entity-edit"]')); - $this->assertNoText('Last name', 'The non-translatable last_name field is hidden.'); - $edit = [ - 'multi[form][inline_entity_form][entities][0][form][title][0][value]' => 'An inline node in French!', - 'multi[form][inline_entity_form][entities][0][form][first_name][0][value]' => 'Damien', - ]; - $this->drupalPostAjaxForm(NULL, $edit, $this->getButtonName('//input[@type="submit" and @value="Update node" and @data-drupal-selector="edit-multi-form-inline-entity-form-entities-0-form-actions-ief-edit-save"]')); - - $this->drupalPostAjaxForm(NULL, [], $this->getButtonName('//input[@type="submit" and @value="Edit" and @data-drupal-selector="edit-multi-entities-1-actions-ief-entity-edit"]')); - $edit = [ - 'multi[form][inline_entity_form][entities][1][form][title][0][value]' => 'Another inline node in French!', - 'multi[form][inline_entity_form][entities][1][form][first_name][0][value]' => 'Jacques', - ]; - $this->drupalPostAjaxForm(NULL, $edit, $this->getButtonName('//input[@type="submit" and @value="Update node" and @data-drupal-selector="edit-multi-form-inline-entity-form-entities-1-form-actions-ief-edit-save"]')); - - $this->drupalPostForm(NULL, [], t('Save (this translation)')); - $this->assertResponse(200, 'Saving the parent entity was successful.'); - - // Load using the original titles, confirming they haven't changed. - $first_inline_node = $this->drupalGetNodeByTitle('An inline node', TRUE); - $second_inline_node = $this->drupalGetNodeByTitle('Another inline node', TRUE); - // Confirm that the expected translated values are present. - $this->assertTrue($first_inline_node->hasTranslation('fr'), 'The first inline entity has a FR translation'); - $this->assertTrue($second_inline_node->hasTranslation('fr'), 'The second inline entity has a FR translation'); - $first_translation = $first_inline_node->getTranslation('fr'); - $this->assertEqual($first_translation->title->value, 'An inline node in French!'); - $this->assertEqual($first_translation->first_name->value, 'Damien'); - $second_translation = $second_inline_node->getTranslation('fr'); - $this->assertEqual($second_translation->title->value, 'Another inline node in French!'); - $this->assertEqual($second_translation->first_name->value, 'Jacques'); - } - -} diff --git a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_complex_simple.default.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_complex_simple.default.yml index a82aa29724..e81fe9a830 100644 --- a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_complex_simple.default.yml +++ b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_complex_simple.default.yml @@ -57,6 +57,7 @@ content: weight: 5 settings: match_operator: CONTAINS + match_limit: 10 size: 60 placeholder: '' third_party_settings: { } diff --git a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_reference_type.default.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_reference_type.default.yml index 90883dfd34..646b6e37e2 100644 --- a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_reference_type.default.yml +++ b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_reference_type.default.yml @@ -51,6 +51,7 @@ content: weight: 5 settings: match_operator: CONTAINS + match_limit: 10 size: 60 placeholder: '' third_party_settings: { } diff --git a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_simple_entity_no_bundle.default.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_simple_entity_no_bundle.default.yml index a320b9430b..ed578fe369 100644 --- a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_simple_entity_no_bundle.default.yml +++ b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_simple_entity_no_bundle.default.yml @@ -50,8 +50,8 @@ content: weight: 5 settings: match_operator: CONTAINS + match_limit: 10 size: 60 placeholder: '' third_party_settings: { } hidden: { } - diff --git a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_simple_single.default.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_simple_single.default.yml index 3ac6ae71f7..634199ed68 100644 --- a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_simple_single.default.yml +++ b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_simple_single.default.yml @@ -37,6 +37,7 @@ content: weight: 5 settings: match_operator: CONTAINS + match_limit: 10 size: 60 placeholder: '' third_party_settings: { } diff --git a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_test_complex.default.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_test_complex.default.yml index 0e4cbf68c7..746d7f8c90 100644 --- a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_test_complex.default.yml +++ b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_test_complex.default.yml @@ -37,6 +37,7 @@ content: weight: 5 settings: match_operator: CONTAINS + match_limit: 10 size: 60 placeholder: '' third_party_settings: { } diff --git a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_test_custom.default.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_test_custom.default.yml index 07d71a96f5..8ba9401755 100644 --- a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_test_custom.default.yml +++ b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_test_custom.default.yml @@ -44,6 +44,7 @@ content: weight: 5 settings: match_operator: CONTAINS + match_limit: 10 size: 60 placeholder: '' third_party_settings: { } diff --git a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_test_nested1.default.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_test_nested1.default.yml index 6abd3d8875..9ca5c25748 100644 --- a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_test_nested1.default.yml +++ b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_test_nested1.default.yml @@ -37,6 +37,7 @@ content: weight: 5 settings: match_operator: CONTAINS + match_limit: 10 size: 60 placeholder: '' third_party_settings: { } diff --git a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_test_nested2.default.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_test_nested2.default.yml index d97bd49e05..f50c43385c 100644 --- a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_test_nested2.default.yml +++ b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_test_nested2.default.yml @@ -37,6 +37,7 @@ content: weight: 5 settings: match_operator: CONTAINS + match_limit: 10 size: 60 placeholder: '' third_party_settings: { } diff --git a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_test_nested3.default.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_test_nested3.default.yml index 8394cc3506..3700da6d3f 100644 --- a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_test_nested3.default.yml +++ b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/core.entity_form_display.node.ief_test_nested3.default.yml @@ -37,6 +37,7 @@ content: weight: 5 settings: match_operator: CONTAINS + match_limit: 10 size: 60 placeholder: '' third_party_settings: { } diff --git a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/field.field.node.ief_simple_entity_no_bundle.field_ief_entity_no_bundle.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/field.field.node.ief_simple_entity_no_bundle.field_ief_entity_no_bundle.yml index be73463eb5..f0e0cee7af 100644 --- a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/field.field.node.ief_simple_entity_no_bundle.field_ief_entity_no_bundle.yml +++ b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/field.field.node.ief_simple_entity_no_bundle.field_ief_entity_no_bundle.yml @@ -23,4 +23,3 @@ settings: field: _none auto_create: false field_type: entity_reference - diff --git a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/field.storage.node.field_ief_entity_no_bundle.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/field.storage.node.field_ief_entity_no_bundle.yml index 9b21f692ac..105911519f 100644 --- a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/field.storage.node.field_ief_entity_no_bundle.yml +++ b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/field.storage.node.field_ief_entity_no_bundle.yml @@ -18,4 +18,3 @@ translatable: true indexes: { } persist_with_no_fields: false custom_storage: false - diff --git a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/node.type.ief_simple_entity_no_bundle.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/node.type.ief_simple_entity_no_bundle.yml index dfd0b7bde1..c1220552a5 100644 --- a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/node.type.ief_simple_entity_no_bundle.yml +++ b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/install/node.type.ief_simple_entity_no_bundle.yml @@ -8,4 +8,3 @@ help: '' new_revision: true preview_mode: 1 display_submitted: true - diff --git a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.base_field_override.node.err_level_1.promote.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.base_field_override.node.err_level_1.promote.yml new file mode 100644 index 0000000000..4ddf2dfdd0 --- /dev/null +++ b/web/modules/inline_entity_form/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/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.base_field_override.node.err_level_2.promote.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.base_field_override.node.err_level_2.promote.yml new file mode 100644 index 0000000000..cb90dffd2f --- /dev/null +++ b/web/modules/inline_entity_form/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/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.base_field_override.node.err_level_3.promote.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.base_field_override.node.err_level_3.promote.yml new file mode 100644 index 0000000000..39c23b6b8c --- /dev/null +++ b/web/modules/inline_entity_form/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/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_form_display.node.err_level_1.default.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_form_display.node.err_level_1.default.yml new file mode 100644 index 0000000000..322840859d --- /dev/null +++ b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_form_display.node.err_level_1.default.yml @@ -0,0 +1,62 @@ +langcode: en +status: true +dependencies: + config: + - field.field.node.err_level_1.field_level_2_entity_no_bundle + - 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_entity_no_bundle: + weight: 32 + settings: + form_mode: compact + revision: true + label_singular: '' + label_plural: '' + allow_new: true + match_operator: CONTAINS + override_labels: false + collapsible: false + collapsed: false + allow_existing: false + allow_duplicate: false + third_party_settings: { } + type: inline_entity_form_complex + region: 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 + revision: true + collapsible: false + collapsed: false + allow_duplicate: false + third_party_settings: { } + type: inline_entity_form_complex + region: content + title: + type: string_textfield + weight: -5 + settings: + size: 60 + placeholder: '' + third_party_settings: { } + region: content +hidden: + created: true + path: true + promote: true + sticky: true + uid: true diff --git a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_form_display.node.err_level_2.default.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_form_display.node.err_level_2.default.yml new file mode 100644 index 0000000000..849b2b4030 --- /dev/null +++ b/web/modules/inline_entity_form/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/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_form_display.node.err_level_3.default.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_form_display.node.err_level_3.default.yml new file mode 100644 index 0000000000..7d94d96b48 --- /dev/null +++ b/web/modules/inline_entity_form/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/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_1.default.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_1.default.yml new file mode 100644 index 0000000000..b3de56d890 --- /dev/null +++ b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_1.default.yml @@ -0,0 +1,34 @@ +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_entity_no_bundle: + weight: 102 + label: above + settings: + view_mode: default + link: '' + third_party_settings: { } + type: entity_reference_revisions_entity_view + region: 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/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_1.teaser.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_1.teaser.yml new file mode 100644 index 0000000000..ea334e8d86 --- /dev/null +++ b/web/modules/inline_entity_form/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/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_2.default.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_2.default.yml new file mode 100644 index 0000000000..7a2e001c84 --- /dev/null +++ b/web/modules/inline_entity_form/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/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_2.teaser.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_2.teaser.yml new file mode 100644 index 0000000000..8ccdf1503c --- /dev/null +++ b/web/modules/inline_entity_form/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/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_3.default.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_3.default.yml new file mode 100644 index 0000000000..d3de6a5dce --- /dev/null +++ b/web/modules/inline_entity_form/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/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_3.teaser.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/core.entity_view_display.node.err_level_3.teaser.yml new file mode 100644 index 0000000000..c119fd326a --- /dev/null +++ b/web/modules/inline_entity_form/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/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/field.field.node.err_level_1.field_level_2_entity_no_bundle.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/field.field.node.err_level_1.field_level_2_entity_no_bundle.yml new file mode 100644 index 0000000000..5906fffca3 --- /dev/null +++ b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/field.field.node.err_level_1.field_level_2_entity_no_bundle.yml @@ -0,0 +1,27 @@ +uuid: 616ca481-7579-4873-aee6-6aaf74375d7b +langcode: en +status: true +dependencies: + config: + - field.storage.node.field_level_2_entity_no_bundle + - node.type.err_level_1 + module: + - entity_reference_revisions +id: node.err_level_1.field_level_2_entity_no_bundle +field_name: field_level_2_entity_no_bundle +entity_type: node +bundle: err_level_1 +label: 'Test entity no bundle' +description: '' +required: false +translatable: false +default_value: { } +default_value_callback: '' +settings: + handler: 'default:entity_test_no_bundle' + handler_settings: + target_bundles: null + sort: + field: _none + auto_create: false +field_type: entity_reference_revisions diff --git a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/field.field.node.err_level_1.field_level_2_items.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/field.field.node.err_level_1.field_level_2_items.yml new file mode 100644 index 0000000000..025d09ce17 --- /dev/null +++ b/web/modules/inline_entity_form/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/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/field.field.node.err_level_2.field_level_3_items.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/field.field.node.err_level_2.field_level_3_items.yml new file mode 100644 index 0000000000..e285cec7b3 --- /dev/null +++ b/web/modules/inline_entity_form/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/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/field.storage.node.field_level_2_entity_no_bundle.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/field.storage.node.field_level_2_entity_no_bundle.yml new file mode 100644 index 0000000000..bb09a02cb3 --- /dev/null +++ b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/field.storage.node.field_level_2_entity_no_bundle.yml @@ -0,0 +1,21 @@ +uuid: 2111cc32-c893-4518-864a-74aed74266c7 +langcode: en +status: true +dependencies: + module: + - entity_reference_revisions + - entity_test + - node +id: node.field_level_2_entity_no_bundle +field_name: field_level_2_entity_no_bundle +entity_type: node +type: entity_reference_revisions +settings: + target_type: entity_test_no_bundle +module: entity_reference_revisions +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/field.storage.node.field_level_2_items.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/field.storage.node.field_level_2_items.yml new file mode 100644 index 0000000000..1070cc3fc1 --- /dev/null +++ b/web/modules/inline_entity_form/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/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/field.storage.node.field_level_3_items.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/field.storage.node.field_level_3_items.yml new file mode 100644 index 0000000000..757c48a72a --- /dev/null +++ b/web/modules/inline_entity_form/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/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/node.type.err_level_1.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/node.type.err_level_1.yml new file mode 100644 index 0000000000..4865eb9e31 --- /dev/null +++ b/web/modules/inline_entity_form/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/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/node.type.err_level_2.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/node.type.err_level_2.yml new file mode 100644 index 0000000000..289dc9dc81 --- /dev/null +++ b/web/modules/inline_entity_form/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/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/node.type.err_level_3.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/config/optional/node.type.err_level_3.yml new file mode 100644 index 0000000000..b22f916962 --- /dev/null +++ b/web/modules/inline_entity_form/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 diff --git a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/inline_entity_form_test.info.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/inline_entity_form_test.info.yml index 699134915f..254568bd5a 100644 --- a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/inline_entity_form_test.info.yml +++ b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/inline_entity_form_test.info.yml @@ -1,17 +1,15 @@ name: 'IEF test' type: module description: 'Support module for the Inline entity form module tests.' -# core: 8.x +core_version_requirement: ^8.7.7 || ^9 package: Testing -# version: VERSION dependencies: - - inline_entity_form - - node - - file - - image + - inline_entity_form:inline_entity_form + - drupal:node + - drupal:file + - drupal:image -# Information added by Drupal.org packaging script on 2018-05-22 -version: '8.x-1.0-rc1' -core: '8.x' +# Information added by Drupal.org packaging script on 2020-05-12 +version: '8.x-1.0-rc6' project: 'inline_entity_form' -datestamp: 1527030788 +datestamp: 1589280849 diff --git a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/src/IefTest.php b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/src/IefTest.php index 344ee7c587..dc27f81100 100644 --- a/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/src/IefTest.php +++ b/web/modules/inline_entity_form/tests/modules/inline_entity_form_test/src/IefTest.php @@ -45,7 +45,8 @@ public function buildForm(array $form, FormStateInterface $form_state, $form_mod */ public function submitForm(array &$form, FormStateInterface $form_state) { $entity = $form['inline_entity_form']['#entity']; - drupal_set_message(t('Created @entity_type @label.', ['@entity_type' => $entity->getEntityType()->getLabel(), '@label' => $entity->label()])); + $message = $this->t('Created @entity_type @label.', ['@entity_type' => $entity->getEntityType()->getLabel(), '@label' => $entity->label()]); + $this->messenger()->addMessage($message); } } diff --git a/web/modules/inline_entity_form/tests/modules/inline_entity_form_translation_test/config/install/language.content_settings.node.ief_reference_type.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_translation_test/config/install/language.content_settings.node.ief_reference_type.yml new file mode 100644 index 0000000000..27108ddd19 --- /dev/null +++ b/web/modules/inline_entity_form/tests/modules/inline_entity_form_translation_test/config/install/language.content_settings.node.ief_reference_type.yml @@ -0,0 +1,17 @@ +langcode: en +status: true +dependencies: + config: + - node.type.ief_reference_type + module: + - content_translation +third_party_settings: + content_translation: + enabled: true + bundle_settings: + untranslatable_fields_hide: '0' +id: node.ief_reference_type +target_entity_type_id: node +target_bundle: ief_reference_type +default_langcode: site_default +language_alterable: true diff --git a/web/modules/inline_entity_form/tests/modules/inline_entity_form_translation_test/config/install/language.content_settings.node.ief_test_complex.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_translation_test/config/install/language.content_settings.node.ief_test_complex.yml new file mode 100644 index 0000000000..7790a43430 --- /dev/null +++ b/web/modules/inline_entity_form/tests/modules/inline_entity_form_translation_test/config/install/language.content_settings.node.ief_test_complex.yml @@ -0,0 +1,17 @@ +langcode: en +status: true +dependencies: + config: + - node.type.ief_test_complex + module: + - content_translation +third_party_settings: + content_translation: + enabled: true + bundle_settings: + untranslatable_fields_hide: '0' +id: node.ief_test_complex +target_entity_type_id: node +target_bundle: ief_test_complex +default_langcode: site_default +language_alterable: true diff --git a/web/modules/inline_entity_form/tests/modules/inline_entity_form_translation_test/inline_entity_form_translation_test.info.yml b/web/modules/inline_entity_form/tests/modules/inline_entity_form_translation_test/inline_entity_form_translation_test.info.yml new file mode 100644 index 0000000000..8f46dfe35d --- /dev/null +++ b/web/modules/inline_entity_form/tests/modules/inline_entity_form_translation_test/inline_entity_form_translation_test.info.yml @@ -0,0 +1,14 @@ +name: 'IEF translation test' +type: module +description: 'Support module for the Inline entity form module tests.' +core_version_requirement: ^8.7.7 || ^9 +package: Testing +dependencies: + - inline_entity_form_test:inline_entity_form_test + - drupal:language + - drupal:content_translation + +# Information added by Drupal.org packaging script on 2020-05-12 +version: '8.x-1.0-rc6' +project: 'inline_entity_form' +datestamp: 1589280849 diff --git a/web/modules/inline_entity_form/tests/src/FunctionalJavascript/ComplexSimpleWidgetTest.php b/web/modules/inline_entity_form/tests/src/FunctionalJavascript/ComplexSimpleWidgetTest.php new file mode 100644 index 0000000000..2a53a7dea2 --- /dev/null +++ b/web/modules/inline_entity_form/tests/src/FunctionalJavascript/ComplexSimpleWidgetTest.php @@ -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 + */ + public static $modules = [ + 'inline_entity_form_test', + 'field', + 'field_ui', + ]; + + /** + * {@inheritdoc} + */ + protected function setUp() { + 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(8); + $inner_title = $this->randomMachineName(8); + $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(8); + $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."); + } + } + } + } + } + +} diff --git a/web/modules/inline_entity_form/tests/src/FunctionalJavascript/ComplexWidgetRevisionsTest.php b/web/modules/inline_entity_form/tests/src/FunctionalJavascript/ComplexWidgetRevisionsTest.php new file mode 100644 index 0000000000..9796ba450f --- /dev/null +++ b/web/modules/inline_entity_form/tests/src/FunctionalJavascript/ComplexWidgetRevisionsTest.php @@ -0,0 +1,263 @@ +<?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 + */ + public static $modules = [ + 'field', + 'field_ui', + 'entity_test', + 'entity_reference_revisions', + 'inline_entity_form_test', + ]; + + /** + * URL to add new content. + * + * @var string + */ + protected $formContentAddUrl; + + /** + * Prepares environment for testing. + */ + protected function setUp() { + 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'; + } + + /** + * Tests saving entity reference revisions' field types at depth. + */ + public function testRevisionsAtDepth() { + // 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(); + $this->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'); + $this->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(); + $this->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'); + $this->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(); + $this->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'); + $this->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->assertNotEqual($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. + $this->assertEqual($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(); + $this->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(); + $this->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->assertNotEqual($entity_no_bundle_vid, $entity_no_bundle_vid_new); + } + +} diff --git a/web/modules/inline_entity_form/tests/src/FunctionalJavascript/ComplexWidgetTest.php b/web/modules/inline_entity_form/tests/src/FunctionalJavascript/ComplexWidgetTest.php new file mode 100644 index 0000000000..71dbf36606 --- /dev/null +++ b/web/modules/inline_entity_form/tests/src/FunctionalJavascript/ComplexWidgetTest.php @@ -0,0 +1,909 @@ +<?php + +namespace Drupal\Tests\inline_entity_form\FunctionalJavascript; + +use Drupal\node\Entity\Node; +use Drupal\node\NodeInterface; +use Drupal\Tests\TestFileCreationTrait; + +/** + * IEF complex field widget tests. + * + * @group inline_entity_form + */ +class ComplexWidgetTest extends InlineEntityFormTestBase { + + use TestFileCreationTrait { + getTestFiles as drupalGetTestFiles; + } + + /** + * Modules to enable. + * + * @var array + */ + public static $modules = [ + 'inline_entity_form_test', + 'field', + 'field_ui', + ]; + + /** + * URL to add new content. + * + * @var string + */ + protected $formContentAddUrl; + + /** + * Entity form display storage. + * + * @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface + */ + protected $entityFormDisplayStorage; + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + + $this->user = $this->createUser([ + 'create ief_reference_type content', + 'create ief_test_nested1 content', + 'create ief_test_nested2 content', + 'create ief_test_nested3 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', + 'edit any ief_test_nested1 content', + 'edit any ief_test_nested2 content', + 'edit any ief_test_nested3 content', + 'view own unpublished content', + 'administer content types', + ]); + $this->drupalLogin($this->user); + + $this->formContentAddUrl = 'node/add/ief_test_complex'; + $this->entityFormDisplayStorage = $this->container->get('entity_type.manager')->getStorage('entity_form_display'); + } + + /** + * Tests if form behaves correctly when field is empty. + */ + public function testEmptyField() { + // Get the xpath selectors for the input fields in this test. + $inner_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(); + // Don't allow addition of existing nodes. + $this->updateSetting('allow_existing', FALSE); + $this->drupalGet($this->formContentAddUrl); + + // Assert title field on inline form exists. + $assert_session->elementExists('xpath', $inner_title_field_xpath); + // Assert first name field on inline form exists. + $assert_session->elementExists('xpath', $first_name_field_xpath); + // Assert last name field on inline form exists. + $assert_session->elementExists('xpath', $last_name_field_xpath); + $assert_session->buttonExists('Create node'); + + // Allow addition of existing nodes. + $this->updateSetting('allow_existing', TRUE); + + // Asserts 'Add new node' form elements. + $this->drupalGet($this->formContentAddUrl); + $multi_fieldset = $assert_session + ->elementExists('css', 'fieldset[data-drupal-selector="edit-multi"]'); + // Assert title field does not appear. + $assert_session->elementNotExists('xpath', $inner_title_field_xpath); + // Assert first name field does not appear. + $assert_session->elementNotExists('xpath', $first_name_field_xpath); + // Assert last name field does not appear. + $assert_session->elementNotExists('xpath', $last_name_field_xpath); + $assert_session->buttonExists('Add existing node', $multi_fieldset); + // Now submit 'Add new node' button in the 'Multiple nodes' fieldset. + $multi_fieldset->pressButton('Add new node'); + // Assert title field on inline form exists. + $this->assertNotEmpty($assert_session->waitForElement('xpath', $inner_title_field_xpath)); + // Assert first name field on inline form exists. + $assert_session->elementExists('xpath', $first_name_field_xpath); + // Assert second name field on inline form exists. + $assert_session->elementExists('xpath', $last_name_field_xpath); + $assert_session->buttonExists('Create node'); + $assert_session->buttonExists('Cancel'); + + // Asserts 'Add existing node' form elements. + $this->drupalGet($this->formContentAddUrl); + $multi_fieldset = $assert_session->elementExists('css', 'fieldset[data-drupal-selector="edit-multi"]'); + $multi_fieldset->pressButton('Add existing node'); + // Assert existing entity reference autocomplete field appears. + $this->assertNotEmpty($assert_session->waitForElement('xpath', $this->getXpathForAutoCompleteInput())); + $assert_session->buttonExists('Add node'); + $assert_session->buttonExists('Cancel'); + } + + /** + * Tests creation of entities. + */ + public function testEntityCreation() { + // Get the xpath selectors for the input fields in this test. + $first_title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 1); + $inner_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(); + + // Allow addition of existing nodes. + $this->updateSetting('allow_existing', TRUE); + + $this->drupalGet($this->formContentAddUrl); + $multi_fieldset = $assert_session + ->elementExists('css', 'fieldset[data-drupal-selector="edit-multi"]'); + $multi_fieldset->pressButton('Add new node'); + $this->assertNotEmpty($create_node_button = $assert_session->waitForButton('Create node')); + $create_node_button->press(); + $this->assertNotEmpty($assert_session->waitForElement('css', 'div[data-drupal-messages]')); + $assert_session->pageTextContains('First name field is required.'); + $assert_session->pageTextContains('Last name field is required.'); + $assert_session->pageTextContains('Title field is required.'); + + // Create ief_reference_type node in IEF. + $this->drupalGet($this->formContentAddUrl); + $multi_fieldset = $assert_session + ->elementExists('css', 'fieldset[data-drupal-selector="edit-multi"]'); + $multi_fieldset->pressButton('Add new node'); + $this->assertNotEmpty($assert_session->waitForElement('xpath', $inner_title_field_xpath)); + $assert_session->elementExists('xpath', $inner_title_field_xpath)->setValue('Some reference'); + $assert_session->elementExists('xpath', $first_name_field_xpath)->setValue('John'); + $assert_session->elementExists('xpath', $last_name_field_xpath)->setValue('Doe'); + $page->pressButton('Create node'); + $this->assertNotEmpty($assert_session->waitForElement('css', '.ief-row-entity')); + + // Tests if correct fields appear in the table. + $assert_session->elementTextContains('css', '.ief-row-entity .inline-entity-form-node-label', 'Some reference'); + $assert_session->elementTextContains('css', '.ief-row-entity .inline-entity-form-node-status', 'Published'); + + // Tests if edit and remove buttons appear. + $multi_fieldset = $assert_session + ->elementExists('css', 'fieldset[data-drupal-selector="edit-multi"]'); + $assert_session->buttonExists('Edit', $multi_fieldset); + $assert_session->buttonExists('Remove', $multi_fieldset); + + // Test edit functionality. + $assert_session->buttonExists('Edit', $multi_fieldset)->press(); + $this->assertNotEmpty($assert_session->waitForElement('xpath', $inner_title_field_xpath)); + $assert_session->elementExists('xpath', $inner_title_field_xpath)->setValue('Some changed reference'); + $page->pressButton('Update node'); + $this->waitForRowByTitle('Some changed reference'); + // Tests if correct fields appear in the table. + $assert_session->elementTextContains('css', '.ief-row-entity .inline-entity-form-node-label', 'Some changed reference'); + $assert_session->elementTextContains('css', '.ief-row-entity .inline-entity-form-node-status', 'Published'); + // Tests if edit and remove buttons appear. + $multi_fieldset = $assert_session + ->elementExists('css', 'fieldset[data-drupal-selector="edit-multi"]'); + $assert_session->buttonExists('Edit', $multi_fieldset); + $assert_session->buttonExists('Remove', $multi_fieldset); + + // Make sure unrelated AJAX submit doesn't save the referenced entity. + // @todo restore this test. + // @see https://www.drupal.org/project/inline_entity_form/issues/3088453 + $assert_session->elementExists('xpath', $first_title_field_xpath)->setValue('Some title'); + $page->pressButton('Save'); + $assert_session->pageTextContains('IEF test complex Some title has been created.'); + + // Checks values of created entities. + $node = $this->drupalGetNodeByTitle('Some changed reference'); + $this->assertNotEmpty($node, 'Created ief_reference_type node ' . $node->label()); + $this->assertSame('John', $node->get('first_name')->value, 'First name in reference node set to John'); + $this->assertSame('Doe', $node->get('last_name')->value, 'Last name in reference node set to Doe'); + + $parent_node = $this->drupalGetNodeByTitle('Some title'); + $this->assertNotEmpty($parent_node, 'Created ief_test_complex node ' . $parent_node->label()); + $this->assertSame($node->id(), $parent_node->multi->target_id, 'Reference node id set to ' . $node->id()); + } + + /** + * Tests the entity creation with different bundles nested in each other. + * + * Ief_test_nested1 -> ief_test_nested2 -> ief_test_nested3 + */ + public function testNestedEntityCreationWithDifferentBundlesAjaxSubmit() { + // 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); + + $page = $this->getSession()->getPage(); + $assert_session = $this->assertSession(); + + foreach ([FALSE, TRUE] as $required) { + $this->setupNestedComplexForm($required); + $required_string = ($required) ? ' required' : ' unrequired'; + $double_nested_title = 'Dream within a dream' . $required_string; + $nested_title = 'Dream' . $required_string; + $top_level_title = 'Reality' . $required_string; + $this->assertNotEmpty($field = $assert_session->waitForElement('xpath', $double_nested_title_field_xpath)); + $field->setValue($double_nested_title); + $page->pressButton('Create node 3'); + $this->waitForRowByTitle($double_nested_title); + + // Assert title of second nested node found. + $this->assertNoNodeByTitle($double_nested_title, 'Second nested entity is not saved yet.'); + + $assert_session->elementExists('xpath', $nested_title_field_xpath)->setValue($nested_title); + $page->pressButton('Create node 2'); + $this->waitForRowByTitle($nested_title); + $this->assertNoNodeByTitle($nested_title, 'First nested entity is not saved yet.'); + + $assert_session->elementExists('xpath', $top_title_field_xpath)->setValue($top_level_title); + $page->pressButton('Save'); + $assert_session->pageTextContains("IEF test nested 1 $top_level_title has been created."); + $top_level_node = $this->drupalGetNodeByTitle($top_level_title); + $this->assertNotEmpty($top_level_node); + $nested_node = $this->drupalGetNodeByTitle($nested_title); + $this->assertNotEmpty($nested_node); + $double_nested_node = $this->drupalGetNodeByTitle($double_nested_title); + $this->assertNotEmpty($double_nested_node); + $this->checkNestedNodes($top_level_node, $nested_node, $double_nested_node); + } + } + + /** + * Tests the entity creation with different bundles nested in each other. + * + * Ief_test_nested1 -> ief_test_nested2 -> ief_test_nested3 + */ + public function testNestedEntityCreationWithDifferentBundlesNoAjaxSubmit() { + // 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); + + $page = $this->getSession()->getPage(); + $assert_session = $this->assertSession(); + foreach ([FALSE, TRUE] as $required) { + $this->setupNestedComplexForm($required); + $required_string = ($required) ? ' required' : ' unrequired'; + $double_nested_title = 'Dream within a dream' . $required_string; + $nested_title = 'Dream' . $required_string; + $top_level_title = 'Reality' . $required_string; + $assert_session->elementExists('xpath', $top_title_field_xpath)->setValue($top_level_title); + $assert_session->elementExists('xpath', $nested_title_field_xpath)->setValue($nested_title); + $assert_session->elementExists('xpath', $double_nested_title_field_xpath)->setValue($double_nested_title); + $page->pressButton('Save'); + $assert_session->pageTextContains("IEF test nested 1 $top_level_title has been created."); + $top_level_node = $this->drupalGetNodeByTitle($top_level_title); + $this->assertNotEmpty($top_level_node); + $nested_node = $this->drupalGetNodeByTitle($nested_title); + $this->assertNotEmpty($nested_node); + $double_nested_node = $this->drupalGetNodeByTitle($double_nested_title); + $this->assertNotEmpty($double_nested_node); + $this->checkNestedNodes($top_level_node, $nested_node, $double_nested_node); + } + } + + /** + * Tests if editing and removing entities work. + */ + public function testEntityEditingAndRemoving() { + // Get the xpath selectors for the fields in this test. + $inner_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); + $first_delete_checkbox_xpath = $this->getXpathForNthInputByLabelText('Delete this node from the system.', 1); + + $assert_session = $this->assertSession(); + $page = $this->getSession()->getPage(); + // Allow addition of existing nodes. + $this->updateSetting('allow_existing', TRUE); + + // Create three ief_reference_type entities. + $referenceNodes = $this->createReferenceContent(3); + $this->drupalCreateNode([ + 'type' => 'ief_test_complex', + 'title' => 'Some title', + 'multi' => array_values($referenceNodes), + ]); + /** @var \Drupal\node\NodeInterface $parent_node */ + $parent_node = $this->drupalGetNodeByTitle('Some title'); + + // Edit the second entity. + $this->drupalGet('node/' . $parent_node->id() . '/edit'); + $assert_session->elementExists('xpath', '(//input[@value="Edit"])[2]')->press(); + $this->assertNotEmpty($assert_session->waitForElement('xpath', $inner_title_field_xpath)); + $assert_session->elementExists('xpath', $first_name_field_xpath)->setValue('John'); + $assert_session->elementExists('xpath', $last_name_field_xpath)->setValue('Doe'); + $page->pressButton('Update node'); + $this->assertNotEmpty($this->waitForElementRemoved('css', 'div[data-drupal-selector="edit-multi-form-inline-entity-form-entities-1-form"]')); + $this->waitForRowByTitle('Some reference 2'); + + // Save the ief_test_complex node. + $page->pressButton('Save'); + $assert_session->pageTextContains('IEF test complex Some title has been updated.'); + + // Checks values of changed entities. + $node = $this->drupalGetNodeByTitle('Some reference 2', TRUE); + $this->assertSame('John', $node->first_name->value, 'First name in reference node changed to John'); + $this->assertSame('Doe', $node->last_name->value, 'Last name in reference node changed to Doe'); + + // Delete the second entity. + $this->drupalGet('node/' . $parent_node->id() . '/edit'); + $assert_session->elementsCount('css', 'tr.ief-row-entity', 3); + $assert_session->elementExists('xpath', '(//input[@value="Remove"])[2]')->press(); + $this->assertNotEmpty($confirm_checkbox = $assert_session->waitForElement('xpath', $first_delete_checkbox_xpath)); + $assert_session->pageTextContains('Are you sure you want to remove Some reference 2?'); + $confirm_checkbox->check(); + $assert_session->elementExists('xpath', '(//input[@value="Remove"])[2]')->press(); + $this->waitForRowRemovedByTitle('Some reference 2'); + // Assert two rows show, instead of 3. + $assert_session->elementsCount('css', 'tr.ief-row-entity', 2); + + // Save the ief_test_complex node. + $page->pressButton('Save'); + $assert_session->pageTextContains('IEF test complex Some title has been updated.'); + + $deleted_node = $this->drupalGetNodeByTitle('Some reference 2'); + $this->assertEmpty($deleted_node, 'The inline entity was deleted from the site.'); + + // Checks that entity does nor appear in IEF. + $this->drupalGet('node/' . $parent_node->id() . '/edit'); + // Assert 2 rows show, instead of 3. + $assert_session->elementsCount('css', 'tr.ief-row-entity', 2); + $this->assertRowByTitle('Some reference 1'); + $this->assertNoRowByTitle('Some reference 2'); + $this->assertRowByTitle('Some reference 3'); + + // Delete the third entity reference only, don't delete the node. The third + // entity now is second referenced entity because the second one was deleted + // in previous step. + $this->drupalGet('node/' . $parent_node->id() . '/edit'); + $assert_session->elementsCount('css', 'tr.ief-row-entity', 2); + $assert_session->elementExists('xpath', '(//input[@value="Remove"])[2]')->press(); + $this->assertNotEmpty($confirm_checkbox = $assert_session->waitForElement('xpath', $first_delete_checkbox_xpath)); + $assert_session->pageTextContains('Are you sure you want to remove Some reference 3?'); + $assert_session->elementExists('xpath', '(//input[@value="Remove"])[2]')->press(); + $this->waitForRowRemovedByTitle('Some reference 3'); + // Assert only one row displays. + $assert_session->elementsCount('css', 'tr.ief-row-entity', 1); + $this->assertRowByTitle('Some reference 1'); + $this->assertNoRowByTitle('Some reference 2'); + $this->assertNoRowByTitle('Some reference 3'); + + // Save the ief_test_complex node. + $page->pressButton('Save'); + $assert_session->pageTextContains('IEF test complex Some title has been updated.'); + + // Checks that entity is not deleted. + $node = $this->drupalGetNodeByTitle('Some reference 3'); + $this->assertNotEmpty($node, 'Reference node not deleted'); + } + + /** + * Tests if referencing existing entities work. + */ + public function testReferencingExistingEntities() { + // Get the xpath selectors for the input fields in this test. + $node_field_xpath = $this->getXpathForNthInputByLabelText('Node', 1); + + $assert_session = $this->assertSession(); + $page = $this->getSession()->getPage(); + // Allow addition of existing nodes. + $this->updateSetting('allow_existing', TRUE); + + // Create three ief_reference_type entities. + $referenceNodes = $this->createReferenceContent(3); + + // Create a node for every bundle available. + $bundle_nodes = $this->createNodeForEveryBundle(); + + // Create ief_test_complex node with first ief_reference_type node and first + // node from bundle nodes. + $this->drupalCreateNode([ + 'type' => 'ief_test_complex', + 'title' => 'Some title', + 'multi' => [1], + 'all_bundles' => key($bundle_nodes), + ]); + // Remove first node since we already added it. + unset($bundle_nodes[key($bundle_nodes)]); + + $parent_node = $this->drupalGetNodeByTitle('Some title', TRUE); + + // Add remaining existing reference nodes. + $this->drupalGet('node/' . $parent_node->id() . '/edit'); + for ($i = 2; $i <= 3; $i++) { + $this->openMultiExistingForm(); + $title = 'Some reference ' . $i; + $assert_session->elementExists('xpath', $node_field_xpath)->setValue($title . ' (' . $referenceNodes[$title] . ')'); + $page->pressButton('Add node'); + $this->waitForRowByTitle($title); + } + // Add all remaining nodes from all bundles. + foreach ($bundle_nodes as $id => $title) { + $all_bundles_fieldset = $assert_session + ->elementExists('css', 'fieldset[data-drupal-selector="edit-all-bundles"]'); + $assert_session->buttonExists('Add existing node', $all_bundles_fieldset)->press(); + $this->assertNotEmpty($assert_session->waitForElement('xpath', $node_field_xpath)); + $assert_session->elementExists('xpath', $node_field_xpath)->setValue($title . ' (' . $id . ')'); + $page->pressButton('Add node'); + $this->waitForRowByTitle($title); + } + // Save the node. + $page->pressButton('Save'); + $assert_session->pageTextContains('IEF test complex Some title has been updated.'); + + // Check if entities are referenced. + $this->drupalGet('node/' . $parent_node->id() . '/edit'); + + $assert_session->elementsCount('css', 'fieldset[data-drupal-selector="edit-multi"] tr.ief-row-entity', 3); + $this->assertRowByTitle('Some reference 1'); + $this->assertRowByTitle('Some reference 2'); + $this->assertRowByTitle('Some reference 3'); + + // Check if all remaining nodes from all bundles are referenced. + $assert_session->elementsCount('css', 'fieldset[data-drupal-selector="edit-all-bundles"] tr.ief-row-entity', 12); + foreach ($bundle_nodes as $id => $title) { + $this->assertRowByTitle($title); + } + } + + /** + * Tests if referencing an existing entity works without submitting the form. + */ + public function testReferencingExistingEntitiesNoSubmit() { + // Get the xpath selectors for the input fields in this test. + $node_field_xpath = $this->getXpathForNthInputByLabelText('Node', 1); + $title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 1); + + // Allow addition of existing nodes. + $this->updateSetting('allow_existing', TRUE); + $title = $this->randomMachineName(); + + $this->drupalCreateNode([ + 'type' => 'ief_reference_type', + 'title' => $title, + 'first_name' => $this->randomMachineName(), + 'last_name' => $this->randomMachineName(), + ]); + $node = $this->drupalGetNodeByTitle($title); + $this->assertNotEmpty($node, 'Created ief_reference_type node "' . $node->label() . '"'); + + $this->drupalGet($this->formContentAddUrl); + $assert_session = $this->assertSession(); + $page = $this->getSession()->getPage(); + $this->openMultiExistingForm(); + $assert_session->elementExists('xpath', $node_field_xpath)->setValue($node->getTitle() . ' (' . $node->id() . ')'); + $parent_title = $this->randomMachineName(); + $assert_session->elementExists('xpath', $title_field_xpath)->setValue($parent_title); + $page->pressButton('Save'); + $assert_session->pageTextContains("IEF test complex $parent_title has been created."); + $assert_session->pageTextNotContains('This value should not be null.'); + $node = $this->drupalGetNodeByTitle($parent_title); + $this->assertNotEmpty($node, 'Created ief_reference_type node.'); + } + + /** + * Test if invalid values get correct validation messages. + * + * Tests validation in reference existing entity form. It also checks if + * existing entity reference form can be canceled. + */ + public function testReferenceExistingValidation() { + // Get the xpath selectors for the input fields in this test. + $node_field_xpath = $this->getXpathForNthInputByLabelText('Node', 1); + + $page = $this->getSession()->getPage(); + $assert_session = $this->assertSession(); + $this->updateSetting('allow_existing', TRUE); + + $this->drupalGet('node/add/ief_test_complex'); + $this->checkExistingValidationExpectation('', 'Node field is required.'); + $this->checkExistingValidationExpectation('Fake Title', 'There are no entities matching "Fake Title"'); + // Check adding nodes that cannot be referenced by this field. + foreach ($this->createNodeForEveryBundle() as $id => $title) { + $node = Node::load($id); + if ($node->bundle() !== 'ief_reference_type') { + $this->checkExistingValidationExpectation("$title ($id)", "The referenced entity (node: $id) does not exist."); + } + } + + foreach ($this->createReferenceContent(2) as $title => $id) { + $this->openMultiExistingForm(); + $current_title = "$title ($id)"; + $assert_session->elementExists('xpath', $node_field_xpath)->setValue($current_title); + $page->pressButton('Add node'); + $this->waitForRowByTitle($title); + $assert_session->elementNotExists('xpath', $node_field_xpath); + // Try to add the same node again. + $this->checkExistingValidationExpectation($current_title, 'The selected node has already been added.'); + } + } + + /** + * Tests if duplicating entities works. + */ + public function testDuplicatingEntities() { + // Get the xpath selectors for the input fields in this test. + $title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 2); + $first_name_field_xpath = $this->getXpathForNthInputByLabelText('First name', 1); + + $page = $this->getSession()->getPage(); + $assert_session = $this->assertSession(); + $this->updateSetting('allow_duplicate', TRUE); + + $referenceNodes = $this->createReferenceContent(2); + $this->drupalCreateNode([ + 'type' => 'ief_test_complex', + 'title' => 'Some title', + 'multi' => array_values($referenceNodes), + ]); + /** @var \Drupal\node\NodeInterface $parent_node */ + $parent_node = $this->drupalGetNodeByTitle('Some title'); + + $this->drupalGet('node/' . $parent_node->id() . '/edit'); + $this->assertNotEmpty($multi_fieldset = $assert_session->waitForElement('css', 'fieldset[data-drupal-selector="edit-multi"]')); + $assert_session->buttonExists('Duplicate', $multi_fieldset)->press(); + $this->assertNotEmpty($create_node_button = $assert_session->waitForButton('Duplicate node')); + $assert_session->elementExists('xpath', $title_field_xpath)->setValue('Duplicate!'); + $assert_session->elementExists('xpath', $first_name_field_xpath)->setValue('Bojan'); + $create_node_button->press(); + + $this->waitForRowByTitle('Duplicate!'); + $assert_session->elementsCount('css', 'tr.ief-row-entity', 3); + $this->assertRowByTitle('Some reference 1'); + $this->assertRowByTitle('Some reference 2'); + $this->assertRowByTitle('Duplicate!'); + $page->pressButton('Save'); + $duplicate = $this->drupalGetNodeByTitle('Duplicate!'); + $this->assertNotEmpty($duplicate, 'Duplicate node created.'); + $this->assertSame('Bojan', $duplicate->first_name->value); + } + + /** + * Tests if a referenced content can be edited. + * + * When the referenced content is newer than the referencing parent node, + * test if a referenced content can be edited. + */ + public function testEditedInlineEntityValidation() { + // Get the xpath selectors for the input fields in this test. + $nested_title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 2); + $title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 1); + + $page = $this->getSession()->getPage(); + $assert_session = $this->assertSession(); + $this->updateSetting('allow_existing', TRUE); + + // Create referenced content. + $referenced_nodes = $this->createReferenceContent(1); + + // Create first referencing node. + $this->drupalCreateNode([ + 'type' => 'ief_test_complex', + 'title' => 'First referencing node', + 'multi' => array_values($referenced_nodes), + ]); + $first_node = $this->drupalGetNodeByTitle('First referencing node'); + + // Create second referencing node. + $this->drupalCreateNode([ + 'type' => 'ief_test_complex', + 'title' => 'Second referencing node', + 'multi' => array_values($referenced_nodes), + ]); + $second_node = $this->drupalGetNodeByTitle('Second referencing node'); + + // Edit referenced content in first node. + $this->drupalGet('node/' . $first_node->id() . '/edit'); + $page->pressButton('Edit'); + $this->assertNotEmpty($nested_title = $assert_session->waitForElement('xpath', $nested_title_field_xpath)); + $nested_title->setValue('Some reference updated'); + $page->pressButton('Update node'); + $this->waitForRowByTitle('Some reference updated'); + $assert_session->elementsCount('css', 'tr.ief-row-entity', 1); + + // Save the first node after editing the reference. + $assert_session->elementExists('xpath', $title_field_xpath)->setValue('First node updated'); + $page->pressButton('Save'); + $assert_session->pageTextContains('IEF test complex First node updated has been updated.'); + + // The changed value of the referenced content is now newer than the + // changed value of the second node. + // Edit referenced content in second node. + $this->drupalGet('node/' . $second_node->id() . '/edit'); + + // Edit referenced node. + $page->pressButton('Edit'); + $this->assertNotEmpty($nested_title = $assert_session->waitForElement('xpath', $nested_title_field_xpath)); + $nested_title->setValue('Some reference updated the second time'); + $page->pressButton('Update node'); + $this->waitForRowByTitle('Some reference updated the second time'); + $assert_session->elementsCount('css', 'tr.ief-row-entity', 1); + + // Save the second node after editing the reference. + $assert_session->elementExists('xpath', $title_field_xpath)->setValue('Second node updated'); + $page->pressButton('Save'); + $assert_session->pageTextContains('IEF test complex Second node updated has been updated.'); + + // Check if the referenced content could be edited. + $assert_session->pageTextNotContains('The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.'); + } + + /** + * Checks that nested IEF entity references can be edited and saved. + * + * @param \Drupal\node\NodeInterface $node + * Top level node of type ief_test_nested1 to check. + */ + protected function checkNestedNodeEditing(NodeInterface $node) { + // Get the xpath selectors for the input fields in this test. + $double_nested_title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 3); + $title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 1); + + $assert_session = $this->assertSession(); + $page = $this->getSession()->getPage(); + $nested_node = $node->test_ref_nested1->entity; + $double_nested_node = $nested_node->test_ref_nested2->entity; + + $this->drupalGet("node/{$node->id()}/edit"); + $this->assertRowByTitle($nested_node->label()); + $page->pressButton('Edit'); + $this->waitForRowByTitle($double_nested_node->label()); + $page->pressButton('Edit'); + $this->assertNotEmpty($assert_session->waitforButton('Update node 3')); + $double_nested_node_update_title = $double_nested_node->getTitle() . ' - updated'; + $assert_session->elementExists('xpath', $double_nested_title_field_xpath)->setValue($double_nested_node_update_title); + // Close the double nested IEF form. + $page->pressButton('Update node 3'); + $this->waitForRowByTitle($double_nested_node_update_title); + + // Close the nested IEF form. + $page->pressButton('Update node 2'); + $this->assertNotEmpty($this->waitForElementRemoved('css', 'div[data-drupal-selector="edit-test-ref-nested1-form-inline-entity-form-entities-0-form"]')); + $this->waitForRowByTitle($nested_node->label()); + // Save the top level node. + $page->pressButton('Save'); + + $assert_session->pageTextContains('IEF test nested 1 ' . $node->label() . ' has been updated.'); + + // Verify the double nested node title change saved properly. + $this->drupalGet("node/{$node->id()}/edit"); + $page->pressButton('Edit'); + $this->waitForRowByTitle($double_nested_node_update_title); + $this->drupalGet("node/{$double_nested_node->id()}/edit"); + $this->assertSame($double_nested_node_update_title, $assert_session->elementExists('xpath', $title_field_xpath)->getValue()); + } + + /** + * Creates ief_reference_type nodes which shall serve as reference nodes. + * + * @param int $numNodes + * The number of nodes to create. + * + * @return array + * Array of created node ids keyed by labels. + */ + protected function createReferenceContent($numNodes = 3) { + $retval = []; + for ($i = 1; $i <= $numNodes; $i++) { + $this->drupalCreateNode([ + 'type' => 'ief_reference_type', + 'title' => 'Some reference ' . $i, + 'first_name' => 'First Name ' . $i, + 'last_name' => 'Last Name ' . $i, + ]); + $node = $this->drupalGetNodeByTitle('Some reference ' . $i); + $this->assertNotEmpty($node, 'Created ief_reference_type node "' . $node->label() . '"'); + $retval[$node->label()] = $node->id(); + } + return $retval; + } + + /** + * Updates an IEF setting and saves the underlying entity display. + * + * @param string $name + * The name of the setting. + * @param mixed $value + * The value to set. + */ + protected function updateSetting($name, $value) { + /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $display */ + $display = $this->entityFormDisplayStorage->load('node.ief_test_complex.default'); + $component = $display->getComponent('multi'); + $component['settings'][$name] = $value; + $display->setComponent('multi', $component)->save(); + } + + /** + * Creates a node for every node bundle. + * + * @return array + * Array of node titles keyed by ids. + */ + protected function createNodeForEveryBundle() { + $retval = []; + $bundles = $this->container->get('entity_type.bundle.info')->getBundleInfo('node'); + foreach ($bundles as $id => $value) { + $this->drupalCreateNode(['type' => $id, 'title' => $value['label']]); + $node = $this->drupalGetNodeByTitle($value['label']); + $this->assertNotEmpty($node, 'Created node "' . $node->label() . '"'); + $retval[$node->id()] = $value['label']; + } + return $retval; + } + + /** + * Set up the ief_test_nested1 node add form. + * + * Sets the nested fields' required settings. + * Gets the form. + * Opens the inline entity forms if they are not required. + * + * @param bool $required + * Whether the fields are required. + */ + protected function setupNestedComplexForm($required) { + $assert_session = $this->assertSession(); + $page = $this->getSession()->getPage(); + /** @var \Drupal\Core\Field\FieldConfigInterface $ief_test_nested1 */ + $this->fieldConfigStorage->load('node.ief_test_nested1.test_ref_nested1') + ->setRequired($required) + ->save(); + /** @var \Drupal\Core\Field\FieldConfigInterface $ief_test_nested2 */ + $this->fieldConfigStorage + ->load('node.ief_test_nested2.test_ref_nested2') + ->setRequired($required) + ->save(); + + $this->drupalGet('node/add/ief_test_nested1'); + + if (!$required) { + // Open inline forms if not required. + $page->pressButton('Add new node 2'); + $this->assertNotEmpty($button = $assert_session->waitForButton('Add new node 3')); + $button->press(); + $this->assertNotEmpty($assert_session->waitForButton('Create node 3')); + } + + } + + /** + * Opens the existing node form on the "multi" field. + */ + protected function openMultiExistingForm() { + $assert_session = $this->assertSession(); + $this->assertNotEmpty($multi_fieldset = $assert_session->waitForElement('css', 'fieldset[data-drupal-selector="edit-multi"]')); + $assert_session->buttonExists('Add existing node', $multi_fieldset)->press(); + $this->assertNotEmpty($assert_session->waitForElement('xpath', $this->getXpathForAutoCompleteInput())); + } + + /** + * Check existing node field validation. + * + * Checks that an invalid value for an existing node will be display the + * expected error. + * + * @param string $existing_node_text + * The text to enter into the existing node text field. + * @param string $expected_error + * The error message that is expected to be shown. + */ + protected function checkExistingValidationExpectation($existing_node_text, $expected_error) { + $page = $this->getSession()->getPage(); + $assert_session = $this->assertSession(); + $this->openMultiExistingForm(); + $field = $assert_session->waitForElement('xpath', $this->getXpathForAutoCompleteInput()); + $field->setValue($existing_node_text); + $page->pressButton('Add node'); + $this->assertNotEmpty($assert_session->waitForText($expected_error)); + $assert_session->buttonExists('Cancel')->press(); + $this->assertNotEmpty($this->waitForElementRemoved('xpath', $this->getXpathForAutoCompleteInput())); + } + + /** + * Tests create access on IEF Complex content type. + */ + public function testComplexEntityCreate() { + // Get the xpath selectors for the input fields in this test. + $nested_title_field_xpath = $this->getXpathForNthInputByLabelText('Title', 2); + + $user = $this->createUser([ + 'create ief_test_complex content', + ]); + $this->drupalLogin($user); + + $this->drupalGet('node/add/ief_test_complex'); + $assert_session = $this->assertSession(); + $assert_session->fieldNotExists('all_bundles[actions][bundle]'); + $assert_session->elementNotExists('xpath', $nested_title_field_xpath); + + $user = $this->createUser([ + 'create ief_test_complex content', + 'create ief_reference_type content', + ]); + $this->drupalLogin($user); + + $this->drupalGet('node/add/ief_test_complex'); + $assert_session->fieldExists('all_bundles[actions][bundle]'); + $this->assertOption('edit-all-bundles-actions-bundle', 'ief_reference_type'); + $this->assertOption('edit-all-bundles-actions-bundle', 'ief_test_complex'); + $assert_session->elementExists('xpath', $nested_title_field_xpath); + } + + /** + * Checks if nested nodes for ief_test_nested1 content are created. + * + * @param \Drupal\node\NodeInterface $top_level_node + * The top level node. + * @param \Drupal\node\NodeInterface $nested_node + * The second level node. + * @param \Drupal\node\NodeInterface $double_nested_node + * The the third level node. + */ + protected function checkNestedNodes(NodeInterface $top_level_node, NodeInterface $nested_node, NodeInterface $double_nested_node) { + // Check the type and title of the second level node. + if ($nested_node->id() == $top_level_node->test_ref_nested1->entity->id()) { + $this->assertEquals(1, $top_level_node->test_ref_nested1->count(), 'Only one nested node created'); + $this->assertSame($top_level_node->test_ref_nested1->entity->label(), $nested_node->label(), "Nested node's title is correct."); + $this->assertSame('ief_test_nested2', $nested_node->bundle(), "Nested node's type is correct."); + + // Check the type and title of the third level node. + if ($double_nested_node->id() == $nested_node->test_ref_nested2->entity->id()) { + $this->assertEquals(1, $nested_node->test_ref_nested2->count(), 'Only one node within a node within a node created.'); + $this->assertSame($nested_node->test_ref_nested2->entity->label(), $double_nested_node->label(), "Node within a node within a node's title is correct."); + $this->assertSame('ief_test_nested3', $double_nested_node->bundle(), "Node within a node within a node's type is correct."); + $this->checkNestedNodeEditing($top_level_node); + } + } + } + + /** + * Tests the separation of nested data. + * + * Using entity creation with different bundles nested in each other. + * Ief_test_nested1 -> ief_test_nested2 -> ief_test_nested3 + * + * When creating a second ief_test_nested2 it should be empty and not be + * prefilled with the ief_test_nested3 of the first ief_test_nested2. + */ + public function testSeparateNestedDataMultiValueFields() { + // 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); + + $page = $this->getSession()->getPage(); + $assert_session = $this->assertSession(); + foreach ([FALSE, TRUE] as $required) { + $this->setupNestedComplexForm($required); + $required_string = ($required) ? ' required' : ' unrequired'; + $double_nested_title = 'Dream within a dream' . $required_string; + $nested_title = 'Dream' . $required_string; + $top_level_title = 'Reality' . $required_string; + $assert_session->elementExists('xpath', $top_title_field_xpath) + ->setValue($top_level_title); + $assert_session->elementExists('xpath', $nested_title_field_xpath) + ->setValue($nested_title); + $assert_session->elementExists('xpath', $double_nested_title_field_xpath) + ->setValue($double_nested_title); + $page->pressButton('Create node 3'); + $assert_session->waitForButton('Add new node 3'); + $page->pressButton('Create node 2'); + $assert_session->waitForButton('Add new node 2'); + $page->pressButton('Add new node 2'); + $assert_session->waitForButton('Add new node 3'); + // The new node 2 should be empty and not already have a + // double_nested_title present. + $this->assertNoRowByTitle($double_nested_title); + } + } + +} diff --git a/web/modules/inline_entity_form/tests/src/FunctionalJavascript/ElementWebTest.php b/web/modules/inline_entity_form/tests/src/FunctionalJavascript/ElementWebTest.php new file mode 100644 index 0000000000..46c5d4ed76 --- /dev/null +++ b/web/modules/inline_entity_form/tests/src/FunctionalJavascript/ElementWebTest.php @@ -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 + */ + public static $modules = ['inline_entity_form_test']; + + /** + * {@inheritdoc} + */ + protected function setUp() { + 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'); + } + } + +} diff --git a/web/modules/inline_entity_form/tests/src/FunctionalJavascript/InlineEntityFormTestBase.php b/web/modules/inline_entity_form/tests/src/FunctionalJavascript/InlineEntityFormTestBase.php new file mode 100644 index 0000000000..5f0625218c --- /dev/null +++ b/web/modules/inline_entity_form/tests/src/FunctionalJavascript/InlineEntityFormTestBase.php @@ -0,0 +1,319 @@ +<?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() { + 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($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($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($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->assertEqual($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($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(); + $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($form_display, $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, NULL); + } + } + + /** + * Wait for an IEF table row to appear. + * + * @param string $title + * The title of the row for which to wait. + */ + protected function waitForRowByTitle($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($title) { + $this->assertNotEmpty($this->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($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($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($label, $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($value, $index) { + return "(//input[@type='submit' and @value='{$value}'][{$index}])"; + } + + /** + * Looks for the specified selector and returns TRUE when it is unavailable. + * + * @todo Remove when tests are running on Drupal 8.8. or greater. Then + * we can use $assert_session->waitForElementRemoved(). This is will be when + * Drupal 8.7 reaches EOL (which is when 8.9 is released in June 2020). + * + * @param string $selector + * The selector engine name. See ElementInterface::findAll() for the + * supported selectors. + * @param string|array $locator + * The selector locator. + * @param int $timeout + * (Optional) Timeout in milliseconds, defaults to 10000. + * + * @return bool + * TRUE if not found, FALSE if found. + * + * @see \Drupal\FunctionalJavascriptTests\JSWebAssert::waitForElementRemoved + */ + public function waitForElementRemoved($selector, $locator, $timeout = 10000) { + $page = $this->getSession()->getPage(); + + $result = $page->waitFor($timeout / 1000, function () use ($page, $selector, $locator) { + return !$page->find($selector, $locator); + }); + + return $result; + } + +} diff --git a/web/modules/inline_entity_form/tests/src/FunctionalJavascript/SimpleWidgetTest.php b/web/modules/inline_entity_form/tests/src/FunctionalJavascript/SimpleWidgetTest.php new file mode 100644 index 0000000000..95df5451e1 --- /dev/null +++ b/web/modules/inline_entity_form/tests/src/FunctionalJavascript/SimpleWidgetTest.php @@ -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 + */ + public static $modules = ['inline_entity_form_test']; + + /** + * {@inheritdoc} + */ + protected function setUp() { + 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 single simple 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 single simple 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 single simple 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 single simple 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 single simple 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 single simple 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, $number_of_items, $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->assertContains($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->drupalPostForm(NULL, $edit, t('Save')); + $assert_session->pageTextContains("IEF single simple {$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."); + } + } + +} diff --git a/web/modules/inline_entity_form/tests/src/FunctionalJavascript/TranslationTest.php b/web/modules/inline_entity_form/tests/src/FunctionalJavascript/TranslationTest.php new file mode 100644 index 0000000000..ef798794ea --- /dev/null +++ b/web/modules/inline_entity_form/tests/src/FunctionalJavascript/TranslationTest.php @@ -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 + */ + public static $modules = [ + 'content_translation', + 'inline_entity_form_translation_test', + 'language', + ]; + + /** + * {@inheritdoc} + */ + protected function setUp() { + 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->assertEqual('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); + } + +} -- GitLab