93e0b9fc385ed2f85b4d8789ab1f8b3b07ee554a
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Tests / Unit / Persistence / Generic / PersistenceManagerTest.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Tests\Unit\Persistence\Generic;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2012 Nico de Haen
8 * All rights reserved
9 *
10 * This class is a backport of the corresponding class of FLOW3.
11 * All credits go to the v5 team.
12 *
13 * This script is part of the TYPO3 project. The TYPO3 project is
14 * free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * The GNU General Public License can be found at
20 * http://www.gnu.org/copyleft/gpl.html.
21 *
22 * This script is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
29
30 /**
31 * A PersistenceManager Test
32 */
33 class PersistenceManagerTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
34
35 /**
36 * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
37 */
38 protected $mockObjectManager;
39
40 public function setUp() {
41 $this->mockObjectManager = $this->getMock('TYPO3\\CMS\\Extbase\\Object\\ObjectManagerInterface');
42 }
43
44 /**
45 * @test
46 */
47 public function persistAllPassesAddedObjectsToBackend() {
48 $entity2 = new \TYPO3\CMS\Extbase\Tests\Unit\Persistence\Fixture\Model\Entity2();
49 $objectStorage = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
50 $objectStorage->attach($entity2);
51 $mockBackend = $this->getMock('TYPO3\CMS\Extbase\Persistence\Generic\BackendInterface');
52 $mockBackend->expects($this->once())->method('setAggregateRootObjects')->with($objectStorage);
53
54 $manager = $this->getAccessibleMock('TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager', array('dummy'));
55 $manager->_set('backend', $mockBackend);
56 $manager->add($entity2);
57
58 $manager->persistAll();
59 }
60
61 /**
62 * @test
63 */
64 public function persistAllPassesRemovedObjectsToBackend() {
65 $entity2 = new \TYPO3\CMS\Extbase\Tests\Unit\Persistence\Fixture\Model\Entity2();
66 $objectStorage = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
67 $objectStorage->attach($entity2);
68 $mockBackend = $this->getMock('TYPO3\CMS\Extbase\Persistence\Generic\BackendInterface');
69 $mockBackend->expects($this->once())->method('setDeletedEntities')->with($objectStorage);
70
71 $manager = $this->getAccessibleMock('TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager', array('dummy'));
72 $manager->_set('backend', $mockBackend);
73 $manager->remove($entity2);
74
75 $manager->persistAll();
76 }
77
78 /**
79 * @test
80 */
81 public function getIdentifierByObjectReturnsIdentifierFromSession() {
82 $fakeUuid = 'fakeUuid';
83 $object = new \stdClass();
84
85 $mockSession = $this->getMock('TYPO3\CMS\Extbase\Persistence\Generic\Session');
86 $mockSession->expects($this->once())->method('getIdentifierByObject')->with($object)->will($this->returnValue($fakeUuid));
87
88 /** @var \TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface $manager */
89 $manager = $this->getAccessibleMock('TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager', array('dummy'));
90 $manager->_set('persistenceSession', $mockSession);
91
92 $this->assertEquals($manager->getIdentifierByObject($object), $fakeUuid);
93 }
94
95 /**
96 * @test
97 */
98 public function getObjectByIdentifierReturnsObjectFromSessionIfAvailable() {
99 $fakeUuid = 'fakeUuid';
100 $object = new \stdClass();
101
102 $mockSession = $this->getMock('TYPO3\CMS\Extbase\Persistence\Generic\Session');
103 $mockSession->expects($this->once())->method('hasIdentifier')->with($fakeUuid)->will($this->returnValue(TRUE));
104 $mockSession->expects($this->once())->method('getObjectByIdentifier')->with($fakeUuid)->will($this->returnValue($object));
105
106 $manager = $this->getAccessibleMock('TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager', array('dummy'));
107 $manager->_set('persistenceSession', $mockSession);
108
109 $this->assertEquals($manager->getObjectByIdentifier($fakeUuid), $object);
110 }
111
112 /**
113 * @test
114 */
115 public function getObjectByIdentifierReturnsObjectFromPersistenceIfAvailable() {
116 $fakeUuid = '42';
117 $object = new \stdClass();
118 $fakeEntityType = get_class($object);
119
120 $mockSession = $this->getMock('TYPO3\CMS\Extbase\Persistence\Generic\Session');
121 $mockSession->expects($this->once())->method('hasIdentifier')->with($fakeUuid)->will($this->returnValue(FALSE));
122
123 $mockBackend = $this->getMock('TYPO3\CMS\Extbase\Persistence\Generic\BackendInterface');
124 $mockBackend->expects($this->once())->method('getObjectByIdentifier')->with($fakeUuid, $fakeEntityType)->will($this->returnValue($object));
125
126 $manager = $this->getAccessibleMock('TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager', array('dummy'));
127 $manager->_set('persistenceSession', $mockSession);
128 $manager->_set('backend', $mockBackend);
129
130 $this->assertEquals($manager->getObjectByIdentifier($fakeUuid, $fakeEntityType), $object);
131 }
132
133 /**
134 * @test
135 */
136 public function getObjectByIdentifierReturnsNullForUnknownObject() {
137 $fakeUuid = '42';
138 $fakeEntityType = 'foobar';
139
140 $mockSession = $this->getMock('TYPO3\CMS\Extbase\Persistence\Generic\Session');
141 $mockSession->expects($this->once())->method('hasIdentifier')->with($fakeUuid, $fakeEntityType)->will($this->returnValue(FALSE));
142
143 $mockBackend = $this->getMock('TYPO3\CMS\Extbase\Persistence\Generic\BackendInterface');
144 $mockBackend->expects($this->once())->method('getObjectByIdentifier')->with($fakeUuid, $fakeEntityType)->will($this->returnValue(NULL));
145
146 $manager = $this->getAccessibleMock('TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager', array('dummy'));
147 $manager->_set('persistenceSession', $mockSession);
148 $manager->_set('backend', $mockBackend);
149
150 $this->assertNull($manager->getObjectByIdentifier($fakeUuid, $fakeEntityType));
151 }
152
153 /**
154 * @test
155 */
156 public function addActuallyAddsAnObjectToTheInternalObjectsArray() {
157 $someObject = new \stdClass();
158 $persistenceManager = new \TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager();
159 $persistenceManager->add($someObject);
160
161 $this->assertAttributeContains($someObject, 'addedObjects', $persistenceManager);
162 }
163
164 /**
165 * @test
166 */
167 public function removeActuallyRemovesAnObjectFromTheInternalObjectsArray() {
168 $object1 = new \stdClass();
169 $object2 = new \stdClass();
170 $object3 = new \stdClass();
171
172 $persistenceManager = new \TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager();
173 $persistenceManager->add($object1);
174 $persistenceManager->add($object2);
175 $persistenceManager->add($object3);
176
177 $persistenceManager->remove($object2);
178
179 $this->assertAttributeContains($object1, 'addedObjects', $persistenceManager);
180 $this->assertAttributeNotContains($object2, 'addedObjects', $persistenceManager);
181 $this->assertAttributeContains($object3, 'addedObjects', $persistenceManager);
182 }
183
184 /**
185 * @test
186 */
187 public function removeRemovesTheRightObjectEvenIfItHasBeenModifiedSinceItsAddition() {
188 $object1 = new \ArrayObject(array('val' => '1'));
189 $object2 = new \ArrayObject(array('val' => '2'));
190 $object3 = new \ArrayObject(array('val' => '3'));
191
192 $persistenceManager = new \TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager();
193 $persistenceManager->add($object1);
194 $persistenceManager->add($object2);
195 $persistenceManager->add($object3);
196
197 $object2['foo'] = 'bar';
198 $object3['val'] = '2';
199
200 $persistenceManager->remove($object2);
201
202 $this->assertAttributeContains($object1, 'addedObjects', $persistenceManager);
203 $this->assertAttributeNotContains($object2, 'addedObjects', $persistenceManager);
204 $this->assertAttributeContains($object3, 'addedObjects', $persistenceManager);
205 }
206
207 /**
208 * Make sure we remember the objects that are not currently add()ed
209 * but might be in persistent storage.
210 *
211 * @test
212 */
213 public function removeRetainsObjectForObjectsNotInCurrentSession() {
214 $object = new \ArrayObject(array('val' => '1'));
215 $persistenceManager = new \TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager();
216 $persistenceManager->remove($object);
217
218 $this->assertAttributeContains($object, 'removedObjects', $persistenceManager);
219 }
220
221 /**
222 * @test
223 */
224 public function updateSchedulesAnObjectForPersistence() {
225 $className = uniqid('BazFixture');
226 eval ('
227 namespace ' . __NAMESPACE__ . '\\Domain\\Model;
228 class ' . $className . ' extends \\TYPO3\\CMS\\Extbase\\DomainObject\\AbstractEntity {
229 protected $uid = 42;
230 }
231 ');
232 eval ('
233 namespace ' . __NAMESPACE__ . '\\Domain\\Repository;
234 class ' . $className . 'Repository extends \\TYPO3\\CMS\\Extbase\\Persistence\\Repository {}
235 ');
236 $classNameWithNamespace = __NAMESPACE__ . '\\Domain\\Model\\' . $className;
237 $repositorClassNameWithNamespace = __NAMESPACE__ . '\\Domain\\Repository\\' . $className . 'Repository';
238
239 $persistenceManager = $this->getAccessibleMock('TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager', array('dummy'));
240 $session = new \TYPO3\CMS\Extbase\Persistence\Generic\Session();
241 $changedEntities = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
242 $entity1 = new $classNameWithNamespace();
243 $repository = $this->getAccessibleMock($repositorClassNameWithNamespace, array('dummy'), array($this->mockObjectManager));
244 $repository->_set('objectType', get_class($entity1));
245 $mockBackend = $this->getMock($this->buildAccessibleProxy('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Backend'), array('commit', 'setChangedEntities'), array(), '', FALSE);
246 $mockBackend->expects($this->once())
247 ->method('setChangedEntities')
248 ->with($this->equalTo($changedEntities));
249
250 $persistenceManager->_set('backend', $mockBackend);
251 $persistenceManager->_set('persistenceSession', $session);
252
253 $repository->_set('persistenceManager', $persistenceManager);
254 $session->registerObject($entity1, 42);
255 $changedEntities->attach($entity1);
256 $repository->update($entity1);
257 $persistenceManager->persistAll();
258
259 }
260
261 /**
262 * @test
263 */
264 public function clearStateForgetsAboutNewObjects() {
265 $mockObject = $this->getMock('TYPO3\CMS\Extbase\Persistence\Aspect\PersistenceMagicInterface');
266 $mockObject->Persistence_Object_Identifier = 'abcdefg';
267
268 $mockSession = $this->getMock('TYPO3\CMS\Extbase\Persistence\Generic\Session');
269 $mockSession->expects($this->any())->method('hasIdentifier')->will($this->returnValue(FALSE));
270 $mockBackend = $this->getMock('TYPO3\CMS\Extbase\Persistence\Generic\BackendInterface');
271 $mockBackend->expects($this->any())->method('getObjectDataByIdentifier')->will($this->returnValue(FALSE));
272
273 $persistenceManager = $this->getAccessibleMock('TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager', array('dummy'));
274 $persistenceManager->_set('persistenceSession', $mockSession);
275 $persistenceManager->_set('backend', $mockBackend);
276
277 $persistenceManager->registerNewObject($mockObject);
278 $persistenceManager->clearState();
279
280 $object = $persistenceManager->getObjectByIdentifier('abcdefg');
281 $this->assertNull($object);
282 }
283
284 /**
285 * @test
286 */
287 public function tearDownWithBackendNotSupportingTearDownDoesNothing() {
288 $mockBackend = $this->getMock('TYPO3\CMS\Extbase\Persistence\Generic\BackendInterface');
289 $mockBackend->expects($this->never())->method('tearDown');
290
291 $persistenceManager = $this->getAccessibleMock('TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager', array('dummy'));
292 $persistenceManager->_set('backend', $mockBackend);
293
294 $persistenceManager->tearDown();
295 }
296
297 /**
298 * @test
299 */
300 public function tearDownWithBackendSupportingTearDownDelegatesCallToBackend() {
301 $methods = array_merge(get_class_methods('TYPO3\CMS\Extbase\Persistence\Generic\BackendInterface'), array('tearDown'));
302 $mockBackend = $this->getMock('TYPO3\CMS\Extbase\Persistence\Generic\BackendInterface', $methods);
303 $mockBackend->expects($this->once())->method('tearDown');
304
305 $persistenceManager = $this->getAccessibleMock('TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager', array('dummy'));
306 $persistenceManager->_set('backend', $mockBackend);
307
308 $persistenceManager->tearDown();
309 }
310
311 /**
312 * @test
313 *
314 * This test and the related Fixtures TxDomainModelTestEntity and
315 * TxDomainRepositoryTestEntityRepository can be removed if we do not need to support
316 * underscore class names instead of namespaced class names
317 */
318 public function persistAllAddsReconstitutedObjectFromSessionToBackendsAggregateRootObjects() {
319 $className = uniqid('BazFixture');
320 eval ('
321 class Foo_Bar_Domain_Model_' . $className . ' extends \\TYPO3\\CMS\\Extbase\\DomainObject\\AbstractEntity {}
322 ');
323 eval ('
324 class Foo_Bar_Domain_Repository_' . $className . 'Repository {}
325 ');
326 $persistenceManager = $this->getAccessibleMock('TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager', array('dummy'));
327 $aggregateRootObjects = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
328 $fullClassName = 'Foo_Bar_Domain_Model_' . $className;
329 $entity1 = new $fullClassName();
330 $aggregateRootObjects->attach($entity1);
331 $mockBackend = $this->getMock($this->buildAccessibleProxy('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Backend'), array('commit', 'setAggregateRootObjects', 'setDeletedEntities'), array(), '', FALSE);
332 $mockBackend->expects($this->once())
333 ->method('setAggregateRootObjects')
334 ->with($this->equalTo($aggregateRootObjects));
335 $persistenceManager->_set('backend', $mockBackend);
336 $persistenceManager->add($entity1);
337 $persistenceManager->persistAll();
338 }
339
340 /**
341 * @test
342 */
343 public function persistAllAddsNamespacedReconstitutedObjectFromSessionToBackendsAggregateRootObjects() {
344 $className = uniqid('BazFixture');
345 eval ('
346 namespace ' . __NAMESPACE__ . '\\Domain\\Model;
347 class ' . $className . ' extends \\TYPO3\\CMS\\Extbase\\DomainObject\\AbstractEntity {}
348 ');
349 eval ('
350 namespace ' . __NAMESPACE__ . '\\Domain\\Repository;
351 class ' . $className . 'Repository {}
352 ');
353 $persistenceManager = $this->getAccessibleMock('TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager', array('dummy'));
354 $aggregateRootObjects = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
355 $classNameWithNamespace = __NAMESPACE__ . '\\Domain\\Model\\' . $className;
356 $entity1 = new $classNameWithNamespace();
357 $aggregateRootObjects->attach($entity1);
358 $mockBackend = $this->getMock($this->buildAccessibleProxy('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Backend'), array('commit', 'setAggregateRootObjects', 'setDeletedEntities'), array(), '', FALSE);
359 $mockBackend->expects($this->once())
360 ->method('setAggregateRootObjects')
361 ->with($this->equalTo($aggregateRootObjects));
362 $persistenceManager->_set('backend', $mockBackend);
363 $persistenceManager->add($entity1);
364 $persistenceManager->persistAll();
365 }
366
367 }