updated core to 7.58 (right after the site was hacked)

This commit is contained in:
2018-04-20 23:48:40 +02:00
parent 18f4aba146
commit 9344a61b61
711 changed files with 99690 additions and 480 deletions

View File

@@ -0,0 +1,6 @@
<p>one paragraph with special characters: äöüľščťžýáíéäňú©«®™»</p>
<p>one paragraph with a <br />break line</p>
<p>one paragraph with html entities: &amp;&lt;&gt;</p>
<p>and here we have some link <a href="http://example.com">break line</a></p>
<p>one paragraph with an <img src="not-existing.gif" alt="not existing image" title="not existing image" />image</p>
<p>hello <span class="green">world</span> this is <span class="red">simple html</span></p><div>nested 1<div>nested 2<div>nested 3</div></div></div>

View File

@@ -0,0 +1,245 @@
<?php
/*
* @file
* Contains tests for Translation management
*/
/**
* Utility test case class with helper methods to create entities and their
* fields with populated translatable content. Extend this class if you create
* tests in which you need Drupal entities and/or fields.
*/
abstract class TMGMTEntityTestCaseUtility extends TMGMTBaseTestCase {
public $field_names = array();
/**
* Creates node type with several text fields with different cardinality.
*
* Internally it calls TMGMTEntityTestCaseUtility::attachFields() to create
* and attach fields to newly created bundle. You can than use
* $this->field_names['node']['YOUR_BUNDLE_NAME'] to access them.
*
* @param string $machine_name
* Machine name of the node type.
* @param string $human_name
* Human readable name of the node type.
* @param int $language_content_type
* Either 0 (disabled), 1 (language enabled but no translations),
* TRANSLATION_ENABLED or ENTITY_TRANSLATION_ENABLED.
* pparam bool $attach_fields
* (optional) If fields with the same translatability should automatically
* be attached to the node type.
*/
function createNodeType($machine_name, $human_name, $language_content_type = 0, $attach_fields = TRUE) {
// Create new bundle.
$type = array(
'type' => $machine_name,
'name' => $human_name,
'base' => 'node_content',
'description' => '',
'custom' => 1,
'modified' => 1,
'locked' => 0,
);
$type = node_type_set_defaults($type);
node_type_save($type);
node_add_body_field($type);
node_types_rebuild();
// Set content type to be translatable as specified by
// $language_content_type.
$edit = array();
$edit['language_content_type'] = $language_content_type;
$this->drupalPost('admin/structure/types/manage/' . $machine_name, $edit, t('Save content type'));
$translatable = FALSE;
if (defined('ENTITY_TRANSLATION_ENABLED') && $language_content_type == ENTITY_TRANSLATION_ENABLED) {
$translatable = TRUE;
}
// Push in also the body field.
$this->field_names['node'][$machine_name][] = 'body';
if ($attach_fields) {
$this->attachFields('node', $machine_name, $translatable);
}
// Change body field to be translatable.
$body = field_info_field('body');
$body['translatable'] = $translatable;
field_update_field($body);
}
/**
* Creates taxonomy vocabulary with custom fields.
*
* To create and attach fields it internally calls
* TMGMTEntityTestCaseUtility::attachFields(). You can than access these
* fields calling $this->field_names['node']['YOUR_BUNDLE_NAME'].
*
* @param string $machine_name
* Vocabulary machine name.
* @param string $human_name
* Vocabulary human readable name.
* @param bool|array $fields_translatable
* Flag or definition array to determine which or all fields should be
* translatable.
*
* @return stdClass
* Created vocabulary object.
*/
function createTaxonomyVocab($machine_name, $human_name, $fields_translatable = TRUE) {
$vocabulary = new stdClass();
$vocabulary->name = $human_name;
$vocabulary->machine_name = $machine_name;
taxonomy_vocabulary_save($vocabulary);
$this->attachFields('taxonomy_term', $vocabulary->machine_name, $fields_translatable);
return $vocabulary;
}
/**
* Creates fields of type text and text_with_summary of different cardinality.
*
* It will attach created fields to provided entity name and bundle.
*
* Field names will be stored in $this->field_names['entity']['bundle']
* through which you can access them.
*
* @param string $entity_name
* Entity name to which fields should be attached.
* @param string $bundle
* Bundle name to which fields should be attached.
* @param bool|array $translatable
* Flag or definition array to determine which or all fields should be
* translatable.
*/
function attachFields($entity_name, $bundle, $translatable = TRUE) {
// Create several text fields.
$field_types = array('text', 'text_with_summary');
for ($i = 0 ; $i <= 5; $i++) {
$field_type = $field_types[array_rand($field_types, 1)];
$field_name = drupal_strtolower($this->randomName());
// Create a field.
$field = array(
'field_name' => $field_name,
'type' => $field_type,
'cardinality' => mt_rand(1, 5),
'translatable' => is_array($translatable) && isset($translatable[$i]) ? $translatable[$i] : (boolean) $translatable,
);
field_create_field($field);
// Create an instance of the previously created field.
$instance = array(
'field_name' => $field_name,
'entity_type' => $entity_name,
'bundle' => $bundle,
'label' => $this->randomName(10),
'description' => $this->randomString(30),
'widget' => array(
'type' => $field_type == 'text' ? 'text_textfield' : 'text_textarea_with_summary',
'label' => $this->randomString(10),
),
);
field_create_instance($instance);
// Store field names in case there are needed outside this method.
$this->field_names[$entity_name][$bundle][] = $field_name;
}
}
/**
* Creates a node of a given bundle.
*
* It uses $this->field_names to populate content of attached fields.
*
* @param string $bundle
* Node type name.
* @param string $sourcelang
* Source lang of the node to be created.
*
* @return object
* Newly created node object.
*/
function createNode($bundle, $sourcelang = 'en') {
$node = array(
'type' => $bundle,
'language' => $sourcelang,
// Ensure that the body field is defined for the node language.
'body' => array($sourcelang => array(0 => array())),
);
foreach ($this->field_names['node'][$bundle] as $field_name) {
$field_info = field_info_field($field_name);
$cardinality = $field_info['cardinality'] == FIELD_CARDINALITY_UNLIMITED ? 1 : $field_info['cardinality'];
$field_langcode = field_is_translatable('node', $field_info) ? $sourcelang : LANGUAGE_NONE;
// Create two deltas for each field.
for ($delta = 0; $delta <= $cardinality; $delta++) {
$node[$field_name][$field_langcode][$delta]['value'] = $this->randomName(20);
if ($field_info['type'] == 'text_with_summary') {
$node[$field_name][$field_langcode][$delta]['summary'] = $this->randomName(10);
}
}
}
return $this->drupalCreateNode($node);
}
/**
* Creates a taxonomy term of a given vocabulary.
*
* It uses $this->field_names to populate content of attached fields. You can
* access fields values using
* $this->field_names['taxonomy_term'][$vocabulary->machine_name].
*
* @param object $vocabulary
* Vocabulary object for which the term should be created.
*
* @param string $langcode
* The language code to be set as the entity source language.
*
* @return object
* Newly created node object.
*/
function createTaxonomyTerm($vocabulary, $langcode = 'en') {
// When an entity is being saved, the entity_translation module initializes
// a translation fetching the language from an entity. But the taxonomy
// terms have no entity language key, so its langcode will be the set to the
// default one.
/* @see entity_translation_field_attach_insert() */
/* @see EntityTranslationDefaultHandler::initTranslations() */
/* @see EntityTranslationDefaultHandler::getLanguage() */
$settings_variable_name = 'entity_translation_settings_taxonomy_term__' . $vocabulary->machine_name;
variable_set($settings_variable_name, array('default_language' => $langcode));
$term = new stdClass();
$term->name = $this->randomName();
$term->description = $this->randomName();
$term->vid = $vocabulary->vid;
foreach ($this->field_names['taxonomy_term'][$vocabulary->machine_name] as $field_name) {
$field_info = field_info_field($field_name);
$cardinality = $field_info['cardinality'] == FIELD_CARDINALITY_UNLIMITED ? 1 : $field_info['cardinality'];
$field_lang = $field_info['translatable'] ? $langcode : LANGUAGE_NONE;
// Create two deltas for each field.
for ($delta = 0; $delta <= $cardinality; $delta++) {
$term->{$field_name}[$field_lang][$delta]['value'] = $this->randomName(20);
if ($field_info['type'] == 'text_with_summary') {
$term->{$field_name}[$field_lang][$delta]['summary'] = $this->randomName(10);
}
}
}
taxonomy_term_save($term);
return taxonomy_term_load($term->tid);
}
}

View File

