[BUGFIX] Add missing namespace parts
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Tests / Unit / Form / FormDataProvider / DatabaseSystemLanguageRowsTest.php
1 <?php
2 namespace TYPO3\CMS\Backend\Tests\Unit\Form\FormDataProvider;
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 Doctrine\DBAL\Driver\Statement;
18 use Prophecy\Argument;
19 use Prophecy\Prophecy\ObjectProphecy;
20 use TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseSystemLanguageRows;
21 use TYPO3\CMS\Core\Database\ConnectionPool;
22 use TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder;
23 use TYPO3\CMS\Core\Database\Query\QueryBuilder;
24 use TYPO3\CMS\Core\Database\Query\Restriction\QueryRestrictionContainerInterface;
25 use TYPO3\CMS\Core\Messaging\FlashMessage;
26 use TYPO3\CMS\Core\Messaging\FlashMessageQueue;
27 use TYPO3\CMS\Core\Messaging\FlashMessageService;
28 use TYPO3\CMS\Core\Utility\GeneralUtility;
29 use TYPO3\CMS\Lang\LanguageService;
30
31 /**
32 * Test case
33 */
34 class DatabaseSystemLanguageRowsTest extends \TYPO3\Components\TestingFramework\Core\Unit\UnitTestCase
35 {
36 /**
37 * @var DatabaseSystemLanguageRows
38 */
39 protected $subject;
40
41 /**
42 * @var array A backup of registered singleton instances
43 */
44 protected $singletonInstances = [];
45
46 protected function setUp()
47 {
48 $this->singletonInstances = GeneralUtility::getSingletonInstances();
49 $languageService = $this->prophesize(LanguageService::class);
50 $GLOBALS['LANG'] = $languageService->reveal();
51 $languageService->sL(Argument::cetera())->willReturnArgument(0);
52 $this->subject = new DatabaseSystemLanguageRows();
53 }
54
55 protected function tearDown()
56 {
57 GeneralUtility::purgeInstances();
58 GeneralUtility::resetSingletonInstances($this->singletonInstances);
59 parent::tearDown();
60 }
61
62 /**
63 * @test
64 */
65 public function addDataSetsDefaultLanguageAndAllEntries()
66 {
67 $expected = [
68 'systemLanguageRows' => [
69 -1 => [
70 'uid' => -1,
71 'title' => 'LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf:multipleLanguages',
72 'iso' => 'DEF',
73 'flagIconIdentifier' => 'flags-multiple',
74 ],
75 0 => [
76 'uid' => 0,
77 'title' => 'LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf:defaultLanguage',
78 'iso' => 'DEF',
79 'flagIconIdentifier' => 'empty-empty',
80 ],
81 ],
82 ];
83
84 // Prophecies and revelations for a lot of the database stack classes
85 $queryBuilderProphecy = $this->prophesize(QueryBuilder::class);
86 $queryBuilderRevelation = $queryBuilderProphecy->reveal();
87 $connectionPoolProphecy = $this->prophesize(ConnectionPool::class);
88 $queryRestrictionContainerProphecy = $this->prophesize(QueryRestrictionContainerInterface::class);
89 $queryRestrictionContainerRevelation = $queryRestrictionContainerProphecy->reveal();
90 $expressionBuilderProphecy = $this->prophesize(ExpressionBuilder::class);
91 $statementProphecy = $this->prophesize(Statement::class);
92
93 // Register connection pool revelation in framework, this is the entry point used by the system during tests
94 GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolProphecy->reveal());
95
96 // Simulate method call flow on database objects and verify correct query is built
97 $connectionPoolProphecy->getQueryBuilderForTable('sys_language')->shouldBeCalled()->willReturn($queryBuilderRevelation);
98 $queryRestrictionContainerProphecy->removeAll()->shouldBeCalled()->willReturn($queryRestrictionContainerRevelation);
99 $queryBuilderProphecy->getRestrictions()->shouldBeCalled()->willReturn($queryRestrictionContainerRevelation);
100 $queryBuilderProphecy->select('uid', 'title', 'language_isocode', 'flag')->shouldBeCalled()->willReturn($queryBuilderRevelation);
101 $queryBuilderProphecy->from('sys_language')->shouldBeCalled()->willReturn($queryBuilderRevelation);
102 $queryBuilderProphecy->orderBy('sorting')->shouldBeCalled()->willReturn($queryBuilderRevelation);
103 $queryBuilderProphecy->expr()->shouldBeCalled()->willReturn($expressionBuilderProphecy->reveal());
104 $expressionBuilderProphecy->eq('pid', 0)->shouldBeCalled()->willReturn('pid = 0');
105 $queryBuilderProphecy->where('pid = 0')->shouldBeCalled()->willReturn($queryBuilderRevelation);
106 $queryBuilderProphecy->createNamedParameter(Argument::cetera())->willReturnArgument(0);
107 $queryBuilderProphecy->execute()->shouldBeCalled()->willReturn($statementProphecy->reveal());
108 $statementProphecy->fetch()->shouldBeCalledTimes(1)->willReturn(false);
109
110 $this->assertSame($expected, $this->subject->addData([]));
111 }
112
113 /**
114 * @test
115 */
116 public function addDataSetsDefaultLanguageTitleFromPageTsConfig()
117 {
118 $input = [
119 'pageTsConfig' => [
120 'mod.' => [
121 'SHARED.' => [
122 'defaultLanguageLabel' => 'foo',
123 ],
124 ]
125 ],
126 ];
127
128 // Prophecies and revelations for a lot of the database stack classes
129 $queryBuilderProphecy = $this->prophesize(QueryBuilder::class);
130 $queryBuilderRevelation = $queryBuilderProphecy->reveal();
131 $connectionPoolProphecy = $this->prophesize(ConnectionPool::class);
132 $queryRestrictionContainerProphecy = $this->prophesize(QueryRestrictionContainerInterface::class);
133 $queryRestrictionContainerRevelation = $queryRestrictionContainerProphecy->reveal();
134 $expressionBuilderProphecy = $this->prophesize(ExpressionBuilder::class);
135 $statementProphecy = $this->prophesize(Statement::class);
136
137 // Register connection pool revelation in framework, this is the entry point used by the system during tests
138 GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolProphecy->reveal());
139
140 // Simulate method call flow on database objects and verify correct query is built
141 $connectionPoolProphecy->getQueryBuilderForTable('sys_language')->shouldBeCalled()->willReturn($queryBuilderRevelation);
142 $queryRestrictionContainerProphecy->removeAll()->shouldBeCalled()->willReturn($queryRestrictionContainerRevelation);
143 $queryBuilderProphecy->getRestrictions()->shouldBeCalled()->willReturn($queryRestrictionContainerRevelation);
144 $queryBuilderProphecy->select('uid', 'title', 'language_isocode', 'flag')->shouldBeCalled()->willReturn($queryBuilderRevelation);
145 $queryBuilderProphecy->from('sys_language')->shouldBeCalled()->willReturn($queryBuilderRevelation);
146 $queryBuilderProphecy->orderBy('sorting')->shouldBeCalled()->willReturn($queryBuilderRevelation);
147 $queryBuilderProphecy->expr()->shouldBeCalled()->willReturn($expressionBuilderProphecy->reveal());
148 $expressionBuilderProphecy->eq('pid', 0)->shouldBeCalled()->willReturn('pid = 0');
149 $queryBuilderProphecy->where('pid = 0')->shouldBeCalled()->willReturn($queryBuilderRevelation);
150 $queryBuilderProphecy->createNamedParameter(Argument::cetera())->willReturnArgument(0);
151 $queryBuilderProphecy->execute()->shouldBeCalled()->willReturn($statementProphecy->reveal());
152 $statementProphecy->fetch()->shouldBeCalledTimes(1)->willReturn(false);
153
154 $expected = $input;
155 $expected['systemLanguageRows'] = [
156 -1 => [
157 'uid' => -1,
158 'title' => 'LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf:multipleLanguages',
159 'iso' => 'DEF',
160 'flagIconIdentifier' => 'flags-multiple',
161 ],
162 0 => [
163 'uid' => 0,
164 'title' => 'foo (LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf:defaultLanguage)',
165 'iso' => 'DEF',
166 'flagIconIdentifier' => 'empty-empty',
167 ],
168 ];
169 $this->assertSame($expected, $this->subject->addData($input));
170 }
171
172 /**
173 * @test
174 */
175 public function addDataSetsDefaultLanguageFlagFromPageTsConfig()
176 {
177 $input = [
178 'pageTsConfig' => [
179 'mod.' => [
180 'SHARED.' => [
181 'defaultLanguageFlag' => 'uk',
182 ],
183 ]
184 ],
185 ];
186
187 // Prophecies and revelations for a lot of the database stack classes
188 $queryBuilderProphecy = $this->prophesize(QueryBuilder::class);
189 $queryBuilderRevelation = $queryBuilderProphecy->reveal();
190 $connectionPoolProphecy = $this->prophesize(ConnectionPool::class);
191 $queryRestrictionContainerProphecy = $this->prophesize(QueryRestrictionContainerInterface::class);
192 $queryRestrictionContainerRevelation = $queryRestrictionContainerProphecy->reveal();
193 $expressionBuilderProphecy = $this->prophesize(ExpressionBuilder::class);
194 $statementProphecy = $this->prophesize(Statement::class);
195
196 // Register connection pool revelation in framework, this is the entry point used by the system during tests
197 GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolProphecy->reveal());
198
199 // Simulate method call flow on database objects and verify correct query is built
200 $connectionPoolProphecy->getQueryBuilderForTable('sys_language')->shouldBeCalled()->willReturn($queryBuilderRevelation);
201 $queryRestrictionContainerProphecy->removeAll()->shouldBeCalled()->willReturn($queryRestrictionContainerRevelation);
202 $queryBuilderProphecy->getRestrictions()->shouldBeCalled()->willReturn($queryRestrictionContainerRevelation);
203 $queryBuilderProphecy->select('uid', 'title', 'language_isocode', 'flag')->shouldBeCalled()->willReturn($queryBuilderRevelation);
204 $queryBuilderProphecy->from('sys_language')->shouldBeCalled()->willReturn($queryBuilderRevelation);
205 $queryBuilderProphecy->orderBy('sorting')->shouldBeCalled()->willReturn($queryBuilderRevelation);
206 $queryBuilderProphecy->expr()->shouldBeCalled()->willReturn($expressionBuilderProphecy->reveal());
207 $expressionBuilderProphecy->eq('pid', 0)->shouldBeCalled()->willReturn('pid = 0');
208 $queryBuilderProphecy->where('pid = 0')->shouldBeCalled()->willReturn($queryBuilderRevelation);
209 $queryBuilderProphecy->createNamedParameter(Argument::cetera())->willReturnArgument(0);
210 $queryBuilderProphecy->execute()->shouldBeCalled()->willReturn($statementProphecy->reveal());
211 $statementProphecy->fetch()->shouldBeCalledTimes(1)->willReturn(false);
212
213 $expected = $input;
214 $expected['systemLanguageRows'] = [
215 -1 => [
216 'uid' => -1,
217 'title' => 'LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf:multipleLanguages',
218 'iso' => 'DEF',
219 'flagIconIdentifier' => 'flags-multiple',
220 ],
221 0 => [
222 'uid' => 0,
223 'title' => 'LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf:defaultLanguage',
224 'iso' => 'DEF',
225 'flagIconIdentifier' => 'flags-uk',
226 ],
227 ];
228 $this->assertSame($expected, $this->subject->addData($input));
229 }
230
231 /**
232 * @test
233 */
234 public function addDataResolvesLanguageIsocodeFromDatabaseField()
235 {
236 $aDatabaseResultRow = [
237 'uid' => 3,
238 'title' => 'french',
239 'language_isocode' => 'fr',
240 'static_lang_isocode' => '',
241 'flag' => 'fr',
242 ];
243
244 // Prophecies and revelations for a lot of the database stack classes
245 $queryBuilderProphecy = $this->prophesize(QueryBuilder::class);
246 $queryBuilderRevelation = $queryBuilderProphecy->reveal();
247 $connectionPoolProphecy = $this->prophesize(ConnectionPool::class);
248 $queryRestrictionContainerProphecy = $this->prophesize(QueryRestrictionContainerInterface::class);
249 $queryRestrictionContainerRevelation = $queryRestrictionContainerProphecy->reveal();
250 $expressionBuilderProphecy = $this->prophesize(ExpressionBuilder::class);
251 $statementProphecy = $this->prophesize(Statement::class);
252
253 // Register connection pool revelation in framework, this is the entry point used by the system during tests
254 GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolProphecy->reveal());
255
256 // Simulate method call flow on database objects and verify correct query is built
257 $connectionPoolProphecy->getQueryBuilderForTable('sys_language')->shouldBeCalled()->willReturn($queryBuilderRevelation);
258 $queryRestrictionContainerProphecy->removeAll()->shouldBeCalled()->willReturn($queryRestrictionContainerRevelation);
259 $queryBuilderProphecy->orderBy('sorting')->shouldBeCalled()->willReturn($queryBuilderRevelation);
260 $queryBuilderProphecy->getRestrictions()->shouldBeCalled()->willReturn($queryRestrictionContainerRevelation);
261 $queryBuilderProphecy->select('uid', 'title', 'language_isocode', 'flag')->shouldBeCalled()->willReturn($queryBuilderRevelation);
262 $queryBuilderProphecy->from('sys_language')->shouldBeCalled()->willReturn($queryBuilderRevelation);
263 $queryBuilderProphecy->expr()->shouldBeCalled()->willReturn($expressionBuilderProphecy->reveal());
264 $expressionBuilderProphecy->eq('pid', 0)->shouldBeCalled()->willReturn('pid = 0');
265 $queryBuilderProphecy->where('pid = 0')->shouldBeCalled()->willReturn($queryBuilderRevelation);
266 $queryBuilderProphecy->createNamedParameter(Argument::cetera())->willReturnArgument(0);
267 $queryBuilderProphecy->execute()->shouldBeCalled()->willReturn($statementProphecy->reveal());
268
269 $statementProphecy->fetch()->shouldBeCalledTimes(2)->willReturn($aDatabaseResultRow, false);
270
271 $expected = [
272 'systemLanguageRows' => [
273 -1 => [
274 'uid' => -1,
275 'title' => 'LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf:multipleLanguages',
276 'iso' => 'DEF',
277 'flagIconIdentifier' => 'flags-multiple',
278 ],
279 0 => [
280 'uid' => 0,
281 'title' => 'LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf:defaultLanguage',
282 'iso' => 'DEF',
283 'flagIconIdentifier' => 'empty-empty',
284 ],
285 3 => [
286 'uid' => 3,
287 'title' => 'french',
288 'flagIconIdentifier' => 'flags-fr',
289 'iso' => 'fr',
290 ],
291 ],
292 ];
293 $this->assertSame($expected, $this->subject->addData([]));
294 }
295
296 /**
297 * @test
298 */
299 public function addDataAddFlashMessageWithMissingIsoCode()
300 {
301 $aDatabaseResultRow = [
302 'uid' => 3,
303 'title' => 'french',
304 'language_isocode' => '',
305 'static_lang_isocode' => '',
306 'flag' => 'fr',
307 ];
308
309 // Prophecies and revelations for a lot of the database stack classes
310 $queryBuilderProphecy = $this->prophesize(QueryBuilder::class);
311 $queryBuilderRevelation = $queryBuilderProphecy->reveal();
312 $connectionPoolProphecy = $this->prophesize(ConnectionPool::class);
313 $queryRestrictionContainerProphecy = $this->prophesize(QueryRestrictionContainerInterface::class);
314 $queryRestrictionContainerRevelation = $queryRestrictionContainerProphecy->reveal();
315 $expressionBuilderProphecy = $this->prophesize(ExpressionBuilder::class);
316 $statementProphecy = $this->prophesize(Statement::class);
317
318 // Register connection pool revelation in framework, this is the entry point used by the system during tests
319 GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolProphecy->reveal());
320
321 // Simulate method call flow on database objects and verify correct query is built
322 $connectionPoolProphecy->getQueryBuilderForTable('sys_language')->shouldBeCalled()->willReturn($queryBuilderRevelation);
323 $queryRestrictionContainerProphecy->removeAll()->shouldBeCalled()->willReturn($queryRestrictionContainerRevelation);
324 $queryBuilderProphecy->getRestrictions()->shouldBeCalled()->willReturn($queryRestrictionContainerRevelation);
325 $queryBuilderProphecy->select('uid', 'title', 'language_isocode', 'flag')->shouldBeCalled()->willReturn($queryBuilderRevelation);
326 $queryBuilderProphecy->from('sys_language')->shouldBeCalled()->willReturn($queryBuilderRevelation);
327 $queryBuilderProphecy->orderBy('sorting')->shouldBeCalled()->willReturn($queryBuilderRevelation);
328 $queryBuilderProphecy->expr()->shouldBeCalled()->willReturn($expressionBuilderProphecy->reveal());
329 $expressionBuilderProphecy->eq('pid', 0)->shouldBeCalled()->willReturn('pid = 0');
330 $queryBuilderProphecy->where('pid = 0')->shouldBeCalled()->willReturn($queryBuilderRevelation);
331 $queryBuilderProphecy->createNamedParameter(Argument::cetera())->willReturnArgument(0);
332 $queryBuilderProphecy->execute()->shouldBeCalled()->willReturn($statementProphecy->reveal());
333
334 $statementProphecy->fetch()->shouldBeCalledTimes(2)->willReturn($aDatabaseResultRow, false);
335
336 // Needed for backendUtility::getRecord()
337 $GLOBALS['TCA']['static_languages'] = [ 'foo' ];
338 $expected = [
339 'systemLanguageRows' => [
340 -1 => [
341 'uid' => -1,
342 'title' => 'LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf:multipleLanguages',
343 'iso' => 'DEF',
344 'flagIconIdentifier' => 'flags-multiple',
345 ],
346 0 => [
347 'uid' => 0,
348 'title' => 'LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf:defaultLanguage',
349 'iso' => 'DEF',
350 'flagIconIdentifier' => 'empty-empty',
351 ],
352 3 => [
353 'uid' => 3,
354 'title' => 'french',
355 'flagIconIdentifier' => 'flags-fr',
356 'iso' => '',
357 ],
358 ],
359 ];
360
361 /** @var FlashMessage|ObjectProphecy $flashMessage */
362 $flashMessage = $this->prophesize(FlashMessage::class);
363 GeneralUtility::addInstance(FlashMessage::class, $flashMessage->reveal());
364 /** @var FlashMessageService|ObjectProphecy $flashMessageService */
365 $flashMessageService = $this->prophesize(FlashMessageService::class);
366 GeneralUtility::setSingletonInstance(FlashMessageService::class, $flashMessageService->reveal());
367 /** @var FlashMessageQueue|ObjectProphecy $flashMessageQueue */
368 $flashMessageQueue = $this->prophesize(FlashMessageQueue::class);
369 $flashMessageService->getMessageQueueByIdentifier(Argument::cetera())->willReturn($flashMessageQueue->reveal());
370
371 $flashMessageQueue->enqueue($flashMessage)->shouldBeCalled();
372
373 $this->assertSame($expected, $this->subject->addData([]));
374 }
375 }