[!!!][TASK] Improve flex and TCA handling in FormEngine
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Tests / Unit / Form / FormDataProvider / DatabaseRecordTypeValueTest.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\Prophecy\ObjectProphecy;
18 use TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseRecordTypeValue;
19 use TYPO3\CMS\Core\Database\DatabaseConnection;
20
21 /**
22 * Test case
23 */
24 class DatabaseRecordTypeValueTest extends \TYPO3\CMS\Components\TestingFramework\Core\UnitTestCase
25 {
26 /**
27 * @var DatabaseRecordTypeValue|\PHPUnit_Framework_MockObject_MockObject
28 */
29 protected $subject;
30
31 /**
32 * @var DatabaseConnection | ObjectProphecy
33 */
34 protected $dbProphecy;
35
36 protected function setUp()
37 {
38 $this->subject = $this->getMockBuilder(DatabaseRecordTypeValue::class)
39 ->setMethods(['getDatabaseRow'])
40 ->getMock();
41 }
42
43 /**
44 * @test
45 */
46 public function addDataThrowsExceptionIfTcaTypesAreEmpty()
47 {
48 $input = [
49 'processedTca' => [
50 'types' => [],
51 ],
52 ];
53
54 $this->expectException(\UnexpectedValueException::class);
55 $this->expectExceptionCode(1438185331);
56
57 $this->subject->addData($input);
58 }
59
60 /**
61 * @test
62 */
63 public function addDataKeepsExistingTcaRecordTypeValue()
64 {
65 $input = [
66 'recordTypeValue' => 'egon',
67 'processedTca' => [
68 'types' => [
69 '1' => 'foo',
70 ],
71 ],
72 ];
73 $expected = $input;
74 $this->assertSame($expected, $this->subject->addData($input));
75 }
76
77 /**
78 * @test
79 */
80 public function addDataKeepsExistingTcaRecordTypeValueWithValueZero()
81 {
82 $input = [
83 'recordTypeValue' => 0,
84 'processedTca' => [
85 'types' => [
86 '1' => 'foo',
87 ],
88 ],
89 ];
90 $expected = $input;
91 $this->assertSame($expected, $this->subject->addData($input));
92 }
93
94 /**
95 * @test
96 */
97 public function addDataSetsRecordTypeValueToHistoricalOneIfTypeZeroIsNotDefined()
98 {
99 $input = [
100 'recordTypeValue' => '',
101 'processedTca' => [
102 'types' => [
103 '1' => 'foo',
104 ],
105 ],
106 ];
107 $expected = $input;
108 $expected['recordTypeValue'] = '1';
109 $this->assertSame($expected, $this->subject->addData($input));
110 }
111
112 /**
113 * @test
114 */
115 public function addDataSetsRecordTypeValueToZero()
116 {
117 $input = [
118 'recordTypeValue' => '',
119 'processedTca' => [
120 'types' => [
121 '0' => 'foo',
122 ],
123 ],
124 ];
125
126 $expected = $input;
127 $expected['recordTypeValue'] = '0';
128
129 $this->assertSame($expected, $this->subject->addData($input));
130 }
131
132 /**
133 * @test
134 */
135 public function addDataThrowsExceptionIfTypePointsToANotExistingField()
136 {
137 $input = [
138 'recordTypeValue' => '',
139 'processedTca' => [
140 'ctrl' => [
141 'type' => 'notExists',
142 ],
143 'types' => [
144 '0' => 'foo',
145 ],
146 ],
147 'databaseRow' => [
148 'uid' => 23,
149 ],
150 ];
151
152 $this->expectException(\UnexpectedValueException::class);
153 $this->expectExceptionCode(1438183881);
154
155 $this->subject->addData($input);
156 }
157
158 /**
159 * @test
160 */
161 public function addDataSetsRecordTypeValueToValueOfDatabaseField()
162 {
163 $input = [
164 'recordTypeValue' => '',
165 'processedTca' => [
166 'ctrl' => [
167 'type' => 'aField',
168 ],
169 'types' => [
170 '3' => 'foo',
171 ],
172 ],
173 'databaseRow' => [
174 'aField' => 3,
175 ],
176 ];
177
178 $expected = $input;
179 $expected['recordTypeValue'] = '3';
180
181 $this->assertSame($expected, $this->subject->addData($input));
182 }
183
184 /**
185 * @test
186 */
187 public function addDataSetsRecordTypeValueToZeroIfValueOfDatabaseFieldIsNotDefinedInTca()
188 {
189 $input = [
190 'recordTypeValue' => '',
191 'processedTca' => [
192 'ctrl' => [
193 'type' => 'aField',
194 ],
195 'types' => [
196 '0' => 'foo',
197 ],
198 ],
199 'databaseRow' => [
200 'aField' => 3,
201 ],
202 ];
203
204 $expected = $input;
205 $expected['recordTypeValue'] = '0';
206
207 $this->assertSame($expected, $this->subject->addData($input));
208 }
209
210 /**
211 * @test
212 */
213 public function addDataSetsRecordTypeValueToZeroIfValueOfDatabaseFieldIsEmptyString()
214 {
215 $input = [
216 'recordTypeValue' => '',
217 'processedTca' => [
218 'ctrl' => [
219 'type' => 'aField',
220 ],
221 'types' => [
222 '0' => 'foo',
223 ],
224 ],
225 'databaseRow' => [
226 'aField' => '',
227 ],
228 ];
229
230 $expected = $input;
231 $expected['recordTypeValue'] = '0';
232
233 $this->assertSame($expected, $this->subject->addData($input));
234 }
235
236 /**
237 * @test
238 */
239 public function addDataThrowsExceptionIfValueTypesNotExistsAndNoFallbackExists()
240 {
241 $input = [
242 'recordTypeValue' => '',
243 'processedTca' => [
244 'ctrl' => [
245 'type' => 'aField',
246 ],
247 'types' => [
248 '42' => 'foo',
249 ],
250 ],
251 'databaseRow' => [
252 'aField' => 23,
253 ],
254 ];
255
256 $this->expectException(\UnexpectedValueException::class);
257 $this->expectExceptionCode(1438185437);
258
259 $this->subject->addData($input);
260 }
261
262 /**
263 * @test
264 */
265 public function addDataSetsRecordTypeValueToValueOfDefaultLanguageRecordIfConfiguredAsExclude()
266 {
267 $input = [
268 'recordTypeValue' => '',
269 'processedTca' => [
270 'ctrl' => [
271 'languageField' => 'sys_language_uid',
272 'type' => 'aField',
273 ],
274 'columns' => [
275 'aField' => [
276 'l10n_mode' => 'exclude',
277 ],
278 ],
279 'types' => [
280 '3' => 'foo',
281 ],
282 ],
283 'databaseRow' => [
284 'sys_language_uid' => 2,
285 'aField' => 4,
286 ],
287 'defaultLanguageRow' => [
288 'aField' => 3,
289 ],
290 ];
291
292 $expected = $input;
293 $expected['recordTypeValue'] = '3';
294
295 $this->assertSame($expected, $this->subject->addData($input));
296 }
297
298 /**
299 * @test
300 */
301 public function addDataSetsRecordTypeValueToValueOfDefaultLanguageRecordIfConfiguredAsMergeIfNotBlank()
302 {
303 $input = [
304 'recordTypeValue' => '',
305 'processedTca' => [
306 'ctrl' => [
307 'languageField' => 'sys_language_uid',
308 'type' => 'aField',
309 ],
310 'columns' => [
311 'aField' => [
312 'l10n_mode' => 'mergeIfNotBlank',
313 ],
314 ],
315 'types' => [
316 '3' => 'foo',
317 ],
318 ],
319 'databaseRow' => [
320 'sys_language_uid' => 2,
321 'aField' => '',
322 ],
323 'defaultLanguageRow' => [
324 'aField' => 3,
325 ],
326 ];
327
328 $expected = $input;
329 $expected['recordTypeValue'] = '3';
330
331 $this->assertSame($expected, $this->subject->addData($input));
332 }
333
334 /**
335 * @test
336 */
337 public function addDataSetsRecordTypeValueToValueOfLocalizedRecordIfConfiguredAsMergeIfNotBlankButNotBlank()
338 {
339 $input = [
340 'recordTypeValue' => '',
341 'processedTca' => [
342 'ctrl' => [
343 'languageField' => 'sys_language_uid',
344 'type' => 'aField',
345 ],
346 'columns' => [
347 'aField' => [
348 'l10n_mode' => 'mergeIfNotBlank',
349 ],
350 ],
351 'types' => [
352 '3' => 'foo',
353 ],
354 ],
355 'databaseRow' => [
356 'sys_language_uid' => 2,
357 'aField' => 3,
358 ],
359 'defaultLanguageRow' => [
360 'aField' => 4,
361 ],
362 ];
363
364 $expected = $input;
365 $expected['recordTypeValue'] = '3';
366
367 $this->assertSame($expected, $this->subject->addData($input));
368 }
369
370 /**
371 * @test
372 */
373 public function addDataThrowsExceptionForForeignTypeConfigurationNotAsSelectOrGroup()
374 {
375 $input = [
376 'recordTypeValue' => '',
377 'processedTca' => [
378 'ctrl' => [
379 'type' => 'localField:foreignField',
380 ],
381 'columns' => [
382 'localField' => [
383 'config' => [
384 'type' => 'input',
385 ],
386 ],
387 ],
388 'types' => [
389 '3' => 'foo',
390 ],
391 ],
392 ];
393
394 $this->expectException(\UnexpectedValueException::class);
395 $this->expectExceptionCode(1325862241);
396
397 $this->subject->addData($input);
398 }
399
400 /**
401 * @test
402 */
403 public function addDataThrowsExceptionForForeignTypeIfPointerConfigurationHasNoTable()
404 {
405 $input = [
406 'recordTypeValue' => '',
407 'processedTca' => [
408 'ctrl' => [
409 'type' => 'localField:foreignField',
410 ],
411 'columns' => [
412 'localField' => [
413 'config' => [
414 'type' => 'select',
415 ],
416 ],
417 ],
418 'types' => [
419 '3' => 'foo',
420 ],
421 ],
422 'databaseRow' => [
423 'localField' => 3,
424 ],
425 ];
426
427 $this->expectException(\UnexpectedValueException::class);
428 $this->expectExceptionCode(1438253614);
429
430 $this->subject->addData($input);
431 }
432
433 /**
434 * @test
435 */
436 public function addDataSetsTypeValueFromForeignTableRecord()
437 {
438 $input = [
439 'recordTypeValue' => '',
440 'processedTca' => [
441 'ctrl' => [
442 'type' => 'localField:foreignField',
443 ],
444 'columns' => [
445 'localField' => [
446 'config' => [
447 'type' => 'select',
448 'foreign_table' => 'foreignTable',
449 ],
450 ],
451 ],
452 'types' => [
453 '3' => 'foo',
454 ],
455 ],
456 'databaseRow' => [
457 // Point to record 42 in foreignTable
458 'localField' => 42,
459 ],
460 ];
461
462 $foreignRecordResult = [
463 'foreignField' => 3,
464 ];
465
466 $this->subject->expects($this->once())
467 ->method('getDatabaseRow')
468 ->with('foreignTable', 42, 'foreignField')
469 ->willReturn($foreignRecordResult);
470
471 $expected = $input;
472 $expected['recordTypeValue'] = '3';
473
474 $this->assertSame($expected, $this->subject->addData($input));
475 }
476
477 /**
478 * @test
479 */
480 public function addDataSetsTypeValueFromNestedTcaGroupField()
481 {
482 $input = [
483 'recordTypeValue' => '',
484 'processedTca' => [
485 'ctrl' => [
486 'type' => 'uid_local:type',
487 ],
488 'columns' => [
489 'uid_local' => [
490 'config' => [
491 'type' => 'group',
492 'internal_type' => 'db',
493 'size' => 1,
494 'maxitems' => 1,
495 'minitems' => 0,
496 'allowed' => 'sys_file'
497 ],
498 ],
499 ],
500 'types' => [
501 '2' => 'foo',
502 ],
503 ],
504 'databaseRow' => [
505 // Processed group field
506 'uid_local' => [
507 [
508 'uid' => 222,
509 ],
510 ],
511 ],
512 ];
513
514 $foreignRecordResult = [
515 'type' => 2,
516 ];
517
518 $this->subject->expects($this->once())
519 ->method('getDatabaseRow')
520 ->with('sys_file', 222, 'type')
521 ->willReturn($foreignRecordResult);
522
523 $expected = $input;
524 $expected['recordTypeValue'] = '2';
525
526 $this->assertSame($expected, $this->subject->addData($input));
527 }
528 }