View source
<?php
namespace Drupal\locale\Tests;
use Drupal\simpletest\WebTestBase;
use Drupal\Core\Language\LanguageInterface;
class LocaleImportFunctionalTest extends WebTestBase {
public static $modules = array(
'locale',
'dblog',
);
protected $adminUser;
protected $adminUserAccessSiteReports;
protected function setUp() {
parent::setUp();
file_unmanaged_copy(drupal_get_path('module', 'locale') . '/tests/test.de.po', 'translations://', FILE_EXISTS_REPLACE);
file_unmanaged_copy(drupal_get_path('module', 'locale') . '/tests/test.xx.po', 'translations://', FILE_EXISTS_REPLACE);
$this->adminUser = $this
->drupalCreateUser(array(
'administer languages',
'translate interface',
'access administration pages',
));
$this->adminUserAccessSiteReports = $this
->drupalCreateUser(array(
'administer languages',
'translate interface',
'access administration pages',
'access site reports',
));
$this
->drupalLogin($this->adminUser);
$this
->config('locale.settings')
->set('translation.import_enabled', TRUE)
->save();
}
public function testStandalonePoFile() {
$this
->importPoFile($this
->getPoFile(), array(
'langcode' => 'fr',
));
$this
->config('locale.settings');
$this
->assertRaw(t('The language %language has been created.', array(
'%language' => 'French',
)), 'The language has been automatically created.');
$this
->assertRaw(t('One translation file imported. %number translations were added, %update translations were updated and %delete translations were removed.', array(
'%number' => 8,
'%update' => 0,
'%delete' => 0,
)), 'The translation file was successfully imported.');
$locale_plurals = \Drupal::service('locale.plural.formula')
->getNumberOfPlurals('fr');
$this
->assertEqual(2, $locale_plurals, 'Plural number initialized.');
$this
->assertUrl(\Drupal::url('locale.translate_page', [], [
'absolute' => TRUE,
]), [], 'Correct page redirection.');
$this
->importPoFile($this
->getBadPoFile(), array(
'langcode' => 'fr',
));
$this
->assertRaw(t('One translation file imported. %number translations were added, %update translations were updated and %delete translations were removed.', array(
'%number' => 1,
'%update' => 0,
'%delete' => 0,
)), 'The translation file was successfully imported.');
$skip_message = \Drupal::translation()
->formatPlural(2, 'One translation string was skipped because of disallowed or malformed HTML. <a href=":url">See the log</a> for details.', '@count translation strings were skipped because of disallowed or malformed HTML. See the log for details.', array(
':url' => \Drupal::url('dblog.overview'),
));
$this
->assertRaw($skip_message, 'Unsafe strings were skipped.');
$this
->drupalLogin($this->adminUserAccessSiteReports);
$this
->importPoFile($this
->getBadPoFile(), array(
'langcode' => 'fr',
));
$skip_message = \Drupal::translation()
->formatPlural(2, 'One translation string was skipped because of disallowed or malformed HTML. <a href=":url">See the log</a> for details.', '@count translation strings were skipped because of disallowed or malformed HTML. <a href=":url">See the log</a> for details.', array(
':url' => \Drupal::url('dblog.overview'),
));
$this
->assertRaw($skip_message, 'Unsafe strings were skipped.');
$this
->drupalLogin($this->adminUser);
$this
->importPoFile($this
->getEmptyPoFile(), array(
'langcode' => 'fr',
));
$this
->assertRaw(t('One translation file could not be imported. See the log for details.'), 'The empty translation file import reported no translations imported.');
$this
->drupalLogin($this->adminUserAccessSiteReports);
$this
->importPoFile($this
->getEmptyPoFile(), array(
'langcode' => 'fr',
));
$this
->assertRaw(t('One translation file could not be imported. <a href=":url">See the log</a> for details.', array(
':url' => \Drupal::url('dblog.overview'),
)), 'The empty translation file import reported no translations imported.');
$name = $this
->randomMachineName(16);
$this
->drupalPostForm('admin/config/regional/translate/import', array(
'langcode' => 'fr',
'files[file]' => $name,
), t('Import'));
$this
->assertUrl(\Drupal::url('locale.translate_import', [], [
'absolute' => TRUE,
]), [], 'Correct page redirection.');
$this
->assertText(t('File to import not found.'), 'File to import not found message.');
$this
->importPoFile($this
->getOverwritePoFile(), array(
'langcode' => 'fr',
));
$this
->assertRaw(t('One translation file imported. %number translations were added, %update translations were updated and %delete translations were removed.', array(
'%number' => 1,
'%update' => 0,
'%delete' => 0,
)), 'The translation file was successfully imported.');
$search = array(
'string' => 'Montag',
'langcode' => 'fr',
'translation' => 'translated',
);
$this
->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$this
->assertText(t('No strings available.'), 'String not overwritten by imported string.');
$locale_plurals = \Drupal::service('locale.plural.formula')
->getNumberOfPlurals('fr');
$this
->assertEqual(2, $locale_plurals, 'Plural numbers untouched.');
$this
->importPoFile($this
->getOverwritePoFile(), array(
'langcode' => 'fr',
'overwrite_options[not_customized]' => TRUE,
));
$this
->assertRaw(t('One translation file imported. %number translations were added, %update translations were updated and %delete translations were removed.', array(
'%number' => 0,
'%update' => 2,
'%delete' => 0,
)), 'The translation file was successfully imported.');
$search = array(
'string' => 'Montag',
'langcode' => 'fr',
'translation' => 'translated',
);
$this
->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$this
->assertNoText(t('No strings available.'), 'String overwritten by imported string.');
$locale_plurals = \Drupal::service('locale.plural.formula')
->reset()
->getNumberOfPlurals('fr');
$this
->assertEqual(3, $locale_plurals, 'Plural numbers changed.');
$this
->importPoFile($this
->getCustomPoFile(), array(
'langcode' => 'fr',
'customized' => TRUE,
));
$this
->assertRaw(t('One translation file imported. %number translations were added, %update translations were updated and %delete translations were removed.', array(
'%number' => 6,
'%update' => 0,
'%delete' => 0,
)), 'The customized translation file was successfully imported.');
$count = db_query('SELECT COUNT(*) FROM {locales_target} WHERE customized = :custom', array(
':custom' => 1,
))
->fetchField();
$this
->assertEqual($count, 6, 'Customized translations successfully imported.');
$this
->importPoFile($this
->getCustomOverwritePoFile(), array(
'langcode' => 'fr',
'overwrite_options[not_customized]' => TRUE,
'overwrite_options[customized]' => FALSE,
));
$this
->assertRaw(t('One translation file imported. %number translations were added, %update translations were updated and %delete translations were removed.', array(
'%number' => 1,
'%update' => 0,
'%delete' => 0,
)), 'The customized translation file was successfully imported.');
$search = array(
'string' => 'januari',
'langcode' => 'fr',
'translation' => 'translated',
);
$this
->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$this
->assertText(t('No strings available.'), 'Customized string not overwritten by imported string.');
$this
->importPoFile($this
->getCustomOverwritePoFile(), array(
'langcode' => 'fr',
'overwrite_options[not_customized]' => FALSE,
'overwrite_options[customized]' => TRUE,
));
$this
->assertRaw(t('One translation file imported. %number translations were added, %update translations were updated and %delete translations were removed.', array(
'%number' => 0,
'%update' => 2,
'%delete' => 0,
)), 'The customized translation file was successfully imported.');
$search = array(
'string' => 'januari',
'langcode' => 'fr',
'translation' => 'translated',
);
$this
->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$this
->assertNoText(t('No strings available.'), 'Customized string overwritten by imported string.');
}
public function testLanguageContext() {
$this
->importPoFile($this
->getPoFileWithContext(), array(
'langcode' => 'hr',
));
$this
->assertIdentical((string) t('May', array(), array(
'langcode' => 'hr',
'context' => 'Long month name',
)), 'Svibanj', 'Long month name context is working.');
$this
->assertIdentical((string) t('May', array(), array(
'langcode' => 'hr',
)), 'Svi.', 'Default context is working.');
}
public function testEmptyMsgstr() {
$langcode = 'hu';
$this
->importPoFile($this
->getPoFileWithMsgstr(), array(
'langcode' => $langcode,
));
$this
->assertRaw(t('One translation file imported. %number translations were added, %update translations were updated and %delete translations were removed.', array(
'%number' => 1,
'%update' => 0,
'%delete' => 0,
)), 'The translation file was successfully imported.');
$this
->assertIdentical((string) t('Operations', array(), array(
'langcode' => $langcode,
)), 'Műveletek', 'String imported and translated.');
$this
->importPoFile($this
->getPoFileWithEmptyMsgstr(), array(
'langcode' => $langcode,
'overwrite_options[not_customized]' => TRUE,
));
$this
->assertRaw(t('One translation file imported. %number translations were added, %update translations were updated and %delete translations were removed.', array(
'%number' => 0,
'%update' => 0,
'%delete' => 1,
)), 'The translation file was successfully imported.');
$str = "Operations";
$search = array(
'string' => $str,
'langcode' => $langcode,
'translation' => 'untranslated',
);
$this
->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$this
->assertText($str, 'Search found the string as untranslated.');
}
public function testConfigPoFile() {
$config_strings = array(
'system.maintenance' => array(
'@site is currently under maintenance. We should be back shortly. Thank you for your patience.',
'@site karbantartás alatt áll. Rövidesen visszatérünk. Köszönjük a türelmet.',
'message',
),
'user.role.anonymous' => array(
'Anonymous user',
'Névtelen felhasználó',
'label',
),
);
$langcode = 'xx';
$edit = array(
'predefined_langcode' => 'custom',
'langcode' => $langcode,
'label' => $this
->randomMachineName(16),
'direction' => LanguageInterface::DIRECTION_LTR,
);
$this
->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language'));
$locale_storage = $this->container
->get('locale.storage');
foreach ($config_strings as $config_string) {
$string = $locale_storage
->findString(array(
'source' => $config_string[0],
'context' => '',
'type' => 'configuration',
));
$this
->assertTrue($string, 'Configuration strings have been created upon installation.');
}
$this
->importPoFile($this
->getPoFileWithConfig(), array(
'langcode' => $langcode,
));
foreach ($config_strings as $config_string) {
$search = array(
'string' => $config_string[0],
'langcode' => $langcode,
'translation' => 'all',
);
$this
->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$this
->assertText($config_string[1], format_string('Translation of @string found.', array(
'@string' => $config_string[0],
)));
}
$overrides = \Drupal::service('language.config_factory_override');
foreach ($config_strings as $config_key => $config_string) {
$override = $overrides
->getOverride($langcode, $config_key);
$this
->assertEqual($override
->get($config_string[2]), $config_string[1]);
}
}
public function testConfigtranslationImportingPoFile() {
$langcode = 'de';
$this
->importPoFile($this
->getPoFileWithConfigDe(), array(
'langcode' => $langcode,
));
$config = \Drupal::languageManager()
->getLanguageConfigOverride($langcode, 'user.settings');
$this
->assertEqual($config
->get('anonymous'), 'Anonymous German');
}
public function testCreatedLanguageTranslation() {
$this
->importPoFile($this
->getPoFileWithConfigDe(), array(
'langcode' => 'de',
));
$override = \Drupal::languageManager()
->getLanguageConfigOverride('de', 'language.entity.de');
$this
->assertEqual($override
->get('label'), 'Deutsch');
}
public function importPoFile($contents, array $options = array()) {
$name = tempnam('temporary://', "po_") . '.po';
file_put_contents($name, $contents);
$options['files[file]'] = $name;
$this
->drupalPostForm('admin/config/regional/translate/import', $options, t('Import'));
drupal_unlink($name);
}
public function getPoFile() {
return <<<EOF
msgid ""
msgstr ""
"Project-Id-Version: Drupal 8\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=UTF-8\\n"
"Content-Transfer-Encoding: 8bit\\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\\n"
msgid "One sheep"
msgid_plural "@count sheep"
msgstr[0] "un mouton"
msgstr[1] "@count moutons"
msgid "Monday"
msgstr "lundi"
msgid "Tuesday"
msgstr "mardi"
msgid "Wednesday"
msgstr "mercredi"
msgid "Thursday"
msgstr "jeudi"
msgid "Friday"
msgstr "vendredi"
msgid "Saturday"
msgstr "samedi"
msgid "Sunday"
msgstr "dimanche"
EOF;
}
public function getEmptyPoFile() {
return '';
}
public function getBadPoFile() {
return <<<EOF
msgid ""
msgstr ""
"Project-Id-Version: Drupal 8\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=UTF-8\\n"
"Content-Transfer-Encoding: 8bit\\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\\n"
msgid "Save configuration"
msgstr "Enregistrer la configuration"
msgid "edit"
msgstr "modifier<img SRC="javascript:alert(\\'xss\\');">"
msgid "delete"
msgstr "supprimer<script>alert('xss');</script>"
EOF;
}
public function getOverwritePoFile() {
return <<<EOF
msgid ""
msgstr ""
"Project-Id-Version: Drupal 8\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=UTF-8\\n"
"Content-Transfer-Encoding: 8bit\\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\\n"
msgid "Monday"
msgstr "Montag"
msgid "Day"
msgstr "Jour"
EOF;
}
public function getCustomPoFile() {
return <<<EOF
msgid ""
msgstr ""
"Project-Id-Version: Drupal 8\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=UTF-8\\n"
"Content-Transfer-Encoding: 8bit\\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\\n"
msgid "One dog"
msgid_plural "@count dogs"
msgstr[0] "un chien"
msgstr[1] "@count chiens"
msgid "January"
msgstr "janvier"
msgid "February"
msgstr "février"
msgid "March"
msgstr "mars"
msgid "April"
msgstr "avril"
msgid "June"
msgstr "juin"
EOF;
}
public function getCustomOverwritePoFile() {
return <<<EOF
msgid ""
msgstr ""
"Project-Id-Version: Drupal 8\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=UTF-8\\n"
"Content-Transfer-Encoding: 8bit\\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\\n"
msgid "January"
msgstr "januari"
msgid "February"
msgstr "februari"
msgid "July"
msgstr "juillet"
EOF;
}
public function getPoFileWithContext() {
return <<<EOF
msgid ""
msgstr ""
"Project-Id-Version: Drupal 8\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=UTF-8\\n"
"Content-Transfer-Encoding: 8bit\\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\\n"
msgctxt "Long month name"
msgid "May"
msgstr "Svibanj"
msgid "May"
msgstr "Svi."
EOF;
}
public function getPoFileWithEmptyMsgstr() {
return <<<EOF
msgid ""
msgstr ""
"Project-Id-Version: Drupal 8\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=UTF-8\\n"
"Content-Transfer-Encoding: 8bit\\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\\n"
msgid "Operations"
msgstr ""
EOF;
}
public function getPoFileWithMsgstr() {
return <<<EOF
msgid ""
msgstr ""
"Project-Id-Version: Drupal 8\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=UTF-8\\n"
"Content-Transfer-Encoding: 8bit\\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\\n"
msgid "Operations"
msgstr "Műveletek"
msgid "Will not appear in Drupal core, so we can ensure the test passes"
msgstr ""
EOF;
}
public function getPoFileWithConfig() {
return <<<EOF
msgid ""
msgstr ""
"Project-Id-Version: Drupal 8\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=UTF-8\\n"
"Content-Transfer-Encoding: 8bit\\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\\n"
msgid "@site is currently under maintenance. We should be back shortly. Thank you for your patience."
msgstr "@site karbantartás alatt áll. Rövidesen visszatérünk. Köszönjük a türelmet."
msgid "Anonymous user"
msgstr "Névtelen felhasználó"
EOF;
}
public function getPoFileWithConfigDe() {
return <<<EOF
msgid ""
msgstr ""
"Project-Id-Version: Drupal 8\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=UTF-8\\n"
"Content-Transfer-Encoding: 8bit\\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\\n"
msgid "Anonymous"
msgstr "Anonymous German"
msgid "German"
msgstr "Deutsch"
EOF;
}
}