[!!!][TASK] Remove IdentityMap from persistence
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Tests / Unit / Persistence / RepositoryTest.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Tests\Unit\Persistence;
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 /**
18 * Test case
19 */
20 class RepositoryTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
21
22 /**
23 * @var \TYPO3\CMS\Extbase\Persistence\Repository|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface
24 */
25 protected $repository;
26
27 /**
28 * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
29 */
30 protected $mockObjectManager;
31
32 /**
33 * @var \TYPO3\CMS\Extbase\Persistence\Generic\QueryFactory
34 */
35 protected $mockQueryFactory;
36
37 /**
38 * @var \TYPO3\CMS\Extbase\Persistence\Generic\BackendInterface
39 */
40 protected $mockBackend;
41
42 /**
43 * @var \TYPO3\CMS\Extbase\Persistence\Generic\Session
44 */
45 protected $mockSession;
46
47 /**
48 * @var \TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface
49 */
50 protected $mockPersistenceManager;
51
52 /**
53 * @var \TYPO3\CMS\Extbase\Persistence\QueryInterface
54 */
55 protected $mockQuery;
56
57 /**
58 * @var \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface
59 */
60 protected $mockQuerySettings;
61
62 /**
63 * @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManager
64 */
65 protected $mockConfigurationManager;
66
67 protected function setUp() {
68 $this->mockQueryFactory = $this->getMock(\TYPO3\CMS\Extbase\Persistence\Generic\QueryFactory::class);
69 $this->mockQuery = $this->getMock(\TYPO3\CMS\Extbase\Persistence\QueryInterface::class);
70 $this->mockQuerySettings = $this->getMock(\TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface::class);
71 $this->mockQuery->expects($this->any())->method('getQuerySettings')->will($this->returnValue($this->mockQuerySettings));
72 $this->mockQueryFactory->expects($this->any())->method('create')->will($this->returnValue($this->mockQuery));
73 $this->mockSession = $this->getMock(\TYPO3\CMS\Extbase\Persistence\Generic\Session::class);
74 $this->mockConfigurationManager = $this->getMock(\TYPO3\CMS\Extbase\Configuration\ConfigurationManager::class);
75 $this->mockBackend = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Backend::class, array('dummy'), array($this->mockConfigurationManager));
76 $this->inject($this->mockBackend, 'session', $this->mockSession);
77 $this->mockPersistenceManager = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager::class, array('createQueryForType'));
78 $this->inject($this->mockBackend, 'persistenceManager', $this->mockPersistenceManager);
79 $this->inject($this->mockPersistenceManager, 'persistenceSession', $this->mockSession);
80 $this->inject($this->mockPersistenceManager, 'backend', $this->mockBackend);
81 $this->mockPersistenceManager->expects($this->any())->method('createQueryForType')->will($this->returnValue($this->mockQuery));
82 $this->mockObjectManager = $this->getMock(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface::class);
83 $this->repository = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Repository::class, array('dummy'), array($this->mockObjectManager));
84 $this->repository->_set('persistenceManager', $this->mockPersistenceManager);
85 }
86
87 /**
88 * @test
89 */
90 public function abstractRepositoryImplementsRepositoryInterface() {
91 $this->assertTrue($this->repository instanceof \TYPO3\CMS\Extbase\Persistence\RepositoryInterface);
92 }
93
94 /**
95 * @test
96 */
97 public function createQueryCallsPersistenceManagerWithExpectedClassName() {
98 $mockPersistenceManager = $this->getMock(\TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager::class);
99 $mockPersistenceManager->expects($this->once())->method('createQueryForType')->with('ExpectedType');
100
101 $this->repository->_set('objectType', 'ExpectedType');
102 $this->inject($this->repository, 'persistenceManager', $mockPersistenceManager);
103
104 $this->repository->createQuery();
105 }
106
107 /**
108 * @test
109 */
110 public function createQuerySetsDefaultOrderingIfDefined() {
111 $orderings = array('foo' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING);
112 $mockQuery = $this->getMock(\TYPO3\CMS\Extbase\Persistence\QueryInterface::class);
113 $mockQuery->expects($this->once())->method('setOrderings')->with($orderings);
114 $mockPersistenceManager = $this->getMock(\TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager::class);
115 $mockPersistenceManager->expects($this->exactly(2))->method('createQueryForType')->with('ExpectedType')->will($this->returnValue($mockQuery));
116
117 $this->repository->_set('objectType', 'ExpectedType');
118 $this->inject($this->repository, 'persistenceManager', $mockPersistenceManager);
119 $this->repository->setDefaultOrderings($orderings);
120 $this->repository->createQuery();
121
122 $this->repository->setDefaultOrderings(array());
123 $this->repository->createQuery();
124 }
125
126 /**
127 * @test
128 */
129 public function findAllCreatesQueryAndReturnsResultOfExecuteCall() {
130 $expectedResult = $this->getMock(\TYPO3\CMS\Extbase\Persistence\QueryResultInterface::class);
131
132 $mockQuery = $this->getMock(\TYPO3\CMS\Extbase\Persistence\QueryInterface::class);
133 $mockQuery->expects($this->once())->method('execute')->with()->will($this->returnValue($expectedResult));
134
135 $repository = $this->getMock(\TYPO3\CMS\Extbase\Persistence\Repository::class, array('createQuery'), array($this->mockObjectManager));
136 $repository->expects($this->once())->method('createQuery')->will($this->returnValue($mockQuery));
137
138 $this->assertSame($expectedResult, $repository->findAll());
139 }
140
141 /**
142 * @test
143 */
144 public function findByidentifierReturnsResultOfGetObjectByIdentifierCallFromBackend() {
145 $identifier = '42';
146 $object = new \stdClass();
147
148 $expectedResult = $this->getMock(\TYPO3\CMS\Extbase\Persistence\QueryResultInterface::class);
149 $expectedResult->expects($this->once())->method('getFirst')->will($this->returnValue($object));
150
151 $this->mockQuery->expects($this->any())->method('getQuerySettings')->will($this->returnValue($this->mockQuerySettings));
152 $this->mockQuery->expects($this->once())->method('matching')->will($this->returnValue($this->mockQuery));
153 $this->mockQuery->expects($this->once())->method('execute')->will($this->returnValue($expectedResult));
154
155 // skip backend, as we want to test the backend
156 $this->mockSession->expects($this->any())->method('hasIdentifier')->will($this->returnValue(FALSE));
157 $this->assertSame($object, $this->repository->findByIdentifier($identifier));
158 }
159
160 /**
161 * @test
162 */
163 public function addDelegatesToPersistenceManager() {
164 $object = new \stdClass();
165 $mockPersistenceManager = $this->getMock(\TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface::class);
166 $mockPersistenceManager->expects($this->once())->method('add')->with($object);
167 $this->inject($this->repository, 'persistenceManager', $mockPersistenceManager);
168 $this->repository->_set('objectType', get_class($object));
169 $this->repository->add($object);
170 }
171
172 /**
173 * @test
174 */
175 public function removeDelegatesToPersistenceManager() {
176 $object = new \stdClass();
177 $mockPersistenceManager = $this->getMock(\TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface::class);
178 $mockPersistenceManager->expects($this->once())->method('remove')->with($object);
179 $this->inject($this->repository, 'persistenceManager', $mockPersistenceManager);
180 $this->repository->_set('objectType', get_class($object));
181 $this->repository->remove($object);
182 }
183
184 /**
185 * @test
186 */
187 public function updateDelegatesToPersistenceManager() {
188 $object = new \stdClass();
189 $mockPersistenceManager = $this->getMock(\TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface::class);
190 $mockPersistenceManager->expects($this->once())->method('update')->with($object);
191 $this->inject($this->repository, 'persistenceManager', $mockPersistenceManager);
192 $this->repository->_set('objectType', get_class($object));
193 $this->repository->update($object);
194 }
195
196 /**
197 * @test
198 */
199 public function magicCallMethodAcceptsFindBySomethingCallsAndExecutesAQueryWithThatCriteria() {
200 $mockQueryResult = $this->getMock(\TYPO3\CMS\Extbase\Persistence\QueryResultInterface::class);
201 $mockQuery = $this->getMock(\TYPO3\CMS\Extbase\Persistence\QueryInterface::class);
202 $mockQuery->expects($this->once())->method('equals')->with('foo', 'bar')->will($this->returnValue('matchCriteria'));
203 $mockQuery->expects($this->once())->method('matching')->with('matchCriteria')->will($this->returnValue($mockQuery));
204 $mockQuery->expects($this->once())->method('execute')->with()->will($this->returnValue($mockQueryResult));
205
206 $repository = $this->getMock(\TYPO3\CMS\Extbase\Persistence\Repository::class, array('createQuery'), array($this->mockObjectManager));
207 $repository->expects($this->once())->method('createQuery')->will($this->returnValue($mockQuery));
208
209 $this->assertSame($mockQueryResult, $repository->findByFoo('bar'));
210 }
211
212 /**
213 * @test
214 */
215 public function magicCallMethodAcceptsFindOneBySomethingCallsAndExecutesAQueryWithThatCriteria() {
216 $object = new \stdClass();
217 $mockQueryResult = $this->getMock(\TYPO3\CMS\Extbase\Persistence\QueryResultInterface::class);
218 $mockQueryResult->expects($this->once())->method('getFirst')->will($this->returnValue($object));
219 $mockQuery = $this->getMock(\TYPO3\CMS\Extbase\Persistence\QueryInterface::class);
220 $mockQuery->expects($this->once())->method('equals')->with('foo', 'bar')->will($this->returnValue('matchCriteria'));
221 $mockQuery->expects($this->once())->method('matching')->with('matchCriteria')->will($this->returnValue($mockQuery));
222 $mockQuery->expects($this->once())->method('setLimit')->will($this->returnValue($mockQuery));
223 $mockQuery->expects($this->once())->method('execute')->will($this->returnValue($mockQueryResult));
224
225 $repository = $this->getMock(\TYPO3\CMS\Extbase\Persistence\Repository::class, array('createQuery'), array($this->mockObjectManager));
226 $repository->expects($this->once())->method('createQuery')->will($this->returnValue($mockQuery));
227
228 $this->assertSame($object, $repository->findOneByFoo('bar'));
229 }
230
231 /**
232 * @test
233 */
234 public function magicCallMethodAcceptsCountBySomethingCallsAndExecutesAQueryWithThatCriteria() {
235 $mockQuery = $this->getMock(\TYPO3\CMS\Extbase\Persistence\QueryInterface::class);
236 $mockQueryResult = $this->getMock(\TYPO3\CMS\Extbase\Persistence\QueryResultInterface::class);
237 $mockQuery->expects($this->once())->method('equals')->with('foo', 'bar')->will($this->returnValue('matchCriteria'));
238 $mockQuery->expects($this->once())->method('matching')->with('matchCriteria')->will($this->returnValue($mockQuery));
239 $mockQuery->expects($this->once())->method('execute')->will($this->returnValue($mockQueryResult));
240 $mockQueryResult->expects($this->once())->method('count')->will($this->returnValue(2));
241
242 $repository = $this->getMock(\TYPO3\CMS\Extbase\Persistence\Repository::class, array('createQuery'), array($this->mockObjectManager));
243 $repository->expects($this->once())->method('createQuery')->will($this->returnValue($mockQuery));
244
245 $this->assertSame(2, $repository->countByFoo('bar'));
246 }
247
248 /**
249 * @test
250 * @expectedException \TYPO3\CMS\Extbase\Persistence\Generic\Exception\UnsupportedMethodException
251 */
252 public function magicCallMethodTriggersAnErrorIfUnknownMethodsAreCalled() {
253 $repository = $this->getMock(\TYPO3\CMS\Extbase\Persistence\Repository::class, array('createQuery'), array($this->mockObjectManager));
254 $repository->__call('foo', array());
255 }
256
257 /**
258 * @test
259 * @expectedException \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
260 */
261 public function addChecksObjectType() {
262 $this->repository->_set('objectType', 'ExpectedObjectType');
263 $this->repository->add(new \stdClass());
264 }
265
266 /**
267 * @test
268 * @expectedException \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
269 */
270 public function removeChecksObjectType() {
271 $this->repository->_set('objectType', 'ExpectedObjectType');
272 $this->repository->remove(new \stdClass());
273 }
274 /**
275 * @test
276 * @expectedException \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
277 */
278 public function updateChecksObjectType() {
279 $repository = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Repository::class, array('dummy'), array($this->mockObjectManager));
280 $repository->_set('objectType', 'ExpectedObjectType');
281
282 $repository->update(new \stdClass());
283 }
284
285 /**
286 * dataProvider for createQueryCallsQueryFactoryWithExpectedType
287 *
288 * @return array
289 */
290 public function modelAndRepositoryClassNames() {
291 return array(
292 array('Tx_BlogExample_Domain_Repository_BlogRepository', 'Tx_BlogExample_Domain_Model_Blog'),
293 array('_Domain_Repository_Content_PageRepository', '_Domain_Model_Content_Page'),
294 array('Tx_RepositoryExample_Domain_Repository_SomeModelRepository', 'Tx_RepositoryExample_Domain_Model_SomeModel'),
295 array('Tx_RepositoryExample_Domain_Repository_RepositoryRepository', 'Tx_RepositoryExample_Domain_Model_Repository'),
296 array('Tx_Repository_Domain_Repository_RepositoryRepository', 'Tx_Repository_Domain_Model_Repository')
297 );
298 }
299
300 /**
301 * @test
302 * @dataProvider modelAndRepositoryClassNames
303 * @param string $repositoryClassName
304 * @param string $modelClassName
305 */
306 public function constructSetsObjectTypeFromClassName($repositoryClassName, $modelClassName) {
307 $repositoryClassNameWithNS = __NAMESPACE__ . '\\' . $repositoryClassName;
308 eval('namespace ' . __NAMESPACE__ . '; class ' . $repositoryClassName . ' extends \\TYPO3\\CMS\\Extbase\\Persistence\\Repository {
309 protected function getRepositoryClassName() {
310 return \'' . $repositoryClassName . '\';
311 }
312 public function _getObjectType() {
313 return $this->objectType;
314 }
315 }');
316 $this->repository = new $repositoryClassNameWithNS($this->mockObjectManager);
317 $this->assertEquals($modelClassName, $this->repository->_getObjectType());
318 }
319
320 /**
321 * @test
322 */
323 public function createQueryReturnsQueryWithUnmodifiedDefaultQuerySettings() {
324 $this->mockQuery = new \TYPO3\CMS\Extbase\Persistence\Generic\Query('foo');
325 $mockDefaultQuerySettings = $this->getMock(\TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface::class);
326 $this->repository->setDefaultQuerySettings($mockDefaultQuerySettings);
327 $query = $this->repository->createQuery();
328 $instanceQuerySettings = $query->getQuerySettings();
329 $this->assertEquals($mockDefaultQuerySettings, $instanceQuerySettings);
330 $this->assertNotSame($mockDefaultQuerySettings, $instanceQuerySettings);
331 }
332
333 /**
334 * @test
335 */
336 public function findByUidReturnsResultOfGetObjectByIdentifierCall() {
337 $fakeUid = '123';
338 $object = new \stdClass();
339 $repository = $this->getMock(\TYPO3\CMS\Extbase\Persistence\Repository::class, array('findByIdentifier'), array($this->mockObjectManager));
340 $expectedResult = $object;
341 $repository->expects($this->once())->method('findByIdentifier')->will($this->returnValue($object));
342 $actualResult = $repository->findByUid($fakeUid);
343 $this->assertSame($expectedResult, $actualResult);
344 }
345
346 /**
347 * @test
348 * @expectedException \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
349 */
350 public function updateRejectsObjectsOfWrongType() {
351 $this->repository->_set('objectType', 'Foo');
352 $this->repository->update(new \stdClass());
353 }
354
355 /**
356 * @test
357 */
358 public function magicCallMethodReturnsFirstArrayKeyInFindOneBySomethingIfQueryReturnsRawResult() {
359 $queryResultArray = array(
360 0 => array(
361 'foo' => 'bar',
362 ),
363 );
364 $this->mockQuery->expects($this->once())->method('equals')->with('foo', 'bar')->will($this->returnValue('matchCriteria'));
365 $this->mockQuery->expects($this->once())->method('matching')->with('matchCriteria')->will($this->returnValue($this->mockQuery));
366 $this->mockQuery->expects($this->once())->method('setLimit')->with(1)->will($this->returnValue($this->mockQuery));
367 $this->mockQuery->expects($this->once())->method('execute')->will($this->returnValue($queryResultArray));
368 $this->assertSame(array('foo' => 'bar'), $this->repository->findOneByFoo('bar'));
369 }
370
371 /**
372 * @test
373 */
374 public function magicCallMethodReturnsNullInFindOneBySomethingIfQueryReturnsEmptyRawResult() {
375 $queryResultArray = array();
376 $this->mockQuery->expects($this->once())->method('equals')->with('foo', 'bar')->will($this->returnValue('matchCriteria'));
377 $this->mockQuery->expects($this->once())->method('matching')->with('matchCriteria')->will($this->returnValue($this->mockQuery));
378 $this->mockQuery->expects($this->once())->method('setLimit')->with(1)->will($this->returnValue($this->mockQuery));
379 $this->mockQuery->expects($this->once())->method('execute')->will($this->returnValue($queryResultArray));
380 $this->assertNull($this->repository->findOneByFoo('bar'));
381 }
382
383 }