[TASK] Provide QueryHelper to prepare SQL fragments for the QueryBuilder
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Database / Query / QueryHelperTest.php
1 <?php
2 declare (strict_types = 1);
3 namespace TYPO3\CMS\Core\Tests\Unit\Database\Query;
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
18 use TYPO3\CMS\Core\Database\Query\QueryHelper;
19 use TYPO3\CMS\Core\Tests\UnitTestCase;
20
21 /**
22 * Query helper test
23 */
24 class QueryHelperTest extends UnitTestCase
25 {
26 /**
27 * Test cases for stripping of leading logical operators in where constraints.
28 *
29 * @return array
30 */
31 public function stripLogicalOperatorPrefixDataProvider(): array
32 {
33 return [
34 'unprefixed input' => ['1=1', '1=1'],
35 'leading/trailing whitespace is removed' => [' 1=1 ', '1=1'],
36 'AND' => ['AND 1=1', '1=1'],
37 'AND with leading space' => [' AND 1=1', '1=1'],
38 'AND with mixed whitespace' => [' AND 1<>1', '1<>1'],
39 'AND with opening bracket' => ['AND (1=1)', '(1=1)'],
40 'AND without whitespace before bracket' => ['AND(1=1)', '(1=1)'],
41 'AND within input' => ['1=1 AND 2=2', '1=1 AND 2=2'],
42 'OR' => ['OR 1=1', '1=1'],
43 'OR with leading space' => [' OR 1=1', '1=1'],
44 'OR with mixed whitespace' => [' OR 1<>1', '1<>1'],
45 'OR with opening bracket' => ['OR (1=1)', '(1=1)'],
46 'OR without whitespace before bracket' => ['OR(1=1)', '(1=1)'],
47 'OR within input' => ['1=1 OR 2=2', '1=1 OR 2=2'],
48 ];
49 }
50
51 /**
52 * @test
53 * @dataProvider stripLogicalOperatorPrefixDataProvider
54 * @param string $input
55 * @param string $expectedSql
56 */
57 public function stripLogicalOperatorPrefixRemovesConstraintPrefixes(string $input, string $expectedSql)
58 {
59 $this->assertSame($expectedSql, QueryHelper::stripLogicalOperatorPrefix($input));
60 }
61
62 /**
63 * Test cases for parsing ORDER BY SQL fragments
64 *
65 * @return array
66 */
67 public function parseOrderByDataProvider(): array
68 {
69 return [
70 'single field' => [
71 'aField',
72 [
73 ['aField', null],
74 ],
75 ],
76 'single field with leading whitespace' => [
77 ' aField',
78 [
79 ['aField', null],
80 ],
81 ],
82 'prefixed single field' => [
83 'ORDER BY aField',
84 [
85 ['aField', null],
86 ],
87 ],
88 'prefixed single field with leading whitespace' => [
89 ' ORDER BY aField',
90 [
91 ['aField', null],
92 ],
93 ],
94 'single field with direction' => [
95 'aField DESC',
96 [
97 ['aField', 'DESC'],
98 ],
99 ],
100 'multiple fields' => [
101 'aField,anotherField, aThirdField',
102 [
103 ['aField', null],
104 ['anotherField', null],
105 ['aThirdField', null]
106 ],
107 ],
108 'multiple fields with direction' => [
109 'aField ASC,anotherField, aThirdField DESC',
110 [
111 ['aField', 'ASC'],
112 ['anotherField', null],
113 ['aThirdField', 'DESC']
114 ],
115 ],
116 'prefixed multiple fields with direction' => [
117 'ORDER BY aField ASC,anotherField, aThirdField DESC',
118 [
119 ['aField', 'ASC'],
120 ['anotherField', null],
121 ['aThirdField', 'DESC']
122 ],
123 ],
124 'with table prefix' => [
125 'ORDER BY be_groups.title',
126 [
127 ['be_groups.title', null]
128 ]
129 ],
130 ];
131 }
132
133 /**
134 * @test
135 * @dataProvider parseOrderByDataProvider
136 * @param string $input
137 * @param array $expectedResult
138 */
139 public function parseOrderByTest(string $input, array $expectedResult)
140 {
141 $this->assertSame($expectedResult, QueryHelper::parseOrderBy($input));
142 }
143
144 /**
145 * Test cases for parsing ORDER BY SQL fragments
146 *
147 * @return array
148 */
149 public function parseGroupByDataProvider(): array
150 {
151 return [
152 'single field' => [
153 'aField',
154 ['aField'],
155 ],
156 'single field with leading whitespace' => [
157 ' aField',
158 ['aField'],
159 ],
160 'prefixed single field' => [
161 'GROUP BY aField',
162 ['aField'],
163 ],
164 'prefixed single field with leading whitespace' => [
165 ' GROUP BY aField',
166 ['aField'],
167 ],
168 'multiple fields' => [
169 'aField,anotherField, aThirdField',
170 ['aField', 'anotherField', 'aThirdField']
171 ],
172 'prefixed multiple fields' => [
173 'GROUP BY aField,anotherField, aThirdField',
174 ['aField', 'anotherField', 'aThirdField']
175 ],
176 'with table prefix' => [
177 'GROUP BY be_groups.title',
178 ['be_groups.title']
179 ],
180 ];
181 }
182
183 /**
184 * @test
185 * @dataProvider parseGroupByDataProvider
186 * @param string $input
187 * @param array $expectedResult
188 */
189 public function parseGroupByTest(string $input, array $expectedResult)
190 {
191 $this->assertSame($expectedResult, QueryHelper::parseGroupBy($input));
192 }
193
194 }