[BUGFIX] Add missing namespace parts
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Tree / TableConfiguration / DatabaseTreeDataProviderTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Unit\Tree\TableConfiguration;
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 Doctrine\DBAL\Driver\Statement;
18 use Prophecy\Argument;
19 use TYPO3\CMS\Backend\Tree\TreeNode;
20 use TYPO3\CMS\Backend\Tree\TreeNodeCollection;
21 use TYPO3\CMS\Core\Database\ConnectionPool;
22 use TYPO3\CMS\Core\Database\DatabaseConnection;
23 use TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder;
24 use TYPO3\CMS\Core\Database\Query\QueryBuilder;
25 use TYPO3\CMS\Core\Database\Query\Restriction\QueryRestrictionContainerInterface;
26 use TYPO3\CMS\Core\Tree\TableConfiguration\DatabaseTreeDataProvider;
27 use TYPO3\CMS\Core\Utility\GeneralUtility;
28
29 /**
30 * Testcase for \TYPO3\CMS\Core\Tree\TableConfiguration\DatabaseTreeDataProvider
31 */
32 class DatabaseTreeDataProviderTest extends \TYPO3\Components\TestingFramework\Core\Unit\UnitTestCase
33 {
34 /**
35 * @var \PHPUnit_Framework_MockObject_MockObject|DatabaseTreeDataProvider|\TYPO3\Components\TestingFramework\Core\AccessibleObjectInterface
36 */
37 protected $subject;
38
39 /**
40 * @var TreeNode
41 */
42 protected $treeData;
43
44 /**
45 * @var \PHPUnit_Framework_MockObject_MockObject|DatabaseConnection|\TYPO3\Components\TestingFramework\Core\AccessibleObjectInterface
46 */
47 protected $database;
48
49 /**
50 * Set up
51 *
52 * @return void
53 */
54 protected function setUp()
55 {
56 $this->treeData = new TreeNode();
57 }
58
59 /**
60 * Setup prophecies for database stack
61 *
62 * @param int $instanceCount Number of instances of ConnectionPool::class to register
63 * @return \Prophecy\Prophecy\ObjectProphecy|\TYPO3\CMS\Core\Database\Query\QueryBuilder
64 */
65 protected function setupDatabaseMock(int $instanceCount = 1)
66 {
67 // Prophecies and revelations for a lot of the database stack classes
68 $connectionPoolProphecy = $this->prophesize(ConnectionPool::class);
69 $queryRestrictionProphecy = $this->prophesize(QueryRestrictionContainerInterface::class);
70 $queryBuilderProphecy = $this->prophesize(QueryBuilder::class);
71 $expressionBuilderProphecy = $this->prophesize(ExpressionBuilder::class);
72 $statementProphecy = $this->prophesize(Statement::class);
73
74 $expressionBuilderProphecy->eq(Argument::cetera())->willReturn('1=1');
75
76 // Simulate method call flow on database objects and verify correct query is built
77 $connectionPoolProphecy->getQueryBuilderForTable(Argument::cetera())
78 ->shouldBeCalled()
79 ->willReturn($queryBuilderProphecy->reveal());
80 $queryRestrictionProphecy->removeAll()
81 ->shouldBeCalled()
82 ->willReturn($queryRestrictionProphecy->reveal());
83 $queryBuilderProphecy->getRestrictions()
84 ->shouldBeCalled()
85 ->willReturn($queryRestrictionProphecy->reveal());
86 $queryBuilderProphecy->expr()
87 ->shouldBeCalled()
88 ->willReturn($expressionBuilderProphecy->reveal());
89 $queryBuilderProphecy->execute()
90 ->shouldBeCalled()
91 ->willReturn($statementProphecy->reveal());
92
93 $queryBuilderProphecy->select(Argument::cetera())
94 ->shouldBeCalled()
95 ->willReturn($queryBuilderProphecy->reveal());
96 $queryBuilderProphecy->from(Argument::cetera())
97 ->shouldBeCalled()
98 ->willReturn($queryBuilderProphecy->reveal());
99 $queryBuilderProphecy->createNamedParameter(Argument::cetera())
100 ->shouldBeCalled()
101 ->willReturnArgument(0);
102 $queryBuilderProphecy->where(Argument::cetera())
103 ->shouldBeCalled()
104 ->willReturn($queryBuilderProphecy->reveal());
105 $queryBuilderProphecy->setMaxResults(Argument::cetera())
106 ->shouldBeCalled()
107 ->willReturn($queryBuilderProphecy->reveal());
108
109 $statementProphecy->fetch()
110 ->shouldBeCalled()
111 ->willReturn(['uid' => 0, 'parent' => '']);
112
113 // Register connection pool revelation in framework, this is the entry point used by system unter test
114 for ($i = 1; $i <= $instanceCount; $i++) {
115 GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolProphecy->reveal());
116 }
117
118 return $queryBuilderProphecy;
119 }
120
121 /**
122 * @param array $mockMethods
123 */
124 protected function initializeSubjectMock(array $mockMethods)
125 {
126 $this->subject = $this->getAccessibleMock(DatabaseTreeDataProvider::class, $mockMethods, [], '', false);
127 $this->subject->expects($this->any())->method('getRootUid')->will($this->returnValue(0));
128 $this->subject->_set('treeData', $this->treeData);
129 }
130
131 /**
132 * @test
133 */
134 public function loadTreeDataLevelMaximumSetToZeroWorks()
135 {
136 $this->initializeSubjectMock(['getRelatedRecords', 'getRootUid', 'getChildrenOf']);
137 $this->subject->_set('levelMaximum', 0);
138 $this->subject->expects($this->never())->method('getChildrenOf');
139 $this->subject->_call('loadTreeData');
140 }
141
142 /**
143 * @test
144 */
145 public function loadTreeDataLevelMaximumSetToOneWorks()
146 {
147 $this->initializeSubjectMock(['getRelatedRecords', 'getRootUid', 'getChildrenOf']);
148 $this->subject->_set('levelMaximum', 1);
149 $this->subject->expects($this->once())->method('getChildrenOf')->with($this->treeData, 1);
150 $this->subject->_call('loadTreeData');
151 }
152
153 /**
154 * @test
155 */
156 public function getChildrenOfLevelMaximumSetToOneWorks()
157 {
158 $this->setupDatabaseMock();
159
160 $expectedTreeNode = new TreeNode();
161 $expectedTreeNode->setId(1);
162 $expectedStorage = new TreeNodeCollection();
163 $expectedStorage->append($expectedTreeNode);
164
165 $this->initializeSubjectMock(['getRelatedRecords', 'getRootUid']);
166 $this->subject->_set('levelMaximum', 1);
167 $this->subject->expects($this->once())->method('getRelatedRecords')->will($this->returnValue([1]));
168 $storage = $this->subject->_call('getChildrenOf', $this->treeData, 1);
169
170 $this->assertEquals($expectedStorage, $storage);
171 }
172
173 /**
174 * @test
175 */
176 public function getChildrenOfLevelMaximumSetToTwoWorks()
177 {
178 $this->setupDatabaseMock(2);
179
180 $expectedStorage = new TreeNodeCollection();
181
182 $expectedFirstLevelTreeNode = new TreeNode();
183 $expectedFirstLevelTreeNode->setId(1);
184
185 $expectedSecondLevelTreeNode = new TreeNode();
186 $expectedSecondLevelTreeNode->setId(2);
187
188 $expectedStorageOfSecondLevelChildren = new TreeNodeCollection();
189 $expectedStorageOfSecondLevelChildren->append($expectedSecondLevelTreeNode);
190
191 $expectedFirstLevelTreeNode->setChildNodes($expectedStorageOfSecondLevelChildren);
192 $expectedStorage->append($expectedFirstLevelTreeNode);
193
194 $this->initializeSubjectMock(['getRelatedRecords', 'getRootUid']);
195 $this->subject->_set('levelMaximum', 2);
196 $this->subject->expects($this->at(0))->method('getRelatedRecords')->will($this->returnValue([1]));
197 $this->subject->expects($this->at(1))->method('getRelatedRecords')->will($this->returnValue([2]));
198 $storage = $this->subject->_call('getChildrenOf', $this->treeData, 1);
199
200 $this->assertEquals($expectedStorage, $storage);
201 }
202 }