[!!!][TASK] Extbase: Remove preparsing of queries
[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 Doctrine\DBAL\Driver\Statement;
18 use Prophecy\Argument;
19 use TYPO3\CMS\Core\Database\ConnectionPool;
20 use TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder;
21 use TYPO3\CMS\Core\Database\Query\QueryBuilder;
22 use TYPO3\CMS\Core\Database\Query\Restriction\FrontendRestrictionContainer;
23 use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper;
24 use TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface;
25 use TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend;
26 use TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser;
27 use TYPO3\CMS\Extbase\Persistence\QueryInterface;
28 use TYPO3\CMS\Extbase\Service\EnvironmentService;
29
30 /**
31 * Test case
32 */
33 class Typo3DbBackendTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
34 {
35 /**
36 * @var DataMapper
37 */
38 protected static $dataMapper;
39
40 public function setUp()
41 {
42 parent::setUp();
43 $GLOBALS['TSFE'] = new \stdClass();
44 $GLOBALS['TSFE']->gr_list = '';
45 }
46
47 /**
48 * Setup DataMapper
49 */
50 public static function setUpBeforeClass()
51 {
52 self::$dataMapper = new DataMapper();
53 }
54
55 /**
56 * @return array
57 */
58 public function uidOfAlreadyPersistedValueObjectIsDeterminedCorrectlyDataProvider(): array
59 {
60 return [
61 'isFrontendEnvironment' => [true],
62 'isBackendEnvironment' => [false],
63 ];
64 }
65
66 /**
67 * @test
68 * @dataProvider uidOfAlreadyPersistedValueObjectIsDeterminedCorrectlyDataProvider
69 */
70 public function uidOfAlreadyPersistedValueObjectIsDeterminedCorrectly(bool $isFrontendEnvironment)
71 {
72 $mockValueObject = $this->getMockBuilder(\TYPO3\CMS\Extbase\DomainObject\AbstractValueObject::class)
73 ->setMethods(array('_getProperties'))
74 ->disableOriginalConstructor()
75 ->getMock();
76 $mockValueObject->expects($this->once())->method('_getProperties')
77 ->will($this->returnValue(['propertyName' => 'propertyValue']));
78 $mockColumnMap = $this->getMockBuilder(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMap::class)
79 ->setMethods(array('isPersistableProperty', 'getColumnName'))
80 ->disableOriginalConstructor()
81 ->getMock();
82 $mockColumnMap->expects($this->any())->method('getColumnName')->will($this->returnValue('column_name'));
83 $tableName = 'tx_foo_table';
84 $mockDataMap = $this->getMockBuilder(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMap::class)
85 ->setMethods(array('isPersistableProperty', 'getColumnMap', 'getTableName'))
86 ->disableOriginalConstructor()
87 ->getMock();
88 $mockDataMap->expects($this->any())->method('isPersistableProperty')->will($this->returnValue(true));
89 $mockDataMap->expects($this->any())->method('getColumnMap')->will($this->returnValue($mockColumnMap));
90 $mockDataMap->expects($this->any())->method('getTableName')->will($this->returnValue($tableName));
91 $mockDataMapper = $this->getMockBuilder(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper::class)
92 ->setMethods(array('getDataMap', 'getPlainValue'))
93 ->disableOriginalConstructor()
94 ->getMock();
95 $mockDataMapper->expects($this->once())->method('getDataMap')
96 ->will($this->returnValue($mockDataMap));
97 $mockDataMapper->expects($this->once())->method('getPlainValue')
98 ->will($this->returnValue('plainPropertyValue'));
99 $expectedUid = 52;
100
101 $expressionBuilderProphet = $this->prophesize(ExpressionBuilder::class);
102 $expressionBuilderProphet->eq(Argument::cetera())->willReturn('1 = 1');
103 $queryResultProphet = $this->prophesize(Statement::class);
104 $queryResultProphet->fetchColumn(Argument::cetera())->willReturn($expectedUid);
105 $queryBuilderProphet = $this->prophesize(QueryBuilder::class);
106 $queryBuilderProphet->execute()->willReturn($queryResultProphet->reveal());
107 $queryBuilderProphet->expr()->willReturn($expressionBuilderProphet->reveal());
108 $queryBuilderProphet->createNamedParameter(Argument::cetera())->willReturnArgument(0);
109 $queryBuilderProphet->select('uid')->willReturn($queryBuilderProphet->reveal());
110 $queryBuilderProphet->from($tableName)->willReturn($queryBuilderProphet->reveal());
111 $queryBuilderProphet->where(Argument::cetera())->willReturn($queryBuilderProphet->reveal());
112 $connectionPoolProphet = $this->prophesize(ConnectionPool::class);
113 $connectionPoolProphet->getQueryBuilderForTable(Argument::cetera())->willReturn($queryBuilderProphet->reveal());
114
115 $environmentServiceProphet = $this->prophesize(EnvironmentService::class);
116 $environmentServiceProphet->isEnvironmentInFrontendMode()->willReturn($isFrontendEnvironment);
117
118 if ($isFrontendEnvironment) {
119 $queryBuilderProphet->setRestrictions(Argument::type(FrontendRestrictionContainer::class))
120 ->shouldBeCalled();
121 }
122
123 $mockTypo3DbBackend = $this->getAccessibleMock(
124 \TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend::class,
125 ['dummy'],
126 [],
127 '',
128 false
129 );
130 $mockTypo3DbBackend->_set('dataMapper', $mockDataMapper);
131 $mockTypo3DbBackend->_set('connectionPool', $connectionPoolProphet->reveal());
132 $mockTypo3DbBackend->_set('environmentService', $environmentServiceProphet->reveal());
133 $result = $mockTypo3DbBackend->_callRef('getUidOfAlreadyPersistedValueObject', $mockValueObject);
134 $this->assertSame($expectedUid, $result);
135 }
136
137 /**
138 * @test
139 */
140 public function doLanguageAndWorkspaceOverlayChangesUidIfInPreview()
141 {
142 $comparisonRow = array(
143 'uid' => '42',
144 'pid' => '42',
145 '_ORIG_pid' => '-1',
146 '_ORIG_uid' => '43'
147 );
148 $row = array(
149 'uid' => '42',
150 'pid' => '42'
151 );
152 $workspaceVersion = array(
153 'uid' => '43',
154 'pid' => '-1'
155 );
156 /** @var \TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings|\PHPUnit_Framework_MockObject_MockObject $querySettings */
157 $mockQuerySettings = $this->getMockBuilder(\TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings::class)
158 ->setMethods(array('dummy'))
159 ->disableOriginalConstructor()
160 ->getMock();
161
162 $workspaceUid = 2;
163 $sourceMock = new \TYPO3\CMS\Extbase\Persistence\Generic\Qom\Selector('tx_foo', 'Tx_Foo');
164 /** @var $pageRepositoryMock \TYPO3\CMS\Frontend\Page\PageRepository|\PHPUnit_Framework_MockObject_MockObject */
165 $pageRepositoryMock = $this->getMockBuilder(\TYPO3\CMS\Frontend\Page\PageRepository::class)
166 ->setMethods(array('movePlhOL', 'getWorkspaceVersionOfRecord'))
167 ->getMock();
168 $pageRepositoryMock->versioningPreview = true;
169 $pageRepositoryMock->expects($this->once())->method('getWorkspaceVersionOfRecord')->with($workspaceUid, 'tx_foo', '42')->will($this->returnValue($workspaceVersion));
170 $mockTypo3DbBackend = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend::class, array('dummy'), array(), '', false);
171 $mockTypo3DbBackend->_set('pageRepository', $pageRepositoryMock);
172 $this->assertSame(array($comparisonRow), $mockTypo3DbBackend->_call('doLanguageAndWorkspaceOverlay', $sourceMock, array($row), $mockQuerySettings, $workspaceUid));
173 }
174
175 /**
176 * @test
177 * @return void
178 */
179 public function getObjectCountByQueryThrowsExceptionIfOffsetWithoutLimitIsUsed()
180 {
181 $querySettingsProphecy = $this->prophesize(QuerySettingsInterface::class);
182 $queryInterfaceProphecy = $this->prophesize(QueryInterface::class);
183 $queryParserProphecy = $this->prophesize(Typo3DbQueryParser::class);
184 $queryParserProphecy->parseQuery($queryInterfaceProphecy->reveal())->willReturn(
185 ['tables' => ['tt_content'], 'offset' => 10, 'limit' => null]
186 );
187 $queryInterfaceProphecy->getQuerySettings()->willReturn($querySettingsProphecy->reveal());
188 $queryInterfaceProphecy->getConstraint()->willReturn();
189 $queryInterfaceProphecy->getLimit()->willReturn();
190 $queryInterfaceProphecy->getOffset()->willReturn(10);
191
192 $this->expectException(\InvalidArgumentException::class);
193 $this->expectExceptionCode(1465223252);
194
195 $typo3DbBackend = new Typo3DbBackend();
196 $typo3DbBackend->injectQueryParser($queryParserProphecy->reveal());
197 $typo3DbBackend->getObjectCountByQuery($queryInterfaceProphecy->reveal());
198 }
199 }