View source
<?php
namespace Drupal\Tests\lingotek\Functional;
use Drupal\Core\Url;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\lingotek\Lingotek;
class LingotekInterfaceTranslationTest extends LingotekTestBase {
use LingotekInterfaceTranslationTestTrait;
public static $modules = [
'block',
'node',
'potx',
'lingotek_interface_translation_test',
];
protected function setUp() : void {
parent::setUp();
$this
->drupalPlaceBlock('page_title_block', [
'region' => 'content',
'weight' => -5,
]);
$this
->drupalPlaceBlock('local_tasks_block', [
'region' => 'content',
'weight' => -10,
]);
\Drupal::state()
->set('lingotek.uploaded_content_type', 'interface-translation');
ConfigurableLanguage::createFromLangcode('es')
->setThirdPartySetting('lingotek', 'locale', 'es_MX')
->save();
}
public function testInterfaceTranslationWithoutPotx() {
$assert_session = $this
->assertSession();
$this
->drupalLogin($this->rootUser);
$this
->drupalGet('/admin/modules');
$this
->assertSession()
->checkboxChecked('edit-modules-potx-enable');
$this
->clickLink('Uninstall');
$edit = [
'uninstall[potx]' => '1',
];
$this
->drupalPostForm(NULL, $edit, 'Uninstall');
$assert_session
->responseContains('The following modules will be completely uninstalled from your site, and <em>all data from these modules will be lost</em>!');
$assert_session
->responseContains('Translation template extractor');
$this
->drupalPostForm(NULL, [], 'Uninstall');
$this
->goToInterfaceTranslationManagementForm();
$assert_session
->responseContains('The <a href="https://www.drupal.org/project/potx">potx</a> module is required for interface translation with Lingotek');
}
public function testInterfaceTranslationUsingLinks() {
$path = drupal_get_path('module', 'lingotek_interface_translation_test');
$component = $path;
$indexOfModuleLink = 1;
$assert_session = $this
->assertSession();
$this
->drupalLogin($this->rootUser);
$this
->goToInterfaceTranslationManagementForm();
$assert_session
->responseContains('lingotek');
$assert_session
->responseContains('lingotek_test');
$assert_session
->responseContains('lingotek_interface_translation_test');
$assert_session
->responseContains('stark');
$this
->assertLingotekInterfaceTranslationUploadLink('core/profiles/testing');
$this
->assertLingotekInterfaceTranslationUploadLink('core/themes/stark');
$this
->assertLingotekInterfaceTranslationUploadLink($component);
$this
->assertNoLingotekInterfaceTranslationRequestTranslationLink($component, 'es_MX');
$this
->clickLink('EN', $indexOfModuleLink);
$assert_session
->responseContains('<em class="placeholder">' . $component . '</em> uploaded successfully');
$data = json_decode(\Drupal::state()
->get('lingotek.uploaded_content', '[]'), TRUE);
$singularStrings = [
'Test title for interface translation',
];
$pluralStrings = [
"This is a singular example<PLURAL>This is a plural @count example<CONTEXT>" => [
"This is a singular example" => "This is a singular example",
"This is a plural @count example" => "This is a plural @count example",
"_context" => '',
],
];
$contextStrings = [
"This is test of context<CONTEXT>" => [
"This is test of context" => "This is test of context",
"_context" => '',
],
"This is test of context<CONTEXT>multiple p" => [
"This is test of context" => "This is test of context",
"_context" => 'multiple p',
],
"This is test of context<CONTEXT>multiple t" => [
"This is test of context" => "This is test of context",
"_context" => 'multiple t',
],
];
foreach ($singularStrings as $singularString) {
$singularStringWithContext = $singularString . '<CONTEXT>';
$this
->assertTrue(isset($data[$singularStringWithContext]));
$this
->assertSame($singularString, $data[$singularStringWithContext][$singularString]);
$this
->assertSame('', $data[$singularStringWithContext]['_context']);
}
foreach ($pluralStrings as $key => $pluralData) {
$this
->assertTrue(isset($data[$key]));
$this
->assertSame('', $data[$key]['_context']);
foreach ($pluralData as $pluralString => $pluralTranslatedString) {
if ($pluralString !== '_context') {
$this
->assertTrue(isset($data[$key][$pluralString]));
$this
->assertSame($pluralTranslatedString, $data[$key][$pluralString]);
}
}
}
foreach ($contextStrings as $key => $contextData) {
$this
->assertTrue(isset($data[$key]));
foreach ($contextData as $contextString => $contextTranslatedString) {
$this
->assertSame($contextData['_context'], $data[$key]['_context']);
if ($contextString !== '_context') {
$this
->assertTrue(isset($data[$key][$contextString]));
$this
->assertSame($contextTranslatedString, $data[$key][$contextString]);
}
}
}
$this
->assertSame('en_US', \Drupal::state()
->get('lingotek.uploaded_locale'));
$this
->assertLingotekInterfaceTranslationCheckSourceStatusLink($component);
$this
->assertLingotekInterfaceTranslationRequestTranslationLink($component, 'es_MX');
$this
->clickLink('EN', $indexOfModuleLink);
$assert_session
->responseContains('The import for <em class="placeholder">' . $component . '</em> is complete.');
$this
->assertLingotekInterfaceTranslationRequestTranslationLink($component, 'es_MX');
$this
->clickLink('ES');
$assert_session
->responseContains('Locale \'es_MX\' was added as a translation target for <em class="placeholder">' . $component . '</em>.');
$this
->assertIdentical('es_MX', \Drupal::state()
->get('lingotek.added_target_locale'));
$this
->assertLingotekInterfaceTranslationCheckTargetStatusLink($component, 'es_MX');
$this
->clickLink('ES');
$this
->assertSame('es_MX', \Drupal::state()
->get('lingotek.checked_target_locale'));
$assert_session
->responseContains('The es_MX translation for <em class="placeholder">' . $component . '</em> is ready for download.');
$this
->assertLingotekInterfaceTranslationDownloadLink($component, 'es_MX');
$this
->clickLink('ES');
$assert_session
->responseContains('The translation of <em class="placeholder">' . $component . '</em> into es_MX has been downloaded.');
$this
->assertSame('es_MX', \Drupal::state()
->get('lingotek.downloaded_locale'));
$this
->assertLingotekWorkbenchLink('es_MX');
$this
->drupalGet('es/lingotek-interface-translation-test');
$assert_session
->responseContains('Título de Prueba para Traducción de Interfaz');
$assert_session
->responseContains('Este es un ejemplo en singular');
$assert_session
->responseNotContains('This is test of context');
$assert_session
->responseContains('Esto es una prueba de contexto');
$assert_session
->responseContains('Esto es una pppprueba de contexto');
$assert_session
->responseContains('Estttto es una prueba de conttttextttto');
$this
->drupalGet('es/lingotek-interface-translation-test', [
'query' => [
'count' => 10,
],
]);
$assert_session
->responseContains('Título de Prueba para Traducción de Interfaz');
$assert_session
->responseContains('Este es un ejemplo en plural: 10');
$assert_session
->responseNotContains('This is test of context');
$assert_session
->responseContains('Esto es una prueba de contexto');
$assert_session
->responseContains('Esto es una pppprueba de contexto');
$assert_session
->responseContains('Estttto es una prueba de conttttextttto');
}
public function testClearInterfaceTranslationMetadata() {
$path1 = drupal_get_path('module', 'lingotek_interface_translation_test');
$path2 = drupal_get_path('module', 'lingotek_test');
$component1 = $path1;
$component2 = $path2;
$indexOfModuleLink1 = 1;
$indexOfModuleLink2 = 2;
$assert_session = $this
->assertSession();
$this
->drupalLogin($this->rootUser);
$this
->goToInterfaceTranslationManagementForm();
$assert_session
->responseContains('lingotek_test');
$assert_session
->responseContains('lingotek_interface_translation_test');
$this
->assertLingotekInterfaceTranslationUploadLink($component1);
$this
->assertLingotekInterfaceTranslationUploadLink($component2);
$this
->assertNoLingotekInterfaceTranslationRequestTranslationLink($component1, 'es_MX');
$this
->assertNoLingotekInterfaceTranslationRequestTranslationLink($component2, 'es_MX');
$this
->clickLink('EN', $indexOfModuleLink1);
$assert_session
->responseContains('<em class="placeholder">' . $component1 . '</em> uploaded successfully');
$this
->clickLink('EN', $indexOfModuleLink2);
$assert_session
->responseContains('<em class="placeholder">' . $component2 . '</em> uploaded successfully');
$this
->assertLingotekInterfaceTranslationCheckSourceStatusLink($component1);
$this
->assertLingotekInterfaceTranslationCheckSourceStatusLink($component2);
$this
->assertLingotekInterfaceTranslationRequestTranslationLink($component1, 'es_MX');
$this
->assertLingotekInterfaceTranslationRequestTranslationLink($component2, 'es_MX');
$this
->clickLink('EN', $indexOfModuleLink1);
$assert_session
->responseContains('The import for <em class="placeholder">' . $component1 . '</em> is complete.');
$this
->assertLingotekInterfaceTranslationRequestTranslationLink($component1, 'es_MX');
$this
->assertLingotekInterfaceTranslationRequestTranslationLink($component2, 'es_MX');
$this
->clickLink('ES');
$assert_session
->responseContains('Locale \'es_MX\' was added as a translation target for <em class="placeholder">' . $component1 . '</em>.');
$this
->drupalPostForm(NULL, [], 'Clear Lingotek interface translation metadata');
$assert_session
->responseContains('This will remove the metadata stored about your Lingotek interface translations, so you will need to re-upload those in case you want to translate them.');
$this
->drupalPostForm(NULL, [], 'Clear metadata');
$assert_session
->responseContains('You have cleared the Lingotek metadata for interface translations.');
$this
->assertLingotekInterfaceTranslationUploadLink($component1);
$this
->assertLingotekInterfaceTranslationUploadLink($component2);
$this
->assertNoLingotekInterfaceTranslationRequestTranslationLink($component1, 'es_MX');
$this
->assertNoLingotekInterfaceTranslationRequestTranslationLink($component2, 'es_MX');
}
public function testAddingLanguageAllowsRequesting() {
$assert_session = $this
->assertSession();
$this
->testInterfaceTranslationUsingLinks();
ConfigurableLanguage::createFromLangcode('ca')
->save();
$this
->goToInterfaceTranslationManagementForm();
$path = drupal_get_path('module', 'lingotek_interface_translation_test');
$component = $path;
$this
->assertLingotekInterfaceTranslationRequestTranslationLink($component, 'ca_ES');
$this
->clickLink('CA');
$assert_session
->responseContains('Locale \'ca_ES\' was added as a translation target for <em class="placeholder">' . $component . '</em>.');
}
public function testFormWorksAfterRemovingLanguageWithStatuses() {
$assert_session = $this
->assertSession();
$this
->testAddingLanguageAllowsRequesting();
ConfigurableLanguage::load('es')
->delete();
$this
->goToInterfaceTranslationManagementForm();
$assert_session
->linkNotExists('ES');
$assert_session
->linkExists('CA');
}
public function testUploadingWithAnError() {
\Drupal::state()
->set('lingotek.must_error_in_upload', TRUE);
$path = drupal_get_path('module', 'lingotek_interface_translation_test');
$component = $path;
$indexOfModuleLink = 1;
$assert_session = $this
->assertSession();
$this
->drupalLogin($this->rootUser);
$this
->goToInterfaceTranslationManagementForm();
$assert_session
->responseContains('lingotek_interface_translation_test');
$this
->assertLingotekInterfaceTranslationUploadLink($component);
$this
->clickLink('EN', $indexOfModuleLink);
$assert_session
->responseContains('The upload for <em class="placeholder">' . $component . '</em> failed. Please try again.');
$this
->assertSourceStatus('EN', Lingotek::STATUS_ERROR);
$translation_service = \Drupal::service('lingotek.interface_translation');
$source_status = $translation_service
->getSourceStatus($component);
$this
->assertEqual(Lingotek::STATUS_ERROR, $source_status, 'The source upload has been marked as error.');
\Drupal::state()
->set('lingotek.must_error_in_upload', FALSE);
$this
->clickLink('EN', $indexOfModuleLink);
$assert_session
->responseContains('<em class="placeholder">' . $component . '</em> uploaded successfully');
}
public function testUploadingWithAPaymentRequiredError() {
\Drupal::state()
->set('lingotek.must_payment_required_error_in_upload', TRUE);
$path = drupal_get_path('module', 'lingotek_interface_translation_test');
$component = $path;
$indexOfModuleLink = 1;
$assert_session = $this
->assertSession();
$this
->drupalLogin($this->rootUser);
$this
->goToInterfaceTranslationManagementForm();
$assert_session
->responseContains('lingotek_interface_translation_test');
$this
->assertLingotekInterfaceTranslationUploadLink($component);
$this
->clickLink('EN', $indexOfModuleLink);
$assert_session
->responseContains('Community has been disabled. Please contact support@lingotek.com to re-enable your community.');
$this
->assertSourceStatus('EN', Lingotek::STATUS_ERROR);
$this
->assertSourceStatus('EN', Lingotek::STATUS_ERROR);
$translation_service = \Drupal::service('lingotek.interface_translation');
$source_status = $translation_service
->getSourceStatus($component);
$this
->assertEqual(Lingotek::STATUS_ERROR, $source_status, 'The source upload has been marked as error.');
\Drupal::state()
->set('lingotek.must_payment_required_error_in_upload', FALSE);
$this
->clickLink('EN', $indexOfModuleLink);
$assert_session
->responseContains('<em class="placeholder">' . $component . '</em> uploaded successfully');
}
public function testRequestTranslationWithAnError() {
\Drupal::state()
->set('lingotek.must_error_in_request_translation', TRUE);
$path = drupal_get_path('module', 'lingotek_interface_translation_test');
$component = $path;
$indexOfModuleLink = 1;
$assert_session = $this
->assertSession();
$this
->drupalLogin($this->rootUser);
$this
->goToInterfaceTranslationManagementForm();
$assert_session
->responseContains('lingotek_interface_translation_test');
$this
->assertLingotekInterfaceTranslationUploadLink($component);
$this
->clickLink('EN', $indexOfModuleLink);
$assert_session
->responseContains('<em class="placeholder">' . $component . '</em> uploaded successfully');
$this
->assertLingotekInterfaceTranslationCheckSourceStatusLink($component);
$this
->clickLink('EN', $indexOfModuleLink);
$assert_session
->responseContains('The import for <em class="placeholder">' . $component . '</em> is complete.');
$this
->assertLingotekInterfaceTranslationRequestTranslationLink($component, 'es_MX');
$this
->clickLink('ES');
$this
->assertTargetStatus('ES', Lingotek::STATUS_REQUEST);
$assert_session
->responseContains('Requesting \'es_MX\' translation for <em class="placeholder">' . $component . '</em> failed. Please try again.');
}
public function testRequestTranslationWithAPaymentRequiredError() {
\Drupal::state()
->set('lingotek.must_payment_required_error_in_request_translation', TRUE);
$path = drupal_get_path('module', 'lingotek_interface_translation_test');
$component = $path;
$indexOfModuleLink = 1;
$assert_session = $this
->assertSession();
$this
->drupalLogin($this->rootUser);
$this
->goToInterfaceTranslationManagementForm();
$assert_session
->responseContains('lingotek_interface_translation_test');
$this
->assertLingotekInterfaceTranslationUploadLink($component);
$this
->clickLink('EN', $indexOfModuleLink);
$assert_session
->responseContains('<em class="placeholder">' . $component . '</em> uploaded successfully');
$this
->assertLingotekInterfaceTranslationCheckSourceStatusLink($component);
$this
->clickLink('EN', $indexOfModuleLink);
$assert_session
->responseContains('The import for <em class="placeholder">' . $component . '</em> is complete.');
$this
->assertLingotekInterfaceTranslationRequestTranslationLink($component, 'es_MX');
$this
->clickLink('ES');
$this
->assertTargetStatus('ES', Lingotek::STATUS_REQUEST);
$assert_session
->responseContains('Community has been disabled. Please contact support@lingotek.com to re-enable your community.');
}
public function testRequestTranslationWithADocumentArchivedError() {
\Drupal::state()
->set('lingotek.must_document_archived_error_in_request_translation', TRUE);
$path = drupal_get_path('module', 'lingotek_interface_translation_test');
$component = $path;
$indexOfModuleLink = 1;
$assert_session = $this
->assertSession();
$this
->drupalLogin($this->rootUser);
$this
->goToInterfaceTranslationManagementForm();
$assert_session
->responseContains('lingotek_interface_translation_test');
$this
->assertLingotekInterfaceTranslationUploadLink($component);
$this
->clickLink('EN', $indexOfModuleLink);
$assert_session
->responseContains('<em class="placeholder">' . $component . '</em> uploaded successfully');
$this
->assertLingotekInterfaceTranslationCheckSourceStatusLink($component);
$this
->clickLink('EN', $indexOfModuleLink);
$assert_session
->responseContains('The import for <em class="placeholder">' . $component . '</em> is complete.');
$this
->assertLingotekInterfaceTranslationRequestTranslationLink($component, 'es_MX');
$this
->clickLink('ES');
$this
->assertLingotekInterfaceTranslationUploadLink($component);
$this
->assertNoLingotekInterfaceTranslationRequestTranslationLink($component, 'es_MX');
$assert_session
->responseContains('Document <em class="placeholder">' . $component . '</em> has been archived. Please upload again.');
}
public function testRequestTranslationWithADocumentLockedError() {
\Drupal::state()
->set('lingotek.must_document_locked_error_in_request_translation', TRUE);
$path = drupal_get_path('module', 'lingotek_interface_translation_test');
$component = $path;
$indexOfModuleLink = 1;
$assert_session = $this
->assertSession();
$this
->drupalLogin($this->rootUser);
$this
->goToInterfaceTranslationManagementForm();
$assert_session
->responseContains('lingotek_interface_translation_test');
$this
->assertLingotekInterfaceTranslationUploadLink($component);
$this
->clickLink('EN', $indexOfModuleLink);
$assert_session
->responseContains('<em class="placeholder">' . $component . '</em> uploaded successfully');
$this
->assertLingotekInterfaceTranslationRequestTranslationLink($component, 'es_MX');
$this
->clickLink('ES');
$this
->assertSourceStatus('EN', Lingotek::STATUS_IMPORTING);
$this
->assertTargetStatus('ES', Lingotek::STATUS_REQUEST);
$assert_session
->responseContains('Document <em class="placeholder">' . $component . '</em> has a new version. The document id has been updated for all future interactions. Please try again.');
}
public function testCheckTranslationStatusWithAnError() {
\Drupal::state()
->set('lingotek.must_error_in_check_target_status', TRUE);
$path = drupal_get_path('module', 'lingotek_interface_translation_test');
$component = $path;
$indexOfModuleLink = 1;
$assert_session = $this
->assertSession();
$this
->drupalLogin($this->rootUser);
$this
->goToInterfaceTranslationManagementForm();
$assert_session
->responseContains('lingotek_interface_translation_test');
$this
->assertLingotekInterfaceTranslationUploadLink($component);
$this
->clickLink('EN', $indexOfModuleLink);
$assert_session
->responseContains('<em class="placeholder">' . $component . '</em> uploaded successfully');
$this
->assertLingotekInterfaceTranslationRequestTranslationLink($component, 'es_MX');
$this
->clickLink('ES');
$this
->assertTargetStatus('ES', Lingotek::STATUS_PENDING);
$this
->clickLink('ES');
$this
->assertTargetStatus('ES', Lingotek::STATUS_PENDING);
$assert_session
->responseContains('The request for <em class="placeholder">' . $component . '</em> \'es_MX\' translation status failed. Please try again.');
}
public function testDownloadTranslationWithAnError() {
\Drupal::state()
->set('lingotek.must_error_in_download', TRUE);
$path = drupal_get_path('module', 'lingotek_interface_translation_test');
$component = $path;
$indexOfModuleLink = 1;
$assert_session = $this
->assertSession();
$this
->drupalLogin($this->rootUser);
$this
->goToInterfaceTranslationManagementForm();
$assert_session
->responseContains('lingotek_interface_translation_test');
$this
->assertLingotekInterfaceTranslationUploadLink($component);
$this
->clickLink('EN', $indexOfModuleLink);
$assert_session
->responseContains('<em class="placeholder">' . $component . '</em> uploaded successfully');
$this
->assertLingotekInterfaceTranslationRequestTranslationLink($component, 'es_MX');
$this
->clickLink('ES');
$this
->assertTargetStatus('ES', Lingotek::STATUS_PENDING);
$this
->clickLink('ES');
$this
->assertTargetStatus('ES', Lingotek::STATUS_READY);
$this
->clickLink('ES');
$this
->assertTargetStatus('ES', Lingotek::STATUS_ERROR);
$assert_session
->responseContains('The \'es_MX\' translation download for <em class="placeholder">' . $component . '</em> failed. Please try again.');
}
public function testAutomatedNotificationInterfaceTranslation() {
$this
->drupalLogin($this->rootUser);
$path = drupal_get_path('module', 'lingotek_interface_translation_test');
$component = $path;
$indexOfModuleLink = 1;
$assert_session = $this
->assertSession();
$this
->drupalLogin($this->rootUser);
$this
->goToInterfaceTranslationManagementForm();
$assert_session
->responseContains('lingotek_interface_translation_test');
$this
->assertLingotekInterfaceTranslationUploadLink($component);
$this
->clickLink('EN', $indexOfModuleLink);
$translation_service = \Drupal::service('lingotek.interface_translation');
$this
->assertIdentical(Lingotek::STATUS_IMPORTING, $translation_service
->getSourceStatus($component));
$this
->goToInterfaceTranslationManagementForm();
$url = Url::fromRoute('lingotek.notify', [], [
'query' => [
'project_id' => 'test_project',
'document_id' => 'dummy-document-hash-id',
'complete' => 'false',
'type' => 'document_uploaded',
'progress' => '0',
],
])
->setAbsolute()
->toString();
$request = $this->client
->post($url, [
'cookies' => $this->cookies,
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/json',
],
'http_errors' => FALSE,
]);
$response = json_decode($request
->getBody(), TRUE);
$this
->verbose($request);
$this
->assertIdentical([], $response['result']['request_translations'], 'No translations have been requested after notification automatically.');
$this
->goToInterfaceTranslationManagementForm();
$this
->assertIdentical(Lingotek::STATUS_CURRENT, $translation_service
->getSourceStatus($component));
$this
->assertIdentical(Lingotek::STATUS_REQUEST, $translation_service
->getTargetStatus($component, 'es'));
$this
->clickLink('ES');
$this
->goToInterfaceTranslationManagementForm();
$this
->assertIdentical(Lingotek::STATUS_PENDING, $translation_service
->getTargetStatus($component, 'es'));
$url = Url::fromRoute('lingotek.notify', [], [
'query' => [
'project_id' => 'test_project',
'document_id' => 'dummy-document-hash-id',
'locale_code' => 'es-ES',
'locale' => 'es_ES',
'complete' => 'true',
'type' => 'target',
'progress' => '100',
],
])
->setAbsolute()
->toString();
$request = $this->client
->post($url, [
'cookies' => $this->cookies,
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/json',
],
'http_errors' => FALSE,
]);
$response = json_decode($request
->getBody(), TRUE);
$this
->verbose($request);
$this
->assertFalse($response['result']['download'], 'No targets have been downloaded after notification automatically.');
$this
->goToInterfaceTranslationManagementForm();
$this
->assertIdentical(Lingotek::STATUS_READY, $translation_service
->getTargetStatus($component, 'es'));
$this
->clickLink('ES');
$this
->goToInterfaceTranslationManagementForm();
$this
->assertIdentical(Lingotek::STATUS_CURRENT, $translation_service
->getTargetStatus($component, 'es'));
}
}