/** * Test the basic translation workflow. */ public function testBasicWorkflow() { $translator = Translator::load('local'); /** @var FilterFormat $basic_html_format */ $basic_html_format = FilterFormat::create(array('format' => 'basic_html', 'name' => 'Basic HTML')); $basic_html_format->save(); // Create a job and request a local translation. $this->loginAsTranslator(); $job = $this->createJob(); $job->translator = $translator->id(); $job->addItem('test_source', 'test', '1'); \Drupal::state()->set('tmgmt.test_source_data', ['dummy' => ['deep_nesting' => ['#text' => file_get_contents(drupal_get_path('module', 'tmgmt') . '/tests/testing_html/sample.html'), '#label' => 'Label for job item with type test and id 2.', '#translate' => TRUE, '#format' => 'basic_html']], 'second' => ['#text' => 'second text', '#label' => 'Second label', '#translate' => TRUE], 'third' => ['#text' => 'third text', '#label' => 'Third label', '#translate' => TRUE]]); $job->addItem('test_source', 'test', '2'); $job->save(); // Make sure that the checkout page works as expected when there are no // roles. $this->drupalGet($job->toUrl()); $this->assertText(t('@translator can not translate from @source to @target.', array('@translator' => 'Drupal user', '@source' => 'English', '@target' => 'German'))); $xpath = $this->xpath('//*[@id="edit-translator"]')[0]; $this->assertEqual($xpath->option[0], 'Drupal user (unsupported)'); $this->assignee = $this->drupalCreateUser(array_merge($this->localTranslatorPermissions, [$basic_html_format->getPermissionName()])); // The same when there is a single role. $this->drupalGet($job->toUrl()); $this->assertText(t('@translator can not translate from @source to @target.', array('@translator' => 'Drupal user', '@source' => 'English', '@target' => 'German'))); // Create another local translator with the required abilities. $other_assignee_same = $this->drupalCreateUser($this->localTranslatorPermissions); // And test again with two roles but still no abilities. $this->drupalGet($job->toUrl()); $this->assertText(t('@translator can not translate from @source to @target.', array('@translator' => 'Drupal user', '@source' => 'English', '@target' => 'German'))); $this->drupalLogin($other_assignee_same); // Configure language abilities. $edit = array('tmgmt_translation_skills[0][language_from]' => 'en', 'tmgmt_translation_skills[0][language_to]' => 'de'); $this->drupalPostForm('user/' . $other_assignee_same->id() . '/edit', $edit, t('Save')); // Check that the user is not listed in the translator selection form. $this->loginAsAdmin(); $this->drupalGet($job->toUrl()); $xpath = $this->xpath('//*[@id="edit-translator"]')[0]; $this->assertEqual($xpath->option[0], 'Drupal user'); $this->assertText(t('Assign job to')); $this->assertText($other_assignee_same->getUsername()); $this->assertNoText($this->assignee->getUsername()); $this->drupalLogin($this->assignee); // Configure language abilities. $edit = array('tmgmt_translation_skills[0][language_from]' => 'en', 'tmgmt_translation_skills[0][language_to]' => 'de'); $this->drupalPostForm('user/' . $this->assignee->id() . '/edit', $edit, t('Save')); // Check that the translator is now listed. $this->loginAsAdmin(); $this->drupalGet($job->toUrl()); $this->assertText($this->assignee->getUsername()); // Test assign task while submitting job. $job_comment = 'Dummy job comment'; $edit = ['settings[translator]' => $this->assignee->id(), 'settings[job_comment]' => $job_comment]; $this->drupalPostForm(NULL, $edit, t('Submit to provider')); $this->drupalLogin($this->assignee); $this->drupalGet('translate/pending'); $this->assertText($job->label()); $this->loginAsAdmin($this->localManagerPermissions); $this->drupalGet('manage-translate/assigned'); $this->assertNoLink(t('Delete')); $this->clickLink(t('Unassign')); $this->drupalPostForm(NULL, [], t('Unassign')); // Test for job comment in the job checkout info pane. $this->drupalGet($job->toUrl()); $this->assertText($job_comment); $this->drupalLogin($this->assignee); // Create a second local translator with different language abilities, // make sure that he does not see the task. $other_translator = $this->drupalCreateUser($this->localTranslatorPermissions); $this->drupalLogin($other_translator); // Configure language abilities. $edit = array('tmgmt_translation_skills[0][language_from]' => 'de', 'tmgmt_translation_skills[0][language_to]' => 'en'); $this->drupalPostForm('user/' . $other_translator->id() . '/edit', $edit, t('Save')); $this->drupalGet('translate'); $this->assertNoText($job->label()); $this->drupalLogin($this->assignee); // Check the translate overview. $this->drupalGet('translate'); $this->assertText($job->label()); // @todo: Fails, encoding problem? // $this->assertText(t('@from => @to', array('@from' => 'en', '@to' => 'de'))); // Test LocalTaskForm. $this->clickLink('View'); $this->assertText('Unassigned'); $xpath = $this->xpath('//*[@id="edit-status"]'); $this->assertTrue(empty($xpath)); $this->loginAsAdmin($this->localManagerPermissions); $this->drupalGet('translate'); $this->clickLink('View'); $xpath = $this->xpath('//*[@id="edit-tuid"]'); $this->assertFalse(empty($xpath)); $edit = array('tuid' => $this->assignee->id()); $this->drupalPostForm(NULL, $edit, t('Save task')); $this->assertText(t('Assigned to user @assignee.', ['@assignee' => $this->assignee->getDisplayName()])); $this->drupalGet('manage-translate/assigned'); $this->clickLink('View'); $edit = array('tuid' => 0); $this->drupalPostForm(NULL, $edit, t('Save task')); $this->drupalLogin($this->assignee); $this->drupalGet('translate'); // Assign to action not working yet. $edit = array('tmgmt_local_task_bulk_form[0]' => TRUE, 'action' => 'tmgmt_local_task_assign_to_me'); $this->drupalPostForm(NULL, $edit, t('Apply')); $this->assertText(t('Assign to me was applied to 1 item.')); // Unassign again. $edit = array('tmgmt_local_task_bulk_form[0]' => TRUE, 'action' => 'tmgmt_local_task_unassign_multiple'); $this->drupalPostForm(NULL, $edit, t('Apply')); $this->assertText(t('Unassign was applied to 1 item.')); // Now test the assign link. // @todo Action should not redirect to mine. $this->drupalGet('translate'); $this->clickLink(t('Assign to me')); $this->assertText(t('The task has been assigned to you.')); // Assert created local task and task items. $this->drupalGet('translate/pending'); $this->clickLink(t('View')); $this->assertTrue(preg_match('|translate/(\\d+)|', $this->getUrl(), $matches), 'Task found'); /** @var \Drupal\tmgmt_local\Entity\LocalTask $task */ $task = \Drupal::entityTypeManager()->getStorage('tmgmt_local_task')->load($matches[1]); $this->assertTrue($task->isPending()); $items = $task->getItems(); /** @var \Drupal\tmgmt_local\Entity\LocalTaskItem $first_task_item */ $first_task_item = reset($items); $this->assertTrue($first_task_item->isPending()); // Log in with the translator with the same abilities, make sure that he // does not see the assigned task. $this->drupalLogin($other_assignee_same); $this->drupalGet('translate'); $this->assertNoText($job->label()); $this->drupalGet('translate/items/' . $first_task_item->id()); $this->assertResponse(403); $this->drupalLogin($this->assignee); // Translate the task. $this->drupalGet('translate/' . $task->id()); $this->assertText('test_source:test:1'); $this->assertText('test_source:test:2'); // Translate the first item. $this->clickLink(t('Translate')); // Assert the breadcrumb. $this->assertLink(t('Home')); $this->assertLink(t('Local Tasks')); $this->assertText($job->label()); // Assert the header. $this->assertLink($first_task_item->getJobItem()->getSourceLabel()); $this->assertText($first_task_item->getJobItem()->getSourceType()); $this->assertText($first_task_item->getJobItem()->getJob()->getSourceLanguage()->getName()); $this->assertText($first_task_item->getJobItem()->getJob()->getTargetLanguage()->getName()); $this->assertText(\Drupal::service('date.formatter')->format($first_task_item->getChangedTime())); $this->assertText($first_task_item->getStatus()); $this->assertLink($first_task_item->getTask()->label()); $this->assertText(t('Dummy')); // Check if Save as completed button is displayed. $elements = $this->xpath('//*[@id="edit-save-as-completed"]'); $this->assertTrue(!empty($elements), "'Save as completed' button appears."); // Job comment is present in the translate tool as well. $this->assertText($job_comment); $this->assertText('test_source:test:1'); // Try to complete a translation when translations are missing. $edit = array('dummy|deep_nesting[translation]' => ''); $this->drupalPostForm(NULL, $edit, t('Save as completed')); $this->assertText(t('Missing translation.')); $edit = array('dummy|deep_nesting[translation]' => $translation1 = 'German translation of source 1'); $this->drupalPostForm(NULL, $edit, t('Save as completed')); $this->assertRaw('tmgmt/icons/gray-check.svg" title="Translated"'); $this->assertText('The translation for ' . $first_task_item->label() . ' has been saved as completed.'); // Check that the source has not being modified. $this->clickLink(t('View')); /** @var \Drupal\tmgmt\JobItemInterface $job_item */ $job_items = $job->getItems(['tjiid' => 1]); $job_item = reset($job_items); $source = $job_item->getData(['dummy', 'deep_nesting', '#text']); $this->assertText($source); // Review and accept the first item. \Drupal::entityTypeManager()->getStorage('tmgmt_job_item')->resetCache(); drupal_static_reset('tmgmt_local_task_statistics_load'); /** @var \Drupal\tmgmt\JobItemInterface $item1 */ $item1 = JobItem::load(1); // The first item should be available for review. $this->assertTrue($item1->isNeedsReview(), 'Job item 1 needs review.'); $item1->acceptTranslation(); // The first item should be accepted now, the second still in progress. \Drupal::entityTypeManager()->getStorage('tmgmt_local_task_item')->resetCache(); $this->drupalGet('translate/1'); // Checking if the 'Save as completed' button is not displayed. $this->drupalGet('translate/items/1'); $elements = $this->xpath('//*[@id="edit-save-as-completed"]'); $this->assertTrue(empty($elements), "'Save as completed' button does not appear."); // Checking if the item status is not displayed. $this->assertNoRaw('title="Finish"'); $this->assertNoRaw('title="Reject"'); // We can go back to the Task from the item. $this->drupalGet('translate/items/1'); $this->clickLink($task->label()); // Let's check the task status. /** @var \Drupal\tmgmt_local\Entity\LocalTask $task */ $task = entity_load('tmgmt_local_task', $task->id(), TRUE); $this->assertTrue($task->isPending()); /** @var \Drupal\tmgmt_local\Entity\LocalTaskItem $second_task_item */ list($first_task_item, $second_task_item) = array_values($task->getItems()); $this->assertTrue($first_task_item->isClosed()); // Assert that translator can provide translations for a "Dummy" field. An // empty text field should be displayed as translator does not have a // permission to use "full_html" text format. $second_task_item->updateData('dummy|deep_nesting', ['#format' => 'full_html']); $second_task_item->save(); $this->clickLink(t('Translate')); $this->assertFieldByName('dummy|deep_nesting[translation]'); $this->assertRaw('Save as completed" class="button button--primary js-form-submit form-submit"'); $translation_field = $this->xpath('//*[@id="edit-dummydeep-nesting-translation"]')[0]; $this->assertEqual($translation_field, ''); // Translate the second item but do not mark as translated it yet. $second_task_item->updateData('dummy|deep_nesting', ['#format' => 'basic_html']); $second_task_item->save(); $this->drupalGet('translate/items/' . $second_task_item->id()); $xpath = $this->xpath('//*[@id="edit-dummydeep-nesting-translation-format-guidelines"]/div')[0]; $this->assertEqual($xpath[0]->h4[0], t('Basic HTML')); // Assert the order of the displayed elements. $translate_elements = $this->xpath('//*[@id="edit-translation"]/table'); $ids = []; foreach ($translate_elements as $translate_element) { $ids[] = (string) $translate_element['id']; } $this->assertEqual($ids[0], 'tmgmt-local-element-dummy-deep-nesting'); $this->assertEqual($ids[1], 'tmgmt-local-element-second'); $this->assertEqual($ids[2], 'tmgmt-local-element-third'); $edit = array('dummy|deep_nesting[translation][value]' => $translation2 = 'German translation of source 2'); $this->drupalPostForm(NULL, $edit, t('Save')); $this->assertText('The translation for ' . $second_task_item->label() . ' has been saved.'); drupal_static_reset('tmgmt_local_task_statistics_load'); /** @var \Drupal\tmgmt_local\Entity\LocalTask $task */ $task = entity_load('tmgmt_local_task', $task->id(), TRUE); $this->assertTrue($task->isPending()); // Mark the data item as translated but don't save the task item as // completed. $this->clickLink(t('Translate')); $this->drupalPostAjaxForm(NULL, [], 'finish-dummy|deep_nesting'); $this->assertRaw('name="reject-dummy|deep_nesting"', "'✗' button appears."); $this->drupalGet('translate/' . $task->id()); \Drupal::entityTypeManager()->getStorage('tmgmt_local_task_item')->resetCache(); drupal_static_reset('tmgmt_local_task_statistics_load'); /** @var \Drupal\tmgmt_local\Entity\LocalTask $task */ $task = entity_load('tmgmt_local_task', $task->id(), TRUE); $this->assertTrue($task->isPending()); list($first_task_item, $second_task_item) = array_values($task->getItems()); $this->assertTrue($first_task_item->isClosed()); $this->assertTrue($second_task_item->isPending()); // Check the job data. \Drupal::entityTypeManager()->getStorage('tmgmt_job_item')->resetCache(); /** @var \Drupal\tmgmt\JobInterface $job */ $job = Job::load($job->id()); /** @var \Drupal\tmgmt\JobItemInterface $item2 */ list($item1, $item2) = array_values($job->getItems()); $this->assertTrue($item1->isAccepted(), 'Job item 1 is accepted.'); // The first item should be active. $this->assertTrue($item2->isActive(), 'Job item 2 is still active.'); // Check the overview page, the task should still show in progress. $this->drupalGet('translate'); $this->assertText(t('Pending')); // Mark the second item as completed now. $this->clickLink(t('View')); $this->clickLink(t('Translate')); $remaining_translations = ['second[translation]' => 'Third translation', 'third[translation]' => 'Third translation']; $this->drupalPostForm(NULL, $remaining_translations, t('Save as completed')); $this->assertText('The translation for ' . $second_task_item->label() . ' has been saved as completed.'); $this->clickLink('View'); // Review and accept the second item. \Drupal::entityTypeManager()->getStorage('tmgmt_job_item')->resetCache(); drupal_static_reset('tmgmt_local_task_statistics_load'); $item1 = JobItem::load(2); $item1->acceptTranslation(); // Refresh the page. $this->drupalGet('translate'); // We should have been redirect back to the overview, the task should be // completed now. $this->assertNoText($task->getJob()->label()); $this->clickLink(t('Closed')); $this->assertText($task->getJob()->label()); $this->assertText(t('Completed')); \Drupal::entityTypeManager()->getStorage('tmgmt_local_task_item')->resetCache(); $task = tmgmt_local_task_load($task->id()); $this->assertTrue($task->isClosed()); list($first_task_item, $second_task_item) = array_values($task->getItems()); $this->assertTrue($first_task_item->isClosed()); $this->assertTrue($second_task_item->isClosed()); \Drupal::entityTypeManager()->getStorage('tmgmt_job_item')->resetCache(); $job = Job::load($job->id()); list($item1, $item2) = array_values($job->getItems()); // Job was accepted and finished automatically due to the default approve // setting. $this->assertTrue($job->isFinished()); $this->assertEqual($item1->getData(array('dummy', 'deep_nesting', '#translation', '#text')), $translation1); $this->assertEqual($item2->getData(array('dummy', 'deep_nesting', '#translation', '#text')), $translation2); // Delete the job, make sure that the corresponding task and task items were // deleted. $job->delete(); $this->assertFalse(tmgmt_local_task_item_load($task->id())); $this->assertFalse($task->getItems()); }
/** * {@inheritdoc} */ public function getMostRecentItem($plugin, $item_type, $item_id) { $query = \Drupal::entityQuery('tmgmt_job_item')->condition('tjid', $this->id())->condition('plugin', $plugin)->condition('item_type', $item_type)->condition('item_id', $item_id)->sort('tjiid', 'DESC')->range(0, 1); $result = $query->execute(); if (!empty($result)) { return JobItem::load(reset($result)); } return NULL; }
/** * Test for simple configuration translation. */ function testSimpleConfigTranslation() { $this->loginAsTranslator(array('translate configuration')); // Go to the translate tab. $this->drupalGet('admin/tmgmt/sources/config/_simple_config'); // Assert some basic strings on that page. $this->assertText(t('Simple configuration overview (Config Entity)')); // Request a translation for Site information settings. $edit = array('items[system.site_information_settings]' => TRUE); $this->drupalPostForm(NULL, $edit, t('Request translation')); // Verify that we are on the translate tab. $this->assertText(t('One job needs to be checked out.')); $this->assertText('System information (English to ?, Unprocessed)'); // Submit. $this->drupalPostForm(NULL, array(), t('Submit to provider')); // Make sure that we're back on the originally defined destination URL. $this->assertUrl('admin/tmgmt/sources/config/_simple_config'); $overview_url = Url::fromRoute('tmgmt.source_overview', array('plugin' => 'config', 'item_type' => '_simple_config'))->toString(); // Translated languages should now be listed as Needs review. $this->assertRaw(SafeMarkup::format('href=":url" title="Active job item: Needs review"', array(':url' => JobItem::load(1)->urlInfo()->setOption('query', ['destination' => $overview_url])->toString()))); $this->assertText(t('Test translation created.')); $this->assertText('The translation of System information to German is finished and can now be reviewed.'); // Verify that the pending translation is shown. $review = $this->xpath('//table[@id="edit-items"]/tbody/tr[@class="even"][1]/td[@class="langstatus-de"]/a/@href'); $destination = $this->getAbsoluteUrl($review[0]['href']); $this->drupalGet($destination); $this->drupalPostForm(NULL, array(), t('Save')); // Request a translation for Account settings $edit = array('items[entity.user.admin_form]' => TRUE); $this->drupalPostForm(NULL, $edit, t('Request translation')); // Verify that we are on the checkout page. $this->assertText(t('One job needs to be checked out.')); $this->assertText('Account settings (English to ?, Unprocessed)'); $this->drupalPostForm(NULL, array(), t('Submit to provider')); // Make sure that we're back on the originally defined destination URL. $this->assertUrl('admin/tmgmt/sources/config/_simple_config'); // Translated languages should now be listed as Needs review. $links = $this->xpath('//table[@id="edit-items"]/tbody/tr/td/a/@href'); $counter = 0; foreach ($links as $subarray) { $counter += count($subarray); } $this->assertEqual($counter, 2); // Save one translation. $this->drupalPostForm('admin/tmgmt/items/1', array(), t('Save as completed')); // Test if the filter works. $filters = array('search[name]' => 'system'); $this->drupalPostForm('admin/tmgmt/sources/config/_simple_config', $filters, t('Search')); // Check if the list has 2 rows. $this->assertEqual(count($this->xpath('//tbody/tr')), 2); $filters = array('search[target_language]' => 'de', 'search[target_status]' => 'translated'); $this->drupalPostForm('admin/tmgmt/sources/config/_simple_config', $filters, t('Search')); // Just 1 simple configuration was translated. $this->assertEqual(count($this->xpath('//tbody/tr')), 1); // Filter with name and target_status. $filters = array('search[name]' => 'settings', 'search[target_language]' => 'de', 'search[target_status]' => 'untranslated'); $this->drupalPostForm('admin/tmgmt/sources/config/_simple_config', $filters, t('Search')); // There is 1 simple configuration untranslated with name 'settings'. $this->assertEqual(count($this->xpath('//tbody/tr')), 1); $filters = array('search[name]' => 'sys', 'search[target_language]' => 'de', 'search[target_status]' => 'translated'); $this->drupalPostForm('admin/tmgmt/sources/config/_simple_config', $filters, t('Search')); // There are 2 simple configurations with name 'sys' but just 1 is translated. $this->assertEqual(count($this->xpath('//tbody/tr')), 1); }
/** * {@inheritdoc} */ public function validateImport($imported_file, $is_file = TRUE) { // Validates imported XLIFF file. // Checks: // - Job ID // - Target ans source languages // - Content integrity. $xml = $this->getImportedXML($imported_file, $is_file); if ($xml === FALSE) { drupal_set_message(t('The imported file is not a valid XML.'), 'error'); return FALSE; } // Check if our phase information is there. $phase = $xml->xpath("//xliff:phase[@phase-name='extraction']"); if ($phase) { $phase = reset($phase); } else { drupal_set_message(t('The imported file is missing required XLIFF phase information.'), 'error'); return FALSE; } // Check if the job has a valid job reference. if (!isset($phase['job-id'])) { drupal_set_message(t('The imported file does not contain a job reference.'), 'error'); return FALSE; } // Attempt to load the job if none passed. $job = Job::load((int) $phase['job-id']); if (empty($job)) { drupal_set_message(t('The imported file job id @file_tjid is not available.', array('@file_tjid' => $phase['job-id'])), 'error'); return FALSE; } // Compare source language. if (!isset($xml->file['source-language']) || $job->getRemoteSourceLanguage() != $xml->file['source-language']) { $job->addMessage('The imported file source language @file_language does not match the job source language @job_language.', array('@file_language' => empty($xml->file['source-language']) ? t('none') : $xml->file['source-language'], '@job_language' => $job->source_language), 'error'); return FALSE; } // Compare target language. if (!isset($xml->file['target-language']) || $job->getRemoteTargetLanguage() != $xml->file['target-language']) { $job->addMessage('The imported file target language @file_language does not match the job target language @job_language.', array('@file_language' => empty($xml->file['target-language']) ? t('none') : $xml->file['target-language'], '@job_language' => $job->target_language), 'error'); return FALSE; } $targets = $this->getImportedTargets($job); if (empty($targets)) { $job->addMessage('The imported file seems to be missing translation.', 'error'); return FALSE; } // In case we do not do xliff processing we cannot do the elements // count validation. if (!$job->getSetting('xliff_processing')) { return $job; } $reader = new \XMLReader(); $xliff_validation = $job->getSetting('xliff_validation'); foreach ($targets as $id => $target) { $array_key = \Drupal::service('tmgmt.data')->ensureArrayKey($id); $job_item = JobItem::load(array_shift($array_key)); $count = 0; $reader->XML('<translation>' . $target['#text'] . '</translation>'); while ($reader->read()) { if (in_array($reader->name, array('translation', '#text'))) { continue; } $count++; } if (!isset($xliff_validation[$id]) || $xliff_validation[$id] != $count) { $job_item->addMessage('Failed to validate semantic integrity of %key element. Please check also the HTML code of the element in the review process.', array('%key' => \Drupal::service('tmgmt.data')->ensureStringKey($array_key))); } } // Validation successful. return $job; }
/** * Tests of the job item review process. */ public function testReview() { $job = $this->createJob(); $job->translator = $this->default_translator->id(); $job->settings = array(); $job->save(); $item = $job->addItem('test_source', 'test', 1); // The test expects the item to be active. $item->active(); $data = \Drupal::service('tmgmt.data')->flatten($item->getData()); $keys = array_keys($data); $key = $keys[0]; $this->drupalGet('admin/tmgmt/items/' . $item->id()); // Test that source and target languages are displayed. $this->assertText($item->getJob()->getSourceLanguage()->getName()); $this->assertText($item->getJob()->getTargetLanguage()->getName()); // Testing the title of the preview page. $this->assertText(t('Job item @source_label', array('@source_label' => $job->label()))); // Testing the result of the // TMGMTTranslatorUIControllerInterface::reviewDataItemElement() $this->assertText(t('Testing output of review data item element @key from the testing provider.', array('@key' => $key))); // Test the review tool source textarea. $this->assertFieldByName('dummy|deep_nesting[source]', $data[$key]['#text']); // Save translation. $this->drupalPostForm(NULL, array('dummy|deep_nesting[translation]' => $data[$key]['#text'] . 'translated'), t('Save')); // Test review data item. $this->drupalGet('admin/tmgmt/items/' . $item->id()); $this->drupalPostAjaxForm(NULL, [], 'reviewed-dummy|deep_nesting'); $this->assertRaw('icons/gray-check.svg" alt="Reviewed"'); \Drupal::entityTypeManager()->getStorage('tmgmt_job')->resetCache(); \Drupal::entityTypeManager()->getStorage('tmgmt_job_item')->resetCache(); /** @var JobItem $item */ $item = JobItem::load($item->id()); $this->assertEqual($item->getCountReviewed(), 1, 'Item reviewed correctly.'); // Check if translation has been saved. $this->assertFieldByName('dummy|deep_nesting[translation]', $data[$key]['#text'] . 'translated'); // Tests for the minimum height of the textareas. $rows = $this->xpath('//textarea[@name="dummy|deep_nesting[source]"]'); $this->assertEqual((string) $rows[0]['rows'], 3); $rows2 = $this->xpath('//textarea[@name="dummy|deep_nesting[translation]"]'); $this->assertEqual((string) $rows2[0]['rows'], 3); // Test data item status when content changes. $this->drupalPostForm(NULL, array(), t('Save')); $this->drupalGet('admin/tmgmt/items/' . $item->id()); $this->assertRaw('icons/gray-check.svg" alt="Reviewed"'); $edit = ['dummy|deep_nesting[translation]' => 'New text for job item']; $this->drupalPostForm(NULL, $edit, t('Save')); $this->drupalGet('admin/tmgmt/items/' . $item->id()); $this->assertRaw('icons/gray-check.svg" alt="Reviewed"'); $this->assertFieldByName('dummy|deep_nesting[translation]', 'New text for job item'); // Test for the dynamical height of the source textarea. \Drupal::state()->set('tmgmt.test_source_data', array('dummy' => array('deep_nesting' => array('#text' => str_repeat('Text for job item', 20), '#label' => 'Label')))); $item2 = $job->addItem('test_source', 'test', 2); $this->drupalGet('admin/tmgmt/items/' . $item2->id()); $rows3 = $this->xpath('//textarea[@name="dummy|deep_nesting[source]"]'); $this->assertEqual((string) $rows3[0]['rows'], 4); // Test for the maximum height of the source textarea. \Drupal::state()->set('tmgmt.test_source_data', array('dummy' => array('deep_nesting' => array('#text' => str_repeat('Text for job item', 100), '#label' => 'Label')))); $item3 = $job->addItem('test_source', 'test', 3); $this->drupalGet('admin/tmgmt/items/' . $item3->id()); $rows4 = $this->xpath('//textarea[@name="dummy|deep_nesting[source]"]'); $this->assertEqual((string) $rows4[0]['rows'], 15); // Tests the HTML tags validation. \Drupal::state()->set('tmgmt.test_source_data', array('title' => array('deep_nesting' => array('#text' => '<p><em><strong>Source text bold and Italic</strong></em></p>', '#label' => 'Title')), 'body' => array('deep_nesting' => array('#text' => '<p><em><strong>Source body bold and Italic</strong></em></p>', '#label' => 'Body')))); $item4 = $job->addItem('test_source', 'test', 4); $this->drupalGet('admin/tmgmt/items/' . $item4->id()); // Drop <strong> tag in translated text. $edit = array('title|deep_nesting[translation]' => '<em>Translated italic text missing paragraph</em>'); $this->drupalPostForm(NULL, $edit, t('Validate HTML tags')); $this->assertText(t('Expected tags @tags not found.', array('@tags' => '<p>,<strong>,</strong>,</p>'))); $this->assertText(t('@tag expected 1, found 0.', array('@tag' => '<p>'))); $this->assertText(t('@tag expected 1, found 0.', array('@tag' => '<strong>'))); $this->assertText(t('@tag expected 1, found 0.', array('@tag' => '</strong>'))); $this->assertText(t('@tag expected 1, found 0.', array('@tag' => '</p>'))); $this->assertText(t('HTML tag validation failed for 1 field(s).')); // Change the order of HTML tags. $edit = array('title|deep_nesting[translation]' => '<p><strong><em>Translated text Italic and bold</em></strong></p>'); $this->drupalPostForm(NULL, $edit, t('Validate HTML tags')); $this->assertText(t('Order of the HTML tags are incorrect.')); $this->assertText(t('HTML tag validation failed for 1 field(s).')); // Add multiple tags incorrectly. $edit = array('title|deep_nesting[translation]' => '<p><p><p><p><strong><em><em>Translated text Italic and bold, many tags</em></strong></strong></strong></p>'); $this->drupalPostForm(NULL, $edit, t('Validate HTML tags')); $this->assertText(t('@tag expected 1, found 4.', array('@tag' => '<p>'))); $this->assertText(t('@tag expected 1, found 2.', array('@tag' => '<em>'))); $this->assertText(t('@tag expected 1, found 3.', array('@tag' => '</strong>'))); $this->assertText(t('HTML tag validation failed for 1 field(s).')); // Check validation errors for two fields. $edit = array('title|deep_nesting[translation]' => '<p><p><p><p><strong><em><em>Translated text Italic and bold, many tags</em></strong></strong></strong></p>', 'body|deep_nesting[translation]' => '<p>Source body bold and Italic</strong></em></p>'); $this->drupalPostForm(NULL, $edit, t('Validate HTML tags')); $this->assertText(t('HTML tag validation failed for 2 field(s).')); // Tests that there is always a title. $text = '<p><em><strong>Source text bold and Italic</strong></em></p>'; \Drupal::state()->set('tmgmt.test_source_data', ['title' => [['value' => ['#text' => $text, '#label' => 'Title', '#translate' => TRUE, '#format' => 'filtered_html']]], 'body' => ['deep_nesting' => ['#text' => $text, '#label' => 'Body', '#translate' => TRUE, '#format' => 'filtered_html']]]); $item5 = $job->addItem('test_source', 'test', 4); $this->drupalPostForm('admin/tmgmt/items/' . $item5->id(), [], t('Validate')); $this->assertText(t('The field is empty.')); // Test review just one data item. $edit = ['title|0|value[translation][value]' => $text . 'translated', 'body|deep_nesting[translation][value]' => $text . 'no save']; $this->drupalPostAjaxForm('admin/tmgmt/items/' . $item5->id(), $edit, 'reviewed-title|0|value'); // Check if translation has been saved. $this->drupalGet('admin/tmgmt/items/' . $item5->id()); $this->assertFieldByName('title|0|value[translation][value]', $text . 'translated'); $this->assertNoFieldByName('body|deep_nesting[translation][value]', $text . 'no save'); // Tests field is less than max_length. \Drupal::state()->set('tmgmt.test_source_data', ['title' => [['value' => ['#text' => $text, '#label' => 'Title', '#translate' => TRUE, '#max_length' => 10]]], 'body' => ['deep_nesting' => ['#text' => $text, '#label' => 'Body', '#translate' => TRUE, '#max_length' => 20]]]); $item5 = $job->addItem('test_source', 'test', 4); $this->drupalPostForm('admin/tmgmt/items/' . $item5->id(), ['title|0|value[translation]' => $text, 'body|deep_nesting[translation]' => $text], t('Save')); $this->assertText(t('The field has @size characters while the limit is @limit.', ['@size' => strlen($text), '@limit' => 10])); $this->assertText(t('The field has @size characters while the limit is @limit.', ['@size' => strlen($text), '@limit' => 20])); // Test if the validation is properly done. $this->drupalPostAjaxForm(NULL, [], 'reviewed-body|deep_nesting'); $this->assertUniqueText(t('The field has @size characters while the limit is @limit.', ['@size' => strlen($text), '@limit' => 10])); // Test for the text with format set. \Drupal::state()->set('tmgmt.test_source_data', array('dummy' => array('deep_nesting' => array('#text' => 'Text for job item', '#label' => 'Label', '#format' => 'filtered_html')))); $item5 = $job->addItem('test_source', 'test', 5); $item5->active(); $this->drupalGet('admin/tmgmt/jobs/' . $job->id()); $this->assertText('The translation of test_source:test:1 to German is finished and can now be reviewed.'); $this->clickLink(t('reviewed')); $this->assertText('Needs review'); $this->assertText('Job item test_source:test:1'); $edit = array('target_language' => 'de', 'settings[action]' => 'submit'); $this->drupalPostForm('admin/tmgmt/jobs/' . $job->id(), $edit, t('Submit to provider')); $this->drupalGet('admin/tmgmt/items/' . $item5->id()); $xpath = $this->xpath('//*[@id="edit-dummydeep-nesting-translation-format-guidelines"]/div')[0]; $this->assertEqual($xpath[0]->h4[0], t('Filtered HTML')); $rows5 = $this->xpath('//textarea[@name="dummy|deep_nesting[source][value]"]'); $this->assertEqual((string) $rows5[0]['rows'], 3); $this->drupalPostForm(NULL, [], t('Save')); $this->assertNoText('has been saved successfully.'); $this->drupalGet('admin/tmgmt/items/' . $item5->id()); $this->assertText('In progress'); $edit = array('dummy|deep_nesting[translation][value]' => 'Translated text for job item'); $this->drupalPostForm(NULL, $edit, t('Save')); $this->assertText('The translation for ' . trim($item5->label()) . ' has been saved successfully.'); $this->drupalGet('admin/tmgmt/items/' . $item5->id()); $this->assertText('Translated text for job item'); $this->drupalPostForm(NULL, $edit, t('Save as completed')); $this->assertEqual(\Drupal::state()->get('tmgmt_test_saved_translation_' . $item5->getItemType() . '_' . $item5->getItemId())['dummy']['deep_nesting']['#translation']['#text'], 'Translated text for job item'); // Test if the icons are displayed. $this->assertRaw('views-field-progress">Accepted'); $this->assertRaw('icons/ready.svg" title="Needs review"'); $this->loginAsAdmin(); // Create two translators. $translator1 = $this->createTranslator(); $translator2 = $this->createTranslator(); $this->drupalGet('admin/tmgmt/jobs'); // Assert that translators are in dropdown list. $this->assertOption('edit-translator', $translator1->id()); $this->assertOption('edit-translator', $translator2->id()); // Assign each job to a translator. $job1 = $this->createJob(); $this->drupalGet('admin/tmgmt/jobs'); $label = trim((string) $this->xpath('//table[@class="views-table views-view-table cols-10"]/tbody/tr')[0]->td[1]); $job2 = $this->createJob(); $this->drupalGet('admin/tmgmt/jobs'); $this->assertTrue($label, trim((string) $this->xpath('//table[@class="views-table views-view-table cols-10"]/tbody/tr')[0]->td[1])); $job1->set('translator', $translator1->id())->save(); $job2->set('translator', $translator2->id())->save(); // Test that progress bar is being displayed. $this->assertRaw('class="tmgmt-progress-pending" style="width: 50%"'); // Filter jobs by translator and assert values. $this->drupalGet('admin/tmgmt/jobs', array('query' => array('translator' => $translator1->id()))); $label = trim((string) $this->xpath('//table[@class="views-table views-view-table cols-10"]/tbody/tr')[0]->td[4]); $this->assertEqual($label, $translator1->label(), 'Found provider label in table'); $this->assertNotEqual($label, $translator2->label(), "Providers filtered in table"); $this->drupalGet('admin/tmgmt/jobs', array('query' => array('translator' => $translator2->id()))); $label = trim((string) $this->xpath('//table[@class="views-table views-view-table cols-10"]/tbody/tr')[0]->td[4]); $this->assertEqual($label, $translator2->label(), 'Found provider label in table'); $this->assertNotEqual($label, $translator1->label(), "Providers filtered in table"); $edit = array('dummy|deep_nesting[translation]' => ''); $this->drupalGet('admin/tmgmt/items/' . $item->id()); $this->drupalPostForm(NULL, $edit, t('Validate')); $this->assertText(t('The field is empty.')); $this->drupalPostForm(NULL, [], t('Save')); $this->assertNoText(t('The field is empty.')); $this->drupalGet('admin/tmgmt/items/' . $item->id()); $this->drupalPostForm(NULL, [], t('Save as completed')); $this->assertText(t('The field is empty.')); // Test validation message for 'Validate' button. $this->drupalGet('admin/tmgmt/items/' . $item->id()); $translation_field = $this->randomMachineName(); $edit = array('dummy|deep_nesting[translation]' => $translation_field); $this->drupalPostForm(NULL, $edit, t('Validate')); $this->assertText(t('Validation completed successfully.'), 'Message is correctly displayed.'); // Test validation message for 'Validate HTML tags' button. $this->drupalPostForm(NULL, $edit, t('Validate HTML tags')); $this->assertText(t('Validation completed successfully.'), 'Message is correctly displayed.'); // Test that normal job item are shown in job items overview. $this->drupalGet('admin/tmgmt/job_items', array('query' => array('state' => 'All'))); $this->assertNoText($job1->label(), 'Normal job item is displayed on job items overview.'); // Test that the legend is being displayed. $this->assertRaw('class="tmgmt-color-legend clearfix"'); // Test that progress bar is being displayed. $this->assertRaw('class="tmgmt-progress-reviewed" style="width: 100%"'); }
/** * Create a Suggestion-Table entry based on a Job and a title. * * @param array $result * Suggestion array with the keys job_item, reason and from_item. * * @return array * Options-Entry for a tableselect array. */ function addSuggestionItem(array $result) { $item = $result['job_item']; $reason = isset($result['reason']) ? $result['reason'] : NULL; $option = array('title' => $item->label(), 'type' => $item->getSourceType(), 'words' => $item->getWordCount(), 'tags' => $item->getTagsCount(), 'reason' => $reason); if (!empty($result['from_item'])) { $from_item = JobItem::load($result['from_item']); if ($from_item) { $option['reason'] = t('%reason in %job', array('%reason' => $option['reason'], '%job' => $from_item->label())); } } return $option; }