Commit a03df8d1 authored by webchick's avatar webchick
Browse files

Issue #1452188 by Schnitzel, droplet, Sutharsan, Bojhan, Kristen Pol, Gábor...

Issue #1452188 by Schnitzel, droplet, Sutharsan, Bojhan, Kristen Pol, Gábor Hojtsy, ershov.andrey, perusio, nod_, rvilar, andypost: Added New UI for string translation.
parent c32682a7
......@@ -103,15 +103,29 @@ function testUILanguageNegotiation() {
$language_browser_fallback_string = "In $langcode_browser_fallback In $langcode_browser_fallback In $langcode_browser_fallback";
$language_string = "In $langcode In $langcode In $langcode";
// Do a translate search of our target string.
$edit = array( 'string' => $default_string);
$this->drupalPost('admin/config/regional/translate/translate', $edit, t('Filter'));
// Should find the string and now click edit to post translated string.
$this->clickLink('edit');
$search = array(
'string' => $default_string,
'langcode' => $langcode_browser_fallback,
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$edit = array(
$lid => $language_browser_fallback_string,
);
$this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
$search = array(
'string' => $default_string,
'langcode' => $langcode,
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$edit = array(
"translations[$langcode_browser_fallback][0]" => $language_browser_fallback_string,
"translations[$langcode][0]" => $language_string,
$lid => $language_string,
);
$this->drupalPost(NULL, $edit, t('Save translations'));
$this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
// Configure URL language rewrite.
variable_set('language_negotiation_url_type', LANGUAGE_TYPE_INTERFACE);
......
......@@ -91,7 +91,7 @@ function testStandalonePoFile() {
// Ensure string wasn't overwritten.
$search = array(
'string' => 'Montag',
'language' => 'fr',
'langcode' => 'fr',
'translation' => 'translated',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
......@@ -113,7 +113,7 @@ function testStandalonePoFile() {
// Ensure string was overwritten.
$search = array(
'string' => 'Montag',
'language' => 'fr',
'langcode' => 'fr',
'translation' => 'translated',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
......@@ -149,7 +149,7 @@ function testStandalonePoFile() {
// Ensure string wasn't overwritten.
$search = array(
'string' => 'januari',
'language' => 'fr',
'langcode' => 'fr',
'translation' => 'translated',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
......@@ -168,7 +168,7 @@ function testStandalonePoFile() {
// Ensure string was overwritten.
$search = array(
'string' => 'januari',
'language' => 'fr',
'langcode' => 'fr',
'translation' => 'translated',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
......@@ -201,7 +201,7 @@ function testAutomaticModuleTranslationImportLanguageEnable() {
// Ensure strings were successfully imported.
$search = array(
'string' => 'lundi',
'language' => $langcode,
'langcode' => $langcode,
'translation' => 'translated',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
......@@ -241,20 +241,15 @@ function testEmptyMsgstr() {
'overwrite_options[not_customized]' => TRUE,
));
$this->assertRaw(t('The translation was successfully imported. There are %number newly created translated strings, %update strings were updated and %delete strings were removed.', array('%number' => 0, '%update' => 0, '%delete' => 1)), t('The translation file was successfully imported.'));
// This is the language indicator on the translation search screen for
// untranslated strings.
$language_indicator = "<em class=\"locale-untranslated\">$langcode</em> ";
$str = "Operations";
$search = array(
'string' => $str,
'language' => 'all',
'translation' => 'all',
'langcode' => $langcode,
'translation' => 'untranslated',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
// assertText() seems to remove the input field where $str always could be
// found, so this is not a false assert.
$this->assertText($str, t('Search found the string.'));
$this->assertRaw($language_indicator, t('String is untranslated again.'));
$this->assertText($str, t('Search found the string as untranslated.'));
}
/**
......
......@@ -160,32 +160,41 @@ function testPluralEditExport() {
// Check if the source appears on the translation page.
$this->drupalGet('admin/config/regional/translate');
$this->assertText("1 hour, @count hours");
$this->assertText("1 hour");
$this->assertText("@count hours");
// Look up editing page for this plural string and check fields.
$lid = db_query("SELECT lid FROM {locales_source} WHERE source = :source AND context = ''", array(':source' => "1 hour" . LOCALE_PLURAL_DELIMITER . "@count hours"))->fetchField();
$path = 'admin/config/regional/translate/edit/' . $lid;
$path = 'admin/config/regional/translate/';
$this->drupalGet($path);
// Labels for plural editing elements.
$this->assertFieldByXPath('//label[@for="edit-translations-hr-0"]', 'Singular form ');
$this->assertFieldByXPath('//label[@for="edit-translations-hr-1"]', 'First plural form ');
$this->assertFieldByXPath('//label[@for="edit-translations-hr-2"]', '2. plural form ');
$this->assertFieldByXPath('//label[@for="edit-translations-fr-0"]', 'Singular form ');
$this->assertFieldByXPath('//label[@for="edit-translations-fr-1"]', 'Plural form ');
// Plural values for both languages.
$this->assertFieldById('edit-translations-hr-0', '@count sat');
$this->assertFieldById('edit-translations-hr-1', '@count sata');
$this->assertFieldById('edit-translations-hr-2', '@count sati');
$this->assertNoFieldById('edit-translations-hr-3');
$this->assertFieldById('edit-translations-fr-0', '1 heure');
$this->assertFieldById('edit-translations-fr-1', '@count heures');
$this->assertNoFieldById('edit-translations-fr-2');
// Edit some translations and see if that took effect.
$this->assertText('Singular form');
$this->assertText('First plural form');
$this->assertText('2. plural form');
$this->assertNoText('3. plural form');
// Plural values for langcode hr.
$this->assertText('@count sat');
$this->assertText('@count sata');
$this->assertText('@count sati');
// Edit langcode hr translations and see if that took effect.
$edit = array(
'translations[fr][0]' => '1 heure edited',
'translations[hr][1]' => '@count sata edited',
'strings[10][translations][1]' => '@count sata edited',
);
$this->drupalPost($path, $edit, t('Save translations'));
$search = array(
'langcode' => 'fr',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
// Plural values for the langcode fr.
$this->assertText('1 heure');
$this->assertText('@count heures');
$this->assertNoText('2. plural form');
// Edit langcode fr translations and see if that took effect.
$edit = array(
'strings[10][translations][0]' => '1 heure edited',
);
$this->drupalPost($path, $edit, t('Save translations'));
......@@ -194,21 +203,36 @@ function testPluralEditExport() {
// not save our source string for performance optimization if we do not ask
// specifically for a language.
format_plural(1, '1 day', '@count days', array(), array('langcode' => 'fr'));
// Look up editing page for this plural string and check fields.
$lid = db_query("SELECT lid FROM {locales_source} WHERE source = :source AND context = ''", array(':source' => "1 day" . LOCALE_PLURAL_DELIMITER . "@count days"))->fetchField();
$path = 'admin/config/regional/translate/edit/' . $lid;
// Look up editing page for this plural string and check fields.
$search = array(
'string' => '1 day',
'langcode' => 'fr',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
// Save complete translations for the string in both languages.
// Save complete translations for the string in langcode fr.
$edit = array(
'translations[fr][0]' => '1 jour',
'translations[fr][1]' => '@count jours',
'translations[hr][0]' => '@count dan',
'translations[hr][1]' => '@count dana',
'translations[hr][2]' => '@count dana',
"strings[$lid][translations][0]" => '1 jour',
"strings[$lid][translations][1]" => '@count jours',
);
$this->drupalPost($path, $edit, t('Save translations'));
// Get the French translations.
// Save complete translations for the string in langcode hr.
$search = array(
'string' => '1 day',
'langcode' => 'hr',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
$edit = array(
"strings[$lid][translations][0]" => '@count dan',
"strings[$lid][translations][1]" => '@count dana',
"strings[$lid][translations][2]" => '@count dana',
);
$this->drupalPost($path, $edit, t('Save translations'));
// Get the French translations.
$this->drupalPost('admin/config/regional/translate/export', array(
'langcode' => 'fr',
), t('Export'));
......@@ -225,7 +249,6 @@ function testPluralEditExport() {
$this->assertRaw("msgid \"1 day\"\nmsgid_plural \"@count days\"\nmsgstr[0] \"@count dan\"\nmsgstr[1] \"@count dana\"\nmsgstr[2] \"@count dana\"", t('Added Croatian plural translations exported properly.'));
}
/**
* Imports a standalone .po file in a given language.
*
......
......@@ -67,21 +67,19 @@ function testStringTranslation() {
$this->drupalLogin($translate_user);
$search = array(
'string' => $name,
'language' => 'all',
'translation' => 'all',
'langcode' => $langcode,
'translation' => 'untranslated',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
// assertText() seems to remove the input field where $name always could be
// found, so this is not a false assert. See how assertNoText succeeds
// later.
$this->assertText($name, t('Search found the name.'));
$this->assertRaw($language_indicator, t('Name is untranslated.'));
$this->assertText($name, t('Search found the string as untranslated.'));
// Assume this is the only result, given the random name.
$this->clickLink(t('edit'));
// We save the lid from the path.
$matches = array();
preg_match('!admin/config/regional/translate/edit/(\d+)!', $this->getUrl(), $matches);
$lid = $matches[1];
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$edit = array(
$lid => $this->randomName(),
);
// No t() here, it's surely not translated yet.
$this->assertText($name, t('name found on edit screen.'));
$this->assertNoText('English', t('No way to translate the string to English.'));
......@@ -91,24 +89,46 @@ function testStringTranslation() {
$this->drupalLogout();
$this->drupalLogin($translate_user);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
// assertText() seems to remove the input field where $name always could be
// found, so this is not a false assert. See how assertNoText succeeds
// later.
$this->assertText($name, t('Search found the name.'));
$this->assertRaw($language_indicator, t('Name is untranslated.'));
$this->assertText($name, t('Search found the string as untranslated.'));
// Assume this is the only result, given the random name.
$this->clickLink(t('edit'));
$string_edit_url = $this->getUrl();
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$edit = array(
"translations[$langcode][0]" => $translation,
'translations[en][0]' => $translation_to_en,
$lid => $translation,
);
$this->drupalPost(NULL, $edit, t('Save translations'));
$this->assertText(t('The string has been saved.'), t('The string has been saved.'));
$this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
$this->assertText(t('The strings have been saved.'), t('The strings have been saved.'));
$this->assertEqual($this->getUrl(), url('admin/config/regional/translate/translate', array('absolute' => TRUE)), t('Correct page redirection.'));
$this->drupalGet($string_edit_url);
$search = array(
'string' => $name,
'langcode' => $langcode,
'translation' => 'translated',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
$this->assertRaw($translation, t('Non-English translation properly saved.'));
$search = array(
'string' => $name,
'langcode' => 'en',
'translation' => 'untranslated',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$edit = array(
$lid => $translation_to_en,
);
$this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
$search = array(
'string' => $name,
'langcode' => 'en',
'translation' => 'translated',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
$this->assertRaw($translation_to_en, t('English translation properly saved.'));
$this->assertTrue($name != $translation && t($name, array(), array('langcode' => $langcode)) == $translation, t('t() works for non-English.'));
// Refresh the locale() cache to get fresh data from t() below. We are in
// the same HTTP request and therefore t() is not refreshed by saving the
......@@ -117,16 +137,15 @@ function testStringTranslation() {
// Now we should get the proper fresh translation from t().
$this->assertTrue($name != $translation_to_en && t($name, array(), array('langcode' => 'en')) == $translation_to_en, t('t() works for English.'));
$this->assertTrue(t($name, array(), array('langcode' => LANGUAGE_SYSTEM)) == $name, t('t() works for LANGUAGE_SYSTEM.'));
$search = array(
'string' => $name,
'langcode' => 'en',
'translation' => 'untranslated',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
// The indicator should not be here.
$this->assertNoRaw($language_indicator, t('String is translated.'));
// Try to edit a non-existent string and ensure we're redirected correctly.
// Assuming we don't have 999,999 strings already.
$random_lid = 999999;
$this->drupalGet('admin/config/regional/translate/edit/' . $random_lid);
$this->assertText(t('String not found'), t('String not found.'));
$this->assertEqual($this->getUrl(), url('admin/config/regional/translate/translate', array('absolute' => TRUE)), t('Correct page redirection.'));
$this->assertText(t('No strings available.'), t('String is translated.'));
$this->drupalLogout();
// Delete the language.
......@@ -147,26 +166,26 @@ function testStringTranslation() {
$this->drupalLogin($translate_user);
$search = array(
'string' => $name,
'language' => 'all',
'translation' => 'all',
'langcode' => 'en',
'translation' => 'translated',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
// Assume this is the only result, given the random name.
$this->clickLink(t('delete'));
$this->assertText(t('Are you sure you want to delete the string'), t('"delete" link is correct.'));
// Delete the string.
$path = 'admin/config/regional/translate/delete/' . $lid;
$this->drupalGet($path);
// First test the 'cancel' link.
$this->clickLink(t('Cancel'));
$this->assertEqual($this->getUrl(), url('admin/config/regional/translate/translate', array('absolute' => TRUE)), t('Correct page redirection.'));
$this->assertRaw($name, t('The string was not deleted.'));
// Delete the name string.
$this->drupalPost('admin/config/regional/translate/delete/' . $lid, array(), t('Delete'));
$this->assertText(t('The string has been removed.'), t('The string has been removed message.'));
$this->assertEqual($this->getUrl(), url('admin/config/regional/translate/translate', array('absolute' => TRUE)), t('Correct page redirection.'));
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$edit = array(
$lid => '',
);
$this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
$this->assertRaw($name, t('The strings have been saved.'));
$this->drupalLogin($translate_user);
$search = array(
'string' => $name,
'langcode' => 'en',
'translation' => 'untranslated',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
$this->assertNoText($name, t('Search now can not find the name.'));
$this->assertNoText(t('No strings available.'), t('The translation has been removed'));
}
/*
......@@ -192,16 +211,29 @@ function testJavaScriptTranslation() {
drupal_static_reset('language_list');
// Build the JavaScript translation file.
$this->drupalGet('admin/config/regional/translate/translate');
// Retrieve the id of the first string available in the {locales_source}
// table and translate it.
$query = db_select('locales_source', 'l');
$query->addExpression('min(l.lid)', 'lid');
$result = $query->condition('l.location', '%.js%', 'LIKE')->execute();
$url = 'admin/config/regional/translate/edit/' . $result->fetchObject()->lid;
$edit = array('translations['. $langcode .'][0]' => $this->randomName());
$this->drupalPost($url, $edit, t('Save translations'));
// Retrieve the source string of the first string available in the
// {locales_source} table and translate it.
$source = db_select('locales_source', 'l')
->fields('l', array('source'))
->condition('l.location', '%.js%', 'LIKE')
->range(0, 1)
->execute()
->fetchField();
$search = array(
'string' => $source,
'langcode' => $langcode,
'translation' => 'all',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$edit = array(
$lid => $this->randomName(),
);
$this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
// Trigger JavaScript translation parsing and building.
_locale_rebuild_js($langcode);
......@@ -230,9 +262,7 @@ function testStringValidation() {
$langcode = 'xx';
// The English name for the language. This will be translated.
$name = $this->randomName(16);
// This is the language indicator on the translation search screen for
// untranslated strings.
$language_indicator = "<em class=\"locale-untranslated\">$langcode</em> ";
// These will be the invalid translations of $name.
$key = $this->randomName(16);
$bad_translations[$key] = "<script>alert('xss');</script>" . $key;
......@@ -256,19 +286,19 @@ function testStringValidation() {
// Reset locale cache.
$search = array(
'string' => $name,
'language' => 'all',
'langcode' => $langcode,
'translation' => 'all',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
// Find the edit path.
$content = $this->drupalGetContent();
$this->assertTrue(preg_match('@(admin/config/regional/translate/edit/[0-9]+)@', $content, $matches), t('Found the edit path.'));
$path = $matches[0];
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
foreach ($bad_translations as $key => $translation) {
$edit = array(
"translations[$langcode][0]" => $translation,
$lid => $translation,
);
$this->drupalPost($path, $edit, t('Save translations'));
$this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
// Check for a form error on the textarea.
$form_class = $this->xpath('//form[@id="locale-translate-edit-form"]//textarea/@class');
$this->assertNotIdentical(FALSE, strpos($form_class[0], 'error'), t('The string was rejected as unsafe.'));
......@@ -306,6 +336,15 @@ function testStringSearch() {
'direction' => '0',
);
$this->drupalPost('admin/config/regional/language/add', $edit, t('Add custom language'));
$edit = array(
'predefined_langcode' => 'custom',
'langcode' => 'yy',
'name' => $this->randomName(16),
'direction' => '0',
);
$this->drupalPost('admin/config/regional/language/add', $edit, t('Add custom language'));
// Add string.
t($name, array(), array('langcode' => $langcode));
// Reset locale cache.
......@@ -316,7 +355,7 @@ function testStringSearch() {
$this->drupalLogin($translate_user);
$search = array(
'string' => $name,
'language' => 'all',
'langcode' => $langcode,
'translation' => 'all',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
......@@ -329,7 +368,7 @@ function testStringSearch() {
// translated strings'.
$search = array(
'string' => $name,
'language' => 'all',
'langcode' => $langcode,
'translation' => 'translated',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
......@@ -339,7 +378,7 @@ function testStringSearch() {
// strings'.
$search = array(
'string' => $name,
'language' => 'all',
'langcode' => $langcode,
'translation' => 'untranslated',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
......@@ -347,21 +386,19 @@ function testStringSearch() {
// Add translation.
// Assume this is the only result, given the random name.
$this->clickLink(t('edit'));
// We save the lid from the path.
$matches = array();
preg_match('!admin/config/regional/translate/edit/(\d)+!', $this->getUrl(), $matches);
$lid = $matches[1];
$textarea = current($this->xpath('//textarea'));
$lid = (string) $textarea[0]['name'];
$edit = array(
"translations[$langcode][0]" => $translation,
$lid => $translation,
);
$this->drupalPost(NULL, $edit, t('Save translations'));
$this->drupalPost('admin/config/regional/translate/translate', $edit, t('Save translations'));
// Ensure translated string does appear if searching on 'only
// translated strings'.
$search = array(
'string' => $translation,
'language' => 'all',
'langcode' => $langcode,
'translation' => 'translated',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
......@@ -371,7 +408,7 @@ function testStringSearch() {
// untranslated strings'.
$search = array(
'string' => $name,
'language' => 'all',
'langcode' => $langcode,
'translation' => 'untranslated',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
......@@ -381,7 +418,7 @@ function testStringSearch() {
// untranslated strings'.
$search = array(
'string' => $translation,
'language' => 'all',
'langcode' => $langcode,
'translation' => 'untranslated',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
......@@ -390,7 +427,7 @@ function testStringSearch() {
// Ensure translated string does appear if searching on the custom language.
$search = array(
'string' => $translation,
'language' => $langcode,
'langcode' => $langcode,
'translation' => 'all',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
......@@ -399,7 +436,7 @@ function testStringSearch() {
// Ensure translated string doesn't appear if searching in System (English).
$search = array(
'string' => $translation,
'language' => LANGUAGE_SYSTEM,
'langcode' => 'yy',
'translation' => 'all',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
......@@ -409,7 +446,7 @@ function testStringSearch() {
$unavailable_string = $this->randomName(16);
$search = array(
'string' => $unavailable_string,
'language' => 'all',
'langcode' => $langcode,
'translation' => 'all',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
......
......@@ -61,11 +61,13 @@ function testUninstallProcess() {
$user = $this->drupalCreateUser(array('translate interface', 'access administration pages'));
$this->drupalLogin($user);
$this->drupalGet('admin/config/regional/translate/translate');
$string = db_query('SELECT min(lid) AS lid FROM {locales_source} WHERE location LIKE :location', array(