9fbd885ad7b0ed1c0397d961efdf12237388f585
[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 'empty string' => [
71 '',
72 [],
73 ],
74 'single field' => [
75 'aField',
76 [
77 ['aField', null],
78 ],
79 ],
80 'single field with leading whitespace' => [
81 ' aField',
82 [
83 ['aField', null],
84 ],
85 ],
86 'prefixed single field' => [
87 'ORDER BY aField',
88 [
89 ['aField', null],
90 ],
91 ],
92 'prefixed single field with leading whitespace' => [
93 ' ORDER BY aField',
94 [
95 ['aField', null],
96 ],
97 ],
98 'single field with direction' => [
99 'aField DESC',
100 [
101 ['aField', 'DESC'],
102 ],
103 ],
104 'multiple fields' => [
105 'aField,anotherField, aThirdField',
106 [
107 ['aField', null],
108 ['anotherField', null],
109 ['aThirdField', null]
110 ],
111 ],
112 'multiple fields with direction' => [
113 'aField ASC,anotherField, aThirdField DESC',
114 [
115 ['aField', 'ASC'],
116 ['anotherField', null],
117 ['aThirdField', 'DESC']
118 ],
119 ],
120 'prefixed multiple fields with direction' => [
121 'ORDER BY aField ASC,anotherField, aThirdField DESC',
122 [
123 ['aField', 'ASC'],
124 ['anotherField', null],
125 ['aThirdField', 'DESC']
126 ],
127 ],
128 'with table prefix' => [
129 'ORDER BY be_groups.title',
130 [
131 ['be_groups.title', null]
132 ]
133 ],
134 ];
135 }
136
137 /**
138 * @test
139 * @dataProvider parseOrderByDataProvider
140 * @param string $input
141 * @param array $expectedResult
142 */
143 public function parseOrderByTest(string $input, array $expectedResult)
144 {
145 $this->assertSame($expectedResult, QueryHelper::parseOrderBy($input));
146 }
147
148 /**
149 * Test cases for parsing FROM tableList SQL fragments
150 *
151 * @return array
152 */
153 public function parseTableListDataProvider(): array
154 {
155 return [
156 'single table' => [
157 'aTable',
158 [
159 ['aTable', null],
160 ],
161 ],
162 'single table with leading whitespace' => [
163 ' aTable',
164 [
165 ['aTable', null],
166 ],
167 ],
168 'prefixed single table' => [
169 'FROM aTable',
170 [
171 ['aTable', null],
172 ],
173 ],
174 'prefixed single table with leading whitespace' => [
175 ' FROM aTable',
176 [
177 ['aTable', null],
178 ],
179 ],
180 'single table with alias' => [
181 'aTable a',
182 [
183 ['aTable', 'a'],
184 ],
185 ],
186 'multiple tables' => [
187 'aTable,anotherTable, aThirdTable',
188 [
189 ['aTable', null],
190 ['anotherTable', null],
191 ['aThirdTable', null]
192 ],
193 ],
194 'multiple tables with aliases' => [
195 'aTable a,anotherTable, aThirdTable AS c',
196 [
197 ['aTable', 'a'],
198 ['anotherTable', null],
199 ['aThirdTable', 'c']
200 ],
201 ],
202 'prefixed multiple tables with aliases' => [
203 'FROM aTable a,anotherTable, aThirdTable AS c',
204 [
205 ['aTable', 'a'],
206 ['anotherTable', null],
207 ['aThirdTable', 'c']
208 ],
209 ]
210 ];
211 }
212
213 /**
214 * @test
215 * @dataProvider parseTableListDataProvider
216 * @param string $input
217 * @param array $expectedResult
218 */
219 public function parseTableListTest(string $input, array $expectedResult)
220 {
221 $this->assertSame($expectedResult, QueryHelper::parseTableList($input));
222 }
223
224 /**
225 * Test cases for parsing ORDER BY SQL fragments
226 *
227 * @return array
228 */
229 public function parseGroupByDataProvider(): array
230 {
231 return [
232 'single field' => [
233 'aField',
234 ['aField'],
235 ],
236 'single field with leading whitespace' => [
237 ' aField',
238 ['aField'],
239 ],
240 'prefixed single field' => [
241 'GROUP BY aField',
242 ['aField'],
243 ],
244 'prefixed single field with leading whitespace' => [
245 ' GROUP BY aField',
246 ['aField'],
247 ],
248 'multiple fields' => [
249 'aField,anotherField, aThirdField',
250 ['aField', 'anotherField', 'aThirdField']
251 ],
252 'prefixed multiple fields' => [
253 'GROUP BY aField,anotherField, aThirdField',
254 ['aField', 'anotherField', 'aThirdField']
255 ],
256 'with table prefix' => [
257 'GROUP BY be_groups.title',
258 ['be_groups.title']
259 ],
260 ];
261 }
262
263 /**
264 * @test
265 * @dataProvider parseGroupByDataProvider
266 * @param string $input
267 * @param array $expectedResult
268 */
269 public function parseGroupByTest(string $input, array $expectedResult)
270 {
271 $this->assertSame($expectedResult, QueryHelper::parseGroupBy($input));
272 }
273 }