‪TYPO3CMS  10.4
QueryHelperTest.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Prophecy\Argument;
23 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
24 
28 class ‪QueryHelperTest extends UnitTestCase
29 {
36  {
37  return [
38  'unprefixed input' => ['1=1', '1=1'],
39  'leading/trailing whitespace is removed' => [' 1=1 ', '1=1'],
40  'AND' => ['AND 1=1', '1=1'],
41  'AND with leading space' => [' AND 1=1', '1=1'],
42  'AND with mixed whitespace' => [' AND 1<>1', '1<>1'],
43  'AND with opening bracket' => ['AND (1=1)', '(1=1)'],
44  'AND without whitespace before bracket' => ['AND(1=1)', '(1=1)'],
45  'AND within input' => ['1=1 AND 2=2', '1=1 AND 2=2'],
46  'OR' => ['OR 1=1', '1=1'],
47  'OR with leading space' => [' OR 1=1', '1=1'],
48  'OR with mixed whitespace' => [' OR 1<>1', '1<>1'],
49  'OR with opening bracket' => ['OR (1=1)', '(1=1)'],
50  'OR without whitespace before bracket' => ['OR(1=1)', '(1=1)'],
51  'OR within input' => ['1=1 OR 2=2', '1=1 OR 2=2'],
52  ];
53  }
54 
61  public function ‪stripLogicalOperatorPrefixRemovesConstraintPrefixes(string $input, string $expectedSql): void
62  {
63  self::assertSame($expectedSql, ‪QueryHelper::stripLogicalOperatorPrefix($input));
64  }
65 
71  public function ‪parseOrderByDataProvider(): array
72  {
73  return [
74  'empty string' => [
75  '',
76  [],
77  ],
78  'single field' => [
79  'aField',
80  [
81  ['aField', null],
82  ],
83  ],
84  'single field with leading whitespace' => [
85  ' aField',
86  [
87  ['aField', null],
88  ],
89  ],
90  'prefixed single field' => [
91  'ORDER BY aField',
92  [
93  ['aField', null],
94  ],
95  ],
96  'prefixed single field with leading whitespace' => [
97  ' ORDER BY aField',
98  [
99  ['aField', null],
100  ],
101  ],
102  'single field with direction' => [
103  'aField DESC',
104  [
105  ['aField', 'DESC'],
106  ],
107  ],
108  'multiple fields' => [
109  'aField,anotherField, aThirdField',
110  [
111  ['aField', null],
112  ['anotherField', null],
113  ['aThirdField', null]
114  ],
115  ],
116  'multiple fields with direction' => [
117  'aField ASC,anotherField, aThirdField DESC',
118  [
119  ['aField', 'ASC'],
120  ['anotherField', null],
121  ['aThirdField', 'DESC']
122  ],
123  ],
124  'prefixed multiple fields with direction' => [
125  'ORDER BY aField ASC,anotherField, aThirdField DESC',
126  [
127  ['aField', 'ASC'],
128  ['anotherField', null],
129  ['aThirdField', 'DESC']
130  ],
131  ],
132  'with table prefix' => [
133  'ORDER BY be_groups.title',
134  [
135  ['be_groups.title', null]
136  ]
137  ],
138  ];
139  }
140 
147  public function ‪parseOrderByTest(string $input, array $expectedResult): void
148  {
149  self::assertSame($expectedResult, ‪QueryHelper::parseOrderBy($input));
150  }
151 
157  public function ‪parseTableListDataProvider(): array
158  {
159  return [
160  'single table' => [
161  'aTable',
162  [
163  ['aTable', null],
164  ],
165  ],
166  'single table with leading whitespace' => [
167  ' aTable',
168  [
169  ['aTable', null],
170  ],
171  ],
172  'prefixed single table' => [
173  'FROM aTable',
174  [
175  ['aTable', null],
176  ],
177  ],
178  'prefixed single table with leading whitespace' => [
179  ' FROM aTable',
180  [
181  ['aTable', null],
182  ],
183  ],
184  'single table with alias' => [
185  'aTable a',
186  [
187  ['aTable', 'a'],
188  ],
189  ],
190  'multiple tables' => [
191  'aTable,anotherTable, aThirdTable',
192  [
193  ['aTable', null],
194  ['anotherTable', null],
195  ['aThirdTable', null]
196  ],
197  ],
198  'multiple tables with aliases' => [
199  'aTable a,anotherTable, aThirdTable AS c',
200  [
201  ['aTable', 'a'],
202  ['anotherTable', null],
203  ['aThirdTable', 'c']
204  ],
205  ],
206  'prefixed multiple tables with aliases' => [
207  'FROM aTable a,anotherTable, aThirdTable AS c',
208  [
209  ['aTable', 'a'],
210  ['anotherTable', null],
211  ['aThirdTable', 'c']
212  ],
213  ]
214  ];
215  }
216 
223  public function ‪parseTableListTest(string $input, array $expectedResult): void
224  {
225  self::assertSame($expectedResult, ‪QueryHelper::parseTableList($input));
226  }
227 
233  public function ‪parseGroupByDataProvider(): array
234  {
235  return [
236  'single field' => [
237  'aField',
238  ['aField'],
239  ],
240  'single field with leading whitespace' => [
241  ' aField',
242  ['aField'],
243  ],
244  'prefixed single field' => [
245  'GROUP BY aField',
246  ['aField'],
247  ],
248  'prefixed single field with leading whitespace' => [
249  ' GROUP BY aField',
250  ['aField'],
251  ],
252  'multiple fields' => [
253  'aField,anotherField, aThirdField',
254  ['aField', 'anotherField', 'aThirdField']
255  ],
256  'prefixed multiple fields' => [
257  'GROUP BY aField,anotherField, aThirdField',
258  ['aField', 'anotherField', 'aThirdField']
259  ],
260  'with table prefix' => [
261  'GROUP BY be_groups.title',
262  ['be_groups.title']
263  ],
264  ];
265  }
266 
273  public function ‪parseGroupByTest(string $input, array $expectedResult): void
274  {
275  self::assertSame($expectedResult, ‪QueryHelper::parseGroupBy($input));
276  }
277 
283  public function ‪parseJoinDataProvider(): array
284  {
285  return [
286  'unquoted tableName' => [
287  'aTable ON aTable.uid = anotherTable.uid_foreign',
288  [
289  'tableName' => 'aTable',
290  'tableAlias' => 'aTable',
291  'joinCondition' => 'aTable.uid = anotherTable.uid_foreign'
292  ],
293  ],
294  'quoted tableName' => [
295  '`aTable` ON aTable.uid = anotherTable.uid_foreign',
296  [
297  'tableName' => 'aTable',
298  'tableAlias' => 'aTable',
299  'joinCondition' => 'aTable.uid = anotherTable.uid_foreign'
300  ],
301  ],
302  'quoted tableName with alias' => [
303  '`aTable` a ON a.uid = anotherTable.uid_foreign',
304  [
305  'tableName' => 'aTable',
306  'tableAlias' => 'a',
307  'joinCondition' => 'a.uid = anotherTable.uid_foreign'
308  ],
309  ],
310  'quoted tableName with quoted alias' => [
311  '`aTable` `a` ON a.uid = anotherTable.uid_foreign',
312  [
313  'tableName' => 'aTable',
314  'tableAlias' => 'a',
315  'joinCondition' => 'a.uid = anotherTable.uid_foreign'
316  ],
317  ],
318  'quoted tableName with AS alias' => [
319  '`aTable` AS anAlias ON anAlias.uid = anotherTable.uid_foreign',
320  [
321  'tableName' => 'aTable',
322  'tableAlias' => 'anAlias',
323  'joinCondition' => 'anAlias.uid = anotherTable.uid_foreign'
324  ],
325  ],
326  'quoted tableName with AS quoted alias' => [
327  '`aTable` AS `anAlias` ON anAlias.uid = anotherTable.uid_foreign',
328  [
329  'tableName' => 'aTable',
330  'tableAlias' => 'anAlias',
331  'joinCondition' => 'anAlias.uid = anotherTable.uid_foreign'
332  ],
333  ],
334  'unquoted tableName with AS quoted alias' => [
335  'aTable AS `anAlias` ON anAlias.uid = anotherTable.uid_foreign',
336  [
337  'tableName' => 'aTable',
338  'tableAlias' => 'anAlias',
339  'joinCondition' => 'anAlias.uid = anotherTable.uid_foreign'
340  ],
341  ],
342  ];
343  }
344 
351  public function ‪parseJoinSplitsStatement(string $input, array $expected): void
352  {
353  self::assertSame($expected, ‪QueryHelper::parseJoin($input));
354  }
355 
361  public function ‪quoteDatabaseIdentifierDataProvider(): array
362  {
363  return [
364  'no marked identifiers' => [
365  'colPos=0',
366  'colPos=0',
367  ],
368  'single fieldname' => [
369  '{#colPos}=0',
370  '"colPos"=0',
371  ],
372  'tablename and fieldname' => [
373  '{#tt_content.colPos}=0',
374  '"tt_content"."colPos"=0',
375  ],
376  'multiple fieldnames' => [
377  '{#colPos}={#aField}',
378  '"colPos"="aField"',
379  ],
380  ];
381  }
382 
389  public function ‪quoteDatabaseIdentifiers(string $input, string $expected): void
390  {
391  $connectionProphet = $this->prophesize(Connection::class);
392  $connectionProphet->quoteIdentifier(Argument::cetera())->will(function (‪$args) {
393  $parts = array_map(
394  function ($identifier) {
395  return '"' . $identifier . '"';
396  },
397  explode('.', ‪$args[0])
398  );
399 
400  return implode('.', $parts);
401  });
402 
403  self::assertSame($expected, ‪QueryHelper::quoteDatabaseIdentifiers($connectionProphet->reveal(), $input));
404  }
405 }
‪TYPO3\CMS\Core\Database\Query\QueryHelper\parseOrderBy
‪static array array[] parseOrderBy(string $input)
Definition: QueryHelper.php:44
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryHelperTest\parseJoinDataProvider
‪array parseJoinDataProvider()
Definition: QueryHelperTest.php:283
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryHelperTest\stripLogicalOperatorPrefixDataProvider
‪array stripLogicalOperatorPrefixDataProvider()
Definition: QueryHelperTest.php:35
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryHelperTest\parseOrderByTest
‪parseOrderByTest(string $input, array $expectedResult)
Definition: QueryHelperTest.php:147
‪TYPO3\CMS\Core\Database\Query\QueryHelper\parseTableList
‪static array array[] parseTableList(string $input)
Definition: QueryHelper.php:72
‪TYPO3\CMS\Core\Database\Query\QueryHelper\parseJoin
‪static array parseJoin(string $input)
Definition: QueryHelper.php:115
‪TYPO3\CMS\Core\Database\Query\QueryHelper\parseGroupBy
‪static array string[] parseGroupBy(string $input)
Definition: QueryHelper.php:102
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryHelperTest\parseJoinSplitsStatement
‪parseJoinSplitsStatement(string $input, array $expected)
Definition: QueryHelperTest.php:351
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryHelperTest\parseOrderByDataProvider
‪array parseOrderByDataProvider()
Definition: QueryHelperTest.php:71
‪TYPO3\CMS\Core\Database\Query\QueryHelper\quoteDatabaseIdentifiers
‪static string quoteDatabaseIdentifiers(Connection $connection, string $sql)
Definition: QueryHelper.php:219
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryHelperTest
Definition: QueryHelperTest.php:29
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryHelperTest\stripLogicalOperatorPrefixRemovesConstraintPrefixes
‪stripLogicalOperatorPrefixRemovesConstraintPrefixes(string $input, string $expectedSql)
Definition: QueryHelperTest.php:61
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryHelperTest\parseGroupByDataProvider
‪array parseGroupByDataProvider()
Definition: QueryHelperTest.php:233
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryHelperTest\parseTableListTest
‪parseTableListTest(string $input, array $expectedResult)
Definition: QueryHelperTest.php:223
‪TYPO3\CMS\Core\Database\Query\QueryHelper
Definition: QueryHelper.php:32
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryHelperTest\quoteDatabaseIdentifiers
‪quoteDatabaseIdentifiers(string $input, string $expected)
Definition: QueryHelperTest.php:389
‪$args
‪$args
Definition: validateRstFiles.php:214
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:36
‪TYPO3\CMS\Core\Database\Query\QueryHelper\stripLogicalOperatorPrefix
‪static string stripLogicalOperatorPrefix(string $constraint)
Definition: QueryHelper.php:165
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryHelperTest\parseTableListDataProvider
‪array parseTableListDataProvider()
Definition: QueryHelperTest.php:157
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryHelperTest\quoteDatabaseIdentifierDataProvider
‪array quoteDatabaseIdentifierDataProvider()
Definition: QueryHelperTest.php:361
‪TYPO3\CMS\Core\Tests\Unit\Database\Query
Definition: BulkInsertTest.php:18
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryHelperTest\parseGroupByTest
‪parseGroupByTest(string $input, array $expectedResult)
Definition: QueryHelperTest.php:273