layout_paragraphs-1.0.x-dev/tests/src/FunctionalJavascript/TranslationTest.php

tests/src/FunctionalJavascript/TranslationTest.php
<?php

declare(strict_types=1);

namespace Drupal\Tests\layout_paragraphs\FunctionalJavascript;

use Behat\Mink\Exception\ExpectationException;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\language\Entity\ContentLanguageSettings;

/**
 * Tests various translation contexts for Layout Paragraphs.
 *
 * @group layout_paragraphs
 */
class TranslationTest extends BuilderTestBase {


  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'layout_paragraphs',
    'paragraphs',
    'node',
    'field',
    'field_ui',
    'block',
    'paragraphs_test',
    'content_translation',
    'language',
    'layout_paragraphs_translations_test',
  ];

  /**
   * Tests symmetric translations.
   */
  public function testSymmetricTranslations() {
    $this->testContentTranslations(FALSE);
  }

  /**
   * Tests asymmetric translations.
   */
  public function testAsymmetricTranslations() {
    $this->testContentTranslations(TRUE);

    /** @var Drupal\node\Entity\Node $node */
    $node = \Drupal::entityTypeManager()
      ->getStorage('node')
      ->load(1);

    $paragraphs = $node->field_content->referencedEntities();
    $src_paragraph_ids = array_map(function ($paragraph) {
      return $paragraph->id();
    }, $paragraphs);
    $src_paragraph_languages = array_unique(array_map(function ($paragraph) {
      return $paragraph->language()->getId();
    }, $paragraphs));

    $translation = $node->getTranslation('de');
    $paragraphs = $translation->field_content->referencedEntities();
    $translation_paragraph_ids = array_map(function ($paragraph) {
      return $paragraph->id();
    }, $paragraphs);
    $translation_paragraph_languages = array_unique(array_map(function ($paragraph) {
      return $paragraph->language()->getId();
    }, $paragraphs));

    if (count($src_paragraph_languages) > 1) {
      throw new ExpectationException('There should only be one language in source paragraphs.', $this->getSession()->getDriver());
    }
    if (count($translation_paragraph_languages) > 1) {
      throw new ExpectationException('There should only be one language in translated paragraphs.', $this->getSession()->getDriver());
    }
    if ($translation_paragraph_languages == $src_paragraph_languages) {
      throw new ExpectationException('Translated paragraphs should be in a different language than source paragraphs.', $this->getSession()->getDriver());
    }
    if (count(array_intersect($src_paragraph_ids, $translation_paragraph_ids)) > 0) {
      throw new ExpectationException('Async translations should duplicate paragraphs, not just translate them.', $this->getSession()->getDriver());
    }
  }

  /**
   * Tests switching the host entity language.
   */
  public function testSwitchLanguage() {
    $this->enableTranslations();
    $this->createTestContent();
    $this->drupalGet('node/1/edit');
    $this->submitForm([
      'title[0][value]' => 'Node title (de)',
      'langcode[0][value]' => 'de',
    ], 'Save');
    // Test that all paragraphs have "de" langcode, not "en".
    $this->assertSession()->pageTextContains('Section component language: de');
    $this->assertSession()->pageTextContains('Text component language: de');
    $this->assertSession()->pageTextNotContains('Text component language: en');
    $this->assertSession()->pageTextNotContains('Text component language: en');
  }

  /**
   * Tests adding paragraphs in the correct language.
   */
  public function testAddedInCorrectLanguage() {
    $this->testSwitchLanguage();
    $this->drupalGet('node/1/edit');
    $this->addTextComponent('Language should be "de".', '.layout__region--first .lpb-btn--add.after');
    $this->assertSession()->pageTextNotContains('Text component language: en');
    $this->assertSession()->pageTextContains('Text component language: de');
    $this->htmlOutput($this->getSession()->getPage()->getHtml());
  }

  /**
   * Enables content translations.
   *
   * @param bool $asymmetric
   *   Whether to support asymmetric translations.
   */
  protected function enableTranslations($asymmetric = FALSE) {
    // Add a second language.
    ConfigurableLanguage::create(['id' => 'de'])->save();

    // Configure content translation.
    \Drupal::service('content_translation.manager')->setEnabled('node', 'page', TRUE);
    ContentLanguageSettings::loadByEntityTypeBundle('node', 'page')
      ->setLanguageAlterable(TRUE)
      ->save();
    if ($asymmetric) {
      // Reference field IS translatable for asymmetrical translations.
      \Drupal::service('entity_field.manager')->getFieldDefinitions('node', 'page')['field_content']->setTranslatable(TRUE)->save();
      // Disable translation for paragraphs, as they are cloned not translated.
      \Drupal::service('content_translation.manager')->setEnabled('paragraph', 'text', FALSE);
      \Drupal::service('content_translation.manager')->setEnabled('paragraph', 'section', FALSE);
      \Drupal::service('entity_field.manager')->getFieldDefinitions('paragraph', 'text')['field_text']->setTranslatable(FALSE)->save();
    }
    else {
      // Reference field IS NOT translatable for symmetrical translations.
      \Drupal::service('entity_field.manager')->getFieldDefinitions('node', 'page')['field_content']->setTranslatable(FALSE)->save();
      // Enable translation for paragraphs.
      \Drupal::service('content_translation.manager')->setEnabled('paragraph', 'text', TRUE);
      \Drupal::service('content_translation.manager')->setEnabled('paragraph', 'section', TRUE);
      \Drupal::service('entity_field.manager')->getFieldDefinitions('paragraph', 'text')['field_text']->setTranslatable(TRUE)->save();
    }
  }

  /**
   * Creates some test content.
   */
  protected function createTestContent() {
    $this->loginWithPermissions([
      'create page content',
      'edit own page content',
      'create content translations',
      'translate any entity',
    ]);

    // Create a new page.
    $this->drupalGet('node/add/page');

    // Add a three-column section.
    $this->addSectionComponent(2, '.lpb-btn--add');

    // Add a text component to each section and save the node.
    $this->addTextComponent('First component', '.layout__region--first .lpb-btn--add');
    $this->addTextComponent('Second component', '.layout__region--second .lpb-btn--add');
    $this->addTextComponent('Third component', '.layout__region--third .lpb-btn--add');
    $this->submitForm([
      'title[0][value]' => 'Node title',
    ], 'Save');
  }

  /**
   * Tests symmetric or asymmetric translations.
   */
  protected function testContentTranslations($asymmetric = FALSE) {

    $this->enableTranslations($asymmetric);
    $this->createTestContent();

    // Translate the node into German.
    $this->drupalGet('node/1/translations');
    $page = $this->getSession()->getPage();
    $button = $page->find('css', '[hreflang="de"]');
    $button->click();

    if ($asymmetric) {
      // Test that the interface shows the asymmetric translation warning
      // and that delete/duplicate buttons are NOT hidden.
      $this->assertSession()->pageTextContains('You are in translation mode. Changes will only affect the current language.');
      $this->assertSession()->elementExists('css', '.lpb-duplicate');
      $this->assertSession()->elementExists('css', '.lpb-delete');
    }
    else {
      $this->assertSession()->pageTextContains('You are in translation mode. You cannot add or remove items while translating. Reordering items will affect all languages.');
      $this->assertSession()->elementNotExists('css', '.lpb-duplicate');
      $this->assertSession()->elementNotExists('css', '.lpb-delete');
    }

    // Change the text of the German-language components and save the node.
    $this->changeTextComponentText('.layout__region--first .lpb-edit', 'first (de)');
    $this->changeTextComponentText('.layout__region--second .lpb-edit', 'second (de)');
    $this->changeTextComponentText('.layout__region--third .lpb-edit', 'third (de)');
    $this->submitForm([
      'title[0][value]' => 'Node title (de)',
    ], 'Save');

    // Test that the English-language node was not affected.
    $this->drupalGet('node/1');
    $this->assertSession()->pageTextNotContains('first (de)');
    $this->assertSession()->pageTextNotContains('second (de)');
    $this->assertSession()->pageTextNotContains('third (de)');

    // Test that the German-language node was correctly changed.
    $this->drupalGet('de/node/1');
    $this->assertSession()->pageTextContains('first (de)');
    $this->assertSession()->pageTextContains('second (de)');
    $this->assertSession()->pageTextContains('third (de)');

    $this->drupalGet('node/1/edit');
    $button = $page->find('css', '.layout__region--third a.lpb-delete');
    $button->click();
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->assertSession()->pageTextContains('Delete component');
    $button = $page->find('css', 'button.lpb-btn--confirm-delete');
    $button->click();
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->assertSession()->pageTextNotContains('third');
    $this->submitForm([], 'Save');
    $this->assertSession()->pageTextNotContains('third');
    $this->drupalGet('de/node/1');

    if ($asymmetric) {
      // Test that deleting a component from the primary language node
      // DOES NOT remove the component from the translation.
      $this->assertSession()->pageTextContains('third (de)');
    }
    else {
      // If in symmetric mode, deleting component from the primary language
      // deletes it everywhere.
      $this->assertSession()->pageTextNotContains('third (de)');
    }

  }

  /**
   * Changes the text field for a text component.
   *
   * @param string $css_selector
   *   CSS selector of the edit button to push.
   * @param string $new_text
   *   The new text value.
   */
  protected function changeTextComponentText($css_selector, $new_text) {
    $page = $this->getSession()->getPage();
    $button = $page->find('css', $css_selector);
    $button->click();
    $this->assertSession()->assertWaitOnAjaxRequest();
    $page->fillField('field_text[0][value]', $new_text);
    // Force show the hidden submit button so we can click it.
    $this->getSession()->executeScript("jQuery('.lpb-btn--save').attr('style', '');");
    $button = $this->assertSession()->waitForElementVisible('css', ".lpb-btn--save");
    $button->press();
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->assertSession()->pageTextContains($new_text);
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc