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