@@ -0,0 +1,219 @@
<?php
/*
* @file
* Contains tests for Translation management
*/
/**
* Base class for tests.
*/
class TMGMTBaseTestCase extends DrupalWebTestCase {
protected $profile = 'testing';
/**
* A default translator using the test translator.
*
* @var TMGMTTranslator
*/
protected $default_translator;
/**
* List of permissions used by loginAsAdmin().
*
* @var array
*/
protected $admin_permissions = array();
/**
* Drupal user object created by loginAsAdmin().
*
* @var object
*/
protected $admin_user = NULL;
/**
* List of permissions used by loginAsTranslator().
*
* @var array
*/
protected $translator_permissions = array();
/**
* Drupal user object created by loginAsTranslator().
*
* @var object
*/
protected $translator_user = NULL;
/**
* Overrides DrupalWebTestCase::setUp()
*/
function setUp() {
$modules = func_get_args();
if (isset($modules[0]) && is_array($modules[0])) {
$modules = $modules[0];
}
$modules = array_merge(array('entity', 'tmgmt', 'tmgmt_test'), $modules);
parent::setUp($modules);
$this->default_translator = tmgmt_translator_load('test_translator');
// 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',
);
}
/**
* Will create a user with admin permissions and log it in.
*
* @param array $additional_permissions
* Additional permissions that will be granted to admin user.
* @param boolean $reset_permissions
* Flag to determine if default admin permissions will be replaced by
* $additional_permissions.
*
* @return object
* Newly created and logged in user object.
*/
function loginAsAdmin($additional_permissions = array(), $reset_permissions = FALSE) {
$permissions = $this->admin_permissions;
if ($reset_permissions) {
$permissions = $additional_permissions;
}
elseif (!empty($additional_permissions)) {
$permissions = array_merge($permissions, $additional_permissions);
}
$this->admin_user = $this->drupalCreateUser($permissions);
$this->drupalLogin($this->admin_user);
return $this->admin_user;
}
/**
* Will create a user with translator permissions and log it in.
*
* @param array $additional_permissions
* Additional permissions that will be granted to admin user.
* @param boolean $reset_permissions
* Flag to determine if default admin permissions will be replaced by
* $additional_permissions.
*
* @return object
* Newly created and logged in user object.
*/
function loginAsTranslator($additional_permissions = array(), $reset_permissions = FALSE) {
$permissions = $this->translator_permissions;
if ($reset_permissions) {
$permissions = $additional_permissions;
}
elseif (!empty($additional_permissions)) {
$permissions = array_merge($permissions, $additional_permissions);
}
$this->translator_user = $this->drupalCreateUser($permissions);
$this->drupalLogin($this->translator_user);
return $this->translator_user;
}
/**
* Creates, saves and returns a translator.
*
* @return TMGMTTranslator
*/
function createTranslator() {
$translator = new TMGMTTranslator();
$translator->name = strtolower($this->randomName());
$translator->label = $this->randomName();
$translator->plugin = 'test_translator';
$translator->settings = array(
'key' => $this->randomName(),
'another_key' => $this->randomName(),
);
$this->assertEqual(SAVED_NEW, $translator->save());
// Assert that the translator was assigned a tid.
$this->assertTrue($translator->tid > 0);
return $translator;
}
/**
* Creates, saves and returns a translation job.
*
* @return TMGMTJob
*/
function createJob($source = 'en', $target = 'de', $uid = 1) {
$job = tmgmt_job_create($source, $target, $uid);
$this->assertEqual(SAVED_NEW, $job->save());
// Assert that the translator was assigned a tid.
$this->assertTrue($job->tjid > 0);
return $job;
}
/**
* Sets the proper environment.
*
* Currently just adds a new language.
*
* @param string $langcode
* The language code.
*/
function setEnvironment($langcode) {
// Add the language.
locale_add_language($langcode);
}
/**
* Asserts job item language codes.
*
* @param TMGMTJobItem $job_item
* Job item to check.
* @param string $expected_source_lang
* Expected source language.
* @param array $actual_lang_codes
* Expected existing language codes (translations).
*/
function assertJobItemLangCodes(TMGMTJobItem $job_item, $expected_source_lang, array $actual_lang_codes) {
$this->assertEqual($job_item->getSourceLangCode(), $expected_source_lang);
$existing = $job_item->getExistingLangCodes();
sort($existing);
sort($actual_lang_codes);
$this->assertEqual($existing, $actual_lang_codes);
}
/**
* Adds languages as admin user and switches to a translator user.
*/
protected function createLanguagesLoginTranslator($permissions = NULL) {
// Login as admin to be able to set environment variables.
$this->loginAsAdmin();
$this->setEnvironment('de');
$this->setEnvironment('es');
$this->setEnvironment('el');
$base_permissions = array(
'access administration pages',
'create translation jobs',
'submit translation jobs',
);
$permissions = $permissions ? array_merge($permissions, $base_permissions) : $base_permissions;
// Login as translator only with limited permissions to run these tests.
$this->loginAsTranslator($permissions, TRUE);
}
}

View File

