[TASK] Removes extra empty lines
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / DataHandling / DataHandlerTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Unit\DataHandler;
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\Core\Authentication\BackendUserAuthentication;
18 use TYPO3\CMS\Core\Database\DatabaseConnection;
19 use TYPO3\CMS\Core\DataHandling\DataHandler;
20 use TYPO3\CMS\Core\Tests\Unit\DataHandling\Fixtures\AllowAccessHookFixture;
21 use TYPO3\CMS\Core\Tests\Unit\DataHandling\Fixtures\InvalidHookFixture;
22 use TYPO3\CMS\Core\Utility\GeneralUtility;
23
24 /**
25 * Test case
26 */
27 class DataHandlerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
28 {
29 /**
30 * @var array A backup of registered singleton instances
31 */
32 protected $singletonInstances = array();
33
34 /**
35 * @var DataHandler|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface
36 */
37 protected $subject;
38
39 /**
40 * @var BackendUserAuthentication a mock logged-in back-end user
41 */
42 protected $backEndUser;
43
44 /**
45 * @var DatabaseConnection|\PHPUnit_Framework_MockObject_MockObject
46 */
47 protected $mockDatabaseConnection;
48
49 /**
50 * Set up the tests
51 */
52 protected function setUp()
53 {
54 $GLOBALS['TCA'] = array();
55 $this->singletonInstances = GeneralUtility::getSingletonInstances();
56 $this->backEndUser = $this->getMock(BackendUserAuthentication::class);
57 $this->mockDatabaseConnection = $this->getMock(DatabaseConnection::class, array(), array(), '', false);
58 $GLOBALS['TYPO3_DB'] = $this->mockDatabaseConnection;
59 $this->subject = $this->getAccessibleMock(DataHandler::class, ['dummy']);
60 $this->subject->start(array(), '', $this->backEndUser);
61 }
62
63 /**
64 * Tear down the tests
65 */
66 protected function tearDown()
67 {
68 GeneralUtility::resetSingletonInstances($this->singletonInstances);
69 parent::tearDown();
70 }
71
72 //////////////////////////////////////
73 // Tests for the basic functionality
74 //////////////////////////////////////
75 /**
76 * @test
77 */
78 public function fixtureCanBeCreated()
79 {
80 $this->assertTrue($this->subject instanceof DataHandler);
81 }
82
83 //////////////////////////////////////////
84 // Test concerning checkModifyAccessList
85 //////////////////////////////////////////
86 /**
87 * @test
88 */
89 public function adminIsAllowedToModifyNonAdminTable()
90 {
91 $this->subject->admin = true;
92 $this->assertTrue($this->subject->checkModifyAccessList('tt_content'));
93 }
94
95 /**
96 * @test
97 */
98 public function nonAdminIsNorAllowedToModifyNonAdminTable()
99 {
100 $this->subject->admin = false;
101 $this->assertFalse($this->subject->checkModifyAccessList('tt_content'));
102 }
103
104 /**
105 * @test
106 */
107 public function nonAdminWithTableModifyAccessIsAllowedToModifyNonAdminTable()
108 {
109 $this->subject->admin = false;
110 $this->backEndUser->groupData['tables_modify'] = 'tt_content';
111 $this->assertTrue($this->subject->checkModifyAccessList('tt_content'));
112 }
113
114 /**
115 * @test
116 */
117 public function adminIsAllowedToModifyAdminTable()
118 {
119 $this->subject->admin = true;
120 $this->assertTrue($this->subject->checkModifyAccessList('be_users'));
121 }
122
123 /**
124 * @test
125 */
126 public function nonAdminIsNotAllowedToModifyAdminTable()
127 {
128 $this->subject->admin = false;
129 $this->assertFalse($this->subject->checkModifyAccessList('be_users'));
130 }
131
132 /**
133 * @test
134 */
135 public function nonAdminWithTableModifyAccessIsNotAllowedToModifyAdminTable()
136 {
137 $tableName = $this->getUniqueId('aTable');
138 $GLOBALS['TCA'] = array(
139 $tableName => array(
140 'ctrl' => array(
141 'adminOnly' => true,
142 ),
143 ),
144 );
145 $this->subject->admin = false;
146 $this->backEndUser->groupData['tables_modify'] = $tableName;
147 $this->assertFalse($this->subject->checkModifyAccessList($tableName));
148 }
149
150 /**
151 * @test
152 */
153 public function evalCheckValueDouble2()
154 {
155 $testData = array(
156 '-0,5' => '-0.50',
157 '1000' => '1000.00',
158 '1000,10' => '1000.10',
159 '1000,0' => '1000.00',
160 '600.000.000,00' => '600000000.00',
161 '60aaa00' => '6000.00'
162 );
163 foreach ($testData as $value => $expectedReturnValue) {
164 $returnValue = $this->subject->checkValue_input_Eval($value, array('double2'), '');
165 $this->assertSame($returnValue['value'], $expectedReturnValue);
166 }
167 }
168
169 /**
170 * Data provider for inputValueCheckRecognizesStringValuesAsIntegerValuesCorrectly
171 *
172 * @return array
173 */
174 public function inputValuesStringsDataProvider()
175 {
176 return array(
177 '"0" returns zero as integer' => array(
178 '0',
179 0
180 ),
181 '"-1999999" is interpreted correctly as -1999999 and is lot lower than -200000' => array(
182 '-1999999',
183 -1999999
184 ),
185 '"3000000" is interpreted correctly as 3000000 but is higher then 200000 and set to 200000' => array(
186 '3000000',
187 2000000
188 ),
189 );
190 }
191
192 /**
193 * @test
194 * @dataProvider inputValuesStringsDataProvider
195 * @param string $value
196 * @param int $expectedReturnValue
197 */
198 public function inputValueCheckRecognizesStringValuesAsIntegerValuesCorrectly($value, $expectedReturnValue)
199 {
200 $tcaFieldConf = array(
201 'input' => array(),
202 'eval' => 'int',
203 'range' => array(
204 'lower' => '-2000000',
205 'upper' => '2000000'
206 )
207 );
208 $returnValue = $this->subject->_call('checkValueForInput', $value, $tcaFieldConf, '', 0, 0, '');
209 $this->assertSame($returnValue['value'], $expectedReturnValue);
210 }
211
212 /**
213 * @return array
214 */
215 public function inputValueCheckCallsGetDateTimeFormatsForDatetimeFieldsDataProvider()
216 {
217 return array(
218 'dbType = date' => array(
219 'date'
220 ),
221 'dbType = datetime' => array(
222 'datetime'
223 )
224 );
225 }
226
227 /**
228 * @test
229 * @dataProvider inputValueCheckCallsGetDateTimeFormatsForDatetimeFieldsDataProvider
230 * @param string $dbType
231 */
232 public function inputValueCheckCallsGetDateTimeFormatsForDatetimeFields($dbType)
233 {
234 $tcaFieldConf = array(
235 'input' => array(),
236 'dbType' => $dbType
237 );
238 $this->mockDatabaseConnection->expects($this->once())->method('getDateTimeFormats');
239 $this->subject->_call('checkValueForInput', '', $tcaFieldConf, '', 0, 0, '');
240 }
241
242 /**
243 * @return array
244 */
245 public function inputValueCheckDoesNotCallGetDateTimeFormatsForNonDatetimeFieldsDataProvider()
246 {
247 return array(
248 'tca without dbType' => array(
249 array(
250 'input' => array()
251 )
252 ),
253 'tca with dbType != date/datetime' => array(
254 array(
255 'input' => array(),
256 'dbType' => 'foo'
257 )
258 )
259 );
260 }
261
262 /**
263 * @test
264 * @param array $tcaFieldConf
265 * @dataProvider inputValueCheckDoesNotCallGetDateTimeFormatsForNonDatetimeFieldsDataProvider
266 */
267 public function inputValueCheckDoesNotCallGetDateTimeFormatsForNonDatetimeFields($tcaFieldConf)
268 {
269 $this->mockDatabaseConnection->expects($this->never())->method('getDateTimeFormats');
270 $this->subject->_call('checkValueForInput', '', $tcaFieldConf, '', 0, 0, '');
271 }
272
273 ///////////////////////////////////////////
274 // Tests concerning checkModifyAccessList
275 ///////////////////////////////////////////
276 //
277 /**
278 * Tests whether a wrong interface on the 'checkModifyAccessList' hook throws an exception.
279 *
280 * @test
281 * @expectedException \UnexpectedValueException
282 */
283 public function doesCheckModifyAccessListThrowExceptionOnWrongHookInterface()
284 {
285 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['checkModifyAccessList'][] = InvalidHookFixture::class;
286 $this->subject->checkModifyAccessList('tt_content');
287 }
288
289 /**
290 * Tests whether the 'checkModifyAccessList' hook is called correctly.
291 *
292 * @test
293 */
294 public function doesCheckModifyAccessListHookGetsCalled()
295 {
296 $hookClass = $this->getUniqueId('tx_coretest');
297 $hookMock = $this->getMock(\TYPO3\CMS\Core\DataHandling\DataHandlerCheckModifyAccessListHookInterface::class, array('checkModifyAccessList'), array(), $hookClass);
298 $hookMock->expects($this->once())->method('checkModifyAccessList');
299 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['checkModifyAccessList'][] = $hookClass;
300 $GLOBALS['T3_VAR']['getUserObj'][$hookClass] = $hookMock;
301 $this->subject->checkModifyAccessList('tt_content');
302 }
303
304 /**
305 * Tests whether the 'checkModifyAccessList' hook modifies the $accessAllowed variable.
306 *
307 * @test
308 */
309 public function doesCheckModifyAccessListHookModifyAccessAllowed()
310 {
311 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['checkModifyAccessList'][] = AllowAccessHookFixture::class;
312 $this->assertTrue($this->subject->checkModifyAccessList('tt_content'));
313 }
314
315 /////////////////////////////////////
316 // Tests concerning process_datamap
317 /////////////////////////////////////
318 /**
319 * @test
320 */
321 public function processDatamapForFrozenNonZeroWorkspaceReturnsFalse()
322 {
323 /** @var DataHandler $subject */
324 $subject = $this->getMock(DataHandler::class, array('newlog'));
325 $this->backEndUser->workspace = 1;
326 $this->backEndUser->workspaceRec = array('freeze' => true);
327 $subject->BE_USER = $this->backEndUser;
328 $this->assertFalse($subject->process_datamap());
329 }
330
331 /**
332 * @test
333 */
334 public function processDatamapWhenEditingRecordInWorkspaceCreatesNewRecordInWorkspace()
335 {
336 // Unset possible hooks on method under test
337 // @TODO: Can be removed if unit test boostrap is fixed to not load LocalConfiguration anymore
338 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass'] = array();
339
340 $GLOBALS['TCA'] = array(
341 'pages' => array(
342 'columns' => array(),
343 ),
344 );
345
346 /** @var $subject DataHandler|\PHPUnit_Framework_MockObject_MockObject */
347 $subject = $this->getMock(
348 DataHandler::class,
349 array('newlog', 'checkModifyAccessList', 'tableReadOnly', 'checkRecordUpdateAccess')
350 );
351
352 $subject->bypassWorkspaceRestrictions = false;
353 $subject->datamap = array(
354 'pages' => array(
355 '1' => array(
356 'header' => 'demo'
357 )
358 )
359 );
360 $subject->expects($this->once())->method('checkModifyAccessList')->with('pages')->will($this->returnValue(true));
361 $subject->expects($this->once())->method('tableReadOnly')->with('pages')->will($this->returnValue(false));
362 $subject->expects($this->once())->method('checkRecordUpdateAccess')->will($this->returnValue(true));
363
364 /** @var BackendUserAuthentication|\PHPUnit_Framework_MockObject_MockObject $backEndUser */
365 $backEndUser = $this->getMock(BackendUserAuthentication::class);
366 $backEndUser->workspace = 1;
367 $backEndUser->workspaceRec = array('freeze' => false);
368 $backEndUser->expects($this->once())->method('workspaceAllowAutoCreation')->will($this->returnValue(true));
369 $backEndUser->expects($this->once())->method('workspaceCannotEditRecord')->will($this->returnValue(true));
370 $backEndUser->expects($this->once())->method('recordEditAccessInternals')->with('pages', 1)->will($this->returnValue(true));
371 $subject->BE_USER = $backEndUser;
372 $createdTceMain = $this->getMock(DataHandler::class, array());
373 $createdTceMain->expects($this->once())->method('start')->with(array(), array(
374 'pages' => array(
375 1 => array(
376 'version' => array(
377 'action' => 'new',
378 'treeLevels' => -1,
379 'label' => 'Auto-created for WS #1'
380 )
381 )
382 )
383 ));
384 $createdTceMain->expects($this->never())->method('process_datamap');
385 $createdTceMain->expects($this->once())->method('process_cmdmap');
386 GeneralUtility::addInstance(DataHandler::class, $createdTceMain);
387 $subject->process_datamap();
388 }
389
390 /**
391 * @test
392 */
393 public function doesCheckFlexFormValueHookGetsCalled()
394 {
395 $hookClass = $this->getUniqueId('tx_coretest');
396 $hookMock = $this->getMock($hookClass, array('checkFlexFormValue_beforeMerge'));
397 $hookMock->expects($this->once())->method('checkFlexFormValue_beforeMerge');
398 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['checkFlexFormValue'][] = $hookClass;
399 $GLOBALS['T3_VAR']['getUserObj'][$hookClass] = $hookMock;
400 $this->subject->_call('checkValueForFlex', [], [], [], '', 0, '', '', 0, 0, 0, [], '');
401 }
402
403 /////////////////////////////////////
404 // Tests concerning log
405 /////////////////////////////////////
406 /**
407 * @test
408 */
409 public function logCallsWriteLogOfBackendUserIfLoggingIsEnabled()
410 {
411 $backendUser = $this->getMock(BackendUserAuthentication::class);
412 $backendUser->expects($this->once())->method('writelog');
413 $this->subject->enableLogging = true;
414 $this->subject->BE_USER = $backendUser;
415 $this->subject->log('', 23, 0, 42, 0, 'details');
416 }
417
418 /**
419 * @test
420 */
421 public function logDoesNotCallWriteLogOfBackendUserIfLoggingIsDisabled()
422 {
423 $backendUser = $this->getMock(BackendUserAuthentication::class);
424 $backendUser->expects($this->never())->method('writelog');
425 $this->subject->enableLogging = false;
426 $this->subject->BE_USER = $backendUser;
427 $this->subject->log('', 23, 0, 42, 0, 'details');
428 }
429
430 /**
431 * @test
432 */
433 public function logAddsEntryToLocalErrorLogArray()
434 {
435 $backendUser = $this->getMock(BackendUserAuthentication::class);
436 $this->subject->BE_USER = $backendUser;
437 $this->subject->enableLogging = true;
438 $this->subject->errorLog = array();
439 $logDetailsUnique = $this->getUniqueId('details');
440 $this->subject->log('', 23, 0, 42, 1, $logDetailsUnique);
441 $this->assertStringEndsWith($logDetailsUnique, $this->subject->errorLog[0]);
442 }
443
444 /**
445 * @test
446 */
447 public function logFormatsDetailMessageWithAdditionalDataInLocalErrorArray()
448 {
449 $backendUser = $this->getMock(BackendUserAuthentication::class);
450 $this->subject->BE_USER = $backendUser;
451 $this->subject->enableLogging = true;
452 $this->subject->errorLog = array();
453 $logDetails = $this->getUniqueId('details');
454 $this->subject->log('', 23, 0, 42, 1, '%1$s' . $logDetails . '%2$s', -1, array('foo', 'bar'));
455 $expected = 'foo' . $logDetails . 'bar';
456 $this->assertStringEndsWith($expected, $this->subject->errorLog[0]);
457 }
458
459 /**
460 * @param bool $expected
461 * @param string $submittedValue
462 * @param string $storedValue
463 * @param string $storedType
464 * @param bool $allowNull
465 *
466 * @dataProvider equalSubmittedAndStoredValuesAreDeterminedDataProvider
467 * @test
468 */
469 public function equalSubmittedAndStoredValuesAreDetermined($expected, $submittedValue, $storedValue, $storedType, $allowNull)
470 {
471 $result = $this->callInaccessibleMethod(
472 $this->subject,
473 'isSubmittedValueEqualToStoredValue',
474 $submittedValue, $storedValue, $storedType, $allowNull
475 );
476 $this->assertEquals($expected, $result);
477 }
478
479 /**
480 * @return array
481 */
482 public function equalSubmittedAndStoredValuesAreDeterminedDataProvider()
483 {
484 return array(
485 // String
486 'string value "" vs. ""' => array(
487 true,
488 '', '', 'string', false
489 ),
490 'string value 0 vs. "0"' => array(
491 true,
492 0, '0', 'string', false
493 ),
494 'string value 1 vs. "1"' => array(
495 true,
496 1, '1', 'string', false
497 ),
498 'string value "0" vs. ""' => array(
499 false,
500 '0', '', 'string', false
501 ),
502 'string value 0 vs. ""' => array(
503 false,
504 0, '', 'string', false
505 ),
506 'string value null vs. ""' => array(
507 true,
508 null, '', 'string', false
509 ),
510 // Integer
511 'integer value 0 vs. 0' => array(
512 true,
513 0, 0, 'int', false
514 ),
515 'integer value "0" vs. "0"' => array(
516 true,
517 '0', '0', 'int', false
518 ),
519 'integer value 0 vs. "0"' => array(
520 true,
521 0, '0', 'int', false
522 ),
523 'integer value "" vs. "0"' => array(
524 true,
525 '', '0', 'int', false
526 ),
527 'integer value "" vs. 0' => array(
528 true,
529 '', 0, 'int', false
530 ),
531 'integer value "0" vs. 0' => array(
532 true,
533 '0', 0, 'int', false
534 ),
535 'integer value 1 vs. 1' => array(
536 true,
537 1, 1, 'int', false
538 ),
539 'integer value 1 vs. "1"' => array(
540 true,
541 1, '1', 'int', false
542 ),
543 'integer value "1" vs. "1"' => array(
544 true,
545 '1', '1', 'int', false
546 ),
547 'integer value "1" vs. 1' => array(
548 true,
549 '1', 1, 'int', false
550 ),
551 'integer value "0" vs. "1"' => array(
552 false,
553 '0', '1', 'int', false
554 ),
555 // String with allowed NULL values
556 'string with allowed null value "" vs. ""' => array(
557 true,
558 '', '', 'string', true
559 ),
560 'string with allowed null value 0 vs. "0"' => array(
561 true,
562 0, '0', 'string', true
563 ),
564 'string with allowed null value 1 vs. "1"' => array(
565 true,
566 1, '1', 'string', true
567 ),
568 'string with allowed null value "0" vs. ""' => array(
569 false,
570 '0', '', 'string', true
571 ),
572 'string with allowed null value 0 vs. ""' => array(
573 false,
574 0, '', 'string', true
575 ),
576 'string with allowed null value null vs. ""' => array(
577 false,
578 null, '', 'string', true
579 ),
580 'string with allowed null value "" vs. null' => array(
581 false,
582 '', null, 'string', true
583 ),
584 'string with allowed null value null vs. null' => array(
585 true,
586 null, null, 'string', true
587 ),
588 // Integer with allowed NULL values
589 'integer with allowed null value 0 vs. 0' => array(
590 true,
591 0, 0, 'int', true
592 ),
593 'integer with allowed null value "0" vs. "0"' => array(
594 true,
595 '0', '0', 'int', true
596 ),
597 'integer with allowed null value 0 vs. "0"' => array(
598 true,
599 0, '0', 'int', true
600 ),
601 'integer with allowed null value "" vs. "0"' => array(
602 true,
603 '', '0', 'int', true
604 ),
605 'integer with allowed null value "" vs. 0' => array(
606 true,
607 '', 0, 'int', true
608 ),
609 'integer with allowed null value "0" vs. 0' => array(
610 true,
611 '0', 0, 'int', true
612 ),
613 'integer with allowed null value 1 vs. 1' => array(
614 true,
615 1, 1, 'int', true
616 ),
617 'integer with allowed null value "1" vs. "1"' => array(
618 true,
619 '1', '1', 'int', true
620 ),
621 'integer with allowed null value "1" vs. 1' => array(
622 true,
623 '1', 1, 'int', true
624 ),
625 'integer with allowed null value 1 vs. "1"' => array(
626 true,
627 1, '1', 'int', true
628 ),
629 'integer with allowed null value "0" vs. "1"' => array(
630 false,
631 '0', '1', 'int', true
632 ),
633 'integer with allowed null value null vs. ""' => array(
634 false,
635 null, '', 'int', true
636 ),
637 'integer with allowed null value "" vs. null' => array(
638 false,
639 '', null, 'int', true
640 ),
641 'integer with allowed null value null vs. null' => array(
642 true,
643 null, null, 'int', true
644 ),
645 'integer with allowed null value null vs. "0"' => array(
646 false,
647 null, '0', 'int', true
648 ),
649 'integer with allowed null value null vs. 0' => array(
650 false,
651 null, 0, 'int', true
652 ),
653 'integer with allowed null value "0" vs. null' => array(
654 false,
655 '0', null, 'int', true
656 ),
657 );
658 }
659
660 /**
661 * @param bool $expected
662 * @param array $eval
663 * @dataProvider getPlaceholderTitleForTableLabelReturnsLabelThatsMatchesLabelFieldConditionsDataProvider
664 * @test
665 */
666 public function getPlaceholderTitleForTableLabelReturnsLabelThatsMatchesLabelFieldConditions($expected, $eval)
667 {
668 $table = 'phpunit_dummy';
669
670 /** @var DataHandler|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface $subject */
671 $subject = $this->getAccessibleMock(
672 DataHandler::class,
673 array('dummy')
674 );
675
676 $backendUser = $this->getMock(BackendUserAuthentication::class);
677 $subject->BE_USER = $backendUser;
678 $subject->BE_USER->workspace = 1;
679
680 $GLOBALS['TCA'][$table] = array();
681 $GLOBALS['TCA'][$table]['ctrl'] = array('label' => 'dummy');
682 $GLOBALS['TCA'][$table]['columns'] = array(
683 'dummy' => array(
684 'config' => array(
685 'eval' => $eval
686 )
687 )
688 );
689
690 $this->assertEquals($expected, $subject->_call('getPlaceholderTitleForTableLabel', $table));
691 }
692
693 /**
694 * @return array
695 */
696 public function getPlaceholderTitleForTableLabelReturnsLabelThatsMatchesLabelFieldConditionsDataProvider()
697 {
698 return array(
699 array(
700 0.10,
701 'double2'
702 ),
703 array(
704 0,
705 'int'
706 ),
707 array(
708 '0',
709 'datetime'
710 ),
711 array(
712 '[PLACEHOLDER, WS#1]',
713 ''
714 )
715 );
716 }
717
718 /**
719 * @test
720 */
721 public function deleteRecord_procBasedOnFieldTypeRespectsEnableCascadingDelete()
722 {
723 $table = $this->getUniqueId('foo_');
724 $conf = array(
725 'type' => 'inline',
726 'foreign_table' => $this->getUniqueId('foreign_foo_'),
727 'behaviour' => array(
728 'enableCascadingDelete' => 0,
729 )
730 );
731
732 /** @var \TYPO3\CMS\Core\Database\RelationHandler $mockRelationHandler */
733 $mockRelationHandler = $this->getMock(\TYPO3\CMS\Core\Database\RelationHandler::class, array(), array(), '', false);
734 $mockRelationHandler->itemArray = array(
735 '1' => array('table' => $this->getUniqueId('bar_'), 'id' => 67)
736 );
737
738 /** @var DataHandler|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface $mockDataHandler */
739 $mockDataHandler = $this->getAccessibleMock(DataHandler::class, array('getInlineFieldType', 'deleteAction', 'createRelationHandlerInstance'), array(), '', false);
740 $mockDataHandler->expects($this->once())->method('getInlineFieldType')->will($this->returnValue('field'));
741 $mockDataHandler->expects($this->once())->method('createRelationHandlerInstance')->will($this->returnValue($mockRelationHandler));
742 $mockDataHandler->expects($this->never())->method('deleteAction');
743 $mockDataHandler->deleteRecord_procBasedOnFieldType($table, 42, 'foo', 'bar', $conf);
744 }
745
746 /**
747 * @return array
748 */
749 public function checkValue_checkReturnsExpectedValuesDataProvider()
750 {
751 return array(
752 'None item selected' => array(
753 0,
754 0
755 ),
756 'All items selected' => array(
757 7,
758 7
759 ),
760 'Item 1 and 2 are selected' => array(
761 3,
762 3
763 ),
764 'Value is higher than allowed' => array(
765 15,
766 7
767 ),
768 'Negative value' => array(
769 -5,
770 0
771 )
772 );
773 }
774
775 /**
776 * @param string $value
777 * @param string $expectedValue
778 *
779 * @dataProvider checkValue_checkReturnsExpectedValuesDataProvider
780 * @test
781 */
782 public function checkValue_checkReturnsExpectedValues($value, $expectedValue)
783 {
784 $expectedResult = array(
785 'value' => $expectedValue
786 );
787 $result = array();
788 $tcaFieldConfiguration = array(
789 'items' => array(
790 array('Item 1', 0),
791 array('Item 2', 0),
792 array('Item 3', 0)
793 )
794 );
795 $this->assertSame($expectedResult, $this->subject->_call('checkValueForCheck', $result, $value, $tcaFieldConfiguration, '', 0, 0, ''));
796 }
797
798 /**
799 * @test
800 */
801 public function checkValueForInputConvertsNullToEmptyString()
802 {
803 $previousLanguageService = $GLOBALS['LANG'];
804 $GLOBALS['LANG'] = GeneralUtility::makeInstance(\TYPO3\CMS\Lang\LanguageService::class);
805 $GLOBALS['LANG']->init('default');
806 $expectedResult = array('value' => '');
807 $this->assertSame($expectedResult, $this->subject->_call('checkValueForInput', null, array('type' => 'string', 'max' => 40), 'tt_content', 'NEW55c0e67f8f4d32.04974534', 89, 'table_caption'));
808 $GLOBALS['LANG'] = $previousLanguageService;
809 }
810
811 /**
812 * @param mixed $value
813 * @param array $configuration
814 * @param int|string $expected
815 * @test
816 * @dataProvider referenceValuesAreCastedDataProvider
817 */
818 public function referenceValuesAreCasted($value, array $configuration, $expected)
819 {
820 $this->assertEquals(
821 $expected,
822 $this->subject->_call('castReferenceValue', $value, $configuration)
823 );
824 }
825
826 /**
827 * @return array
828 */
829 public function referenceValuesAreCastedDataProvider()
830 {
831 return array(
832 'all empty' => array(
833 '', array(), ''
834 ),
835 'cast zero with MM table' => array(
836 '', array('MM' => 'table'), 0
837 ),
838 'cast zero with MM table with default value' => array(
839 '', array('MM' => 'table', 'default' => 13), 0
840 ),
841 'cast zero with foreign field' => array(
842 '', array('foreign_field' => 'table', 'default' => 13), 0
843 ),
844 'cast zero with foreign field with default value' => array(
845 '', array('foreign_field' => 'table'), 0
846 ),
847 'pass zero' => array(
848 '0', array(), '0'
849 ),
850 'pass value' => array(
851 '1', array('default' => 13), '1'
852 ),
853 'use default value' => array(
854 '', array('default' => 13), 13
855 ),
856 );
857 }
858 }