bd34d205d8a5663ef09e8c9d7f175fe8b70fbd2c
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Tests / Unit / Persistence / Generic / Storage / Typo3DbQueryParserTest.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Tests\Unit\Persistence\Generic\Storage;
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 use Prophecy\Argument;
17 use TYPO3\CMS\Core\Database\Connection;
18 use TYPO3\CMS\Core\Database\ConnectionPool;
19 use TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder;
20 use TYPO3\CMS\Core\Database\Query\QueryBuilder;
21 use TYPO3\CMS\Core\Utility\GeneralUtility;
22 use TYPO3\CMS\Extbase\Persistence\Generic\Exception\InconsistentQuerySettingsException;
23 use TYPO3\CMS\Extbase\Persistence\Generic\Exception\UnsupportedOrderException;
24
25 class Typo3DbQueryParserTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
26 {
27 /**
28 * @var array
29 */
30 protected $singletonInstances;
31
32 /**
33 * Set up tests
34 */
35 protected function setUp()
36 {
37 parent::setUp();
38 $this->singletonInstances = GeneralUtility::getSingletonInstances();
39 }
40
41 /**
42 * Clean up after tests
43 */
44 protected function tearDown()
45 {
46 GeneralUtility::purgeInstances();
47 GeneralUtility::resetSingletonInstances($this->singletonInstances);
48 parent::tearDown();
49 }
50
51 /**
52 * @test
53 */
54 public function addSysLanguageStatementWorksForDefaultLanguage()
55 {
56 $table = $this->getUniqueId('tx_coretest_table');
57 $GLOBALS['TCA'][$table]['ctrl'] = array(
58 'languageField' => 'sys_language_uid'
59 );
60 /** @var \TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings|\PHPUnit_Framework_MockObject_MockObject $querySettings */
61 $querySettings = $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings::class);
62 $mockTypo3DbQueryParser = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser::class, array('dummy'), array(), '', false);
63 $sql = $mockTypo3DbQueryParser->_callRef('getSysLanguageStatement', $table, $table, $querySettings);
64 $expectedSql = '(' . $table . '.sys_language_uid IN (0,-1))';
65 $this->assertSame($expectedSql, $sql);
66 }
67
68 /**
69 * @test
70 */
71 public function addSysLanguageStatementWorksForNonDefaultLanguage()
72 {
73 $table = $this->getUniqueId('tx_coretest_table');
74 $GLOBALS['TCA'][$table]['ctrl'] = array(
75 'languageField' => 'sys_language_uid'
76 );
77 /** @var \TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings|\PHPUnit_Framework_MockObject_MockObject $querySettings */
78 $querySettings = $this->getMockBuilder(\TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings::class)
79 ->setMethods(array('dummy'))
80 ->getMock();
81 $querySettings->setLanguageUid('1');
82 $mockTypo3DbQueryParser = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser::class, array('dummy'), array(), '', false);
83 $sql = $mockTypo3DbQueryParser->_callRef('getSysLanguageStatement', $table, $table, $querySettings);
84 $result = '(' . $table . '.sys_language_uid IN (1,-1))';
85 $this->assertSame($result, $sql);
86 }
87
88 /**
89 * @test
90 */
91 public function addSysLanguageStatementWorksInBackendContextWithNoGlobalTypoScriptFrontendControllerAvailable()
92 {
93 $table = $this->getUniqueId('tx_coretest_table');
94 $GLOBALS['TCA'][$table]['ctrl'] = array(
95 'languageField' => 'sys_language_uid'
96 );
97 $querySettings = new \TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings();
98 $mockTypo3DbQueryParser = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser::class, array('dummy'), array(), '', false);
99 $sql = $mockTypo3DbQueryParser->_callRef('getSysLanguageStatement', $table, $table, $querySettings);
100 $expectedSql = '(' . $table . '.sys_language_uid IN (0,-1))';
101 $this->assertSame($expectedSql, $sql);
102 }
103
104 /**
105 * @test
106 */
107 public function addSysLanguageStatementWorksForDefaultLanguageWithoutDeleteStatementReturned()
108 {
109 $table = $this->getUniqueId('tx_coretest_table');
110 $GLOBALS['TCA'][$table]['ctrl'] = array(
111 'languageField' => 'sys_language_uid',
112 'delete' => 'deleted'
113 );
114 $querySettings = new \TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings();
115 $querySettings->setLanguageUid(0);
116 $mockTypo3DbQueryParser = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser::class, array('dummy'), array(), '', false);
117 $sql = $mockTypo3DbQueryParser->_callRef('getSysLanguageStatement', $table, $table, $querySettings);
118 $expectedSql = '(' . $table . '.sys_language_uid IN (0,-1))';
119 $this->assertSame($expectedSql, $sql);
120 }
121
122 /**
123 * @test
124 */
125 public function addSysLanguageStatementWorksForForeignLanguageWithoutSubselection()
126 {
127 $table = $this->getUniqueId('tx_coretest_table');
128 $GLOBALS['TCA'][$table]['ctrl'] = array(
129 'languageField' => 'sys_language_uid'
130 );
131 $querySettings = new \TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings();
132 $querySettings->setLanguageUid(2);
133 $mockTypo3DbQueryParser = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser::class, array('dummy'), array(), '', false);
134 $sql = $mockTypo3DbQueryParser->_callRef('getSysLanguageStatement', $table, $table, $querySettings);
135 $expectedSql = '(' . $table . '.sys_language_uid IN (2,-1))';
136 $this->assertSame($expectedSql, $sql);
137 }
138
139 /**
140 * @test
141 */
142 public function addSysLanguageStatementWorksForForeignLanguageWithSubselectionWithoutDeleteStatementReturned()
143 {
144 $table = $this->getUniqueId('tx_coretest_table');
145 $GLOBALS['TCA'][$table]['ctrl'] = array(
146 'languageField' => 'sys_language_uid',
147 'transOrigPointerField' => 'l10n_parent'
148 );
149 $querySettings = new \TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings();
150 $querySettings->setLanguageUid(2);
151 $mockTypo3DbQueryParser = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser::class, array('dummy'), array(), '', false);
152 $sql = $mockTypo3DbQueryParser->_callRef('getSysLanguageStatement', $table, $table, $querySettings);
153 $expectedSql = '(' . $table . '.sys_language_uid IN (2,-1) OR (' . $table . '.sys_language_uid=0 AND ' . $table . '.uid NOT IN (SELECT ' . $table . '.l10n_parent FROM ' . $table . ' WHERE ' . $table . '.l10n_parent>0 AND ' . $table . '.sys_language_uid=2)))';
154 $this->assertSame($expectedSql, $sql);
155 }
156
157 /**
158 * @test
159 */
160 public function addSysLanguageStatementWorksForForeignLanguageWithSubselectionTakesDeleteStatementIntoAccountIfNecessary()
161 {
162 $table = $this->getUniqueId('tx_coretest_table');
163 $GLOBALS['TCA'][$table]['ctrl'] = array(
164 'languageField' => 'sys_language_uid',
165 'transOrigPointerField' => 'l10n_parent',
166 'delete' => 'deleted'
167 );
168 $querySettings = new \TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings();
169 $querySettings->setLanguageUid(2);
170 $mockTypo3DbQueryParser = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser::class, array('dummy'), array(), '', false);
171 $sql= $mockTypo3DbQueryParser->_callRef('getSysLanguageStatement', $table, $table, $querySettings);
172 $expectedSql = '(' . $table . '.sys_language_uid IN (2,-1)' .
173 ' OR (' . $table . '.sys_language_uid=0 AND ' . $table . '.uid NOT IN (' .
174 'SELECT ' . $table . '.l10n_parent FROM ' . $table .
175 ' WHERE ' . $table . '.l10n_parent>0 AND ' .
176 $table . '.sys_language_uid=2 AND ' .
177 $table . '.deleted=0)))';
178 $this->assertSame($expectedSql, $sql);
179 }
180
181 /**
182 * @test
183 */
184 public function addSysLanguageStatementWorksInBackendContextWithSubselectionTakesDeleteStatementIntoAccountIfNecessary()
185 {
186 $table = 'tt_content';
187 $GLOBALS['TCA'][$table]['ctrl'] = array(
188 'languageField' => 'sys_language_uid',
189 'transOrigPointerField' => 'l10n_parent',
190 'delete' => 'deleted'
191 );
192 $querySettings = new \TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings();
193 $querySettings->setLanguageUid(2);
194 $mockTypo3DbQueryParser = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser::class, array('dummy'), array(), '', false);
195 $sql = $mockTypo3DbQueryParser->_callRef('getSysLanguageStatement', $table, $table, $querySettings);
196 $expectedSql = '(' . $table . '.sys_language_uid IN (2,-1)' .
197 ' OR (' . $table . '.sys_language_uid=0 AND ' . $table . '.uid NOT IN (' .
198 'SELECT ' . $table . '.l10n_parent FROM ' . $table .
199 ' WHERE ' . $table . '.l10n_parent>0 AND ' .
200 $table . '.sys_language_uid=2 AND ' .
201 $table . '.deleted=0)))';
202 $this->assertSame($expectedSql, $sql);
203 }
204
205 /**
206 * @test
207 */
208 public function orderStatementGenerationWorks()
209 {
210 $mockSource = $this->getMockBuilder(\TYPO3\CMS\Extbase\Persistence\Generic\Qom\Selector::class)
211 ->setMethods(array('getNodeTypeName'))
212 ->disableOriginalConstructor()
213 ->getMock();
214 $mockSource->expects($this->any())->method('getNodeTypeName')->will($this->returnValue('Tx_MyExt_ClassName'));
215 $mockDataMapper = $this->getMockBuilder(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper::class)
216 ->setMethods(array('convertPropertyNameToColumnName', 'convertClassNameToTableName'))
217 ->disableOriginalConstructor()
218 ->getMock();
219 $mockDataMapper->expects($this->once())->method('convertClassNameToTableName')->with('Tx_MyExt_ClassName')->will($this->returnValue('tx_myext_tablename'));
220 $mockDataMapper->expects($this->once())->method('convertPropertyNameToColumnName')->with('fooProperty', 'Tx_MyExt_ClassName')->will($this->returnValue('converted_fieldname'));
221 $sql = array();
222 $orderings = array('fooProperty' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING);
223 $mockTypo3DbQueryParser = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser::class, array('dummy'), array(), '', false);
224 $mockTypo3DbQueryParser->_set('dataMapper', $mockDataMapper);
225 $mockTypo3DbQueryParser->_callRef('parseOrderings', $orderings, $mockSource, $sql);
226 $expectedSql = array('orderings' => array('tx_myext_tablename.converted_fieldname ASC'));
227 $this->assertSame($expectedSql, $sql);
228 }
229
230 /**
231 * @test
232 */
233 public function orderStatementGenerationThrowsExceptionOnUnsupportedOrder()
234 {
235 $this->expectException(UnsupportedOrderException::class);
236 $this->expectExceptionCode(1242816074);
237 $mockSource = $this->getMockBuilder(\TYPO3\CMS\Extbase\Persistence\Generic\Qom\Selector::class)
238 ->setMethods(array('getNodeTypeName'))
239 ->disableOriginalConstructor()
240 ->getMock();
241 $mockSource->expects($this->never())->method('getNodeTypeName');
242 $mockDataMapper = $this->getMockBuilder(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper::class)
243 ->setMethods(array('convertPropertyNameToColumnName', 'convertClassNameToTableName'))
244 ->disableOriginalConstructor()
245 ->getMock();
246 $mockDataMapper->expects($this->never())->method('convertClassNameToTableName');
247 $mockDataMapper->expects($this->never())->method('convertPropertyNameToColumnName');
248 $sql = array();
249 $orderings = array('fooProperty' => 'unsupported_order');
250 $mockTypo3DbQueryParser = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser::class, array('dummy'), array(), '', false);
251 $mockTypo3DbQueryParser->_set('dataMapper', $mockDataMapper);
252 $mockTypo3DbQueryParser->_callRef('parseOrderings', $orderings, $mockSource, $sql);
253 }
254
255 /**
256 * @test
257 */
258 public function orderStatementGenerationWorksWithMultipleOrderings()
259 {
260 $mockSource = $this->getMockBuilder(\TYPO3\CMS\Extbase\Persistence\Generic\Qom\Selector::class)
261 ->setMethods(array('getNodeTypeName'))
262 ->disableOriginalConstructor()
263 ->getMock();
264 $mockSource->expects($this->any())->method('getNodeTypeName')->will($this->returnValue('Tx_MyExt_ClassName'));
265 $mockDataMapper = $this->getMockBuilder(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper::class)
266 ->setMethods(array('convertPropertyNameToColumnName', 'convertClassNameToTableName'))
267 ->disableOriginalConstructor()
268 ->getMock();
269 $mockDataMapper->expects($this->any())->method('convertClassNameToTableName')->with('Tx_MyExt_ClassName')->will($this->returnValue('tx_myext_tablename'));
270 $mockDataMapper->expects($this->any())->method('convertPropertyNameToColumnName')->will($this->returnValue('converted_fieldname'));
271 $sql = array();
272 $orderings = array(
273 'fooProperty' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING,
274 'barProperty' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING
275 );
276 $mockTypo3DbQueryParser = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser::class, array('dummy'), array(), '', false);
277 $mockTypo3DbQueryParser->_set('dataMapper', $mockDataMapper);
278 $mockTypo3DbQueryParser->_callRef('parseOrderings', $orderings, $mockSource, $sql);
279 $expectedSql = array('orderings' => array('tx_myext_tablename.converted_fieldname ASC', 'tx_myext_tablename.converted_fieldname DESC'));
280 $this->assertSame($expectedSql, $sql);
281 }
282
283 public function providerForVisibilityConstraintStatement()
284 {
285 return array(
286 'in be: include all' => array('BE', true, array(), true, ''),
287 'in be: ignore enable fields but do not include deleted' => array('BE', true, array(), false, 'tx_foo_table.deleted_column = 0'),
288 'in be: respect enable fields but include deleted' => array('BE', false, array(), true, 'tx_foo_table.disabled_column=0 AND (tx_foo_table.starttime_column<=123456789)'),
289 'in be: respect enable fields and do not include deleted' => array('BE', false, array(), false, 'tx_foo_table.disabled_column=0 AND (tx_foo_table.starttime_column<=123456789) AND tx_foo_table.deleted_column = 0'),
290 'in fe: include all' => array('FE', true, array(), true, ''),
291 'in fe: ignore enable fields but do not include deleted' => array('FE', true, array(), false, 'tx_foo_table.deleted_column=0'),
292 'in fe: ignore only starttime and do not include deleted' => array('FE', true, array('starttime'), false, 'tx_foo_table.deleted_column=0 AND tx_foo_table.disabled_column=0'),
293 'in fe: respect enable fields and do not include deleted' => array('FE', false, array(), false, 'tx_foo_table.deleted_column=0 AND tx_foo_table.disabled_column=0 AND tx_foo_table.starttime_column<=123456789')
294 );
295 }
296
297 /**
298 * @test
299 * @dataProvider providerForVisibilityConstraintStatement
300 */
301 public function visibilityConstraintStatementIsGeneratedAccordingToTheQuerySettings($mode, $ignoreEnableFields, $enableFieldsToBeIgnored, $deletedValue, $expectedSql)
302 {
303 $tableName = 'tx_foo_table';
304 $GLOBALS['TCA'][$tableName]['ctrl'] = array(
305 'enablecolumns' => array(
306 'disabled' => 'disabled_column',
307 'starttime' => 'starttime_column'
308 ),
309 'delete' => 'deleted_column'
310 );
311 $GLOBALS['TSFE'] = new \stdClass();
312 $GLOBALS['TSFE']->sys_page = new \TYPO3\CMS\Frontend\Page\PageRepository();
313 $GLOBALS['SIM_ACCESS_TIME'] = 123456789;
314
315 $connectionProphet = $this->prophesize(Connection::class);
316 $connectionProphet->quoteIdentifier(Argument::cetera())->willReturnArgument(0);
317
318 $queryBuilderProphet = $this->prophesize(QueryBuilder::class);
319 $queryBuilderProphet->expr()->willReturn(
320 GeneralUtility::makeInstance(ExpressionBuilder::class, $connectionProphet->reveal())
321 );
322
323 $connectionPoolProphet = $this->prophesize(ConnectionPool::class);
324 $connectionPoolProphet->getQueryBuilderForTable($tableName)->willReturn($queryBuilderProphet->reveal());
325 GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolProphet->reveal());
326
327 $mockQuerySettings = $this->getMockBuilder(\TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings::class)
328 ->setMethods(array('getIgnoreEnableFields', 'getEnableFieldsToBeIgnored', 'getIncludeDeleted'))
329 ->disableOriginalConstructor()
330 ->getMock();
331 $mockQuerySettings->expects($this->once())->method('getIgnoreEnableFields')->will($this->returnValue($ignoreEnableFields));
332 $mockQuerySettings->expects($this->once())->method('getEnableFieldsToBeIgnored')->will($this->returnValue($enableFieldsToBeIgnored));
333 $mockQuerySettings->expects($this->once())->method('getIncludeDeleted')->will($this->returnValue($deletedValue));
334
335 /** @var $mockEnvironmentService \TYPO3\CMS\Extbase\Service\EnvironmentService | \PHPUnit_Framework_MockObject_MockObject */
336 $mockEnvironmentService = $this->getMockBuilder(\TYPO3\CMS\Extbase\Service\EnvironmentService::class)
337 ->setMethods(array('isEnvironmentInFrontendMode'))
338 ->getMock();
339 $mockEnvironmentService->expects($this->any())->method('isEnvironmentInFrontendMode')->will($this->returnValue($mode == 'FE'));
340
341 $mockTypo3DbQueryParser = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser::class, array('dummy'), array(), '', false);
342 $mockTypo3DbQueryParser->_set('environmentService', $mockEnvironmentService);
343 $resultSql = $mockTypo3DbQueryParser->_callRef('getVisibilityConstraintStatement', $mockQuerySettings, $tableName, $tableName);
344 $this->assertSame($expectedSql, $resultSql);
345 unset($GLOBALS['TCA'][$tableName]);
346 }
347
348 public function providerForRespectEnableFields()
349 {
350 return array(
351 'in be: respectEnableFields=false' => array('BE', false, ''),
352 'in be: respectEnableFields=true' => array('BE', true, 'tx_foo_table.disabled_column=0 AND (tx_foo_table.starttime_column<=123456789) AND tx_foo_table.deleted_column = 0'),
353 'in FE: respectEnableFields=false' => array('FE', false, ''),
354 'in FE: respectEnableFields=true' => array('FE', true, 'tx_foo_table.deleted_column=0 AND tx_foo_table.disabled_column=0 AND tx_foo_table.starttime_column<=123456789')
355 );
356 }
357
358 /**
359 * @test
360 * @dataProvider providerForRespectEnableFields
361 */
362 public function respectEnableFieldsSettingGeneratesCorrectStatement($mode, $respectEnableFields, $expectedSql)
363 {
364 $tableName = 'tx_foo_table';
365 $GLOBALS['TCA'][$tableName]['ctrl'] = array(
366 'enablecolumns' => array(
367 'disabled' => 'disabled_column',
368 'starttime' => 'starttime_column'
369 ),
370 'delete' => 'deleted_column'
371 );
372 $GLOBALS['TSFE'] = new \stdClass();
373 $GLOBALS['TSFE']->sys_page = new \TYPO3\CMS\Frontend\Page\PageRepository();
374 $GLOBALS['SIM_ACCESS_TIME'] = 123456789;
375
376 $connectionProphet = $this->prophesize(Connection::class);
377 $connectionProphet->quoteIdentifier(Argument::cetera())->willReturnArgument(0);
378
379 $queryBuilderProphet = $this->prophesize(QueryBuilder::class);
380 $queryBuilderProphet->expr()->willReturn(
381 GeneralUtility::makeInstance(ExpressionBuilder::class, $connectionProphet->reveal())
382 );
383
384 $connectionPoolProphet = $this->prophesize(ConnectionPool::class);
385 $connectionPoolProphet->getQueryBuilderForTable($tableName)->willReturn($queryBuilderProphet->reveal());
386 GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolProphet->reveal());
387
388 /** @var \TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings $mockQuerySettings */
389 $mockQuerySettings = $this->getMockBuilder(\TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings::class)
390 ->setMethods(array('dummy'))
391 ->disableOriginalConstructor()
392 ->getMock();
393 $mockQuerySettings->setIgnoreEnableFields(!$respectEnableFields);
394 $mockQuerySettings->setIncludeDeleted(!$respectEnableFields);
395
396 /** @var $mockEnvironmentService \TYPO3\CMS\Extbase\Service\EnvironmentService | \PHPUnit_Framework_MockObject_MockObject */
397 $mockEnvironmentService = $this->getMockBuilder(\TYPO3\CMS\Extbase\Service\EnvironmentService::class)
398 ->setMethods(array('isEnvironmentInFrontendMode'))
399 ->getMock();
400 $mockEnvironmentService->expects($this->any())->method('isEnvironmentInFrontendMode')->will($this->returnValue($mode == 'FE'));
401
402 $mockTypo3DbQueryParser = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser::class, array('dummy'), array(), '', false);
403 $mockTypo3DbQueryParser->_set('environmentService', $mockEnvironmentService);
404 $actualSql = $mockTypo3DbQueryParser->_callRef('getVisibilityConstraintStatement', $mockQuerySettings, $tableName, $tableName);
405 $this->assertSame($expectedSql, $actualSql);
406 unset($GLOBALS['TCA'][$tableName]);
407 }
408
409 /**
410 * @test
411 */
412 public function visibilityConstraintStatementGenerationThrowsExceptionIfTheQuerySettingsAreInconsistent()
413 {
414 $this->expectException(InconsistentQuerySettingsException::class);
415 $this->expectExceptionCode(1460975922);
416 $tableName = 'tx_foo_table';
417 $GLOBALS['TCA'][$tableName]['ctrl'] = array(
418 'enablecolumns' => array(
419 'disabled' => 'disabled_column'
420 ),
421 'delete' => 'deleted_column'
422 );
423 $mockQuerySettings = $this->getMockBuilder(\TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings::class)
424 ->setMethods(array('getIgnoreEnableFields', 'getEnableFieldsToBeIgnored', 'getIncludeDeleted'))
425 ->disableOriginalConstructor()
426 ->getMock();
427 $mockQuerySettings->expects($this->once())->method('getIgnoreEnableFields')->will($this->returnValue(false));
428 $mockQuerySettings->expects($this->once())->method('getEnableFieldsToBeIgnored')->will($this->returnValue(array()));
429 $mockQuerySettings->expects($this->once())->method('getIncludeDeleted')->will($this->returnValue(true));
430
431 /** @var $mockEnvironmentService \TYPO3\CMS\Extbase\Service\EnvironmentService | \PHPUnit_Framework_MockObject_MockObject */
432 $mockEnvironmentService = $this->getMockBuilder(\TYPO3\CMS\Extbase\Service\EnvironmentService::class)
433 ->setMethods(array('isEnvironmentInFrontendMode'))
434 ->getMock();
435 $mockEnvironmentService->expects($this->any())->method('isEnvironmentInFrontendMode')->will($this->returnValue(true));
436
437 $mockTypo3DbQueryParser = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser::class, array('dummy'), array(), '', false);
438 $mockTypo3DbQueryParser->_set('environmentService', $mockEnvironmentService);
439 $mockTypo3DbQueryParser->_callRef('getVisibilityConstraintStatement', $mockQuerySettings, $tableName, $tableName);
440 unset($GLOBALS['TCA'][$tableName]);
441 }
442
443 /**
444 * DataProvider for addPageIdStatement Tests
445 */
446 public function providerForAddPageIdStatementData()
447 {
448 $table = $this->getUniqueId('tx_coretest_table');
449 return array(
450 'set Pid to zero if rootLevel = 1' => array(
451 '1',
452 $table,
453 $table . '.pid = 0'
454 ),
455 'set Pid to given Pids if rootLevel = 0' => array(
456 '0',
457 $table,
458 $table . '.pid IN (42,27)'
459 ),
460 'add 0 to given Pids if rootLevel = -1' => array(
461 '-1',
462 $table,
463 $table . '.pid IN (42,27,0)'
464 ),
465 'set Pid to zero if rootLevel = -1 and no further pids given' => array(
466 '-1',
467 $table,
468 $table . '.pid = 0',
469 array()
470 ),
471 'set no statement for invalid configuration' => array(
472 '2',
473 $table,
474 ''
475 )
476 );
477 }
478
479 /**
480 * @test
481 * @dataProvider providerForAddPageIdStatementData
482 */
483 public function addPageIdStatementSetsPidToZeroIfTableDeclaresRootlevel($rootLevel, $table, $expectedSql, $storagePageIds = array(42, 27))
484 {
485 $GLOBALS['TCA'][$table]['ctrl'] = array(
486 'rootLevel' => $rootLevel
487 );
488 $mockTypo3DbQueryParser = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser::class, array('dummy'), array(), '', false);
489 $sql = $mockTypo3DbQueryParser->_callRef('getPageIdStatement', $table, $table, $storagePageIds);
490
491 $this->assertSame($expectedSql, $sql);
492 }
493 }