@@ -0,0 +1,532 @@
<?php
/*
* @file
* Contains tests for Translation management
*/
/**
* Basic CRUD tests.
*/
class TMGMTCRUDTestCase extends TMGMTBaseTestCase {
static function getInfo() {
return array(
'name' => 'CRUD tests',
'description' => 'Basic crud operations for jobs and translators',
'group' => 'Translation Management',
);
}
/**
* Test crud operations of translators.
*/
function testTranslators() {
$translator = $this->createTranslator();
$loaded_translator = tmgmt_translator_load($translator->tid);
$this->assertEqual($translator->name, $loaded_translator->name);
$this->assertEqual($translator->label, $loaded_translator->label);
$this->assertEqual($translator->settings, $loaded_translator->settings);
// Update the settings.
$translator->settings['new_key'] = $this->randomString();
$this->assertEqual(SAVED_UPDATED, $translator->save());
$loaded_translator = tmgmt_translator_load($translator->tid);
$this->assertEqual($translator->name, $loaded_translator->name);
$this->assertEqual($translator->label, $loaded_translator->label);
$this->assertEqual($translator->settings, $loaded_translator->settings);
// Delete the translator, make sure the translator is gone.
$translator->delete();
$this->assertFalse(tmgmt_translator_load($translator->tid));
}
/**
* Test crud operations of jobs.
*/
function testJobs() {
$job = $this->createJob();
$loaded_job = tmgmt_job_load($job->tjid);
$this->assertEqual($job->source_language, $loaded_job->source_language);
$this->assertEqual($job->target_language, $loaded_job->target_language);
// Assert that the created and changed information has been set to the
// default value.
$this->assertTrue($loaded_job->created > 0);
$this->assertTrue($loaded_job->changed > 0);
$this->assertEqual(0, $loaded_job->state);
// Update the settings.
$job->reference = 7;
$this->assertEqual(SAVED_UPDATED, $job->save());
$loaded_job = tmgmt_job_load($job->tjid);
$this->assertEqual($job->reference, $loaded_job->reference);
// Test the job items.
$item1 = $job->addItem('test_source', 'type', 5);
$item2 = $job->addItem('test_source', 'type', 4);
// Load and compare the items.
$items = $job->getItems();
$this->assertEqual(2, count($items));
$this->assertEqual($item1->plugin, $items[$item1->tjiid]->plugin);
$this->assertEqual($item1->item_type, $items[$item1->tjiid]->item_type);
$this->assertEqual($item1->item_id, $items[$item1->tjiid]->item_id);
$this->assertEqual($item2->plugin, $items[$item2->tjiid]->plugin);
$this->assertEqual($item2->item_type, $items[$item2->tjiid]->item_type);
$this->assertEqual($item2->item_id, $items[$item2->tjiid]->item_id);
// Delete the job and make sure it is gone.
$job->delete();
$this->assertFalse(tmgmt_job_load($job->tjid));
}
function testRemoteMappings() {
$data_key = '5][test_source][type';
$translator = $this->createTranslator();
$job = $this->createJob();
$job->translator = $translator->name;
$job->save();
$item1 = $job->addItem('test_source', 'type', 5);
$item2 = $job->addItem('test_source', 'type', 4);
$mapping_data = array(
'remote_identifier_2' => 'id12',
'remote_identifier_3' => 'id13',
'amount' => 1043,
'currency' => 'EUR',
);
$result = $item1->addRemoteMapping($data_key, 'id11', $mapping_data);
$this->assertEqual($result, SAVED_NEW);
$job_mappings = $job->getRemoteMappings();
$item_mappings = $item1->getRemoteMappings();
$job_mapping = array_shift($job_mappings);
$item_mapping = array_shift($item_mappings);
$_job = $job_mapping->getJob();
$this->assertEqual($job->tjid, $_job->tjid);
$_job = $item_mapping->getJob();
$this->assertEqual($job->tjid, $_job->tjid);
$_item1 = $item_mapping->getJobItem();
$this->assertEqual($item1->tjiid, $_item1->tjiid);
/**
* @var TMGMTRemoteController $remote_mapping_controller
*/
$remote_mapping_controller = entity_get_controller('tmgmt_remote');
$remote_mappings = $remote_mapping_controller->loadByRemoteIdentifier('id11', 'id12', 'id13');
$remote_mapping = array_shift($remote_mappings);
$this->assertEqual($remote_mapping->tjiid, $item1->tjiid);
$this->assertEqual($remote_mapping->amount, $mapping_data['amount']);
$this->assertEqual($remote_mapping->currency, $mapping_data['currency']);
$this->assertEqual(count($remote_mapping_controller->loadByRemoteIdentifier('id11')), 1);
$this->assertEqual(count($remote_mapping_controller->loadByRemoteIdentifier('id11', '')), 0);
$this->assertEqual(count($remote_mapping_controller->loadByRemoteIdentifier('id11', NULL, '')), 0);
$this->assertEqual(count($remote_mapping_controller->loadByRemoteIdentifier(NULL, NULL, 'id13')), 1);
// Test remote data.
$item_mapping->addRemoteData('test_data', 'test_value');
entity_save('tmgmt_remote', $item_mapping);
$item_mapping = entity_load_single('tmgmt_remote', $item_mapping->trid);
$this->assertEqual($item_mapping->getRemoteData('test_data'), 'test_value');
// Add mapping to the other job item as well.
$item2->addRemoteMapping($data_key, 'id21', array('remote_identifier_2' => 'id22', 'remote_identifier_3' => 'id23'));
// Test deleting.
// Delete item1.
entity_get_controller('tmgmt_job_item')->delete(array($item1->tjiid));
// Test if mapping for item1 has been removed as well.
$this->assertEqual(count($remote_mapping_controller->loadByLocalData(NULL, $item1->tjiid)), 0);
// We still should have mapping for item2.
$this->assertEqual(count($remote_mapping_controller->loadByLocalData(NULL, $item2->tjiid)), 1);
// Now delete the job and see if remaining mappings were removed as well.
entity_get_controller('tmgmt_job')->delete(array($job->tjid));
$this->assertEqual(count($remote_mapping_controller->loadByLocalData(NULL, $item2->tjiid)), 0);
}
/**
* Test crud operations of job items.
*/
function testJobItems() {
$job = $this->createJob();
// Add some test items.
$item1 = $job->addItem('test_source', 'type', 5);
$item2 = $job->addItem('test_source', 'test_with_long_label', 4);
// Test single load callback.
$item = tmgmt_job_item_load($item1->tjiid);
$this->assertEqual($item1->plugin, $item->plugin);
$this->assertEqual($item1->item_type, $item->item_type);
$this->assertEqual($item1->item_id, $item->item_id);
// Test multiple load callback.
$items = tmgmt_job_item_load_multiple(array($item1->tjiid, $item2->tjiid));
$this->assertEqual(2, count($items));
$this->assertEqual($item1->plugin, $items[$item1->tjiid]->plugin);
$this->assertEqual($item1->item_type, $items[$item1->tjiid]->item_type);
$this->assertEqual($item1->item_id, $items[$item1->tjiid]->item_id);
$this->assertEqual($item2->plugin, $items[$item2->tjiid]->plugin);
$this->assertEqual($item2->item_type, $items[$item2->tjiid]->item_type);
$this->assertEqual($item2->item_id, $items[$item2->tjiid]->item_id);
// Test the second item label length - it must not exceed the
// TMGMT_JOB_LABEL_MAX_LENGTH.
$this->assertTrue(TMGMT_JOB_LABEL_MAX_LENGTH >= strlen($items[$item2->tjiid]->label()));
}
/**
* Tests adding translated data and revision handling.
*/
function testAddingTranslatedData() {
$translator = $this->createTranslator();
$job = $this->createJob();
$job->translator = $translator->name;
$job->save();
// Add some test items.
$item1 = $job->addItem('test_source', 'test_with_long_label', 5);
// Test the job label - it must not exceed the TMGMT_JOB_LABEL_MAX_LENGTH.
$this->assertTrue(TMGMT_JOB_LABEL_MAX_LENGTH >= strlen($job->label()));
$key = array('dummy', 'deep_nesting');
$translation['dummy']['deep_nesting']['#text'] = 'translated 1';
$item1->addTranslatedData($translation);
$data = $item1->getData($key);
// Check job messages.
$messages = $job->getMessages();
$this->assertEqual(count($messages), 1);
$last_message = end($messages);
$this->assertEqual($last_message->message, 'The translation of !source to @language is finished and can now be <a href="!review_url">reviewed</a>.');
// Initial state - translation has been received for the first time.
$this->assertEqual($data['#translation']['#text'], 'translated 1');
$this->assertTrue(empty($data['#translation']['#text_revisions']));
$this->assertEqual($data['#translation']['#origin'], 'remote');
$this->assertEqual($data['#translation']['#timestamp'], REQUEST_TIME);
// Set status back to pending as if the data item was rejected.
$item1->updateData(array('dummy', 'deep_nesting'), array('#status' => TMGMT_DATA_ITEM_STATE_PENDING));
// Add same translation text.
$translation['dummy']['deep_nesting']['#text'] = 'translated 1';
$item1->addTranslatedData($translation);
$data = $item1->getData($key);
// Check if the status has been updated back to translated.
$this->assertEqual($data['#status'], TMGMT_DATA_ITEM_STATE_TRANSLATED);
// Add translation, however locally customized.
$translation['dummy']['deep_nesting']['#text'] = 'translated 2';
$translation['dummy']['deep_nesting']['#origin'] = 'local';
$translation['dummy']['deep_nesting']['#timestamp'] = REQUEST_TIME - 5;
$item1->addTranslatedData($translation);
$data = $item1->getData($key);
// The translation text is updated.
$this->assertEqual($data['#translation']['#text'], 'translated 2');
$this->assertEqual($data['#translation']['#timestamp'], REQUEST_TIME - 5);
// Previous translation is among text_revisions.
$this->assertEqual($data['#translation']['#text_revisions'][0]['#text'], 'translated 1');
$this->assertEqual($data['#translation']['#text_revisions'][0]['#origin'], 'remote');
$this->assertEqual($data['#translation']['#text_revisions'][0]['#timestamp'], REQUEST_TIME);
// Current translation origin is local.
$this->assertEqual($data['#translation']['#origin'], 'local');
// Check job messages.
$messages = $job->getMessages();
$this->assertEqual(count($messages), 1);
// Add translation - not local.
$translation['dummy']['deep_nesting']['#text'] = 'translated 3';
unset($translation['dummy']['deep_nesting']['#origin']);
unset($translation['dummy']['deep_nesting']['#timestamp']);
$item1->addTranslatedData($translation);
$data = $item1->getData($key);
// The translation text is NOT updated.
$this->assertEqual($data['#translation']['#text'], 'translated 2');
$this->assertEqual($data['#translation']['#timestamp'], REQUEST_TIME - 5);
// Received translation is the latest revision.
$last_revision = end($data['#translation']['#text_revisions']);
$this->assertEqual($last_revision['#text'], 'translated 3');
$this->assertEqual($last_revision['#origin'], 'remote');
$this->assertEqual($last_revision['#timestamp'], REQUEST_TIME);
// Current translation origin is local.
$this->assertEqual($data['#translation']['#origin'], 'local');
// Check job messages.
$messages = $job->getMessages();
$this->assertEqual(count($messages), 2);
$last_message = end($messages);
$this->assertEqual($last_message->message, 'Translation for customized @key received. Revert your changes if you wish to use it.');
// Revert to previous revision which is the latest received translation.
$item1->dataItemRevert($key);
$data = $item1->getData($key);
// The translation text is updated.
$this->assertEqual($data['#translation']['#text'], 'translated 3');
$this->assertEqual($data['#translation']['#origin'], 'remote');
$this->assertEqual($data['#translation']['#timestamp'], REQUEST_TIME);
// Latest revision is now the formerly added local translation.
$last_revision = end($data['#translation']['#text_revisions']);
$this->assertTrue($last_revision['#text'], 'translated 2');
$this->assertTrue($last_revision['#origin'], 'remote');
$this->assertEqual($last_revision['#timestamp'], REQUEST_TIME - 5);
// Check job messages.
$messages = $job->getMessages();
$this->assertEqual(count($messages), 3);
$last_message = end($messages);
$this->assertEqual($last_message->message, 'Translation for @key reverted to the latest version.');
// There should be three revisions now.
$this->assertEqual(count($data['#translation']['#text_revisions']), 3);
// Attempt to update the translation with the same text, this should not
// lead to a new revision.
$translation['dummy']['deep_nesting']['#text'] = 'translated 3';
//unset($translation['dummy']['deep_nesting']['#origin']);
//unset($translation['dummy']['deep_nesting']['#timestamp']);
$item1->addTranslatedData($translation);
$data = $item1->getData($key);
$this->assertEqual(count($data['#translation']['#text_revisions']), 3);
// Mark the translation as reviewed, a new translation should not update the
// existing one but create a new translation.
$item1->updateData($key, array('#status' => TMGMT_DATA_ITEM_STATE_REVIEWED));
$translation['dummy']['deep_nesting']['#text'] = 'translated 4';
$item1->addTranslatedData($translation);
$data = $item1->getData($key);
// The translation text is NOT updated.
$this->assertEqual($data['#translation']['#text'], 'translated 3');
// Received translation is the latest revision.
$this->assertEqual(count($data['#translation']['#text_revisions']), 4);
$last_revision = end($data['#translation']['#text_revisions']);
$this->assertEqual($last_revision['#text'], 'translated 4');
$this->assertEqual($last_revision['#origin'], 'remote');
$this->assertEqual($last_revision['#timestamp'], REQUEST_TIME);
// Check job messages.
$messages = $job->getMessages();
$this->assertEqual(count($messages), 4);
$last_message = end($messages);
$this->assertEqual($last_message->message, 'Translation for already reviewed @key received and stored as a new revision. Revert to it if you wish to use it.');
}
/**
* Test the calculations of the counters.
*/
function testJobItemsCounters() {
$job = $this->createJob();
// Some test data items.
$data1 = array(
'#text' => 'The text to be translated.',
);
$data2 = array(
'#text' => 'The text to be translated.',
'#translation' => '',
);
$data3 = array(
'#text' => 'The text to be translated.',
'#translation' => 'The translated data. Set by the translator plugin.',
);
$data4 = array(
'#text' => 'Another, longer text to be translated.',
'#translation' => 'The translated data. Set by the translator plugin.',
'#status' => TMGMT_DATA_ITEM_STATE_REVIEWED,
);
$data5 = array(
'#label' => 'label',
'data1' => $data1,
'data4' => $data4,
);
// No data items.
$this->assertEqual(0, $job->getCountPending());
$this->assertEqual(0, $job->getCountTranslated());
$this->assertEqual(0, $job->getCountReviewed());
$this->assertEqual(0, $job->getCountAccepted());
$this->assertEqual(0, $job->getWordCount());
// Add a test items.
$job_item1 = tmgmt_job_item_create('plugin', 'type', 4, array('tjid' => $job->tjid));
$job_item1->save();
// No pending, translated and confirmed data items.
$job = entity_load_single('tmgmt_job', $job->tjid);
$job_item1 = entity_load_single('tmgmt_job_item', $job_item1->tjiid);
drupal_static_reset('tmgmt_job_statistics_load');
$this->assertEqual(0, $job_item1->getCountPending());
$this->assertEqual(0, $job_item1->getCountTranslated());
$this->assertEqual(0, $job_item1->getCountReviewed());
$this->assertEqual(0, $job_item1->getCountAccepted());
$this->assertEqual(0, $job->getCountPending());
$this->assertEqual(0, $job->getCountTranslated());
$this->assertEqual(0, $job->getCountReviewed());
$this->assertEqual(0, $job->getCountAccepted());
// Add an untranslated data item.
$job_item1->data['data_item1'] = $data1;
$job_item1->save();
// One pending data items.
$job = entity_load_single('tmgmt_job', $job->tjid);
$job_item1 = entity_load_single('tmgmt_job_item', $job_item1->tjiid);
drupal_static_reset('tmgmt_job_statistics_load');
$this->assertEqual(1, $job_item1->getCountPending());
$this->assertEqual(0, $job_item1->getCountTranslated());
$this->assertEqual(0, $job_item1->getCountReviewed());
$this->assertEqual(5, $job_item1->getWordCount());
$this->assertEqual(1, $job->getCountPending());
$this->assertEqual(0, $job->getCountReviewed());
$this->assertEqual(0, $job->getCountTranslated());
$this->assertEqual(5, $job->getWordCount());
// Add another untranslated data item.
// Test with an empty translation set.
$job_item1->data['data_item1'] = $data2;
$job_item1->save();
// One pending data items.
$job = entity_load_single('tmgmt_job', $job->tjid);
$job_item1 = entity_load_single('tmgmt_job_item', $job_item1->tjiid);
drupal_static_reset('tmgmt_job_statistics_load');
$this->assertEqual(1, $job_item1->getCountPending());
$this->assertEqual(0, $job_item1->getCountTranslated());
$this->assertEqual(0, $job_item1->getCountReviewed());
$this->assertEqual(5, $job_item1->getWordCount());
$this->assertEqual(1, $job->getCountPending());
$this->assertEqual(0, $job->getCountTranslated());
$this->assertEqual(0, $job->getCountReviewed());
$this->assertEqual(5, $job->getWordCount());
// Add a translated data item.
$job_item1->data['data_item1'] = $data3;
$job_item1->save();
// One translated data items.
drupal_static_reset('tmgmt_job_statistics_load');
$this->assertEqual(0, $job_item1->getCountPending());
$this->assertEqual(1, $job_item1->getCountTranslated());
$this->assertEqual(0, $job_item1->getCountReviewed());
$this->assertEqual(0, $job->getCountPending());
$this->assertEqual(0, $job->getCountReviewed());
$this->assertEqual(1, $job->getCountTranslated());
// Add a confirmed data item.
$job_item1->data['data_item1'] = $data4;
$job_item1->save();
// One reviewed data item.
drupal_static_reset('tmgmt_job_statistics_load');
$this->assertEqual(1, $job_item1->getCountReviewed());
$this->assertEqual(1, $job->getCountReviewed());
// Add a translated and an untranslated and a confirmed data item
$job = entity_load_single('tmgmt_job', $job->tjid);
$job_item1 = entity_load_single('tmgmt_job_item', $job_item1->tjiid);
$job_item1->data['data_item1'] = $data1;
$job_item1->data['data_item2'] = $data3;
$job_item1->data['data_item3'] = $data4;
$job_item1->save();
// One pending and translated data items each.
drupal_static_reset('tmgmt_job_statistics_load');
$this->assertEqual(1, $job->getCountPending());
$this->assertEqual(1, $job->getCountTranslated());
$this->assertEqual(1, $job->getCountReviewed());
$this->assertEqual(16, $job->getWordCount());
// Add nested data items.
$job_item1->data['data_item1'] = $data5;
$job_item1->save();
// One pending data items.
$job = entity_load_single('tmgmt_job', $job->tjid);
$job_item1 = entity_load_single('tmgmt_job_item', $job_item1->tjiid);
$this->assertEqual('label', $job_item1->data['data_item1']['#label']);
$this->assertEqual(3, count($job_item1->data['data_item1']));
// Add a greater number of data items
for ($index = 1; $index <= 3; $index++) {
$job_item1->data['data_item' . $index] = $data1;
}
for ($index = 4; $index <= 10; $index++) {
$job_item1->data['data_item' . $index] = $data3;
}
for ($index = 11; $index <= 15; $index++) {
$job_item1->data['data_item' . $index] = $data4;
}
$job_item1->save();
// 3 pending and 7 translated data items each.
$job = entity_load_single('tmgmt_job', $job->tjid);
drupal_static_reset('tmgmt_job_statistics_load');
$this->assertEqual(3, $job->getCountPending());
$this->assertEqual(7, $job->getCountTranslated());
$this->assertEqual(5, $job->getCountReviewed());
// Add several job items
$job_item2 = tmgmt_job_item_create('plugin', 'type', 5, array('tjid' => $job->tjid));
for ($index = 1; $index <= 4; $index++) {
$job_item2->data['data_item' . $index] = $data1;
}
for ($index = 5; $index <= 12; $index++) {
$job_item2->data['data_item' . $index] = $data3;
}
for ($index = 13; $index <= 16; $index++) {
$job_item2->data['data_item' . $index] = $data4;
}
$job_item2->save();
// 3 pending and 7 translated data items each.
$job = entity_load_single('tmgmt_job', $job->tjid);
drupal_static_reset('tmgmt_job_statistics_load');
$this->assertEqual(7, $job->getCountPending());
$this->assertEqual(15, $job->getCountTranslated());
$this->assertEqual(9, $job->getCountReviewed());
// Accept the job items.
foreach ($job->getItems() as $item) {
// Set the state directly to avoid triggering translator and source
// controllers that do not exist.
$item->setState(TMGMT_JOB_ITEM_STATE_ACCEPTED);
$item->save();
}
drupal_static_reset('tmgmt_job_statistics_load');
$this->assertEqual(0, $job->getCountPending());
$this->assertEqual(0, $job->getCountTranslated());
$this->assertEqual(0, $job->getCountReviewed());
$this->assertEqual(31, $job->getCountAccepted());
}
}

