Mercurial > hg > isophonics-drupal-site
comparison core/modules/locale/tests/src/Functional/LocaleUpdateBase.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 1fec387a4317 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\Tests\locale\Functional; | |
4 | |
5 use Drupal\Core\StreamWrapper\PublicStream; | |
6 use Drupal\file\Entity\File; | |
7 use Drupal\Tests\BrowserTestBase; | |
8 use Drupal\Component\Utility\SafeMarkup; | |
9 | |
10 /** | |
11 * Base class for testing updates to string translations. | |
12 */ | |
13 abstract class LocaleUpdateBase extends BrowserTestBase { | |
14 | |
15 /** | |
16 * Timestamp for an old translation. | |
17 * | |
18 * @var int | |
19 */ | |
20 protected $timestampOld; | |
21 | |
22 /** | |
23 * Timestamp for a medium aged translation. | |
24 * | |
25 * @var int | |
26 */ | |
27 protected $timestampMedium; | |
28 | |
29 /** | |
30 * Timestamp for a new translation. | |
31 * | |
32 * @var int | |
33 */ | |
34 protected $timestampNew; | |
35 | |
36 /** | |
37 * Timestamp for current time. | |
38 * | |
39 * @var int | |
40 */ | |
41 protected $timestampNow; | |
42 | |
43 /** | |
44 * Modules to enable. | |
45 * | |
46 * @var array | |
47 */ | |
48 public static $modules = ['locale', 'locale_test']; | |
49 | |
50 /** | |
51 * {@inheritdoc} | |
52 */ | |
53 protected function setUp() { | |
54 parent::setUp(); | |
55 | |
56 // Setup timestamps to identify old and new translation sources. | |
57 $this->timestampOld = REQUEST_TIME - 300; | |
58 $this->timestampMedium = REQUEST_TIME - 200; | |
59 $this->timestampNew = REQUEST_TIME - 100; | |
60 $this->timestampNow = REQUEST_TIME; | |
61 | |
62 // Enable import of translations. By default this is disabled for automated | |
63 // tests. | |
64 $this->config('locale.settings') | |
65 ->set('translation.import_enabled', TRUE) | |
66 ->save(); | |
67 } | |
68 | |
69 /** | |
70 * Sets the value of the default translations directory. | |
71 * | |
72 * @param string $path | |
73 * Path of the translations directory relative to the drupal installation | |
74 * directory. | |
75 */ | |
76 protected function setTranslationsDirectory($path) { | |
77 file_prepare_directory($path, FILE_CREATE_DIRECTORY); | |
78 $this->config('locale.settings')->set('translation.path', $path)->save(); | |
79 } | |
80 | |
81 /** | |
82 * Adds a language. | |
83 * | |
84 * @param string $langcode | |
85 * The language code of the language to add. | |
86 */ | |
87 protected function addLanguage($langcode) { | |
88 $edit = ['predefined_langcode' => $langcode]; | |
89 $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language')); | |
90 $this->container->get('language_manager')->reset(); | |
91 $this->assertTrue(\Drupal::languageManager()->getLanguage($langcode), SafeMarkup::format('Language %langcode added.', ['%langcode' => $langcode])); | |
92 } | |
93 | |
94 /** | |
95 * Creates a translation file and tests its timestamp. | |
96 * | |
97 * @param string $path | |
98 * Path of the file relative to the public file path. | |
99 * @param string $filename | |
100 * Name of the file to create. | |
101 * @param int $timestamp | |
102 * (optional) Timestamp to set the file to. Defaults to current time. | |
103 * @param array $translations | |
104 * (optional) Array of source/target value translation strings. Only | |
105 * singular strings are supported, no plurals. No double quotes are allowed | |
106 * in source and translations strings. | |
107 */ | |
108 protected function makePoFile($path, $filename, $timestamp = NULL, array $translations = []) { | |
109 $timestamp = $timestamp ? $timestamp : REQUEST_TIME; | |
110 $path = 'public://' . $path; | |
111 $text = ''; | |
112 $po_header = <<<EOF | |
113 msgid "" | |
114 msgstr "" | |
115 "Project-Id-Version: Drupal 8\\n" | |
116 "MIME-Version: 1.0\\n" | |
117 "Content-Type: text/plain; charset=UTF-8\\n" | |
118 "Content-Transfer-Encoding: 8bit\\n" | |
119 "Plural-Forms: nplurals=2; plural=(n > 1);\\n" | |
120 | |
121 EOF; | |
122 | |
123 // Convert array of translations to Gettext source and translation strings. | |
124 if ($translations) { | |
125 foreach ($translations as $source => $target) { | |
126 $text .= 'msgid "' . $source . '"' . "\n"; | |
127 $text .= 'msgstr "' . $target . '"' . "\n"; | |
128 } | |
129 } | |
130 | |
131 file_prepare_directory($path, FILE_CREATE_DIRECTORY); | |
132 $file = File::create([ | |
133 'uid' => 1, | |
134 'filename' => $filename, | |
135 'uri' => $path . '/' . $filename, | |
136 'filemime' => 'text/x-gettext-translation', | |
137 'timestamp' => $timestamp, | |
138 'status' => FILE_STATUS_PERMANENT, | |
139 ]); | |
140 file_put_contents($file->getFileUri(), $po_header . $text); | |
141 touch(drupal_realpath($file->getFileUri()), $timestamp); | |
142 $file->save(); | |
143 } | |
144 | |
145 /** | |
146 * Setup the environment containing local and remote translation files. | |
147 * | |
148 * Update tests require a simulated environment for local and remote files. | |
149 * Normally remote files are located at a remote server (e.g. ftp.drupal.org). | |
150 * For testing we can not rely on this. A directory in the file system of the | |
151 * test site is designated for remote files and is addressed using an absolute | |
152 * URL. Because Drupal does not allow files with a po extension to be accessed | |
153 * (denied in .htaccess) the translation files get a _po extension. Another | |
154 * directory is designated for local translation files. | |
155 * | |
156 * The environment is set up with the following files. File creation times are | |
157 * set to create different variations in test conditions. | |
158 * contrib_module_one | |
159 * - remote file: timestamp new | |
160 * - local file: timestamp old | |
161 * contrib_module_two | |
162 * - remote file: timestamp old | |
163 * - local file: timestamp new | |
164 * contrib_module_three | |
165 * - remote file: timestamp old | |
166 * - local file: timestamp old | |
167 * custom_module_one | |
168 * - local file: timestamp new | |
169 * Time stamp of current translation set by setCurrentTranslations() is always | |
170 * timestamp medium. This makes it easy to predict which translation will be | |
171 * imported. | |
172 */ | |
173 protected function setTranslationFiles() { | |
174 $config = $this->config('locale.settings'); | |
175 | |
176 // A flag is set to let the locale_test module replace the project data with | |
177 // a set of test projects which match the below project files. | |
178 \Drupal::state()->set('locale.test_projects_alter', TRUE); | |
179 \Drupal::state()->set('locale.remove_core_project', FALSE); | |
180 | |
181 // Setup the environment. | |
182 $public_path = PublicStream::basePath(); | |
183 $this->setTranslationsDirectory($public_path . '/local'); | |
184 $config->set('translation.default_filename', '%project-%version.%language._po')->save(); | |
185 | |
186 // Setting up sets of translations for the translation files. | |
187 $translations_one = ['January' => 'Januar_1', 'February' => 'Februar_1', 'March' => 'Marz_1']; | |
188 $translations_two = ['February' => 'Februar_2', 'March' => 'Marz_2', 'April' => 'April_2']; | |
189 $translations_three = ['April' => 'April_3', 'May' => 'Mai_3', 'June' => 'Juni_3']; | |
190 | |
191 // Add a number of files to the local file system to serve as remote | |
192 // translation server and match the project definitions set in | |
193 // locale_test_locale_translation_projects_alter(). | |
194 $this->makePoFile('remote/8.x/contrib_module_one', 'contrib_module_one-8.x-1.1.de._po', $this->timestampNew, $translations_one); | |
195 $this->makePoFile('remote/8.x/contrib_module_two', 'contrib_module_two-8.x-2.0-beta4.de._po', $this->timestampOld, $translations_two); | |
196 $this->makePoFile('remote/8.x/contrib_module_three', 'contrib_module_three-8.x-1.0.de._po', $this->timestampOld, $translations_three); | |
197 | |
198 // Add a number of files to the local file system to serve as local | |
199 // translation files and match the project definitions set in | |
200 // locale_test_locale_translation_projects_alter(). | |
201 $this->makePoFile('local', 'contrib_module_one-8.x-1.1.de._po', $this->timestampOld, $translations_one); | |
202 $this->makePoFile('local', 'contrib_module_two-8.x-2.0-beta4.de._po', $this->timestampNew, $translations_two); | |
203 $this->makePoFile('local', 'contrib_module_three-8.x-1.0.de._po', $this->timestampOld, $translations_three); | |
204 $this->makePoFile('local', 'custom_module_one.de.po', $this->timestampNew); | |
205 } | |
206 | |
207 /** | |
208 * Setup existing translations in the database and set up the status of | |
209 * existing translations. | |
210 */ | |
211 protected function setCurrentTranslations() { | |
212 // Add non customized translations to the database. | |
213 $langcode = 'de'; | |
214 $context = ''; | |
215 $non_customized_translations = [ | |
216 'March' => 'Marz', | |
217 'June' => 'Juni', | |
218 ]; | |
219 foreach ($non_customized_translations as $source => $translation) { | |
220 $string = $this->container->get('locale.storage')->createString([ | |
221 'source' => $source, | |
222 'context' => $context, | |
223 ]) | |
224 ->save(); | |
225 $this->container->get('locale.storage')->createTranslation([ | |
226 'lid' => $string->getId(), | |
227 'language' => $langcode, | |
228 'translation' => $translation, | |
229 'customized' => LOCALE_NOT_CUSTOMIZED, | |
230 ])->save(); | |
231 } | |
232 | |
233 // Add customized translations to the database. | |
234 $customized_translations = [ | |
235 'January' => 'Januar_customized', | |
236 'February' => 'Februar_customized', | |
237 'May' => 'Mai_customized', | |
238 ]; | |
239 foreach ($customized_translations as $source => $translation) { | |
240 $string = $this->container->get('locale.storage')->createString([ | |
241 'source' => $source, | |
242 'context' => $context, | |
243 ]) | |
244 ->save(); | |
245 $this->container->get('locale.storage')->createTranslation([ | |
246 'lid' => $string->getId(), | |
247 'language' => $langcode, | |
248 'translation' => $translation, | |
249 'customized' => LOCALE_CUSTOMIZED, | |
250 ])->save(); | |
251 } | |
252 | |
253 // Add a state of current translations in locale_files. | |
254 $default = [ | |
255 'langcode' => $langcode, | |
256 'uri' => '', | |
257 'timestamp' => $this->timestampMedium, | |
258 'last_checked' => $this->timestampMedium, | |
259 ]; | |
260 $data[] = [ | |
261 'project' => 'contrib_module_one', | |
262 'filename' => 'contrib_module_one-8.x-1.1.de._po', | |
263 'version' => '8.x-1.1', | |
264 ]; | |
265 $data[] = [ | |
266 'project' => 'contrib_module_two', | |
267 'filename' => 'contrib_module_two-8.x-2.0-beta4.de._po', | |
268 'version' => '8.x-2.0-beta4', | |
269 ]; | |
270 $data[] = [ | |
271 'project' => 'contrib_module_three', | |
272 'filename' => 'contrib_module_three-8.x-1.0.de._po', | |
273 'version' => '8.x-1.0', | |
274 ]; | |
275 $data[] = [ | |
276 'project' => 'custom_module_one', | |
277 'filename' => 'custom_module_one.de.po', | |
278 'version' => '', | |
279 ]; | |
280 foreach ($data as $file) { | |
281 $file = array_merge($default, $file); | |
282 db_insert('locale_file')->fields($file)->execute(); | |
283 } | |
284 } | |
285 | |
286 /** | |
287 * Checks the translation of a string. | |
288 * | |
289 * @param string $source | |
290 * Translation source string. | |
291 * @param string $translation | |
292 * Translation to check. Use empty string to check for a not existing | |
293 * translation. | |
294 * @param string $langcode | |
295 * Language code of the language to translate to. | |
296 * @param string $message | |
297 * (optional) A message to display with the assertion. | |
298 */ | |
299 protected function assertTranslation($source, $translation, $langcode, $message = '') { | |
300 $db_translation = db_query('SELECT translation FROM {locales_target} lt INNER JOIN {locales_source} ls ON ls.lid = lt.lid WHERE ls.source = :source AND lt.language = :langcode', [':source' => $source, ':langcode' => $langcode])->fetchField(); | |
301 $db_translation = $db_translation == FALSE ? '' : $db_translation; | |
302 $this->assertEqual($translation, $db_translation, $message ? $message : format_string('Correct translation of %source (%language)', ['%source' => $source, '%language' => $langcode])); | |
303 } | |
304 | |
305 } |