‪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 final 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  $defaultProvider = new ‪DefaultProvider(new ‪Typo3Version(), new ‪Context(), new ‪Features());
80  GeneralUtility::addInstance(DefaultProvider::class, $defaultProvider);
81  $this->conditionMatcher = new ‪ConditionMatcher();
82  $this->conditionMatcher->setLogger(new NullLogger());
83  }
84 
85  public static function ‪requestFunctionDataProvider(): array
86  {
87  return [
88  // GET tests
89  // getQueryParams()
90  'request.getQueryParams()[\'foo\'] > 0' => ['request.getQueryParams()[\'foo\'] > 0', true],
91  'request.getQueryParams()[\'foo\'][\'bar\'] > 0' => ['request.getQueryParams()[\'foo\'][\'bar\'] > 0', false],
92  'request.getQueryParams()[\'foo\'] == 0' => ['request.getQueryParams()[\'foo\'] == 0', false],
93  'request.getQueryParams()[\'foo\'][\'bar\'] == 0' => ['request.getQueryParams()[\'foo\'][\'bar\'] == 0', false],
94  // POST tests
95  // getParsedBody()
96  'request.getParsedBody()[\'foo\'] > 0' => ['request.getParsedBody()[\'foo\'] > 0', true],
97  'request.getParsedBody()[\'foo\'][\'bar\'] > 0' => ['request.getParsedBody()[\'foo\'][\'bar\'] > 0', false],
98  'request.getParsedBody()[\'foo\'] == 0' => ['request.getParsedBody()[\'foo\'] == 0', false],
99  'request.getParsedBody()[\'foo\'][\'bar\'] == 0' => ['request.getParsedBody()[\'foo\'][\'bar\'] == 0', false],
100  // HEADERS tests
101  // getHeaders()
102  'request.getHeaders()[\'foo\'] == [\'1\']' => ['request.getHeaders()[\'foo\'] == [\'1\']', true],
103  'request.getHeaders()[\'foo\'] == [\'0\']' => ['request.getHeaders()[\'foo\'] == [\'0\']', false],
104  'request.getHeaders()[\'foo\'] == [\'bar\']' => ['request.getHeaders()[\'foo\'] == [\'bar\']', false],
105  // COOKIES tests
106  // getCookieParams()
107  'request.getCookieParams()[\'foo\'] > 0' => ['request.getCookieParams()[\'foo\'] > 0', true],
108  'request.getCookieParams()[\'foo\'] > 1' => ['request.getCookieParams()[\'foo\'] > 1', false],
109  ];
110  }
111 
116  public function ‪checkConditionMatcherForRequestFunction(string $expression, bool $expected): void
117  {
118  $request = (new ‪ServerRequest())
119  ->withParsedBody(['foo' => 1])
120  ->withQueryParams(['foo' => 1])
121  ->withCookieParams(['foo' => 1])
122  ->withHeader('foo', '1')
123  ->withAttribute('applicationType', ‪SystemEnvironmentBuilder::REQUESTTYPE_BE);
124  ‪$GLOBALS['TYPO3_REQUEST'] = $request;
125  $this->‪initConditionMatcher();
126  self::assertSame(
127  $expected,
128  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, [$expression])
129  );
130  }
131 
132  public static function ‪datesFunctionDataProvider(): array
133  {
134  return [
135  '[dayofmonth = 17]' => ['j', 17, true],
136  '[dayofweek = 3]' => ['w', 3, true],
137  '[dayofyear = 16]' => ['z', 16, true],
138  '[hour = 11]' => ['G', 11, true],
139  '[minute = 4]' => ['i', 4, true],
140  '[month = 1]' => ['n', 1, true],
141  '[year = 1945]' => ['Y', 1945, true],
142  ];
143  }
144 
149  public function ‪checkConditionMatcherForDateFunction(string $format, int $expressionValue, bool $expected): void
150  {
151  ‪$GLOBALS['SIM_EXEC_TIME'] = gmmktime(11, 4, 0, 1, 17, 1945);
152  GeneralUtility::makeInstance(Context::class)->setAspect('date', new ‪DateTimeAspect(new \DateTimeImmutable('@' . ‪$GLOBALS['SIM_EXEC_TIME'])));
153  $this->‪initConditionMatcher();
154  self::assertSame(
155  $expected,
156  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['date("' . $format . '") == ' . $expressionValue])
157  );
158  }
159 
164  {
165  $featureName = 'test.testFeature';
166  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['features'][$featureName] = true;
167  self::assertTrue(
168  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['feature("' . $featureName . '")'])
169  );
170  self::assertTrue(
171  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['feature("' . $featureName . '") == true'])
172  );
173  self::assertTrue(
174  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['feature("' . $featureName . '") === true'])
175  );
176  self::assertFalse(
177  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['feature("' . $featureName . '") == false'])
178  );
179  self::assertFalse(
180  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['feature("' . $featureName . '") === false'])
181  );
182 
183  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['features'][$featureName] = false;
184  self::assertFalse(
185  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['feature("' . $featureName . '")'])
186  );
187  self::assertFalse(
188  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['feature("' . $featureName . '") == true'])
189  );
190  self::assertFalse(
191  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['feature("' . $featureName . '") === true'])
192  );
193  self::assertTrue(
194  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['feature("' . $featureName . '") == false'])
195  );
196  self::assertTrue(
197  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['feature("' . $featureName . '") === false'])
198  );
199  }
200 
205  {
206  return [
207  ['Production*'],
208  ['Production/Staging/*'],
209  ['Production/Staging/Server2'],
210  ['/^Production.*$/'],
211  ['/^Production\\/.+\\/Server\\d+$/'],
212  ];
213  }
214 
219  public function ‪evaluateConditionCommonReturnsTrueForMatchingContexts($matchingContextCondition): void
220  {
222  new ‪ApplicationContext('Production/Staging/Server2'),
223  true,
224  false,
229  ‪Environment::getPublicPath() . '/index.php',
230  ‪Environment::isWindows() ? 'WINDOWS' : 'UNIX'
231  );
232 
233  $this->‪initConditionMatcher();
234 
235  // Test expression language
236  self::assertTrue(
237  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['like(applicationContext, "' . preg_quote($matchingContextCondition, '/') . '")'])
238  );
239  }
240 
245  {
246  return [
247  ['Production'],
248  ['Testing*'],
249  ['Development/Profiling, Testing/Unit'],
250  ['Testing/Staging/Server2'],
251  ['/^Testing.*$/'],
252  ['/^Production\\/.+\\/Host\\d+$/'],
253  ];
254  }
255 
260  public function ‪evaluateConditionCommonReturnsNullForNotMatchingApplicationContexts($notMatchingApplicationContextCondition): void
261  {
263  new ‪ApplicationContext('Production/Staging/Server2'),
264  true,
265  false,
270  ‪Environment::getPublicPath() . '/index.php',
271  ‪Environment::isWindows() ? 'WINDOWS' : 'UNIX'
272  );
273  $this->‪initConditionMatcher();
274 
275  // Test expression language
276  self::assertFalse(
277  $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['like(applicationContext, "' . preg_quote($notMatchingApplicationContextCondition, '/') . '")'])
278  );
279  }
280 
284  public static function ‪evaluateConditionCommonDevIpMaskDataProvider(): array
285  {
286  return [
287  // [0] $GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask']
288  // [1] Actual IP
289  // [2] Expected condition result
290  'IP matches' => [
291  '127.0.0.1',
292  '127.0.0.1',
293  true,
294  ],
295  'ipv4 wildcard subnet' => [
296  '127.0.0.1/24',
297  '127.0.0.2',
298  true,
299  ],
300  'ipv6 wildcard subnet' => [
301  '0:0::1/128',
302  '::1',
303  true,
304  ],
305  'List of addresses matches' => [
306  '1.2.3.4, 5.6.7.8',
307  '5.6.7.8',
308  true,
309  ],
310  'IP does not match' => [
311  '127.0.0.1',
312  '127.0.0.2',
313  false,
314  ],
315  'ipv4 subnet does not match' => [
316  '127.0.0.1/8',
317  '126.0.0.1',
318  false,
319  ],
320  'ipv6 subnet does not match' => [
321  '::1/127',
322  '::2',
323  false,
324  ],
325  'List of addresses does not match' => [
326  '127.0.0.1, ::1',
327  '::2',
328  false,
329  ],
330  ];
331  }
332 
337  public function ‪evaluateConditionCommonEvaluatesIpAddressesCorrectly($devIpMask, $actualIp, $expectedResult): void
338  {
339  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask'] = $devIpMask;
340 
341  $request = new ‪ServerRequest(
342  new ‪Uri(''),
343  'GET',
344  'php://input',
345  [],
346  [
347  'REMOTE_ADDR' => $actualIp,
348  ]
349  );
350  $normalizedParams = ‪NormalizedParams::createFromRequest($request);
351  $request = $request->withAttribute('normalizedParams', $normalizedParams);
352 
353  ‪$GLOBALS['TYPO3_REQUEST'] = $request;
354 
355  $this->‪initConditionMatcher();
356  $result = $this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['ip("devIP")']);
357  self::assertSame($expectedResult, $result);
358  }
359 
364  {
365  $this->‪initConditionMatcher();
366  $expressionProperty = new \ReflectionProperty(AbstractConditionMatcher::class, 'expressionLanguageResolver');
367  $resolverMock = $this->createMock(Resolver::class);
368  $resolverMock->expects(self::never())->method('evaluate')->withAnyParameters();
369  $expressionProperty->setValue($this->conditionMatcher, $resolverMock);
370  self::assertFalse($this->evaluateExpressionMethod->invokeArgs($this->conditionMatcher, ['ELSE']));
371  }
372 }
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\checkConditionMatcherForRequestFunction
‪checkConditionMatcherForRequestFunction(string $expression, bool $expected)
Definition: AbstractConditionMatcherTest.php:116
‪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\evaluateConditionCommonReturnsTrueForMatchingContexts
‪evaluateConditionCommonReturnsTrueForMatchingContexts($matchingContextCondition)
Definition: AbstractConditionMatcherTest.php:219
‪TYPO3\CMS\Core\Core\ApplicationContext
Definition: ApplicationContext.php:39
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\requestFunctionDataProvider
‪static requestFunctionDataProvider()
Definition: AbstractConditionMatcherTest.php:85
‪TYPO3\CMS\Core\Information\Typo3Version
Definition: Typo3Version.php:21
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\evaluateConditionCommonEvaluatesIpAddressesCorrectly
‪evaluateConditionCommonEvaluatesIpAddressesCorrectly($devIpMask, $actualIp, $expectedResult)
Definition: AbstractConditionMatcherTest.php:337
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\evaluateConditionCommonReturnsNullForNotMatchingApplicationContexts
‪evaluateConditionCommonReturnsNullForNotMatchingApplicationContexts($notMatchingApplicationContextCondition)
Definition: AbstractConditionMatcherTest.php:260
‪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\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\datesFunctionDataProvider
‪static datesFunctionDataProvider()
Definition: AbstractConditionMatcherTest.php:132
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static getPublicPath()
Definition: Environment.php:187
‪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:149
‪TYPO3\CMS\Core\Cache\Frontend\NullFrontend
Definition: NullFrontend.php:30
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\typoScriptElseConditionIsNotEvaluatedAndAlwaysReturnsFalse
‪typoScriptElseConditionIsNotEvaluatedAndAlwaysReturnsFalse()
Definition: AbstractConditionMatcherTest.php:363
‪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\matchingApplicationContextConditionsDataProvider
‪static matchingApplicationContextConditionsDataProvider()
Definition: AbstractConditionMatcherTest.php:204
‪TYPO3\CMS\Core\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\notMatchingApplicationContextConditionsDataProvider
‪static notMatchingApplicationContextConditionsDataProvider()
Definition: AbstractConditionMatcherTest.php:244
‪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:163
‪TYPO3\CMS\Core\ExpressionLanguage\ProviderConfigurationLoader
Definition: ProviderConfigurationLoader.php:28
‪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\Tests\UnitDeprecated\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcherTest\evaluateConditionCommonDevIpMaskDataProvider
‪static evaluateConditionCommonDevIpMaskDataProvider()
Definition: AbstractConditionMatcherTest.php:284
‪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