View File

@@ -0,0 +1,123 @@
<?php
/*
* @file
* Contains tests for Translation management
*/
/**
* Test the helper functions in tmgmt.module.
*/
class TMGMTHelperTestCase extends TMGMTBaseTestCase {
static function getInfo() {
return array(
'name' => 'Helper functions Test case',
'description' => 'Helper functions for other modules',
'group' => 'Translation Management',
);
}
/**
* Tests tmgmt_job_match_item()
*
* @see tmgmt_job_match_item
*/
function testTMGTJobMatchItem() {
$this->loginAsAdmin();
$this->setEnvironment('fr');
$this->setEnvironment('es');
// Add a job from en to fr and en to sp.
$job_en_fr = $this->createJob('en', 'fr');
$job_en_sp = $this->createJob('en', 'es');
// Add a job which has existing source-target combinations.
$this->assertEqual($job_en_fr->tjid, tmgmt_job_match_item('en', 'fr')->tjid);
$this->assertEqual($job_en_sp->tjid, tmgmt_job_match_item('en', 'es')->tjid);
// Add a job which has no existing source-target combination.
$this->assertTrue(tmgmt_job_match_item('fr', 'es'));
}
/**
* Tests the tmgmt_data_item_label() function.
*
* @todo: Move into a unit test case once available.
*/
function testDataIemLabel() {
$no_label = array(
'#text' => 'No label',
);
$this->assertEqual(tmgmt_data_item_label($no_label), 'No label');
$this->assertEqual(tmgmt_data_item_label($no_label, 6), 'No ...');
$label = array(
'#parent_label' => array(),
'#label' => 'A label',
);
$this->assertEqual(tmgmt_data_item_label($label), 'A label');
$this->assertEqual(tmgmt_data_item_label($label, 6), 'A l...');
$parent_label = array(
'#parent_label' => array('Parent label', 'Sub label'),
'#label' => 'A label',
);
$this->assertEqual(tmgmt_data_item_label($parent_label), 'Parent label > Sub label');
$this->assertEqual(tmgmt_data_item_label($parent_label, 18), 'Pare... > Sub ...');
$nested = array(
'#parent_label' => array('Parent label', 'Sub label', 'Sub-sub label'),
'#label' => 'A label',
);
$this->assertEqual(tmgmt_data_item_label($nested), 'Parent label > Sub label > Sub-sub label');
$this->assertEqual(tmgmt_data_item_label($nested, 28), 'Pare... > Sub ... > Sub-...');
$long_label = array(
'#parent_label' => array('Loooooooooooong label', 'Short'),
'#label' => 'A label',
);
$this->assertEqual(tmgmt_data_item_label($long_label), 'Loooooooooooong label > Short');
$this->assertEqual(tmgmt_data_item_label($long_label, 30), 'Loooooooooooong label > Short');
$node_example = array(
'#parent_label' => array('This is a very loooong title, so looong', 'Body', 'Delta #0', 'Body'),
'#label' => 'A label',
);
$this->assertEqual(tmgmt_data_item_label($node_example), 'This is a very loooong title, so looong > Body > Delta #0 > Body');
$this->assertEqual(tmgmt_data_item_label($node_example, 56), 'This is a very loooong title... > Body > Delta #0 > Body');
}
function testWordCount() {
$unit_tests = array(
'empty' => array(
'text' => '',
'count' => 0,
),
'latin' => array(
'text' => 'Drupal is the best!',
'count' => 4,
),
'non-latin' => array(
'text' => 'Друпал лучший!',
'count' => 2,
),
'complex punctuation' => array(
'text' => '<[({-!ReAd@*;: ,?+MoRe...})]>\\|/',
'count' => 2,
'exclude_tags' => FALSE,
),
'repeat' => array(
'text' => 'repeat repeat',
'count' => 2,
),
'strip tags' => array(
'text' => '<a href="http://example.com">link text</a> plain text <div class="some-css-class"></div>',
'count' => 4,
),
);
foreach ($unit_tests as $id => $test_data) {
// Set the exclude_tags flag. In case not provided the TRUE is default.
$test_data += array('exclude_tags' => TRUE);
if (variable_get('tmgmt_word_count_exclude_tags', TRUE) != $test_data['exclude_tags']) {
variable_set('tmgmt_word_count_exclude_tags', $test_data['exclude_tags']);
}
$this->assertEqual($real_count = tmgmt_word_count($test_data['text']), $desirable_count = $test_data['count'], t('!test_id: Real count (=!real_count) should be equal to desirable (=!desirable_count)', array('!test_id' => $id, '!real_count' => $real_count, '!desirable_count' => $desirable_count)));
}
}
}

