Test the translate tab for a single checkout.
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(),
)));
}