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