View File

@@ -0,0 +1,230 @@
<?php
/*
* @file
* Contains tests for Translation management
*/
/**
* Tests interaction between core and the plugins.
*/
class TMGMTPluginsTestCase extends TMGMTBaseTestCase {
static function getInfo() {
return array(
'name' => 'Plugin tests',
'description' => 'Verifies basic functionality of source and translator plugins',
'group' => 'Translation Management',
);
}
function createJob($source = 'en', $target = 'de', $uid = 1) {
$job = parent::createJob();
for ($i = 1; $i < 3; $i++) {
if ($i == 3) {
// Explicitly define the data for the third item.
$data['data'] = array(
'dummy' => array(
'deep_nesting' => array(
'#text' => 'Stored data',
),
),
);
$job->addItem('test_source', 'test', $i, array($data));
}
$job->addItem('test_source', 'test', $i);
}
// Manually specify the translator for now.
$job->translator = $this->default_translator->name;
return $job;
}
function testBasicWorkflow() {
// Submit a translation job.
$submit_job = $this->createJob();
$submit_job->settings = array('action' => 'submit');
$submit_job->requestTranslation();
$submit_job = tmgmt_job_load($submit_job->tjid);
$this->assertTrue($submit_job->isActive());
$messages = $submit_job->getMessages();
$last_message = end($messages);
$this->assertEqual('Test submit.', $last_message->message);
// Translate a job.
$translate_job = $this->createJob();
$translate_job->settings = array('action' => 'translate');
$translate_job->requestTranslation();
$translate_job = tmgmt_job_load($translate_job->tjid);
foreach ($translate_job->getItems() as $job_item) {
$this->assertTrue($job_item->isNeedsReview());
}
$messages = $translate_job->getMessages();
// array_values() results in numeric keys, which is necessary for list.
list($debug, $translated, $needs_review) = array_values($messages);
$this->assertEqual('Test translator called.', $debug->message);
$this->assertEqual('debug', $debug->type);
$this->assertEqual('Test translation created.', $translated->message);
$this->assertEqual('status', $translated->type);
// The third message is specific to a job item and has different state
// constants.
$this->assertEqual('The translation of !source to @language is finished and can now be <a href="!review_url">reviewed</a>.', $needs_review->message);
$this->assertEqual('status', $needs_review->type);
$i = 1;
foreach ($translate_job->getItems() as $item) {
// Check the translated text.
if ($i != 3) {
$expected_text = 'de_Text for job item with type ' . $item->item_type . ' and id ' . $item->item_id . '.';
}
else {
// The third item has an explicitly stored data value.
$expected_text = 'de_Stored data';
}
$item_data = $item->getData();
$this->assertEqual($expected_text, $item_data['dummy']['deep_nesting']['#translation']['#text']);
$i++;
}
foreach ($translate_job->getItems() as $job_item) {
$job_item->acceptTranslation();
}
// @todo Accepting does not result in messages on the job anymore.
// Update once there are job item messages.
/*
$messages = $translate_job->getMessages();
$last_message = end($messages);
$this->assertEqual('Job accepted', $last_message->message);
$this->assertEqual('status', $last_message->type);*/
// Check if the translations have been "saved".
foreach ($translate_job->getItems() as $item) {
$this->assertTrue(variable_get('tmgmt_test_saved_translation_' . $item->item_type . '_' . $item->item_id, FALSE));
}
// A rejected job.
$reject_job = $this->createJob();
$reject_job->settings = array('action' => 'reject');
$reject_job->requestTranslation();
// Still rejected.
$this->assertTrue($reject_job->isRejected());
$messages = $reject_job->getMessages();
$last_message = end($messages);
$this->assertEqual('This is not supported.', $last_message->message);
$this->assertEqual('error', $last_message->type);
// A failing job.
$failing_job = $this->createJob();
$failing_job->settings = array('action' => 'fail');
$failing_job->requestTranslation();
// Still new.
$this->assertTrue($failing_job->isUnprocessed());
$messages = $failing_job->getMessages();
$last_message = end($messages);
$this->assertEqual('Service not reachable.', $last_message->message);
$this->assertEqual('error', $last_message->type);
}
/**
* Tests remote languages mappings support in the tmgmt core.
*/
function testRemoteLanguagesMappings() {
$this->loginAsAdmin();
$this->setEnvironment('de');
$controller = $this->default_translator->getController();
$mappings = $controller->getRemoteLanguagesMappings($this->default_translator);
$this->assertEqual($mappings, array(
'en' => 'en-us',
'de' => 'de-ch',
));
$this->assertEqual($controller->mapToRemoteLanguage($this->default_translator, 'en'), 'en-us');
$this->assertEqual($controller->mapToRemoteLanguage($this->default_translator, 'de'), 'de-ch');
$this->assertEqual($controller->mapToLocalLanguage($this->default_translator, 'en-us'), 'en');
$this->assertEqual($controller->mapToLocalLanguage($this->default_translator, 'de-ch'), 'de');
$this->default_translator->settings['remote_languages_mappings']['de'] = 'de-de';
$this->default_translator->settings['remote_languages_mappings']['en'] = 'en-uk';
$this->default_translator->save();
$this->assertEqual($controller->mapToRemoteLanguage($this->default_translator, 'en'), 'en-uk');
$this->assertEqual($controller->mapToRemoteLanguage($this->default_translator, 'de'), 'de-de');
// Test the fallback.
$info = &drupal_static('_tmgmt_plugin_info');
$info['translator']['test_translator']['map remote languages'] = FALSE;
$this->assertEqual($controller->mapToRemoteLanguage($this->default_translator, 'en'), 'en');
$this->assertEqual($controller->mapToRemoteLanguage($this->default_translator, 'de'), 'de');
}
/**
* Tests escaping and unescaping text.
*/
function testEscaping() {
$controller = $this->default_translator->getController();
$tests = array(
array(
'item' => array('#text' => 'no escaping'),
'expected' => 'no escaping',
),
array(
'item' => array(
'#text' => 'single placeholder',
'#escape' => array(
7 => array('string' => 'placeholder'),
),
),
'expected' => 'single [[[placeholder]]]',
),
array(
'item' => array(
'#text' => 'two placeholder, the second placeholder',
'#escape' => array(
4 => array('string' => 'placeholder'),
28 => array('string' => 'placeholder'),
),
),
'expected' => 'two [[[placeholder]]], the second [[[placeholder]]]',
),
array(
'item' => array(
'#text' => 'something, something else',
'#escape' => array(
0 => array('string' => 'something'),
21 => array('string' => 'else'),
),
),
'expected' => '[[[something]]], something [[[else]]]',
),
array(
'item' => array(
'#text' => 'something, something else',
'#escape' => array(
21 => array('string' => 'else'),
11 => array('string' => 'something'),
),
),
'expected' => 'something, [[[something]]] [[[else]]]',
),
);
foreach ($tests as $test) {
$escaped = $controller->escapeText($test['item']);
// Assert that the string was escaped as expected.
$this->assertEqual($escaped, $test['expected']);
// Assert that the string is the same as the original when unescaped.
$this->assertEqual($controller->unescapeText($escaped), $test['item']['#text']);
}
}
}

