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