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