[BUGFIX] PHP 7.1 unit tests
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Database / DatabaseConnectionTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Unit\Database;
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 * Test case
19 *
20 */
21 class DatabaseConnectionTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
22 {
23 //////////////////////////////////////////////////
24 // Write/Read tests for charsets and binaries
25 //////////////////////////////////////////////////
26
27 /**
28 * @test
29 */
30 public function storedFullAsciiRangeCallsLinkObjectWithGivenData()
31 {
32 $binaryString = '';
33 for ($i = 0; $i < 256; $i++) {
34 $binaryString .= chr($i);
35 }
36
37 /** @var \TYPO3\CMS\Core\Database\DatabaseConnection|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface $subject */
38 $subject = $this->getAccessibleMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, array('fullQuoteStr'), array(), '', false);
39 $subject->_set('isConnected', true);
40 $subject
41 ->expects($this->any())
42 ->method('fullQuoteStr')
43 ->will($this->returnCallback(function ($data) {
44 return $data;
45 }));
46 $mysqliProphecy = $this->prophesize(\mysqli::class);
47 $mysqliProphecy->query('INSERT INTO aTable (fieldblob) VALUES (' . $binaryString . ')')
48 ->shouldBeCalled();
49 $subject->_set('link', $mysqliProphecy->reveal());
50
51 $subject->exec_INSERTquery('aTable', array('fieldblob' => $binaryString));
52 }
53
54 /**
55 * @test
56 */
57 public function storedGzipCompressedDataReturnsSameData()
58 {
59 $testStringWithBinary = @gzcompress('sdfkljer4587');
60
61 /** @var \TYPO3\CMS\Core\Database\DatabaseConnection|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface $subject */
62 $subject = $this->getAccessibleMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, array('fullQuoteStr'), array(), '', false);
63 $subject->_set('isConnected', true);
64 $subject
65 ->expects($this->any())
66 ->method('fullQuoteStr')
67 ->will($this->returnCallback(function ($data) {
68 return $data;
69 }));
70 $mysqliProphecy = $this->prophesize(\mysqli::class);
71 $mysqliProphecy->query('INSERT INTO aTable (fieldblob) VALUES (' . $testStringWithBinary . ')')
72 ->shouldBeCalled();
73 $subject->_set('link', $mysqliProphecy->reveal());
74
75 $subject->exec_INSERTquery('aTable', array('fieldblob' => $testStringWithBinary));
76 }
77
78 ////////////////////////////////
79 // Tests concerning listQuery
80 ////////////////////////////////
81
82 /**
83 * @test
84 * @see http://forge.typo3.org/issues/23253
85 */
86 public function listQueryWithIntegerCommaAsValue()
87 {
88 /** @var \TYPO3\CMS\Core\Database\DatabaseConnection|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface $subject */
89 $subject = $this->getAccessibleMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, array('quoteStr'), array(), '', false);
90 $subject->_set('isConnected', true);
91 $subject
92 ->expects($this->any())
93 ->method('quoteStr')
94 ->will($this->returnCallback(function ($data) {
95 return $data;
96 }));
97 // Note: 44 = ord(',')
98 $this->assertEquals($subject->listQuery('dummy', 44, 'table'), $subject->listQuery('dummy', '44', 'table'));
99 }
100
101 /**
102 * @test
103 * @expectedException \InvalidArgumentException
104 */
105 public function listQueryThrowsExceptionIfValueContainsComma()
106 {
107 /** @var \TYPO3\CMS\Core\Database\DatabaseConnection|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface $subject */
108 $subject = $this->getAccessibleMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, array('quoteStr'), array(), '', false);
109 $subject->_set('isConnected', true);
110 $subject->listQuery('aField', 'foo,bar', 'aTable');
111 }
112
113 ////////////////////////////////
114 // Tests concerning searchQuery
115 ////////////////////////////////
116
117 /**
118 * Data provider for searchQueryCreatesQuery
119 *
120 * @return array
121 */
122 public function searchQueryDataProvider()
123 {
124 return array(
125 'One search word in one field' => array(
126 '(pages.title LIKE \'%TYPO3%\')',
127 array('TYPO3'),
128 array('title'),
129 'pages',
130 'AND'
131 ),
132
133 'One search word with special chars (for like)' => array(
134 '(pages.title LIKE \'%TYPO3\\_100\\%%\')',
135 array('TYPO3_100%'),
136 array('title'),
137 'pages',
138 'AND'
139 ),
140
141 'One search word in multiple fields' => array(
142 '(pages.title LIKE \'%TYPO3%\' OR pages.keyword LIKE \'%TYPO3%\' OR pages.description LIKE \'%TYPO3%\')',
143 array('TYPO3'),
144 array('title', 'keyword', 'description'),
145 'pages',
146 'AND'
147 ),
148
149 'Multiple search words in one field with AND constraint' => array(
150 '(pages.title LIKE \'%TYPO3%\') AND (pages.title LIKE \'%is%\') AND (pages.title LIKE \'%great%\')',
151 array('TYPO3', 'is', 'great'),
152 array('title'),
153 'pages',
154 'AND'
155 ),
156
157 'Multiple search words in one field with OR constraint' => array(
158 '(pages.title LIKE \'%TYPO3%\') OR (pages.title LIKE \'%is%\') OR (pages.title LIKE \'%great%\')',
159 array('TYPO3', 'is', 'great'),
160 array('title'),
161 'pages',
162 'OR'
163 ),
164
165 'Multiple search words in multiple fields with AND constraint' => array(
166 '(pages.title LIKE \'%TYPO3%\' OR pages.keywords LIKE \'%TYPO3%\' OR pages.description LIKE \'%TYPO3%\') AND ' .
167 '(pages.title LIKE \'%is%\' OR pages.keywords LIKE \'%is%\' OR pages.description LIKE \'%is%\') AND ' .
168 '(pages.title LIKE \'%great%\' OR pages.keywords LIKE \'%great%\' OR pages.description LIKE \'%great%\')',
169 array('TYPO3', 'is', 'great'),
170 array('title', 'keywords', 'description'),
171 'pages',
172 'AND'
173 ),
174
175 'Multiple search words in multiple fields with OR constraint' => array(
176 '(pages.title LIKE \'%TYPO3%\' OR pages.keywords LIKE \'%TYPO3%\' OR pages.description LIKE \'%TYPO3%\') OR ' .
177 '(pages.title LIKE \'%is%\' OR pages.keywords LIKE \'%is%\' OR pages.description LIKE \'%is%\') OR ' .
178 '(pages.title LIKE \'%great%\' OR pages.keywords LIKE \'%great%\' OR pages.description LIKE \'%great%\')',
179 array('TYPO3', 'is', 'great'),
180 array('title', 'keywords', 'description'),
181 'pages',
182 'OR'
183 ),
184 );
185 }
186
187 /**
188 * @test
189 * @dataProvider searchQueryDataProvider
190 */
191 public function searchQueryCreatesQuery($expectedResult, $searchWords, $fields, $table, $constraint)
192 {
193 /** @var \TYPO3\CMS\Core\Database\DatabaseConnection|\PHPUnit_Framework_MockObject_MockObject $subject */
194 $subject = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, array('quoteStr'), array(), '', false);
195 $subject
196 ->expects($this->any())
197 ->method('quoteStr')
198 ->will($this->returnCallback(function ($data) {
199 return $data;
200 }));
201
202 $this->assertSame($expectedResult, $subject->searchQuery($searchWords, $fields, $table, $constraint));
203 }
204
205 /////////////////////////////////////////////////
206 // Tests concerning escapeStringForLikeComparison
207 /////////////////////////////////////////////////
208
209 /**
210 * @test
211 */
212 public function escapeStringForLikeComparison()
213 {
214 /** @var \TYPO3\CMS\Core\Database\DatabaseConnection|\PHPUnit_Framework_MockObject_MockObject $subject */
215 $subject = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, array('dummy'), array(), '', false);
216 $this->assertEquals('foo\\_bar\\%', $subject->escapeStrForLike('foo_bar%', 'table'));
217 }
218
219 /////////////////////////////////////////////////
220 // Tests concerning stripOrderByForOrderByKeyword
221 /////////////////////////////////////////////////
222
223 /**
224 * Data Provider for stripGroupByForGroupByKeyword()
225 *
226 * @see stripOrderByForOrderByKeyword()
227 * @return array
228 */
229 public function stripOrderByForOrderByKeywordDataProvider()
230 {
231 return array(
232 'single ORDER BY' => array('ORDER BY name, tstamp', 'name, tstamp'),
233 'single ORDER BY in lower case' => array('order by name, tstamp', 'name, tstamp'),
234 'ORDER BY with additional space behind' => array('ORDER BY name, tstamp', 'name, tstamp'),
235 'ORDER BY without space between the words' => array('ORDERBY name, tstamp', 'name, tstamp'),
236 'ORDER BY added twice' => array('ORDER BY ORDER BY name, tstamp', 'name, tstamp'),
237 'ORDER BY added twice without spaces in the first occurrence' => array('ORDERBY ORDER BY name, tstamp', 'name, tstamp'),
238 'ORDER BY added twice without spaces in the second occurrence' => array('ORDER BYORDERBY name, tstamp', 'name, tstamp'),
239 'ORDER BY added twice without spaces' => array('ORDERBYORDERBY name, tstamp', 'name, tstamp'),
240 'ORDER BY added twice without spaces afterwards' => array('ORDERBYORDERBYname, tstamp', 'name, tstamp'),
241 );
242 }
243
244 /**
245 * @test
246 * @dataProvider stripOrderByForOrderByKeywordDataProvider
247 * @param string $orderByClause The clause to test
248 * @param string $expectedResult The expected result
249 * @return void
250 */
251 public function stripOrderByForOrderByKeyword($orderByClause, $expectedResult)
252 {
253 /** @var \TYPO3\CMS\Core\Database\DatabaseConnection|\PHPUnit_Framework_MockObject_MockObject $subject */
254 $subject = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, array('dummy'), array(), '', false);
255 $strippedQuery = $subject->stripOrderBy($orderByClause);
256 $this->assertEquals($expectedResult, $strippedQuery);
257 }
258
259 /////////////////////////////////////////////////
260 // Tests concerning stripGroupByForGroupByKeyword
261 /////////////////////////////////////////////////
262
263 /**
264 * Data Provider for stripGroupByForGroupByKeyword()
265 *
266 * @see stripGroupByForGroupByKeyword()
267 * @return array
268 */
269 public function stripGroupByForGroupByKeywordDataProvider()
270 {
271 return array(
272 'single GROUP BY' => array('GROUP BY name, tstamp', 'name, tstamp'),
273 'single GROUP BY in lower case' => array('group by name, tstamp', 'name, tstamp'),
274 'GROUP BY with additional space behind' => array('GROUP BY name, tstamp', 'name, tstamp'),
275 'GROUP BY without space between the words' => array('GROUPBY name, tstamp', 'name, tstamp'),
276 'GROUP BY added twice' => array('GROUP BY GROUP BY name, tstamp', 'name, tstamp'),
277 'GROUP BY added twice without spaces in the first occurrence' => array('GROUPBY GROUP BY name, tstamp', 'name, tstamp'),
278 'GROUP BY added twice without spaces in the second occurrence' => array('GROUP BYGROUPBY name, tstamp', 'name, tstamp'),
279 'GROUP BY added twice without spaces' => array('GROUPBYGROUPBY name, tstamp', 'name, tstamp'),
280 'GROUP BY added twice without spaces afterwards' => array('GROUPBYGROUPBYname, tstamp', 'name, tstamp'),
281 );
282 }
283
284 /**
285 * @test
286 * @dataProvider stripGroupByForGroupByKeywordDataProvider
287 * @param string $groupByClause The clause to test
288 * @param string $expectedResult The expected result
289 * @return void
290 */
291 public function stripGroupByForGroupByKeyword($groupByClause, $expectedResult)
292 {
293 /** @var \TYPO3\CMS\Core\Database\DatabaseConnection|\PHPUnit_Framework_MockObject_MockObject $subject */
294 $subject = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, array('dummy'), array(), '', false);
295 $strippedQuery = $subject->stripGroupBy($groupByClause);
296 $this->assertEquals($expectedResult, $strippedQuery);
297 }
298
299 /////////////////////////////////////////////////
300 // Tests concerning stripOrderByForOrderByKeyword
301 /////////////////////////////////////////////////
302
303 /**
304 * Data Provider for stripGroupByForGroupByKeyword()
305 *
306 * @see stripOrderByForOrderByKeyword()
307 * @return array
308 */
309 public function cleanIntArrayDataProvider()
310 {
311 return array(
312 'simple array' => array(
313 array(1, 2, 3),
314 array(1, 2, 3)
315 ),
316 'string array' => array(
317 array('2', '4', '8'),
318 array(2, 4, 8)
319 ),
320 'string array with letters #1' => array(
321 array('3', '6letters', '12'),
322 array(3, 6, 12)
323 ),
324 'string array with letters #2' => array(
325 array('3', 'letters6', '12'),
326 array(3, 0, 12)
327 ),
328 'string array with letters #3' => array(
329 array('3', '6letters4', '12'),
330 array(3, 6, 12)
331 ),
332 'associative array' => array(
333 array('apples' => 3, 'bananas' => 4, 'kiwis' => 9),
334 array('apples' => 3, 'bananas' => 4, 'kiwis' => 9)
335 ),
336 'associative string array' => array(
337 array('apples' => '1', 'bananas' => '5', 'kiwis' => '7'),
338 array('apples' => 1, 'bananas' => 5, 'kiwis' => 7)
339 ),
340 'associative string array with letters #1' => array(
341 array('apples' => '1', 'bananas' => 'no5', 'kiwis' => '7'),
342 array('apples' => 1, 'bananas' => 0, 'kiwis' => 7)
343 ),
344 'associative string array with letters #2' => array(
345 array('apples' => '1', 'bananas' => '5yes', 'kiwis' => '7'),
346 array('apples' => 1, 'bananas' => 5, 'kiwis' => 7)
347 ),
348 'associative string array with letters #3' => array(
349 array('apples' => '1', 'bananas' => '5yes9', 'kiwis' => '7'),
350 array('apples' => 1, 'bananas' => 5, 'kiwis' => 7)
351 ),
352 'multidimensional associative array' => array(
353 array('apples' => '1', 'bananas' => array(3, 4), 'kiwis' => '7'),
354 // intval(array(...)) is 1
355 // But by specification "cleanIntArray" should only get used on one-dimensional arrays
356 array('apples' => 1, 'bananas' => 1, 'kiwis' => 7)
357 ),
358 );
359 }
360
361 /**
362 * @test
363 * @dataProvider cleanIntArrayDataProvider
364 * @param array $exampleData The array to sanitize
365 * @param array $expectedResult The expected result
366 * @return void
367 */
368 public function cleanIntArray($exampleData, $expectedResult)
369 {
370 /** @var \TYPO3\CMS\Core\Database\DatabaseConnection $subject */
371 $subject = new \TYPO3\CMS\Core\Database\DatabaseConnection();
372 $sanitizedArray = $subject->cleanIntArray($exampleData);
373 $this->assertEquals($expectedResult, $sanitizedArray);
374 }
375
376 /**
377 * @test
378 */
379 public function sqlForSelectMmQuery()
380 {
381 $subject = new \TYPO3\CMS\Core\Database\DatabaseConnection();
382 $result = $subject->SELECT_mm_query('*', 'sys_category', 'sys_category_record_mm', 'tt_content', 'AND sys_category.uid = 1', '', 'sys_category.title DESC');
383 $expected = 'SELECT * FROM sys_category,sys_category_record_mm,tt_content WHERE sys_category.uid=sys_category_record_mm.uid_local AND tt_content.uid=sys_category_record_mm.uid_foreign AND sys_category.uid = 1 ORDER BY sys_category.title DESC';
384 $this->assertEquals($expected, $result);
385 }
386 }