You are here

protected function ContentTranslationUITestBase::doTestBasicTranslation in Drupal 10

Same name and namespace in other branches
  1. 8 core/modules/content_translation/tests/src/Functional/ContentTranslationUITestBase.php \Drupal\Tests\content_translation\Functional\ContentTranslationUITestBase::doTestBasicTranslation()
  2. 9 core/modules/content_translation/tests/src/Functional/ContentTranslationUITestBase.php \Drupal\Tests\content_translation\Functional\ContentTranslationUITestBase::doTestBasicTranslation()

Tests the basic translation workflow.

File

core/modules/content_translation/tests/src/Functional/ContentTranslationUITestBase.php, line 70

Class

ContentTranslationUITestBase
Tests the Content Translation UI.

Namespace

Drupal\Tests\content_translation\Functional

Code

protected function doTestBasicTranslation() {

  // Create a new test entity with original values in the default language.
  $default_langcode = $this->langcodes[0];
  $values[$default_langcode] = $this
    ->getNewEntityValues($default_langcode);

  // Create the entity with the editor as owner, so that afterwards a new
  // translation is created by the translator and the translation author is
  // tested.
  $this
    ->drupalLogin($this->editor);
  $this->entityId = $this
    ->createEntity($values[$default_langcode], $default_langcode);
  $this
    ->drupalLogin($this->translator);
  $storage = $this->container
    ->get('entity_type.manager')
    ->getStorage($this->entityTypeId);
  $storage
    ->resetCache([
    $this->entityId,
  ]);
  $entity = $storage
    ->load($this->entityId);
  $this
    ->assertNotEmpty($entity, 'Entity found in the database.');
  $this
    ->drupalGet($entity
    ->toUrl());
  $this
    ->assertSession()
    ->statusCodeEquals(200);

  // Ensure that the content language cache context is not yet added to the
  // page.
  $this
    ->assertCacheContexts($this->defaultCacheContexts);
  $this
    ->drupalGet($entity
    ->toUrl('drupal:content-translation-overview'));
  $this
    ->assertSession()
    ->pageTextNotContains('Source language');
  $translation = $this
    ->getTranslation($entity, $default_langcode);
  foreach ($values[$default_langcode] as $property => $value) {
    $stored_value = $this
      ->getValue($translation, $property, $default_langcode);
    $value = is_array($value) ? $value[0]['value'] : $value;
    $message = new FormattableMarkup('@property correctly stored in the default language.', [
      '@property' => $property,
    ]);
    $this
      ->assertEquals($value, $stored_value, $message);
  }

  // Add a content translation.
  $langcode = 'it';
  $language = ConfigurableLanguage::load($langcode);
  $values[$langcode] = $this
    ->getNewEntityValues($langcode);
  $entity_type_id = $entity
    ->getEntityTypeId();
  $add_url = Url::fromRoute("entity.{$entity_type_id}.content_translation_add", [
    $entity
      ->getEntityTypeId() => $entity
      ->id(),
    'source' => $default_langcode,
    'target' => $langcode,
  ], [
    'language' => $language,
  ]);
  $this
    ->drupalGet($add_url);
  $this
    ->submitForm($this
    ->getEditValues($values, $langcode), $this
    ->getFormSubmitActionForNewTranslation($entity, $langcode));

  // Assert that HTML is not escaped unexpectedly.
  if ($this->testHTMLEscapeForAllLanguages) {
    $this
      ->assertSession()
      ->responseNotContains('<span class="translation-entity-all-languages">(all languages)</span>');
    $this
      ->assertSession()
      ->responseContains('<span class="translation-entity-all-languages">(all languages)</span>');
  }

  // Ensure that the content language cache context is not yet added to the
  // page.
  $storage = $this->container
    ->get('entity_type.manager')
    ->getStorage($this->entityTypeId);
  $storage
    ->resetCache([
    $this->entityId,
  ]);
  $entity = $storage
    ->load($this->entityId);
  $this
    ->drupalGet($entity
    ->toUrl());
  $this
    ->assertCacheContexts(Cache::mergeContexts([
    'languages:language_content',
  ], $this->defaultCacheContexts));

  // Reset the cache of the entity, so that the new translation gets the
  // updated values.
  $metadata_source_translation = $this->manager
    ->getTranslationMetadata($entity
    ->getTranslation($default_langcode));
  $metadata_target_translation = $this->manager
    ->getTranslationMetadata($entity
    ->getTranslation($langcode));
  $author_field_name = $entity
    ->hasField('content_translation_uid') ? 'content_translation_uid' : 'uid';
  if ($entity
    ->getFieldDefinition($author_field_name)
    ->isTranslatable()) {
    $this
      ->assertEquals($this->translator
      ->id(), $metadata_target_translation
      ->getAuthor()
      ->id(), new FormattableMarkup('Author of the target translation @langcode correctly stored for translatable owner field.', [
      '@langcode' => $langcode,
    ]));
    $this
      ->assertNotEquals($metadata_target_translation
      ->getAuthor()
      ->id(), $metadata_source_translation
      ->getAuthor()
      ->id(), new FormattableMarkup('Author of the target translation @target different from the author of the source translation @source for translatable owner field.', [
      '@target' => $langcode,
      '@source' => $default_langcode,
    ]));
  }
  else {
    $this
      ->assertEquals($this->editor
      ->id(), $metadata_target_translation
      ->getAuthor()
      ->id(), 'Author of the entity remained untouched after translation for non translatable owner field.');
  }
  $created_field_name = $entity
    ->hasField('content_translation_created') ? 'content_translation_created' : 'created';
  if ($entity
    ->getFieldDefinition($created_field_name)
    ->isTranslatable()) {

    // Verify that the translation creation timestamp of the target
    // translation language is newer than the creation timestamp of the source
    // translation default language for the translatable created field.
    $this
      ->assertGreaterThan($metadata_source_translation
      ->getCreatedTime(), $metadata_target_translation
      ->getCreatedTime());
  }
  else {
    $this
      ->assertEquals($metadata_source_translation
      ->getCreatedTime(), $metadata_target_translation
      ->getCreatedTime(), 'Creation timestamp of the entity remained untouched after translation for non translatable created field.');
  }
  if ($this->testLanguageSelector) {

    // Verify that language selector is correctly disabled on translations.
    $this
      ->assertSession()
      ->fieldNotExists('edit-langcode-0-value');
  }
  $storage
    ->resetCache([
    $this->entityId,
  ]);
  $entity = $storage
    ->load($this->entityId);
  $this
    ->drupalGet($entity
    ->toUrl('drupal:content-translation-overview'));
  $this
    ->assertSession()
    ->pageTextNotContains('Source language');

  // Switch the source language.
  $langcode = 'fr';
  $language = ConfigurableLanguage::load($langcode);
  $source_langcode = 'it';
  $edit = [
    'source_langcode[source]' => $source_langcode,
  ];
  $entity_type_id = $entity
    ->getEntityTypeId();
  $add_url = Url::fromRoute("entity.{$entity_type_id}.content_translation_add", [
    $entity
      ->getEntityTypeId() => $entity
      ->id(),
    'source' => $default_langcode,
    'target' => $langcode,
  ], [
    'language' => $language,
  ]);

  // This does not save anything, it merely reloads the form and fills in the
  // fields with the values from the different source language.
  $this
    ->drupalGet($add_url);
  $this
    ->submitForm($edit, 'Change');
  $this
    ->assertSession()
    ->fieldValueEquals("{$this->fieldName}[0][value]", $values[$source_langcode][$this->fieldName][0]['value']);

  // Add another translation and mark the other ones as outdated.
  $values[$langcode] = $this
    ->getNewEntityValues($langcode);
  $edit = $this
    ->getEditValues($values, $langcode) + [
    'content_translation[retranslate]' => TRUE,
  ];
  $entity_type_id = $entity
    ->getEntityTypeId();
  $add_url = Url::fromRoute("entity.{$entity_type_id}.content_translation_add", [
    $entity
      ->getEntityTypeId() => $entity
      ->id(),
    'source' => $source_langcode,
    'target' => $langcode,
  ], [
    'language' => $language,
  ]);
  $this
    ->drupalGet($add_url);
  $this
    ->submitForm($edit, $this
    ->getFormSubmitActionForNewTranslation($entity, $langcode));
  $storage
    ->resetCache([
    $this->entityId,
  ]);
  $entity = $storage
    ->load($this->entityId);
  $this
    ->drupalGet($entity
    ->toUrl('drupal:content-translation-overview'));
  $this
    ->assertSession()
    ->pageTextContains('Source language');

  // Check that the entered values have been correctly stored.
  foreach ($values as $langcode => $property_values) {
    $translation = $this
      ->getTranslation($entity, $langcode);
    foreach ($property_values as $property => $value) {
      $stored_value = $this
        ->getValue($translation, $property, $langcode);
      $value = is_array($value) ? $value[0]['value'] : $value;
      $message = new FormattableMarkup('%property correctly stored with language %language.', [
        '%property' => $property,
        '%language' => $langcode,
      ]);
      $this
        ->assertEquals($value, $stored_value, $message);
    }
  }
}