TYPO3 CMS  TYPO3_6-2
DataHandlerTest.php
Go to the documentation of this file.
1 <?php
3 
19 
27 
31  protected $singletonInstances = array();
32 
36  protected $subject;
37 
41  protected $backEndUser;
42 
47 
48  public function setUp() {
49  $GLOBALS['TCA'] = array();
51  $this->backEndUser = $this->getMock('TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication');
52  $this->mockDatabaseConnection = $this->getMock('TYPO3\\CMS\\Core\\Database\\DatabaseConnection', array(), array(), '', FALSE);
54  $this->subject = new \TYPO3\CMS\Core\DataHandling\DataHandler();
55  $this->subject->start(array(), '', $this->backEndUser);
56  }
57 
58  public function tearDown() {
60  parent::tearDown();
61  }
62 
64  // Tests for the basic functionality
66 
69  public function fixtureCanBeCreated() {
70  $this->assertTrue($this->subject instanceof \TYPO3\CMS\Core\DataHandling\DataHandler);
71  }
72 
74  // Test concerning checkModifyAccessList
76 
80  $this->subject->admin = TRUE;
81  $this->assertTrue($this->subject->checkModifyAccessList('tt_content'));
82  }
83 
88  $this->subject->admin = FALSE;
89  $this->assertFalse($this->subject->checkModifyAccessList('tt_content'));
90  }
91 
96  $this->subject->admin = FALSE;
97  $this->backEndUser->groupData['tables_modify'] = 'tt_content';
98  $this->assertTrue($this->subject->checkModifyAccessList('tt_content'));
99  }
100 
105  $this->subject->admin = TRUE;
106  $this->assertTrue($this->subject->checkModifyAccessList('be_users'));
107  }
108 
113  $this->subject->admin = FALSE;
114  $this->assertFalse($this->subject->checkModifyAccessList('be_users'));
115  }
116 
121  $tableName = $this->getUniqueId('aTable');
122  $GLOBALS['TCA'] = array(
123  $tableName => array(
124  'ctrl' => array(
125  'adminOnly' => TRUE,
126  ),
127  ),
128  );
129  $this->subject->admin = FALSE;
130  $this->backEndUser->groupData['tables_modify'] = $tableName;
131  $this->assertFalse($this->subject->checkModifyAccessList($tableName));
132  }
133 
137  public function evalCheckValueDouble2() {
138  $testData = array(
139  '-0,5' => '-0.50',
140  '1000' => '1000.00',
141  '1000,10' => '1000.10',
142  '1000,0' => '1000.00',
143  '600.000.000,00' => '600000000.00',
144  '60aaa00' => '6000.00'
145  );
146  foreach ($testData as $value => $expectedReturnValue) {
147  $returnValue = $this->subject->checkValue_input_Eval($value, array('double2'), '');
148  $this->assertSame($returnValue['value'], $expectedReturnValue);
149  }
150  }
151 
157  public function inputValuesStringsDataProvider() {
158  return array(
159  '"0" returns zero as integer' => array(
160  '0',
161  0
162  ),
163  '"-1999999" is interpreted correctly as -1999999 and is lot lower then -200000' => array(
164  '-1999999',
165  -1999999
166  ),
167  '"3000000" is interpreted correctly as 3000000 but is higher then 200000 and set to 200000' => array(
168  '3000000',
169  2000000
170  ),
171  );
172  }
173 
178  public function inputValueCheckRecognizesStringValuesAsIntegerValuesCorrectly($value, $expectedReturnValue) {
179  $GLOBALS['TYPO3_DB'] = $this->getMock('TYPO3\\CMS\\Core\\Database\\DatabaseConnection', array(), array(), '', FALSE);
180  $tcaFieldConf = array(
181  'input' => array(),
182  'eval' => 'int',
183  'range' => array(
184  'lower' => '-2000000',
185  'upper' => '2000000'
186  )
187  );
188  $returnValue = $this->subject->checkValue_input(array(), $value, $tcaFieldConf, array());
189  $this->assertSame($returnValue['value'], $expectedReturnValue);
190  }
191 
196  return array(
197  'dbType = date' => array(
198  'date'
199  ),
200  'dbType = datetime' => array(
201  'datetime'
202  )
203  );
204  }
205 
212  $tcaFieldConf = array(
213  'input' => array(),
214  'dbType' => $dbType
215  );
216  $this->mockDatabaseConnection->expects($this->never())->method('getDateTimeFormats');
217  $this->subject->checkValue_input(array(), '', $tcaFieldConf, array());
218  }
219 
226  $dateTimeFormats = array(
227  'date' => array(
228  'empty' => '0000-00-00',
229  'format' => 'Y-m-d'
230  ),
231  'datetime' => array(
232  'empty' => '0000-00-00 00:00:00',
233  'format' => 'Y-m-d H:i:s'
234  )
235  );
236  $tcaFieldConf = array(
237  'input' => array(),
238  'dbType' => $dbType
239  );
240  $this->mockDatabaseConnection->expects($this->once())->method('getDateTimeFormats')->willReturn($dateTimeFormats);
241  $this->subject->checkValue_input(array(), $dateTimeFormats[$dbType]['empty'], $tcaFieldConf, '', 0, '');
242  }
243 
248  return array(
249  'tca without dbType' => array(
250  array(
251  'input' => array()
252  )
253  ),
254  'tca with dbType != date/datetime' => array(
255  array(
256  'input' => array(),
257  'dbType' => 'foo'
258  )
259  )
260  );
261  }
262 
269  $this->mockDatabaseConnection->expects($this->never())->method('getDateTimeFormats');
270  $this->subject->checkValue_input(array(), '', $tcaFieldConf, array());
271  }
272 
273 
275  // Tests concerning checkModifyAccessList
277  //
285  $hookClass = $this->getUniqueId('tx_coretest');
286  eval('class ' . $hookClass . ' {}');
287  $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['checkModifyAccessList'][] = $hookClass;
288  $this->subject->checkModifyAccessList('tt_content');
289  }
290 
297  $hookClass = $this->getUniqueId('tx_coretest');
298  $hookMock = $this->getMock('TYPO3\\CMS\\Core\\DataHandling\\DataHandlerCheckModifyAccessListHookInterface', array('checkModifyAccessList'), array(), $hookClass);
299  $hookMock->expects($this->once())->method('checkModifyAccessList');
300  $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['checkModifyAccessList'][] = $hookClass;
301  $GLOBALS['T3_VAR']['getUserObj'][$hookClass] = $hookMock;
302  $this->subject->checkModifyAccessList('tt_content');
303  }
304 
311  $hookClass = $this->getUniqueId('tx_coretest');
312  eval('
313  class ' . $hookClass . ' implements \\TYPO3\\CMS\\Core\\DataHandling\\DataHandlerCheckModifyAccessListHookInterface {
314  public function checkModifyAccessList(&$accessAllowed, $table, \\TYPO3\\CMS\\Core\\DataHandling\\DataHandler $parent) { $accessAllowed = TRUE; }
315  }
316  ');
317  $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['checkModifyAccessList'][] = $hookClass;
318  $this->assertTrue($this->subject->checkModifyAccessList('tt_content'));
319  }
320 
322  // Tests concerning process_datamap
324 
328  $fixture = $this->getMock('TYPO3\\CMS\\Core\\DataHandling\\DataHandler', array('newlog'));
329  $this->backEndUser->workspace = 1;
330  $this->backEndUser->workspaceRec = array('freeze' => TRUE);
331  $fixture->BE_USER = $this->backEndUser;
332  $this->assertFalse($fixture->process_datamap());
333  }
334 
338  public function processDatamapWhenEditingRecordInWorkspaceCreatesNewRecordInWorkspace() {
339  // Unset possible hooks on method under test
340  // @TODO: Can be removed if unit test boostrap is fixed to not load LocalConfiguration anymore
341  $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass'] = array();
342 
343  $GLOBALS['TYPO3_DB'] = $this->getMock('TYPO3\\CMS\\Core\\Database\\DatabaseConnection');
344 
345  $GLOBALS['TCA'] = array(
346  'pages' => array(
347  'columns' => array(),
348  ),
349  );
350 
352  $subject = $this->getMock(
353  'TYPO3\\CMS\\Core\\DataHandling\\DataHandler',
354  array('newlog', 'checkModifyAccessList', 'tableReadOnly', 'checkRecordUpdateAccess')
355  );
356  $subject->bypassWorkspaceRestrictions = FALSE;
357  $subject->datamap = array(
358  'pages' => array(
359  '1' => array(
360  'header' => 'demo'
361  )
362  )
363  );
364  $subject->expects($this->once())->method('checkModifyAccessList')->with('pages')->will($this->returnValue(TRUE));
365  $subject->expects($this->once())->method('tableReadOnly')->with('pages')->will($this->returnValue(FALSE));
366  $subject->expects($this->once())->method('checkRecordUpdateAccess')->will($this->returnValue(TRUE));
367  $backEndUser = $this->getMock('TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication');
368  $backEndUser->workspace = 1;
369  $backEndUser->workspaceRec = array('freeze' => FALSE);
370  $backEndUser->expects($this->once())->method('workspaceAllowAutoCreation')->will($this->returnValue(TRUE));
371  $backEndUser->expects($this->once())->method('workspaceCannotEditRecord')->will($this->returnValue(TRUE));
372  $backEndUser->expects($this->once())->method('recordEditAccessInternals')->with('pages', 1)->will($this->returnValue(TRUE));
373  $subject->BE_USER = $backEndUser;
374  $createdTceMain = $this->getMock('TYPO3\\CMS\\Core\\DataHandling\\DataHandler', array());
375  $createdTceMain->expects($this->once())->method('start')->with(array(), array(
376  'pages' => array(
377  1 => array(
378  'version' => array(
379  'action' => 'new',
380  'treeLevels' => -1,
381  'label' => 'Auto-created for WS #1'
382  )
383  )
384  )
385  ));
386  $createdTceMain->expects($this->never())->method('process_datamap');
387  $createdTceMain->expects($this->once())->method('process_cmdmap');
388  \TYPO3\CMS\Core\Utility\GeneralUtility::addInstance('TYPO3\\CMS\\Core\\DataHandling\\DataHandler', $createdTceMain);
389  $subject->process_datamap();
390  }
391 
396  $GLOBALS['TYPO3_DB'] = $this->getMock('TYPO3\\CMS\\Core\\Database\\DatabaseConnection', array(), array(), '', FALSE);
397  $hookClass = $this->getUniqueId('tx_coretest');
398  $hookMock = $this->getMock($hookClass, array('checkFlexFormValue_beforeMerge'));
399  $hookMock->expects($this->once())->method('checkFlexFormValue_beforeMerge');
400  $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['checkFlexFormValue'][] = $hookClass;
401  $GLOBALS['T3_VAR']['getUserObj'][$hookClass] = $hookMock;
402  $this->subject->checkValue_flex(array(), array(), array(), array(), array(), '');
403  }
404 
406  // Tests concerning log
408 
412  $backendUser = $this->getMock('TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication');
413  $backendUser->expects($this->once())->method('writelog');
414  $this->subject->enableLogging = TRUE;
415  $this->subject->BE_USER = $backendUser;
416  $this->subject->log('', 23, 0, 42, 0, 'details');
417  }
418 
423  $backendUser = $this->getMock('TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication');
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 
434  $backendUser = $this->getMock('TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication');
435  $this->subject->BE_USER = $backendUser;
436  $this->subject->enableLogging = TRUE;
437  $this->subject->errorLog = array();
438  $logDetailsUnique = $this->getUniqueId('details');
439  $this->subject->log('', 23, 0, 42, 1, $logDetailsUnique);
440  $this->assertStringEndsWith($logDetailsUnique, $this->subject->errorLog[0]);
441  }
442 
447  $backendUser = $this->getMock('TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication');
448  $this->subject->BE_USER = $backendUser;
449  $this->subject->enableLogging = TRUE;
450  $this->subject->errorLog = array();
451  $logDetails = $this->getUniqueId('details');
452  $this->subject->log('', 23, 0, 42, 1, '%1$s' . $logDetails . '%2$s', -1, array('foo', 'bar'));
453  $expected = 'foo' . $logDetails . 'bar';
454  $this->assertStringEndsWith($expected, $this->subject->errorLog[0]);
455  }
456 
467  public function equalSubmittedAndStoredValuesAreDetermined($expected, $submittedValue, $storedValue, $storedType, $allowNull) {
469  $this->subject,
470  'isSubmittedValueEqualToStoredValue',
471  $submittedValue, $storedValue, $storedType, $allowNull
472  );
473  $this->assertEquals($expected, $result);
474  }
475 
480  return array(
481  // String
482  'string value "" vs. ""' => array(
483  TRUE,
484  '', '', 'string', FALSE
485  ),
486  'string value 0 vs. "0"' => array(
487  TRUE,
488  0, '0', 'string', FALSE
489  ),
490  'string value 1 vs. "1"' => array(
491  TRUE,
492  1, '1', 'string', FALSE
493  ),
494  'string value "0" vs. ""' => array(
495  FALSE,
496  '0', '', 'string', FALSE
497  ),
498  'string value 0 vs. ""' => array(
499  FALSE,
500  0, '', 'string', FALSE
501  ),
502  'string value null vs. ""' => array(
503  TRUE,
504  NULL, '', 'string', FALSE
505  ),
506  // Integer
507  'integer value 0 vs. 0' => array(
508  TRUE,
509  0, 0, 'int', FALSE
510  ),
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 "" vs. "0"' => array(
520  TRUE,
521  '', '0', 'int', FALSE
522  ),
523  'integer value "" vs. 0' => array(
524  TRUE,
525  '', 0, 'int', FALSE
526  ),
527  'integer value "0" vs. 0' => array(
528  TRUE,
529  '0', 0, 'int', FALSE
530  ),
531  'integer value 1 vs. 1' => array(
532  TRUE,
533  1, 1, '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 "0" vs. "1"' => array(
548  FALSE,
549  '0', '1', 'int', FALSE
550  ),
551  // String with allowed NULL values
552  'string with allowed null value "" vs. ""' => array(
553  TRUE,
554  '', '', 'string', TRUE
555  ),
556  'string with allowed null value 0 vs. "0"' => array(
557  TRUE,
558  0, '0', 'string', TRUE
559  ),
560  'string with allowed null value 1 vs. "1"' => array(
561  TRUE,
562  1, '1', 'string', TRUE
563  ),
564  'string with allowed null value "0" vs. ""' => array(
565  FALSE,
566  '0', '', '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 null vs. ""' => array(
573  FALSE,
574  NULL, '', 'string', TRUE
575  ),
576  'string with allowed null value "" vs. null' => array(
577  FALSE,
578  '', NULL, 'string', TRUE
579  ),
580  'string with allowed null value null vs. null' => array(
581  TRUE,
582  NULL, NULL, 'string', TRUE
583  ),
584  // Integer with allowed NULL values
585  'integer with allowed null value 0 vs. 0' => array(
586  TRUE,
587  0, 0, 'int', TRUE
588  ),
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 "" vs. "0"' => array(
598  TRUE,
599  '', '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 "0" vs. 0' => array(
606  TRUE,
607  '0', 0, 'int', TRUE
608  ),
609  'integer with allowed null value 1 vs. 1' => array(
610  TRUE,
611  1, 1, '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 "0" vs. "1"' => array(
626  FALSE,
627  '0', '1', 'int', TRUE
628  ),
629  'integer with allowed null value null vs. ""' => array(
630  FALSE,
631  NULL, '', 'int', TRUE
632  ),
633  'integer with allowed null value "" vs. null' => array(
634  FALSE,
635  '', NULL, 'int', TRUE
636  ),
637  'integer with allowed null value null vs. null' => array(
638  TRUE,
639  NULL, NULL, 'int', TRUE
640  ),
641  'integer with allowed null value null vs. "0"' => array(
642  FALSE,
643  NULL, '0', '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 "0" vs. null' => array(
650  FALSE,
651  '0', NULL, 'int', TRUE
652  ),
653  );
654  }
655 
663  $table = 'phpunit_dummy';
664 
665  $subject = $this->getAccessibleMock(
666  'TYPO3\\CMS\\Core\\DataHandling\\DataHandler',
667  array('dummy')
668  );
669 
670  $backendUser = $this->getMock('TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication');
671  $subject->BE_USER = $backendUser;
672  $subject->BE_USER->workspace = 1;
673 
674  $GLOBALS['TCA'][$table] = array();
675  $GLOBALS['TCA'][$table]['ctrl'] = array('label' => 'dummy');
676  $GLOBALS['TCA'][$table]['columns'] = array(
677  'dummy' => array(
678  'config' => array(
679  'eval' => $eval
680  )
681  )
682  );
683 
684  $this->assertEquals($expected, $subject->_call('getPlaceholderTitleForTableLabel', $table));
685  }
686 
691  return array(
692  array(
693  0.10,
694  'double2'
695  ),
696  array(
697  0,
698  'int'
699  ),
700  array(
701  '0',
702  'datetime'
703  ),
704  array(
705  '[PLACEHOLDER, WS#1]',
706  ''
707  )
708  );
709  }
710 
714  public function deletePagesOnRootLevelIsDenied() {
716  $dataHandlerMock = $this->getMock('TYPO3\\CMS\\Core\\DataHandling\\DataHandler', array('canDeletePage', 'newlog2'));
717  $dataHandlerMock
718  ->expects($this->never())
719  ->method('canDeletePage');
720  $dataHandlerMock
721  ->expects($this->once())
722  ->method('newlog2')
723  ->with('Deleting all pages starting from the root-page is disabled.', 'pages', 0, 0, 2);
724 
725  $dataHandlerMock->deletePages(0);
726  }
727 
731  public function deleteRecord_procBasedOnFieldTypeRespectsEnableCascadingDelete() {
732  $table = $this->getUniqueId('foo_');
733  $conf = array(
734  'type' => 'inline',
735  'foreign_table' => $this->getUniqueId('foreign_foo_'),
736  'behaviour' => array(
737  'enableCascadingDelete' => 0,
738  )
739  );
740 
742  $mockRelationHandler = $this->getMock('TYPO3\\CMS\\Core\\Database\\RelationHandler', array(), array(), '', FALSE);
743  $mockRelationHandler->itemArray = array(
744  '1' => array('table' => $this->getUniqueId('bar_'), 'id' => 67)
745  );
746 
748  $mockDataHandler = $this->getAccessibleMock('TYPO3\\CMS\\Core\\DataHandling\\DataHandler', array('getInlineFieldType', 'deleteAction', 'createRelationHandlerInstance'), array(), '', FALSE);
749  $mockDataHandler->expects($this->once())->method('getInlineFieldType')->will($this->returnValue('field'));
750  $mockDataHandler->expects($this->once())->method('createRelationHandlerInstance')->will($this->returnValue($mockRelationHandler));
751  $mockDataHandler->expects($this->never())->method('deleteAction');
752  $mockDataHandler->deleteRecord_procBasedOnFieldType($table, 42, 'foo', 'bar', $conf);
753  }
754 
759  return array(
760  'None item selected' => array(
761  0,
762  0
763  ),
764  'All items selected' => array(
765  7,
766  7
767  ),
768  'Item 1 and 2 are selected' => array(
769  3,
770  3
771  ),
772  'Value is higher than allowed' => array(
773  15,
774  7
775  ),
776  'Negative value' => array(
777  -5,
778  0
779  )
780  );
781  }
782 
790  public function checkValue_checkReturnsExpectedValues($value, $expectedValue) {
791  $expectedResult = array(
792  'value' => $expectedValue
793  );
794  $result = array();
795  $tcaFieldConfiguration = array(
796  'items' => array(
797  array('Item 1', 0),
798  array('Item 2', 0),
799  array('Item 3', 0)
800  )
801  );
802  $this->assertSame($expectedResult, $this->subject->checkValue_check($result, $value, $tcaFieldConfiguration, array()));
803  }
804 }
static addInstance($className, $instance)
equalSubmittedAndStoredValuesAreDetermined($expected, $submittedValue, $storedValue, $storedType, $allowNull)
static resetSingletonInstances(array $newSingletonInstances)
getPlaceholderTitleForTableLabelReturnsLabelThatsMatchesLabelFieldConditions($expected, $eval)
getAccessibleMock( $originalClassName, array $methods=array(), array $arguments=array(), $mockClassName='', $callOriginalConstructor=TRUE, $callOriginalClone=TRUE, $callAutoload=TRUE)
if($list_of_literals) if(!empty($literals)) if(!empty($literals)) $result
Analyse literals to prepend the N char to them if their contents aren&#39;t numeric.
inputValueCheckRecognizesStringValuesAsIntegerValuesCorrectly($value, $expectedReturnValue)
if(!defined('TYPO3_MODE')) $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_pre_processing'][]