[BUGFIX] BE: DatabaseTreeDataProvider maxLevels incorrect 96/37196/7
authorAndreas Allacher <andreas.allacher@gmx.at>
Wed, 25 Feb 2015 07:45:45 +0000 (08:45 +0100)
committerWouter Wolters <typo3@wouterwolters.nl>
Wed, 20 May 2015 12:47:29 +0000 (14:47 +0200)
The current behaviour for maxLevels with treeConfig is incorrect.
Currently if one uses maxLevels 0, instead of only seeing the root category,
one actually is presented of nodes up to level 2
(if one would specify the levels in nonSelectableLevels).
With maxLevels 1 it is already up to level 3.
Of course, maxLevels 0 should only display the root level, maxLevels 1 only the first child nodes.
Also increased default levelMaximum to 4, in order to ensure old non configured
trees are still behaving as intended.

Change-Id: Ic1565e39abad01599dd67bbb05b0ce9fa7161af4
Resolves: #65304
Releases: master
Reviewed-on: http://review.typo3.org/37196
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
typo3/sysext/core/Classes/Tree/TableConfiguration/AbstractTableConfigurationTreeDataProvider.php
typo3/sysext/core/Classes/Tree/TableConfiguration/DatabaseTreeDataProvider.php
typo3/sysext/core/Tests/Unit/Tree/TableConfiguration/DatabaseTreeDataProviderTest.php [new file with mode: 0644]

index 2ef85e3..222afa7 100644 (file)
@@ -29,7 +29,7 @@ abstract class AbstractTableConfigurationTreeDataProvider extends \TYPO3\CMS\Bac
        /**
         * @var int
         */
