/** * Tests the UI of the plugin. */ protected function testMicrosoftUi() { $this->loginAsAdmin(); $edit = ['settings[client_id]' => 'wrong client_id', 'settings[client_secret]' => 'wrong client_secret']; $this->drupalPostForm('admin/config/regional/tmgmt_translator/manage/' . $this->translator->id(), $edit, t('Save')); $this->assertText(t('The "Client ID", the "Client secret" or both are not correct.')); $edit = ['settings[client_id]' => 'correct client_id', 'settings[client_secret]' => 'correct client_secret']; $this->drupalPostForm('admin/config/regional/tmgmt_translator/manage/' . $this->translator->id(), $edit, t('Save')); $this->assertText(t('@label configuration has been updated.', ['@label' => $this->translator->label()])); }
/** * 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); }
/** * Execute a request against the Microsoft API. * * @param Translator $translator * The translator entity to get the settings from. * @param $path * The path that should be appended to the base uri, e.g. Translate or * GetLanguagesForTranslate. * @param $query * (Optional) Array of GET query arguments. * @param $headers * (Optional) Array of additional HTTP headers. * * @return \Psr\Http\Message\ResponseInterface * The HTTP response. */ protected function doRequest(Translator $translator, $path, array $query = array(), array $headers = array()) { $custom_url = $translator->getSetting('url'); $url = ($custom_url ? $custom_url : $this->translatorUrl) . '/' . $path; $test_token_url = FALSE; if ($custom_url) { $test_token_url = $custom_url . '/GetToken'; } // The current API uses 2 new parameters and an access token. $client_id = $translator->getSetting('client_id'); $client_secret = $translator->getSetting('client_secret'); $token = $this->getToken($client_id, $client_secret, $test_token_url); $request_url = Url::fromUri($url)->toString(); $request = new Request('GET', $request_url, $headers); $request = $request->withHeader('Authorization', 'Bearer ' . $token); $response = $this->client->send($request, ['query' => $query]); return $response; }
/** * Local method to do request to Google Translate service. * * @param Translator $translator * The translator entity to get the settings from. * @param string $action * Action to be performed [translate, languages, detect] * @param array $request_query * (Optional) Additional query params to be passed into the request. * @param array $options * (Optional) Additional options that will be passed into drupal_http_request(). * * @return array object * Unserialized JSON response from Google. * * @throws TMGMTException * - Invalid action provided * - Unable to connect to the Google Service * - Error returned by the Google Service */ protected function doRequest(Translator $translator, $action, array $request_query = array(), array $options = array()) { if (!in_array($action, $this->availableActions)) { throw new TMGMTException('Invalid action requested: @action', array('@action' => $action)); } $query_string = ''; // Translate action is requested without this argument. if ($action == 'translate') { $action = ''; } // Get custom URL for testing purposes, if available. $custom_url = $translator->getSetting('url'); $url = ($custom_url ? $custom_url : $this->translatorUrl) . '/' . $action; // Prepare Guzzle Object. $request = new Request('GET', $url); // Build the query. $query_string .= '&key=' . $translator->getSetting('api_key'); if (isset($request_query['q'])) { foreach ($request_query['q'] as $source_text) { $query_string .= '&q=' . urlencode($source_text); } } if (isset($request_query['source'])) { $query_string .= '&source=' . $request_query['source']; } if (isset($request_query['target'])) { $query_string .= '&target=' . $request_query['target']; } // Send the request with the query. try { $response = $this->client->send($request, ['query' => $query_string]); } catch (BadResponseException $e) { $error = json_decode($e->getResponse()->getBody(), TRUE); throw new TMGMTException('Google Translate service returned following error: @error', ['@error' => $error['error']['message']]); } // Process the JSON result into array. return json_decode($response->getBody(), TRUE); }
/** * 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 of the job item review process. */ public function testContinuous() { // Test that continuous jobs are shown in the job overview. $this->container->get('module_installer')->install(['tmgmt_file'], TRUE); $non_continuous_translator = Translator::create(['name' => strtolower($this->randomMachineName()), 'label' => $this->randomMachineName(), 'plugin' => 'file', 'remote_languages_mappings' => [], 'settings' => []]); $non_continuous_translator->save(); $continuous_job = $this->createJob('en', 'de', 0, ['label' => 'Continuous job', 'job_type' => 'continuous']); $this->drupalGet('admin/tmgmt/jobs', ['query' => ['state' => '6']]); $this->assertText($continuous_job->label(), 'Continuous job is displayed on job overview page with status filter on continuous jobs.'); $this->drupalGet('admin/tmgmt/jobs', ['query' => ['state' => 'in_progress']]); $this->assertNoText($continuous_job->label(), 'Continuous job is not displayed on job overview page if status filter is on in progress jobs.'); // Test that there are source items checkboxes on a continuous job form. $this->drupalGet('admin/tmgmt/jobs/' . $continuous_job->id()); $this->assertText($continuous_job->label()); $this->assertNoFieldChecked('edit-continuous-settings-content-node-enabled', 'There is content checkbox and it is not checked yet.'); $this->assertNoFieldChecked('edit-continuous-settings-content-node-bundles-article', 'There is article checkbox and it is not checked yet.'); $this->assertNoFieldChecked('edit-continuous-settings-content-node-bundles-page', 'There is page checkbox and it is not checked yet.'); // Enable Article source item for continuous job. $edit_continuous_job = ['continuous_settings[content][node][enabled]' => TRUE, 'continuous_settings[content][node][bundles][article]' => TRUE]; $this->drupalPostForm(NULL, $edit_continuous_job, t('Save job')); // Test that continuous settings configuration is saved correctly. $updated_continuous_job = Job::load($continuous_job->id()); $job_continuous_settings = $updated_continuous_job->getContinuousSettings(); $this->assertEqual($job_continuous_settings['content']['node']['enabled'], 1, 'Continuous settings configuration for node is saved correctly.'); $this->assertEqual($job_continuous_settings['content']['node']['bundles']['article'], 1, 'Continuous settings configuration for article is saved correctly.'); $this->assertEqual($job_continuous_settings['content']['node']['bundles']['page'], 0, 'Continuous settings configuration for page is saved correctly.'); // Test that continuous settings checkboxes are checked correctly. $this->clickLink('Manage'); $this->assertText($continuous_job->label()); $this->assertFieldChecked('edit-continuous-settings-content-node-enabled', 'Content checkbox is now checked.'); $this->assertFieldChecked('edit-continuous-settings-content-node-bundles-article', 'Article checkbox now checked.'); $this->assertNoFieldChecked('edit-continuous-settings-content-node-bundles-page', 'Page checkbox is not checked.'); // Create continuous job through the form. $this->loginAsTranslator(['access administration pages', 'create translation jobs', 'submit translation jobs', 'access user profiles'], TRUE); $owner = $this->drupalCreateUser($this->translator_permissions); $this->drupalGet('admin/tmgmt/continuous_jobs/continuous_add'); $this->assertResponse(403, 'Access denied'); $this->loginAsAdmin(); $this->drupalGet('admin/tmgmt/continuous_jobs/continuous_add'); $this->assertNoText($non_continuous_translator->label()); $continuous_job_label = strtolower($this->randomMachineName()); $edit_job = ['label[0][value]' => $continuous_job_label, 'target_language' => 'de', 'uid' => $owner->getDisplayName(), 'translator' => $this->default_translator->id()]; $this->drupalPostForm(NULL, $edit_job, t('Save job')); $this->assertText($continuous_job_label, 'Continuous job was created.'); // Test that previous created job is continuous job. $this->drupalGet('admin/tmgmt/jobs'); $this->assertText($continuous_job_label, 'Created continuous job is displayed on job overview page.'); // Test that job overview page with status to continuous does not have // Submit link. $this->drupalGet('admin/tmgmt/jobs', ['query' => ['state' => Job::STATE_CONTINUOUS]]); $this->assertNoLink('Submit', 'There is no Submit link on job overview with status to continuous.'); // Test that all unnecessary fields and buttons do not exist on continuous // job edit form. $this->clickLink('Manage', 0); $this->assertText($continuous_job_label); $this->assertFieldById('edit-uid', $owner->getDisplayName() . ' (' . $owner->id() . ')', 'Job owner set correctly'); $this->assertNoRaw('<label for="edit-translator">Provider</label>', 'There is no Provider info field on continuous job edit form.'); $this->assertNoRaw('<label for="edit-word-count">Total word count</label>', 'There is no Total word count info field on continuous job edit form.'); $this->assertNoRaw('<label for="edit-tags-count">Total HTML tags count</label>', 'There is no Total HTML tags count info field on continuous job edit form.'); $this->assertNoRaw('<label for="edit-created">Created</label>', 'There is no Created info field on continuous job edit form.'); $this->assertNoRaw('id="edit-job-items-wrapper"', 'There is no Job items field on continuous job edit form.'); $this->assertNoRaw('<div class="tmgmt-color-legend clearfix">', 'There is no Item state legend on continuous job edit form.'); $this->assertNoRaw('id="edit-messages"', 'There is no Translation Job Messages field on continuous job edit form.'); $this->assertNoFieldById('edit-abort-job', NULL, 'There is no Abort job button.'); $this->assertNoFieldById('edit-submit', NULL, 'There is no Submit button.'); $this->assertNoFieldById('edit-resubmit-job', NULL, 'There is Resubmit job button.'); // Remove continuous jobs and assert there is no filter displayed. $this->loginAsAdmin(); $continuous_job->delete(); $this->drupalGet('admin/tmgmt/jobs'); $this->clickLink(t('Delete')); $this->drupalPostForm(NULL, array(), t('Delete')); $this->drupalGet('admin/tmgmt/job_items'); $this->assertNoText(t('Job type')); $this->assertNoFieldByName('job_type'); // Test that the empty text is displayed. $this->drupalGet('admin/tmgmt/job_items', array('query' => array('state' => 5))); $this->assertText(t('No job items for the current selection.')); }
/** * 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()); }
/** * Creates, saves and returns a translator. * * @return \Drupal\tmgmt\TranslatorInterface */ function createTranslator(array $values = []) { $translator = Translator::create($values + ['name' => strtolower($this->randomMachineName()), 'label' => $this->randomMachineName(), 'plugin' => 'test_translator', 'remote_languages_mappings' => [], 'settings' => empty($values['plugin']) ? ['key' => $this->randomMachineName(), 'another_key' => $this->randomMachineName()] : []]); $this->assertEqual(SAVED_NEW, $translator->save()); return $translator; }
/** * 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()); } }