‪TYPO3CMS  ‪main
AbstractConditionMatcherTest.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
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 
19 
20 use Psr\Log\NullLogger;
39 use TYPO3\CMS\Core\Package\PackageManager;
41 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
42 
43 class ‪AbstractConditionMatcherTest extends UnitTestCase
44 {
45  protected bool ‪$backupEnvironment = true;
46  protected bool ‪$resetSingletonInstances = true;
48  protected ?\ReflectionMethod ‪$evaluateExpressionMethod;
49 
50  protected function ‪setUp(): void
51  {
52  parent::setUp();
53 
54  $cacheManager = new ‪CacheManager();
55  $cacheManager->registerCache(new ‪NullFrontend('core'));
56  $cacheManager->registerCache(new ‪NullFrontend('runtime'));
57  GeneralUtility::setSingletonInstance(CacheManager::class, $cacheManager);
58 
59  $packageManagerMock = $this->createMock(PackageManager::class);
60  $corePackageMock = $this->createMock(PackageInterface::class);
61  $corePackageMock->method('getPackagePath')->willReturn(__DIR__ . '/../../../../../../../sysext/core/');
62  $packageManagerMock->method('getActivePackages')->willReturn([
63  $corePackageMock,
64  ]);
65  GeneralUtility::setSingletonInstance(PackageManager::class, $packageManagerMock);
66 
67  $this->‪initConditionMatcher();
68  }
69 
70  protected function ‪initConditionMatcher(): void
71  {
72  GeneralUtility::addInstance(ProviderConfigurationLoader::class, new ‪ProviderConfigurationLoader(
73  GeneralUtility::makeInstance(PackageManager::class),
74  new ‪NullFrontend('testing'),
75  'ExpressionLanguageProviders'
76  ));
77  // test the abstract methods via the backend condition matcher
78  $this->evaluateExpressionMethod = new \ReflectionMethod(AbstractConditionMatcher::class, 'evaluateExpression');
79  $this->evaluateExpressionMethod->setAccessible(true);
80  $defaultProvider = new ‪DefaultProvider(new ‪Typo3Version(), new ‪Context(), new ‪Features());
81  GeneralUtility::addInstance(DefaultProvider::class, $defaultProvider);
82  $this->conditionMatcher = new ‪ConditionMatcher();
83  $this->conditionMatcher->setLogger(new NullLogger());
84  }
85 
86  public function ‪requestFunctionDataProvider(): array
87  {
88  return [
89  // GET tests
90  // getQueryParams()
91  'request.getQueryParams()[\'foo\'] > 0' => ['request.getQueryParams()[\'foo\'] > 0', true],
92  'request.getQueryParams()[\'foo\'][\'bar\'] > 0' => ['request.getQueryParams()[\'foo\'][\'bar\'] > 0', false],
93  'request.getQueryParams()[\'bar\'][\'foo\'] > 0' => ['request.getQueryParams()[\'bar\'][\'foo\'] > 0', false],
94  'request.getQueryParams()[\'foo\'] == 0' => ['request.getQueryParams()[\'foo\'] == 0', false],
95  'request.getQueryParams()[\'foo\'][\'bar\'] == 0' => ['request.getQueryParams()[\'foo\'][\'bar\'] == 0', false],
96  // POST tests
97  // getParsedBody()
98  'request.getParsedBody()[\'foo\'] > 0' => ['request.getParsedBody()[\'foo\'] > 0', true],
99  'request.getParsedBody()[\'foo\'][\'bar\'] > 0' => ['request.getParsedBody()[\'foo\'][\'bar\'] > 0', false],
100  'request.getParsedBody()[\'bar\'][\'foo\'] > 0' => ['request.getParsedBody()[\'bar\'][\'foo\'] > 0', false],
101  'request.getParsedBody()[\'foo\'] == 0' => ['request.getParsedBody()[\'foo\'] == 0', false],
102  'request.getParsedBody()[\'foo\'][\'bar\'] == 0' => ['request.getParsedBody()[\'foo\'][\'bar\'] == 0', false],
103  // HEADERS tests
104  // getHeaders()
105  'request.getHeaders()[\'foo\'] == [\'1\']' => ['request.getHeaders()[\'foo\'] == [\'1\']', true],
106  'request.getHeaders()[\'foo\'] == [\'0\']' => ['request.getHeaders()[\'foo\'] == [\'0\']', false],
107  'request.getHeaders()[\'foo\'] == [\'bar\']' => ['request.getHeaders()[\'foo\'] == [\'bar\']', false],
108  // COOKIES tests
109  // getCookieParams()
110  'request.getCookieParams()[\'foo\'] > 0' => ['request.getCookieParams()[\'foo\'] > 0', true],
111  'request.getCookieParams()[\'foo\'] > 1' => ['request.getCookieParams()[\'foo\'] > 1', false],
112  ];
113  }
114 
119  public function ‪checkConditionMatcherForRequestFunction(string $expression, bool $expected): void
120  {
121  $request = (new ‪ServerRequest())
122  ->withParsedBody(['foo' => 1])
123  ->withQueryParams(['foo' => 1])
124  ->withCookieParams(['foo' => 1])
125  ->withHeader('foo', '1')
126  ->withAttribute('applicationType', ‪SystemEnvironmentBuilder::REQUESTTYPE_BE);
127  ‪$GLOBALS['TYPO3_REQUEST'] = $request;
128  $this->‪initConditionMatcher();
129  self::assertSame(
130  $expected,
131  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, [$expression])
132  );
133  }
134 
135  public function ‪datesFunctionDataProvider(): array
136  {
137  return [
138  '[dayofmonth = 17]' => ['j', 17, true],
139  '[dayofweek = 3]' => ['w', 3, true],
140  '[dayofyear = 16]' => ['z', 16, true],
141  '[hour = 11]' => ['G', 11, true],
142  '[minute = 4]' => ['i', 4, true],
143  '[month = 1]' => ['n', 1, true],
144  '[year = 1945]' => ['Y', 1945, true],
145  ];
146  }
147 
152  public function ‪checkConditionMatcherForDateFunction(string $format, int $expressionValue, bool $expected): void
153  {
154  ‪$GLOBALS['SIM_EXEC_TIME'] = gmmktime(11, 4, 0, 1, 17, 1945);
155  GeneralUtility::makeInstance(Context::class)->setAspect('date', new ‪DateTimeAspect(new \DateTimeImmutable('@' . ‪$GLOBALS['SIM_EXEC_TIME'])));
156  $this->‪initConditionMatcher();
157  self::assertSame(
158  $expected,
159  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['date("' . $format . '") == ' . $expressionValue])
160  );
161  }
162 
167  {
168  $featureName = 'test.testFeature';
169  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['features'][$featureName] = true;
170  self::assertTrue(
171  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['feature("' . $featureName . '")'])
172  );
173  self::assertTrue(
174  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['feature("' . $featureName . '") == true'])
175  );
176  self::assertTrue(
177  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['feature("' . $featureName . '") === true'])
178  );
179  self::assertFalse(
180  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['feature("' . $featureName . '") == false'])
181  );
182  self::assertFalse(
183  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['feature("' . $featureName . '") === false'])
184  );
185 
186  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['features'][$featureName] = false;
187  self::assertFalse(
188  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['feature("' . $featureName . '")'])
189  );
190  self::assertFalse(
191  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['feature("' . $featureName . '") == true'])
192  );
193  self::assertFalse(
194  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['feature("' . $featureName . '") === true'])
195  );
196  self::assertTrue(
197  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['feature("' . $featureName . '") == false'])
198  );
199  self::assertTrue(
200  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['feature("' . $featureName . '") === false'])
201  );
202  }
203 
208  {
209  return [
210  ['Production*'],
211  ['Production/Staging/*'],
212  ['Production/Staging/Server2'],
213  ['/^Production.*$/'],
214  ['/^Production\\/.+\\/Server\\d+$/'],
215  ];
216  }
217 
222  public function ‪evaluateConditionCommonReturnsTrueForMatchingContexts($matchingContextCondition): void
223  {
225  new ‪ApplicationContext('Production/Staging/Server2'),
226  true,
227  false,
232  ‪Environment::getPublicPath() . '/index.php',
233  ‪Environment::isWindows() ? 'WINDOWS' : 'UNIX'
234  );
235 
236  $this->‪initConditionMatcher();
237 
238  // Test expression language
239  self::assertTrue(
240  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['like(applicationContext, "' . preg_quote($matchingContextCondition, '/') . '")'])
241  );
242  }
243 
248  {
249  return [
250  ['Production'],
251  ['Testing*'],
252  ['Development/Profiling, Testing/Unit'],
253  ['Testing/Staging/Server2'],
254  ['/^Testing.*$/'],
255  ['/^Production\\/.+\\/Host\\d+$/'],
256  ];
257  }
258 
263  public function ‪evaluateConditionCommonReturnsNullForNotMatchingApplicationContexts($notMatchingApplicationContextCondition): void
264  {
266  new ‪ApplicationContext('Production/Staging/Server2'),
267  true,
268  false,
273  ‪Environment::getPublicPath() . '/index.php',
274  ‪Environment::isWindows() ? 'WINDOWS' : 'UNIX'
275  );
276  $this->‪initConditionMatcher();
277 
278  // Test expression language
279  self::assertFalse(
280  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['like(applicationContext, "' . preg_quote($notMatchingApplicationContextCondition, '/') . '")'])
281  );
282  }
283 
288  {
289  return [
290  // [0] $GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask']
291  // [1] Actual IP
292  // [2] Expected condition result
293  'IP matches' => [
294  '127.0.0.1',
295  '127.0.0.1',
296  true,
297  ],
298  'ipv4 wildcard subnet' => [
299  '127.0.0.1/24',
300  '127.0.0.2',
301  true,
302  ],
303  'ipv6 wildcard subnet' => [
304  '0:0::1/128',
305  '::1',
306  true,
307  ],
308  'List of addresses matches' => [
309  '1.2.3.4, 5.6.7.8',
310  '5.6.7.8',
311  true,
312  ],
313  'IP does not match' => [
314  '127.0.0.1',
315  '127.0.0.2',
316  false,
317  ],
318  'ipv4 subnet does not match' => [
319  '127.0.0.1/8',
320  '126.0.0.1',
321  false,
322  ],
323  'ipv6 subnet does not match' => [
324  '::1/127',
325  '::2',
326  false,
327  ],
328  'List of addresses does not match' => [
329  '127.0.0.1, ::1',
330  '::2',
331  false,
332  ],
333  ];
334  }
335 
340  public function ‪evaluateConditionCommonEvaluatesIpAddressesCorrectly($devIpMask, $actualIp, $expectedResult): void
341  {
342  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask'] = $devIpMask;
343 
344  $request = new ‪ServerRequest(
345  new ‪Uri(''),
346  'GET',
347  'php://input',
348  [],
349  [
350  'REMOTE_ADDR' => $actualIp,
351  ]
352  );
353  $normalizedParams = ‪NormalizedParams::createFromRequest($request);
354  $request = $request->withAttribute('normalizedParams', $normalizedParams);
355 
356  ‪$GLOBALS['TYPO3_REQUEST'] = $request;
357 
358  $this->‪initConditionMatcher();
359  $result = $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['ip("devIP")']);
360  self::assertSame($expectedResult, $result);
361  }
362 
367  {
368  $this->‪initConditionMatcher();
369  $expressionProperty = new \ReflectionProperty(AbstractConditionMatcher::class, 'expressionLanguageResolver');
370  $resolverMock = $this->createMock(Resolver::class);
371  $resolverMock->expects(self::never())->method('evaluate')->withAnyParameters();
372  $expressionProperty->setValue($this->conditionMatcher, $resolverMock);
373  self::assertFalse($this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['ELSE']));
374  }
375 }
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\checkConditionMatcherForRequestFunction
‪checkConditionMatcherForRequestFunction(string $expression, bool $expected)
Definition: AbstractConditionMatcherTest.php:119
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\$backupEnvironment
‪bool $backupEnvironment
Definition: AbstractConditionMatcherTest.php:45
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\evaluateConditionCommonDevIpMaskDataProvider
‪evaluateConditionCommonDevIpMaskDataProvider()
Definition: AbstractConditionMatcherTest.php:287
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\evaluateConditionCommonReturnsTrueForMatchingContexts
‪evaluateConditionCommonReturnsTrueForMatchingContexts($matchingContextCondition)
Definition: AbstractConditionMatcherTest.php:222
‪TYPO3\CMS\Core\Core\ApplicationContext
Definition: ApplicationContext.php:39
‪TYPO3\CMS\Core\Information\Typo3Version
Definition: Typo3Version.php:21
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\notMatchingApplicationContextConditionsDataProvider
‪notMatchingApplicationContextConditionsDataProvider()
Definition: AbstractConditionMatcherTest.php:247
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\evaluateConditionCommonEvaluatesIpAddressesCorrectly
‪evaluateConditionCommonEvaluatesIpAddressesCorrectly($devIpMask, $actualIp, $expectedResult)
Definition: AbstractConditionMatcherTest.php:340
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\evaluateConditionCommonReturnsNullForNotMatchingApplicationContexts
‪evaluateConditionCommonReturnsNullForNotMatchingApplicationContexts($notMatchingApplicationContextCondition)
Definition: AbstractConditionMatcherTest.php:263
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder
Definition: SystemEnvironmentBuilder.php:41
‪TYPO3\CMS\Backend\Configuration\TypoScript\ConditionMatching\ConditionMatcher
Definition: ConditionMatcher.php:34
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\$conditionMatcher
‪ConditionMatcher $conditionMatcher
Definition: AbstractConditionMatcherTest.php:47
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static getPublicPath()
Definition: Environment.php:187
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\datesFunctionDataProvider
‪datesFunctionDataProvider()
Definition: AbstractConditionMatcherTest.php:135
‪TYPO3\CMS\Core\ExpressionLanguage\DefaultProvider
Definition: DefaultProvider.php:33
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\REQUESTTYPE_BE
‪const REQUESTTYPE_BE
Definition: SystemEnvironmentBuilder.php:45
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\$evaluateExpressionMethod
‪ReflectionMethod $evaluateExpressionMethod
Definition: AbstractConditionMatcherTest.php:48
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\checkConditionMatcherForDateFunction
‪checkConditionMatcherForDateFunction(string $format, int $expressionValue, bool $expected)
Definition: AbstractConditionMatcherTest.php:152
‪TYPO3\CMS\Core\Cache\Frontend\NullFrontend
Definition: NullFrontend.php:30
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\typoScriptElseConditionIsNotEvaluatedAndAlwaysReturnsFalse
‪typoScriptElseConditionIsNotEvaluatedAndAlwaysReturnsFalse()
Definition: AbstractConditionMatcherTest.php:366
‪TYPO3\CMS\Core\Core\Environment\getVarPath
‪static getVarPath()
Definition: Environment.php:197
‪TYPO3\CMS\Core\Context\Context
Definition: Context.php:55
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest
Definition: AbstractConditionMatcherTest.php:44
‪TYPO3\CMS\Core\Package\PackageInterface
Definition: PackageInterface.php:22
‪TYPO3\CMS\Core\Core\Environment\getConfigPath
‪static getConfigPath()
Definition: Environment.php:212
‪TYPO3\CMS\Core\Http\Uri
Definition: Uri.php:29
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\initConditionMatcher
‪initConditionMatcher()
Definition: AbstractConditionMatcherTest.php:70
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\requestFunctionDataProvider
‪requestFunctionDataProvider()
Definition: AbstractConditionMatcherTest.php:86
‪TYPO3\CMS\Core\Core\Environment\getProjectPath
‪static string getProjectPath()
Definition: Environment.php:160
‪TYPO3\CMS\Core\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcher
Definition: AbstractConditionMatcher.php:37
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching
Definition: AbstractConditionMatcherTest.php:18
‪TYPO3\CMS\Core\Configuration\Features
Definition: Features.php:56
‪TYPO3\CMS\Core\Cache\CacheManager
Definition: CacheManager.php:36
‪TYPO3\CMS\Core\Core\Environment\initialize
‪static initialize(ApplicationContext $context, bool $cli, bool $composerMode, string $projectPath, string $publicPath, string $varPath, string $configPath, string $currentScript, string $os)
Definition: Environment.php:100
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\$resetSingletonInstances
‪bool $resetSingletonInstances
Definition: AbstractConditionMatcherTest.php:46
‪TYPO3\CMS\Core\Http\ServerRequest
Definition: ServerRequest.php:37
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\checkConditionMatcherForFeatureFunction
‪checkConditionMatcherForFeatureFunction()
Definition: AbstractConditionMatcherTest.php:166
‪TYPO3\CMS\Core\ExpressionLanguage\ProviderConfigurationLoader
Definition: ProviderConfigurationLoader.php:28
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\matchingApplicationContextConditionsDataProvider
‪matchingApplicationContextConditionsDataProvider()
Definition: AbstractConditionMatcherTest.php:207
‪TYPO3\CMS\Core\ExpressionLanguage\Resolver
Definition: Resolver.php:32
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\setUp
‪setUp()
Definition: AbstractConditionMatcherTest.php:50
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:41
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:51
‪TYPO3\CMS\Core\Http\NormalizedParams\createFromRequest
‪static static createFromRequest(ServerRequestInterface $request, array $systemConfiguration=null)
Definition: NormalizedParams.php:840
‪TYPO3\CMS\Core\Context\DateTimeAspect
Definition: DateTimeAspect.php:35
‪TYPO3\CMS\Core\Http\NormalizedParams
Definition: NormalizedParams.php:38
‪TYPO3\CMS\Core\Core\Environment\isWindows
‪static isWindows()
Definition: Environment.php:287