[!!!][TASK] Extract testing framework for TYPO3
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Tests / Unit / Utility / LocalizationUtilityTest.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Tests\Unit\Utility;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
18
19 /**
20 * Test case
21 */
22 class LocalizationUtilityTest extends \TYPO3\CMS\Components\TestingFramework\Core\UnitTestCase
23 {
24 /**
25 * Instance of configurationManager, injected to subject
26 *
27 * @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManager
28 */
29 protected $configurationManagerMock;
30
31 /**
32 * LOCAL_LANG array fixture
33 *
34 * @var array
35 */
36 protected $LOCAL_LANG = [
37 'extensionKey' => [
38 'default' => [
39 'key1' => [
40 [
41 'source' => 'English label for key1',
42 'target' => 'English label for key1',
43 ]
44 ],
45 'key2' => [
46 [
47 'source' => 'English label for key2',
48 'target' => 'English label for key2',
49 ]
50 ],
51 'key3' => [
52 [
53 'source' => 'English label for key3',
54 'target' => 'English label for key3',
55 ]
56 ],
57 'key4' => [
58 [
59 'source' => 'English label for key4',
60 'target' => 'English label for key4',
61 ]
62 ],
63 'keyWithPlaceholder' => [
64 [
65 'source' => 'English label with number %d',
66 'target' => 'English label with number %d',
67 ]
68 ],
69 ],
70 'dk' => [
71 'key1' => [
72 [
73 'source' => 'English label for key1',
74 'target' => 'Dansk label for key1',
75 ]
76 ],
77 // not translated in dk => no target (llxml)
78 'key2' => [
79 [
80 'source' => 'English label for key2',
81 ]
82 ],
83 'key3' => [
84 [
85 'source' => 'English label for key3',
86 ]
87 ],
88 // not translated in dk => empty target (xliff)
89 'key4' => [
90 [
91 'source' => 'English label for key4',
92 'target' => '',
93 ]
94 ],
95 // not translated in dk => empty target (xliff)
96 'key5' => [
97 [
98 'source' => 'English label for key5',
99 'target' => '',
100 ]
101 ],
102 'keyWithPlaceholder' => [
103 [
104 'source' => 'English label with number %d',
105 ]
106 ],
107 ],
108 // fallback language for labels which are not translated in dk
109 'dk_alt' => [
110 'key1' => [
111 [
112 'source' => 'English label for key1',
113 ]
114 ],
115 'key2' => [
116 [
117 'source' => 'English label for key2',
118 'target' => 'Dansk alternative label for key2',
119 ]
120 ],
121 'key3' => [
122 [
123 'source' => 'English label for key3',
124 ]
125 ],
126 // not translated in dk_alt => empty target (xliff)
127 'key4' => [
128 [
129 'source' => 'English label for key4',
130 'target' => '',
131 ]
132 ],
133 'key5' => [
134 [
135 'source' => 'English label for key5',
136 'target' => 'Dansk alternative label for key5',
137 ]
138 ],
139 'keyWithPlaceholder' => [
140 [
141 'source' => 'English label with number %d',
142 ]
143 ],
144 ],
145
146 ],
147 ];
148
149 /**
150 * Prepare class mocking some dependencies
151 */
152 protected function setUp()
153 {
154 $reflectionClass = new \ReflectionClass(\TYPO3\CMS\Extbase\Utility\LocalizationUtility::class);
155
156 $this->configurationManager = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Configuration\ConfigurationManager::class, ['getConfiguration']);
157 $property = $reflectionClass->getProperty('configurationManager');
158 $property->setAccessible(true);
159 $property->setValue($this->configurationManager);
160 }
161
162 /**
163 * Reset static properties
164 */
165 protected function tearDown()
166 {
167 $reflectionClass = new \ReflectionClass(\TYPO3\CMS\Extbase\Utility\LocalizationUtility::class);
168
169 $property = $reflectionClass->getProperty('configurationManager');
170 $property->setAccessible(true);
171 $property->setValue(null);
172
173 $property = $reflectionClass->getProperty('LOCAL_LANG');
174 $property->setAccessible(true);
175 $property->setValue([]);
176
177 $property = $reflectionClass->getProperty('languageKey');
178 $property->setAccessible(true);
179 $property->setValue('default');
180
181 $property = $reflectionClass->getProperty('alternativeLanguageKeys');
182 $property->setAccessible(true);
183 $property->setValue([]);
184 }
185
186 /**
187 * @test
188 */
189 public function implodeTypoScriptLabelArrayWorks()
190 {
191 $reflectionClass = new \ReflectionClass(\TYPO3\CMS\Extbase\Utility\LocalizationUtility::class);
192 $method = $reflectionClass->getMethod('flattenTypoScriptLabelArray');
193 $method->setAccessible(true);
194
195 $expected = [
196 'key1' => 'value1',
197 'key2' => 'value2',
198 'key3.subkey1' => 'subvalue1',
199 'key3.subkey2.subsubkey' => 'val'
200 ];
201 $input = [
202 'key1' => 'value1',
203 'key2' => 'value2',
204 'key3' => [
205 'subkey1' => 'subvalue1',
206 'subkey2' => [
207 'subsubkey' => 'val'
208 ]
209 ]
210 ];
211 $result = $method->invoke(null, $input);
212 $this->assertEquals($expected, $result);
213 }
214
215 /**
216 * @test
217 */
218 public function translateForEmptyStringKeyReturnsNull()
219 {
220 $this->assertNull(LocalizationUtility::translate('', 'extbase'));
221 }
222
223 /**
224 * @test
225 */
226 public function translateForEmptyStringKeyWithArgumentsReturnsNull()
227 {
228 $this->assertNull(LocalizationUtility::translate('', 'extbase', ['argument']));
229 }
230
231 /**
232 * @return array
233 */
234 public function translateDataProvider()
235 {
236 return [
237 'get translated key' =>
238 ['key1', $this->LOCAL_LANG, 'dk', 'Dansk label for key1'],
239
240 'fallback to English when translation is missing for key' =>
241 ['key2', $this->LOCAL_LANG, 'dk', 'English label for key2'],
242
243 'fallback to English for non existing language' =>
244 ['key2', $this->LOCAL_LANG, 'xx', 'English label for key2'],
245
246 'replace placeholder with argument' =>
247 ['keyWithPlaceholder', $this->LOCAL_LANG, 'en', 'English label with number 100', [], [100]],
248
249 'get translated key from primary language' =>
250 ['key1', $this->LOCAL_LANG, 'dk', 'Dansk label for key1', ['dk_alt']],
251
252 'fallback to alternative language if translation is missing(llxml)' =>
253 ['key2', $this->LOCAL_LANG, 'dk', 'Dansk alternative label for key2', ['dk_alt']],
254
255 'fallback to alternative language if translation is missing(xlif)' =>
256 ['key5', $this->LOCAL_LANG, 'dk', 'Dansk alternative label for key5', ['dk_alt']],
257
258 'fallback to English for label not translated in dk and dk_alt(llxml)' =>
259 ['key3', $this->LOCAL_LANG, 'dk', 'English label for key3', ['dk_alt']],
260
261 'fallback to English for label not translated in dk and dk_alt(xlif)' =>
262 ['key4', $this->LOCAL_LANG, 'dk', 'English label for key4', ['dk_alt']],
263 ];
264 }
265
266 /**
267 * @param string $key
268 * @param array $LOCAL_LANG
269 * @param string $languageKey
270 * @param string $expected
271 * @param array $altLanguageKeys
272 * @param array $arguments
273 * @return void
274 * @dataProvider translateDataProvider
275 * @test
276 */
277 public function translateTest($key, array $LOCAL_LANG, $languageKey, $expected, array $altLanguageKeys = [], array $arguments = null)
278 {
279 $reflectionClass = new \ReflectionClass(\TYPO3\CMS\Extbase\Utility\LocalizationUtility::class);
280
281 $property = $reflectionClass->getProperty('LOCAL_LANG');
282 $property->setAccessible(true);
283 $property->setValue($LOCAL_LANG);
284
285 $property = $reflectionClass->getProperty('languageKey');
286 $property->setAccessible(true);
287 $property->setValue($languageKey);
288
289 $property = $reflectionClass->getProperty('alternativeLanguageKeys');
290 $property->setAccessible(true);
291 $property->setValue($altLanguageKeys);
292
293 $this->assertEquals($expected, LocalizationUtility::translate($key, 'extensionKey', $arguments));
294 }
295
296 /**
297 * @return array
298 */
299 public function loadTypoScriptLabelsProvider()
300 {
301 return [
302 'override labels with typoscript' => [
303 'LOCAL_LANG' => [
304 'extensionKey' => [
305 'dk' => [
306 'key1' => [
307 [
308 'source' => 'English label for key1',
309 'target' => 'Dansk label for key1 extensionKey',
310 ]
311 ],
312 'key2' => [
313 [
314 'source' => 'English label for key2',
315 ]
316 ],
317 'key3.subkey1' => [
318 [
319 'source' => 'English label for key3',
320 ]
321 ],
322 ],
323 ],
324 'extensionKey1' => [
325 'dk' => [
326 'key1' => [
327 [
328 'source' => 'English label for key1',
329 'target' => 'Dansk label for key1 extensionKey1',
330 ]
331 ],
332 'key2' => [
333 [
334 'source' => 'English label for key2',
335 ]
336 ],
337 'key3.subkey1' => [
338 [
339 'source' => 'English label for key3',
340 ]
341 ],
342 ],
343 ],
344 ],
345 'typoscript LOCAL_LANG' => [
346 '_LOCAL_LANG' => [
347 'dk' => [
348 'key1' => 'key1 value from TS extensionKey',
349 'key3' => [
350 'subkey1' => 'key3.subkey1 value from TS extensionKey',
351 // this key doesn't exist in xml files
352 'subkey2' => [
353 'subsubkey' => 'key3.subkey2.subsubkey value from TS extensionKey'
354 ]
355 ]
356 ]
357 ]
358 ],
359 'language key' => 'dk',
360 'expected' => [
361 'key1' => [
362 [
363 'source' => 'English label for key1',
364 'target' => 'key1 value from TS extensionKey',
365 ]
366 ],
367 'key2' => [
368 [
369 'source' => 'English label for key2',
370 ]
371 ],
372 'key3.subkey1' => [
373 [
374 'source' => 'English label for key3',
375 'target' => 'key3.subkey1 value from TS extensionKey',
376 ]
377 ],
378 'key3.subkey2.subsubkey' => [
379 [
380 'target' => 'key3.subkey2.subsubkey value from TS extensionKey',
381 ]
382 ],
383 ],
384 ]
385 ];
386 }
387
388 /**
389 * Tests whether labels from xml are overwritten by TypoScript labels
390 *
391 * @param array $LOCAL_LANG
392 * @param array $typoScriptLocalLang
393 * @param string $languageKey
394 * @param array $expected
395 * @return void
396 * @dataProvider loadTypoScriptLabelsProvider
397 * @test
398 */
399 public function loadTypoScriptLabels(array $LOCAL_LANG, array $typoScriptLocalLang, $languageKey, array $expected)
400 {
401 $reflectionClass = new \ReflectionClass(\TYPO3\CMS\Extbase\Utility\LocalizationUtility::class);
402
403 $property = $reflectionClass->getProperty('LOCAL_LANG');
404 $property->setAccessible(true);
405 $property->setValue($LOCAL_LANG);
406
407 $property = $reflectionClass->getProperty('languageKey');
408 $property->setAccessible(true);
409 $property->setValue($languageKey);
410
411 $configurationType = \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK;
412 $this->configurationManager->expects($this->at(0))->method('getConfiguration')->with($configurationType, 'extensionKey', null)->will($this->returnValue($typoScriptLocalLang));
413
414 $method = $reflectionClass->getMethod('loadTypoScriptLabels');
415 $method->setAccessible(true);
416 $method->invoke(null, 'extensionKey');
417
418 $property = $reflectionClass->getProperty('LOCAL_LANG');
419 $property->setAccessible(true);
420 $result = $property->getValue();
421
422 $this->assertEquals($expected, $result['extensionKey'][$languageKey]);
423 }
424
425 /**
426 * @return void
427 * @test
428 */
429 public function clearLabelWithTypoScript()
430 {
431 $reflectionClass = new \ReflectionClass(\TYPO3\CMS\Extbase\Utility\LocalizationUtility::class);
432
433 $property = $reflectionClass->getProperty('LOCAL_LANG');
434 $property->setAccessible(true);
435 $property->setValue($this->LOCAL_LANG);
436
437 $property = $reflectionClass->getProperty('languageKey');
438 $property->setAccessible(true);
439 $property->setValue('dk');
440
441 $typoScriptLocalLang = [
442 '_LOCAL_LANG' => [
443 'dk' => [
444 'key1' => '',
445 ]
446 ]
447 ];
448
449 $configurationType = \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK;
450 $this->configurationManager->expects($this->at(0))->method('getConfiguration')->with($configurationType, 'extensionKey', null)->will($this->returnValue($typoScriptLocalLang));
451
452 $method = $reflectionClass->getMethod('loadTypoScriptLabels');
453 $method->setAccessible(true);
454 $method->invoke(null, 'extensionKey');
455
456 $result = LocalizationUtility::translate('key1', 'extensionKey');
457 $this->assertNotNull($result);
458 $this->assertEquals('', $result);
459 }
460 }