‪TYPO3CMS  9.5
DataHandlerTest.php
Go to the documentation of this file.
1 <?php
2 declare(strict_types = 1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
18 use Prophecy\Argument;
27 use TYPO3\TestingFramework\Core\AccessibleObjectInterface;
28 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
29 
33 class ‪DataHandlerTest extends UnitTestCase
34 {
35 
39  protected ‪$resetSingletonInstances = true;
40 
44  protected ‪$singletonInstances = [];
45 
49  protected ‪$subject;
50 
54  protected ‪$backEndUser;
55 
59  protected function ‪setUp()
60  {
61  ‪$GLOBALS['TCA'] = [];
62  $cacheManagerProphecy = $this->prophesize(CacheManager::class);
63  GeneralUtility::setSingletonInstance(CacheManager::class, $cacheManagerProphecy->reveal());
64  $cacheFrontendProphecy = $this->prophesize(FrontendInterface::class);
65  $cacheManagerProphecy->getCache('cache_runtime')->willReturn($cacheFrontendProphecy->reveal());
66  $this->backEndUser = $this->createMock(BackendUserAuthentication::class);
67  $this->subject = $this->getAccessibleMock(DataHandler::class, ['dummy']);
68  $this->subject->start([], '', $this->backEndUser);
69  }
70 
74  public function ‪fixtureCanBeCreated()
75  {
76  $this->assertTrue($this->subject instanceof ‪DataHandler);
77  }
78 
80  // Test concerning checkModifyAccessList
82 
86  {
87  $this->subject->admin = true;
88  $this->assertTrue($this->subject->checkModifyAccessList('tt_content'));
89  }
90 
95  {
96  $this->subject->admin = false;
97  $this->assertFalse($this->subject->checkModifyAccessList('tt_content'));
98  }
99 
104  {
105  $this->subject->admin = false;
106  $this->backEndUser->groupData['tables_modify'] = 'tt_content';
107  $this->assertTrue($this->subject->checkModifyAccessList('tt_content'));
108  }
109 
113  public function ‪adminIsAllowedToModifyAdminTable()
114  {
115  $this->subject->admin = true;
116  $this->assertTrue($this->subject->checkModifyAccessList('be_users'));
117  }
118 
123  {
124  $this->subject->admin = false;
125  $this->assertFalse($this->subject->checkModifyAccessList('be_users'));
126  }
127 
132  {
133  $tableName = $this->getUniqueId('aTable');
134  ‪$GLOBALS['TCA'] = [
135  $tableName => [
136  'ctrl' => [
137  'adminOnly' => true,
138  ],
139  ],
140  ];
141  $this->subject->admin = false;
142  $this->backEndUser->groupData['tables_modify'] = $tableName;
143  $this->assertFalse($this->subject->checkModifyAccessList($tableName));
144  }
145 
149  public function ‪checkValueInputEvalWithEvalDouble2(): void
150  {
151  $testData = [
152  '-0,5' => '-0.50',
153  '1000' => '1000.00',
154  '1000,10' => '1000.10',
155  '1000,0' => '1000.00',
156  '600.000.000,00' => '600000000.00',
157  '60aaa00' => '6000.00'
158  ];
159  foreach ($testData as $value => $expectedReturnValue) {
160  $returnValue = $this->subject->checkValue_input_Eval($value, ['double2'], '');
161  $this->assertSame($returnValue['value'], $expectedReturnValue);
162  }
163  }
164 
169  {
170  // Three elements: input, timezone of input, expected output (UTC)
171  return [
172  'timestamp is passed through, as it is UTC' => [
173  1457103519, 'Europe/Berlin', 1457103519
174  ],
175  'ISO date is interpreted as local date and is output as correct timestamp' => [
176  '2017-06-07T00:10:00Z', 'Europe/Berlin', 1496787000
177  ],
178  ];
179  }
180 
185  public function ‪checkValueInputEvalWithEvalDatetime($input, $serverTimezone, $expectedOutput): void
186  {
187  $oldTimezone = date_default_timezone_get();
188  date_default_timezone_set($serverTimezone);
189 
190  ‪$output = $this->subject->checkValue_input_Eval($input, ['datetime'], '');
191 
192  // set before the assertion is performed, so it is restored even for failing tests
193  date_default_timezone_set($oldTimezone);
194 
195  $this->assertEquals($expectedOutput, ‪$output['value']);
196  }
197 
202  {
203  // Note the involved salted passwords are NOT mocked since the factory is static
204  ‪$subject = new ‪DataHandler();
205  $inputValue = '$1$GNu9HdMt$RwkPb28pce4nXZfnplVZY/';
206  $result = ‪$subject->‪checkValue_input_Eval($inputValue, ['saltedPassword'], '', 'be_users');
207  $this->assertSame($inputValue, $result['value']);
208  }
209 
214  {
215  // Note the involved salted passwords are NOT mocked since the factory is static
216  ‪$subject = new ‪DataHandler();
217  $inputValue = 'M$1$GNu9HdMt$RwkPb28pce4nXZfnplVZY/';
218  $result = ‪$subject->‪checkValue_input_Eval($inputValue, ['saltedPassword'], '', 'be_users');
219  $this->assertSame($inputValue, $result['value']);
220  }
221 
226  {
227  // Note the involved salted passwords are NOT mocked since the factory is static
228  $inputValue = 'myPassword';
229  ‪$subject = new ‪DataHandler();
230  $result = ‪$subject->‪checkValue_input_Eval($inputValue, ['saltedPassword'], '', 'be_users');
231  $this->assertNotSame($inputValue, $result['value']);
232  }
233 
239  public function ‪inputValuesStringsDataProvider()
240  {
241  return [
242  '"0" returns zero as integer' => [
243  '0',
244  0
245  ],
246  '"-2000001" is interpreted correctly as -2000001 but is lower than -2000000 and set to -2000000' => [
247  '-2000001',
248  -2000000
249  ],
250  '"-2000000" is interpreted correctly as -2000000 and is equal to -2000000' => [
251  '-2000000',
252  -2000000
253  ],
254  '"2000000" is interpreted correctly as 2000000 and is equal to 2000000' => [
255  '2000000',
256  2000000
257  ],
258  '"2000001" is interpreted correctly as 2000001 but is greater then 2000000 and set to 2000000' => [
259  '2000001',
260  2000000
261  ],
262  ];
263  }
264 
271  public function ‪inputValueCheckRecognizesStringValuesAsIntegerValuesCorrectly($value, $expectedReturnValue)
272  {
273  $tcaFieldConf = [
274  'input' => [],
275  'eval' => 'int',
276  'range' => [
277  'lower' => '-2000000',
278  'upper' => '2000000'
279  ]
280  ];
281  $returnValue = $this->subject->_call('checkValueForInput', $value, $tcaFieldConf, '', 0, 0, '');
282  $this->assertSame($returnValue['value'], $expectedReturnValue);
283  }
284 
288  public function ‪inputValuesDataTimeDataProvider()
289  {
290  return [
291  'undershot date adjusted' => [
292  '2018-02-28T00:00:00Z',
293  1519862400,
294  ],
295  'exact lower date accepted' => [
296  '2018-03-01T00:00:00Z',
297  1519862400,
298  ],
299  'exact upper date accepted' => [
300  '2018-03-31T23:59:59Z',
301  1522540799,
302  ],
303  'exceeded date adjusted' => [
304  '2018-04-01T00:00:00Z',
305  1522540799,
306  ],
307  ];
308  }
309 
317  public function ‪inputValueCheckRecognizesDateTimeValuesAsIntegerValuesCorrectly($value, int $expected)
318  {
319  $tcaFieldConf = [
320  'input' => [],
321  'eval' => 'datetime',
322  'range' => [
323  // unix timestamp: 1519862400
324  'lower' => gmmktime(0, 0, 0, 3, 1, 2018),
325  // unix timestamp: 1522540799
326  'upper' => gmmktime(23, 59, 59, 3, 31, 2018),
327  ]
328  ];
329 
330  // @todo Switch to UTC since otherwise DataHandler removes timezone offset
331  $previousTimezone = date_default_timezone_get();
332  date_default_timezone_set('UTC');
333 
334  $returnValue = $this->subject->_call('checkValueForInput', $value, $tcaFieldConf, '', 0, 0, '');
335 
336  date_default_timezone_set($previousTimezone);
337 
338  $this->assertSame($returnValue['value'], $expected);
339  }
340 
345  {
346  return [
347  'tca without dbType' => [
348  [
349  'input' => []
350  ]
351  ],
352  'tca with dbType != date/datetime/time' => [
353  [
354  'input' => [],
355  'dbType' => 'foo'
356  ]
357  ]
358  ];
359  }
360 
367  {
368  $this->subject->_call('checkValueForInput', '', $tcaFieldConf, '', 0, 0, '');
369  }
370 
375  {
376  return [
377  // Values of this kind are passed in from the inputDateTime control
378  'time from inputDateTime' => [
379  '1970-01-01T18:54:00Z',
380  'time',
381  '18:54:00',
382  ],
383  'date from inputDateTime' => [
384  '2020-11-25T00:00:00Z',
385  'date',
386  '2020-11-25',
387  ],
388  'datetime from inputDateTime' => [
389  '2020-11-25T18:54:00Z',
390  'datetime',
391  '2020-11-25 18:54:00',
392  ],
393  // Values of this kind are passed in when a data record is copied
394  'time from copying a record' => [
395  '18:54:00',
396  'time',
397  '18:54:00',
398  ],
399  'date from copying a record' => [
400  '2020-11-25',
401  'date',
402  '2020-11-25',
403  ],
404  'datetime from copying a record' => [
405  '2020-11-25 18:54:00',
406  'datetime',
407  '2020-11-25 18:54:00',
408  ],
409  ];
410  }
411 
421  public function ‪inputValueCheckDbtypeIsIndependentFromTimezone($value, $dbtype, $expectedOutput)
422  {
423  $tcaFieldConf = [
424  'input' => [],
425  'dbType' => $dbtype,
426  ];
427 
428  $oldTimezone = date_default_timezone_get();
429  date_default_timezone_set('Europe/Berlin');
430 
431  $returnValue = $this->subject->_call('checkValueForInput', $value, $tcaFieldConf, '', 0, 0, '');
432 
433  // set before the assertion is performed, so it is restored even for failing tests
434  date_default_timezone_set($oldTimezone);
435 
436  self::assertEquals($expectedOutput, $returnValue['value']);
437  }
438 
440  // Tests concerning checkModifyAccessList
442  //
448  {
449  $this->expectException(\UnexpectedValueException::class);
450  $this->expectExceptionCode(1251892472);
451 
452  ‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['checkModifyAccessList'][] = InvalidHookFixture::class;
453  $this->subject->checkModifyAccessList('tt_content');
454  }
455 
462  {
463  $hookClass = $this->getUniqueId('tx_coretest');
464  $hookMock = $this->getMockBuilder(\‪TYPO3\CMS\Core\DataHandling\DataHandlerCheckModifyAccessListHookInterface::class)
465  ->setMethods(['checkModifyAccessList'])
466  ->setMockClassName($hookClass)
467  ->getMock();
468  $hookMock->expects($this->once())->method('checkModifyAccessList');
469  ‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['checkModifyAccessList'][] = $hookClass;
470  GeneralUtility::addInstance($hookClass, $hookMock);
471  $this->subject->checkModifyAccessList('tt_content');
472  }
473 
480  {
481  ‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['checkModifyAccessList'][] = AllowAccessHookFixture::class;
482  $this->assertTrue($this->subject->checkModifyAccessList('tt_content'));
483  }
484 
486  // Tests concerning process_datamap
488 
492  {
494  ‪$subject = $this->getMockBuilder(DataHandler::class)
495  ->setMethods(['newlog'])
496  ->getMock();
497  $this->backEndUser->workspace = 1;
498  $this->backEndUser->workspaceRec = ['freeze' => true];
500  $this->assertFalse(‪$subject->‪process_datamap());
501  }
502 
507  {
508  ‪$GLOBALS['TCA'] = [
509  'pages' => [
510  'columns' => [],
511  ],
512  ];
513 
515  ‪$subject = $this->getMockBuilder(DataHandler::class)
516  ->setMethods([
517  'newlog',
518  'checkModifyAccessList',
519  'tableReadOnly',
520  'checkRecordUpdateAccess',
521  'recordInfo',
522  'getCacheManager',
523  'registerElementsToBeDeleted',
524  'unsetElementsToBeDeleted',
525  'resetElementsToBeDeleted'
526  ])
527  ->disableOriginalConstructor()
528  ->getMock();
529 
530  ‪$subject->bypassWorkspaceRestrictions = false;
531  ‪$subject->datamap = [
532  'pages' => [
533  '1' => [
534  'header' => 'demo'
535  ]
536  ]
537  ];
538 
539  $cacheManagerMock = $this->getMockBuilder(CacheManager::class)
540  ->setMethods(['flushCachesInGroupByTags'])
541  ->getMock();
542  $cacheManagerMock->expects($this->once())->method('flushCachesInGroupByTags')->with('pages', []);
543 
544  ‪$subject->expects($this->once())->method('getCacheManager')->willReturn($cacheManagerMock);
545  ‪$subject->expects($this->once())->method('recordInfo')->will($this->returnValue(null));
546  ‪$subject->expects($this->once())->method('checkModifyAccessList')->with('pages')->will($this->returnValue(true));
547  ‪$subject->expects($this->once())->method('tableReadOnly')->with('pages')->will($this->returnValue(false));
548  ‪$subject->expects($this->once())->method('checkRecordUpdateAccess')->will($this->returnValue(true));
549  ‪$subject->expects($this->once())->method('unsetElementsToBeDeleted')->willReturnArgument(0);
550 
552  ‪$backEndUser = $this->createMock(BackendUserAuthentication::class);
553  ‪$backEndUser->workspace = 1;
554  ‪$backEndUser->workspaceRec = ['freeze' => false];
555  ‪$backEndUser->expects($this->once())->method('workspaceAllowAutoCreation')->will($this->returnValue(true));
556  ‪$backEndUser->expects($this->once())->method('workspaceCannotEditRecord')->will($this->returnValue(true));
557  ‪$backEndUser->expects($this->once())->method('recordEditAccessInternals')->with('pages', 1)->will($this->returnValue(true));
558  ‪$subject->BE_USER = ‪$backEndUser;
559  $createdDataHandler = $this->createMock(DataHandler::class);
560  $createdDataHandler->expects($this->once())->method('start')->with([], [
561  'pages' => [
562  1 => [
563  'version' => [
564  'action' => 'new',
565  'label' => 'Auto-created for WS #1'
566  ]
567  ]
568  ]
569  ]);
570  $createdDataHandler->expects($this->never())->method('process_datamap');
571  $createdDataHandler->expects($this->once())->method('process_cmdmap');
572  GeneralUtility::addInstance(DataHandler::class, $createdDataHandler);
574  }
575 
580  {
581  $hookClass = $this->getUniqueId('tx_coretest');
582  $hookMock = $this->getMockBuilder($hookClass)
583  ->setMethods(['checkFlexFormValue_beforeMerge'])
584  ->getMock();
585  $hookMock->expects($this->once())->method('checkFlexFormValue_beforeMerge');
586  ‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['checkFlexFormValue'][] = $hookClass;
587  GeneralUtility::addInstance($hookClass, $hookMock);
588  $flexFormToolsProphecy = $this->prophesize(FlexFormTools::class);
589  $flexFormToolsProphecy->getDataStructureIdentifier(Argument::cetera())->willReturn('anIdentifier');
590  $flexFormToolsProphecy->parseDataStructureByIdentifier('anIdentifier')->willReturn([]);
591  GeneralUtility::addInstance(FlexFormTools::class, $flexFormToolsProphecy->reveal());
592  $this->subject->_call('checkValueForFlex', [], [], [], '', 0, '', '', 0, 0, 0, [], '');
593  }
594 
596  // Tests concerning log
598 
602  {
603  $backendUser = $this->createMock(BackendUserAuthentication::class);
604  $backendUser->expects($this->once())->method('writelog');
605  $this->subject->enableLogging = true;
606  $this->subject->BE_USER = $backendUser;
607  $this->subject->log('', 23, 0, 42, 0, 'details');
608  }
609 
614  {
615  $backendUser = $this->createMock(BackendUserAuthentication::class);
616  $backendUser->expects($this->never())->method('writelog');
617  $this->subject->enableLogging = false;
618  $this->subject->BE_USER = $backendUser;
619  $this->subject->log('', 23, 0, 42, 0, 'details');
620  }
621 
625  public function ‪logAddsEntryToLocalErrorLogArray()
626  {
627  $backendUser = $this->createMock(BackendUserAuthentication::class);
628  $this->subject->BE_USER = $backendUser;
629  $this->subject->enableLogging = true;
630  $this->subject->errorLog = [];
631  $logDetailsUnique = $this->getUniqueId('details');
632  $this->subject->log('', 23, 0, 42, 1, $logDetailsUnique);
633  $this->assertStringEndsWith($logDetailsUnique, $this->subject->errorLog[0]);
634  }
635 
640  {
641  $backendUser = $this->createMock(BackendUserAuthentication::class);
642  $this->subject->BE_USER = $backendUser;
643  $this->subject->enableLogging = true;
644  $this->subject->errorLog = [];
645  $logDetails = $this->getUniqueId('details');
646  $this->subject->log('', 23, 0, 42, 1, '%1$s' . $logDetails . '%2$s', -1, ['foo', 'bar']);
647  $expected = 'foo' . $logDetails . 'bar';
648  $this->assertStringEndsWith($expected, $this->subject->errorLog[0]);
649  }
650 
661  public function ‪equalSubmittedAndStoredValuesAreDetermined($expected, $submittedValue, $storedValue, $storedType, $allowNull)
662  {
663  $result = $this->callInaccessibleMethod(
664  $this->subject,
665  'isSubmittedValueEqualToStoredValue',
666  $submittedValue,
667  $storedValue,
668  $storedType,
669  $allowNull
670  );
671  $this->assertEquals($expected, $result);
672  }
673 
678  {
679  return [
680  // String
681  'string value "" vs. ""' => [
682  true,
683  '', '', 'string', false
684  ],
685  'string value 0 vs. "0"' => [
686  true,
687  0, '0', 'string', false
688  ],
689  'string value 1 vs. "1"' => [
690  true,
691  1, '1', 'string', false
692  ],
693  'string value "0" vs. ""' => [
694  false,
695  '0', '', 'string', false
696  ],
697  'string value 0 vs. ""' => [
698  false,
699  0, '', 'string', false
700  ],
701  'string value null vs. ""' => [
702  true,
703  null, '', 'string', false
704  ],
705  // Integer
706  'integer value 0 vs. 0' => [
707  true,
708  0, 0, 'int', false
709  ],
710  'integer value "0" vs. "0"' => [
711  true,
712  '0', '0', 'int', false
713  ],
714  'integer value 0 vs. "0"' => [
715  true,
716  0, '0', 'int', false
717  ],
718  'integer value "" vs. "0"' => [
719  true,
720  '', '0', 'int', false
721  ],
722  'integer value "" vs. 0' => [
723  true,
724  '', 0, 'int', false
725  ],
726  'integer value "0" vs. 0' => [
727  true,
728  '0', 0, 'int', false
729  ],
730  'integer value 1 vs. 1' => [
731  true,
732  1, 1, 'int', false
733  ],
734  'integer value 1 vs. "1"' => [
735  true,
736  1, '1', 'int', false
737  ],
738  'integer value "1" vs. "1"' => [
739  true,
740  '1', '1', 'int', false
741  ],
742  'integer value "1" vs. 1' => [
743  true,
744  '1', 1, 'int', false
745  ],
746  'integer value "0" vs. "1"' => [
747  false,
748  '0', '1', 'int', false
749  ],
750  // String with allowed NULL values
751  'string with allowed null value "" vs. ""' => [
752  true,
753  '', '', 'string', true
754  ],
755  'string with allowed null value 0 vs. "0"' => [
756  true,
757  0, '0', 'string', true
758  ],
759  'string with allowed null value 1 vs. "1"' => [
760  true,
761  1, '1', 'string', true
762  ],
763  'string with allowed null value "0" vs. ""' => [
764  false,
765  '0', '', 'string', true
766  ],
767  'string with allowed null value 0 vs. ""' => [
768  false,
769  0, '', 'string', true
770  ],
771  'string with allowed null value null vs. ""' => [
772  false,
773  null, '', 'string', true
774  ],
775  'string with allowed null value "" vs. null' => [
776  false,
777  '', null, 'string', true
778  ],
779  'string with allowed null value null vs. null' => [
780  true,
781  null, null, 'string', true
782  ],
783  // Integer with allowed NULL values
784  'integer with allowed null value 0 vs. 0' => [
785  true,
786  0, 0, 'int', true
787  ],
788  'integer with allowed null value "0" vs. "0"' => [
789  true,
790  '0', '0', 'int', true
791  ],
792  'integer with allowed null value 0 vs. "0"' => [
793  true,
794  0, '0', 'int', true
795  ],
796  'integer with allowed null value "" vs. "0"' => [
797  true,
798  '', '0', 'int', true
799  ],
800  'integer with allowed null value "" vs. 0' => [
801  true,
802  '', 0, 'int', true
803  ],
804  'integer with allowed null value "0" vs. 0' => [
805  true,
806  '0', 0, 'int', true
807  ],
808  'integer with allowed null value 1 vs. 1' => [
809  true,
810  1, 1, 'int', true
811  ],
812  'integer with allowed null value "1" vs. "1"' => [
813  true,
814  '1', '1', 'int', true
815  ],
816  'integer with allowed null value "1" vs. 1' => [
817  true,
818  '1', 1, 'int', true
819  ],
820  'integer with allowed null value 1 vs. "1"' => [
821  true,
822  1, '1', 'int', true
823  ],
824  'integer with allowed null value "0" vs. "1"' => [
825  false,
826  '0', '1', 'int', true
827  ],
828  'integer with allowed null value null vs. ""' => [
829  false,
830  null, '', 'int', true
831  ],
832  'integer with allowed null value "" vs. null' => [
833  false,
834  '', null, 'int', true
835  ],
836  'integer with allowed null value null vs. null' => [
837  true,
838  null, null, 'int', true
839  ],
840  'integer with allowed null value null vs. "0"' => [
841  false,
842  null, '0', 'int', true
843  ],
844  'integer with allowed null value null vs. 0' => [
845  false,
846  null, 0, 'int', true
847  ],
848  'integer with allowed null value "0" vs. null' => [
849  false,
850  '0', null, 'int', true
851  ],
852  ];
853  }
854 
862  {
863  $table = 'phpunit_dummy';
864 
866  ‪$subject = $this->getAccessibleMock(
867  DataHandler::class,
868  ['dummy']
869  );
870 
871  $backendUser = $this->createMock(BackendUserAuthentication::class);
872  ‪$subject->BE_USER = $backendUser;
873  ‪$subject->BE_USER->workspace = 1;
874 
875  ‪$GLOBALS['TCA'][$table] = [];
876  ‪$GLOBALS['TCA'][$table]['ctrl'] = ['label' => 'dummy'];
877  ‪$GLOBALS['TCA'][$table]['columns'] = [
878  'dummy' => [
879  'config' => [
880  'eval' => $eval
881  ]
882  ]
883  ];
884 
885  $this->assertEquals($expected, ‪$subject->_call('getPlaceholderTitleForTableLabel', $table));
886  }
887 
892  {
893  return [
894  [
895  0.10,
896  'double2'
897  ],
898  [
899  0,
900  'int'
901  ],
902  [
903  '0',
904  'datetime'
905  ],
906  [
907  '[PLACEHOLDER, WS#1]',
908  ''
909  ]
910  ];
911  }
912 
916  public function ‪deletePagesOnRootLevelIsDenied()
917  {
919  $dataHandlerMock = $this->getMockBuilder(DataHandler::class)
920  ->setMethods(['canDeletePage', 'log'])
921  ->getMock();
922  $dataHandlerMock
923  ->expects($this->never())
924  ->method('canDeletePage');
925  $dataHandlerMock
926  ->expects($this->once())
927  ->method('log')
928  ->with('pages', 0, 0, 0, 2, 'Deleting all pages starting from the root-page is disabled.', -1, [], 0);
929 
930  $dataHandlerMock->deletePages(0);
931  }
932 
937  {
938  $table = $this->getUniqueId('foo_');
939  $conf = [
940  'type' => 'inline',
941  'foreign_table' => $this->getUniqueId('foreign_foo_'),
942  'behaviour' => [
943  'enableCascadingDelete' => 0,
944  ]
945  ];
946 
948  $mockRelationHandler = $this->createMock(\‪TYPO3\CMS\Core\Database\RelationHandler::class);
949  $mockRelationHandler->itemArray = [
950  '1' => ['table' => $this->getUniqueId('bar_'), 'id' => 67]
951  ];
952 
954  $mockDataHandler = $this->getAccessibleMock(DataHandler::class, ['getInlineFieldType', 'deleteAction', 'createRelationHandlerInstance'], [], '', false);
955  $mockDataHandler->expects($this->once())->method('getInlineFieldType')->will($this->returnValue('field'));
956  $mockDataHandler->expects($this->once())->method('createRelationHandlerInstance')->will($this->returnValue($mockRelationHandler));
957  $mockDataHandler->expects($this->never())->method('deleteAction');
958  $mockDataHandler->deleteRecord_procBasedOnFieldType($table, 42, 'foo', 'bar', $conf);
959  }
960 
965  {
966  return [
967  'None item selected' => [
968  0,
969  0
970  ],
971  'All items selected' => [
972  7,
973  7
974  ],
975  'Item 1 and 2 are selected' => [
976  3,
977  3
978  ],
979  'Value is higher than allowed (all checkboxes checked)' => [
980  15,
981  7
982  ],
983  'Value is higher than allowed (some checkboxes checked)' => [
984  11,
985  3
986  ],
987  'Negative value' => [
988  -5,
989  0
990  ]
991  ];
992  }
993 
1001  public function ‪checkValue_checkReturnsExpectedValues($value, $expectedValue)
1002  {
1003  $expectedResult = [
1004  'value' => $expectedValue
1005  ];
1006  $result = [];
1007  $tcaFieldConfiguration = [
1008  'items' => [
1009  ['Item 1', 0],
1010  ['Item 2', 0],
1011  ['Item 3', 0]
1012  ]
1013  ];
1014  $this->assertSame($expectedResult, $this->subject->_call('checkValueForCheck', $result, $value, $tcaFieldConfiguration, '', 0, 0, ''));
1015  }
1021  {
1022  ‪$GLOBALS['LANG'] = GeneralUtility::makeInstance(\‪TYPO3\CMS\Core\Localization\LanguageService::class);
1023  ‪$GLOBALS['LANG']->init('default');
1024  $expectedResult = ['value' => ''];
1025  $this->assertSame($expectedResult, $this->subject->_call('checkValueForInput', null, ['type' => 'string', 'max' => 40], 'tt_content', 'NEW55c0e67f8f4d32.04974534', 89, 'table_caption'));
1026  }
1027 
1035  public function ‪referenceValuesAreCasted($value, array $configuration, $expected)
1036  {
1037  $this->assertEquals(
1038  $expected,
1039  $this->subject->_call('castReferenceValue', $value, $configuration)
1040  );
1041  }
1046  public function ‪referenceValuesAreCastedDataProvider()
1047  {
1048  return [
1049  'all empty' => [
1050  '', [], ''
1051  ],
1052  'cast zero with MM table' => [
1053  '', ['MM' => 'table'], 0
1054  ],
1055  'cast zero with MM table with default value' => [
1056  '', ['MM' => 'table', 'default' => 13], 0
1057  ],
1058  'cast zero with foreign field' => [
1059  '', ['foreign_field' => 'table', 'default' => 13], 0
1060  ],
1061  'cast zero with foreign field with default value' => [
1062  '', ['foreign_field' => 'table'], 0
1063  ],
1064  'pass zero' => [
1065  '0', [], '0'
1066  ],
1067  'pass value' => [
1068  '1', ['default' => 13], '1'
1069  ],
1070  'use default value' => [
1071  '', ['default' => 13], 13
1072  ],
1073  ];
1074  }
1079  public function ‪clearPrefixFromValueRemovesPrefixDataProvider(): array
1080  {
1081  return [
1082  'normal case' => ['Test (copy 42)', 'Test'],
1083  // all cases below look fishy and indicate bugs
1084  'with double spaces before' => ['Test (copy 42)', 'Test '],
1085  'with three spaces before' => ['Test (copy 42)', 'Test '],
1086  'with space after' => ['Test (copy 42) ', 'Test (copy 42) '],
1087  'with double spaces after' => ['Test (copy 42) ', 'Test (copy 42) '],
1088  'with three spaces after' => ['Test (copy 42) ', 'Test (copy 42) '],
1089  'with double tab before' => ['Test' . "\t" . '(copy 42)', 'Test'],
1090  'with double tab after' => ['Test (copy 42)' . "\t", 'Test (copy 42)' . "\t"],
1091  ];
1092  }
1093 
1100  public function ‪clearPrefixFromValueRemovesPrefix(string $input, string $expected)
1101  {
1102  $languageServiceProphecy = $this->prophesize(\‪TYPO3\CMS\Core\Localization\LanguageService::class);
1103  $languageServiceProphecy->sL('testLabel')->willReturn('(copy %s)');
1104  ‪$GLOBALS['LANG'] = $languageServiceProphecy->reveal();
1105  ‪$GLOBALS['TCA']['testTable']['ctrl']['prependAtCopy'] = 'testLabel';
1106  $this->assertEquals($expected, (new ‪DataHandler())->clearPrefixFromValue('testTable', $input));
1107  }
1108 }
‪TYPO3\CMS\Core\DataHandling\DataHandler
Definition: DataHandler.php:81
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\inputValueCheckDoesNotCallGetDateTimeFormatsForNonDatetimeFieldsDataProvider
‪array inputValueCheckDoesNotCallGetDateTimeFormatsForNonDatetimeFieldsDataProvider()
Definition: DataHandlerTest.php:340
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\logFormatsDetailMessageWithAdditionalDataInLocalErrorArray
‪logFormatsDetailMessageWithAdditionalDataInLocalErrorArray()
Definition: DataHandlerTest.php:635
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\inputValueCheckRecognizesDateTimeValuesAsIntegerValuesCorrectly
‪inputValueCheckRecognizesDateTimeValuesAsIntegerValuesCorrectly($value, int $expected)
Definition: DataHandlerTest.php:313
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\doesCheckModifyAccessListHookGetsCalled
‪doesCheckModifyAccessListHookGetsCalled()
Definition: DataHandlerTest.php:457
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\processDatamapWhenEditingRecordInWorkspaceCreatesNewRecordInWorkspace
‪processDatamapWhenEditingRecordInWorkspaceCreatesNewRecordInWorkspace()
Definition: DataHandlerTest.php:502
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\nonAdminWithTableModifyAccessIsAllowedToModifyNonAdminTable
‪nonAdminWithTableModifyAccessIsAllowedToModifyNonAdminTable()
Definition: DataHandlerTest.php:99
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\processDatamapForFrozenNonZeroWorkspaceReturnsFalse
‪processDatamapForFrozenNonZeroWorkspaceReturnsFalse()
Definition: DataHandlerTest.php:487
‪TYPO3
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\inputValueCheckDoesNotCallGetDateTimeFormatsForNonDatetimeFields
‪inputValueCheckDoesNotCallGetDateTimeFormatsForNonDatetimeFields($tcaFieldConf)
Definition: DataHandlerTest.php:362
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\$backEndUser
‪BackendUserAuthentication $backEndUser
Definition: DataHandlerTest.php:50
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\doesCheckModifyAccessListThrowExceptionOnWrongHookInterface
‪doesCheckModifyAccessListThrowExceptionOnWrongHookInterface()
Definition: DataHandlerTest.php:443
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\nonAdminWithTableModifyAccessIsNotAllowedToModifyAdminTable
‪nonAdminWithTableModifyAccessIsNotAllowedToModifyAdminTable()
Definition: DataHandlerTest.php:127
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\checkValueInputEvalWithSaltedPasswordReturnsHashForSaltedPassword
‪checkValueInputEvalWithSaltedPasswordReturnsHashForSaltedPassword()
Definition: DataHandlerTest.php:221
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\checkValueInputEvalWithEvalDatetimeDataProvider
‪array checkValueInputEvalWithEvalDatetimeDataProvider()
Definition: DataHandlerTest.php:164
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\logDoesNotCallWriteLogOfBackendUserIfLoggingIsDisabled
‪logDoesNotCallWriteLogOfBackendUserIfLoggingIsDisabled()
Definition: DataHandlerTest.php:609
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\getPlaceholderTitleForTableLabelReturnsLabelThatsMatchesLabelFieldConditionsDataProvider
‪array getPlaceholderTitleForTableLabelReturnsLabelThatsMatchesLabelFieldConditionsDataProvider()
Definition: DataHandlerTest.php:887
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\$singletonInstances
‪array $singletonInstances
Definition: DataHandlerTest.php:42
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\checkValueForInputConvertsNullToEmptyString
‪checkValueForInputConvertsNullToEmptyString()
Definition: DataHandlerTest.php:1016
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\checkValue_checkReturnsExpectedValues
‪checkValue_checkReturnsExpectedValues($value, $expectedValue)
Definition: DataHandlerTest.php:997
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\Fixtures\AllowAccessHookFixture
Definition: AllowAccessHookFixture.php:24
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\doesCheckModifyAccessListHookModifyAccessAllowed
‪doesCheckModifyAccessListHookModifyAccessAllowed()
Definition: DataHandlerTest.php:475
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\fixtureCanBeCreated
‪fixtureCanBeCreated()
Definition: DataHandlerTest.php:70
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\$subject
‪DataHandler PHPUnit_Framework_MockObject_MockObject AccessibleObjectInterface $subject
Definition: DataHandlerTest.php:46
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\adminIsAllowedToModifyAdminTable
‪adminIsAllowedToModifyAdminTable()
Definition: DataHandlerTest.php:109
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\referenceValuesAreCastedDataProvider
‪array referenceValuesAreCastedDataProvider()
Definition: DataHandlerTest.php:1042
‪TYPO3\CMS\Core\DataHandling\DataHandler\checkValue_input_Eval
‪array checkValue_input_Eval($value, $evalArray, $is_in, string $table='')
Definition: DataHandler.php:2942
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\inputValuesStringsDataProvider
‪array inputValuesStringsDataProvider()
Definition: DataHandlerTest.php:235
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\inputValuesDataTimeDataProvider
‪array inputValuesDataTimeDataProvider()
Definition: DataHandlerTest.php:284
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\checkValueInputEvalWithEvalDatetime
‪checkValueInputEvalWithEvalDatetime($input, $serverTimezone, $expectedOutput)
Definition: DataHandlerTest.php:181
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\doesCheckFlexFormValueHookGetsCalled
‪doesCheckFlexFormValueHookGetsCalled()
Definition: DataHandlerTest.php:575
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\clearPrefixFromValueRemovesPrefix
‪clearPrefixFromValueRemovesPrefix(string $input, string $expected)
Definition: DataHandlerTest.php:1096
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\nonAdminIsNorAllowedToModifyNonAdminTable
‪nonAdminIsNorAllowedToModifyNonAdminTable()
Definition: DataHandlerTest.php:90
‪TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools
Definition: FlexFormTools.php:36
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\logCallsWriteLogOfBackendUserIfLoggingIsEnabled
‪logCallsWriteLogOfBackendUserIfLoggingIsEnabled()
Definition: DataHandlerTest.php:597
‪TYPO3\CMS\Core\Cache\CacheManager
Definition: CacheManager.php:34
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\Fixtures\InvalidHookFixture
Definition: InvalidHookFixture.php:21
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\$resetSingletonInstances
‪bool $resetSingletonInstances
Definition: DataHandlerTest.php:38
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:45
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\inputValueCheckDbtypeIsIndependentFromTimezoneDataProvider
‪inputValueCheckDbtypeIsIndependentFromTimezoneDataProvider()
Definition: DataHandlerTest.php:370
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\adminIsAllowedToModifyNonAdminTable
‪adminIsAllowedToModifyNonAdminTable()
Definition: DataHandlerTest.php:81
‪TYPO3\CMS\Core\Tests\Unit\DataHandling
Definition: DataHandlerTest.php:3
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\setUp
‪setUp()
Definition: DataHandlerTest.php:55
‪$output
‪$output
Definition: annotationChecker.php:113
‪TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
Definition: FrontendInterface.php:21
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\equalSubmittedAndStoredValuesAreDeterminedDataProvider
‪array equalSubmittedAndStoredValuesAreDeterminedDataProvider()
Definition: DataHandlerTest.php:673
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\checkValueInputEvalWithSaltedPasswordKeepsExistingHash
‪checkValueInputEvalWithSaltedPasswordKeepsExistingHash()
Definition: DataHandlerTest.php:197
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\checkValueInputEvalWithSaltedPasswordKeepsExistingHashForMd5HashedHash
‪checkValueInputEvalWithSaltedPasswordKeepsExistingHashForMd5HashedHash()
Definition: DataHandlerTest.php:209
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\clearPrefixFromValueRemovesPrefixDataProvider
‪array clearPrefixFromValueRemovesPrefixDataProvider()
Definition: DataHandlerTest.php:1075
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\inputValueCheckRecognizesStringValuesAsIntegerValuesCorrectly
‪inputValueCheckRecognizesStringValuesAsIntegerValuesCorrectly($value, $expectedReturnValue)
Definition: DataHandlerTest.php:267
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\equalSubmittedAndStoredValuesAreDetermined
‪equalSubmittedAndStoredValuesAreDetermined($expected, $submittedValue, $storedValue, $storedType, $allowNull)
Definition: DataHandlerTest.php:657
‪TYPO3\CMS\Core\DataHandling\DataHandler\process_datamap
‪bool void process_datamap()
Definition: DataHandler.php:902
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\getPlaceholderTitleForTableLabelReturnsLabelThatsMatchesLabelFieldConditions
‪getPlaceholderTitleForTableLabelReturnsLabelThatsMatchesLabelFieldConditions($expected, $eval)
Definition: DataHandlerTest.php:857
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\logAddsEntryToLocalErrorLogArray
‪logAddsEntryToLocalErrorLogArray()
Definition: DataHandlerTest.php:621
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\nonAdminIsNotAllowedToModifyAdminTable
‪nonAdminIsNotAllowedToModifyAdminTable()
Definition: DataHandlerTest.php:118
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\referenceValuesAreCasted
‪referenceValuesAreCasted($value, array $configuration, $expected)
Definition: DataHandlerTest.php:1031
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\checkValueInputEvalWithEvalDouble2
‪checkValueInputEvalWithEvalDouble2()
Definition: DataHandlerTest.php:145
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\inputValueCheckDbtypeIsIndependentFromTimezone
‪inputValueCheckDbtypeIsIndependentFromTimezone($value, $dbtype, $expectedOutput)
Definition: DataHandlerTest.php:417
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest
Definition: DataHandlerTest.php:34
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\deleteRecord_procBasedOnFieldTypeRespectsEnableCascadingDelete
‪deleteRecord_procBasedOnFieldTypeRespectsEnableCascadingDelete()
Definition: DataHandlerTest.php:932
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\deletePagesOnRootLevelIsDenied
‪deletePagesOnRootLevelIsDenied()
Definition: DataHandlerTest.php:912
‪TYPO3\CMS\Core\Tests\Unit\DataHandling\DataHandlerTest\checkValue_checkReturnsExpectedValuesDataProvider
‪array checkValue_checkReturnsExpectedValuesDataProvider()
Definition: DataHandlerTest.php:960