2 /***************************************************************
5 * (c) 2009 Christopher Hlubek <hlubek@networkteam.com>
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
25 class Tx_Extbase_Persistence_Repository_testcase
extends Tx_Extbase_BaseTestCase
{
29 * @var Tx_Extbase_DomainObject_DomainObjectInterface
31 protected $aggregateRootClassName;
33 public function setUp() {
34 $this->aggregateRootClassName
= uniqid('Tx_Aggregate_Root_Class_');
35 eval('class ' . $this->aggregateRootClassName
. ' implements Tx_Extbase_DomainObject_DomainObjectInterface {
36 public function _memorizeCleanState() {}
37 public function _isNew() {}
38 public function _isDirty() {}
39 public function _setProperty($propertyName, $propertyValue) {}
40 public function _getProperty($propertyName) {}
41 public function _getProperties() {}
42 public function _getDirtyProperties() {}
43 public function getUid() { return 123; }
50 public function abstractRepositoryImplementsRepositoryInterface() {
51 $mockRepository = $this->getMock('Tx_Extbase_Persistence_Repository', array('dummy'), array(), '', FALSE);
52 $this->assertTrue($mockRepository instanceof Tx_Extbase_Persistence_RepositoryInterface
);
58 public function addCorrectlyUpdatesAddedObjectsAndRemovedObjectsCollections() {
59 $aggregateRootObject = new $this->aggregateRootClassName
;
61 $mockAddedObjects = $this->getMock('Tx_Extbase_Persistence_ObjectStorage');
62 $mockAddedObjects->expects($this->once())->method('attach')->with($aggregateRootObject);
64 $mockRemovedObjects = $this->getMock('Tx_Extbase_Persistence_ObjectStorage');
65 $mockRemovedObjects->expects($this->once())->method('detach')->with($aggregateRootObject);
67 $mockRepository = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Repository'), array('dummy'), array(), '', FALSE);
68 $mockRepository->_set('addedObjects', $mockAddedObjects);
69 $mockRepository->_set('removedObjects', $mockRemovedObjects);
70 $mockRepository->_set('objectType', $this->aggregateRootClassName
);
72 $mockRepository->add($aggregateRootObject);
78 public function removeDetachesObjectFromAddedObjectsCollectionIfItExists() {
79 $aggregateRootObject = new $this->aggregateRootClassName
;
81 $mockAddedObjects = $this->getMock('Tx_Extbase_Persistence_ObjectStorage');
82 $mockAddedObjects->expects($this->once())->method('contains')->with($aggregateRootObject)->will($this->returnValue(TRUE));
83 $mockAddedObjects->expects($this->once())->method('detach')->with($aggregateRootObject);
85 $mockRemovedObjects = $this->getMock('Tx_Extbase_Persistence_ObjectStorage');
86 $mockRemovedObjects->expects($this->never())->method('attach');
88 $mockRepository = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Repository'), array('dummy'), array(), '', FALSE);
89 $mockRepository->_set('addedObjects', $mockAddedObjects);
90 $mockRepository->_set('removedObjects', $mockRemovedObjects);
91 $mockRepository->_set('objectType', $this->aggregateRootClassName
);
93 $mockRepository->remove($aggregateRootObject);
99 public function removeAttachesObjectToRemovedObjectsCollectionIfItDoesNotExistInAddedObjectsCollection() {
100 $aggregateRootObject = new $this->aggregateRootClassName
;
102 $mockAddedObjects = $this->getMock('Tx_Extbase_Persistence_ObjectStorage');
103 $mockAddedObjects->expects($this->once())->method('contains')->with($aggregateRootObject)->will($this->returnValue(FALSE));
104 $mockAddedObjects->expects($this->never())->method('detach');
106 $mockRemovedObjects = $this->getMock('Tx_Extbase_Persistence_ObjectStorage');
107 $mockRemovedObjects->expects($this->once())->method('attach')->with($aggregateRootObject);
109 $mockRepository = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Repository'), array('dummy'), array(), '', FALSE);
110 $mockRepository->_set('addedObjects', $mockAddedObjects);
111 $mockRepository->_set('removedObjects', $mockRemovedObjects);
112 $mockRepository->_set('objectType', $this->aggregateRootClassName
);
114 $mockRepository->remove($aggregateRootObject);
120 public function createQueryCallsQueryFactoryWithExpectedType() {
121 $fakeRepositoryClassName = $this->aggregateRootClassName
. 'Repository';
123 $mockQueryFactory = $this->getMock('Tx_Extbase_Persistence_QueryFactoryInterface');
124 $mockQueryFactory->expects($this->once())->method('create')->with($this->aggregateRootClassName
);
126 $mockRepository = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Repository'), array('getRepositoryClassName'), array(), $fakeRepositoryClassName, FALSE);
127 $mockRepository->_set('objectType', $this->aggregateRootClassName
);
128 $mockRepository->_set('queryFactory', $mockQueryFactory);
130 $mockRepository->createQuery();
136 public function findAllCreatesQueryAndReturnsResultOfExecuteCall() {
137 $expectedResult = array('one', 'two');
139 $mockQuery = $this->getMock('Tx_Extbase_Persistence_QueryInterface');
140 $mockQuery->expects($this->once())->method('execute')->will($this->returnValue($expectedResult));
142 $mockRepository = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Repository'), array('createQuery'), array(), '', FALSE);
143 $mockRepository->expects($this->once())->method('createQuery')->will($this->returnValue($mockQuery));
145 $this->assertSame($expectedResult, $mockRepository->findAll());
151 public function findByUidCreatesQueryAndReturnsResultOfExecuteCallAndCachesTheObject() {
154 $mockPersistenceSession = $this->getMock('Tx_Extbase_Persistence_Session');
156 $mockQuery = $this->getMock('Tx_Extbase_Persistence_QueryInterface');
157 $mockQuery->expects($this->once())->method('withUid')->with($fakeUid)->will($this->returnValue('matchCriteria'));
158 $mockQuery->expects($this->once())->method('matching')->with('matchCriteria')->will($this->returnValue($mockQuery));
159 $mockQuery->expects($this->once())->method('execute')->will($this->returnValue(array('one', 'two')));
161 $mockIdentityMap = $this->getMock('Tx_Extbase_Persistence_IdentityMap');
162 $mockIdentityMap->expects($this->once())->method('hasIdentifier')->will($this->returnValue(FALSE));
163 $mockIdentityMap->expects($this->once())->method('registerObject')->with('one', 123);
165 $mockRepository = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Repository'), array('createQuery'), array(), '', FALSE);
166 $mockRepository->_set('identityMap', $mockIdentityMap);
167 $mockRepository->expects($this->once())->method('createQuery')->will($this->returnValue($mockQuery));
169 $this->assertSame('one', $mockRepository->findByUid($fakeUid));
175 public function findByUidReturnsAlreadyCachedObject() {
178 $mockPersistenceSession = $this->getMock('Tx_Extbase_Persistence_Session');
180 $mockIdentityMap = $this->getMock('Tx_Extbase_Persistence_IdentityMap');
181 $mockIdentityMap->expects($this->once())->method('hasIdentifier')->will($this->returnValue(TRUE));
182 $mockIdentityMap->expects($this->once())->method('getObjectByIdentifier')->with(123, 'MyObjectType')->will($this->returnValue('one'));
184 $mockRepository = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Repository'), array('createQuery'), array(), '', FALSE);
185 $mockRepository->_set('identityMap', $mockIdentityMap);
186 $mockRepository->_set('objectType', 'MyObjectType');
187 $mockRepository->expects($this->never())->method('createQuery');
189 $this->assertSame('one', $mockRepository->findByUid($fakeUid));
194 * @expectedException InvalidArgumentException
196 public function findByUidResultsInAnExceptionForInvalidUidArgument() {
197 $mockRepository = $this->getMock('Tx_Extbase_Persistence_Repository', array('createQuery'), array(), '', FALSE);
198 $mockRepository->findByUid(-123);
202 * Replacing a reconstituted object (which has a uid) by a new object
203 * will ask the persistence backend to replace them accordingly in the
209 public function replaceReconstitutedObjectByNewObject() {
210 $existingObject = new $this->aggregateRootClassName
;
211 $newObject = new $this->aggregateRootClassName
;
213 $mockPersistenceBackend = $this->getMock('Tx_Extbase_Persistence_BackendInterface');
214 $mockPersistenceBackend->expects($this->once())->method('getIdentifierByObject')->with($existingObject)->will($this->returnValue(123));
215 $mockPersistenceBackend->expects($this->once())->method('replaceObject')->with($existingObject, $newObject);
217 $mockPersistenceSession = $this->getMock('Tx_Extbase_Persistence_Session', array(), array(), '', FALSE);
218 $mockPersistenceSession->expects($this->once())->method('unregisterReconstitutedObject')->with($existingObject);
219 $mockPersistenceSession->expects($this->once())->method('registerReconstitutedObject')->with($newObject);
221 $mockPersistenceManager = $this->getMock('Tx_Extbase_Persistence_ManagerInterface');
222 $mockPersistenceManager->expects($this->once())->method('getSession')->will($this->returnValue($mockPersistenceSession));
223 $mockPersistenceManager->expects($this->once())->method('getBackend')->will($this->returnValue($mockPersistenceBackend));
225 $mockAddedObjects = $this->getMock('Tx_Extbase_Persistence_ObjectStorage');
227 $mockRemovedObjects = $this->getMock('Tx_Extbase_Persistence_ObjectStorage');
229 $mockRepository = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Repository'), array('dummy'), array(), '', FALSE);
230 $mockRepository->_set('persistenceManager', $mockPersistenceManager);
231 $mockRepository->_set('objectType', $this->aggregateRootClassName
);
232 $mockRepository->_set('addedObjects', $mockAddedObjects);
233 $mockRepository->_set('removedObjects', $mockRemovedObjects);
234 $mockRepository->replace($existingObject, $newObject);
239 * @expectedException Tx_Extbase_Persistence_Exception_UnknownObject
241 public function tryingToReplaceAnUnknownObjectResultsInAnException() {
242 $existingObject = new $this->aggregateRootClassName
;
243 $newObject = new $this->aggregateRootClassName
;
245 $mockPersistenceBackend = $this->getMock('Tx_Extbase_Persistence_Backend', array('getIdentifierByObject'), array(), '', FALSE);
246 $mockPersistenceBackend->expects($this->once())->method('getIdentifierByObject')->with($existingObject)->will($this->returnValue(NULL));
248 $mockPersistenceManager = $this->getMock('Tx_Extbase_Persistence_ManagerInterface');
249 $mockPersistenceManager->expects($this->once())->method('getBackend')->will($this->returnValue($mockPersistenceBackend));
251 $mockAddedObjects = $this->getMock('Tx_Extbase_Persistence_ObjectStorage');
253 $mockRemovedObjects = $this->getMock('Tx_Extbase_Persistence_ObjectStorage');
255 $mockRepository = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Repository'), array('dummy'), array(), '', FALSE);
256 $mockRepository->_set('persistenceManager', $mockPersistenceManager);
257 $mockRepository->_set('objectType', $this->aggregateRootClassName
);
258 $mockRepository->_set('addedObjects', $mockAddedObjects);
259 $mockRepository->_set('removedObjects', $mockRemovedObjects);
260 $mockRepository->replace($existingObject, $newObject);
266 public function magicCallMethodAcceptsFindBySomethingCallsAndExecutesAQueryWithThatCriteria() {
267 $mockPersistenceSession = $this->getMock('Tx_Extbase_Persistence_Session', array(), array(), '', FALSE);
269 $mockQuery = $this->getMock('Tx_Extbase_Persistence_QueryInterface');
270 $mockQuery->expects($this->once())->method('equals')->with('fooBaz', 'bar')->will($this->returnValue('matchCriteria'));
271 $mockQuery->expects($this->once())->method('matching')->with('matchCriteria')->will($this->returnValue($mockQuery));
272 $mockQuery->expects($this->once())->method('execute')->will($this->returnValue(array('baz', 'quux')));
274 $mockRepository = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Repository'), array('createQuery'), array(), '', FALSE);
275 $mockRepository->expects($this->once())->method('createQuery')->will($this->returnValue($mockQuery));
277 $this->assertSame(array('baz', 'quux'), $mockRepository->findByFooBaz('bar'));
283 public function magicCallMethodAcceptsFindOneBySomethingCallsAndExecutesAQueryWithThatCriteria() {
284 $mockPersistenceSession = $this->getMock('Tx_Extbase_Persistence_Session', array(), array(), '', FALSE);
286 $mockQuery = $this->getMock('Tx_Extbase_Persistence_QueryInterface');
287 $mockQuery->expects($this->once())->method('equals')->with('foo', 'bar')->will($this->returnValue('matchCriteria'));
288 $mockQuery->expects($this->once())->method('matching')->with('matchCriteria')->will($this->returnValue($mockQuery));
289 $mockQuery->expects($this->once())->method('setLimit')->with(1)->will($this->returnValue($mockQuery));
290 $mockQuery->expects($this->once())->method('execute')->will($this->returnValue(array('baz', 'foo')));
292 $mockRepository = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Repository'), array('createQuery'), array(), '', FALSE);
293 $mockRepository->expects($this->once())->method('createQuery')->will($this->returnValue($mockQuery));
295 $this->assertSame('baz', $mockRepository->findOneByFoo('bar'));
300 * @expectedException Tx_Extbase_Persistence_Exception_UnsupportedMethod
302 public function magicCallMethodTriggersAnErrorIfUnknownMethodsAreCalled() {
303 $mockRepository = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Repository'), array('dummy'), array(), '', FALSE);
304 $mockRepository->__call('foo', array());