‪TYPO3CMS  11.5
TcaSelectTreeItemsTest.php
Go to the documentation of this file.
1 <?php
2 
3 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 
19 
20 use Doctrine\DBAL\Result;
21 use Prophecy\Argument;
22 use Prophecy\PhpUnit\ProphecyTrait;
28 use TYPO3\CMS\Core\Database\Query\QueryBuilder;
37 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
38 
46 class ‪TcaSelectTreeItemsTest extends UnitTestCase
47 {
48  use ProphecyTrait;
49 
53  protected ‪$resetSingletonInstances = true;
54 
59  protected function ‪mockDatabaseConnection(): void
60  {
61  $connectionProphet = $this->prophesize(Connection::class);
62  $connectionProphet->quote(Argument::cetera())->will(static function ($arguments) {
63  return "'" . $arguments[0] . "'";
64  });
65  $connectionProphet->quoteIdentifier(Argument::cetera())->will(static function ($arguments) {
66  return '`' . $arguments[0] . '`';
67  });
68 
69  $statementProphet = $this->prophesize(Result::class);
70  $statementProphet->fetchAllAssociative()->shouldBeCalled();
71 
72  $restrictionProphet = $this->prophesize(DefaultRestrictionContainer::class);
73  $restrictionProphet->removeAll()->willReturn($restrictionProphet->reveal());
74  $restrictionProphet->add(Argument::cetera())->willReturn($restrictionProphet->reveal());
75 
76  $queryBuilderProphet = $this->prophesize(QueryBuilder::class);
77  $queryBuilderProphet->expr()->willReturn(
78  GeneralUtility::makeInstance(ExpressionBuilder::class, $connectionProphet->reveal())
79  );
80  $queryBuilderProphet->getRestrictions()->willReturn($restrictionProphet->reveal());
81  $queryBuilderProphet->quoteIdentifier(Argument::cetera())->will(static function ($arguments) {
82  return '`' . $arguments[0] . '`';
83  });
84 
85  $connectionPoolProphet = $this->prophesize(ConnectionPool::class);
86  $connectionPoolProphet->getConnectionForTable('foreignTable')
87  ->willReturn($connectionProphet->reveal());
88  $connectionPoolProphet->getQueryBuilderForTable('foreignTable')
89  ->shouldBeCalled()
90  ->willReturn($queryBuilderProphet->reveal());
91 
92  $queryBuilderProphet->select('foreignTable.uid', 'foreignTable.pid')
93  ->shouldBeCalled()
94  ->willReturn($queryBuilderProphet->reveal());
95  $queryBuilderProphet->from('foreignTable')
96  ->shouldBeCalled()
97  ->willReturn($queryBuilderProphet->reveal());
98  $queryBuilderProphet->from('pages')
99  ->shouldBeCalled()
100  ->willReturn($queryBuilderProphet->reveal());
101  $queryBuilderProphet->where('')
102  ->shouldBeCalled()
103  ->willReturn($queryBuilderProphet->reveal());
104  $queryBuilderProphet->andWhere(' 1=1')
105  ->shouldBeCalled()
106  ->willReturn($queryBuilderProphet->reveal());
107  $queryBuilderProphet->andWhere('`pages.uid` = `foreignTable.pid`')
108  ->shouldBeCalled()
109  ->willReturn($queryBuilderProphet->reveal());
110  $queryBuilderProphet->executeQuery()
111  ->shouldBeCalled()
112  ->willReturn($statementProphet->reveal());
113 
114  // Two instances are needed due to the push/pop behavior of addInstance()
115  GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolProphet->reveal());
116  GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolProphet->reveal());
117  }
118 
123  {
124  ‪$GLOBALS['TCA']['foreignTable'] = [];
125 
126  $iconFactoryProphecy = $this->prophesize(IconFactory::class);
127  GeneralUtility::addInstance(IconFactory::class, $iconFactoryProphecy->reveal());
128  GeneralUtility::addInstance(IconFactory::class, $iconFactoryProphecy->reveal());
129 
130  $fileRepositoryProphecy = $this->prophesize(FileRepository::class);
131  $fileRepositoryProphecy->findByRelation(Argument::cetera())->shouldNotBeCalled();
132  GeneralUtility::setSingletonInstance(FileRepository::class, $fileRepositoryProphecy->reveal());
133 
134  $backendUserProphecy = $this->prophesize(BackendUserAuthentication::class);
135  ‪$GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
136  $backendUserProphecy->getPagePermsClause(Argument::cetera())->willReturn(' 1=1');
137 
138  $languageService = $this->prophesize(LanguageService::class);
139  ‪$GLOBALS['LANG'] = $languageService->reveal();
140  $languageService->sL(Argument::cetera())->willReturnArgument(0);
141 
142  $this->‪mockDatabaseConnection();
143 
144  $treeDataProviderProphecy = $this->prophesize(DatabaseTreeDataProvider::class);
145  GeneralUtility::addInstance(DatabaseTreeDataProvider::class, $treeDataProviderProphecy->reveal());
146 
147  $tableConfigurationTreeProphecy = $this->prophesize(TableConfigurationTree::class);
148  GeneralUtility::addInstance(TableConfigurationTree::class, $tableConfigurationTreeProphecy->reveal());
149  $tableConfigurationTreeProphecy->setDataProvider(Argument::cetera())->shouldBeCalled();
150  $tableConfigurationTreeProphecy->setNodeRenderer(Argument::cetera())->shouldBeCalled();
151  $tableConfigurationTreeProphecy->render()->shouldBeCalled()->willReturn(['fake', 'tree', 'data']);
152 
153  $input = [
154  'tableName' => 'aTable',
155  'effectivePid' => 42,
156  'databaseRow' => [
157  'uid' => 5,
158  'aField' => '1',
159  ],
160  'processedTca' => [
161  'columns' => [
162  'aField' => [
163  'config' => [
164  'type' => 'select',
165  'renderType' => 'selectTree',
166  'treeConfig' => [
167  'childrenField' => 'childrenField',
168  ],
169  'foreign_table' => 'foreignTable',
170  'items' => [],
171  'maxitems' => 1,
172  ],
173  ],
174  ],
175  ],
176  'site' => null,
177  'selectTreeCompileItems' => true,
178  ];
179 
180  $expected = $input;
181  $expected['databaseRow']['aField'] = ['1'];
182  $expected['processedTca']['columns']['aField']['config']['items'] = [
183  'fake', 'tree', 'data',
184  ];
185  self::assertEquals($expected, (new ‪TcaSelectTreeItems())->addData($input));
186  }
187 
192  {
193  ‪$GLOBALS['TCA']['foreignTable'] = [];
194 
195  $iconFactoryProphecy = $this->prophesize(IconFactory::class);
196  GeneralUtility::addInstance(IconFactory::class, $iconFactoryProphecy->reveal());
197  GeneralUtility::addInstance(IconFactory::class, $iconFactoryProphecy->reveal());
198 
199  $fileRepositoryProphecy = $this->prophesize(FileRepository::class);
200  $fileRepositoryProphecy->findByRelation(Argument::cetera())->shouldNotBeCalled();
201  GeneralUtility::setSingletonInstance(FileRepository::class, $fileRepositoryProphecy->reveal());
202 
203  $backendUserProphecy = $this->prophesize(BackendUserAuthentication::class);
204  ‪$GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
205  $backendUserProphecy->getPagePermsClause(Argument::cetera())->willReturn(' 1=1');
206 
207  $languageService = $this->prophesize(LanguageService::class);
208  ‪$GLOBALS['LANG'] = $languageService->reveal();
209  $languageService->sL(Argument::cetera())->willReturnArgument(0);
210 
211  $this->‪mockDatabaseConnection();
212 
213  $treeDataProviderProphecy = $this->prophesize(DatabaseTreeDataProvider::class);
214  GeneralUtility::addInstance(DatabaseTreeDataProvider::class, $treeDataProviderProphecy->reveal());
215 
216  $tableConfigurationTreeProphecy = $this->prophesize(TableConfigurationTree::class);
217  GeneralUtility::addInstance(TableConfigurationTree::class, $tableConfigurationTreeProphecy->reveal());
218  $tableConfigurationTreeProphecy->render()->willReturn([]);
219  $tableConfigurationTreeProphecy->setDataProvider(Argument::cetera())->shouldBeCalled();
220  $tableConfigurationTreeProphecy->setNodeRenderer(Argument::cetera())->shouldBeCalled();
221 
222  $input = [
223  'tableName' => 'aTable',
224  'effectivePid' => 42,
225  'databaseRow' => [
226  'uid' => 5,
227  'aField' => '1',
228  ],
229  'processedTca' => [
230  'columns' => [
231  'aField' => [
232  'config' => [
233  'type' => 'select',
234  'renderType' => 'selectTree',
235  'treeConfig' => [
236  'childrenField' => 'childrenField',
237  ],
238  'foreign_table' => 'foreignTable',
239  'items' => [
240  [ 'static item foo', 1, 'foo-icon' ],
241  [ 'static item bar', 2, 'bar-icon' ],
242  ],
243  'maxitems' => 1,
244  ],
245  ],
246  ],
247  ],
248  'pageTsConfig' => [
249  'TCEFORM.' => [
250  'aTable.' => [
251  'aField.' => [
252  'config.' => [
253  'treeConfig.' => [
254  'startingPoints' => '42',
255  'appearance.' => [
256  'expandAll' => 1,
257  'maxLevels' => 4,
258  'nonSelectableLevels' => '0,1',
259  ],
260  ],
261  ],
262  'altLabels.' => [
263  1 => 'alt static item foo',
264  2 => 'alt static item bar',
265  ],
266  'altIcons.' => [
267  1 => 'foo-alt-icon',
268  2 => 'bar-alt-icon',
269  ],
270  ],
271  ],
272  ],
273  ],
274  'site' => null,
275  'selectTreeCompileItems' => true,
276  ];
277 
278  $result = (new ‪TcaSelectTreeItems())->addData($input);
279 
280  $treeDataProviderProphecy->setStartingPoints([42])->shouldHaveBeenCalled();
281  $treeDataProviderProphecy->setExpandAll(true)->shouldHaveBeenCalled();
282  $treeDataProviderProphecy->setLevelMaximum(4)->shouldHaveBeenCalled();
283  $treeDataProviderProphecy->setNonSelectableLevelList('0,1')->shouldHaveBeenCalled();
284 
285  $resultItems = $result['processedTca']['columns']['aField']['config']['items'];
286  self::assertEquals('alt static item foo', $resultItems[0]['name']);
287  self::assertEquals('foo-alt-icon', $resultItems[0]['icon']);
288  self::assertEquals('alt static item bar', $resultItems[1]['name']);
289  self::assertEquals('bar-alt-icon', $resultItems[1]['icon']);
290  }
291 
293  {
294  return [
295  'one setting' => [
296  'inputStartingPoints' => '42,###SITE:categories.contentCategory###,12',
297  'expectedStartingPoints' => [42, 4711, 12],
298  'site' => new ‪Site('some-site', 1, ['rootPageId' => 1, 'categories' => ['contentCategory' => 4711]]),
299  ],
300  'two settings' => [
301  'inputStartingPoints' => '42,###SITE:categories.contentCategory###,12,###SITE:foobar###',
302  'expectedStartingPoints' => [42, 4711, 12, 1],
303  'site' => new ‪Site('some-site', 1, ['rootPageId' => 1, 'foobar' => 1, 'categories' => ['contentCategory' => 4711]]),
304  ],
305  ];
306  }
307 
312  public function ‪addDataHandsSiteConfigurationOverToTableConfigurationTree(string $inputStartingPoints, array $expectedStartingPoints, Site $site): void
313  {
314  ‪$GLOBALS['TCA']['foreignTable'] = [];
315 
316  $iconFactoryProphecy = $this->prophesize(IconFactory::class);
317  GeneralUtility::addInstance(IconFactory::class, $iconFactoryProphecy->reveal());
318  GeneralUtility::addInstance(IconFactory::class, $iconFactoryProphecy->reveal());
319 
320  $fileRepositoryProphecy = $this->prophesize(FileRepository::class);
321  $fileRepositoryProphecy->findByRelation(Argument::cetera())->shouldNotBeCalled();
322  GeneralUtility::setSingletonInstance(FileRepository::class, $fileRepositoryProphecy->reveal());
323 
324  $backendUserProphecy = $this->prophesize(BackendUserAuthentication::class);
325  ‪$GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
326  $backendUserProphecy->getPagePermsClause(Argument::cetera())->willReturn(' 1=1');
327 
328  $languageService = $this->prophesize(LanguageService::class);
329  ‪$GLOBALS['LANG'] = $languageService->reveal();
330  $languageService->sL(Argument::cetera())->willReturnArgument(0);
331 
332  $this->‪mockDatabaseConnection();
333 
334  $treeDataProviderProphecy = $this->prophesize(DatabaseTreeDataProvider::class);
335  GeneralUtility::addInstance(DatabaseTreeDataProvider::class, $treeDataProviderProphecy->reveal());
336 
337  $tableConfigurationTreeProphecy = $this->prophesize(TableConfigurationTree::class);
338  GeneralUtility::addInstance(TableConfigurationTree::class, $tableConfigurationTreeProphecy->reveal());
339  $tableConfigurationTreeProphecy->render()->willReturn([]);
340  $tableConfigurationTreeProphecy->setDataProvider(Argument::cetera())->shouldBeCalled();
341  $tableConfigurationTreeProphecy->setNodeRenderer(Argument::cetera())->shouldBeCalled();
342 
343  $input = [
344  'tableName' => 'aTable',
345  'effectivePid' => 42,
346  'databaseRow' => [
347  'uid' => 5,
348  'aField' => '1',
349  ],
350  'processedTca' => [
351  'columns' => [
352  'aField' => [
353  'config' => [
354  'type' => 'select',
355  'renderType' => 'selectTree',
356  'treeConfig' => [
357  'childrenField' => 'childrenField',
358  'startingPoints' => $inputStartingPoints,
359  'appearance' => [
360  'expandAll' => true,
361  'maxLevels' => 4,
362  ],
363  ],
364  'foreign_table' => 'foreignTable',
365  'maxitems' => 1,
366  ],
367  ],
368  ],
369  ],
370  'site' => $site,
371  'selectTreeCompileItems' => true,
372  ];
373 
374  $result = (new TcaSelectTreeItems())->addData($input);
375 
376  $treeDataProviderProphecy->setStartingPoints($expectedStartingPoints)->shouldHaveBeenCalled();
377  $treeDataProviderProphecy->setExpandAll(true)->shouldHaveBeenCalled();
378  $treeDataProviderProphecy->setLevelMaximum(4)->shouldHaveBeenCalled();
379  $treeDataProviderProphecy->setNonSelectableLevelList('0')->shouldHaveBeenCalled();
380 
381  $resultFieldConfig = $result['processedTca']['columns']['aField']['config'];
382  self::assertSame(implode(',', $expectedStartingPoints), $resultFieldConfig['treeConfig']['startingPoints']);
383  }
384 }
‪TYPO3\CMS\Backend\Tests\Unit\Form\FormDataProvider\TcaSelectTreeItemsTest\addDataHandsPageTsConfigSettingsOverToTableConfigurationTree
‪addDataHandsPageTsConfigSettingsOverToTableConfigurationTree()
Definition: TcaSelectTreeItemsTest.php:189
‪TYPO3\CMS\Backend\Tests\Unit\Form\FormDataProvider\TcaSelectTreeItemsTest\addDataAddsTreeConfigurationForSelectTreeElement
‪addDataAddsTreeConfigurationForSelectTreeElement()
Definition: TcaSelectTreeItemsTest.php:120
‪TYPO3\CMS\Backend\Tests\Unit\Form\FormDataProvider\TcaSelectTreeItemsTest\addDataHandsSiteConfigurationOverToTableConfigurationTree
‪addDataHandsSiteConfigurationOverToTableConfigurationTree(string $inputStartingPoints, array $expectedStartingPoints, Site $site)
Definition: TcaSelectTreeItemsTest.php:310
‪TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder
Definition: ExpressionBuilder.php:36
‪TYPO3\CMS\Core\Tree\TableConfiguration\DatabaseTreeDataProvider
Definition: DatabaseTreeDataProvider.php:37
‪TYPO3\CMS\Core\Tree\TableConfiguration\TableConfigurationTree
Definition: TableConfigurationTree.php:24
‪TYPO3\CMS\Core\Imaging\IconFactory
Definition: IconFactory.php:34
‪TYPO3\CMS\Core\Site\Entity\Site
Definition: Site.php:42
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaSelectTreeItems
Definition: TcaSelectTreeItems.php:39
‪TYPO3\CMS\Core\Resource\FileRepository
Definition: FileRepository.php:33
‪TYPO3\CMS\Backend\Tests\Unit\Form\FormDataProvider\TcaSelectTreeItemsTest\addDataHandsSiteConfigurationOverToTableConfigurationTreeDataProvider
‪addDataHandsSiteConfigurationOverToTableConfigurationTreeDataProvider()
Definition: TcaSelectTreeItemsTest.php:290
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:38
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Backend\Tests\Unit\Form\FormDataProvider\TcaSelectTreeItemsTest\$resetSingletonInstances
‪bool $resetSingletonInstances
Definition: TcaSelectTreeItemsTest.php:51
‪TYPO3\CMS\Backend\Tests\Unit\Form\FormDataProvider\TcaSelectTreeItemsTest
Definition: TcaSelectTreeItemsTest.php:47
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:42
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Backend\Tests\Unit\Form\FormDataProvider\TcaSelectTreeItemsTest\mockDatabaseConnection
‪mockDatabaseConnection()
Definition: TcaSelectTreeItemsTest.php:57
‪TYPO3\CMS\Core\Database\Query\Restriction\DefaultRestrictionContainer
Definition: DefaultRestrictionContainer.php:24
‪TYPO3\CMS\Backend\Tests\Unit\Form\FormDataProvider
Definition: DatabaseDefaultLanguagePageRowTest.php:18