function ContentTmgmtEntitySourceUiTest::testNodeTranslateTabSingleCheckout

Test the translate tab for a single checkout.

File

sources/content/tests/src/Functional/ContentTmgmtEntitySourceUiTest.php, line 60

Class

ContentTmgmtEntitySourceUiTest
Content entity source UI tests.

Namespace

Drupal\Tests\tmgmt_content\Functional

Code

function testNodeTranslateTabSingleCheckout() {
  $this
    ->loginAsTranslator(array(
    'translate any entity',
    'create content translations',
  ));

  // Create an english source node.
  $node = $this
    ->createTranslatableNode('page', 'en');

  // Create a nodes that will not be translated to test the missing
  // translation filter.
  $node_not_translated = $this
    ->createTranslatableNode('page', 'en');
  $node_german = $this
    ->createTranslatableNode('page', 'de');

  // Go to the translate tab.
  $this
    ->drupalGet('node/' . $node
    ->id());
  $this
    ->clickLink('Translate');

  // Assert some basic strings on that page.
  $this
    ->assertSession()
    ->pageTextContains(t('Translations of @title', array(
    '@title' => $node
      ->getTitle(),
  )));
  $this
    ->assertSession()
    ->pageTextContains('Pending Translations');

  // Request a translation for german.
  $edit = array(
    'languages[de]' => TRUE,
  );
  $this
    ->submitForm($edit, 'Request translation');

  // Verify that we are on the translate tab.
  $this
    ->assertSession()
    ->pageTextContains('One job needs to be checked out.');
  $this
    ->assertSession()
    ->pageTextContains($node
    ->getTitle());

  // Submit.
  $this
    ->submitForm([], 'Submit to provider');

  // Make sure that we're back on the translate tab.
  $this
    ->assertEquals($node
    ->toUrl('canonical', array(
    'absolute' => TRUE,
  ))
    ->toString() . '/translations', $this
    ->getUrl());
  $this
    ->assertSession()
    ->pageTextContains('Test translation created.');
  $this
    ->assertSession()
    ->pageTextContains(t('The translation of @title to @language is finished and can now be reviewed.', array(
    '@title' => $node
      ->getTitle(),
    '@language' => t('German'),
  )));

  // Verify that the pending translation is shown.
  $this
    ->clickLinkWithImageTitle('Needs review');
  $this
    ->submitForm([], 'Save as completed');
  $node = Node::load($node
    ->id());
  $translation = $node
    ->getTranslation('de');
  $this
    ->assertSession()
    ->pageTextContains((string) t('The translation for @title has been accepted as @target.', array(
    '@title' => $node
      ->getTitle(),
    '@target' => $translation
      ->label(),
  )));

  // German node should now be listed and be clickable.
  $this
    ->clickLink('de(de-ch): ' . $node
    ->label());
  $this
    ->assertSession()
    ->pageTextContains('de(de-ch): ' . $node
    ->getTitle());
  $this
    ->assertSession()
    ->pageTextContains('de(de-ch): ' . $node->body->value);

  // Test that the destination query argument does not break the redirect
  // and we are redirected back to the correct page.
  // Go to the translate tab.
  $this
    ->drupalGet('node/' . $node
    ->id());
  $this
    ->clickLink('Translate');

  // Request a translation for french.
  $edit = array(
    'languages[fr]' => TRUE,
  );
  $this
    ->submitForm($edit, 'Request translation');
  $this
    ->drupalGet('node/' . $node
    ->id() . '/translations', array(
    'query' => array(
      'destination' => 'node/' . $node
        ->id(),
    ),
  ));

  // The job item is not yet active.
  $this
    ->clickLink('Inactive');
  $this
    ->assertSession()
    ->pageTextContains($node
    ->getTitle());
  $this
    ->assertSession()
    ->responseContains('<div data-drupal-selector="edit-actions" class="form-actions js-form-wrapper form-wrapper" id="edit-actions">');

  // Assert that the validation of HTML tags with editor works.
  $this
    ->submitForm([], 'Validate HTML tags');
  $this
    ->assertSession()
    ->pageTextContains($node
    ->label());
  $this
    ->assertSession()
    ->statusCodeEquals(200);
  $this
    ->drupalGet('node/' . $node
    ->id() . '/translations', array(
    'query' => array(
      'destination' => 'node/' . $node
        ->id(),
    ),
  ));

  // Request a spanish translation.
  $edit = array(
    'languages[es]' => TRUE,
  );
  $this
    ->submitForm($edit, 'Request translation');

  // Verify that we are on the checkout page.
  $this
    ->assertSession()
    ->pageTextContains('One job needs to be checked out.');
  $this
    ->assertSession()
    ->pageTextContains($node
    ->getTitle());
  $this
    ->submitForm([], 'Submit to provider');

  // Make sure that we're back on the originally defined destination URL.
  $this
    ->assertEquals($node
    ->toUrl('canonical', array(
    'absolute' => TRUE,
  ))
    ->toString(), $this
    ->getUrl());

  // Test the missing translation filter.
  $this
    ->drupalGet('admin/tmgmt/sources/content/node');
  $this
    ->assertSession()
    ->pageTextContains($node
    ->getTitle());
  $this
    ->assertSession()
    ->pageTextContains($node_not_translated
    ->getTitle());
  $this
    ->submitForm([
    'search[target_language]' => 'de',
    'search[target_status]' => 'untranslated',
  ], 'Search');
  $this
    ->assertSession()
    ->pageTextNotContains($node
    ->getTitle());
  $this
    ->assertSession()
    ->pageTextNotContains($node_german
    ->getTitle());
  $this
    ->assertSession()
    ->pageTextContains($node_not_translated
    ->getTitle());

  // Update the outdated flag of the translated node and test if it is
  // listed among sources with missing translation.
  \Drupal::entityTypeManager()
    ->getStorage('node')
    ->resetCache();
  $node = Node::load($node
    ->id());
  $node
    ->getTranslation('de')->content_translation_outdated->value = 1;
  $node
    ->save();
  $this
    ->submitForm([
    'search[target_language]' => 'de',
    'search[target_status]' => 'outdated',
  ], 'Search');
  $this
    ->assertSession()
    ->pageTextContains($node
    ->getTitle());
  $this
    ->assertSession()
    ->pageTextNotContains($node_german
    ->getTitle());
  $this
    ->assertSession()
    ->pageTextNotContains($node_not_translated
    ->getTitle());
  $this
    ->submitForm([
    'search[target_language]' => 'de',
    'search[target_status]' => 'untranslated_or_outdated',
  ], 'Search');
  $this
    ->assertSession()
    ->pageTextContains($node
    ->getTitle());
  $this
    ->assertSession()
    ->pageTextNotContains($node_german
    ->getTitle());
  $this
    ->assertSession()
    ->pageTextContains($node_not_translated
    ->getTitle());

  // Check that is set to outdated.
  $xpath = $this
    ->xpath('//*[@id="edit-items"]/tbody/tr[2]/td[6]/a/img');
  $this
    ->assertEquals('Translation Outdated', $xpath[0]
    ->getAttribute('title'));

  // Check that the icons link to the appropriate translations.
  $xpath_source = $this
    ->xpath('//*[@id="edit-items"]/tbody/tr[2]/td[4]/*[1]');
  $xpath_not_translated = $this
    ->xpath('//*[@id="edit-items"]/tbody/tr[2]/td[5]/*[1]');
  $xpath_outdated = $this
    ->xpath('//*[@id="edit-items"]/tbody/tr[2]/td[6]/*[1]');
  $this
    ->assertTrue(strpos($xpath_source[0]
    ->getAttribute('href'), '/node/1') !== FALSE);
  $this
    ->assertStringContainsString('node/1', $xpath_source[0]
    ->getAttribute('href'));
  $this
    ->assertNotEquals('a', $xpath_not_translated[0]
    ->getTagName());
  $this
    ->assertStringContainsString('/de/node/1', $xpath_outdated[0]
    ->getAttribute('href'));

  // Test that a job can not be accepted if the entity does not exist.
  $deleted_node = $this
    ->createTranslatableNode('page', 'en');
  $second_node = $this
    ->createTranslatableNode('page', 'en');
  $this
    ->drupalGet('node/' . $deleted_node
    ->id() . '/translations');
  $edit = array(
    'languages[de]' => TRUE,
  );
  $this
    ->submitForm($edit, 'Request translation');
  $this
    ->submitForm([], 'Submit to provider');
  $edit = array(
    'languages[fr]' => TRUE,
  );
  $this
    ->submitForm($edit, 'Request translation');
  $this
    ->submitForm([], 'Submit to provider');
  $job = $this
    ->createJob('en', 'de');
  $job
    ->addItem('content', 'node', $deleted_node
    ->id());
  $job
    ->addItem('content', 'node', $second_node
    ->id());
  $this
    ->drupalGet($job
    ->toUrl());
  $this
    ->submitForm([], 'Submit to provider');
  $this
    ->assertSession()
    ->pageTextContains('1 conflicting item has been dropped.');
  $this
    ->drupalGet('node/' . $deleted_node
    ->id() . '/translations');
  $this
    ->clickLinkWithImageTitle('Needs review');

  // Delete the node and assert that the job can not be accepted.
  $deleted_node
    ->delete();
  $this
    ->submitForm([], 'Save as completed');
  $this
    ->assertSession()
    ->pageTextContains(t('@id of type @type does not exist, the job can not be completed.', array(
    '@id' => $deleted_node
      ->id(),
    '@type' => $deleted_node
      ->getEntityTypeId(),
  )));
}