You are here

public function ContentTranslationSyncImageTest::testImageFieldSync in Drupal 8

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

Tests image field field synchronization.

File

core/modules/content_translation/tests/src/Functional/ContentTranslationSyncImageTest.php, line 102

Class

ContentTranslationSyncImageTest
Tests the field synchronization behavior for the image field.

Namespace

Drupal\Tests\content_translation\Functional

Code

public function testImageFieldSync() {

  // Check that the alt and title fields are enabled for the image field.
  $this
    ->drupalLogin($this->editor);
  $this
    ->drupalGet('entity_test_mul/structure/' . $this->entityTypeId . '/fields/' . $this->entityTypeId . '.' . $this->entityTypeId . '.' . $this->fieldName);
  $this
    ->assertFieldChecked('edit-third-party-settings-content-translation-translation-sync-alt');
  $this
    ->assertFieldChecked('edit-third-party-settings-content-translation-translation-sync-title');
  $edit = [
    'third_party_settings[content_translation][translation_sync][alt]' => FALSE,
    'third_party_settings[content_translation][translation_sync][title]' => FALSE,
  ];
  $this
    ->drupalPostForm(NULL, $edit, t('Save settings'));

  // Check that the content translation settings page reflects the changes
  // performed in the field edit page.
  $this
    ->drupalGet('admin/config/regional/content-language');
  $this
    ->assertNoFieldChecked('edit-settings-entity-test-mul-entity-test-mul-columns-field-test-et-ui-image-alt');
  $this
    ->assertNoFieldChecked('edit-settings-entity-test-mul-entity-test-mul-columns-field-test-et-ui-image-title');
  $edit = [
    'settings[entity_test_mul][entity_test_mul][fields][field_test_et_ui_image]' => TRUE,
    'settings[entity_test_mul][entity_test_mul][columns][field_test_et_ui_image][alt]' => TRUE,
    'settings[entity_test_mul][entity_test_mul][columns][field_test_et_ui_image][title]' => TRUE,
  ];
  $this
    ->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration'));
  $errors = $this
    ->xpath('//div[contains(@class, "messages--error")]');
  $this
    ->assertEmpty($errors, 'Settings correctly stored.');
  $this
    ->assertFieldChecked('edit-settings-entity-test-mul-entity-test-mul-columns-field-test-et-ui-image-alt');
  $this
    ->assertFieldChecked('edit-settings-entity-test-mul-entity-test-mul-columns-field-test-et-ui-image-title');
  $this
    ->drupalLogin($this->translator);
  $default_langcode = $this->langcodes[0];
  $langcode = $this->langcodes[1];

  // Populate the test entity with some random initial values.
  $values = [
    'name' => $this
      ->randomMachineName(),
    'user_id' => mt_rand(1, 128),
    'langcode' => $default_langcode,
  ];
  $entity = \Drupal::entityTypeManager()
    ->getStorage($this->entityTypeId)
    ->create($values);

  // Create some file entities from the generated test files and store them.
  $values = [];
  for ($delta = 0; $delta < $this->cardinality; $delta++) {

    // For the default language use the same order for files and field items.
    $index = $delta;

    // Create the file entity for the image being processed and record its
    // identifier.
    $field_values = [
      'uri' => $this->files[$index]->uri,
      'uid' => \Drupal::currentUser()
        ->id(),
      'status' => FILE_STATUS_PERMANENT,
    ];
    $file = File::create($field_values);
    $file
      ->save();
    $fid = $file
      ->id();
    $this->files[$index]->fid = $fid;

    // Generate the item for the current image file entity and attach it to
    // the entity.
    $item = [
      'target_id' => $fid,
      'alt' => $default_langcode . '_' . $fid . '_' . $this
        ->randomMachineName(),
      'title' => $default_langcode . '_' . $fid . '_' . $this
        ->randomMachineName(),
    ];
    $entity->{$this->fieldName}[] = $item;

    // Store the generated values keying them by fid for easier lookup.
    $values[$default_langcode][$fid] = $item;
  }
  $entity = $this
    ->saveEntity($entity);

  // Create some field translations for the test image field. The translated
  // items will be one less than the original values to check that only the
  // translated ones will be preserved. In fact we want the same fids and
  // items order for both languages.
  $translation = $entity
    ->addTranslation($langcode);
  for ($delta = 0; $delta < $this->cardinality - 1; $delta++) {

    // Simulate a field reordering: items are shifted of one position ahead.
    // The modulo operator ensures we start from the beginning after reaching
    // the maximum allowed delta.
    $index = ($delta + 1) % $this->cardinality;

    // Generate the item for the current image file entity and attach it to
    // the entity.
    $fid = $this->files[$index]->fid;
    $item = [
      'target_id' => $fid,
      'alt' => $langcode . '_' . $fid . '_' . $this
        ->randomMachineName(),
      'title' => $langcode . '_' . $fid . '_' . $this
        ->randomMachineName(),
    ];
    $translation->{$this->fieldName}[] = $item;

    // Again store the generated values keying them by fid for easier lookup.
    $values[$langcode][$fid] = $item;
  }

  // Perform synchronization: the translation language is used as source,
  // while the default language is used as target.
  $this->manager
    ->getTranslationMetadata($translation)
    ->setSource($default_langcode);
  $entity = $this
    ->saveEntity($translation);
  $translation = $entity
    ->getTranslation($langcode);

  // Check that one value has been dropped from the original values.
  $assert = count($entity->{$this->fieldName}) == 2;
  $this
    ->assertTrue($assert, 'One item correctly removed from the synchronized field values.');

  // Check that fids have been synchronized and translatable column values
  // have been retained.
  $fids = [];
  foreach ($entity->{$this->fieldName} as $delta => $item) {
    $value = $values[$default_langcode][$item->target_id];
    $source_item = $translation->{$this->fieldName}
      ->get($delta);
    $assert = $item->target_id == $source_item->target_id && $item->alt == $value['alt'] && $item->title == $value['title'];
    $this
      ->assertTrue($assert, new FormattableMarkup('Field item @fid has been successfully synchronized.', [
      '@fid' => $item->target_id,
    ]));
    $fids[$item->target_id] = TRUE;
  }

  // Check that the dropped value is the right one.
  $removed_fid = $this->files[0]->fid;
  $this
    ->assertTrue(!isset($fids[$removed_fid]), new FormattableMarkup('Field item @fid has been correctly removed.', [
    '@fid' => $removed_fid,
  ]));

  // Add back an item for the dropped value and perform synchronization again.
  $values[$langcode][$removed_fid] = [
    'target_id' => $removed_fid,
    'alt' => $langcode . '_' . $removed_fid . '_' . $this
      ->randomMachineName(),
    'title' => $langcode . '_' . $removed_fid . '_' . $this
      ->randomMachineName(),
  ];
  $translation->{$this->fieldName}
    ->setValue(array_values($values[$langcode]));
  $entity = $this
    ->saveEntity($translation);
  $translation = $entity
    ->getTranslation($langcode);

  // Check that the value has been added to the default language.
  $assert = count($entity->{$this->fieldName}
    ->getValue()) == 3;
  $this
    ->assertTrue($assert, 'One item correctly added to the synchronized field values.');
  foreach ($entity->{$this->fieldName} as $delta => $item) {

    // When adding an item its value is copied over all the target languages,
    // thus in this case the source language needs to be used to check the
    // values instead of the target one.
    $fid_langcode = $item->target_id != $removed_fid ? $default_langcode : $langcode;
    $value = $values[$fid_langcode][$item->target_id];
    $source_item = $translation->{$this->fieldName}
      ->get($delta);
    $assert = $item->target_id == $source_item->target_id && $item->alt == $value['alt'] && $item->title == $value['title'];
    $this
      ->assertTrue($assert, new FormattableMarkup('Field item @fid has been successfully synchronized.', [
      '@fid' => $item->target_id,
    ]));
  }
}