View File

@@ -0,0 +1,159 @@
<?php
/*
* @file
* Contains tests for Translation management
*/
/**
* Upgrade tests.
*/
class TMGMTUpgradeAlpha1TestCase extends DrupalWebTestCase {
protected $profile = 'testing';
static function getInfo() {
return array(
'name' => t('Upgrade tests Alpha1'),
'description' => t('Tests the upgrade path from 7.x-1.0-alpha1'),
'group' => t('Translation Management'),
);
}
function setUp() {
// Enable all dependencies.
parent::setUp(array('entity', 'views', 'translation', 'locale'));
// Create the tmgmt tables and fill them.
module_load_include('inc', 'tmgmt', 'tests/tmgmt_alpha1_dump.sql');
// @todo: Figure out why this is necessary.
$enabled_modules = db_query("SELECT name FROM {system} where status = 1 and type = 'module'")->fetchCol();
foreach ($enabled_modules as $enabled_module) {
module_load_install($enabled_module);
// Set the schema version to the number of the last update provided
// by the module.
$versions = drupal_get_schema_versions($enabled_module);
$version = $versions ? max($versions) : SCHEMA_INSTALLED;
db_update('system')
->condition('name', $enabled_module)
->fields(array('schema_version' => $version))
->execute();
}
// Set schema version to 0 and then install the tmgmt modules, to simulate
// an enabling.
db_update('system')
->condition('name', array('tmgmt', 'tmgmt_ui', 'tmgmt_field', 'tmgmt_node', 'tmgmt_test', 'tmgmt_node_ui'))
->fields(array(
'schema_version' => 0,
))
->execute();
module_enable(array('tmgmt', 'tmgmt_ui', 'tmgmt_field', 'tmgmt_node', 'tmgmt_test', 'tmgmt_node_ui'));
// Log in as a user that can run update.php
$admin = $this->drupalCreateUser(array('administer software updates'));
$this->drupalLogin($admin);
$this->performUpgrade();
}
/**
* Verifies that the data has been migrated properly
*/
function testUpgradePath() {
// Log in as a user with enough permissions.
$translator = $this->drupalCreateUser(array('administer tmgmt'));
$this->drupalLogin($translator);
// Go to a job and check the review form.
$this->drupalGet('admin/tmgmt/jobs/1');
// Make sure the #status values have been set accordingly.
$this->assertRaw(t('Accepted: @accepted, reviewed: @reviewed, translated: @translated, pending: @pending.', array('@accepted' => 0, '@reviewed' => 0, '@translated' => 2, '@pending' => 0)));
// Extract the word count field and make sure it's correct.
$word_count = $this->xpath('//td[contains(@class, :class)]', array(':class' => 'views-field-word-count-1'));
$this->assertEqual(6, trim((string)reset($word_count)));
$this->clickLink(t('review'));
// Needs review icon.
$this->assertRaw('tmgmt-ui-icon-yellow tmgmt-ui-state-translated');
// Translated values.
$this->assertRaw('de_Test content');
$this->assertRaw('de_This is the body.');
// Reject button.
$this->assertRaw('✗');
// Check that accepted count has been updated correctly.
$this->drupalGet('admin/tmgmt/jobs/2');
// Make sure the #status values have been set accordingly.
$this->assertRaw(t('Accepted: @accepted, reviewed: @reviewed, translated: @translated, pending: @pending.', array('@accepted' => 2, '@reviewed' => 0, '@translated' => 0, '@pending' => 0)));
}
/**
* Perform the upgrade.
*
* Copied and adapted from UpgradePathTestCase::performUpgrade().
*
* @param $register_errors
* Register the errors during the upgrade process as failures.
* @return
* TRUE if the upgrade succeeded, FALSE otherwise.
*/
protected function performUpgrade($register_errors = TRUE) {
$update_url = $GLOBALS['base_url'] . '/update.php';
// Load the first update screen.
$this->drupalGet($update_url, array('external' => TRUE));
if (!$this->assertResponse(200)) {
return FALSE;
}
// Continue.
$this->drupalPost(NULL, array(), t('Continue'));
if (!$this->assertResponse(200)) {
return FALSE;
}
// The test should pass if there are no pending updates.
$content = $this->drupalGetContent();
if (strpos($content, t('No pending updates.')) !== FALSE) {
$this->pass(t('No pending updates and therefore no upgrade process to test.'));
$this->pendingUpdates = FALSE;
return TRUE;
}
// Go!
$this->drupalPost(NULL, array(), t('Apply pending updates'));
if (!$this->assertResponse(200)) {
return FALSE;
}
// Check for errors during the update process.
foreach ($this->xpath('//li[@class=:class]', array(':class' => 'failure')) as $element) {
$message = strip_tags($element->asXML());
$this->upgradeErrors[] = $message;
if ($register_errors) {
$this->fail($message);
}
}
if (!empty($this->upgradeErrors)) {
// Upgrade failed, the installation might be in an inconsistent state,
// don't process.
return FALSE;
}
// Check if there still are pending updates.
$this->drupalGet($update_url, array('external' => TRUE));
$this->drupalPost(NULL, array(), t('Continue'));
if (!$this->assertText(t('No pending updates.'), t('No pending updates at the end of the update process.'))) {
return FALSE;
}
// Clear caches.
$this->checkPermissions(array(), TRUE);
}
}

View File

