2 /***************************************************************
5 * (c) 2009 Oliver Hader <oliver@typo3.org>
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
27 * Testcase for class t3lib_matchCondition_frontend.
29 * @author Oliver Hader <oliver@typo3.org>
33 class t3lib_matchCondition_frontend_testcase
extends tx_phpunit_testcase
{
37 private $backupGlobalVariables;
45 * @var t3lib_matchCondition
47 private $matchCondition;
49 public function setUp() {
50 $this->backupGlobalVariables
= array(
54 '_SERVER' => $_SERVER,
55 'TYPO3_CONF_VARS' => $GLOBALS['TYPO3_CONF_VARS'],
56 'T3_VAR' => $GLOBALS['T3_VAR'],
59 $this->testGlobalNamespace
= uniqid('TEST');
60 $GLOBALS[$this->testGlobalNamespace
] = array();
63 $this->matchCondition
= t3lib_div
::makeInstance('t3lib_matchCondition_frontend');
66 public function tearDown() {
67 foreach ($this->backupGlobalVariables
as $key => $data) {
68 $GLOBALS[$key] = $data;
71 unset($this->matchCondition
);
72 unset($this->backupGlobalVariables
);
73 unset($GLOBALS[$this->testGlobalNamespace
]);
76 private function setUpTSFE() {
77 $this->rootline
= array(
78 2 => array('uid' => 121, 'pid' => 111),
79 1 => array('uid' => 111, 'pid' => 101,),
80 0 => array('uid' => 101, 'pid' => 0,),
83 $GLOBALS['TSFE'] = $this->getMock('tslib_fe', array(), array(), '', FALSE);
84 $GLOBALS['TSFE']->tmpl
= $this->getMock('t3lib_TStemplate');
88 * Tests whether a faulty expression fails.
91 public function simulateDisabledMatchAllConditionsFailsOnFaultyExpression() {
92 $this->matchCondition
->matchAll
= false;
93 $this->assertFalse($this->matchCondition
->match('[nullCondition = This expression would return false in general]'));
97 * Tests whether simulating positive matches for all conditions succeeds.
100 public function simulateEnabledMatchAllConditionsSucceeds() {
101 $this->matchCondition
->setSimulateMatchResult(true);
102 $this->assertTrue($this->matchCondition
->match('[nullCondition = This expression would return false in general]'));
106 * Tests whether simulating positive matches for specific conditions succeeds.
109 public function simulateEnabledMatchSpecificConditionsSucceeds() {
110 $testCondition = '[' . uniqid('test') . ' = Any condition to simulate a positive match]';
111 $this->matchCondition
->setSimulateMatchConditions(array($testCondition));
112 $this->assertTrue($this->matchCondition
->match($testCondition));
116 * Tests whether a condition matches Internet Explorer 7 on Windows.
121 public function conditionMatchesInternetExplorer7Windows() {
122 $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)';
123 $result = $this->matchCondition
->match('[browser = msie] && [version = 7] && [system = winNT]');
124 $this->assertTrue($result);
128 * Tests whether a condition does not match Internet Explorer 7 on Windows.
133 public function conditionDoesNotMatchInternetExplorer7Windows() {
134 $_SERVER['HTTP_USER_AGENT'] = 'Opera/9.25 (Windows NT 6.0; U; en)';
135 $result = $this->matchCondition
->match('[browser = msie] && [version = 7] && [system = winNT]');
136 $this->assertFalse($result);
140 * Tests whether a device type condition matches a crawler.
143 public function deviceConditionMatchesRobot() {
144 $_SERVER['HTTP_USER_AGENT'] = 'Googlebot/2.1 (+http://www.google.com/bot.html)';
145 $result = $this->matchCondition
->match('[device = robot]');
146 $this->assertTrue($result);
150 * Tests whether a device type condition does not match a crawler.
153 public function deviceConditionDoesNotMatchRobot() {
154 $_SERVER['HTTP_USER_AGENT'] = md5('Some strange user agent');
155 $result = $this->matchCondition
->match('[device = robot]');
156 $this->assertFalse($result);
160 * Tests whether the browserInfo hook is called.
165 public function deprecatedBrowserInfoHookIsCalled() {
166 $GLOBALS['TYPO3_CONF_VARS']['SYS']['enableDeprecationLog'] = FALSE;
168 $classRef = uniqid('tx_browserInfoHook');
169 $browserInfoHookMock = $this->getMock($classRef, array('browserInfo'));
170 $browserInfoHookMock->expects($this->atLeastOnce())->method('browserInfo');
172 $GLOBALS['T3_VAR']['getUserObj'][$classRef] = $browserInfoHookMock;
173 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_matchcondition.php']['matchConditionClass'][$classRef] = $classRef;
175 $this->matchCondition
->__construct();
176 $this->matchCondition
->match('[browser = msie] && [version = 7] && [system = winNT]');
180 * Tests whether the whichDevice hook is called.
185 public function deprecatedWhichDeviceHookIsCalled() {
186 $GLOBALS['TYPO3_CONF_VARS']['SYS']['enableDeprecationLog'] = FALSE;
188 $classRef = uniqid('tx_whichDeviceHook');
189 $whichDeviceHookMock = $this->getMock($classRef, array('whichDevice'));
190 $whichDeviceHookMock->expects($this->atLeastOnce())->method('whichDevice');
192 $GLOBALS['T3_VAR']['getUserObj'][$classRef] = $whichDeviceHookMock;
193 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_matchcondition.php']['matchConditionClass'][$classRef] = $classRef;
195 $this->matchCondition
->__construct();
196 $this->matchCondition
->match('[device = robot]');
200 * Tests whether the language comparison matches.
203 public function languageConditionMatchesSingleLanguageExpression() {
204 $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'de-de,de;q=0.8,en-us;q=0.5,en;q=0.3';
205 $this->assertTrue($this->matchCondition
->match('[language = *de*]'));
206 $this->assertTrue($this->matchCondition
->match('[language = *de-de*]'));
210 * Tests whether the language comparison matches.
213 public function languageConditionMatchesMultipleLanguagesExpression() {
214 $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'de-de,de;q=0.8,en-us;q=0.5,en;q=0.3';
215 $this->assertTrue($this->matchCondition
->match('[language = *en*,*de*]'));
216 $this->assertTrue($this->matchCondition
->match('[language = *en-us*,*de-de*]'));
220 * Tests whether the language comparison matches.
223 public function languageConditionMatchesCompleteLanguagesExpression() {
224 $this->markTestSkipped('This comparison seems to be incomplete in t3lib_matchCondition.');
226 $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'de-de,de;q=0.8,en-us;q=0.5,en;q=0.3';
227 $this->assertTrue($this->matchCondition
->match('[language = de-de,de;q=0.8]'));
231 * Tests whether usergroup comparison matches.
234 public function usergroupConditionMatchesSingleGroupId() {
235 $GLOBALS['TSFE']->gr_list
= '13,14,15';
236 $this->assertTrue($this->matchCondition
->match('[usergroup = 13]'));
240 * Tests whether usergroup comparison matches.
243 public function usergroupConditionMatchesMultipleUserGroupId() {
244 $GLOBALS['TSFE']->gr_list
= '13,14,15';
245 $this->assertTrue($this->matchCondition
->match('[usergroup = 999,15,14,13]'));
249 * Tests whether usergroup comparison matches.
252 public function usergroupConditionDoesNotMatchDefaulUserGroupIds() {
253 $GLOBALS['TSFE']->gr_list
= '0,-1';
254 $this->assertFalse($this->matchCondition
->match('[usergroup = 0,-1]'));
258 * Tests whether user comparison matches.
261 public function loginUserConditionMatchesAnyLoggedInUser() {
262 $GLOBALS['TSFE']->loginUser
= TRUE;
263 $GLOBALS['TSFE']->fe_user
->user
['uid'] = 13;
264 $this->assertTrue($this->matchCondition
->match('[loginUser = *]'));
268 * Tests whether user comparison matches.
271 public function loginUserConditionMatchesSingleLoggedInUser() {
272 $GLOBALS['TSFE']->loginUser
= TRUE;
273 $GLOBALS['TSFE']->fe_user
->user
['uid'] = 13;
274 $this->assertTrue($this->matchCondition
->match('[loginUser = 13]'));
278 * Tests whether user comparison matches.
281 public function loginUserConditionMatchesMultipleLoggedInUsers() {
282 $GLOBALS['TSFE']->loginUser
= TRUE;
283 $GLOBALS['TSFE']->fe_user
->user
['uid'] = 13;
284 $this->assertTrue($this->matchCondition
->match('[loginUser = 999,13]'));
288 * Tests whether user comparison matches.
291 public function loginUserConditionDoesNotMatchIfNotUserIsLoggedId() {
292 $GLOBALS['TSFE']->loginUser
= FALSE;
293 $GLOBALS['TSFE']->fe_user
->user
['uid'] = 13;
294 $this->assertFalse($this->matchCondition
->match('[loginUser = *]'));
295 $this->assertFalse($this->matchCondition
->match('[loginUser = 13]'));
299 * Tests whether numerical comparison matches.
302 public function globalVarConditionMatchesOnEqualExpression() {
303 $this->assertTrue($this->matchCondition
->match('[globalVar = LIT:10 = 10]'));
304 $this->assertTrue($this->matchCondition
->match('[globalVar = LIT:10.1 = 10.1]'));
306 $this->assertTrue($this->matchCondition
->match('[globalVar = LIT:10 == 10]'));
307 $this->assertTrue($this->matchCondition
->match('[globalVar = LIT:10.1 == 10.1]'));
311 * Tests whether numerical comparison matches.
314 public function globalVarConditionMatchesOnNotEqualExpression() {
315 $this->assertTrue($this->matchCondition
->match('[globalVar = LIT:10 != 20]'));
316 $this->assertTrue($this->matchCondition
->match('[globalVar = LIT:10.1 != 10.2]'));
320 * Tests whether numerical comparison matches.
323 public function globalVarConditionMatchesOnLowerThanExpression() {
324 $this->assertTrue($this->matchCondition
->match('[globalVar = LIT:10 < 20]'));
325 $this->assertTrue($this->matchCondition
->match('[globalVar = LIT:10.1 < 10.2]'));
329 * Tests whether numerical comparison matches.
332 public function globalVarConditionMatchesOnLowerThanOrEqualExpression() {
333 $this->assertTrue($this->matchCondition
->match('[globalVar = LIT:10 <= 10]'));
334 $this->assertTrue($this->matchCondition
->match('[globalVar = LIT:10 <= 20]'));
336 $this->assertTrue($this->matchCondition
->match('[globalVar = LIT:10.1 <= 10.1]'));
337 $this->assertTrue($this->matchCondition
->match('[globalVar = LIT:10.1 <= 10.2]'));
341 * Tests whether numerical comparison matches.
344 public function globalVarConditionMatchesOnGreaterThanExpression() {
345 $this->assertTrue($this->matchCondition
->match('[globalVar = LIT:20 > 10]'));
346 $this->assertTrue($this->matchCondition
->match('[globalVar = LIT:10.2 > 10.1]'));
350 * Tests whether numerical comparison matches.
353 public function globalVarConditionMatchesOnGreaterThanOrEqualExpression() {
354 $this->assertTrue($this->matchCondition
->match('[globalVar = LIT:10 >= 10]'));
355 $this->assertTrue($this->matchCondition
->match('[globalVar = LIT:20 >= 10]'));
357 $this->assertTrue($this->matchCondition
->match('[globalVar = LIT:10.1 >= 10.1]'));
358 $this->assertTrue($this->matchCondition
->match('[globalVar = LIT:10.2 >= 10.1]'));
362 * Tests whether numerical comparison matches.
365 public function globalVarConditionMatchesOnEmptyExpressionWithNoValueSet() {
366 $testKey = uniqid('test');
367 $this->assertTrue($this->matchCondition
->match('[globalVar = GP:' . $testKey . '=]'));
368 $this->assertTrue($this->matchCondition
->match('[globalVar = GP:' . $testKey . ' = ]'));
372 * Tests whether numerical comparison matches.
375 public function globalVarConditionDoesNotMatchOnEmptyExpressionWithValueSetToZero() {
376 $testKey = uniqid('test');
379 $_POST = array($testKey => 0);
381 $this->assertFalse($this->matchCondition
->match('[globalVar = GP:' . $testKey . '=]'));
382 $this->assertFalse($this->matchCondition
->match('[globalVar = GP:' . $testKey . ' = ]'));
386 * Tests whether string comparison matches.
389 public function globalStringConditionMatchesOnEqualExpression() {
390 $this->assertTrue($this->matchCondition
->match('[globalString = LIT:TYPO3.Test.Condition = TYPO3.Test.Condition]'));
391 $this->assertFalse($this->matchCondition
->match('[globalString = LIT:TYPO3.Test.Condition = TYPO3]'));
395 * Tests whether string comparison matches.
398 public function globalStringConditionMatchesWildcardExpression() {
399 $this->assertTrue($this->matchCondition
->match('[globalString = LIT:TYPO3.Test.Condition = TYPO3?Test?Condition]'));
400 $this->assertTrue($this->matchCondition
->match('[globalString = LIT:TYPO3.Test.Condition = TYPO3.T*t.Condition]'));
401 $this->assertTrue($this->matchCondition
->match('[globalString = LIT:TYPO3.Test.Condition = TYPO3?T*t?Condition]'));
405 * Tests whether string comparison matches.
408 public function globalStringConditionMatchesRegularExpression() {
409 $this->assertTrue($this->matchCondition
->match('[globalString = LIT:TYPO3.Test.Condition = /^[A-Za-z3.]+$/]'));
410 $this->assertTrue($this->matchCondition
->match('[globalString = LIT:TYPO3.Test.Condition = /^TYPO3\..+Condition$/]'));
411 $this->assertFalse($this->matchCondition
->match('[globalString = LIT:TYPO3.Test.Condition = /^FALSE/]'));
415 * Tests whether string comparison matches.
418 public function globalStringConditionMatchesEmptyRegularExpression() {
419 $testKey = uniqid('test');
420 $_SERVER[$testKey] = '';
421 $this->assertTrue($this->matchCondition
->match('[globalString = _SERVER|' . $testKey . ' = /^$/]'));
425 * Tests whether treeLevel comparison matches.
428 public function treeLevelConditionMatchesSingleValue() {
429 $GLOBALS['TSFE']->tmpl
->rootLine
= $this->rootline
;
430 $this->assertTrue($this->matchCondition
->match('[treeLevel = 2]'));
434 * Tests whether treeLevel comparison matches.
437 public function treeLevelConditionMatchesMultipleValues() {
438 $GLOBALS['TSFE']->tmpl
->rootLine
= $this->rootline
;
439 $this->assertTrue($this->matchCondition
->match('[treeLevel = 999,998,2]'));
443 * Tests whether treeLevel comparison matches.
446 public function treeLevelConditionDoesNotMatchFaultyValue() {
447 $GLOBALS['TSFE']->tmpl
->rootLine
= $this->rootline
;
448 $this->assertFalse($this->matchCondition
->match('[treeLevel = 999]'));
452 * Tests whether a page Id is found in the previous rootline entries.
455 public function PIDupinRootlineConditionMatchesSinglePageIdInRootline() {
456 $GLOBALS['TSFE']->tmpl
->rootLine
= $this->rootline
;
457 $GLOBALS['TSFE']->id
= 121;
458 $this->assertTrue($this->matchCondition
->match('[PIDupinRootline = 111]'));
462 * Tests whether a page Id is found in the previous rootline entries.
465 public function PIDupinRootlineConditionMatchesMultiplePageIdsInRootline() {
466 $GLOBALS['TSFE']->tmpl
->rootLine
= $this->rootline
;
467 $GLOBALS['TSFE']->id
= 121;
468 $this->assertTrue($this->matchCondition
->match('[PIDupinRootline = 999,111,101]'));
472 * Tests whether a page Id is found in the previous rootline entries.
475 public function PIDupinRootlineConditionDoesNotMatchPageIdNotInRootline() {
476 $GLOBALS['TSFE']->tmpl
->rootLine
= $this->rootline
;
477 $GLOBALS['TSFE']->id
= 121;
478 $this->assertFalse($this->matchCondition
->match('[PIDupinRootline = 999]'));
482 * Tests whether a page Id is found in the previous rootline entries.
485 public function PIDupinRootlineConditionDoesNotMatchLastPageIdInRootline() {
486 $GLOBALS['TSFE']->tmpl
->rootLine
= $this->rootline
;
487 $GLOBALS['TSFE']->id
= 121;
488 $this->assertFalse($this->matchCondition
->match('[PIDupinRootline = 121]'));
492 * Tests whether a page Id is found in all rootline entries.
495 public function PIDinRootlineConditionMatchesSinglePageIdInRootline() {
496 $GLOBALS['TSFE']->tmpl
->rootLine
= $this->rootline
;
497 $GLOBALS['TSFE']->id
= 121;
498 $this->assertTrue($this->matchCondition
->match('[PIDinRootline = 111]'));
502 * Tests whether a page Id is found in all rootline entries.
505 public function PIDinRootlineConditionMatchesMultiplePageIdsInRootline() {
506 $GLOBALS['TSFE']->tmpl
->rootLine
= $this->rootline
;
507 $GLOBALS['TSFE']->id
= 121;
508 $this->assertTrue($this->matchCondition
->match('[PIDinRootline = 999,111,101]'));
512 * Tests whether a page Id is found in all rootline entries.
515 public function PIDinRootlineConditionMatchesLastPageIdInRootline() {
516 $GLOBALS['TSFE']->tmpl
->rootLine
= $this->rootline
;
517 $GLOBALS['TSFE']->id
= 121;
518 $this->assertTrue($this->matchCondition
->match('[PIDinRootline = 121]'));
522 * Tests whether a page Id is found in all rootline entries.
525 public function PIDinRootlineConditionDoesNotMatchPageIdNotInRootline() {
526 $GLOBALS['TSFE']->tmpl
->rootLine
= $this->rootline
;
527 $GLOBALS['TSFE']->id
= 121;
528 $this->assertFalse($this->matchCondition
->match('[PIDinRootline = 999]'));
532 * Tests whether the compatibility version can be evaluated.
533 * (e.g. 4.9 is compatible to 4.0 but not to 5.0)
536 public function compatVersionConditionMatchesOlderRelease() {
537 $GLOBALS['TYPO3_CONF_VARS']['SYS']['compat_version'] = '4.9';
538 $this->assertTrue($this->matchCondition
->match('[compatVersion = 4.0]'));
542 * Tests whether the compatibility version can be evaluated.
543 * (e.g. 4.9 is compatible to 4.0 but not to 5.0)
546 public function compatVersionConditionMatchesSameRelease() {
547 $GLOBALS['TYPO3_CONF_VARS']['SYS']['compat_version'] = '4.9';
548 $this->assertTrue($this->matchCondition
->match('[compatVersion = 4.9]'));
552 * Tests whether the compatibility version can be evaluated.
553 * (e.g. 4.9 is compatible to 4.0 but not to 5.0)
556 public function compatVersionConditionDoesNotMatchNewerRelease() {
557 $GLOBALS['TYPO3_CONF_VARS']['SYS']['compat_version'] = '4.9';
558 $this->assertFalse($this->matchCondition
->match('[compatVersion = 5.0]'));
562 * Tests whether the generic fetching of variables works with the namespace 'GP'.
565 public function genericGetVariablesSucceedsWithNamespaceGP() {
566 $_GET = array('testGet' => 'getTest');
567 $_POST = array('testPost' => 'postTest');
569 $this->assertTrue($this->matchCondition
->match('[globalString = GP:testGet = getTest]'));
570 $this->assertTrue($this->matchCondition
->match('[globalString = GP:testPost = postTest]'));
574 * Tests whether the generic fetching of variables works with the namespace 'TSFE'.
577 public function genericGetVariablesSucceedsWithNamespaceTSFE() {
578 $GLOBALS['TSFE']->id
= 1234567;
579 $GLOBALS['TSFE']->testSimpleObject
= new stdClass();
580 $GLOBALS['TSFE']->testSimpleObject
->testSimpleVariable
= 'testValue';
582 $this->assertTrue($this->matchCondition
->match('[globalString = TSFE:id = 1234567]'));
583 $this->assertTrue($this->matchCondition
->match('[globalString = TSFE:testSimpleObject|testSimpleVariable = testValue]'));
587 * Tests whether the generic fetching of variables works with the namespace 'ENV'.
590 public function genericGetVariablesSucceedsWithNamespaceENV() {
591 $testKey = uniqid('test');
592 putenv($testKey .'=testValue');
594 $this->assertTrue($this->matchCondition
->match('[globalString = ENV:' . $testKey . ' = testValue]'));
598 * Tests whether the generic fetching of variables works with the namespace 'IENV'.
601 public function genericGetVariablesSucceedsWithNamespaceIENV() {
602 $_SERVER['HTTP_HOST'] = t3lib_div
::getIndpEnv('TYPO3_HOST_ONLY') . ':1234567';
603 $this->assertTrue($this->matchCondition
->match('[globalString = IENV:TYPO3_PORT = 1234567]'));
607 * Tests whether the generic fetching of variables works with any global namespace.
610 public function genericGetVariablesSucceedsWithAnyGlobalNamespace() {
611 $GLOBALS[$this->testGlobalNamespace
] = array(
612 'first' => 'testFirst',
613 'second' => array('third' => 'testThird'),
616 $this->assertTrue($this->matchCondition
->match(
617 '[globalString = ' . $this->testGlobalNamespace
. '|first = testFirst]'
619 $this->assertTrue($this->matchCondition
->match(
620 '[globalString = ' . $this->testGlobalNamespace
. '|second|third = testThird]'