[BUGFIX] Introduce exception for using offset without limit
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Tests / Unit / Persistence / Generic / Storage / Typo3DbBackendTest.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
17 use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper;
18 use TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface;
19 use TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend;
20 use TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser;
21 use TYPO3\CMS\Extbase\Persistence\QueryInterface;
22
23 /**
24 * Test case
25 */
26 class Typo3DbBackendTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
27 {
28 /**
29 * @var DataMapper
30 */
31 protected static $dataMapper;
32
33 /**
34 * Setup DataMapper
35 */
36 public static function setUpBeforeClass()
37 {
38 self::$dataMapper = new DataMapper();
39 }
40
41 /**
42 * @test
43 */
44 public function uidOfAlreadyPersistedValueObjectIsDeterminedCorrectly()
45 {
46 $mockValueObject = $this->getMock(\TYPO3\CMS\Extbase\DomainObject\AbstractValueObject::class, array('_getProperties'), array(), '', false);
47 $mockValueObject->expects($this->once())->method('_getProperties')->will($this->returnValue(array('propertyName' => 'propertyValue')));
48 $mockColumnMap = $this->getMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMap::class, array('isPersistableProperty', 'getColumnName'), array(), '', false);
49 $mockColumnMap->expects($this->any())->method('getColumnName')->will($this->returnValue('column_name'));
50 $tableName = 'tx_foo_table';
51 $mockDataMap = $this->getMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMap::class, array('isPersistableProperty', 'getColumnMap', 'getTableName'), array(), '', false);
52 $mockDataMap->expects($this->any())->method('isPersistableProperty')->will($this->returnValue(true));
53 $mockDataMap->expects($this->any())->method('getColumnMap')->will($this->returnValue($mockColumnMap));
54 $mockDataMap->expects($this->any())->method('getTableName')->will($this->returnValue($tableName));
55 $mockDataMapper = $this->getMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper::class, array('getDataMap', 'getPlainValue'), array(), '', false);
56 $mockDataMapper->expects($this->once())->method('getDataMap')->will($this->returnValue($mockDataMap));
57 $mockDataMapper->expects($this->once())->method('getPlainValue')->will($this->returnValue('plainPropertyValue'));
58 $expectedStatement = 'SELECT * FROM tx_foo_table WHERE column_name=?';
59 $expectedParameters = array('plainPropertyValue');
60 $expectedUid = 52;
61 $mockDataBaseHandle = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, array('sql_query', 'sql_fetch_assoc'), array(), '', false);
62 $mockDataBaseHandle->expects($this->once())->method('sql_query')->will($this->returnValue('resource'));
63 $mockDataBaseHandle->expects($this->any())->method('sql_fetch_assoc')->with('resource')->will($this->returnValue(array('uid' => $expectedUid)));
64 $mockTypo3DbBackend = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend::class, array('checkSqlErrors', 'replacePlaceholders', 'addVisibilityConstraintStatement'), array(), '', false);
65 $mockTypo3DbBackend->expects($this->once())->method('addVisibilityConstraintStatement')->with($this->isInstanceOf(\TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface::class), $tableName, $this->isType('array'));
66 $mockTypo3DbBackend->expects($this->once())->method('replacePlaceholders')->with($expectedStatement, $expectedParameters);
67 $mockTypo3DbBackend->_set('dataMapper', $mockDataMapper);
68 $mockTypo3DbBackend->_set('databaseHandle', $mockDataBaseHandle);
69 $result = $mockTypo3DbBackend->_callRef('getUidOfAlreadyPersistedValueObject', $mockValueObject);
70 $this->assertSame($expectedUid, $result);
71 }
72
73 /**
74 * @test
75 */
76 public function doLanguageAndWorkspaceOverlayChangesUidIfInPreview()
77 {
78 $comparisonRow = array(
79 'uid' => '42',
80 'pid' => '42',
81 '_ORIG_pid' => '-1',
82 '_ORIG_uid' => '43'
83 );
84 $row = array(
85 'uid' => '42',
86 'pid' => '42'
87 );
88 $workspaceVersion = array(
89 'uid' => '43',
90 'pid' => '-1'
91 );
92 /** @var \TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings|\PHPUnit_Framework_MockObject_MockObject $querySettings */
93 $mockQuerySettings = $this->getMock(\TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings::class, array('dummy'), array(), '', false);
94
95 $workspaceUid = 2;
96 $sourceMock = new \TYPO3\CMS\Extbase\Persistence\Generic\Qom\Selector('tx_foo', 'Tx_Foo');
97 /** @var $pageRepositoryMock \TYPO3\CMS\Frontend\Page\PageRepository|\PHPUnit_Framework_MockObject_MockObject */
98 $pageRepositoryMock = $this->getMock(\TYPO3\CMS\Frontend\Page\PageRepository::class, array('movePlhOL', 'getWorkspaceVersionOfRecord'));
99 $pageRepositoryMock->versioningPreview = true;
100 $pageRepositoryMock->expects($this->once())->method('getWorkspaceVersionOfRecord')->with($workspaceUid, 'tx_foo', '42')->will($this->returnValue($workspaceVersion));
101 $mockTypo3DbBackend = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend::class, array('dummy'), array(), '', false);
102 $mockTypo3DbBackend->_set('pageRepository', $pageRepositoryMock);
103 $this->assertSame(array($comparisonRow), $mockTypo3DbBackend->_call('doLanguageAndWorkspaceOverlay', $sourceMock, array($row), $mockQuerySettings, $workspaceUid));
104 }
105
106 /**
107 * @return array
108 */
109 public function resolveParameterPlaceholdersReplacesValuesDataProvider()
110 {
111 return array(
112 'string' => array('bar', '123', '123'),
113 'array' => array('bar', array(1,2,3), '1,2,3'),
114 );
115 }
116
117 /**
118 * @param $parameter
119 * @param $value
120 * @param $expected
121 * @test
122 * @dataProvider resolveParameterPlaceholdersReplacesValuesDataProvider
123 */
124 public function resolveParameterPlaceholdersReplacesValues($parameter, $value, $expected)
125 {
126 $mock = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend::class, array('quoteTextValueCallback'));
127 $mock->expects($this->any())->method('quoteTextValueCallback')->will($this->returnArgument(0));
128 $mock->_set('dataMapper', self::$dataMapper);
129 $stmtParts = array('tables' => array('foo'), 'where' => $parameter);
130 $parameters = array($parameter => $value);
131 $result = $mock->_call('resolveParameterPlaceholders', $stmtParts, $parameters);
132 $this->assertSame($expected, $result['where']);
133 }
134
135 /**
136 * @test
137 * @return void
138 */
139 public function getObjectCountByQueryThrowsExceptionIfOffsetWithoutLimitIsUsed()
140 {
141 $querySettingsProphecy = $this->prophesize(QuerySettingsInterface::class);
142 $queryInterfaceProphecy = $this->prophesize(QueryInterface::class);
143 $queryParserProphecy = $this->prophesize(Typo3DbQueryParser::class);
144 $queryParserProphecy->preparseQuery($queryInterfaceProphecy->reveal())->willReturn([123, []]);
145 $queryParserProphecy->parseQuery($queryInterfaceProphecy->reveal())->willReturn(
146 ['tables' => ['tt_content']]
147 );
148 $queryParserProphecy->addDynamicQueryParts(\Prophecy\Argument::cetera())->willReturn();
149 $queryInterfaceProphecy->getQuerySettings()->willReturn($querySettingsProphecy->reveal());
150 $queryInterfaceProphecy->getConstraint()->willReturn();
151 $queryInterfaceProphecy->getLimit()->willReturn();
152 $queryInterfaceProphecy->getOffset()->willReturn(10);
153
154 $this->expectException(\InvalidArgumentException::class);
155 $this->expectExceptionCode(1465223252);
156
157 $typo3DbQueryParser = new Typo3DbBackend();
158 $typo3DbQueryParser->injectQueryParser($queryParserProphecy->reveal());
159 $typo3DbQueryParser->getObjectCountByQuery($queryInterfaceProphecy->reveal());
160 }
161 }