[!!!][TASK] Always include pageId in cHash calculation
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Tests / Unit / Page / CacheHashCalculatorTest.php
1 <?php
2 namespace TYPO3\CMS\Frontend\Tests\Unit\Page;
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 /**
18 * Testcase
19 */
20 class CacheHashCalculatorTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
21 {
22 /**
23 * @var \TYPO3\CMS\Frontend\Page\CacheHashCalculator
24 */
25 protected $subject;
26
27 protected function setUp()
28 {
29 $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] = 't3lib_cacheHashTest';
30 $this->subject = $this->getMockBuilder(\TYPO3\CMS\Frontend\Page\CacheHashCalculator::class)
31 ->setMethods(['foo'])
32 ->getMock();
33 $this->subject->setConfiguration([
34 'excludedParameters' => ['exclude1', 'exclude2'],
35 'cachedParametersWhiteList' => [],
36 'requireCacheHashPresenceParameters' => ['req1', 'req2'],
37 'excludedParametersIfEmpty' => [],
38 'excludeAllEmptyParameters' => false
39 ]);
40 }
41
42 /**
43 * @dataProvider cacheHashCalculationDataProvider
44 * @test
45 */
46 public function cacheHashCalculationWorks($params, $expected)
47 {
48 $this->assertEquals($expected, $this->subject->calculateCacheHash($params));
49 }
50
51 /**
52 * @return array
53 */
54 public function cacheHashCalculationDataProvider()
55 {
56 return [
57 'Empty parameters should not return a hash' => [
58 [],
59 ''
60 ],
61 'Trivial key value combination should generate hash' => [
62 [
63 'encryptionKey' => 't3lib_cacheHashTest',
64 'key' => 'value'
65 ],
66 '5cfdcf826275558b3613dd51714a0a17'
67 ],
68 'Multiple parameters should generate hash' => [
69 [
70 'a' => 'v',
71 'b' => 'v',
72 'encryptionKey' => 't3lib_cacheHashTest'
73 ],
74 '0f40b089cdad149aea99e9bf4badaa93'
75 ]
76 ];
77 }
78
79 /**
80 * @dataProvider getRelevantParametersDataprovider
81 * @test
82 */
83 public function getRelevantParametersWorks($params, $expected)
84 {
85 $actual = $this->subject->getRelevantParameters($params);
86 $this->assertEquals($expected, array_keys($actual));
87 }
88
89 /**
90 * @return array
91 */
92 public function getRelevantParametersDataprovider()
93 {
94 return [
95 'Empty list should be passed through' => ['', []],
96 'Simple parameter should be passed through and the encryptionKey should be added' => [
97 'key=v&id=42',
98 ['encryptionKey', 'id', 'key']
99 ],
100 'Simple parameter should be passed through' => [
101 'key1=v&key2=v&id=42',
102 ['encryptionKey', 'id', 'key1', 'key2']
103 ],
104 'System and exclude parameters should be omitted' => [
105 'id=1&type=3&exclude1=x&no_cache=1',
106 []
107 ],
108 'System and exclude parameters (except id) should be omitted, others should stay' => [
109 'id=1&type=3&key=x&no_cache=1',
110 ['encryptionKey', 'id', 'key']
111 ],
112 'System and exclude parameters should be omitted and id is not required to be specified' => [
113 '&type=3&no_cache=1',
114 []
115 ]
116 ];
117 }
118
119 /**
120 * @dataProvider canGenerateForParametersDataProvider
121 * @test
122 */
123 public function canGenerateForParameters($params, $expected)
124 {
125 $this->assertEquals($expected, $this->subject->generateForParameters($params));
126 }
127
128 /**
129 * @test
130 * @expectedException \RuntimeException
131 * @expectedExceptionCode 1467983513
132 */
133 public function generateForParametersThrowsExceptionWhenIdIsNotSpecified()
134 {
135 $this->subject->generateForParameters('&key=x');
136 }
137
138 /**
139 * @return array
140 */
141 public function canGenerateForParametersDataProvider()
142 {
143 $knowHash = 'fac112f7e662c83c19b57142c3a921f5';
144 return [
145 'Empty parameters should not return an hash' => ['&id=42', ''],
146 'Querystring has no relevant parameters so we should not have a cacheHash' => ['&exclude1=val', ''],
147 'Querystring has only system parameters so we should not have a cacheHash' => ['&id=42&type=val', ''],
148 'Trivial key value combination should generate hash' => ['&id=42&key=value', $knowHash],
149 'Only the relevant parts should be taken into account' => ['&id=42&key=value&exclude1=val', $knowHash],
150 'Only the relevant parts should be taken into account(exclude2 before key)' => ['&id=42&exclude2=val&key=value', $knowHash],
151 'System parameters should not be taken into account (except id)' => ['&id=42&type=23&key=value', $knowHash],
152 'Admin panel parameters should not be taken into account' => ['&id=42&TSFE_ADMIN_PANEL[display]=7&key=value', $knowHash],
153 'Trivial hash for sorted parameters should be right' => ['&id=42&a=v&b=v', '52c8a1299e20324f90377c43153c4987'],
154 'Parameters should be sorted before cHash is created' => ['&id=42&b=v&a=v', '52c8a1299e20324f90377c43153c4987'],
155 'Empty argument names are filtered out before cHash calculation' => ['&id=42&b=v&a=v&=dummy', '52c8a1299e20324f90377c43153c4987']
156 ];
157 }
158
159 /**
160 * @dataProvider parametersRequireCacheHashDataprovider
161 * @test
162 */
163 public function parametersRequireCacheHashWorks($params, $expected)
164 {
165 $this->assertEquals($expected, $this->subject->doParametersRequireCacheHash($params));
166 }
167
168 /**
169 * @return array
170 */
171 public function parametersRequireCacheHashDataprovider()
172 {
173 return [
174 'Empty parameter strings should not require anything.' => ['', false],
175 'Normal parameters aren\'t required.' => ['key=value', false],
176 'Configured "req1" to be required.' => ['req1=value', true],
177 'Configured "req1" to be required, should also work in combined context' => ['&key=value&req1=value', true],
178 'Configured "req1" to be required, should also work in combined context (key at the end)' => ['req1=value&key=value', true]
179 ];
180 }
181
182 /**
183 * In case the cHashOnlyForParameters is set, other parameters should not
184 * incluence the cHash (except the encryption key of course)
185 *
186 * @dataProvider canWhitelistParametersDataProvider
187 * @test
188 */
189 public function canWhitelistParameters($params, $expected)
190 {
191 $method = new \ReflectionMethod(\TYPO3\CMS\Frontend\Page\CacheHashCalculator::class, 'setCachedParametersWhiteList');
192 $method->setAccessible(true);
193 $method->invoke($this->subject, ['whitep1', 'whitep2']);
194 $this->assertEquals($expected, $this->subject->generateForParameters($params));
195 }
196
197 /**
198 * @return array
199 */
200 public function canWhitelistParametersDataProvider()
201 {
202 $oneParamHash = 'eae50a13101afd53a9d2c543230eb5bb';
203 $twoParamHash = '701e2d2f1becc9d1b71d327e5cb1c3ed';
204 return [
205 'Even with the whitelist enabled, empty parameters should not return an hash.' => ['', ''],
206 'Whitelisted parameters should have a hash.' => ['&id=42&whitep1=value', $oneParamHash],
207 'Blacklisted parameter should not influence hash.' => ['&id=42&whitep1=value&black=value', $oneParamHash],
208 'Multiple whitelisted parameters should work' => ['&id=42&whitep1=value&whitep2=value', $twoParamHash],
209 'The order should not influce the hash.' => ['&id=42&whitep2=value&black=value&whitep1=value', $twoParamHash]
210 ];
211 }
212
213 /**
214 * @dataProvider canSkipParametersWithEmptyValuesDataProvider
215 * @test
216 */
217 public function canSkipParametersWithEmptyValues($params, $settings, $expected)
218 {
219 $this->subject->setConfiguration($settings);
220 $actual = $this->subject->getRelevantParameters($params);
221 $this->assertEquals($expected, array_keys($actual));
222 }
223
224 /**
225 * @return array
226 */
227 public function canSkipParametersWithEmptyValuesDataProvider()
228 {
229 return [
230 'The default configuration does not allow to skip an empty key.' => [
231 '&id=42&key1=v&key2=&key3=',
232 ['excludedParametersIfEmpty' => [], 'excludeAllEmptyParameters' => false],
233 ['encryptionKey', 'id', 'key1', 'key2', 'key3']
234 ],
235 'Due to the empty value, "key2" should be skipped(with equals sign' => [
236 '&id=42&key1=v&key2=&key3=',
237 ['excludedParametersIfEmpty' => ['key2'], 'excludeAllEmptyParameters' => false],
238 ['encryptionKey', 'id', 'key1', 'key3']
239 ],
240 'Due to the empty value, "key2" should be skipped(without equals sign)' => [
241 '&id=42&key1=v&key2&key3',
242 ['excludedParametersIfEmpty' => ['key2'], 'excludeAllEmptyParameters' => false],
243 ['encryptionKey', 'id', 'key1', 'key3']
244 ],
245 'Due to the empty value, "key2" and "key3" should be skipped' => [
246 '&id=42&key1=v&key2=&key3=',
247 ['excludedParametersIfEmpty' => [], 'excludeAllEmptyParameters' => true],
248 ['encryptionKey', 'id', 'key1']
249 ]
250 ];
251 }
252 }