3ab7f190665791f846fc1af5b4273186696f051b
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Tests / UnitDeprecated / Configuration / TypoScript / ConditionMatching / ConditionMatcherTest.php
1 <?php
2 namespace TYPO3\CMS\Backend\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching;
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 TYPO3\CMS\Backend\Configuration\TypoScript\ConditionMatching\ConditionMatcher;
18 use TYPO3\CMS\Backend\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\Fixtures\TestConditionException;
19 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
20 use TYPO3\CMS\Core\Context\Context;
21 use TYPO3\CMS\Core\Context\UserAspect;
22 use TYPO3\CMS\Core\Http\ServerRequest;
23 use TYPO3\CMS\Core\Log\Logger;
24 use TYPO3\CMS\Core\Utility\GeneralUtility;
25
26 /**
27 * Testcase for class \TYPO3\CMS\Backend\Configuration\TypoScript\ConditionMatching\ConditionMatcher.
28 */
29 class ConditionMatcherTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
30 {
31 /**
32 * @var array
33 */
34 protected $rootline;
35
36 /**
37 * @var \TYPO3\CMS\Backend\Configuration\TypoScript\ConditionMatching\ConditionMatcher
38 */
39 protected $matchCondition;
40
41 /**
42 * @var string
43 */
44 protected $testGlobalNamespace;
45
46 /**
47 * @var string
48 */
49 protected $testTableName;
50
51 /**
52 * @var bool Reset singletons
53 */
54 protected $resetSingletonInstances = true;
55
56 /**
57 * Set up tests
58 */
59 protected function setUp()
60 {
61 $GLOBALS['TYPO3_REQUEST'] = new ServerRequest();
62 $this->testTableName = 'conditionMatcherTestTable';
63 $this->testGlobalNamespace = $this->getUniqueId('TEST');
64 $GLOBALS['TCA'][$this->testTableName] = ['ctrl' => []];
65 $GLOBALS[$this->testGlobalNamespace] = [];
66 $this->setUpBackend();
67 $this->matchCondition = $this->getAccessibleMock(ConditionMatcher::class, ['determineRootline'], [], '', false);
68 $this->matchCondition->method('determineRootline')->willReturn([
69 2 => ['uid' => 121, 'pid' => 111],
70 1 => ['uid' => 111, 'pid' => 101],
71 0 => ['uid' => 101, 'pid' => 0]
72 ]);
73 $this->matchCondition->__construct();
74 $loggerProphecy = $this->prophesize(Logger::class);
75 $this->matchCondition->setLogger($loggerProphecy->reveal());
76 }
77
78 /**
79 * Set up a backend
80 */
81 private function setUpBackend()
82 {
83 $this->rootline = [
84 2 => ['uid' => 121, 'pid' => 111],
85 1 => ['uid' => 111, 'pid' => 101],
86 0 => ['uid' => 101, 'pid' => 0]
87 ];
88 $GLOBALS['BE_USER'] = $this->getMockBuilder(BackendUserAuthentication::class)
89 ->setMethods(['dummy'])
90 ->disableOriginalConstructor()
91 ->getMock();
92 $GLOBALS['BE_USER']->groupList = '13,14,15';
93 $GLOBALS['BE_USER']->user['uid'] = 13;
94 $GLOBALS['BE_USER']->user['admin'] = 1;
95
96 GeneralUtility::makeInstance(Context::class)
97 ->setAspect('backend.user', new UserAspect($GLOBALS['BE_USER']));
98 }
99
100 /**
101 * Set up database mock
102 */
103 private function setUpDatabaseMockForDeterminePageId()
104 {
105 $this->matchCondition = $this->getAccessibleMock(ConditionMatcher::class, ['determineRootline', 'determinePageId'], [], '', false);
106 $this->matchCondition->method('determineRootline')->willReturn([
107 2 => ['uid' => 121, 'pid' => 111],
108 1 => ['uid' => 111, 'pid' => 101],
109 0 => ['uid' => 101, 'pid' => 0]
110 ]);
111 $this->matchCondition->__construct();
112 $loggerProphecy = $this->prophesize(Logger::class);
113 $this->matchCondition->setLogger($loggerProphecy->reveal());
114
115 $this->matchCondition->expects($this->once())->method('determinePageId')->willReturn(999);
116 }
117
118 /**
119 * Tests whether a faulty expression fails.
120 *
121 * @test
122 */
123 public function simulateDisabledMatchAllConditionsFailsOnFaultyExpression()
124 {
125 $this->assertFalse($this->matchCondition->match('[nullCondition = This expression would return FALSE in general]'));
126 }
127
128 /**
129 * Tests whether simulating positive matches for all conditions succeeds.
130 *
131 * @test
132 */
133 public function simulateEnabledMatchAllConditionsSucceeds()
134 {
135 $this->matchCondition->setSimulateMatchResult(true);
136 $this->assertTrue($this->matchCondition->match('[nullCondition = This expression would return FALSE in general]'));
137 }
138
139 /**
140 * Tests whether simulating positive matches for specific conditions succeeds.
141 *
142 * @test
143 */
144 public function simulateEnabledMatchSpecificConditionsSucceeds()
145 {
146 $testCondition = '[' . $this->getUniqueId('test') . ' = Any condition to simulate a positive match]';
147 $this->matchCondition->setSimulateMatchConditions([$testCondition]);
148 $this->assertTrue($this->matchCondition->match($testCondition));
149 }
150
151 /**
152 * Tests whether the language comparison matches.
153 *
154 * @test
155 */
156 public function languageConditionMatchesSingleLanguageExpression()
157 {
158 $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'de-de,de;q=0.8,en-us;q=0.5,en;q=0.3';
159 $this->assertTrue($this->matchCondition->match('[language = *de*]'));
160 $this->assertTrue($this->matchCondition->match('[language = *de-de*]'));
161 // Test expression language
162 // @TODO: this test fails, because setting values after init does not work
163 // $this->assertTrue($this->matchCondition->match('[like(request("getAttributes")["normalizedParams"].getHttpAcceptLanguage(), "**de*")]'));
164 // $this->assertTrue($this->matchCondition->match('[like(request("getAttributes")["normalizedParams"].getHttpAcceptLanguage(), "**de-de*")]'));
165 }
166
167 /**
168 * Tests whether the language comparison matches.
169 *
170 * @test
171 */
172 public function languageConditionMatchesMultipleLanguagesExpression()
173 {
174 $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'de-de,de;q=0.8,en-us;q=0.5,en;q=0.3';
175 $this->assertTrue($this->matchCondition->match('[language = *en*,*de*]'));
176 $this->assertTrue($this->matchCondition->match('[language = *en-us*,*de-de*]'));
177 // Test expression language
178 // @TODO: this test fails, because setting values after init does not work
179 // $this->assertTrue($this->matchCondition->match('[like(request("getAttributes")["normalizedParams"].getHttpAcceptLanguage(), "*en*,*de*")]'));
180 // $this->assertTrue($this->matchCondition->match('[like(request("getAttributes")["normalizedParams"].getHttpAcceptLanguage(), "*en-us*,*de-de*")]'));
181 }
182
183 /**
184 * Tests whether the language comparison matches.
185 *
186 * @test
187 */
188 public function languageConditionMatchesCompleteLanguagesExpression()
189 {
190 $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'de-de,de;q=0.8,en-us;q=0.5,en;q=0.3';
191 $this->assertTrue($this->matchCondition->match('[language = de-de,de;q=0.8,en-us;q=0.5,en;q=0.3]'));
192 // Test expression language
193 // @TODO: this test fails, because setting values after init does not work
194 // $this->assertTrue($this->matchCondition->match('[request("getAttributes")["normalizedParams"].getHttpAcceptLanguage() == "de-de,de;q=0.8,en-us;q=0.5,en;q=0.3"]'));
195 }
196
197 /**
198 * Tests whether usergroup comparison matches.
199 *
200 * @test
201 */
202 public function usergroupConditionMatchesSingleGroupId()
203 {
204 $this->assertTrue($this->matchCondition->match('[usergroup = 13]'));
205 // Test expression language
206 $this->assertTrue($this->matchCondition->match('[usergroup(13)]'));
207 $this->assertTrue($this->matchCondition->match('[usergroup("13")]'));
208 $this->assertTrue($this->matchCondition->match('[usergroup(\'13\')]'));
209 }
210
211 /**
212 * Tests whether usergroup comparison matches.
213 *
214 * @test
215 */
216 public function usergroupConditionMatchesMultipleUserGroupId()
217 {
218 $this->assertTrue($this->matchCondition->match('[usergroup = 999,15,14,13]'));
219 // Test expression language
220 $this->assertTrue($this->matchCondition->match('[usergroup("999,15,14,13")]'));
221 $this->assertTrue($this->matchCondition->match('[usergroup(\'999,15,14,13\')]'));
222 }
223
224 /**
225 * Tests whether user comparison matches.
226 *
227 * @test
228 */
229 public function loginUserConditionMatchesAnyLoggedInUser()
230 {
231 $this->assertTrue($this->matchCondition->match('[loginUser = *]'));
232 // Test expression language
233 $this->assertTrue($this->matchCondition->match('[loginUser("*")]'));
234 $this->assertTrue($this->matchCondition->match('[loginUser(\'*\')]'));
235 }
236
237 /**
238 * Tests whether user comparison matches.
239 *
240 * @test
241 */
242 public function loginUserConditionMatchesSingleLoggedInUser()
243 {
244 $this->assertTrue($this->matchCondition->match('[loginUser = 13]'));
245 // Test expression language
246 $this->assertTrue($this->matchCondition->match('[loginUser(13)]'));
247 $this->assertTrue($this->matchCondition->match('[loginUser("13")]'));
248 $this->assertTrue($this->matchCondition->match('[loginUser(\'13\')]'));
249 }
250
251 /**
252 * Tests whether user comparison matches.
253 *
254 * @test
255 */
256 public function loginUserConditionDoesNotMatchSingleLoggedInUser()
257 {
258 $GLOBALS['BE_USER']->user['uid'] = 13;
259 $this->assertFalse($this->matchCondition->match('[loginUser = 999]'));
260 // Test expression language
261 $this->assertFalse($this->matchCondition->match('[loginUser(999)]'));
262 $this->assertFalse($this->matchCondition->match('[loginUser("999")]'));
263 $this->assertFalse($this->matchCondition->match('[loginUser(\'999\')]'));
264 }
265
266 /**
267 * Tests whether user comparison matches.
268 *
269 * @test
270 */
271 public function loginUserConditionMatchesMultipleLoggedInUsers()
272 {
273 $this->assertTrue($this->matchCondition->match('[loginUser = 999,13]'));
274 // Test expression language
275 $this->assertTrue($this->matchCondition->match('[loginUser("999,13")]'));
276 $this->assertTrue($this->matchCondition->match('[loginUser(\'999,13\')]'));
277 }
278
279 /**
280 * Tests whether checkinf for an admin user matches
281 *
282 * @test
283 */
284 public function adminUserConditionMatchesAdminUser()
285 {
286 $this->assertTrue($this->matchCondition->match('[adminUser = 1]'));
287 // Test expression language
288 $this->assertTrue($this->matchCondition->match('[backend.user.isAdmin == true]'));
289 $this->assertTrue($this->matchCondition->match('[backend.user.isAdmin != false]'));
290 $this->assertTrue($this->matchCondition->match('[backend.user.isAdmin]'));
291 }
292
293 /**
294 * Tests whether checkinf for an admin user matches
295 *
296 * @test
297 */
298 public function adminUserConditionMatchesRegularUser()
299 {
300 $GLOBALS['BE_USER']->user['uid'] = 14;
301 $GLOBALS['BE_USER']->user['admin'] = 0;
302 $this->assertTrue($this->matchCondition->match('[adminUser = 0]'));
303 }
304
305 /**
306 * Tests whether checkinf for an admin user matches
307 *
308 * @test
309 */
310 public function adminUserConditionDoesNotMatchRegularUser()
311 {
312 $GLOBALS['BE_USER']->user['uid'] = 14;
313 $GLOBALS['BE_USER']->user['admin'] = 0;
314 $this->assertFalse($this->matchCondition->match('[adminUser = 1]'));
315 }
316
317 /**
318 * Tests whether numerical comparison matches.
319 *
320 * @test
321 */
322 public function globalVarConditionMatchesOnEqualExpression()
323 {
324 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10 = 10]'), '1');
325 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10.1 = 10.1]'), '2');
326 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10 == 10]'), '3');
327 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10.1 == 10.1]'), '4');
328 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:0 = 0]'), '5');
329 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:0 == 0]'), '6');
330 // Test expression language
331 // Access with LIT is not possible in expression language, because constants available as variable
332 }
333
334 /**
335 * Tests whether numerical comparison matches.
336 *
337 * @test
338 */
339 public function globalVarConditionMatchesOnEqualExpressionWithMultipleValues()
340 {
341 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10 = 10|20|30]'));
342 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10.1 = 10.1|20.2|30.3]'));
343 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:20 = 10|20|30]'));
344 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:20.2 = 10.1|20.2|30.3]'));
345 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10 == 10|20|30]'));
346 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10.1 == 10.1|20.2|30.3]'));
347 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:20 == 10|20|30]'));
348 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:20.2 == 10.1|20.2|30.3]'));
349 // Test expression language
350 // Access with LIT is not possible in expression language, because constants available as variable
351 }
352
353 /**
354 * Tests whether numerical comparison matches.
355 *
356 * @test
357 */
358 public function globalVarConditionMatchesOnNotEqualExpression()
359 {
360 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10 != 20]'));
361 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10.1 != 10.2]'));
362 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:0 != 1]'));
363 // Test expression language
364 // Access with LIT is not possible in expression language, because constants available as variable
365 }
366
367 /**
368 * Tests whether numerical comparison does not match.
369 *
370 * @test
371 */
372 public function globalVarConditionDoesNotMatchOnNotEqualExpression()
373 {
374 $this->assertFalse($this->matchCondition->match('[globalVar = LIT:10 != 10]'));
375 // Test expression language
376 // Access with LIT is not possible in expression language, because constants available as variable
377 }
378
379 /**
380 * Tests whether numerical comparison matches.
381 *
382 * @test
383 */
384 public function globalVarConditionMatchesOnNotEqualExpressionWithMultipleValues()
385 {
386 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10 != 20|30]'));
387 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10.1 != 10.2|20.3]'));
388 // Test expression language
389 // Access with LIT is not possible in expression language, because constants available as variable
390 }
391
392 /**
393 * Tests whether numerical comparison matches.
394 *
395 * @test
396 */
397 public function globalVarConditionMatchesOnLowerThanExpression()
398 {
399 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10 < 20]'));
400 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10.1 < 10.2]'));
401 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:0 < 1]'));
402 // Test expression language
403 // Access with LIT is not possible in expression language, because constants available as variable
404 }
405
406 /**
407 * Tests whether numerical comparison matches.
408 *
409 * @test
410 */
411 public function globalVarConditionMatchesOnLowerThanOrEqualExpression()
412 {
413 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10 <= 10]'));
414 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10 <= 20]'));
415 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10.1 <= 10.1]'));
416 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10.1 <= 10.2]'));
417 // Test expression language
418 // Access with LIT is not possible in expression language, because constants available as variable
419 }
420
421 /**
422 * Tests whether numerical comparison matches.
423 *
424 * @test
425 */
426 public function globalVarConditionMatchesOnGreaterThanExpression()
427 {
428 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:20 > 10]'));
429 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10.2 > 10.1]'));
430 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:1 > 0]'));
431 // Test expression language
432 // Access with LIT is not possible in expression language, because constants available as variable
433 }
434
435 /**
436 * Tests whether numerical comparison matches.
437 *
438 * @test
439 */
440 public function globalVarConditionMatchesOnGreaterThanOrEqualExpression()
441 {
442 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10 >= 10]'));
443 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:20 >= 10]'));
444 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10.1 >= 10.1]'));
445 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10.2 >= 10.1]'));
446 // Test expression language
447 // Access with LIT is not possible in expression language, because constants available as variable
448 }
449
450 /**
451 * Tests whether numerical comparison matches.
452 *
453 * @test
454 */
455 public function globalVarConditionMatchesOnEmptyExpressionWithNoValueSet()
456 {
457 $testKey = $this->getUniqueId('test');
458 $this->assertTrue($this->matchCondition->match('[globalVar = GP:' . $testKey . '=]'));
459 $this->assertTrue($this->matchCondition->match('[globalVar = GP:' . $testKey . ' = ]'));
460 // Test expression language
461 // Access request by request() method
462 }
463
464 /**
465 * Tests whether numerical comparison matches.
466 *
467 * @test
468 */
469 public function globalVarConditionDoesNotMatchOnEmptyExpressionWithValueSetToZero()
470 {
471 $testKey = $this->getUniqueId('test');
472 $_GET = [];
473 $_POST = [$testKey => 0];
474 $this->assertFalse($this->matchCondition->match('[globalVar = GP:' . $testKey . '=]'));
475 $this->assertFalse($this->matchCondition->match('[globalVar = GP:' . $testKey . ' = ]'));
476 }
477
478 /**
479 * Tests whether string comparison matches.
480 *
481 * @test
482 */
483 public function globalStringConditionMatchesOnEqualExpression()
484 {
485 $this->assertTrue($this->matchCondition->match('[globalString = LIT:TYPO3.Test.Condition = TYPO3.Test.Condition]'));
486 $this->assertFalse($this->matchCondition->match('[globalString = LIT:TYPO3.Test.Condition = TYPO3]'));
487 // Test expression language
488 // Access with LIT is not possible in expression language, because constants available as variable
489 }
490
491 /**
492 * Tests whether string comparison matches.
493 *
494 * @test
495 */
496 public function globalStringConditionMatchesOnEmptyExpressionWithValueSetToEmptyString()
497 {
498 $testKey = $this->getUniqueId('test');
499 $_GET = [];
500 $_POST = [$testKey => ''];
501 $this->assertTrue($this->matchCondition->match('[globalString = GP:' . $testKey . '=]'));
502 $this->assertTrue($this->matchCondition->match('[globalString = GP:' . $testKey . ' = ]'));
503 // Test expression language
504 // Access request by request() method
505 }
506
507 /**
508 * Tests whether string comparison matches.
509 *
510 * @test
511 */
512 public function globalStringConditionMatchesOnEmptyLiteralExpressionWithValueSetToEmptyString()
513 {
514 $this->assertTrue($this->matchCondition->match('[globalString = LIT:=]'));
515 $this->assertTrue($this->matchCondition->match('[globalString = LIT: = ]'));
516 // Test expression language
517 // Access with LIT is not possible in expression language, because constants available as variable
518 }
519
520 /**
521 * Tests whether string comparison matches.
522 *
523 * @test
524 */
525 public function globalStringConditionMatchesWildcardExpression()
526 {
527 $this->assertTrue($this->matchCondition->match('[globalString = LIT:TYPO3.Test.Condition = TYPO3?Test?Condition]'));
528 $this->assertTrue($this->matchCondition->match('[globalString = LIT:TYPO3.Test.Condition = TYPO3.T*t.Condition]'));
529 $this->assertTrue($this->matchCondition->match('[globalString = LIT:TYPO3.Test.Condition = TYPO3?T*t?Condition]'));
530 // globalString is not implemented, because globalVar did the job
531 // Access with LIT is not possible in expression language, because constants available as variable
532 }
533
534 /**
535 * Tests whether string comparison matches.
536 *
537 * @test
538 */
539 public function globalStringConditionMatchesRegularExpression()
540 {
541 $this->assertTrue($this->matchCondition->match('[globalString = LIT:TYPO3.Test.Condition = /^[A-Za-z3.]+$/]'));
542 $this->assertTrue($this->matchCondition->match('[globalString = LIT:TYPO3.Test.Condition = /^TYPO3\\..+Condition$/]'));
543 $this->assertFalse($this->matchCondition->match('[globalString = LIT:TYPO3.Test.Condition = /^FALSE/]'));
544 // Test expression language
545 // Access with LIT is not possible in expression language, because constants available as variable
546 }
547
548 /**
549 * Tests whether string comparison matches.
550 *
551 * @test
552 */
553 public function globalStringConditionMatchesEmptyRegularExpression()
554 {
555 $testKey = $this->getUniqueId('test');
556 $_SERVER[$testKey] = '';
557 $this->assertTrue($this->matchCondition->match('[globalString = _SERVER|' . $testKey . ' = /^$/]'));
558 // Test expression language
559 // Access request by request() method
560 }
561
562 /**
563 * Tests whether treeLevel comparison matches.
564 *
565 * @test
566 */
567 public function treeLevelConditionMatchesSingleValue()
568 {
569 $this->matchCondition->setRootline($this->rootline);
570 $this->assertTrue($this->matchCondition->match('[treeLevel = 2]'));
571 // Test expression language
572 $this->assertTrue($this->matchCondition->match('[tree.level == 2]'));
573 }
574
575 /**
576 * Tests whether treeLevel comparison matches.
577 *
578 * @test
579 */
580 public function treeLevelConditionMatchesMultipleValues()
581 {
582 $this->matchCondition->setRootline($this->rootline);
583 $this->assertTrue($this->matchCondition->match('[treeLevel = 999,998,2]'));
584 // Test expression language
585 $this->assertTrue($this->matchCondition->match('[tree.level in [999,998,2]]'));
586 }
587
588 /**
589 * Tests whether treeLevel comparison matches.
590 *
591 * @test
592 */
593 public function treeLevelConditionDoesNotMatchFaultyValue()
594 {
595 $this->matchCondition->setRootline($this->rootline);
596 $this->assertFalse($this->matchCondition->match('[treeLevel = 999]'));
597 // Test expression language
598 $this->assertFalse($this->matchCondition->match('[treeLevel == 999]'));
599 }
600
601 /**
602 * Tests whether treeLevel comparison matches when creating new pages.
603 *
604 * @test
605 */
606 public function treeLevelConditionMatchesCurrentPageIdWhileEditingNewPage()
607 {
608 $GLOBALS['SOBE'] = $this->createMock(\TYPO3\CMS\Backend\Controller\EditDocumentController::class);
609 $GLOBALS['SOBE']->elementsData = [
610 [
611 'table' => 'pages',
612 'uid' => 'NEW4adc6021e37e7',
613 'pid' => 121,
614 'cmd' => 'new',
615 'deleteAccess' => 0
616 ]
617 ];
618 $GLOBALS['SOBE']->data = [];
619 $this->matchCondition->setRootline($this->rootline);
620 $this->matchCondition->setPageId(121);
621 $this->assertTrue($this->matchCondition->match('[treeLevel = 3]'));
622 }
623
624 /**
625 * Tests whether treeLevel comparison matches when creating new pages.
626 *
627 * @test
628 */
629 public function treeLevelConditionMatchesCurrentPageIdWhileSavingNewPage()
630 {
631 $GLOBALS['SOBE'] = $this->createMock(\TYPO3\CMS\Backend\Controller\EditDocumentController::class);
632 $GLOBALS['SOBE']->elementsData = [
633 [
634 'table' => 'pages',
635 /// 999 is the uid of the page that was just created
636 'uid' => 999,
637 'pid' => 121,
638 'cmd' => 'edit',
639 'deleteAccess' => 1
640 ]
641 ];
642 $GLOBALS['SOBE']->data = [
643 'pages' => [
644 'NEW4adc6021e37e7' => [
645 'pid' => 121
646 ]
647 ]
648 ];
649 $this->matchCondition->setRootline($this->rootline);
650 $this->matchCondition->setPageId(121);
651 $this->assertTrue($this->matchCondition->match('[treeLevel = 3]'));
652 }
653
654 /**
655 * Tests whether a page Id is found in the previous rootline entries.
656 *
657 * @test
658 */
659 public function PIDupinRootlineConditionMatchesSinglePageIdInRootline()
660 {
661 $this->matchCondition->setRootline($this->rootline);
662 $this->matchCondition->setPageId(121);
663 $this->assertTrue($this->matchCondition->match('[PIDupinRootline = 111]'));
664 // Test expression language
665 $this->assertTrue($this->matchCondition->match('[111 in tree.rootLineIds]'));
666 $this->assertTrue($this->matchCondition->match('["111" in tree.rootLineIds]'));
667 $this->assertTrue($this->matchCondition->match('[\'111\' in tree.rootLineIds]'));
668 }
669
670 /**
671 * Tests whether a page Id is found in the previous rootline entries.
672 *
673 * @test
674 */
675 public function PIDupinRootlineConditionMatchesMultiplePageIdsInRootline()
676 {
677 $this->matchCondition->setRootline($this->rootline);
678 $this->matchCondition->setPageId(121);
679 $this->assertTrue($this->matchCondition->match('[PIDupinRootline = 999,111,101]'));
680 // Test expression language
681 $this->assertTrue($this->matchCondition->match('[999 in tree.rootLineIds][111 in tree.rootLineIds][101 in tree.rootLineIds]'));
682 }
683
684 /**
685 * Tests whether a page Id is found in the previous rootline entries.
686 *
687 * @test
688 */
689 public function PIDupinRootlineConditionDoesNotMatchPageIdNotInRootline()
690 {
691 $this->matchCondition->setRootline($this->rootline);
692 $this->matchCondition->setPageId(121);
693 $this->assertFalse($this->matchCondition->match('[PIDupinRootline = 999]'));
694 // Test expression language
695 $this->assertFalse($this->matchCondition->match('[999 in tree.rootLineIds]'));
696 }
697
698 /**
699 * Tests whether a page Id is found in the previous rootline entries.
700 *
701 * @test
702 */
703 public function PIDupinRootlineConditionDoesNotMatchLastPageIdInRootline()
704 {
705 $this->matchCondition->setRootline($this->rootline);
706 $this->matchCondition->setPageId(121);
707 $this->assertFalse($this->matchCondition->match('[PIDupinRootline = 121]'));
708 // Test expression language
709 // @TODO: this test fails, because setting values after init does not work
710 // $this->assertFalse($this->matchCondition->match('[page.uid != 121 && 121 in rootLineUids]'));
711 }
712
713 /**
714 * Tests whether a page Id is found in the previous rootline entries.
715 *
716 * @test
717 */
718 public function PIDupinRootlineConditionMatchesCurrentPageIdWhileEditingNewPage()
719 {
720 $GLOBALS['SOBE'] = $this->createMock(\TYPO3\CMS\Backend\Controller\EditDocumentController::class);
721 $GLOBALS['SOBE']->elementsData = [
722 [
723 'table' => 'pages',
724 'uid' => 'NEW4adc6021e37e7',
725 'pid' => 121,
726 'cmd' => 'new',
727 'deleteAccess' => 0
728 ]
729 ];
730 $GLOBALS['SOBE']->data = [];
731 $this->matchCondition->setRootline($this->rootline);
732 $this->matchCondition->setPageId(121);
733 $this->assertTrue($this->matchCondition->match('[PIDupinRootline = 121]'));
734 // Test expression language
735 // page is not available here because, page is initialized with BackendUtility::getRecord()
736 // $this->assertTrue($this->matchCondition->match('[page.uid != 999 && 999 in rootLineUids]'));
737 }
738
739 /**
740 * Tests whether a page Id is found in the previous rootline entries.
741 *
742 * @test
743 */
744 public function PIDupinRootlineConditionMatchesCurrentPageIdWhileSavingNewPage()
745 {
746 $GLOBALS['SOBE'] = $this->createMock(\TYPO3\CMS\Backend\Controller\EditDocumentController::class);
747 $GLOBALS['SOBE']->elementsData = [
748 [
749 'table' => 'pages',
750 /// 999 is the uid of the page that was just created
751 'uid' => 999,
752 'pid' => 121,
753 'cmd' => 'edit',
754 'deleteAccess' => 1
755 ]
756 ];
757 $GLOBALS['SOBE']->data = [
758 'pages' => [
759 'NEW4adc6021e37e7' => [
760 'pid' => 121
761 ]
762 ]
763 ];
764 $this->matchCondition->setRootline($this->rootline);
765 $this->matchCondition->setPageId(121);
766 $this->assertTrue($this->matchCondition->match('[PIDupinRootline = 121]'));
767 // Test expression language
768 // page is not available here because, page is initialized with BackendUtility::getRecord()
769 // $this->assertTrue($this->matchCondition->match('[page.uid != 121 && 121 in rootLineUids]'));
770 }
771
772 /**
773 * Tests whether a page Id is found in all rootline entries.
774 *
775 * @test
776 */
777 public function PIDinRootlineConditionMatchesSinglePageIdInRootline()
778 {
779 $this->matchCondition->setRootline($this->rootline);
780 $this->matchCondition->setPageId(121);
781 $this->assertTrue($this->matchCondition->match('[PIDinRootline = 111]'));
782 // Test expression language
783 $this->assertTrue($this->matchCondition->match('[111 in tree.rootLineIds]'));
784 }
785
786 /**
787 * Tests whether a page Id is found in all rootline entries.
788 *
789 * @test
790 */
791 public function PIDinRootlineConditionMatchesMultiplePageIdsInRootline()
792 {
793 $this->matchCondition->setRootline($this->rootline);
794 $this->matchCondition->setPageId(121);
795 $this->assertTrue($this->matchCondition->match('[PIDinRootline = 999,111,101]'));
796 // Test expression language
797 $this->assertTrue($this->matchCondition->match('[999 in tree.rootLineIds][111 in tree.rootLineIds][101 in tree.rootLineIds]'));
798 }
799
800 /**
801 * Tests whether a page Id is found in all rootline entries.
802 *
803 * @test
804 */
805 public function PIDinRootlineConditionMatchesLastPageIdInRootline()
806 {
807 $this->matchCondition->setRootline($this->rootline);
808 $this->matchCondition->setPageId(121);
809 $this->assertTrue($this->matchCondition->match('[PIDinRootline = 121]'));
810 // Test expression language
811 $this->assertTrue($this->matchCondition->match('[121 in tree.rootLineIds]'));
812 }
813
814 /**
815 * Tests whether a page Id is found in all rootline entries.
816 *
817 * @test
818 */
819 public function PIDinRootlineConditionDoesNotMatchPageIdNotInRootline()
820 {
821 $this->matchCondition->setRootline($this->rootline);
822 $this->matchCondition->setPageId(121);
823 $this->assertFalse($this->matchCondition->match('[PIDinRootline = 999]'));
824 // Test expression language
825 $this->assertFalse($this->matchCondition->match('[999 in tree.rootLineIds]'));
826 }
827
828 /**
829 * Tests whether the compatibility version can be evaluated.
830 * (e.g. 7.9 is compatible to 7.0 but not to 15.0)
831 *
832 * @test
833 */
834 public function compatVersionConditionMatchesOlderRelease()
835 {
836 $this->assertTrue($this->matchCondition->match('[compatVersion = 7.0]'));
837 // Test expression language
838 $this->assertTrue($this->matchCondition->match('[compatVersion(7.0)]'));
839 $this->assertTrue($this->matchCondition->match('[compatVersion("7.0")]'));
840 $this->assertTrue($this->matchCondition->match('[compatVersion(\'7.0\')]'));
841 }
842
843 /**
844 * Tests whether the compatibility version can be evaluated.
845 * (e.g. 7.9 is compatible to 7.0 but not to 15.0)
846 *
847 * @test
848 */
849 public function compatVersionConditionMatchesSameRelease()
850 {
851 $this->assertTrue($this->matchCondition->match('[compatVersion = ' . TYPO3_branch . ']'));
852 // Test expression language
853 $this->assertTrue($this->matchCondition->match('[compatVersion(' . TYPO3_branch . ')]'));
854 $this->assertTrue($this->matchCondition->match('[compatVersion("' . TYPO3_branch . '")]'));
855 $this->assertTrue($this->matchCondition->match('[compatVersion(\'' . TYPO3_branch . '\')]'));
856 }
857
858 /**
859 * Tests whether the compatibility version can be evaluated.
860 * (e.g. 7.9 is compatible to 7.0 but not to 15.0)
861 *
862 * @test
863 */
864 public function compatVersionConditionDoesNotMatchNewerRelease()
865 {
866 $this->assertFalse($this->matchCondition->match('[compatVersion = 15.0]'));
867 // Test expression language
868 $this->assertFalse($this->matchCondition->match('[compatVersion(15.0)]'));
869 $this->assertFalse($this->matchCondition->match('[compatVersion("15.0")]'));
870 $this->assertFalse($this->matchCondition->match('[compatVersion(\'15.0\')]'));
871 }
872
873 /**
874 * Tests whether the generic fetching of variables works with the namespace 'GP'.
875 *
876 * @test
877 */
878 public function genericGetVariablesSucceedsWithNamespaceGP()
879 {
880 $_GET = ['testGet' => 'getTest'];
881 $_POST = ['testPost' => 'postTest'];
882 $this->assertTrue($this->matchCondition->match('[globalString = GP:testGet = getTest]'));
883 $this->assertTrue($this->matchCondition->match('[globalString = GP:testPost = postTest]'));
884 }
885
886 /**
887 * Tests whether the generic fetching of variables does not work with the namespace 'TSFE',
888 * since we are in the backend context here.
889 *
890 * @test
891 */
892 public function genericGetVariablesFailsWithNamespaceTSFE()
893 {
894 $GLOBALS['TSFE'] = new \stdClass();
895 $GLOBALS['TSFE']->id = 1234567;
896 $this->assertFalse($this->matchCondition->match('[globalString = TSFE:id = 1234567]'));
897 }
898
899 /**
900 * Tests whether the generic fetching of variables works with the namespace 'ENV'.
901 *
902 * @test
903 */
904 public function genericGetVariablesSucceedsWithNamespaceENV()
905 {
906 $testKey = $this->getUniqueId('test');
907 putenv($testKey . '=testValue');
908 $this->assertTrue($this->matchCondition->match('[globalString = ENV:' . $testKey . ' = testValue]'));
909 // Test expression language
910 $this->assertTrue($this->matchCondition->match('[getenv("' . $testKey . '") == "testValue"]'));
911 }
912
913 /**
914 * Tests whether the generic fetching of variables works with the namespace 'IENV'.
915 *
916 * @test
917 */
918 public function genericGetVariablesSucceedsWithNamespaceIENV()
919 {
920 $_SERVER['HTTP_HOST'] = GeneralUtility::getIndpEnv('TYPO3_HOST_ONLY') . ':1234567';
921 // getIndpEnv() is polluted after above call, clear cache to have it recalculate for subject execption
922 GeneralUtility::flushInternalRuntimeCaches();
923 $this->assertTrue($this->matchCondition->match('[globalString = IENV:TYPO3_PORT = 1234567]'));
924 // Test expression language
925 // Access to global variables is not possible in expression language
926 }
927
928 /**
929 * Tests whether the generic fetching of variables works with any global namespace.
930 *
931 * @test
932 */
933 public function genericGetVariablesSucceedsWithAnyGlobalNamespace()
934 {
935 $GLOBALS[$this->testGlobalNamespace] = [
936 'first' => 'testFirst',
937 'second' => ['third' => 'testThird']
938 ];
939 $this->assertTrue($this->matchCondition->match('[globalString = ' . $this->testGlobalNamespace . '|first = testFirst]'));
940 $this->assertTrue($this->matchCondition->match('[globalString = ' . $this->testGlobalNamespace . '|second|third = testThird]'));
941 // Test expression language
942 // Access to global variables is not possible in expression language, because access to $GLOBALS is bad...
943 }
944
945 /**
946 * Tests whether determining a pageId works.
947 *
948 * @test
949 */
950 public function pageIdCanBeDeterminedWhileCallingModuleWithPageTree()
951 {
952 $_GET['id'] = 999;
953 $this->matchCondition->match('[globalVar = LIT:10 = 10]');
954 $this->assertEquals(999, $this->matchCondition->getPageId());
955 }
956
957 /**
958 * Tests whether determining a pageId works.
959 *
960 * @test
961 */
962 public function pageIdCanBeDeterminedWhileEditingAPageRecord()
963 {
964 $_GET['edit']['pages'][999] = 'edit';
965 $this->matchCondition->match('[globalVar = LIT:10 = 10]');
966 $this->assertEquals(999, $this->matchCondition->getPageId());
967 }
968
969 /**
970 * Tests whether determining a pageId works.
971 *
972 * @test
973 */
974 public function pageIdCanBeDeterminedWhileEditingARegularRecord()
975 {
976 $this->setUpDatabaseMockForDeterminePageId();
977 $_GET['edit'][$this->testTableName][13] = 'edit';
978 $this->matchCondition->match('[globalVar = LIT:10 = 10]');
979 $this->assertEquals(999, $this->matchCondition->getPageId());
980 }
981
982 /**
983 * Tests whether determining a pageId works.
984 *
985 * @test
986 */
987 public function pageIdCanBeDeterminedWhileCreatingARecord()
988 {
989 $_GET['edit']['pages'][999] = 'new';
990 $this->matchCondition->match('[globalVar = LIT:10 = 10]');
991 $this->assertEquals(999, $this->matchCondition->getPageId());
992 }
993
994 /**
995 * Tests whether determining a pageId works.
996 *
997 * @test
998 */
999 public function pageIdCanBeDeterminedWhileCreatingARecordAfterAnExistingRecord()
1000 {
1001 $this->setUpDatabaseMockForDeterminePageId();
1002 $_GET['edit'][$this->testTableName][-13] = 'new';
1003 $this->matchCondition->match('[globalVar = LIT:10 = 10]');
1004 $this->assertEquals(999, $this->matchCondition->getPageId());
1005 }
1006
1007 /**
1008 * Tests whether determining a pageId works.
1009 *
1010 * @test
1011 */
1012 public function pageIdCanBeDeterminedWhileDeletingAPageRecord()
1013 {
1014 $_GET['cmd']['pages'][999]['delete'] = 1;
1015 $this->matchCondition->match('[globalVar = LIT:10 = 10]');
1016 $this->assertEquals(999, $this->matchCondition->getPageId());
1017 }
1018
1019 /**
1020 * Tests whether determining a pageId works.
1021 *
1022 * @test
1023 */
1024 public function pageIdCanBeDeterminedWhileCopyingARecordToAnotherPage()
1025 {
1026 $_GET['cmd']['pages'][121]['copy'] = 999;
1027 $this->matchCondition->match('[globalVar = LIT:10 = 10]');
1028 $this->assertEquals(999, $this->matchCondition->getPageId());
1029 }
1030
1031 /**
1032 * Tests whether determining a pageId works.
1033 *
1034 * @test
1035 */
1036 public function pageIdCanBeDeterminedWhileCopyingARecordAfterAnExistingRecord()
1037 {
1038 $this->setUpDatabaseMockForDeterminePageId();
1039 $_GET['cmd'][$this->testTableName][121]['copy'] = -13;
1040 $this->matchCondition->match('[globalVar = LIT:10 = 10]');
1041 $this->assertEquals(999, $this->matchCondition->getPageId());
1042 }
1043
1044 /**
1045 * Tests whether determining a pageId works.
1046 *
1047 * @test
1048 */
1049 public function pageIdCanBeDeterminedWhileMovingARecordToAnotherPage()
1050 {
1051 $_GET['cmd']['pages'][121]['move'] = 999;
1052 $this->matchCondition->match('[globalVar = LIT:10 = 10]');
1053 $this->assertEquals(999, $this->matchCondition->getPageId());
1054 }
1055
1056 /**
1057 * @test
1058 */
1059 public function matchCallsTestConditionAndHandsOverParameters()
1060 {
1061 $this->expectException(TestConditionException::class);
1062 $this->expectExceptionCode(1476109533);
1063 $this->matchCondition->match('[TYPO3\\CMS\\Backend\\Tests\\UnitDeprecated\\Configuration\\TypoScript\\ConditionMatching\\Fixtures\\TestCondition = 7, != 6]');
1064 }
1065 }