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