c7e831b2344c63ce8c6eacc5ac4c2d34b789af75
[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\Backend\Configuration\TypoScript\ConditionMatching\ConditionMatcher;
18 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
19 use TYPO3\CMS\Core\Context\Context;
20 use TYPO3\CMS\Core\Context\UserAspect;
21 use TYPO3\CMS\Core\Http\ServerRequest;
22 use TYPO3\CMS\Core\Log\Logger;
23 use TYPO3\CMS\Core\Utility\GeneralUtility;
24
25 /**
26 * Testcase for class \TYPO3\CMS\Backend\Configuration\TypoScript\ConditionMatching\ConditionMatcher.
27 */
28 class ConditionMatcherTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
29 {
30 /**
31 * @var array
32 */
33 protected $rootline;
34
35 /**
36 * @var \TYPO3\CMS\Backend\Configuration\TypoScript\ConditionMatching\ConditionMatcher
37 */
38 protected $matchCondition;
39
40 /**
41 * @var string
42 */
43 protected $testGlobalNamespace;
44
45 /**
46 * @var string
47 */
48 protected $testTableName;
49
50 /**
51 * @var bool Reset singletons
52 */
53 protected $resetSingletonInstances = true;
54
55 /**
56 * Set up tests
57 */
58 protected function setUp()
59 {
60 $GLOBALS['TYPO3_REQUEST'] = new ServerRequest();
61 $this->testTableName = 'conditionMatcherTestTable';
62 $this->testGlobalNamespace = $this->getUniqueId('TEST');
63 $GLOBALS['TCA'][$this->testTableName] = ['ctrl' => []];
64 $GLOBALS[$this->testGlobalNamespace] = [];
65 $this->setUpBackend();
66 $this->matchCondition = $this->getAccessibleMock(ConditionMatcher::class, ['determineRootline'], [], '', false);
67 $this->matchCondition->method('determineRootline')->willReturn([
68 2 => ['uid' => 121, 'pid' => 111],
69 1 => ['uid' => 111, 'pid' => 101],
70 0 => ['uid' => 101, 'pid' => 0]
71 ]);
72 $this->matchCondition->__construct();
73 $loggerProphecy = $this->prophesize(Logger::class);
74 $this->matchCondition->setLogger($loggerProphecy->reveal());
75 }
76
77 /**
78 * Set up a backend
79 */
80 private function setUpBackend()
81 {
82 $this->rootline = [
83 2 => ['uid' => 121, 'pid' => 111],
84 1 => ['uid' => 111, 'pid' => 101],
85 0 => ['uid' => 101, 'pid' => 0]
86 ];
87 $GLOBALS['BE_USER'] = $this->getMockBuilder(BackendUserAuthentication::class)
88 ->setMethods(['dummy'])
89 ->disableOriginalConstructor()
90 ->getMock();
91 $GLOBALS['BE_USER']->groupList = '13,14,15';
92 $GLOBALS['BE_USER']->user['uid'] = 13;
93 $GLOBALS['BE_USER']->user['admin'] = 1;
94
95 GeneralUtility::makeInstance(Context::class)
96 ->setAspect('backend.user', new UserAspect($GLOBALS['BE_USER']));
97 }
98
99 /**
100 * Set up database mock
101 */
102 private function setUpDatabaseMockForDeterminePageId()
103 {
104 $this->matchCondition = $this->getAccessibleMock(ConditionMatcher::class, ['determineRootline', 'determinePageId'], [], '', false);
105 $this->matchCondition->method('determineRootline')->willReturn([
106 2 => ['uid' => 121, 'pid' => 111],
107 1 => ['uid' => 111, 'pid' => 101],
108 0 => ['uid' => 101, 'pid' => 0]
109 ]);
110 $this->matchCondition->__construct();
111 $loggerProphecy = $this->prophesize(Logger::class);
112 $this->matchCondition->setLogger($loggerProphecy->reveal());
113
114 $this->matchCondition->expects($this->once())->method('determinePageId')->willReturn(999);
115 }
116
117 /**
118 * Tests whether usergroup comparison matches.
119 *
120 * @test
121 */
122 public function usergroupConditionMatchesSingleGroupId()
123 {
124 $this->assertTrue($this->matchCondition->match('[usergroup(13)]'));
125 $this->assertTrue($this->matchCondition->match('[usergroup("13")]'));
126 $this->assertTrue($this->matchCondition->match('[usergroup(\'13\')]'));
127 }
128
129 /**
130 * Tests whether usergroup comparison matches.
131 *
132 * @test
133 */
134 public function usergroupConditionMatchesMultipleUserGroupId()
135 {
136 $this->assertTrue($this->matchCondition->match('[usergroup("999,15,14,13")]'));
137 $this->assertTrue($this->matchCondition->match('[usergroup(\'999,15,14,13\')]'));
138 }
139
140 /**
141 * Tests whether user comparison matches.
142 *
143 * @test
144 */
145 public function loginUserConditionMatchesAnyLoggedInUser()
146 {
147 $this->assertTrue($this->matchCondition->match('[loginUser("*")]'));
148 $this->assertTrue($this->matchCondition->match('[loginUser(\'*\')]'));
149 }
150
151 /**
152 * Tests whether user comparison matches.
153 *
154 * @test
155 */
156 public function loginUserConditionMatchesSingleLoggedInUser()
157 {
158 $this->assertTrue($this->matchCondition->match('[loginUser(13)]'));
159 $this->assertTrue($this->matchCondition->match('[loginUser("13")]'));
160 $this->assertTrue($this->matchCondition->match('[loginUser(\'13\')]'));
161 }
162
163 /**
164 * Tests whether user comparison matches.
165 *
166 * @test
167 */
168 public function loginUserConditionDoesNotMatchSingleLoggedInUser()
169 {
170 $GLOBALS['BE_USER']->user['uid'] = 13;
171 $this->assertFalse($this->matchCondition->match('[loginUser(999)]'));
172 $this->assertFalse($this->matchCondition->match('[loginUser("999")]'));
173 $this->assertFalse($this->matchCondition->match('[loginUser(\'999\')]'));
174 }
175
176 /**
177 * Tests whether user comparison matches.
178 *
179 * @test
180 */
181 public function loginUserConditionMatchesMultipleLoggedInUsers()
182 {
183 $this->assertTrue($this->matchCondition->match('[loginUser("999,13")]'));
184 $this->assertTrue($this->matchCondition->match('[loginUser(\'999,13\')]'));
185 }
186
187 /**
188 * Tests whether checkinf for an admin user matches
189 *
190 * @test
191 */
192 public function adminUserConditionMatchesAdminUser()
193 {
194 $this->assertTrue($this->matchCondition->match('[backend.user.isAdmin == true]'));
195 $this->assertTrue($this->matchCondition->match('[backend.user.isAdmin != false]'));
196 $this->assertTrue($this->matchCondition->match('[backend.user.isAdmin]'));
197 }
198
199 /**
200 * Tests whether treeLevel comparison matches.
201 *
202 * @test
203 */
204 public function treeLevelConditionMatchesSingleValue()
205 {
206 $this->matchCondition->setRootline($this->rootline);
207 $this->assertTrue($this->matchCondition->match('[tree.level == 2]'));
208 }
209
210 /**
211 * Tests whether treeLevel comparison matches.
212 *
213 * @test
214 */
215 public function treeLevelConditionMatchesMultipleValues()
216 {
217 $this->matchCondition->setRootline($this->rootline);
218 $this->assertTrue($this->matchCondition->match('[tree.level in [999,998,2]]'));
219 }
220
221 /**
222 * Tests whether treeLevel comparison matches.
223 *
224 * @test
225 */
226 public function treeLevelConditionDoesNotMatchFaultyValue()
227 {
228 $this->matchCondition->setRootline($this->rootline);
229 $this->assertFalse($this->matchCondition->match('[tree.level == 999]'));
230 }
231
232 /**
233 * Tests whether a page Id is found in the previous rootline entries.
234 *
235 * @test
236 */
237 public function PIDupinRootlineConditionMatchesSinglePageIdInRootline()
238 {
239 $this->matchCondition->setRootline($this->rootline);
240 $this->matchCondition->setPageId(121);
241 $this->assertTrue($this->matchCondition->match('[111 in tree.rootLineIds]'));
242 $this->assertTrue($this->matchCondition->match('["111" in tree.rootLineIds]'));
243 $this->assertTrue($this->matchCondition->match('[\'111\' in tree.rootLineIds]'));
244 }
245
246 /**
247 * Tests whether a page Id is found in the previous rootline entries.
248 *
249 * @test
250 */
251 public function PIDupinRootlineConditionDoesNotMatchPageIdNotInRootline()
252 {
253 $this->matchCondition->setRootline($this->rootline);
254 $this->matchCondition->setPageId(121);
255 $this->assertFalse($this->matchCondition->match('[999 in tree.rootLineIds]'));
256 }
257
258 /**
259 * Tests whether a page Id is found in all rootline entries.
260 *
261 * @test
262 */
263 public function PIDinRootlineConditionMatchesSinglePageIdInRootline()
264 {
265 $this->matchCondition->setRootline($this->rootline);
266 $this->matchCondition->setPageId(121);
267 $this->assertTrue($this->matchCondition->match('[111 in tree.rootLineIds]'));
268 }
269
270 /**
271 * Tests whether a page Id is found in all rootline entries.
272 *
273 * @test
274 */
275 public function PIDinRootlineConditionMatchesLastPageIdInRootline()
276 {
277 $this->matchCondition->setRootline($this->rootline);
278 $this->matchCondition->setPageId(121);
279 $this->assertTrue($this->matchCondition->match('[121 in tree.rootLineIds]'));
280 }
281
282 /**
283 * Tests whether a page Id is found in all rootline entries.
284 *
285 * @test
286 */
287 public function PIDinRootlineConditionDoesNotMatchPageIdNotInRootline()
288 {
289 $this->matchCondition->setRootline($this->rootline);
290 $this->matchCondition->setPageId(121);
291 $this->assertFalse($this->matchCondition->match('[999 in tree.rootLineIds]'));
292 }
293
294 /**
295 * Tests whether the compatibility version can be evaluated.
296 * (e.g. 7.9 is compatible to 7.0 but not to 15.0)
297 *
298 * @test
299 */
300 public function compatVersionConditionMatchesOlderRelease()
301 {
302 $this->assertTrue($this->matchCondition->match('[compatVersion(7.0)]'));
303 $this->assertTrue($this->matchCondition->match('[compatVersion("7.0")]'));
304 $this->assertTrue($this->matchCondition->match('[compatVersion(\'7.0\')]'));
305 }
306
307 /**
308 * Tests whether the compatibility version can be evaluated.
309 * (e.g. 7.9 is compatible to 7.0 but not to 15.0)
310 *
311 * @test
312 */
313 public function compatVersionConditionMatchesSameRelease()
314 {
315 $this->assertTrue($this->matchCondition->match('[compatVersion(' . TYPO3_branch . ')]'));
316 $this->assertTrue($this->matchCondition->match('[compatVersion("' . TYPO3_branch . '")]'));
317 $this->assertTrue($this->matchCondition->match('[compatVersion(\'' . TYPO3_branch . '\')]'));
318 }
319
320 /**
321 * Tests whether the compatibility version can be evaluated.
322 * (e.g. 7.9 is compatible to 7.0 but not to 15.0)
323 *
324 * @test
325 */
326 public function compatVersionConditionDoesNotMatchNewerRelease()
327 {
328 $this->assertFalse($this->matchCondition->match('[compatVersion(15.0)]'));
329 $this->assertFalse($this->matchCondition->match('[compatVersion("15.0")]'));
330 $this->assertFalse($this->matchCondition->match('[compatVersion(\'15.0\')]'));
331 }
332
333 /**
334 * Tests whether the generic fetching of variables works with the namespace 'ENV'.
335 *
336 * @test
337 */
338 public function genericGetVariablesSucceedsWithNamespaceENV()
339 {
340 $testKey = $this->getUniqueId('test');
341 putenv($testKey . '=testValue');
342 $this->assertTrue($this->matchCondition->match('[getenv("' . $testKey . '") == "testValue"]'));
343 }
344 }