-       protected $levelMaximum = 2;
+       protected $levelMaximum = 4;
 
        /**
         * @var \TYPO3\CMS\Backend\Tree\TreeNode
index 7a8ee9b..a2a5c1f 100644 (file)
@@ -277,14 +277,24 @@ class DatabaseTreeDataProvider extends AbstractTableConfigurationTreeDataProvide
                        throw new \InvalidArgumentException('TCA Tree configuration is invalid: tree for different node-Tables is not implemented yet', 1290944650);
                }
                $this->treeData = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\TreeNode::class);
+               $this->loadTreeData();
+               $this->emitPostProcessTreeDataSignal();
+       }
+
+       /**
+        * Loads the tree data (all possible children)
+        *
+        * @return void
+        */
+       protected function loadTreeData() {
                $this->treeData->setId($this->getRootUid());
                $this->treeData->setParentNode(NULL);
-               $childNodes = $this->getChildrenOf($this->treeData, 0);
-               if ($childNodes !== NULL) {
-                       $this->treeData->setChildNodes($childNodes);
+               if ($this->levelMaximum >= 1) {
+                       $childNodes = $this->getChildrenOf($this->treeData, 1);
+                       if ($childNodes !== NULL) {
+                               $this->treeData->setChildNodes($childNodes);
+                       }
                }
-
-               $this->emitPostProcessTreeDataSignal();
        }
 
        /**
@@ -313,7 +323,7 @@ class DatabaseTreeDataProvider extends AbstractTableConfigurationTreeDataProvide
                        foreach ($children as $child) {
                                $node = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\TreeNode::class);
                                $node->setId($child);
-                               if ($level <= $this->levelMaximum) {
+                               if ($level < $this->levelMaximum) {
                                        $children = $this->getChildrenOf($node, $level + 1);
                                        if ($children !== NULL) {
                                                $node->setChildNodes($children);
diff --git a/typo3/sysext/core/Tests/Unit/Tree/TableConfiguration/DatabaseTreeDataProviderTest.php b/typo3/sysext/core/Tests/Unit/Tree/TableConfiguration/DatabaseTreeDataProviderTest.php
new file mode 100644 (file)
index 0000000..3ef72cf
--- /dev/null
@@ -0,0 +1,128 @@
+<?php
+namespace TYPO3\CMS\Core\Tests\Unit\Tree\TableConfiguration;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Backend\Tree\TreeNodeCollection;
+use TYPO3\CMS\Core\Database\DatabaseConnection;
+use TYPO3\CMS\Core\Tests\UnitTestCase;
+use TYPO3\CMS\Core\Tree\TableConfiguration\DatabaseTreeDataProvider;
+use TYPO3\CMS\Backend\Tree\TreeNode;
+
+/**
+ * Testcase for \TYPO3\CMS\Core\Tree\TableConfiguration\DatabaseTreeDataProvider
+ */
+class DatabaseTreeDataProviderTest extends UnitTestCase {
+
+       /**
+        * @var \PHPUnit_Framework_MockObject_MockObject|DatabaseTreeDataProvider|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface
+        */
+       protected $subject;
+
+       /**
+        * @var TreeNode
+        */
+       protected $treeData;
+
+       /**
+        * @var \PHPUnit_Framework_MockObject_MockObject|DatabaseConnection|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface
+        */
+       protected $database;
+
+       /**
+        * Set up
+        *
+        * @return void
+        */
+       protected function setUp() {
+               $this->database = $this->getMock(DatabaseConnection::class, array('exec_SELECTgetSingleRow'));
+               $this->database->expects($this->any())->method('exec_SELECTgetSingleRow')->will($this->returnValue(array('uid' => 0, 'parent' => '')));
+               $this->treeData = new TreeNode();
+               $GLOBALS['TYPO3_DB'] = $this->database;
+       }
+
+       /**
+        * @param array $mockMethods
+        */
+       protected function initializeSubjectMock(array $mockMethods) {
+               $this->subject = $this->getAccessibleMock(DatabaseTreeDataProvider::class, $mockMethods, array(), '', FALSE);
+               $this->subject->expects($this->any())->method('getRootUid')->will($this->returnValue(0));
+               $this->subject->_set('treeData', $this->treeData);
+       }
+
+       /**
+        * @test
+        */
+       public function loadTreeDataLevelMaximumSetToZeroWorks() {
+               $this->initializeSubjectMock(array('getRelatedRecords', 'getRootUid', 'getChildrenOf'));
+               $this->subject->_set('levelMaximum', 0);
+               $this->subject->expects($this->never())->method('getChildrenOf');
+               $this->subject->_call('loadTreeData');
+       }
+
+       /**
+        * @test
+        */
+       public function loadTreeDataLevelMaximumSetToOneWorks() {
+               $this->initializeSubjectMock(array('getRelatedRecords', 'getRootUid', 'getChildrenOf'));
+               $this->subject->_set('levelMaximum', 1);
+               $this->subject->expects($this->once())->method('getChildrenOf')->with($this->treeData, 1);
+               $this->subject->_call('loadTreeData');
+       }
+
+       /**
+        * @test
+        */
+       public function getChildrenOfLevelMaximumSetToOneWorks() {
+               $expectedTreeNode = new TreeNode();
+               $expectedTreeNode->setId(1);
+               $expectedStorage = new TreeNodeCollection();
+               $expectedStorage->append($expectedTreeNode);
+
+               $this->initializeSubjectMock(array('getRelatedRecords', 'getRootUid'));
+               $this->subject->_set('levelMaximum', 1);
+               $this->subject->expects($this->once())->method('getRelatedRecords')->will($this->returnValue(array(1)));
+               $storage = $this->subject->_call('getChildrenOf', $this->treeData, 1);
+
+               $this->assertEquals($expectedStorage, $storage);
+       }
+
+       /**
+        * @test
+        */
+       public function getChildrenOfLevelMaximumSetToTwoWorks() {
+               $expectedStorage = new TreeNodeCollection();
+
+               $expectedFirstLevelTreeNode = new TreeNode();
+               $expectedFirstLevelTreeNode->setId(1);
+
+               $expectedSecondLevelTreeNode = new TreeNode();
+               $expectedSecondLevelTreeNode->setId(2);
+
+               $expectedStorageOfSecondLevelChildren = new TreeNodeCollection();
+               $expectedStorageOfSecondLevelChildren->append($expectedSecondLevelTreeNode);
+
+               $expectedFirstLevelTreeNode->setChildNodes($expectedStorageOfSecondLevelChildren);
+               $expectedStorage->append($expectedFirstLevelTreeNode);
+
+
+               $this->initializeSubjectMock(array('getRelatedRecords', 'getRootUid'));
+               $this->subject->_set('levelMaximum', 2);
+               $this->subject->expects($this->at(0))->method('getRelatedRecords')->will($this->returnValue(array(1)));
+               $this->subject->expects($this->at(1))->method('getRelatedRecords')->will($this->returnValue(array(2)));
+               $storage = $this->subject->_call('getChildrenOf', $this->treeData, 1);
+
+               $this->assertEquals($expectedStorage, $storage);
+       }
+}
\ No newline at end of file