865ad7a141ef608626abced802658a4c682213b8
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Tests / Unit / Form / FormDataProvider / TcaRadioItemsTest.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 Prophecy\Argument;
18 use Prophecy\Prophecy\ObjectProphecy;
19 use TYPO3\CMS\Backend\Form\FormDataProvider\TcaRadioItems;
20 use TYPO3\CMS\Core\Localization\LanguageService;
21 use TYPO3\CMS\Core\Messaging\FlashMessage;
22 use TYPO3\CMS\Core\Messaging\FlashMessageQueue;
23 use TYPO3\CMS\Core\Messaging\FlashMessageService;
24 use TYPO3\CMS\Core\Utility\GeneralUtility;
25
26 /**
27 * Test case
28 */
29 class TcaRadioItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
30 {
31 /**
32 * Subject is not notice free, disable E_NOTICES
33 */
34 protected static $suppressNotices = true;
35
36 /**
37 * @var TcaRadioItems
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 $this->subject = new TcaRadioItems();
50 }
51
52 protected function tearDown()
53 {
54 GeneralUtility::purgeInstances();
55 GeneralUtility::resetSingletonInstances($this->singletonInstances);
56 parent::tearDown();
57 }
58
59 /**
60 * @test
61 */
62 public function addDataThrowsExceptionIfRadioItemsNotDefined()
63 {
64 $input = [
65 'processedTca' => [
66 'columns' => [
67 'aField' => [
68 'config' => [
69 'type' => 'radio',
70 ],
71 ],
72 ],
73 ],
74 ];
75 $this->expectException(\UnexpectedValueException::class);
76 $this->expectExceptionCode(1438594829);
77 $this->subject->addData($input);
78 }
79
80 /**
81 * @test
82 */
83 public function addDataKeepExistingItems()
84 {
85 $input = [
86 'processedTca' => [
87 'columns' => [
88 'aField' => [
89 'config' => [
90 'type' => 'radio',
91 'items' => [
92 0 => [
93 'foo',
94 'bar',
95 ],
96 ],
97 ],
98 ],
99 ],
100 ],
101 ];
102 $languageService = $this->prophesize(LanguageService::class);
103 $GLOBALS['LANG'] = $languageService->reveal();
104 $languageService->sL(Argument::cetera())->willReturnArgument(0);
105
106 $expected = $input;
107 $this->assertSame($expected, $this->subject->addData($input));
108 }
109
110 /**
111 * @test
112 */
113 public function addDataThrowsExceptionIfItemsAreNoArray()
114 {
115 $input = [
116 'processedTca' => [
117 'columns' => [
118 'aField' => [
119 'config' => [
120 'type' => 'radio',
121 'items' => [
122 0 => 'aoeu',
123 ],
124 ],
125 ],
126 ],
127 ],
128 ];
129 $this->expectException(\UnexpectedValueException::class);
130 $this->expectExceptionCode(1438607163);
131 $this->subject->addData($input);
132 }
133
134 /**
135 * @test
136 */
137 public function addDataThrowsExceptionIfItemLabelIsNotSet()
138 {
139 $input = [
140 'processedTca' => [
141 'columns' => [
142 'aField' => [
143 'config' => [
144 'type' => 'radio',
145 'items' => [
146 0 => [
147 'funnyKey' => 'funnyValue',
148 ],
149 ],
150 ],
151 ],
152 ],
153 ],
154 ];
155 $this->expectException(\UnexpectedValueException::class);
156 $this->expectExceptionCode(1438607164);
157 $this->subject->addData($input);
158 }
159
160 /**
161 * @test
162 */
163 public function addDataThrowsExceptionIfItemValueIsNotSet()
164 {
165 $input = [
166 'processedTca' => [
167 'columns' => [
168 'aField' => [
169 'config' => [
170 'type' => 'radio',
171 'items' => [
172 0 => [
173 0 => 'aLabel',
174 ],
175 ],
176 ],
177 ],
178 ],
179 ],
180 ];
181 $this->expectException(\UnexpectedValueException::class);
182 $this->expectExceptionCode(1438607165);
183 $this->subject->addData($input);
184 }
185
186 /**
187 * @test
188 */
189 public function addDataTranslatesItemLabels()
190 {
191 $input = [
192 'processedTca' => [
193 'columns' => [
194 'aField' => [
195 'config' => [
196 'type' => 'radio',
197 'items' => [
198 0 => [
199 0 => 'aLabel',
200 1 => 'aValue',
201 ],
202 ],
203 ],
204 ],
205 ],
206 ],
207 ];
208
209 /** @var LanguageService|ObjectProphecy $languageService */
210 $languageService = $this->prophesize(LanguageService::class);
211 $GLOBALS['LANG'] = $languageService->reveal();
212
213 $languageService->sL('aLabel')->shouldBeCalled()->willReturn('translated');
214
215 $expected = $input;
216 $expected['processedTca']['columns']['aField']['config']['items'][0][0] = 'translated';
217
218 $this->assertSame($expected, $this->subject->addData($input));
219 $this->subject->addData($input);
220 }
221
222 /**
223 * @test
224 */
225 public function addDataCallsItemsProcFunc()
226 {
227 $input = [
228 'tableName' => 'aTable',
229 'databaseRow' => [],
230 'processedTca' => [
231 'columns' => [
232 'aField' => [
233 'config' => [
234 'type' => 'radio',
235 'items' => [],
236 'itemsProcFunc' => function (array $parameters, $pObj) {
237 $parameters['items'] = [
238 'foo' => 'bar',
239 ];
240 },
241 ],
242 ],
243 ],
244 ],
245 ];
246 $expected = $input;
247 $expected['processedTca']['columns']['aField']['config'] = [
248 'type' => 'radio',
249 'items' => [
250 'foo' => 'bar',
251 ],
252 ];
253 $this->assertSame($expected, $this->subject->addData($input));
254 }
255
256 /**
257 * @test
258 */
259 public function addDataItemsProcFuncReceivesParameters()
260 {
261 $input = [
262 'tableName' => 'aTable',
263 'databaseRow' => [
264 'aField' => 'aValue',
265 ],
266 'pageTsConfig' => [
267 'TCEFORM.' => [
268 'aTable.' => [
269 'aField.' => [
270 'itemsProcFunc.' => [
271 'itemParamKey' => 'itemParamValue',
272 ],
273 ]
274 ],
275 ],
276 ],
277 'processedTca' => [
278 'columns' => [
279 'aField' => [
280 'config' => [
281 'type' => 'radio',
282 'aKey' => 'aValue',
283 'items' => [
284 0 => [
285 'foo',
286 'bar',
287 ],
288 ],
289 'itemsProcFunc' => function (array $parameters, $pObj) {
290 if ($parameters['items'] !== [ 0 => [ 'foo', 'bar'] ]
291 || $parameters['config']['aKey'] !== 'aValue'
292 || $parameters['TSconfig'] !== [ 'itemParamKey' => 'itemParamValue' ]
293 || $parameters['table'] !== 'aTable'
294 || $parameters['row'] !== [ 'aField' => 'aValue' ]
295 || $parameters['field'] !== 'aField'
296 ) {
297 throw new \UnexpectedValueException('broken', 1476109434);
298 }
299 },
300 ],
301 ],
302 ],
303 ],
304 ];
305
306 $languageService = $this->prophesize(LanguageService::class);
307 $GLOBALS['LANG'] = $languageService->reveal();
308 $languageService->sL(Argument::cetera())->willReturnArgument(0);
309 /** @var FlashMessage|ObjectProphecy $flashMessage */
310 $flashMessage = $this->prophesize(FlashMessage::class);
311 GeneralUtility::addInstance(FlashMessage::class, $flashMessage->reveal());
312 /** @var FlashMessageService|ObjectProphecy $flashMessageService */
313 $flashMessageService = $this->prophesize(FlashMessageService::class);
314 GeneralUtility::setSingletonInstance(FlashMessageService::class, $flashMessageService->reveal());
315 /** @var FlashMessageQueue|ObjectProphecy $flashMessageQueue */
316 $flashMessageQueue = $this->prophesize(FlashMessageQueue::class);
317 $flashMessageService->getMessageQueueByIdentifier(Argument::cetera())->willReturn($flashMessageQueue->reveal());
318
319 // itemsProcFunc must NOT have raised an exception
320 $flashMessageQueue->enqueue($flashMessage)->shouldNotBeCalled();
321
322 $this->subject->addData($input);
323 }
324
325 /**
326 * @test
327 */
328 public function addDataItemsProcFuncEnqueuesFlashMessageOnException()
329 {
330 $input = [
331 'tableName' => 'aTable',
332 'databaseRow' => [
333 'aField' => 'aValue',
334 ],
335 'pageTsConfig' => [
336 'TCEFORM.' => [
337 'aTable.' => [
338 'aField.' => [
339 'itemsProcFunc.' => [
340 'itemParamKey' => 'itemParamValue',
341 ],
342 ]
343 ],
344 ],
345 ],
346 'processedTca' => [
347 'columns' => [
348 'aField' => [
349 'config' => [
350 'type' => 'radio',
351 'aKey' => 'aValue',
352 'items' => [
353 0 => [
354 'foo',
355 'bar',
356 ],
357 ],
358 'itemsProcFunc' => function (array $parameters, $pObj) {
359 throw new \UnexpectedValueException('anException', 1476109435);
360 },
361 ],
362 ],
363 ],
364 ],
365 ];
366
367 $languageService = $this->prophesize(LanguageService::class);
368 $GLOBALS['LANG'] = $languageService->reveal();
369 /** @var FlashMessage|ObjectProphecy $flashMessage */
370 $flashMessage = $this->prophesize(FlashMessage::class);
371 GeneralUtility::addInstance(FlashMessage::class, $flashMessage->reveal());
372 /** @var FlashMessageService|ObjectProphecy $flashMessageService */
373 $flashMessageService = $this->prophesize(FlashMessageService::class);
374 GeneralUtility::setSingletonInstance(FlashMessageService::class, $flashMessageService->reveal());
375 /** @var FlashMessageQueue|ObjectProphecy $flashMessageQueue */
376 $flashMessageQueue = $this->prophesize(FlashMessageQueue::class);
377 $flashMessageService->getMessageQueueByIdentifier(Argument::cetera())->willReturn($flashMessageQueue->reveal());
378
379 $flashMessageQueue->enqueue($flashMessage)->shouldBeCalled();
380
381 $this->subject->addData($input);
382 }
383
384 /**
385 * @test
386 */
387 public function addDataTranslatesItemLabelsFromPageTsConfig()
388 {
389 $input = [
390 'tableName' => 'aTable',
391 'processedTca' => [
392 'columns' => [
393 'aField' => [
394 'config' => [
395 'type' => 'radio',
396 'items' => [
397 0 => [
398 0 => 'aLabel',
399 1 => 'aValue',
400 ],
401 ],
402 ],
403 ],
404 ],
405 ],
406 'pageTsConfig' => [
407 'TCEFORM.' => [
408 'aTable.' => [
409 'aField.' => [
410 'altLabels.' => [
411 0 => 'labelOverride',
412 ],
413 ]
414 ],
415 ],
416 ],
417 ];
418
419 /** @var LanguageService|ObjectProphecy $languageService */
420 $languageService = $this->prophesize(LanguageService::class);
421 $GLOBALS['LANG'] = $languageService->reveal();
422 $languageService->sL('aLabel')->willReturnArgument(0);
423
424 $languageService->sL('labelOverride')->shouldBeCalled()->willReturnArgument(0);
425
426 $expected = $input;
427 $expected['processedTca']['columns']['aField']['config']['items'][0][0] = 'labelOverride';
428
429 $this->assertSame($expected, $this->subject->addData($input));
430 $this->subject->addData($input);
431 }
432 }