[BUGFIX] Update complete database after extension installation
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Category / CategoryRegistryTest.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Core\Tests\Unit\Category;
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
18 use TYPO3\CMS\Core\Category\CategoryRegistry;
19 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
20
21 /**
22 * Testcase for CategoryRegistry
23 */
24 class CategoryRegistryTest extends UnitTestCase
25 {
26 /**
27 * @var CategoryRegistry
28 */
29 protected $subject;
30
31 /**
32 * @var array
33 */
34 protected $tables;
35
36 /**
37 * Sets up this test suite.
38 */
39 protected function setUp(): void
40 {
41 $GLOBALS['TYPO3_CONF_VARS']['SYS']['defaultCategorizedTables'] = 'pages';
42 $GLOBALS['TCA']['pages']['columns'] = [];
43 $this->subject = new CategoryRegistry();
44 $this->tables = [
45 'first' => $this->getUniqueId('first'),
46 'second' => $this->getUniqueId('second')
47 ];
48 foreach ($this->tables as $tableName) {
49 $GLOBALS['TCA'][$tableName] = [
50 'ctrl' => [],
51 'columns' => [],
52 'types' => [
53 '0' => [
54 'showitem' => ''
55 ],
56 '1' => [
57 'showitem' => ''
58 ]
59 ],
60 ];
61 }
62 }
63
64 /**
65 * @test
66 */
67 public function doesAddReturnTrueOnDefinedTable(): void
68 {
69 $this->assertTrue($this->subject->add('test_extension_a', $this->tables['first'], 'categories'));
70 }
71
72 /**
73 * @test
74 */
75 public function doesAddReturnTrueOnDefinedTableTheFirstTimeAndFalseTheSecondTime(): void
76 {
77 $this->assertTrue($this->subject->add('test_extension_a', $this->tables['first'], 'categories'));
78 $this->assertFalse($this->subject->add('test_extension_a', $this->tables['first'], 'categories'));
79 }
80
81 /**
82 * @test
83 */
84 public function doesAddThrowExceptionOnEmptyTablename(): void
85 {
86 $this->expectException(\InvalidArgumentException::class);
87 $this->expectExceptionCode(1369122038);
88
89 $this->subject->add('test_extension_a', '', 'categories');
90 }
91
92 /**
93 * @test
94 */
95 public function doesAddThrowExceptionOnEmptyExtensionKey(): void
96 {
97 $this->expectException(\InvalidArgumentException::class);
98 $this->expectExceptionCode(1397836158);
99
100 $this->subject->add('', 'foo', 'categories');
101 }
102
103 /**
104 * @test
105 */
106 public function doesAddThrowExceptionOnInvalidTablename(): void
107 {
108 $this->expectException(\InvalidArgumentException::class);
109 $this->expectExceptionCode(1369122038);
110
111 $this->subject->add('test_extension_a', '', 'categories');
112 }
113
114 /**
115 * @test
116 */
117 public function doesAddThrowExceptionOnInvalidExtensionKey(): void
118 {
119 $this->expectException(\InvalidArgumentException::class);
120 $this->expectExceptionCode(1397836158);
121
122 $this->subject->add('', 'foo', 'categories');
123 }
124
125 /**
126 * @test
127 */
128 public function areMultipleElementsOfSameExtensionRegistered(): void
129 {
130 $this->subject->add('test_extension_a', $this->tables['first'], 'categories');
131 $this->subject->add('test_extension_a', $this->tables['second'], 'categories');
132 $this->subject->applyTcaForPreRegisteredTables();
133
134 $this->assertArrayHasKey('categories', $GLOBALS['TCA'][$this->tables['first']]['columns']);
135 $this->assertArrayHasKey('categories', $GLOBALS['TCA'][$this->tables['second']]['columns']);
136 }
137
138 /**
139 * @test
140 */
141 public function areElementsOfDifferentExtensionsRegistered(): void
142 {
143 $this->subject->add('test_extension_a', $this->tables['first'], 'categories');
144 $this->subject->add('test_extension_b', $this->tables['second'], 'categories');
145 $this->subject->applyTcaForPreRegisteredTables();
146
147 $this->assertArrayHasKey('categories', $GLOBALS['TCA'][$this->tables['first']]['columns']);
148 $this->assertArrayHasKey('categories', $GLOBALS['TCA'][$this->tables['second']]['columns']);
149 }
150
151 /**
152 * @test
153 */
154 public function areElementsOfDifferentExtensionsOnSameTableRegistered(): void
155 {
156 $this->subject->add('test_extension_a', $this->tables['first'], 'categories1');
157 $this->subject->add('test_extension_b', $this->tables['first'], 'categories2');
158 $this->subject->applyTcaForPreRegisteredTables();
159
160 $this->assertArrayHasKey('categories1', $GLOBALS['TCA'][$this->tables['first']]['columns']);
161 $this->assertArrayHasKey('categories2', $GLOBALS['TCA'][$this->tables['first']]['columns']);
162 }
163
164 /**
165 * @test
166 */
167 public function areElementsOfSameExtensionOnSameTableRegistered(): void
168 {
169 $this->subject->add('test_extension_a', $this->tables['first'], 'categories1');
170 $this->subject->add('test_extension_a', $this->tables['first'], 'categories2');
171 $this->subject->applyTcaForPreRegisteredTables();
172
173 $this->assertArrayHasKey('categories1', $GLOBALS['TCA'][$this->tables['first']]['columns']);
174 $this->assertArrayHasKey('categories2', $GLOBALS['TCA'][$this->tables['first']]['columns']);
175 }
176
177 /**
178 * @test
179 */
180 public function areDatabaseDefinitionsOfAllElementsAvailable(): void
181 {
182 $this->subject->add('test_extension_a', $this->tables['first'], 'categories');
183 $this->subject->add('test_extension_b', $this->tables['second'], 'categories');
184 $this->subject->add('test_extension_c', $this->tables['first'], 'categories');
185 $definitions = $this->subject->getDatabaseTableDefinitions();
186 $matches = [];
187 preg_match_all('#CREATE TABLE\\s*([^ (]+)\\s*\\(\\s*([^ )]+)\\s+int\\(11\\)[^)]+\\);#mis', $definitions, $matches);
188 $this->assertCount(2, $matches[0]);
189 $this->assertEquals($matches[1][0], $this->tables['first']);
190 $this->assertEquals($matches[2][0], 'categories');
191 $this->assertEquals($matches[1][1], $this->tables['second']);
192 $this->assertEquals($matches[2][1], 'categories');
193 }
194
195 /**
196 * @test
197 */
198 public function areDatabaseDefinitionsOfParticularExtensionAvailable(): void
199 {
200 $this->subject->add('test_extension_a', $this->tables['first'], 'categories');
201 $this->subject->add('test_extension_b', $this->tables['second'], 'categories');
202 $definitions = $this->subject->getDatabaseTableDefinition('test_extension_a');
203 $matches = [];
204 preg_match_all('#CREATE TABLE\\s*([^ (]+)\\s*\\(\\s*([^ )]+)\\s+int\\(11\\)[^)]+\\);#mis', $definitions, $matches);
205 $this->assertCount(1, $matches[0]);
206 $this->assertEquals($matches[1][0], $this->tables['first']);
207 $this->assertEquals($matches[2][0], 'categories');
208 }
209
210 /**
211 * @test
212 */
213 public function areDefaultCategorizedTablesLoaded(): void
214 {
215 $GLOBALS['TYPO3_CONF_VARS']['SYS']['defaultCategorizedTables'] = $this->tables['first'] . ',' . $this->tables['second'];
216 $this->subject->applyTcaForPreRegisteredTables();
217
218 $this->assertArrayHasKey('categories', $GLOBALS['TCA'][$this->tables['first']]['columns']);
219 $this->assertArrayHasKey('categories', $GLOBALS['TCA'][$this->tables['second']]['columns']);
220 }
221
222 /**
223 * @test
224 */
225 public function canApplyTca(): void
226 {
227 $this->subject->add('test_extension_a', $this->tables['first'], 'categories');
228 $this->subject->add('test_extension_b', $this->tables['second'], 'categories');
229 $this->subject->applyTcaForPreRegisteredTables();
230
231 $this->assertNotEmpty($GLOBALS['TCA'][$this->tables['first']]['columns']['categories']);
232 $this->assertNotEmpty($GLOBALS['TCA'][$this->tables['second']]['columns']['categories']);
233 }
234
235 /**
236 * @test
237 */
238 public function isRegisteredReturnsTrueIfElementIsAlreadyRegistered(): void
239 {
240 $this->subject->add('test_extension_a', $this->tables['first'], 'categories');
241 $this->assertTrue($this->subject->isRegistered($this->tables['first'], 'categories'));
242 }
243
244 /**
245 * @test
246 */
247 public function isRegisteredReturnsFalseIfElementIsNotRegistered(): void
248 {
249 $this->subject->add('test_extension_a', $this->tables['first'], 'categories');
250 $this->assertFalse($this->subject->isRegistered($this->tables['first'], '_not_registered'));
251 $this->assertFalse($this->subject->isRegistered($this->tables['second'], 'categories'));
252 }
253
254 /**
255 * @test
256 */
257 public function tabIsAddedForElement(): void
258 {
259 $this->subject->add('text_extension_a', $this->tables['first']);
260 $this->subject->applyTcaForPreRegisteredTables();
261
262 foreach ($GLOBALS['TCA'][$this->tables['first']]['types'] as $typeConfig) {
263 $this->assertContains('--div--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_category.tabs.category', $typeConfig['showitem']);
264 }
265 }
266
267 /**
268 * @test
269 */
270 public function tabIsNotAddedForElementIfFieldListIsSpecified(): void
271 {
272 $this->subject->add('text_extension_a', $this->tables['first'], 'categories', ['fieldList' => 'categories']);
273 $this->subject->applyTcaForPreRegisteredTables();
274
275 foreach ($GLOBALS['TCA'][$this->tables['first']]['types'] as $typeConfig) {
276 $this->assertNotContains('--div--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_category.tabs.category', $typeConfig['showitem']);
277 }
278 }
279
280 /**
281 * @test
282 */
283 public function tabIsOnlyAddedForTypesThatAreSpecifiedInTypesList(): void
284 {
285 $this->subject->add('text_extension_a', $this->tables['first'], 'categories', ['typesList' => '0']);
286 $this->subject->applyTcaForPreRegisteredTables();
287 $this->assertSame('', $GLOBALS['TCA'][$this->tables['first']]['types'][1]['showitem']);
288 }
289
290 /**
291 * @test
292 */
293 public function tabIsAddedOnlyOncePerTable(): void
294 {
295 $this->subject->add('text_extension_a', $this->tables['first'], 'categories1');
296 $this->subject->add('text_extension_a', $this->tables['first'], 'categories2');
297 $this->subject->applyTcaForPreRegisteredTables();
298
299 foreach ($GLOBALS['TCA'][$this->tables['first']]['types'] as $typeConfig) {
300 $this->assertSame(
301 1,
302 substr_count($typeConfig['showitem'], '--div--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_category.tabs.category')
303 );
304 }
305 }
306
307 /**
308 * @test
309 */
310 public function addAllowsSettingOfTheSameTableFieldTwice(): void
311 {
312 $this->subject->add('text_extension_a', $this->tables['first'], 'categories1');
313 $result = $this->subject->add('text_extension_a', $this->tables['first'], 'categories1', [], true);
314 $this->assertTrue($result);
315 }
316
317 /**
318 * @test
319 */
320 public function addInitializesMissingTypes(): void
321 {
322 $this->subject->add('text_extension_a', $this->tables['first'], 'categories1');
323 $GLOBALS['TCA'][$this->tables['first']]['types']['newtypeafterfirstadd'] = ['showitem' => ''];
324 $this->subject->add('text_extension_a', $this->tables['first'], 'categories1', [], true);
325 $this->assertSame(
326 1,
327 substr_count($GLOBALS['TCA'][$this->tables['first']]['types']['newtypeafterfirstadd']['showitem'], '--div--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_category.tabs.category')
328 );
329 }
330 }