3 namespace Drupal\Tests\locale\Functional;
5 use Drupal\Tests\BrowserTestBase;
8 * Tests the exportation of locale files.
12 class LocaleExportTest extends BrowserTestBase {
19 public static $modules = ['locale'];
22 * A user able to create languages and export translations.
24 protected $adminUser = NULL;
29 protected function setUp() {
32 $this->adminUser = $this->drupalCreateUser(['administer languages', 'translate interface', 'access administration pages']);
33 $this->drupalLogin($this->adminUser);
35 // Copy test po files to the translations directory.
36 file_unmanaged_copy(__DIR__ . '/../../tests/test.de.po', 'translations://', FILE_EXISTS_REPLACE);
37 file_unmanaged_copy(__DIR__ . '/../../tests/test.xx.po', 'translations://', FILE_EXISTS_REPLACE);
41 * Test exportation of translations.
43 public function testExportTranslation() {
44 // First import some known translations.
45 // This will also automatically add the 'fr' language.
46 $name = \Drupal::service('file_system')->tempnam('temporary://', "po_") . '.po';
47 file_put_contents($name, $this->getPoFile());
48 $this->drupalPostForm('admin/config/regional/translate/import', [
50 'files[file]' => $name,
54 // Get the French translations.
55 $this->drupalPostForm('admin/config/regional/translate/export', [
59 // Ensure we have a translation file.
60 $this->assertRaw('# French translation of Drupal', 'Exported French translation file.');
61 // Ensure our imported translations exist in the file.
62 $this->assertRaw('msgstr "lundi"', 'French translations present in exported file.');
64 // Import some more French translations which will be marked as customized.
65 $name = \Drupal::service('file_system')->tempnam('temporary://', "po2_") . '.po';
66 file_put_contents($name, $this->getCustomPoFile());
67 $this->drupalPostForm('admin/config/regional/translate/import', [
69 'files[file]' => $name,
74 // Create string without translation in the locales_source table.
76 ->get('locale.storage')
78 ->setString('February')
81 // Export only customized French translations.
82 $this->drupalPostForm('admin/config/regional/translate/export', [
84 'content_options[not_customized]' => FALSE,
85 'content_options[customized]' => TRUE,
86 'content_options[not_translated]' => FALSE,
89 // Ensure we have a translation file.
90 $this->assertRaw('# French translation of Drupal', 'Exported French translation file with only customized strings.');
91 // Ensure the customized translations exist in the file.
92 $this->assertRaw('msgstr "janvier"', 'French custom translation present in exported file.');
93 // Ensure no untranslated strings exist in the file.
94 $this->assertNoRaw('msgid "February"', 'Untranslated string not present in exported file.');
96 // Export only untranslated French translations.
97 $this->drupalPostForm('admin/config/regional/translate/export', [
99 'content_options[not_customized]' => FALSE,
100 'content_options[customized]' => FALSE,
101 'content_options[not_translated]' => TRUE,
104 // Ensure we have a translation file.
105 $this->assertRaw('# French translation of Drupal', 'Exported French translation file with only untranslated strings.');
106 // Ensure no customized translations exist in the file.
107 $this->assertNoRaw('msgstr "janvier"', 'French custom translation not present in exported file.');
108 // Ensure the untranslated strings exist in the file, and with right quotes.
109 $this->assertRaw($this->getUntranslatedString(), 'Empty string present in exported file.');
113 * Test exportation of translation template file.
115 public function testExportTranslationTemplateFile() {
116 // Load an admin page with JavaScript so _drupal_add_library() fires at
117 // least once and _locale_parse_js_file() gets to run at least once so that
118 // the locales_source table gets populated with something.
119 $this->drupalGet('admin/config/regional/language');
120 // Get the translation template file.
121 $this->drupalPostForm('admin/config/regional/translate/export', [], t('Export'));
122 // Ensure we have a translation file.
123 $this->assertRaw('# LANGUAGE translation of PROJECT', 'Exported translation template file.');
127 * Helper function that returns a proper .po file.
129 public function getPoFile() {
133 "Project-Id-Version: Drupal 8\\n"
134 "MIME-Version: 1.0\\n"
135 "Content-Type: text/plain; charset=UTF-8\\n"
136 "Content-Transfer-Encoding: 8bit\\n"
137 "Plural-Forms: nplurals=2; plural=(n > 1);\\n"
145 * Helper function that returns a .po file which strings will be marked
148 public function getCustomPoFile() {
152 "Project-Id-Version: Drupal 8\\n"
153 "MIME-Version: 1.0\\n"
154 "Content-Type: text/plain; charset=UTF-8\\n"
155 "Content-Transfer-Encoding: 8bit\\n"
156 "Plural-Forms: nplurals=2; plural=(n > 1);\\n"
164 * Returns a .po file fragment with an untranslated string.
167 * A .po file fragment with an untranslated string.
169 public function getUntranslatedString() {