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