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