‪TYPO3CMS  ‪main
TcaCategoryTest.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 PHPUnit\Framework\Attributes\DataProvider;
21 use PHPUnit\Framework\Attributes\Test;
25 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
26 
27 final class ‪TcaCategoryTest extends FunctionalTestCase
28 {
29  protected function ‪setUp(): void
30  {
31  parent::setUp();
32  $this->importCSVDataSet(__DIR__ . '/../Fixtures/CategoryRelations.csv');
33  $this->importCSVDataSet(__DIR__ . '/../../Fixtures/be_users.csv');
34  $backendUser = $this->setUpBackendUser(1);
35  ‪$GLOBALS['LANG'] = $this->get(LanguageServiceFactory::class)->createFromUserPreferences($backendUser);
36  }
37 
38  #[Test]
39  public function ‪addDataOnlyWorksForTypeCategory(): void
40  {
41  $input = [
42  'command' => 'edit',
43  'tableName' => 'tt_content',
44  'effectivePid' => 89,
45  'databaseRow' => [
46  'uid' => 298,
47  'categories' => '2',
48  ],
49  'processedTca' => [
50  'columns' => [
51  'categories' => [
52  'config' => [
53  'type' => 'input',
54  ],
55  ],
56  ],
57  ],
58  ];
59 
60  // We expect no change to the input data
61  $expected = $input;
62 
63  self::assertEquals($expected, (new ‪TcaCategory())->addData($input));
64  }
65 
66  #[Test]
67  public function ‪addDataChecksForTargetRenderType(): void
68  {
69  $input = [
70  'command' => 'edit',
71  'tableName' => 'tt_content',
72  'effectivePid' => 89,
73  'databaseRow' => [
74  'uid' => 298,
75  'categories' => '2',
76  ],
77  'processedTca' => [
78  'columns' => [
79  'categories' => [
80  'config' => $this->‪getFieldConfiguration([
81  'type' => 'category',
82  'renderType' => 'someRenderType',
83  ]),
84  ],
85  ],
86  ],
87  ];
88 
89  // We expect no change to the input data
90  $expected = $input;
91 
92  self::assertEquals($expected, (new ‪TcaCategory())->addData($input));
93  }
94 
95  #[Test]
97  {
98  $input = [
99  'command' => 'edit',
100  'tableName' => 'tt_content',
101  'effectivePid' => 89,
102  'databaseRow' => [
103  'uid' => 298,
104  'categories' => '2',
105  ],
106  'processedTca' => [
107  'columns' => [
108  'categories' => [
109  'config' => $this->‪getFieldConfiguration(['type' => 'category']),
110  ],
111  ],
112  ],
113  ];
114 
115  $expected = $input;
116  $expected['databaseRow']['categories'] = ['2'];
117  $expected['processedTca']['columns']['categories']['config']['treeConfig'] = [
118  'parentField' => 'parent',
119  'appearance' => [
120  'expandAll' => true,
121  'showHeader' => true,
122  'maxLevels' => 99,
123  ],
124  ];
125 
126  self::assertEquals($expected, (new ‪TcaCategory())->addData($input));
127  }
128 
129  #[Test]
131  {
132  $input = [
133  'command' => 'edit',
134  'tableName' => 'tt_content',
135  'effectivePid' => 89,
136  'databaseRow' => [
137  'uid' => 298,
138  'categories' => '2',
139  ],
140  'processedTca' => [
141  'columns' => [
142  'categories' => [
143  'config' => $this->‪getFieldConfiguration(['type' => 'category']),
144  ],
145  ],
146  ],
147  'pageTsConfig' => [
148  'TCEFORM.' => [
149  'tt_content.' => [
150  'categories.' => [
151  'config.' => [
152  'treeConfig.' => [
153  'startingPoints' => '1',
154  'appearance.' => [
155  'expandAll' => false,
156  'maxLevels' => 10,
157  ],
158  ],
159  ],
160  ],
161  ],
162  ],
163  ],
164  ];
165 
166  $expected = $input;
167  $expected['databaseRow']['categories'] = ['2'];
168  $expected['processedTca']['columns']['categories']['config']['treeConfig'] = [
169  'parentField' => 'parent',
170  'startingPoints' => '1',
171  'appearance' => [
172  'expandAll' => false,
173  'showHeader' => true,
174  'maxLevels' => 10,
175  ],
176  ];
177 
178  self::assertEquals($expected, (new ‪TcaCategory())->addData($input));
179  }
180 
182  {
183  return [
184  'one setting' => [
185  'inputStartingPoints' => '42,###SITE:categories.contentCategory###,12',
186  'expectedStartingPoints' => '42,4711,12',
187  'site' => new ‪Site('some-site', 1, ['rootPageId' => 1, 'categories' => ['contentCategory' => 4711]]),
188  ],
189  'one setting, multiple categories as array' => [
190  'inputStartingPoints' => '###SITE:categories.contentCategories###',
191  'expectedStartingPoints' => '4711,4712,42',
192  'site' => new ‪Site('some-site', 1, ['rootPageId' => 1, 'categories' => ['contentCategories' => [4711, 4712, 42]]]),
193  ],
194  'one setting, multiple categories as csv' => [
195  'inputStartingPoints' => '###SITE:categories.contentCategories###',
196  'expectedStartingPoints' => '4711,4712,42',
197  'site' => new ‪Site('some-site', 1, ['rootPageId' => 1, 'categories' => ['contentCategories' => '4711,4712,42']]),
198  ],
199  'two settings' => [
200  'inputStartingPoints' => '42,###SITE:categories.contentCategory###,12,###SITE:foobar###',
201  'expectedStartingPoints' => '42,4711,12,1',
202  'site' => new ‪Site('some-site', 1, ['rootPageId' => 1, 'foobar' => 1, 'categories' => ['contentCategory' => 4711]]),
203  ],
204  'one invalid settings' => [
205  'inputStartingPoints' => '42,12,###SITE:invalid###',
206  'expectedStartingPoints' => '42,12',
207  'site' => new ‪Site('some-site', 1, ['rootPageId' => 1]),
208  ],
209  'one valid and one invalid setting' => [
210  'inputStartingPoints' => '42,###SITE:invalid###,12,###SITE:categories.contentCategory###',
211  'expectedStartingPoints' => '42,12,4711,4712',
212  'site' => new ‪Site('some-site', 1, ['rootPageId' => 1, 'categories' => ['contentCategory' => '4711,4712']]),
213  ],
214  ];
215  }
216 
217  #[DataProvider('addDataOverridesDefaultFieldConfigurationBySiteConfigDataProvider')]
218  #[Test]
219  public function ‪addDataOverridesDefaultFieldConfigurationBySiteConfig(string $inputStartingPoints, string $expectedStartingPoints, ‪Site $site): void
220  {
221  $input = [
222  'command' => 'edit',
223  'tableName' => 'tt_content',
224  'effectivePid' => 89,
225  'databaseRow' => [
226  'uid' => 298,
227  'categories' => '2',
228  ],
229  'processedTca' => [
230  'columns' => [
231  'categories' => [
232  'config' => $this->‪getFieldConfiguration([
233  'type' => 'category',
234  'treeConfig' => [
235  'startingPoints' => $inputStartingPoints,
236  ],
237  ]),
238  ],
239  ],
240  ],
241  'site' => $site,
242  ];
243 
244  $expected = $input;
245  $expected['databaseRow']['categories'] = ['2'];
246  $expected['processedTca']['columns']['categories']['config']['treeConfig'] = [
247  'parentField' => 'parent',
248  'startingPoints' => $expectedStartingPoints,
249  'appearance' => [
250  'expandAll' => true,
251  'showHeader' => true,
252  'maxLevels' => 99,
253  ],
254  ];
255 
256  self::assertEquals($expected, (new ‪TcaCategory())->addData($input));
257  }
258 
259  #[Test]
261  {
262  $input = [
263  'command' => 'edit',
264  'tableName' => 'tt_content',
265  'effectivePid' => 89,
266  'databaseRow' => [
267  'uid' => 298,
268  'categories' => '2',
269  ],
270  'processedTca' => [
271  'columns' => [
272  'categories' => [
273  'config' => $this->‪getFieldConfiguration(['type' => 'category', 'relationship' => 'manyToMany']),
274  ],
275  ],
276  ],
277  ];
278 
279  $expected = $input;
280  $expected['databaseRow']['categories'] = [
281  '29',
282  '30',
283  ];
284  $expected['processedTca']['columns']['categories']['config']['treeConfig'] = [
285  'parentField' => 'parent',
286  'appearance' => [
287  'expandAll' => true,
288  'showHeader' => true,
289  'maxLevels' => 99,
290  ],
291  ];
292 
293  self::assertEquals($expected, (new ‪TcaCategory())->addData($input));
294  }
295 
296  #[Test]
298  {
299  $input = [
300  'command' => 'edit',
301  'tableName' => 'tt_content',
302  'selectTreeCompileItems' => true,
303  'effectivePid' => 89,
304  'databaseRow' => [
305  'uid' => 298,
306  'categories' => '31',
307  ],
308  'processedTca' => [
309  'columns' => [
310  'categories' => [
311  'config' => $this->‪getFieldConfiguration([
312  'type' => 'category',
313  'items' => [
314  [
315  'Static item',
316  1234,
317  'icon-identifier',
318  ],
319  ],
320  ]),
321  ],
322  ],
323  ],
324  ];
325 
326  $this->expectExceptionCode(1627336557);
327  $this->expectException(\RuntimeException::class);
328 
329  (new ‪TcaCategory())->addData($input);
330  }
331 
332  #[Test]
333  public function ‪addDataBuildsTreeForSingle(): void
334  {
335  $input = [
336  'command' => 'edit',
337  'tableName' => 'tt_content',
338  'selectTreeCompileItems' => true,
339  'effectivePid' => 89,
340  'databaseRow' => [
341  'uid' => 298,
342  'categories' => '31',
343  ],
344  'processedTca' => [
345  'columns' => [
346  'categories' => [
347  'config' => $this->‪getFieldConfiguration([
348  'type' => 'category',
349  'relationship' => 'oneToOne',
350  ]),
351  ],
352  ],
353  ],
354  'rootline' => [],
355  'site' => null,
356  ];
357 
358  $expected = $input;
359  $expected['databaseRow']['categories'] = ['31'];
360  $expected['processedTca']['columns']['categories']['config']['treeConfig'] = [
361  'parentField' => 'parent',
362  'appearance' => [
363  'expandAll' => true,
364  'showHeader' => true,
365  'maxLevels' => 99,
366  ],
367  ];
368  // Expect fetched category items
369  $expected['processedTca']['columns']['categories']['config']['items'] = $this->‪getExpectedCategoryItems([31]);
370 
371  self::assertEquals($expected, (new ‪TcaCategory())->addData($input));
372  }
373 
374  #[Test]
375  public function ‪addDataBuildsTreeForCsv(): void
376  {
377  $input = [
378  'command' => 'edit',
379  'tableName' => 'tt_content',
380  'selectTreeCompileItems' => true,
381  'effectivePid' => 89,
382  'databaseRow' => [
383  'uid' => 298,
384  'categories' => '29,30',
385  ],
386  'processedTca' => [
387  'columns' => [
388  'categories' => [
389  'config' => $this->‪getFieldConfiguration([
390  'type' => 'category',
391  'relationship' => 'oneToMany',
392  'maxitems' => 123,
393  'treeConfig' => [
394  'appearance' => [
395  'expandAll' => false,
396  'showHeader' => false,
397  ],
398  ],
399  ]),
400  ],
401  ],
402  ],
403  'pageTsConfig' => [
404  'TCEFORM.' => [
405  'tt_content.' => [
406  'categories.' => [
407  'removeItems' => '31',
408  ],
409  ],
410  ],
411  ],
412  'rootline' => [],
413  'site' => null,
414  ];
415 
416  $expected = $input;
417  $expected['databaseRow']['categories'] = [
418  '29',
419  '30',
420  ];
421  $expected['processedTca']['columns']['categories']['config']['treeConfig'] = [
422  'parentField' => 'parent',
423  'appearance' => [
424  'expandAll' => false,
425  'showHeader' => false,
426  'maxLevels' => 99,
427  ],
428  ];
429  // Expect fetched category items
430  $expected['processedTca']['columns']['categories']['config']['items'] = $this->‪getExpectedCategoryItems([29, 30]);
431 
432  // TSconfig "removeItems" should be respected
433  unset($expected['processedTca']['columns']['categories']['config']['items'][2]);
434  $expected['processedTca']['columns']['categories']['config']['items'][1]['hasChildren'] = false;
435  $expected['processedTca']['columns']['categories']['config']['items'] = array_values(
436  $expected['processedTca']['columns']['categories']['config']['items']
437  );
438 
439  self::assertEquals($expected, (new ‪TcaCategory())->addData($input));
440  }
441 
442  #[Test]
443  public function ‪addDataBuildsTreeForMM(): void
444  {
445  $input = [
446  'command' => 'edit',
447  'tableName' => 'tt_content',
448  'selectTreeCompileItems' => true,
449  'effectivePid' => 89,
450  'databaseRow' => [
451  'uid' => 298,
452  'categories' => '2',
453  ],
454  'processedTca' => [
455  'columns' => [
456  'categories' => [
457  'config' => $this->‪getFieldConfiguration(['type' => 'category', 'relationship' => 'manyToMany']),
458  ],
459  ],
460  ],
461  'pageTsConfig' => [
462  'TCEFORM.' => [
463  'tt_content.' => [
464  'categories.' => [
465  'keepItems' => '28,29,30',
466  ],
467  ],
468  ],
469  ],
470  'rootline' => [],
471  'site' => null,
472  ];
473 
474  $expected = $input;
475  $expected['databaseRow']['categories'] = [
476  '29',
477  '30',
478  ];
479  $expected['processedTca']['columns']['categories']['config']['treeConfig'] = [
480  'parentField' => 'parent',
481  'appearance' => [
482  'expandAll' => true,
483  'showHeader' => true,
484  'maxLevels' => 99,
485  ],
486  ];
487  // Expect fetched category items
488  $expected['processedTca']['columns']['categories']['config']['items'] = $this->‪getExpectedCategoryItems([29, 30]);
489 
490  // TSconfig "keepItems" should be respected
491  unset($expected['processedTca']['columns']['categories']['config']['items'][2]);
492  $expected['processedTca']['columns']['categories']['config']['items'][1]['hasChildren'] = false;
493  $expected['processedTca']['columns']['categories']['config']['items'] = array_values(
494  $expected['processedTca']['columns']['categories']['config']['items']
495  );
496 
497  self::assertEquals($expected, (new ‪TcaCategory())->addData($input));
498  }
499 
504  protected function ‪getFieldConfiguration(array $input): array
505  {
506  $default = [
507  'relationship' => 'oneToOne',
508  'foreign_table' => 'sys_category',
509  'foreign_table_where' => ' AND {#sys_category}.{#sys_language_uid} IN (-1, 0)',
510  'size' => 20,
511  'default' => 0,
512  'maxitems' => 1,
513  ];
514 
515  if (($input['relationship'] ?? '') === 'manyToMany') {
516  $default['MM'] = 'sys_category_record_mm';
517  $default['MM_opposite_field'] = 'items';
518  $default['MM_match_fields'] = [
519  'tablenames' => 'tt_content',
520  'fieldname' => 'categories',
521  ];
522  $default['maxitems'] = 99999;
523  }
524 
525  return array_replace_recursive($default, $input);
526  }
527 
533  protected function ‪getExpectedCategoryItems(array $checked = []): array
534  {
535  return [
536  [
537  'identifier' => '0',
538  'name' => 'Category',
539  'icon' => 'mimetypes-x-sys_category',
540  'overlayIcon' => '',
541  'depth' => 0,
542  'hasChildren' => true,
543  'selectable' => false,
544  'checked' => false,
545  ],
546  [
547  'identifier' => '28',
548  'name' => 'Category A',
549  'icon' => 'mimetypes-x-sys_category',
550  'overlayIcon' => '',
551  'depth' => 1,
552  'hasChildren' => true,
553  'selectable' => true,
554  'checked' => in_array(28, $checked, true),
555  ],
556  [
557  'identifier' => '31',
558  'name' => 'Category A.A',
559  'icon' => 'mimetypes-x-sys_category',
560  'overlayIcon' => '',
561  'depth' => 2,
562  'hasChildren' => false,
563  'selectable' => true,
564  'checked' => in_array(31, $checked, true),
565  ],
566  [
567  'identifier' => '29',
568  'name' => 'Category B',
569  'icon' => 'mimetypes-x-sys_category',
570  'overlayIcon' => '',
571  'depth' => 1,
572  'hasChildren' => false,
573  'selectable' => true,
574  'checked' => in_array(29, $checked, true),
575  ],
576  [
577  'identifier' => '30',
578  'name' => 'Category C',
579  'icon' => 'mimetypes-x-sys_category',
580  'overlayIcon' => '',
581  'depth' => 1,
582  'hasChildren' => false,
583  'selectable' => true,
584  'checked' => in_array(30, $checked, true),
585  ],
586  ];
587  }
588 }
‪TYPO3\CMS\Core\Localization\LanguageServiceFactory
Definition: LanguageServiceFactory.php:25
‪TYPO3\CMS\Backend\Tests\Functional\Form\FormDataProvider\TcaCategoryTest\addDataInitializesDefaultFieldConfiguration
‪addDataInitializesDefaultFieldConfiguration()
Definition: TcaCategoryTest.php:96
‪TYPO3\CMS\Backend\Tests\Functional\Form\FormDataProvider\TcaCategoryTest\addDataBuildsTreeForSingle
‪addDataBuildsTreeForSingle()
Definition: TcaCategoryTest.php:333
‪TYPO3\CMS\Backend\Tests\Functional\Form\FormDataProvider\TcaCategoryTest\addDataThorwsExceptionForStaticItems
‪addDataThorwsExceptionForStaticItems()
Definition: TcaCategoryTest.php:297
‪TYPO3\CMS\Backend\Tests\Functional\Form\FormDataProvider\TcaCategoryTest\addDataOverridesDefaultFieldConfigurationBySiteConfig
‪addDataOverridesDefaultFieldConfigurationBySiteConfig(string $inputStartingPoints, string $expectedStartingPoints, Site $site)
Definition: TcaCategoryTest.php:219
‪TYPO3\CMS\Backend\Tests\Functional\Form\FormDataProvider\TcaCategoryTest\addDataProcessesCategoryFieldValue
‪addDataProcessesCategoryFieldValue()
Definition: TcaCategoryTest.php:260
‪TYPO3\CMS\Backend\Tests\Functional\Form\FormDataProvider\TcaCategoryTest\addDataBuildsTreeForCsv
‪addDataBuildsTreeForCsv()
Definition: TcaCategoryTest.php:375
‪TYPO3\CMS\Backend\Tests\Functional\Form\FormDataProvider\TcaCategoryTest\addDataChecksForTargetRenderType
‪addDataChecksForTargetRenderType()
Definition: TcaCategoryTest.php:67
‪TYPO3\CMS\Backend\Tests\Functional\Form\FormDataProvider\TcaCategoryTest\addDataBuildsTreeForMM
‪addDataBuildsTreeForMM()
Definition: TcaCategoryTest.php:443
‪TYPO3\CMS\Core\Site\Entity\Site
Definition: Site.php:42
‪TYPO3\CMS\Backend\Tests\Functional\Form\FormDataProvider\TcaCategoryTest\getExpectedCategoryItems
‪array[] getExpectedCategoryItems(array $checked=[])
Definition: TcaCategoryTest.php:533
‪TYPO3\CMS\Backend\Tests\Functional\Form\FormDataProvider\TcaCategoryTest\addDataOverridesDefaultFieldConfigurationByTSconfig
‪addDataOverridesDefaultFieldConfigurationByTSconfig()
Definition: TcaCategoryTest.php:130
‪TYPO3\CMS\Backend\Tests\Functional\Form\FormDataProvider\TcaCategoryTest\setUp
‪setUp()
Definition: TcaCategoryTest.php:29
‪TYPO3\CMS\Backend\Tests\Functional\Form\FormDataProvider\TcaCategoryTest
Definition: TcaCategoryTest.php:28
‪TYPO3\CMS\Backend\Tests\Functional\Form\FormDataProvider\TcaCategoryTest\addDataOverridesDefaultFieldConfigurationBySiteConfigDataProvider
‪static addDataOverridesDefaultFieldConfigurationBySiteConfigDataProvider()
Definition: TcaCategoryTest.php:181
‪TYPO3\CMS\Backend\Tests\Functional\Form\FormDataProvider\TcaCategoryTest\getFieldConfiguration
‪getFieldConfiguration(array $input)
Definition: TcaCategoryTest.php:504
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaCategory
Definition: TcaCategory.php:39
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Backend\Tests\Functional\Form\FormDataProvider
Definition: TcaCategoryTest.php:18
‪TYPO3\CMS\Backend\Tests\Functional\Form\FormDataProvider\TcaCategoryTest\addDataOnlyWorksForTypeCategory
‪addDataOnlyWorksForTypeCategory()
Definition: TcaCategoryTest.php:39