/** * Overrides DrupalWebTestCase::setUp() */ function setUp() { parent::setUp(); $this->default_translator = Translator::load('test_translator'); $this->drupalPlaceBlock('local_tasks_block'); $this->drupalPlaceBlock('local_actions_block'); $this->drupalPlaceBlock('page_title_block'); // Load default admin permissions. $this->admin_permissions = array('administer languages', 'access administration pages', 'administer content types', 'administer tmgmt'); // Load default translator user permissions. $this->translator_permissions = array('create translation jobs', 'submit translation jobs', 'accept translation jobs'); }
/** * Test the preview of TMGMT local. */ public function testPreview() { // Create translatable node. $this->createNodeType('article', 'Article', TRUE); $node = $this->createTranslatableNode('article', 'en'); $node->setPublished(FALSE); $node->save(); $translator = Translator::load('local'); $job = $this->createJob('en', 'de'); $job->translator = $translator; $job->save(); $job_item = tmgmt_job_item_create('content', $node->getEntityTypeId(), $node->id(), array('tjid' => $job->id())); $job_item->save(); // Create another local translator with the required abilities. $this->loginAsAdmin($this->localManagerPermissions); // Configure language abilities. $edit = array('tmgmt_translation_skills[0][language_from]' => 'en', 'tmgmt_translation_skills[0][language_to]' => 'de'); $this->drupalPostForm('user/' . $this->admin_user->id() . '/edit', $edit, t('Save')); $this->drupalGet('admin/tmgmt/jobs/' . $job->id()); $edit = ['settings[translator]' => $this->admin_user->id()]; $this->drupalPostForm(NULL, $edit, t('Submit to provider')); $this->drupalGet('translate'); $this->clickLink('View'); $this->clickLink('Translate'); // Check preview. $edit = array('title|0|value[translation]' => $translation1 = 'German translation of title', 'body|0|value[translation][value]' => $translation2 = 'German translation of body'); $this->drupalPostForm(NULL, $edit, t('Preview')); $this->assertResponse(200); $this->assertText($translation1); $this->assertText($translation2); $this->drupalGet('translate'); $this->clickLink('View'); $this->clickLink('Translate'); // Assert source link $this->assertLink($node->getTitle()); // Test that local translator can access an unpublished node. $this->clickLink($node->getTitle()); $this->assertText($node->getTitle()); }
/** * Tests of the task progress. */ public function testLocalProgress() { // Load the local translator. $translator = Translator::load('local'); // Create assignee with the skills. $assignee1 = $this->drupalCreateUser($this->localManagerPermissions); $this->drupalLogin($assignee1); $edit = array('tmgmt_translation_skills[0][language_from]' => 'en', 'tmgmt_translation_skills[0][language_to]' => 'de'); $this->drupalPostForm('user/' . $assignee1->id() . '/edit', $edit, t('Save')); // Login as translator. $this->loginAsTranslator(); // Create the basic html format. $basic_html_format = FilterFormat::create(array('format' => 'basic_html', 'name' => 'Basic HTML')); $basic_html_format->save(); // Create a Job. $job = $this->createJob(); $job->translator = $translator->id(); $item1 = $job->addItem('test_source', 'test', '1'); \Drupal::state()->set('tmgmt.test_source_data', array('title' => array('deep_nesting' => array('#text' => 'Example text', '#label' => 'Label for job item with type test and id 2.', '#translate' => TRUE)), 'text' => array('deep_nesting' => array('#text' => 'Example text', '#label' => 'Label for job item with type test and id 2.', '#translate' => TRUE)))); $job->addItem('test_source', 'test', '2'); $job->save(); $this->drupalGet($job->toUrl()); $this->drupalPostForm(NULL, NULL, t('Submit to provider')); // Login as assignee. $this->drupalLogin($assignee1); // Check the task unassigned icon. $this->drupalGet('/manage-translate'); $this->assertTaskStatusIcon(1, 'manage-translate-task', 'unassigned', 'Unassigned'); // Assign the task and check its icon. $edit = array('action' => 'tmgmt_local_task_assign_to_me', 'tmgmt_local_task_bulk_form[0]' => 1); $this->drupalPostForm(NULL, $edit, t('Apply')); $this->assertTaskStatusIcon(1, 'manage-translate-task', 'assigned', 'Needs action'); // Unassign it back. $edit = array('action' => 'tmgmt_local_task_unassign_multiple', 'tmgmt_local_task_bulk_form[0]' => 1); $this->drupalPostForm(NULL, $edit, t('Apply')); // Check its unassigned icon. $this->drupalGet('/manage-translate'); $this->assertTaskStatusIcon(1, 'manage-translate-task', 'unassigned', 'Unassigned'); $this->drupalGet('/translate'); // Check the unassigned status. $this->assertTaskStatusIcon(1, 'task-overview', 'unassigned', 'Unassigned'); $edit = array('tmgmt_local_task_bulk_form[0]' => 1); $this->drupalPostForm(NULL, $edit, t('Apply')); // Check the needs action status. $this->assertTaskStatusIcon(1, 'task-overview', 'my-tasks', 'Needs action'); // Check if the task is displayed on pending overview. $this->drupalGet('/translate/pending'); $this->assertTaskStatusIcon(1, 'task-overview', 'pending', 'Needs action'); $this->drupalGet('/manage-translate/pending'); $this->assertTaskStatusIcon(1, 'manage-translate-task', 'pending', 'Needs action'); // Check the icons of the task items. $this->drupalGet('/translate/1'); $this->assertTaskItemStatusIcon(1, 'Untranslated'); $this->assertTaskItemStatusIcon(2, 'Untranslated'); $this->assertTaskItemProgress(1, 1, 0, 0); $this->assertTaskItemProgress(2, 2, 0, 0); // Check the progress bar and status of the task. $this->drupalGet('/translate'); $this->assertTaskProgress(1, 'my-tasks', 3, 0, 0); $this->assertTaskStatusIcon(1, 'task-overview', 'my-tasks', 'Needs action'); $this->drupalGet('/manage-translate'); $this->assertTaskStatusIcon(1, 'manage-translate-task', 'assigned', 'Needs action'); // Set two items as translated. $this->drupalPostAjaxForm('/translate/items/1', [], 'finish-dummy|deep_nesting'); $this->drupalPostAjaxForm('/translate/items/2', [], 'finish-title|deep_nesting'); // Check the task items icons and progress. $this->drupalGet('/translate/1'); $this->assertTaskItemStatusIcon(1, 'Untranslated'); $this->assertTaskItemStatusIcon(2, 'Untranslated'); $this->assertTaskItemProgress(1, 0, 1, 0); $this->assertTaskItemProgress(2, 1, 1, 0); // Check the progress bar and status of the task. $this->drupalGet('/translate'); $this->assertTaskProgress(1, 'my-tasks', 1, 2, 0); $this->assertTaskStatusIcon(1, 'task-overview', 'my-tasks', 'Needs action'); $this->drupalGet('/manage-translate'); $this->assertTaskStatusIcon(1, 'manage-translate-task', 'assigned', 'Needs action'); // Save the first item as completed and check item icons and progress. $edit = ['dummy|deep_nesting[translation]' => 'German translation']; $this->drupalPostForm('/translate/items/1', $edit, t('Save as completed')); $this->assertTaskItemStatusIcon(1, 'Translated'); $this->assertTaskItemStatusIcon(2, 'Untranslated'); $this->assertTaskItemProgress(1, 0, 0, 1); $this->assertTaskItemProgress(2, 1, 1, 0); // Check the progress bar and status of the task. $this->drupalGet('/translate'); $this->assertTaskProgress(1, 'my-tasks', 1, 1, 1); $this->assertTaskStatusIcon(1, 'task-overview', 'my-tasks', 'Needs action'); $this->drupalGet('/manage-translate'); $this->assertTaskStatusIcon(1, 'manage-translate-task', 'assigned', 'Needs action'); // Save the second item as completed. $edit = ['title|deep_nesting[translation]' => 'German translation of title', 'text|deep_nesting[translation]' => 'German translation of text']; $this->drupalPostForm('/translate/items/2', $edit, t('Save as completed')); // Check the icon a progress bar of the task. $this->assertTaskProgress(1, 'my-tasks', 0, 0, 3); $this->assertTaskStatusIcon(1, 'task-overview', 'my-tasks', 'In review'); // Check the task items icons. $this->drupalGet('/translate/1'); $this->assertTaskItemStatusIcon(1, 'Translated'); $this->assertTaskItemStatusIcon(2, 'Translated'); $this->assertTaskItemProgress(1, 0, 0, 1); $this->assertTaskItemProgress(2, 0, 0, 2); // Check if the task is displayed on the completed overview. $this->drupalGet('/translate/completed'); $this->assertTaskStatusIcon(1, 'task-overview', 'completed', 'In review'); $this->drupalGet('/manage-translate/completed'); $this->assertTaskStatusIcon(1, 'manage-translate-task', 'completed', 'In review'); // Accept translation of the job items. /** @var \Drupal\tmgmt\Entity\Job $job1 */ $job1 = Job::load($job->id()); /** @var \Drupal\tmgmt\Entity\JobItem $item */ foreach ($job1->getItems() as $item) { $item->acceptTranslation(); } // Check if the task is displayed on the closed overview. $this->drupalGet('/translate/closed'); $this->assertTaskStatusIcon(1, 'task-overview', 'closed', 'Closed'); $this->drupalGet('/manage-translate/closed'); $this->assertTaskStatusIcon(1, 'manage-translate-task', 'closed', 'Closed'); // Assert the legend. $this->drupalGet('/translate/items/' . $item1->id()); $this->assertRaw('class="tmgmt-color-legend'); }
/** * Test translating comments. */ function testCommentTranslateTab() { // Allow auto-accept. $default_translator = Translator::load('test_translator'); $default_translator->setAutoAccept(TRUE)->save(); // Add default comment type. $this->addDefaultCommentField('node', 'article'); // Enable comment translation. /** @var \Drupal\content_translation\ContentTranslationManagerInterface $content_translation_manager */ $content_translation_manager = \Drupal::service('content_translation.manager'); $content_translation_manager->setEnabled('comment', 'comment', TRUE); drupal_static_reset(); \Drupal::entityManager()->clearCachedDefinitions(); \Drupal::service('router.builder')->rebuild(); \Drupal::service('entity.definition_update_manager')->applyUpdates(); $this->applySchemaUpdates(); // Change comment_body field to be translatable. $comment_body = FieldConfig::loadByName('comment', 'comment', 'comment_body'); $comment_body->setTranslatable(TRUE)->save(); // Create a user that is allowed to translate comments. $permissions = array_merge($this->translator_permissions, array('translate comment', 'post comments', 'skip comment approval', 'edit own comments', 'access comments')); $this->loginAsTranslator($permissions, TRUE); // Create an english source article. $node = $this->createTranslatableNode('article', 'en'); // Add a comment. $this->drupalGet('node/' . $node->id()); $edit = array('subject[0][value]' => $this->randomMachineName(), 'comment_body[0][value]' => $this->randomMachineName()); $this->drupalPostForm(NULL, $edit, t('Save')); $this->assertText(t('Your comment has been posted.')); // Go to the translate tab. $this->clickLink('Edit'); $this->assertTrue(preg_match('|comment/(\\d+)/edit$|', $this->getUrl(), $matches), 'Comment found'); $comment = Comment::load($matches[1]); $this->clickLink('Translate'); // Assert some basic strings on that page. $this->assertText(t('Translations of @title', array('@title' => $comment->getSubject()))); $this->assertText(t('Pending Translations')); // Request translations. $edit = array('languages[de]' => TRUE, 'languages[es]' => TRUE); $this->drupalPostForm(NULL, $edit, t('Request translation')); // Verify that we are on the translate tab. $this->assertText(t('2 jobs need to be checked out.')); // Submit all jobs. $this->assertText($comment->getSubject()); $this->drupalPostForm(NULL, array(), t('Submit to provider and continue')); $this->assertText($comment->getSubject()); $this->drupalPostForm(NULL, array(), t('Submit to provider')); // Make sure that we're back on the translate tab. $this->assertUrl($comment->url('canonical', array('absolute' => TRUE)) . '/translations'); $this->assertText(t('Test translation created.')); $this->assertNoText(t('The translation of @title to @language is finished and can now be reviewed.', array('@title' => $comment->getSubject(), '@language' => t('Spanish')))); $this->assertText(t('The translation for @title has been accepted as es: @target.', array('@title' => $comment->getSubject(), '@target' => $comment->getSubject()))); // The translated content should be in place. $this->clickLink('de(de-ch): ' . $comment->getSubject()); $this->assertText('de(de-ch): ' . $comment->get('comment_body')->value); $this->drupalGet('comment/1/translations'); $this->clickLink('es: ' . $comment->getSubject()); $this->drupalGet('es/node/' . $comment->id()); $this->assertText('es: ' . $comment->get('comment_body')->value); }
/** * Test abortion of continuous translators. */ public function testContinuousTranslatorsAbortion() { \Drupal::service('router.builder')->rebuild(); // Create a continuous translator. $translator = Translator::load('test_translator'); $this->assertTrue($translator->getPlugin() instanceof ContinuousTranslatorInterface); // Create a node type. $type = NodeType::create(['type' => $this->randomMachineName()]); $type->save(); // Enable the node type for translation. $content_translation_manager = \Drupal::service('content_translation.manager'); $content_translation_manager->setEnabled('node', $type->id(), TRUE); // Create a continuous job. $continuous_job = tmgmt_job_create('en', 'de', 0, ['job_type' => Job::TYPE_CONTINUOUS, 'continuous_settings' => ['content' => ['node' => ['enabled' => TRUE, 'bundles' => [$type->id() => TRUE]]]]]); $continuous_job->translator = $translator; $continuous_job->save(); // Abort a continuous job. $continuous_job->aborted(); // Create a node. $node = Node::create(array('title' => $this->randomMachineName(), 'type' => $type->id(), 'language' => 'en', 'body' => $this->randomMachineName())); $node->save(); // Assert that node has not been captured. $updated_continuous_job = Job::load($continuous_job->id()); $this->assertEqual($updated_continuous_job->getItems(), []); $this->assertEqual($updated_continuous_job->getState(), Job::STATE_ABORTED); }
/** * Tests the tmgmt_job_checkout() function. */ function testCheckoutFunction() { $job = $this->createJob(); // Check out a job when only the test translator is available. That one has // settings, so a checkout is necessary. $redirects = tmgmt_job_checkout_multiple(array($job)); $this->assertEqual($job->urlInfo()->getInternalPath(), $redirects[0]); $this->assertTrue($job->isUnprocessed()); $job->delete(); // Hide settings on the test translator. $default_translator = Translator::load('test_translator'); $default_translator->setSetting('expose_settings', FALSE)->save(); $job = $this->createJob(); $redirects = tmgmt_job_checkout_multiple(array($job)); $this->assertFalse($redirects); $this->assertTrue($job->isActive()); // A job without target language needs to be checked out. $job = $this->createJob('en', ''); $redirects = tmgmt_job_checkout_multiple(array($job)); $this->assertEqual($job->urlInfo()->getInternalPath(), $redirects[0]); $this->assertTrue($job->isUnprocessed()); // Create a second file translator. This should check // out immediately. $job = $this->createJob(); $second_translator = $this->createTranslator(); $second_translator->setSetting('expose_settings', FALSE)->save(); $redirects = tmgmt_job_checkout_multiple(array($job)); $this->assertEqual($job->urlInfo()->getInternalPath(), $redirects[0]); $this->assertTrue($job->isUnprocessed()); }
/** * Tests import and export for the XLIFF format. */ function testXLIFF() { $translator = Translator::load('file'); $translator->setSetting('export_format', 'xlf')->save(); // Set multiple data items for the source. \Drupal::state()->set('tmgmt.test_source_data', array('dummy' => array('deep_nesting' => array('#text' => 'Text of deep nested item @id.', '#label' => 'Label of deep nested item @id')), 'another_item' => array('#text' => 'Text of another item @id.', '#label' => 'Label of another item @id.'))); $job = $this->createJob(); $job->translator = $translator->id(); $first_item = $job->addItem('test_source', 'test', '1'); // Keep the first item data for later use. $first_item_data = \Drupal::service('tmgmt.data')->flatten($first_item->getData()); $job->addItem('test_source', 'test', '2'); $job->requestTranslation(); $messages = $job->getMessages(); $message = reset($messages); $variables = $message->variables; $download_url = $variables->{'@link'}; $this->assertFalse((bool) strpos('< a', $download_url)); $xliff = file_get_contents($download_url); $dom = new \DOMDocument(); $dom->loadXML($xliff); $this->assertTrue($dom->schemaValidate(drupal_get_path('module', 'tmgmt_file') . '/xliff-core-1.2-strict.xsd')); // "Translate" items. $xml = simplexml_import_dom($dom); $translated_text = array(); foreach ($xml->file->body->children() as $group) { foreach ($group->children() as $transunit) { if ($transunit->getName() == 'trans-unit') { // The target should be empty. $this->assertEqual($transunit->target, ''); $transunit->target = $xml->file['target-language'] . '_' . (string) $transunit->source; // Store the text to allow assertions later on. $translated_text[(string) $group['id']][(string) $transunit['id']] = (string) $transunit->target; } } } // Change the job id to a non-existing one and try to import it. $wrong_xml = clone $xml; $wrong_xml->file->header->{'phase-group'}->phase['job-id'] = 500; $wrong_file = 'public://tmgmt_file/wrong_file.xlf'; $wrong_xml->asXML($wrong_file); $edit = array('files[file]' => $wrong_file); $this->drupalPostForm($job->urlInfo(), $edit, t('Import')); $this->assertText(t('Failed to validate file, import aborted.')); // Change the job id to a wrong one and try to import it. $wrong_xml = clone $xml; $second_job = $this->createJob(); $second_job->translator = $translator->id(); // We need to add the elements count value into settings, otherwise the // validation will fail on integrity check. $xliff_validation = array(1 => 0, 2 => 0); $second_job->settings->xliff_validation = $xliff_validation; $second_job->save(); $wrong_xml->file->header->{'phase-group'}->phase['job-id'] = $second_job->id(); $wrong_file = 'public://tmgmt_file/wrong_file.xlf'; $wrong_xml->asXML($wrong_file); $edit = array('files[file]' => $wrong_file); $this->drupalPostForm($job->urlInfo(), $edit, t('Import')); $this->assertRaw(t('The imported file job id @file_id does not match the job id @job_id.', array('@file_id' => $second_job->id(), '@job_id' => $job->id()))); $translated_file = 'public://tmgmt_file/translated file.xlf'; $xml->asXML($translated_file); // Import the file and accept translation for the "dummy" item. $edit = array('files[file]' => $translated_file); $this->drupalPostForm($job->urlInfo(), $edit, t('Import')); $this->assertText(t('The translation of @job_item to German is finished and can now be reviewed.', ['@job_item' => $first_item->label()])); $this->clickLink(t('Review')); $this->drupalPostAjaxForm(NULL, NULL, array('reviewed-dummy|deep_nesting' => '✓')); // Update the translation for "another" item and import. $xml->file->body->group[0]->{'trans-unit'}[1]->target = $xml->file->body->group[0]->{'trans-unit'}[1]->target . ' updated'; $xml->asXML($translated_file); $edit = array('files[file]' => $translated_file); $this->drupalPostForm($job->urlInfo(), $edit, t('Import')); // At this point we must have the "dummy" item accepted and intact. The // "another" item must have updated translation. $this->clickLink(t('Review')); $this->assertFieldByName('dummy|deep_nesting[translation]', 'de_' . $first_item_data['dummy][deep_nesting']['#text']); $this->assertFieldByName('another_item[translation]', 'de_' . $first_item_data['another_item']['#text'] . ' updated'); // Now finish the import/save as completed process doing another extra // import. The extra import will test that a duplicate import of the same // file does not break the process. $this->importFile($translated_file, $translated_text, $job); $this->assertNoText(t('Import translated file')); // Create a job, assign to the file translator and delete before attaching // a file. $other_job = $this->createJob(); $other_job->translator = $translator->id(); $other_job->save(); $other_job->delete(); // Make sure the file of the other job still exists. $response = \Drupal::httpClient()->get($download_url); $this->assertEqual(200, $response->getStatusCode()); // Delete the job and then make sure that the file has been deleted. $job->delete(); try { $response = \Drupal::httpClient()->get($download_url); $this->fail('Expected exception not thrown.'); } catch (RequestException $e) { $this->assertEqual(404, $e->getResponse()->getStatusCode()); } }