[!!!][TASK] Drop "documentation" extension
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Tests / Unit / Configuration / TypoScript / ConditionMatching / ConditionMatcherTest.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Frontend\Tests\Unit\Configuration\TypoScript\ConditionMatching;
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 Prophecy\Argument;
19 use TYPO3\CMS\Core\Configuration\TypoScript\Exception\InvalidTypoScriptConditionException;
20 use TYPO3\CMS\Core\Http\ServerRequest;
21 use TYPO3\CMS\Core\Site\Entity\Site;
22 use TYPO3\CMS\Core\Utility\GeneralUtility;
23 use TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication;
24 use TYPO3\CMS\Frontend\Configuration\TypoScript\ConditionMatching\ConditionMatcher;
25 use TYPO3\CMS\Frontend\Tests\Unit\Configuration\TypoScript\ConditionMatching\Fixtures\TestConditionException;
26 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
27
28 /**
29 * Test case
30 */
31 class ConditionMatcherTest extends UnitTestCase
32 {
33 /**
34 * @var \TYPO3\CMS\Frontend\Configuration\TypoScript\ConditionMatching\ConditionMatcher Class under test
35 */
36 protected $matchCondition;
37
38 protected function setUp(): void
39 {
40 $this->testGlobalNamespace = $this->getUniqueId('TEST');
41 GeneralUtility::flushInternalRuntimeCaches();
42 $GLOBALS[$this->testGlobalNamespace] = [];
43 $GLOBALS['TSFE'] = new \stdClass();
44 $GLOBALS['TSFE']->tmpl = new \stdClass();
45 $GLOBALS['TSFE']->tmpl->rootLine = [
46 2 => ['uid' => 121, 'pid' => 111],
47 1 => ['uid' => 111, 'pid' => 101],
48 0 => ['uid' => 101, 'pid' => 0]
49 ];
50 $this->matchCondition = GeneralUtility::makeInstance(ConditionMatcher::class);
51 }
52
53 /**
54 * Tests whether a faulty expression fails.
55 *
56 * @test
57 */
58 public function simulateDisabledMatchAllConditionsFailsOnFaultyExpression(): void
59 {
60 $this->matchCondition->matchAll = false;
61 $this->assertFalse($this->matchCondition->match('[nullCondition = This expression would return FALSE in general]'));
62 }
63
64 /**
65 * Tests whether simulating positive matches for all conditions succeeds.
66 *
67 * @test
68 */
69 public function simulateEnabledMatchAllConditionsSucceeds(): void
70 {
71 $this->matchCondition->setSimulateMatchResult(true);
72 $this->assertTrue($this->matchCondition->match('[nullCondition = This expression would return FALSE in general]'));
73 }
74
75 /**
76 * Tests whether simulating positive matches for specific conditions succeeds.
77 *
78 * @test
79 */
80 public function simulateEnabledMatchSpecificConditionsSucceeds(): void
81 {
82 $testCondition = '[' . $this->getUniqueId('test') . ' = Any condition to simulate a positive match]';
83 $this->matchCondition->setSimulateMatchConditions([$testCondition]);
84 $this->assertTrue($this->matchCondition->match($testCondition));
85 }
86
87 /**
88 * Tests whether the language comparison matches.
89 *
90 * @test
91 */
92 public function languageConditionMatchesSingleLanguageExpression(): void
93 {
94 $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'de-de,de;q=0.8,en-us;q=0.5,en;q=0.3';
95 $this->assertTrue($this->matchCondition->match('[language = *de*]'));
96 $this->assertTrue($this->matchCondition->match('[language = *de-de*]'));
97 }
98
99 /**
100 * Tests whether the language comparison matches.
101 *
102 * @test
103 */
104 public function languageConditionMatchesMultipleLanguagesExpression(): void
105 {
106 $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'de-de,de;q=0.8,en-us;q=0.5,en;q=0.3';
107 $this->assertTrue($this->matchCondition->match('[language = *en*,*de*]'));
108 $this->assertTrue($this->matchCondition->match('[language = *en-us*,*de-de*]'));
109 }
110
111 /**
112 * Tests whether the language comparison matches.
113 *
114 * @test
115 */
116 public function languageConditionMatchesCompleteLanguagesExpression(): void
117 {
118 $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'de-de,de;q=0.8,en-us;q=0.5,en;q=0.3';
119 $this->assertTrue($this->matchCondition->match('[language = de-de,de;q=0.8,en-us;q=0.5,en;q=0.3]'));
120 }
121
122 /**
123 * Tests whether usergroup comparison matches.
124 *
125 * @test
126 */
127 public function usergroupConditionMatchesSingleGroupId(): void
128 {
129 $GLOBALS['TSFE']->gr_list = '13,14,15';
130 $this->assertTrue($this->matchCondition->match('[usergroup = 13]'));
131 }
132
133 /**
134 * Tests whether usergroup comparison matches.
135 *
136 * @test
137 */
138 public function usergroupConditionMatchesMultipleUserGroupId(): void
139 {
140 $GLOBALS['TSFE']->gr_list = '13,14,15';
141 $this->assertTrue($this->matchCondition->match('[usergroup = 999,15,14,13]'));
142 }
143
144 /**
145 * Tests whether usergroup comparison matches.
146 *
147 * @test
148 */
149 public function usergroupConditionDoesNotMatchDefaulUserGroupIds(): void
150 {
151 $GLOBALS['TSFE']->gr_list = '0,-1';
152 $this->assertFalse($this->matchCondition->match('[usergroup = 0,-1]'));
153 }
154
155 /**
156 * Tests whether user comparison matches.
157 *
158 * @test
159 */
160 public function loginUserConditionMatchesAnyLoggedInUser(): void
161 {
162 $GLOBALS['TSFE']->loginUser = true;
163 $GLOBALS['TSFE']->fe_user->user['uid'] = 13;
164 $this->assertTrue($this->matchCondition->match('[loginUser = *]'));
165 }
166
167 /**
168 * Tests whether user comparison matches.
169 *
170 * @test
171 */
172 public function loginUserConditionMatchesSingleLoggedInUser(): void
173 {
174 $GLOBALS['TSFE']->loginUser = true;
175 $GLOBALS['TSFE']->fe_user->user['uid'] = 13;
176 $this->assertTrue($this->matchCondition->match('[loginUser = 13]'));
177 }
178
179 /**
180 * Tests whether user comparison matches.
181 *
182 * @test
183 */
184 public function loginUserConditionMatchesMultipleLoggedInUsers(): void
185 {
186 $GLOBALS['TSFE']->loginUser = true;
187 $GLOBALS['TSFE']->fe_user->user['uid'] = 13;
188 $this->assertTrue($this->matchCondition->match('[loginUser = 999,13]'));
189 }
190
191 /**
192 * Tests whether user comparison matches.
193 *
194 * @test
195 */
196 public function loginUserConditionDoesNotMatchIfNotUserIsLoggedId(): void
197 {
198 $GLOBALS['TSFE']->loginUser = false;
199 $GLOBALS['TSFE']->fe_user->user['uid'] = 13;
200 $this->assertFalse($this->matchCondition->match('[loginUser = *]'));
201 $this->assertFalse($this->matchCondition->match('[loginUser = 13]'));
202 }
203
204 /**
205 * Tests whether user is not logged in
206 *
207 * @test
208 */
209 public function loginUserConditionMatchIfUserIsNotLoggedIn(): void
210 {
211 $GLOBALS['TSFE']->loginUser = false;
212 $this->assertTrue($this->matchCondition->match('[loginUser = ]'));
213 }
214
215 /**
216 * Tests whether numerical comparison matches.
217 *
218 * @test
219 */
220 public function globalVarConditionMatchesOnEqualExpression(): void
221 {
222 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10 = 10]'));
223 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10.1 = 10.1]'));
224 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10 == 10]'));
225 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10.1 == 10.1]'));
226 }
227
228 /**
229 * Tests whether numerical comparison matches.
230 *
231 * @test
232 */
233 public function globalVarConditionMatchesOnEqualExpressionWithMultipleValues(): void
234 {
235 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10 = 10|20|30]'));
236 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10.1 = 10.1|20.2|30.3]'));
237 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:20 = 10|20|30]'));
238 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:20.2 = 10.1|20.2|30.3]'));
239 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10 == 10|20|30]'));
240 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10.1 == 10.1|20.2|30.3]'));
241 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:20 == 10|20|30]'));
242 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:20.2 == 10.1|20.2|30.3]'));
243 }
244
245 /**
246 * Tests whether numerical comparison matches.
247 *
248 * @test
249 */
250 public function globalVarConditionMatchesOnNotEqualExpression(): void
251 {
252 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10 != 20]'));
253 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10.1 != 10.2]'));
254 }
255
256 /**
257 * Tests whether numerical comparison does not match.
258 *
259 * @test
260 */
261 public function globalVarConditionDoesNotMatchOnNotEqualExpression(): void
262 {
263 $this->assertFalse($this->matchCondition->match('[globalVar = LIT:10 != 10]'));
264 }
265
266 /**
267 * Tests whether numerical comparison matches.
268 *
269 * @test
270 */
271 public function globalVarConditionMatchesOnNotEqualExpressionWithMultipleValues(): void
272 {
273 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10 != 20|30]'));
274 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10.1 != 10.2|20.3]'));
275 }
276
277 /**
278 * Tests whether numerical comparison matches.
279 *
280 * @test
281 */
282 public function globalVarConditionMatchesOnLowerThanExpression(): void
283 {
284 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10 < 20]'));
285 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10.1 < 10.2]'));
286 }
287
288 /**
289 * Tests whether numerical comparison matches.
290 *
291 * @test
292 */
293 public function globalVarConditionMatchesOnLowerThanOrEqualExpression(): void
294 {
295 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10 <= 10]'));
296 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10 <= 20]'));
297 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10.1 <= 10.1]'));
298 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10.1 <= 10.2]'));
299 }
300
301 /**
302 * Tests whether numerical comparison matches.
303 *
304 * @test
305 */
306 public function globalVarConditionMatchesOnGreaterThanExpression(): void
307 {
308 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:20 > 10]'));
309 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10.2 > 10.1]'));
310 }
311
312 /**
313 * Tests whether numerical comparison matches.
314 *
315 * @test
316 */
317 public function globalVarConditionMatchesOnGreaterThanOrEqualExpression(): void
318 {
319 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10 >= 10]'));
320 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:20 >= 10]'));
321 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10.1 >= 10.1]'));
322 $this->assertTrue($this->matchCondition->match('[globalVar = LIT:10.2 >= 10.1]'));
323 }
324
325 /**
326 * Tests whether numerical comparison matches.
327 *
328 * @test
329 */
330 public function globalVarConditionMatchesOnEmptyExpressionWithNoValueSet(): void
331 {
332 $testKey = $this->getUniqueId('test');
333 $this->assertTrue($this->matchCondition->match('[globalVar = GP:' . $testKey . '=]'));
334 $this->assertTrue($this->matchCondition->match('[globalVar = GP:' . $testKey . ' = ]'));
335 }
336
337 /**
338 * Tests whether numerical comparison matches.
339 *
340 * @test
341 */
342 public function globalVarConditionDoesNotMatchOnEmptyExpressionWithValueSetToZero(): void
343 {
344 $testKey = $this->getUniqueId('test');
345 $_GET = [];
346 $_POST = [$testKey => 0];
347 $this->assertFalse($this->matchCondition->match('[globalVar = GP:' . $testKey . '=]'));
348 $this->assertFalse($this->matchCondition->match('[globalVar = GP:' . $testKey . ' = ]'));
349 }
350
351 /**
352 * Tests whether an array with zero as key matches its value
353 *
354 * @test
355 */
356 public function globalVarConditionMatchesOnArrayExpressionWithZeroAsKey(): void
357 {
358 $testKey = $this->getUniqueId('test');
359 $testValue = '1';
360 $_GET = [];
361 $_POST = [$testKey => ['0' => $testValue]];
362 $this->assertTrue($this->matchCondition->match('[globalVar = GP:' . $testKey . '|0=' . $testValue . ']'));
363 }
364
365 /**
366 * Tests whether string comparison matches.
367 *
368 * @test
369 */
370 public function globalStringConditionMatchesOnEqualExpression(): void
371 {
372 $this->assertTrue($this->matchCondition->match('[globalString = LIT:TYPO3.Test.Condition = TYPO3.Test.Condition]'));
373 $this->assertFalse($this->matchCondition->match('[globalString = LIT:TYPO3.Test.Condition = TYPO3]'));
374 }
375
376 /**
377 * Tests whether string comparison matches.
378 *
379 * @test
380 */
381 public function globalStringConditionMatchesOnEmptyExpressionWithValueSetToEmptyString(): void
382 {
383 $testKey = $this->getUniqueId('test');
384 $_GET = [];
385 $_POST = [$testKey => ''];
386 $this->assertTrue($this->matchCondition->match('[globalString = GP:' . $testKey . '=]'));
387 $this->assertTrue($this->matchCondition->match('[globalString = GP:' . $testKey . ' = ]'));
388 }
389
390 /**
391 * Tests whether string comparison matches.
392 *
393 * @test
394 */
395 public function globalStringConditionMatchesOnEmptyLiteralExpressionWithValueSetToEmptyString(): void
396 {
397 $this->assertTrue($this->matchCondition->match('[globalString = LIT:=]'));
398 $this->assertTrue($this->matchCondition->match('[globalString = LIT: = ]'));
399 }
400
401 /**
402 * Tests whether string comparison matches.
403 *
404 * @test
405 */
406 public function globalStringConditionMatchesWildcardExpression(): void
407 {
408 $this->assertTrue($this->matchCondition->match('[globalString = LIT:TYPO3.Test.Condition = TYPO3?Test?Condition]'));
409 $this->assertTrue($this->matchCondition->match('[globalString = LIT:TYPO3.Test.Condition = TYPO3.T*t.Condition]'));
410 $this->assertTrue($this->matchCondition->match('[globalString = LIT:TYPO3.Test.Condition = TYPO3?T*t?Condition]'));
411 }
412
413 /**
414 * Tests whether string comparison matches.
415 *
416 * @test
417 */
418 public function globalStringConditionMatchesRegularExpression(): void
419 {
420 $this->assertTrue($this->matchCondition->match('[globalString = LIT:TYPO3.Test.Condition = /^[A-Za-z3.]+$/]'));
421 $this->assertTrue($this->matchCondition->match('[globalString = LIT:TYPO3.Test.Condition = /^TYPO3\\..+Condition$/]'));
422 $this->assertFalse($this->matchCondition->match('[globalString = LIT:TYPO3.Test.Condition = /^FALSE/]'));
423 }
424
425 /**
426 * Tests whether string comparison matches.
427 *
428 * @test
429 */
430 public function globalStringConditionMatchesEmptyRegularExpression(): void
431 {
432 $testKey = $this->getUniqueId('test');
433 $_SERVER[$testKey] = '';
434 $this->assertTrue($this->matchCondition->match('[globalString = _SERVER|' . $testKey . ' = /^$/]'));
435 }
436
437 /**
438 * Tests whether treeLevel comparison matches.
439 *
440 * @test
441 */
442 public function treeLevelConditionMatchesSingleValue(): void
443 {
444 $this->assertTrue($this->matchCondition->match('[treeLevel = 2]'));
445 }
446
447 /**
448 * Tests whether treeLevel comparison matches.
449 *
450 * @test
451 */
452 public function treeLevelConditionMatchesMultipleValues(): void
453 {
454 $this->assertTrue($this->matchCondition->match('[treeLevel = 999,998,2]'));
455 }
456
457 /**
458 * Tests whether treeLevel comparison matches.
459 *
460 * @test
461 */
462 public function treeLevelConditionDoesNotMatchFaultyValue(): void
463 {
464 $this->assertFalse($this->matchCondition->match('[treeLevel = 999]'));
465 }
466
467 /**
468 * Tests whether a page Id is found in the previous rootline entries.
469 *
470 * @test
471 */
472 public function PIDupinRootlineConditionMatchesSinglePageIdInRootline(): void
473 {
474 $GLOBALS['TSFE']->id = 121;
475 $this->assertTrue($this->matchCondition->match('[PIDupinRootline = 111]'));
476 }
477
478 /**
479 * Tests whether a page Id is found in the previous rootline entries.
480 *
481 * @test
482 */
483 public function PIDupinRootlineConditionMatchesMultiplePageIdsInRootline(): void
484 {
485 $GLOBALS['TSFE']->id = 121;
486 $this->assertTrue($this->matchCondition->match('[PIDupinRootline = 999,111,101]'));
487 }
488
489 /**
490 * Tests whether a page Id is found in the previous rootline entries.
491 *
492 * @test
493 */
494 public function PIDupinRootlineConditionDoesNotMatchPageIdNotInRootline(): void
495 {
496 $GLOBALS['TSFE']->id = 121;
497 $this->assertFalse($this->matchCondition->match('[PIDupinRootline = 999]'));
498 }
499
500 /**
501 * Tests whether a page Id is found in the previous rootline entries.
502 *
503 * @test
504 */
505 public function PIDupinRootlineConditionDoesNotMatchLastPageIdInRootline(): void
506 {
507 $GLOBALS['TSFE']->id = 121;
508 $this->assertFalse($this->matchCondition->match('[PIDupinRootline = 121]'));
509 }
510
511 /**
512 * Tests whether a page Id is found in all rootline entries.
513 *
514 * @test
515 */
516 public function PIDinRootlineConditionMatchesSinglePageIdInRootline(): void
517 {
518 $GLOBALS['TSFE']->id = 121;
519 $this->assertTrue($this->matchCondition->match('[PIDinRootline = 111]'));
520 }
521
522 /**
523 * Tests whether a page Id is found in all rootline entries.
524 *
525 * @test
526 */
527 public function PIDinRootlineConditionMatchesMultiplePageIdsInRootline(): void
528 {
529 $GLOBALS['TSFE']->id = 121;
530 $this->assertTrue($this->matchCondition->match('[PIDinRootline = 999,111,101]'));
531 }
532
533 /**
534 * Tests whether a page Id is found in all rootline entries.
535 *
536 * @test
537 */
538 public function PIDinRootlineConditionMatchesLastPageIdInRootline(): void
539 {
540 $GLOBALS['TSFE']->id = 121;
541 $this->assertTrue($this->matchCondition->match('[PIDinRootline = 121]'));
542 }
543
544 /**
545 * Tests whether a page Id is found in all rootline entries.
546 *
547 * @test
548 */
549 public function PIDinRootlineConditionDoesNotMatchPageIdNotInRootline(): void
550 {
551 $GLOBALS['TSFE']->id = 121;
552 $this->assertFalse($this->matchCondition->match('[PIDinRootline = 999]'));
553 }
554
555 /**
556 * Tests whether the compatibility version can be evaluated.
557 * (e.g. 7.9 is compatible to 7.0 but not to 15.0)
558 *
559 * @test
560 */
561 public function compatVersionConditionMatchesOlderRelease(): void
562 {
563 $this->assertTrue($this->matchCondition->match('[compatVersion = 7.0]'));
564 }
565
566 /**
567 * Tests whether the compatibility version can be evaluated.
568 * (e.g. 7.9 is compatible to 7.0 but not to 15.0)
569 *
570 * @test
571 */
572 public function compatVersionConditionMatchesSameRelease(): void
573 {
574 $this->assertTrue($this->matchCondition->match('[compatVersion = ' . TYPO3_branch . ']'));
575 }
576
577 /**
578 * Tests whether the compatibility version can be evaluated.
579 * (e.g. 7.9 is compatible to 7.0 but not to 15.0)
580 *
581 * @test
582 */
583 public function compatVersionConditionDoesNotMatchNewerRelease(): void
584 {
585 $this->assertFalse($this->matchCondition->match('[compatVersion = 15.0]'));
586 }
587
588 /**
589 * Tests whether the generic fetching of variables works with the namespace 'GP'.
590 *
591 * @test
592 */
593 public function genericGetVariablesSucceedsWithNamespaceGP(): void
594 {
595 $_GET = ['testGet' => 'getTest'];
596 $_POST = ['testPost' => 'postTest'];
597 $this->assertTrue($this->matchCondition->match('[globalString = GP:testGet = getTest]'));
598 $this->assertTrue($this->matchCondition->match('[globalString = GP:testPost = postTest]'));
599 }
600
601 /**
602 * Tests whether the generic fetching of variables works with the namespace 'TSFE'.
603 *
604 * @test
605 */
606 public function genericGetVariablesSucceedsWithNamespaceTSFE(): void
607 {
608 $GLOBALS['TSFE']->id = 1234567;
609 $GLOBALS['TSFE']->testSimpleObject = new \stdClass();
610 $GLOBALS['TSFE']->testSimpleObject->testSimpleVariable = 'testValue';
611
612 $this->assertTrue($this->matchCondition->match('[globalString = TSFE:id = 1234567]'));
613 $this->assertTrue($this->matchCondition->match('[globalString = TSFE:testSimpleObject|testSimpleVariable = testValue]'));
614 }
615
616 /**
617 * Tests whether the generic fetching of variables works with the namespace 'session'.
618 *
619 * @test
620 */
621 public function genericGetVariablesSucceedsWithNamespaceSession(): void
622 {
623 $prophecy = $this->prophesize(FrontendUserAuthentication::class);
624 $prophecy->getSessionData(Argument::exact('foo'))->willReturn(['bar' => 1234567]);
625 $GLOBALS['TSFE']->fe_user = $prophecy->reveal();
626
627 $this->assertTrue($this->matchCondition->match('[globalString = session:foo|bar = 1234567]'));
628 }
629
630 /**
631 * Tests whether the generic fetching of variables works with the namespace 'ENV'.
632 *
633 * @test
634 */
635 public function genericGetVariablesSucceedsWithNamespaceENV(): void
636 {
637 $testKey = $this->getUniqueId('test');
638 putenv($testKey . '=testValue');
639 $this->assertTrue($this->matchCondition->match('[globalString = ENV:' . $testKey . ' = testValue]'));
640 }
641
642 /**
643 * Tests whether the generic fetching of variables works with the namespace 'IENV'.
644 *
645 * @test
646 */
647 public function genericGetVariablesSucceedsWithNamespaceIENV(): void
648 {
649 $_SERVER['HTTP_HOST'] = GeneralUtility::getIndpEnv('TYPO3_HOST_ONLY') . ':1234567';
650 $this->assertTrue($this->matchCondition->match('[globalString = IENV:TYPO3_PORT = 1234567]'));
651 }
652
653 /**
654 * Tests whether the generic fetching of variables works with any global namespace.
655 *
656 * @test
657 */
658 public function genericGetVariablesSucceedsWithAnyGlobalNamespace(): void
659 {
660 $GLOBALS[$this->testGlobalNamespace] = [
661 'first' => 'testFirst',
662 'second' => ['third' => 'testThird']
663 ];
664 $this->assertTrue($this->matchCondition->match('[globalString = ' . $this->testGlobalNamespace . '|first = testFirst]'));
665 $this->assertTrue($this->matchCondition->match('[globalString = ' . $this->testGlobalNamespace . '|second|third = testThird]'));
666 }
667
668 /**
669 * Tests whether any property of a site language matches the request
670 *
671 * @test
672 */
673 public function siteLanguageMatchesCondition(): void
674 {
675 $site = new Site('angelo', 13, [
676 'languages' => [
677 [
678 'languageId' => 0,
679 'title' => 'United States',
680 'locale' => 'en_US.UTF-8',
681 ],
682 [
683 'languageId' => 2,
684 'title' => 'UK',
685 'locale' => 'en_UK.UTF-8',
686 ]
687 ]
688 ]);
689 $GLOBALS['TYPO3_REQUEST'] = new ServerRequest();
690 $GLOBALS['TYPO3_REQUEST'] = $GLOBALS['TYPO3_REQUEST']->withAttribute('language', $site->getLanguageById(0));
691 $this->assertTrue($this->matchCondition->match('[siteLanguage = locale = en_US.UTF-8]'));
692 $this->assertTrue($this->matchCondition->match('[siteLanguage = locale = de_DE, locale = en_US.UTF-8]'));
693 }
694
695 /**
696 * Tests whether any property of a site language does NOT match the request
697 *
698 * @test
699 */
700 public function siteLanguageDoesNotMatchCondition(): void
701 {
702 $site = new Site('angelo', 13, [
703 'languages' => [
704 [
705 'languageId' => 0,
706 'title' => 'United States',
707 'locale' => 'en_US.UTF-8',
708 ],
709 [
710 'languageId' => 2,
711 'title' => 'UK',
712 'locale' => 'en_UK.UTF-8',
713 ]
714 ]
715 ]);
716 $GLOBALS['TYPO3_REQUEST'] = new ServerRequest();
717 $GLOBALS['TYPO3_REQUEST'] = $GLOBALS['TYPO3_REQUEST']->withAttribute('language', $site->getLanguageById(0));
718 $this->assertFalse($this->matchCondition->match('[siteLanguage = locale = en_UK.UTF-8]'));
719 $this->assertFalse($this->matchCondition->match('[siteLanguage = locale = de_DE, title = UK]'));
720 }
721
722 /**
723 * Tests whether any property of a site matches the request
724 *
725 * @test
726 */
727 public function siteMatchesCondition(): void
728 {
729 $site = new Site('angelo', 13, ['languages' => [], 'base' => 'https://typo3.org/']);
730 $GLOBALS['TYPO3_REQUEST'] = new ServerRequest();
731 $GLOBALS['TYPO3_REQUEST'] = $GLOBALS['TYPO3_REQUEST']->withAttribute('language', $site->getLanguageById(0));
732 $this->assertTrue($this->matchCondition->match('[site = identifier = angelo]'));
733 $this->assertTrue($this->matchCondition->match('[site = rootPageId = 13]'));
734 $this->assertTrue($this->matchCondition->match('[site = base = https://typo3.org/]'));
735 }
736
737 /**
738 * Tests whether any property of a site that does NOT match the request
739 *
740 * @test
741 */
742 public function siteDoesNotMatchCondition(): void
743 {
744 $site = new Site('angelo', 13, [
745 'languages' => [
746 [
747 'languageId' => 0,
748 'title' => 'United States',
749 'locale' => 'en_US.UTF-8',
750 ],
751 [
752 'languageId' => 2,
753 'title' => 'UK',
754 'locale' => 'en_UK.UTF-8',
755 ]
756 ]
757 ]);
758 $GLOBALS['TYPO3_REQUEST'] = new ServerRequest();
759 $GLOBALS['TYPO3_REQUEST'] = $GLOBALS['TYPO3_REQUEST']->withAttribute('language', $site->getLanguageById(0));
760 $this->assertFalse($this->matchCondition->match('[site = identifier = berta]'));
761 $this->assertFalse($this->matchCondition->match('[site = rootPageId = 14, rootPageId=23]'));
762 }
763
764 /**
765 * @test
766 */
767 public function matchThrowsExceptionIfConditionClassDoesNotInheritFromAbstractCondition(): void
768 {
769 $this->expectException(InvalidTypoScriptConditionException::class);
770 $this->expectExceptionCode(1410286153);
771 $this->matchCondition->match('[stdClass = foo]');
772 }
773
774 /**
775 * @test
776 */
777 public function matchCallsTestConditionAndHandsOverParameters(): void
778 {
779 $this->expectException(TestConditionException::class);
780 $this->expectExceptionCode(1411581139);
781 $this->matchCondition->match('[TYPO3\\CMS\\Frontend\\Tests\\Unit\\Configuration\\TypoScript\\ConditionMatching\\Fixtures\\TestCondition = 7, != 6]');
782 }
783 }