3 namespace Drupal\paragraphs\Tests\Experimental;
5 use Drupal\Component\Render\FormattableMarkup;
6 use Drupal\Core\Entity\Entity\EntityFormDisplay;
7 use Drupal\Core\Language\LanguageInterface;
8 use Drupal\paragraphs\Entity\Paragraph;
9 use Drupal\node\Entity\Node;
12 * Tests the configuration of paragraphs.
16 class ParagraphsExperimentalTranslationTest extends ParagraphsExperimentalTestBase {
23 public static $modules = array(
25 'content_translation',
32 protected function setUp() {
35 'administer site configuration',
36 'create paragraphed_content_demo content',
37 'edit any paragraphed_content_demo content',
38 'delete any paragraphed_content_demo content',
39 'administer content translation',
40 'translate any entity',
41 'create content translations',
42 'administer languages',
45 'settings[paragraph][nested_paragraph][translatable]' => TRUE,
46 'settings[paragraph][nested_paragraph][settings][language][language_alterable]' => TRUE,
47 'settings[paragraph][images][fields][field_images_demo]' => TRUE,
49 $this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration'));
53 * Tests the paragraph translation.
55 public function testParagraphTranslation() {
56 $this->drupalGet('admin/config/regional/content-language');
58 // Check the settings are saved correctly.
59 $this->assertFieldChecked('edit-entity-types-paragraph');
60 $this->assertFieldChecked('edit-settings-node-paragraphed-content-demo-translatable');
61 $this->assertFieldChecked('edit-settings-paragraph-text-image-translatable');
62 $this->assertFieldChecked('edit-settings-paragraph-images-columns-field-images-demo-alt');
63 $this->assertFieldChecked('edit-settings-paragraph-images-columns-field-images-demo-title');
65 // Check if the publish/unpublish option works.
66 $this->drupalGet('admin/structure/paragraphs_type/text_image/form-display');
68 'fields[status][type]' => 'boolean_checkbox',
69 'fields[status][region]' => 'content',
71 // Use the experimental widget.
72 $form_display = EntityFormDisplay::load('node.paragraphed_content_demo.default')
73 ->setComponent('field_paragraphs_demo', [
74 'type' => 'paragraphs',
76 $form_display->save();
77 // Use the experimental widget.
78 $form_display = EntityFormDisplay::load('paragraph.nested_paragraph.default')
79 ->setComponent('field_paragraphs_demo', [
80 'type' => 'paragraphs',
82 $form_display->save();
83 $this->drupalPostForm(NULL, $edit, t('Save'));
84 $this->drupalGet('node/add/paragraphed_content_demo');
85 $this->drupalPostForm(NULL, NULL, t('Add Text + Image'));
86 $this->assertRaw('edit-field-paragraphs-demo-0-subform-status-value');
88 'title[0][value]' => 'example_publish_unpublish',
89 'field_paragraphs_demo[0][subform][field_text_demo][0][value]' => 'Example published and unpublished',
91 $this->drupalPostForm(NULL, $edit, t('Save and publish'));
92 $this->assertText(t('Example published and unpublished'));
93 $this->clickLink(t('Edit'));
95 $this->drupalPostAjaxForm(NULL, NULL, 'field_paragraphs_demo_nested_paragraph_add_more');
96 $this->drupalPostAjaxForm(NULL, NULL, 'field_paragraphs_demo_1_subform_field_paragraphs_demo_text_add_more');
98 'field_paragraphs_demo[0][subform][status][value]' => FALSE,
99 'field_paragraphs_demo[1][subform][field_paragraphs_demo][0][subform][field_text_demo][0][value]' => 'Dummy text'
101 $this->drupalPostForm(NULL, $edit, t('Save and keep published'));
102 $this->assertNoText(t('Example published and unpublished'));
104 // Check the parent fields are set properly. Get the node.
105 $node = $this->drupalGetNodeByTitle('example_publish_unpublish');
106 // Loop over the paragraphs of the node.
107 foreach ($node->field_paragraphs_demo->referencedEntities() as $paragraph) {
108 $node_paragraph = Paragraph::load($paragraph->id())->toArray();
109 // Check if the fields are set properly.
110 $this->assertEqual($node_paragraph['parent_id'][0]['value'], $node->id());
111 $this->assertEqual($node_paragraph['parent_type'][0]['value'], 'node');
112 $this->assertEqual($node_paragraph['parent_field_name'][0]['value'], 'field_paragraphs_demo');
113 // If the paragraph is nested type load the child.
114 if ($node_paragraph['type'][0]['target_id'] == 'nested_paragraph') {
115 $nested_paragraph = Paragraph::load($node_paragraph['field_paragraphs_demo'][0]['target_id'])->toArray();
116 // Check if the fields are properly set.
117 $this->assertEqual($nested_paragraph['parent_id'][0]['value'], $paragraph->id());
118 $this->assertEqual($nested_paragraph['parent_type'][0]['value'], 'paragraph');
119 $this->assertEqual($nested_paragraph['parent_field_name'][0]['value'], 'field_paragraphs_demo');
123 // Add paragraphed content.
124 $this->drupalGet('node/add/paragraphed_content_demo');
125 $this->drupalPostForm(NULL, NULL, t('Add Text + Image'));
127 'title[0][value]' => 'Title in english',
128 'field_paragraphs_demo[0][subform][field_text_demo][0][value]' => 'Text in english',
130 // The button to remove a paragraph is present.
131 $this->assertRaw(t('Remove'));
132 $this->drupalPostForm(NULL, $edit, t('Save and publish'));
133 $node = $this->drupalGetNodeByTitle('Title in english');
134 // The text is present when editing again.
135 $this->clickLink(t('Edit'));
136 $this->assertText('Title in english');
137 $this->assertText('Text in english');
139 // Add french translation.
140 $this->clickLink(t('Translate'));
141 $this->clickLink(t('Add'), 1);
142 // Make sure the Add / Remove paragraph buttons are hidden.
143 $this->assertNoRaw(t('Remove'));
144 $this->assertNoRaw(t('Add Text + Image'));
145 // Make sure that the original paragraph text is displayed.
146 $this->assertText('Text in english');
149 'title[0][value]' => 'Title in french',
150 'field_paragraphs_demo[0][subform][field_text_demo][0][value]' => 'Text in french',
152 'revision_log[0][value]' => 'french 1',
154 $this->drupalPostForm(NULL, $edit, t('Save and keep published (this translation)'));
155 $this->assertText('Paragraphed article Title in french has been updated.');
157 // Check the english translation.
158 $this->drupalGet('node/' . $node->id());
159 $this->assertText('Title in english');
160 $this->assertText('Text in english');
161 $this->assertNoText('Title in french');
162 $this->assertNoText('Text in french');
164 // Check the french translation.
165 $this->drupalGet('fr/node/' . $node->id());
166 $this->assertText('Title in french');
167 $this->assertText('Text in french');
168 $this->assertNoText('Title in english');
169 // The translation is still present when editing again.
170 $this->clickLink(t('Edit'));
171 $this->assertText('Title in french');
172 $this->assertText('Text in french');
174 'title[0][value]' => 'Title Change in french',
175 'field_paragraphs_demo[0][subform][field_text_demo][0][value]' => 'New text in french',
177 'revision_log[0][value]' => 'french 2',
179 $this->drupalPostForm(NULL, $edit, t('Save and keep published (this translation)'));
180 $this->assertText('Title Change in french');
181 $this->assertText('New text in french');
183 // Back to the source language.
184 $this->drupalGet('node/' . $node->id());
185 $this->clickLink(t('Edit'));
186 $this->assertText('Title in english');
187 $this->assertText('Text in english');
188 // Save the original content on second request.
189 $this->drupalPostForm(NULL, NULL, t('Save and keep published (this translation)'));
190 $this->assertText('Paragraphed article Title in english has been updated.');
192 // Test if reverting to old paragraphs revisions works, make sure that
193 // the reverted node can be saved again.
194 $this->drupalGet('fr/node/' . $node->id() . '/revisions');
195 $this->clickLink(t('Revert'));
196 $this->drupalPostForm(NULL, ['revert_untranslated_fields' => TRUE], t('Revert'));
197 $this->clickLink(t('Edit'));
198 $this->assertRaw('Title in french');
199 $this->assertText('Text in french');
200 $this->drupalPostForm(NULL, [], t('Save and keep published (this translation)'));
201 $this->assertNoRaw('The content has either been modified by another user, or you have already submitted modifications');
202 $this->assertText('Text in french');
204 //Add paragraphed content with untranslatable language
205 $this->drupalGet('node/add/paragraphed_content_demo');
206 $edit = array('langcode[0][value]' => LanguageInterface::LANGCODE_NOT_SPECIFIED);
207 $this->drupalPostForm(NULL, $edit, t('Add Text + Image'));
208 $this->assertResponse(200);
210 // Make 'Images' paragraph field translatable, enable alt and title fields.
211 $this->drupalGet('admin/structure/paragraphs_type/images/fields');
212 $this->clickLink('Edit');
215 'settings[alt_field]' => 1,
216 'settings[title_field]' => 1,
218 $this->drupalPostForm(NULL, $edit, t('Save settings'));
220 // Create a node with an image paragraph, its alt and title text.
221 $text = 'Trust me I\'m an image';
222 file_put_contents('temporary://Image.jpg', $text);
223 $file_path = $this->container->get('file_system')->realpath('temporary://Image.jpg');
224 $this->drupalGet('node/add/paragraphed_content_demo');
225 $this->drupalPostForm(NULL, [], t('Add Images'));
226 $this->drupalPostForm(NULL, ['files[field_paragraphs_demo_0_subform_field_images_demo_0][]' => $file_path], t('Upload'));
228 'title[0][value]' => 'Title EN',
229 'field_paragraphs_demo[0][subform][field_images_demo][0][alt]' => 'Image alt',
230 'field_paragraphs_demo[0][subform][field_images_demo][0][title]' => 'Image title',
231 'field_paragraphs_demo[0][subform][field_images_demo][0][width]' => 100,
232 'field_paragraphs_demo[0][subform][field_images_demo][0][height]' => 100,
234 $this->drupalPostForm(NULL, $edit, t('Save and publish'));
236 // Translate the node with the image paragraph.
237 $this->clickLink('Translate');
238 $this->clickLink(t('Add'), 1);
240 'title[0][value]' => 'Title FR',
241 'field_paragraphs_demo[0][subform][field_images_demo][0][alt]' => 'Image alt FR',
242 'field_paragraphs_demo[0][subform][field_images_demo][0][title]' => 'Image title FR',
244 $this->drupalPostForm(NULL, $edit, t('Save and keep published (this translation)'));
245 $this->assertRaw('Title FR');
247 $this->drupalGet('node/add/paragraphed_content_demo');
248 $this->drupalPostForm(NULL, [], t('Add Text'));
250 'field_paragraphs_demo[0][subform][field_text_demo][0][value]' => 'texto',
251 'title[0][value]' => 'titulo',
252 'langcode[0][value]' => 'de',
254 $this->drupalPostForm(NULL, $edit, t('Save and publish'));
255 $node = $this->drupalGetNodeByTitle('titulo');
256 $this->assertParagraphsLangcode($node->id(), 'de');
258 // Test langcode matching when Paragraphs and node have different language.
259 $paragraph_1 = Paragraph::create([
260 'title' => 'Paragraph',
263 'field_text_demo' => 'english_text_1',
265 $paragraph_1->save();
267 $paragraph_2 = Paragraph::create([
268 'title' => 'Paragraph',
271 'field_text_demo' => 'english_text_2',
273 $paragraph_2->save();
275 $paragraph_data = $paragraph_2->toArray();
276 $paragraph_data['field_text_demo'] = 'german_text_2';
277 $paragraph_2->addTranslation('de', $paragraph_data);
278 $paragraph_2->save();
279 $translated_paragraph = $paragraph_2->getTranslation('en');
281 $node = $this->createNode([
283 'type' => 'paragraphed_content_demo',
284 'field_paragraphs_demo' => [$paragraph_1, $translated_paragraph],
286 $this->drupalGet('node/' . $node->id() . '/edit');
287 $this->drupalPostForm(NULL, [], t('Save and keep published'));
288 $this->assertText('Paragraphed article ' . $node->label() . ' has been updated.');
289 // Check that first paragraph langcode has been updated.
290 $paragraph = Paragraph::load($paragraph_1->id());
291 $this->assertEqual($paragraph->language()->getId(), 'de');
292 $this->assertFalse($paragraph->hasTranslation('en'));
293 // Check that second paragraph has two translations.
294 $paragraph = Paragraph::load($paragraph_2->id());
295 $this->assertTrue($paragraph->hasTranslation('de'));
296 $this->assertTrue($paragraph->hasTranslation('en'));
297 $this->assertRaw('german_text');
299 // Create an english translation of the node.
301 'field_paragraphs_demo[0][subform][field_text_demo][0][value]' => 'english_translation_1',
302 'field_paragraphs_demo[1][subform][field_text_demo][0][value]' => 'english_translation_2',
304 $this->drupalPostForm('node/' . $node->id() . '/translations/add/de/en', $edit, t('Save and keep published (this translation)'));
305 // Attempt to create a french translation.
306 $this->drupalGet('node/' . $node->id() . '/translations/add/de/fr');
307 // Check that the german translation of the paragraphs is displayed.
308 $this->assertFieldByName('field_paragraphs_demo[0][subform][field_text_demo][0][value]', 'english_text_1');
309 $this->assertFieldByName('field_paragraphs_demo[1][subform][field_text_demo][0][value]', 'german_text_2');
310 $this->drupalPostForm(NULL, ['source_langcode[source]' => 'en'], t('Change'));
311 // Check that the english translation of the paragraphs is displayed.
312 $this->assertFieldByName('field_paragraphs_demo[0][subform][field_text_demo][0][value]', 'english_translation_1');
313 $this->assertFieldByName('field_paragraphs_demo[1][subform][field_text_demo][0][value]', 'english_translation_2');
315 // Create a node with empty Paragraphs.
316 $this->drupalGet('node/add/paragraphed_content_demo');
317 $this->drupalPostForm(NULL, [], t('Add Nested Paragraph'));
318 $this->drupalPostForm(NULL, ['title[0][value]' => 'empty_node'], t('Save and publish'));
319 // Attempt to translate it.
320 $this->clickLink(t('Translate'));
321 $this->clickLink(t('Add'));
322 // Check the add button is not displayed.
323 $this->assertEqual(count($this->xpath('//*[@name="field_paragraphs_demo_0_subform_field_paragraphs_demo_images_add_more"]')), 0);
325 // Add a non translatable field to Text Paragraph type.
327 'new_storage_type' => 'text_long',
328 'label' => 'untranslatable_field',
329 'field_name' => 'untranslatable_field',
331 $this->drupalPostForm('admin/structure/paragraphs_type/text/fields/add-field', $edit, t('Save and continue'));
332 $this->drupalPostForm(NULL, [], t('Save field settings'));
333 $this->drupalPostForm(NULL, [], t('Save settings'));
335 // Add a non translatable reference field.
337 'new_storage_type' => 'field_ui:entity_reference:node',
338 'label' => 'untranslatable_ref_field',
339 'field_name' => 'untranslatable_ref_field',
341 $this->drupalPostForm('admin/structure/paragraphs_type/text/fields/add-field', $edit, t('Save and continue'));
342 $this->drupalPostForm(NULL, [], t('Save field settings'));
343 $this->drupalPostForm(NULL, ['settings[handler_settings][target_bundles][paragraphed_content_demo]' => TRUE], t('Save settings'));
345 // Add a non translatable link field.
347 'new_storage_type' => 'link',
348 'label' => 'untranslatable_link_field',
349 'field_name' => 'untranslatable_link_field',
351 $this->drupalPostForm('admin/structure/paragraphs_type/text/fields/add-field', $edit, t('Save and continue'));
352 $this->drupalPostForm(NULL, [], t('Save field settings'));
353 $this->drupalPostForm(NULL, [], t('Save settings'));
355 // Attempt to add a translation.
356 $this->drupalGet('node/' . $node->id() . '/translations/add/de/fr');
357 $this->assertText('untranslatable_field (all languages)');
358 $this->assertText('untranslatable_ref_field (all languages)');
359 $this->assertText('untranslatable_link_field (all languages)');
360 $this->assertNoText('Text (all languages)');
362 // Enable translations for the reference and link field.
364 'translatable' => TRUE,
366 $this->drupalPostForm('admin/structure/paragraphs_type/text/fields/paragraph.text.field_untranslatable_ref_field', $edit, t('Save settings'));
367 $this->drupalPostForm('admin/structure/paragraphs_type/text/fields/paragraph.text.field_untranslatable_link_field', $edit, t('Save settings'));
369 // Attempt to add a translation.
370 $this->drupalGet('node/' . $node->id() . '/translations/add/de/fr');
371 $this->assertText('untranslatable_field (all languages)');
372 $this->assertNoText('untranslatable_link_field (all languages)');
373 $this->assertNoText('untranslatable_ref_field (all languages)');
374 $this->assertNoText('Text (all languages)');
378 * Tests the paragraph buttons presence in translation multilingual workflow.
380 * This test covers the following test cases:
381 * 1) original node langcode in EN, translate in FR, change to DE.
382 * 2) original node langcode in DE, change site langcode to DE, change node
385 public function testParagraphTranslationMultilingual() {
386 // Case 1: original node langcode in EN, translate in FR, change to DE.
388 // Add 'Images' paragraph and check the paragraphs buttons are displayed.
389 // Use the experimental widget.
390 $form_display = EntityFormDisplay::load('node.paragraphed_content_demo.default')
391 ->setComponent('field_paragraphs_demo', [
392 'type' => 'paragraphs',
394 $form_display->save();
395 // Use the experimental widget.
396 $form_display = EntityFormDisplay::load('paragraph.nested_paragraph.default')
397 ->setComponent('field_paragraphs_demo', [
398 'type' => 'paragraphs',
400 $form_display->save();
401 $this->drupalGet('node/add/paragraphed_content_demo');
402 $this->drupalPostForm(NULL, NULL, t('Add Images'));
403 $this->assertParagraphsButtons(1);
404 // Upload an image and check the paragraphs buttons are still displayed.
405 $images = $this->drupalGetTestFiles('image')[0];
407 'title[0][value]' => 'Title in english',
408 'files[field_paragraphs_demo_0_subform_field_images_demo_0][]' => $images->uri,
410 $this->drupalPostForm(NULL, $edit, t('Upload'));
411 $this->assertParagraphsButtons(1);
412 $this->drupalPostForm(NULL, NULL, t('Save and publish'));
413 $this->assertText('Title in english');
414 $node = $this->drupalGetNodeByTitle('Title in english');
415 // Check the paragraph langcode is 'en'.
416 $this->assertParagraphsLangcode($node->id());
418 // Add french translation.
419 $this->clickLink(t('Translate'));
420 $this->clickLink(t('Add'), 1);
421 // Make sure the host entity and its paragraphs have valid source language
422 // and check that the paragraphs buttons are hidden.
423 $this->assertNoParagraphsButtons(1);
425 'title[0][value]' => 'Title in french',
427 $this->drupalPostForm(NULL, $edit, t('Save and keep published (this translation)'));
428 $this->assertParagraphsLangcode($node->id(), 'en', 'fr');
429 $this->assertText('Paragraphed article Title in french has been updated.');
430 $this->assertText('Title in french');
431 $this->assertNoText('Title in english');
432 // Check the original node and the paragraph langcode is still 'en'.
433 $this->assertParagraphsLangcode($node->id());
435 // Edit the french translation and upload a new image.
436 $this->clickLink('Edit');
437 $images = $this->drupalGetTestFiles('image')[1];
438 $this->drupalPostForm(NULL, [
439 'files[field_paragraphs_demo_0_subform_field_images_demo_1][]' => $images->uri,
441 // Check editing a translation does not affect the source langcode and
442 // check that the paragraphs buttons are still hidden.
443 $this->assertParagraphsLangcode($node->id(), 'en', 'fr');
444 $this->assertNoParagraphsButtons(1);
445 $this->drupalPostForm(NULL, NULL, t('Save and keep published (this translation)'));
446 $this->assertText('Title in french');
447 $this->assertNoText('Title in english');
449 // Back to the original node.
450 $this->drupalGet('node/' . $node->id());
451 $this->assertText('Title in english');
452 $this->assertNoText('Title in french');
453 // Check the original node and the paragraph langcode are still 'en' and
454 // check that the paragraphs buttons are still displayed.
455 $this->clickLink('Edit');
456 $this->assertParagraphsLangcode($node->id());
457 $this->assertParagraphsButtons(1);
458 // Change the node langcode to 'german', add a 'Nested Paragraph', check
459 // the paragraphs langcode are still 'en' and their buttons are displayed.
461 'title[0][value]' => 'Title in english (de)',
462 'langcode[0][value]' => 'de',
464 $this->drupalPostForm(NULL, $edit, t('Add Nested Paragraph'));
465 $this->assertParagraphsLangcode($node->id());
466 $this->assertParagraphsButtons(2);
467 // Add an 'Images' paragraph inside the nested one, check the paragraphs
468 // langcode are still 'en' and the paragraphs buttons are still displayed.
469 $this->drupalPostAjaxForm(NULL, NULL, 'field_paragraphs_demo_1_subform_field_paragraphs_demo_images_add_more');
470 $this->assertParagraphsLangcode($node->id());
471 $this->assertParagraphsButtons(2);
472 // Upload a new image, check the paragraphs langcode are still 'en' and the
473 // paragraphs buttons are displayed.
474 $images = $this->drupalGetTestFiles('image')[2];
475 $this->drupalPostForm(NULL, [
476 'files[field_paragraphs_demo_1_subform_field_paragraphs_demo_0_subform_field_images_demo_0][]' => $images->uri,
478 $this->assertParagraphsLangcode($node->id());
479 $this->assertParagraphsButtons(2);
480 $this->drupalPostForm(NULL, NULL, t('Save and keep published (this translation)'));
481 $this->assertText('Title in english (de)');
482 $this->assertNoText('Title in french');
483 // Check the original node and the paragraphs langcode are now 'de'.
484 $this->assertParagraphsLangcode($node->id(), 'de');
486 // Check the french translation.
487 $this->drupalGet('fr/node/' . $node->id());
488 $this->assertText('Title in french');
489 $this->assertNoText('Title in english (de)');
490 // Check editing a translation does not affect the source langcode and
491 // check that the paragraphs buttons are still hidden.
492 $this->clickLink('Edit');
493 $this->assertParagraphsLangcode($node->id(), 'de', 'fr');
494 $this->assertNoParagraphsButtons(2);
496 // Case 2: original node langcode in DE, change site langcode to DE, change
497 // node langcode to EN.
499 // Change the site langcode to french.
500 $this->drupalPostForm('admin/config/regional/language', [
501 'site_default_language' => 'fr',
502 ], t('Save configuration'));
504 // Check the original node and its paragraphs langcode are still 'de'
505 // and the paragraphs buttons are still displayed.
506 $this->drupalGet('node/' . $node->id() . '/edit');
507 $this->assertParagraphsLangcode($node->id(), 'de');
508 $this->assertParagraphsButtons(2);
510 // Go to the french translation.
511 $this->drupalGet('node/' . $node->id() . '/translations');
512 $this->clickLink(t('Edit'), 1);
513 // Check editing a translation does not affect the source langcode and
514 // check that the paragraphs buttons are still hidden.
515 $this->assertParagraphsLangcode($node->id(), 'de', 'fr');
516 $this->assertNoParagraphsButtons(2);
517 // Upload another image.
518 $images = $this->drupalGetTestFiles('image')[3];
519 $this->drupalPostForm(NULL, [
520 'files[field_paragraphs_demo_1_subform_field_paragraphs_demo_0_subform_field_images_demo_1][]' => $images->uri,
522 // Check editing a translation does not affect the source langcode and
523 // check that the paragraphs buttons are still hidden.
524 $this->assertParagraphsLangcode($node->id(), 'de', 'fr');
525 $this->assertNoParagraphsButtons(2);
526 $this->drupalPostForm(NULL, NULL, t('Save and keep published (this translation)'));
527 // Check the paragraphs langcode are still 'de' after saving the translation.
528 $this->assertParagraphsLangcode($node->id(), 'de', 'fr');
529 $this->assertText('Title in french');
530 $this->assertNoText('Title in english (de)');
532 // Back to the original node.
533 $this->drupalGet('node/' . $node->id());
534 $this->assertText('Title in english (de)');
535 $this->assertNoText('Title in french');
536 // Check the original node and the paragraphs langcode are still 'de' and
537 // check that the paragraphs buttons are still displayed.
538 $this->clickLink('Edit');
539 $this->assertParagraphsLangcode($node->id(), 'de');
540 $this->assertParagraphsButtons(2);
541 // Change the node langcode back to 'english', add an 'Images' paragraph,
542 // check the paragraphs langcode are still 'de' and their buttons are shown.
544 'title[0][value]' => 'Title in english',
545 'langcode[0][value]' => 'en',
547 $this->drupalPostForm(NULL, $edit, t('Add Images'));
548 $this->assertParagraphsLangcode($node->id(), 'de');
549 $this->assertParagraphsButtons(3);
550 // Upload a new image, check the paragraphs langcode are still 'de' and the
551 // paragraphs buttons are displayed.
552 $images = $this->drupalGetTestFiles('image')[4];
553 $this->drupalPostForm(NULL, [
554 'files[field_paragraphs_demo_2_subform_field_images_demo_0][]' => $images->uri,
556 $this->assertParagraphsLangcode($node->id(), 'de');
557 $this->assertParagraphsButtons(3);
558 $this->drupalPostForm(NULL, NULL, t('Save and keep published (this translation)'));
559 // Check the original node and the paragraphs langcode are now 'en'.
560 $this->assertParagraphsLangcode($node->id());
564 * Tests the paragraphs buttons presence in multilingual workflow.
566 * This test covers the following test cases:
567 * 1) original node langcode in german, change to english.
568 * 2) original node langcode in english, change to german.
569 * 3) original node langcode in english, change site langcode to german,
570 * change node langcode to german.
572 public function testParagraphsMultilingualWorkflow() {
573 // Case 1: Check the paragraphs buttons after changing the NODE language
574 // (original node langcode in GERMAN, default site langcode in english).
575 // Use the experimental widget.
576 $form_display = EntityFormDisplay::load('node.paragraphed_content_demo.default')
577 ->setComponent('field_paragraphs_demo', [
578 'type' => 'paragraphs',
580 $form_display->save();
581 // Use the experimental widget.
582 $form_display = EntityFormDisplay::load('paragraph.nested_paragraph.default')
583 ->setComponent('field_paragraphs_demo', [
584 'type' => 'paragraphs',
586 $form_display->save();
587 // Create a node and check that the node langcode is 'english'.
588 $this->drupalGet('node/add/paragraphed_content_demo');
589 $this->assertOptionSelected('edit-langcode-0-value', 'en');
590 // Change the node langcode to 'german' and add a 'Nested Paragraph'.
592 'title[0][value]' => 'Title in german',
593 'langcode[0][value]' => 'de',
595 $this->drupalPostForm(NULL, $edit, t('Add Nested Paragraph'));
596 // Check that the paragraphs buttons are displayed and add an 'Images'
597 // paragraph inside the nested paragraph.
598 $this->assertParagraphsButtons(1);
599 $this->drupalPostAjaxForm(NULL, NULL, 'field_paragraphs_demo_0_subform_field_paragraphs_demo_images_add_more');
600 // Upload an image and check the paragraphs buttons are still displayed.
601 $images = $this->drupalGetTestFiles('image')[0];
602 $this->drupalPostForm(NULL, [
603 'files[field_paragraphs_demo_0_subform_field_paragraphs_demo_0_subform_field_images_demo_0][]' => $images->uri,
605 $this->assertParagraphsButtons(1);
606 $this->drupalPostForm(NULL, NULL, t('Save and publish'));
607 $this->assertText('Title in german');
608 $node1 = $this->getNodeByTitle('Title in german');
610 // Check the paragraph langcode is 'de' and its buttons are displayed.
611 // @todo check for the nested children paragraphs buttons and langcode
612 // when it's supported.
613 $this->clickLink(t('Edit'));
614 $this->assertParagraphsLangcode($node1->id(), 'de');
615 $this->assertParagraphsButtons(1);
616 // Change the node langcode to 'english' and upload another image.
617 $images = $this->drupalGetTestFiles('image')[1];
619 'title[0][value]' => 'Title in german (en)',
620 'langcode[0][value]' => 'en',
621 'files[field_paragraphs_demo_0_subform_field_paragraphs_demo_0_subform_field_images_demo_1][]' => $images->uri,
623 $this->drupalPostForm(NULL, $edit, t('Upload'));
624 // Check the paragraph langcode is still 'de' and its buttons are shown.
625 $this->assertParagraphsLangcode($node1->id(), 'de');
626 $this->assertParagraphsButtons(1);
627 $this->drupalPostForm(NULL, NULL, t('Save and keep published'));
628 // Check the paragraph langcode is now 'en' after saving.
629 $this->assertParagraphsLangcode($node1->id());
631 // Check the paragraph langcode is 'en' and its buttons are still shown.
632 $this->clickLink(t('Edit'));
633 $this->assertParagraphsLangcode($node1->id());
634 $this->assertParagraphsButtons(1);
636 // Case 2: Check the paragraphs buttons after changing the NODE language
637 // (original node langcode in ENGLISH, default site langcode in english).
639 // Create another node.
640 $this->drupalGet('node/add/paragraphed_content_demo');
641 // Check that the node langcode is 'english' and add a 'Nested Paragraph'.
642 $this->assertOptionSelected('edit-langcode-0-value', 'en');
643 $this->drupalPostForm(NULL, NULL, t('Add Nested Paragraph'));
644 // Check that the paragraphs buttons are displayed and add an 'Images'
645 // paragraph inside the nested paragraph.
646 $this->assertParagraphsButtons(1);
647 $this->drupalPostAjaxForm(NULL, NULL, 'field_paragraphs_demo_0_subform_field_paragraphs_demo_images_add_more');
648 // Upload an image and check the paragraphs buttons are still displayed.
649 $images = $this->drupalGetTestFiles('image')[0];
651 'title[0][value]' => 'Title in english',
652 'files[field_paragraphs_demo_0_subform_field_paragraphs_demo_0_subform_field_images_demo_0][]' => $images->uri,
654 $this->drupalPostForm(NULL, $edit, t('Upload'));
655 $this->assertParagraphsButtons(1);
656 $this->drupalPostForm(NULL, NULL, t('Save and publish'));
657 $this->assertText('Title in english');
658 $node2 = $this->drupalGetNodeByTitle('Title in english');
660 // Check the paragraph langcode is 'en' and its buttons are displayed.
661 // @todo check for the nested children paragraphs buttons and langcode
662 // when it's supported.
663 $this->clickLink(t('Edit'));
664 $this->assertParagraphsLangcode($node2->id());
665 $this->assertParagraphsButtons(1);
666 // Change the node langcode to 'german' and add another 'Images' paragraph.
668 'title[0][value]' => 'Title in english (de)',
669 'langcode[0][value]' => 'de',
671 $this->drupalPostForm(NULL, $edit, t('Add Images'));
672 // Check the paragraphs langcode are still 'en' and their buttons are shown.
673 $this->assertParagraphsLangcode($node2->id());
674 $this->assertParagraphsButtons(2);
675 // Upload an image, check the paragraphs langcode are still 'en' and their
676 // buttons are displayed.
677 $images = $this->drupalGetTestFiles('image')[1];
678 $this->drupalPostForm(NULL, [
679 'files[field_paragraphs_demo_1_subform_field_images_demo_0][]' => $images->uri,
681 $this->assertParagraphsLangcode($node2->id());
682 $this->assertParagraphsButtons(2);
683 $this->drupalPostForm(NULL, NULL, t('Save and keep published'));
684 // Check the paragraphs langcode are now 'de' after saving.
685 $this->assertParagraphsLangcode($node2->id(), 'de');
687 // Change node langcode back to 'english' and save.
688 $this->clickLink(t('Edit'));
690 'title[0][value]' => 'Title in english',
691 'langcode[0][value]' => 'en',
693 $this->drupalPostForm(NULL, $edit, t('Save and keep published'));
694 // Check the paragraphs langcode are now 'en' after saving.
695 $this->assertParagraphsLangcode($node2->id());
697 // Case 3: Check the paragraphs buttons after changing the SITE language.
699 // Change the site langcode to german.
701 'site_default_language' => 'de',
703 $this->drupalPostForm('admin/config/regional/language', $edit, t('Save configuration'));
705 // Check the original node and the paragraphs langcode are still 'en' and
706 // check that the paragraphs buttons are still displayed.
707 $this->drupalGet('node/' . $node2->id() . '/edit');
708 $this->assertParagraphsLangcode($node2->id());
709 $this->assertParagraphsButtons(2);
710 // Add another 'Images' paragraph with node langcode as 'english'.
711 $this->drupalPostForm(NULL, NULL, t('Add Images'));
712 // Check the paragraph langcode are still 'en' and their buttons are shown.
713 $this->assertParagraphsLangcode($node2->id());
714 $this->assertParagraphsButtons(3);
715 // Upload an image, check the paragraphs langcode are still 'en' and their
716 // buttons are displayed.
717 $images = $this->drupalGetTestFiles('image')[2];
718 $this->drupalPostForm(NULL, [
719 'files[field_paragraphs_demo_2_subform_field_images_demo_0][]' => $images->uri,
721 $this->assertParagraphsLangcode($node2->id());
722 $this->assertParagraphsButtons(3);
723 $this->drupalPostForm(NULL, NULL, t('Save and keep published'));
724 // Check the paragraphs langcode are still 'en' after saving.
725 $this->assertParagraphsLangcode($node2->id());
727 // Check the paragraphs langcode are still 'en' and their buttons are shown.
728 $this->clickLink(t('Edit'));
729 $this->assertParagraphsLangcode($node2->id());
730 $this->assertParagraphsButtons(3);
731 // Change node langcode to 'german' and add another 'Images' paragraph.
733 'title[0][value]' => 'Title in english (de)',
734 'langcode[0][value]' => 'de',
736 $this->drupalPostForm(NULL, $edit, t('Add Images'));
737 // Check the paragraphs langcode are still 'en' and their buttons are shown.
738 $this->assertParagraphsLangcode($node2->id());
739 $this->assertParagraphsButtons(4);
740 // Upload an image, check the paragraphs langcode are still 'en' and their
741 // buttons are displayed.
742 $images = $this->drupalGetTestFiles('image')[3];
743 $this->drupalPostForm(NULL, [
744 'files[field_paragraphs_demo_3_subform_field_images_demo_0][]' => $images->uri,
746 $this->assertParagraphsLangcode($node2->id());
747 $this->assertParagraphsButtons(4);
748 $this->drupalPostForm(NULL, NULL, t('Save and keep published'));
749 // Check the paragraphs langcode are now 'de' after saving.
750 $this->assertParagraphsLangcode($node2->id(), 'de');
754 * Passes if the paragraphs buttons are present.
757 * Number of paragraphs buttons to look for.
759 protected function assertParagraphsButtons($count) {
760 $this->assertParagraphsButtonsHelper($count, FALSE);
764 * Passes if the paragraphs buttons are NOT present.
767 * Number of paragraphs buttons to look for.
769 protected function assertNoParagraphsButtons($count) {
770 $this->assertParagraphsButtonsHelper($count, TRUE);
774 * Helper for assertParagraphsButtons and assertNoParagraphsButtons.
777 * Number of paragraphs buttons to look for.
778 * @param bool $hidden
779 * TRUE if these buttons should not be shown, FALSE otherwise.
782 protected function assertParagraphsButtonsHelper($count, $hidden = TRUE) {
783 for ($i = 0; $i < $count; $i++) {
784 $remove_button = $this->xpath('//*[@name="field_paragraphs_demo_' . $i . '_remove"]');
786 $this->assertNotEqual(count($remove_button), 0);
789 $this->assertEqual(count($remove_button), 0);
793 // It is enough to check for the specific paragraph type 'Images' to assert
794 // the add more buttons presence for this test class.
795 $add_button = $this->xpath('//input[@value="Add Images"]');
797 $this->assertNotEqual(count($add_button), 0);
800 $this->assertEqual(count($add_button), 0);
805 * Assert each paragraph items have the same langcode as the node one.
807 * @param string $node_id
808 * The node ID which contains the paragraph items to be checked.
809 * @param string $source_lang
810 * The expected node source langcode. Defaults to 'en'.
811 * @param string $trans_lang
812 * The expected translated node langcode. Defaults to NULL.
814 protected function assertParagraphsLangcode($node_id, $source_lang = 'en', $trans_lang = NULL) {
815 // Update the outdated node and check all the paragraph items langcodes.
816 \Drupal::entityTypeManager()->getStorage('node')->resetCache([$node_id]);
817 /** @var \Drupal\node\NodeInterface $node */
818 $node = Node::load($node_id);
819 $node_langcode = $node->langcode->value;
820 $this->assertEqual($node_langcode, $source_lang, 'Host langcode matches.');
822 /** @var \Drupal\Core\Entity\ContentEntityBase $paragraph */
823 foreach ($node->field_paragraphs_demo->referencedEntities() as $paragraph) {
824 $paragraph_langcode = $paragraph->language()->getId();
825 $message = new FormattableMarkup('Node langcode is "@node", paragraph item langcode is "@item".', ['@node' => $source_lang, '@item' => $paragraph_langcode]);
826 $this->assertEqual($paragraph_langcode, $source_lang, $message);
829 // Check the translation.
830 if (!empty($trans_lang)) {
831 $this->assertTrue($node->hasTranslation($trans_lang), 'Translation exists.');
833 if ($node->hasTranslation($trans_lang)) {
834 $trans_node = $node->getTranslation($trans_lang);
835 $trans_node_langcode = $trans_node->language()->getId();
836 $this->assertEqual($trans_node_langcode, $trans_lang, 'Translated node langcode matches.');
838 // Check the paragraph item langcode matching the translated node langcode.
839 foreach ($trans_node->field_paragraphs_demo->referencedEntities() as $paragraph) {
840 if ($paragraph->hasTranslation($trans_lang)) {
841 $trans_item = $paragraph->getTranslation($trans_lang);
842 $paragraph_langcode = $trans_item->language()->getId();
843 $message = new FormattableMarkup('Translated node langcode is "@node", paragraph item langcode is "@item".', ['@node' => $trans_lang, '@item' => $paragraph_langcode]);
844 $this->assertEqual($paragraph_langcode, $trans_lang, $message);