@@ -0,0 +1,463 @@
<?php
/**
* @file
* Filled installation of TMGMT 7.x-1.0-alpha1, for test purposes.
*
* This file was generated by the dump-database-d7.sh tool, from an
* installation of Drupal 7, filled with data using the generate-d7-content.sh
* tool. It has the following modules installed:
* - tmgmt
* - tmgmt_field
* - tmgmt_node
* - tmgmt_node_ui
* - tmgmt_test
* - tmgmt_ui
*/
db_create_table('cache_tmgmt', array(
'fields' => array(
'cid' => array(
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
),
'data' => array(
'type' => 'blob',
'not null' => FALSE,
'size' => 'big',
),
'expire' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
),
'created' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
),
'serialized' => array(
'type' => 'int',
'size' => 'small',
'not null' => TRUE,
'default' => 0,
),
),
'indexes' => array(
'expire' => array(
'expire',
),
),
'primary key' => array(
'cid',
),
'module' => 'tmgmt',
'name' => 'cache_tmgmt',
));
db_create_table('tmgmt_job', array(
'fields' => array(
'tjid' => array(
'type' => 'serial',
'not null' => TRUE,
),
'source_language' => array(
'type' => 'varchar',
'length' => 12,
'not null' => TRUE,
),
'target_language' => array(
'type' => 'varchar',
'length' => 12,
'not null' => TRUE,
),
'state' => array(
'type' => 'int',
'not null' => TRUE,
),
'created' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
),
'changed' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
),
'translator' => array(
'type' => 'varchar',
'length' => 128,
),
'settings' => array(
'type' => 'text',
'size' => 'big',
'serialize' => TRUE,
),
'reference' => array(
'type' => 'varchar',
'length' => 256,
),
'uid' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
),
'label' => array(
'type' => 'varchar',
'length' => 256,
),
),
'primary key' => array(
'tjid',
),
'indexes' => array(
'state' => array(
'state',
),
'reference' => array(
'reference',
),
),
'module' => 'tmgmt',
'name' => 'tmgmt_job',
));
db_insert('tmgmt_job')->fields(array(
'tjid',
'source_language',
'target_language',
'state',
'created',
'changed',
'translator',
'settings',
'reference',
'uid',
'label',
))
->values(array(
'tjid' => '1',
'source_language' => 'en',
'target_language' => 'de',
'state' => '1',
'created' => '1342074121',
'changed' => '1342074125',
'translator' => 'test_translator',
'settings' => 'a:1:{s:6:"action";s:9:"translate";}',
'reference' => NULL,
'uid' => '1',
'label' => '',
))
->values(array(
'tjid' => '2',
'source_language' => 'en',
'target_language' => 'es',
'state' => '5',
'created' => '1342074121',
'changed' => '1342074127',
'translator' => 'test_translator',
'settings' => 'a:1:{s:6:"action";s:9:"translate";}',
'reference' => NULL,
'uid' => '1',
'label' => '',
))
->execute();
db_create_table('tmgmt_job_item', array(
'fields' => array(
'tjiid' => array(
'type' => 'serial',
'not null' => TRUE,
),
'tjid' => array(
'type' => 'int',
'not null' => TRUE,
'unsigned' => TRUE,
),
'plugin' => array(
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
),
'item_type' => array(
'type' => 'varchar',
'length' => 128,
),
'item_id' => array(
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
),
'state' => array(
'type' => 'int',
'not null' => TRUE,
),
'data' => array(
'type' => 'text',
'not null' => TRUE,
'size' => 'big',
'serialize' => TRUE,
),
'translation' => array(
'type' => 'text',
'not null' => TRUE,
'size' => 'big',
'serialize' => TRUE,
),
'changed' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
),
),
'primary key' => array(
'tjiid',
),
'indexes' => array(
'job_id' => array(
'tjid',
),
),
'foreign keys' => array(
'job' => array(
'table' => 'tmgmt_job',
'columns' => array(
'tjid',
),
),
),
'module' => 'tmgmt',
'name' => 'tmgmt_job_item',
));
db_insert('tmgmt_job_item')->fields(array(
'tjiid',
'tjid',
'plugin',
'item_type',
'item_id',
'state',
'data',
'translation',
'changed',
))
->values(array(
'tjiid' => '1',
'tjid' => '1',
'plugin' => 'node',
'item_type' => 'node',
'item_id' => '1',
'state' => '2',
'data' => 'a:3:{s:6:"#label";s:7:"Article";s:10:"node_title";a:2:{s:6:"#label";s:5:"Title";s:5:"#text";s:12:"Test content";}s:4:"body";a:2:{s:6:"#label";s:4:"Body";i:0;a:2:{s:6:"#label";s:8:"Delta #0";s:5:"value";a:3:{s:6:"#label";s:4:"Body";s:5:"#text";s:17:"This is the body.";s:10:"#translate";b:1;}}}}',
'translation' => 'a:2:{s:10:"node_title";a:2:{s:6:"#label";s:5:"Title";s:5:"#text";s:15:"de_Test content";}s:4:"body";a:1:{i:0;a:1:{s:5:"value";a:3:{s:6:"#label";s:4:"Body";s:5:"#text";s:20:"de_This is the body.";s:10:"#translate";b:1;}}}}',
'changed' => '1342074125',
))
->values(array(
'tjiid' => '2',
'tjid' => '2',
'plugin' => 'node',
'item_type' => 'node',
'item_id' => '1',
'state' => '3',
'data' => 'a:3:{s:6:"#label";s:7:"Article";s:10:"node_title";a:2:{s:6:"#label";s:5:"Title";s:5:"#text";s:12:"Test content";}s:4:"body";a:2:{s:6:"#label";s:4:"Body";i:0;a:2:{s:6:"#label";s:8:"Delta #0";s:5:"value";a:3:{s:6:"#label";s:4:"Body";s:5:"#text";s:17:"This is the body.";s:10:"#translate";b:1;}}}}',
'translation' => 'a:2:{s:10:"node_title";a:2:{s:6:"#label";s:5:"Title";s:5:"#text";s:15:"es_Test content";}s:4:"body";a:1:{i:0;a:1:{s:5:"value";a:3:{s:6:"#label";s:4:"Body";s:5:"#text";s:20:"es_This is the body.";s:10:"#translate";b:1;}}}}',
'changed' => '1342074127',
))
->execute();
db_create_table('tmgmt_message', array(
'fields' => array(
'mid' => array(
'type' => 'serial',
'not null' => TRUE,
),
'tjid' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
),
'tjiid' => array(
'type' => 'int',
'unsigned' => TRUE,
),
'message' => array(
'type' => 'text',
'size' => 'big',
),
'variables' => array(
'type' => 'text',
'size' => 'big',
'serialize' => TRUE,
),
'created' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
),
'type' => array(
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
),
),
'primary key' => array(
'mid',
),
'indexes' => array(
'tjid' => array(
'tjid',
),
'tjiid' => array(
'tjiid',
),
),
'module' => 'tmgmt',
'name' => 'tmgmt_message',
));
db_insert('tmgmt_message')->fields(array(
'mid',
'tjid',
'tjiid',
'message',
'variables',
'created',
'type',
))
->values(array(
'mid' => '1',
'tjid' => '1',
'tjiid' => NULL,
'message' => 'Test translator called.',
'variables' => 'a:0:{}',
'created' => '1342074125',
'type' => 'debug',
))
->values(array(
'mid' => '2',
'tjid' => '1',
'tjiid' => NULL,
'message' => 'Test translation created.',
'variables' => 'a:0:{}',
'created' => '1342074125',
'type' => 'status',
))
->values(array(
'mid' => '3',
'tjid' => '1',
'tjiid' => '1',
'message' => 'The translation for !source is finished and can now be reviewed.',
'variables' => 'a:1:{s:7:"!source";s:34:"<a href="/node/1">Test content</a>";}',
'created' => '1342074125',
'type' => 'status',
))
->values(array(
'mid' => '4',
'tjid' => '2',
'tjiid' => NULL,
'message' => 'Test translator called.',
'variables' => 'a:0:{}',
'created' => '1342074127',
'type' => 'debug',
))
->values(array(
'mid' => '5',
'tjid' => '2',
'tjiid' => NULL,
'message' => 'Test translation created.',
'variables' => 'a:0:{}',
'created' => '1342074127',
'type' => 'status',
))
->values(array(
'mid' => '6',
'tjid' => '2',
'tjiid' => '2',
'message' => 'The translation for !source is finished and can now be reviewed.',
'variables' => 'a:1:{s:7:"!source";s:34:"<a href="/node/1">Test content</a>";}',
'created' => '1342074127',
'type' => 'status',
))
->execute();
db_create_table('tmgmt_translator', array(
'fields' => array(
'tid' => array(
'type' => 'serial',
'not null' => TRUE,
),
'name' => array(
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
),
'label' => array(
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
),
'description' => array(
'type' => 'text',
'size' => 'medium',
),
'plugin' => array(
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
),
'settings' => array(
'type' => 'text',
'size' => 'big',
'serialize' => TRUE,
),
'weight' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
),
'status' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 1,
'size' => 'tiny',
),
'module' => array(
'type' => 'varchar',
'length' => 255,
'not null' => FALSE,
),
),
'primary key' => array(
'tid',
),
'unique keys' => array(
'name' => array(
'name',
),
),
'module' => 'tmgmt',
'name' => 'tmgmt_translator',
));
db_insert('tmgmt_translator')->fields(array(
'tid',
'name',
'label',
'description',
'plugin',
'settings',
'weight',
'status',
'module',
))
->values(array(
'tid' => '1',
'name' => 'test_translator',
'label' => 'Test translator (auto created)',
'description' => 'Simple translator for testing purposes.',
'plugin' => 'test_translator',
'settings' => 'a:2:{s:11:"auto_accept";b:0;s:15:"expose_settings";b:1;}',
'weight' => '0',
'status' => '1',
'module' => NULL,
))
->execute();

View File

@@ -0,0 +1,16 @@
name = Translation Management Test plugins
package = Translation Management
core = 7.x
hidden = TRUE
dependencies[] = tmgmt
files[] = tmgmt_test.plugin.source.inc
files[] = tmgmt_test.plugin.html_source.inc
files[] = tmgmt_test.plugin.translator.inc
files[] = tmgmt_test.ui.translator.inc
; Information added by Drupal.org packaging script on 2016-09-21
version = "7.x-1.0-rc2+1-dev"
core = "7.x"
project = "tmgmt"
datestamp = "1474446494"

View File

