TYPO3 CMS  TYPO3_7-6
Typo3DatabaseBackendTest.php
Go to the documentation of this file.
1 <?php
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 
22 {
29  protected function setUpMockFrontendOfBackend(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend $backend)
30  {
31  $mockCache = $this->getMock(\TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class, [], [], '', false);
32  $mockCache->expects($this->any())->method('getIdentifier')->will($this->returnValue('Testing'));
33  $backend->setCache($mockCache);
34  return $mockCache;
35  }
36 
40  public function setCacheCalculatesCacheTableName()
41  {
43  $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, ['dummy'], ['Testing']);
44  $this->setUpMockFrontendOfBackend($backend);
45  $this->assertEquals('cf_Testing', $backend->getCacheTable());
46  }
47 
51  public function setCacheCalculatesTagsTableName()
52  {
54  $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, ['dummy'], ['Testing']);
55  $this->setUpMockFrontendOfBackend($backend);
56  $this->assertEquals('cf_Testing_tags', $backend->getTagsTable());
57  }
58 
63  public function setThrowsExceptionIfFrontendWasNotSet()
64  {
66  $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, ['dummy'], ['Testing']);
67  $backend->set('identifier', 'data');
68  }
69 
74  public function setThrowsExceptionIfDataIsNotAString()
75  {
77  $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, ['dummy'], ['Testing']);
78  $this->setUpMockFrontendOfBackend($backend);
79  $data = ['Some data'];
80  $entryIdentifier = 'BackendDbTest';
81  $backend->set($entryIdentifier, $data);
82  }
83 
87  public function setInsertsEntryInTable()
88  {
90  $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, ['dummy'], ['Testing']);
91  $this->setUpMockFrontendOfBackend($backend);
92  $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, [], [], '', false);
93  $GLOBALS['TYPO3_DB']
94  ->expects($this->once())
95  ->method('exec_INSERTquery')
96  ->with('cf_Testing', $this->callback(function (array $data) {
97  if ($data['content'] !== 'someData') {
98  return false;
99  }
100  if ($data['identifier'] !== 'anIdentifier') {
101  return false;
102  }
103  return true;
104  }));
105  $backend->set('anIdentifier', 'someData');
106  }
107 
111  public function setRemovesAnAlreadyExistingCacheEntryForTheSameIdentifier()
112  {
114  $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, ['remove'], ['Testing']);
115  $this->setUpMockFrontendOfBackend($backend);
116  $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, [], [], '', false);
117 
118  $backend->expects($this->once())->method('remove');
119  $data = $this->getUniqueId('someData');
120  $entryIdentifier = 'anIdentifier';
121  $backend->set($entryIdentifier, $data, [], 500);
122  }
123 
127  public function setReallySavesSpecifiedTags()
128  {
130  $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, ['dummy'], ['Testing']);
131  $this->setUpMockFrontendOfBackend($backend);
132  $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, [], [], '', false);
133  $GLOBALS['TYPO3_DB']
134  ->expects($this->once())
135  ->method('exec_INSERTmultipleRows')
136  ->with(
137  'cf_Testing_tags',
138  $this->callback(function (array $data) {
139  if ($data[0] === 'identifier' && $data[1] === 'tag') {
140  return true;
141  }
142  return false;
143  }),
144  $this->callback(function (array $data) {
145  if ($data[0][0] !== 'anIdentifier' || $data[0][1] !== 'UnitTestTag%tag1') {
146  return false;
147  }
148  if ($data[1][0] !== 'anIdentifier' || $data[1][1] !== 'UnitTestTag%tag2') {
149  return false;
150  }
151  return true;
152  })
153  );
154  $backend->set('anIdentifier', 'someData', ['UnitTestTag%tag1', 'UnitTestTag%tag2']);
155  }
156 
160  public function setSavesCompressedDataWithEnabledCompression()
161  {
162  $backendOptions = [
163  'compression' => true
164  ];
166  $backend = $this->getMock(
167  \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class,
168  ['dummy'],
169  ['Testing', $backendOptions]
170  );
171  $this->setUpMockFrontendOfBackend($backend);
172 
173  $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, [], [], '', false);
174  $GLOBALS['TYPO3_DB']
175  ->expects($this->once())
176  ->method('exec_INSERTquery')
177  ->with(
178  'cf_Testing',
179  $this->callback(function (array $data) {
180  if (@gzuncompress($data['content']) === 'someData') {
181  return true;
182  }
183  return false;
184  }
185  ));
186 
187  $backend->set('anIdentifier', 'someData');
188  }
189 
193  public function setWithUnlimitedLifetimeWritesCorrectEntry()
194  {
196  $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, ['dummy'], ['Testing']);
197  $this->setUpMockFrontendOfBackend($backend);
198 
199  $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, [], [], '', false);
200  $GLOBALS['TYPO3_DB']
201  ->expects($this->once())
202  ->method('exec_INSERTquery')
203  ->with(
204  'cf_Testing',
205  $this->callback(function (array $data) {
206  $lifetime = $data['expires'];
207  if ($lifetime > 2000000000) {
208  return true;
209  }
210  return false;
211  }
212  ));
213 
214  $backend->set('aIdentifier', 'someData', [], 0);
215  }
216 
221  public function getThrowsExceptionIfFrontendWasNotSet()
222  {
224  $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, ['dummy'], ['Testing']);
225  $backend->get('identifier');
226  }
227 
231  public function getReturnsContentOfTheCorrectCacheEntry()
232  {
234  $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, ['dummy'], ['Testing']);
235  $this->setUpMockFrontendOfBackend($backend);
236 
237  $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, [], [], '', false);
238  $GLOBALS['TYPO3_DB']
239  ->expects($this->once())
240  ->method('exec_SELECTgetSingleRow')
241  ->with('content', 'cf_Testing', $this->anything())
242  ->will($this->returnValue(['content' => 'someData']));
243 
244  $loadedData = $backend->get('aIdentifier');
245  $this->assertEquals('someData', $loadedData);
246  }
247 
251  public function getSetsExceededLifetimeQueryPart()
252  {
254  $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, ['dummy'], ['Testing']);
255  $this->setUpMockFrontendOfBackend($backend);
256 
257  $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, [], [], '', false);
258  $GLOBALS['TYPO3_DB']
259  ->expects($this->once())
260  ->method('exec_SELECTgetSingleRow')
261  ->with(
262  'content',
263  'cf_Testing',
264  $this->stringContains('identifier = AND cf_Testing.expires >=')
265  );
266 
267  $backend->get('aIdentifier');
268  }
269 
274  public function hasThrowsExceptionIfFrontendWasNotSet()
275  {
277  $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, ['dummy'], ['Testing']);
278  $backend->has('identifier');
279  }
280 
284  public function hasReturnsTrueForExistingEntry()
285  {
287  $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, ['dummy'], ['Testing']);
288  $this->setUpMockFrontendOfBackend($backend);
289 
290  $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, [], [], '', false);
291  $GLOBALS['TYPO3_DB']
292  ->expects($this->once())
293  ->method('exec_SELECTcountRows')
294  ->with('*', 'cf_Testing', $this->anything())
295  ->will($this->returnValue(1));
296 
297  $this->assertTrue($backend->has('aIdentifier'));
298  }
299 
303  public function hasSetsExceededLifetimeQueryPart()
304  {
306  $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, ['dummy'], ['Testing']);
307  $this->setUpMockFrontendOfBackend($backend);
308 
309  $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, [], [], '', false);
310  $GLOBALS['TYPO3_DB']
311  ->expects($this->once())
312  ->method('exec_SELECTcountRows')
313  ->with(
314  '*',
315  'cf_Testing',
316  $this->stringContains('identifier = AND cf_Testing.expires >='))
317  ->will($this->returnValue(1));
318 
319  $this->assertTrue($backend->has('aIdentifier'));
320  }
321 
326  public function removeThrowsExceptionIfFrontendWasNotSet()
327  {
329  $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, ['dummy'], ['Testing']);
330  $backend->remove('identifier');
331  }
332 
337  public function collectGarbageThrowsExceptionIfFrontendWasNotSet()
338  {
340  $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, ['dummy'], ['Testing']);
341  $backend->collectGarbage();
342  }
343 
347  public function collectGarbageDeletesTagsFromExpiredEntries()
348  {
350  $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, ['dummy'], ['Testing']);
351  $this->setUpMockFrontendOfBackend($backend);
352 
353  $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, [], [], '', false);
354  $GLOBALS['TYPO3_DB']
355  ->expects($this->at(1))
356  ->method('sql_fetch_assoc')
357  ->will($this->returnValue(['identifier' => 'aIdentifier']));
358  $GLOBALS['TYPO3_DB']
359  ->expects($this->at(2))
360  ->method('fullQuoteStr')
361  ->will($this->returnValue('aIdentifier'));
362  $GLOBALS['TYPO3_DB']
363  ->expects($this->at(3))
364  ->method('sql_fetch_assoc')
365  ->will($this->returnValue(false));
366  $GLOBALS['TYPO3_DB']
367  ->expects($this->at(5))
368  ->method('exec_DELETEquery')
369  ->with('cf_Testing_tags', 'identifier IN (aIdentifier)');
370 
371  $backend->collectGarbage();
372  }
373 
378  public function findIdentifiersByTagThrowsExceptionIfFrontendWasNotSet()
379  {
381  $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, ['dummy'], ['Testing']);
382  $backend->findIdentifiersByTag('identifier');
383  }
384 
388  public function findIdentifiersByTagFindsCacheEntriesWithSpecifiedTag()
389  {
391  $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, ['dummy'], ['Testing']);
392  $this->setUpMockFrontendOfBackend($backend);
393 
394  $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, [], [], '', false);
395  $GLOBALS['TYPO3_DB']
396  ->expects($this->at(0))
397  ->method('fullQuoteStr')
398  ->will($this->returnValue('cf_Testing_tags'));
399  $GLOBALS['TYPO3_DB']
400  ->expects($this->at(1))
401  ->method('exec_SELECTgetRows')
402  ->with(
403  'cf_Testing.identifier',
404  'cf_Testing, cf_Testing_tags',
405  $this->stringContains('cf_Testing_tags.tag = cf_Testing_tags AND cf_Testing.identifier = cf_Testing_tags.identifier AND cf_Testing.expires >= '),
406  'cf_Testing.identifier'
407  )
408  ->will($this->returnValue([['identifier' => 'aIdentifier']]));
409  $this->assertSame(['aIdentifier' => 'aIdentifier'], $backend->findIdentifiersByTag('aTag'));
410  }
411 
416  public function flushThrowsExceptionIfFrontendWasNotSet()
417  {
419  $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, ['dummy'], ['Testing']);
420  $backend->flush();
421  }
422 
426  public function flushRemovesAllCacheEntries()
427  {
429  $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, ['dummy'], ['Testing']);
430  $this->setUpMockFrontendOfBackend($backend);
431 
432  $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, [], [], '', false);
433  $GLOBALS['TYPO3_DB']
434  ->expects($this->at(0))
435  ->method('exec_TRUNCATEquery')
436  ->with('cf_Testing');
437  $GLOBALS['TYPO3_DB']
438  ->expects($this->at(1))
439  ->method('exec_TRUNCATEquery')
440  ->with('cf_Testing_tags');
441 
442  $backend->flush();
443  }
444 
449  public function flushByTagThrowsExceptionIfFrontendWasNotSet()
450  {
452  $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, ['dummy'], ['Testing']);
453  $backend->flushByTag([]);
454  }
455 
459  public function flushByTagRemovesCacheEntriesWithSpecifiedTag()
460  {
462  $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, ['dummy'], ['Testing']);
463  $this->setUpMockFrontendOfBackend($backend);
464 
465  $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, [], [], '', false);
466  $GLOBALS['TYPO3_DB']
467  ->expects($this->at(0))
468  ->method('fullQuoteStr')
469  ->will($this->returnValue('UnitTestTag%special'));
470  $GLOBALS['TYPO3_DB']
471  ->expects($this->at(1))
472  ->method('exec_SELECTquery')
473  ->with(
474  'DISTINCT identifier',
475  'cf_Testing_tags',
476  'cf_Testing_tags.tag = UnitTestTag%special'
477  );
478  $GLOBALS['TYPO3_DB']
479  ->expects($this->at(2))
480  ->method('sql_fetch_assoc')
481  ->will($this->returnValue(['identifier' => 'BackendDbTest1']));
482  $GLOBALS['TYPO3_DB']
483  ->expects($this->at(3))
484  ->method('fullQuoteStr')
485  ->with('BackendDbTest1', 'cf_Testing')
486  ->will($this->returnValue('BackendDbTest1'));
487  $GLOBALS['TYPO3_DB']
488  ->expects($this->at(4))
489  ->method('sql_fetch_assoc')
490  ->will($this->returnValue(['identifier' => 'BackendDbTest2']));
491  $GLOBALS['TYPO3_DB']
492  ->expects($this->at(5))
493  ->method('fullQuoteStr')
494  ->with('BackendDbTest2', 'cf_Testing')
495  ->will($this->returnValue('BackendDbTest2'));
496  $GLOBALS['TYPO3_DB']
497  ->expects($this->at(6))
498  ->method('sql_fetch_assoc')
499  ->will($this->returnValue(false));
500  $GLOBALS['TYPO3_DB']
501  ->expects($this->at(7))
502  ->method('sql_free_result')
503  ->will($this->returnValue(true));
504  $GLOBALS['TYPO3_DB']
505  ->expects($this->at(8))
506  ->method('exec_DELETEquery')
507  ->with('cf_Testing', 'identifier IN (BackendDbTest1, BackendDbTest2)');
508  $GLOBALS['TYPO3_DB']
509  ->expects($this->at(9))
510  ->method('exec_DELETEquery')
511  ->with('cf_Testing_tags', 'identifier IN (BackendDbTest1, BackendDbTest2)');
512 
513  $backend->flushByTag('UnitTestTag%special');
514  }
515 }
setUpMockFrontendOfBackend(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend $backend)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']