@@ -0,0 +1,93 @@
<?php
/**
* @file
* Module file of the translation management test module.
*/
/**
* Implements hook_tmgmt_translator_plugin_info().
*/
function tmgmt_test_tmgmt_translator_plugin_info() {
return array(
'test_translator' => array(
'label' => t('Test translator'),
'description' => t('Simple translator for testing purposes.'),
'plugin controller class' => 'TMGMTTestTranslatorPluginController',
'ui controller class' => 'TMGMTTestTranslatorUIController',
'default settings' => array(
'expose_settings' => TRUE,
),
),
);
}
/**
* Implements hook_tmgmt_source_plugin_info().
*/
function tmgmt_test_tmgmt_source_plugin_info() {
return array(
'test_source' => array(
'label' => t('Test source'),
'description' => t('Simple source for testing purposes.'),
'plugin controller class' => 'TMGMTTestSourcePluginController',
),
'test_html_source' => array(
'label' => t('Test html source'),
'description' => t('HTML source for testing purposes.'),
'plugin controller class' => 'TMGMTTestHTMLSourcePluginController',
),
);
}
/**
* Implements hook_tmgmt_source_suggestions().
*/
function tmgmt_test_tmgmt_source_suggestions(array $items, TMGMTJob $job) {
$suggestions = array();
foreach ($items as $item) {
if ($item->plugin == 'test_source') {
$suggestions[] = array(
'job_item' => tmgmt_job_item_create('test_source', $item->item_type . '_suggestion', $item->item_id),
'reason' => t('Test suggestion for @type source @id', array('@type' => $item->item_type,'@id' => $item->item_id)),
'from_item' => $item->tjiid,
);
}
}
return $suggestions;
}
/**
* Implements hook_tmgmt_fle_text_processor_plugin_info().
*/
function tmgmt_test_tmgmt_file_text_processor_plugin_info() {
return array(
'test' => array(
'label' => t('Test'),
'plugin controller class' => 'TMGMTTestTextProcessor',
),
);
}
/**
* Implements hook_menu().
*/
function tmgmt_test_menu() {
$items['tmgmt-add-to-cart/%tmgmt_job_item'] = array(
'title' => 'Add to cart',
'description' => 'Provides the possibility to add testing job items into the cart.',
'page callback' => 'tmgmt_test_add_to_cart',
'page arguments' => array(1),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Callback to add given job item into the cart.
*/
function tmgmt_test_add_to_cart(TMGMTJobITem $job_item) {
tmgmt_ui_cart_get()->addExistingJobItems(array($job_item));
}

View File

@@ -0,0 +1,23 @@
<?php
/**
* @file
* Contains the test source plugin with html.
*/
class TMGMTTestHTMLSourcePluginController extends TMGMTTestSourcePluginController {
/**
* {@inheritdoc}
*/
public function getData(TMGMTJobItem $job_item) {
return array(
'dummy' => array(
'deep_nesting' => array(
'#text' => file_get_contents(drupal_get_path('module', 'tmgmt') . '/tests/testing_html/sample.html'),
'#label' => 'Label for job item with type ' . $job_item->item_type . ' and id ' . $job_item->item_id . '.',
),
),
);
}
}

View File

@@ -0,0 +1,111 @@
<?php
/**
* @file
* Contains the test source plugin.
*/
class TMGMTTestSourcePluginController extends TMGMTDefaultSourcePluginController {
/**
* {@inheritdoc}
*/
public function getUri(TMGMTJobItem $job_item) {
// Provide logic which allows to test for source which is either accessible
// or not accessible to anonymous user. This is may then be used to test if
// the source url is attached to the job comment sent to a translation
// service.
$path = 'node';
if ($job_item->item_type == 'test_not_accessible') {
$path = 'admin';
}
return array('path' => $path, 'options' => array());
}
/**
* {@inheritdoc}
*/
public function getLabel(TMGMTJobItem $job_item) {
$label = $this->pluginType . ':' . $job_item->item_type . ':' . $job_item->item_id;
// We need to test if job and job item labels get properly truncated,
// therefore in case the job item type is "test_with_long_label" we append
// further text to the existing label.
if ($job_item->item_type == 'test_with_long_label') {
$label .= 'Some very long and boring label that definitely exceeds hundred and twenty eight characters which is the maximum character count for the job item label.';
}
return $label;
}
/**
* {@inheritdoc}
*/
public function getData(TMGMTJobItem $job_item) {
// Allow tests to set custom source data.
$source = variable_get('tmgmt_test_source_data', array(
'dummy' => array(
'deep_nesting' => array(
'#text' => 'Text for job item with type @type and id @id.',
'#label' => 'Label for job item with type @type and id @id.',
),
),
));
$variables = array(
'@type' => $job_item->item_type,
'@id' => $job_item->item_id,
);
$this->replacePlaceholders($source, $variables);
return $source;
}
/**
* Will replace placeholders in the #text offsets.
*
* @param array $data
* Data structures where to replace placeholders.
* @param $variables
* Key value pairs.
*/
protected function replacePlaceholders(&$data, $variables) {
foreach (element_children($data) as $key) {
if (isset($data[$key]['#text'])) {
$data[$key]['#text'] = format_string($data[$key]['#text'], $variables);
}
else {
$this->replacePlaceholders($data[$key], $variables);
}
}
}
/**
* {@inheritdoc}
*/
public function saveTranslation(TMGMTJobItem $job_item) {
// Set a variable that can be checked later for a given job item.
variable_set('tmgmt_test_saved_translation_' . $job_item->item_type . '_' . $job_item->item_id, TRUE);
$job_item->accepted();
}
/**
* {@inheritdoc}
*/
public function getExistingLangCodes(TMGMTJobItem $job_item) {
return array_keys(language_list());
}
/**
* {@inheritdoc}
*/
public function getSourceLangCode(TMGMTJobItem $job_item) {
$source_languages = variable_get('tmgmt_test_source_languages', array());
if (isset($source_languages[$job_item->tjiid])) {
return $source_languages[$job_item->tjiid];
}
return 'en';
}
}

View File

@@ -0,0 +1,108 @@
<?php
/**
* @file
* Cotains the test translator plugin.
*/
class TMGMTTestTranslatorPluginController extends TMGMTDefaultTranslatorPluginController implements TMGMTTranslatorRejectDataItem {
/**
* {@inheritdoc}
*/
protected $escapeStart = '[[[';
/**
* {@inheritdoc}
*/
protected $escapeEnd = ']]]';
/**
* {@inheritdoc}
*/
public function getDefaultRemoteLanguagesMappings() {
return array(
'en' => 'en-us',
'de' => 'de-ch',
);
}
/**
* {@inheritdoc}
*/
public function hasCheckoutSettings(TMGMTJob $job) {
return $job->getTranslator()->getSetting('expose_settings');
}
/**
* {@inheritdoc}
*/
function requestTranslation(TMGMTJob $job) {
// Add a debug message.
$job->addMessage('Test translator called.', array(), 'debug');
// Do something different based on the action, if defined.
$action = isset($job->settings['action']) ? $job->settings['action'] : '';
switch ($action) {
case 'submit':
$job->submitted('Test submit.');
break;
case 'reject':
$job->rejected('This is not supported.');
break;
case 'fail':
// Target not reachable.
$job->addMessage('Service not reachable.', array(), 'error');
break;
case 'translate':
default:
// The dummy translation prefixes strings with the target language.
$data = array_filter(tmgmt_flatten_data($job->getData()), '_tmgmt_filter_data');
$tdata = array();
foreach ($data as $key => $value) {
$tdata[$key]['#text'] = $job->target_language . '_' . $value['#text'];
}
$job->submitted('Test translation created.');
$job->addTranslatedData(tmgmt_unflatten_data($tdata));
break;
}
}
/**
* {@inheritdoc}
*/
function canTranslate(TMGMTTranslator $translator, TMGMTJob $job) {
if (isset($job->settings['action']) && $job->settings['action'] == 'not_translatable') {
return FALSE;
}
return parent::canTranslate($translator, $job);
}
/**
* {@inheritdoc}
*/
public function getSupportedTargetLanguages(TMGMTTranslator $translator, $source_language) {
$languages = drupal_map_assoc(array('en', 'de', 'es', 'it', 'zh-hans', 'gsw-berne'));
unset($languages[$source_language]);
return $languages;
}
/**
* {@inheritdoc}
*/
public function rejectDataItem(TMGMTJobItem $job_item, array $key, array $values = NULL) {
$key = '[' . implode('][', $key) . ']';
$job_item->addMessage('Rejected data item @key for job item @item in job @job.', array('@key' => $key, '@item' => $job_item->tjiid, '@job' => $job_item->tjid));
return TRUE;
}
/**
* {@inheritdoc}
*/
public function rejectForm($form, &$form_state) {
return $form;
}
}

View File

@@ -0,0 +1,66 @@
<?php
/**
* @file
* Contains the test translator UI plugin.
*/
class TMGMTTestTranslatorUIController extends TMGMTDefaultTranslatorUIController {
/**
* {@inheritdoc}
*/
public function pluginSettingsForm($form, &$form_state, TMGMTTranslator $translator, $busy = FALSE) {
$form['expose_settings'] = array(
'#type' => 'checkbox',
'#title' => t('Display settings'),
'#default_value' => TRUE,
);
$form['action'] = array(
'#type' => 'select',
'#title' => t('Default action'),
'#options' => array(
'translate' => t('Translate'),
'submit' => t('Submit'),
'reject' => t('Reject'),
'fail' => t('Fail'),
'not_translatable' => t('Not translatable'),
),
);
return parent::pluginSettingsForm($form, $form_state, $translator, $busy);
}
/**
* {@inheritdoc}
*/
public function checkoutSettingsForm($form, &$form_state, TMGMTJob $job) {
if ($job->getTranslator()->getSetting('expose_settings')) {
$form['action'] = array(
'#type' => 'select',
'#title' => t('Action'),
'#options' => array(
'translate' => t('Translate'),
'submit' => t('Submit'),
'reject' => t('Reject'),
'fail' => t('Fail'),
'not_translatable' => t('Not translatable'),
),
'#default_value' => $job->getTranslator()->getSetting('action'),
);
}
return $form;
}
/**
* {@inheritdoc}
*/
public function reviewDataItemElement($form, &$form_state, $data_item_key, $parent_key, array $data_item, TMGMTJobItem $item) {
$form['below'] = array(
'#markup' => t('Testing output of review data item element @key from the testing translator.', array('@key' => $data_item_key))
);
return $form;
}
}