PageRenderTime 67ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor_full/doctrine-mongodb-odm/tests/Doctrine/ODM/MongoDB/Tests/UnitOfWorkTest.php

https://github.com/l3l0/BehatExamples
PHP | 369 lines | 257 code | 66 blank | 46 comment | 5 complexity | b1cff79b3f66aa19e4dcac866dfef20e MD5 | raw file
  1. <?php
  2. namespace Doctrine\ODM\MongoDB\Tests;
  3. use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
  4. use Doctrine\ODM\MongoDB\DocumentManager;
  5. use Doctrine\ODM\MongoDB\UnitOfWork;
  6. use Doctrine\ODM\MongoDB\Persisters\PersistenceBuilder;
  7. use Doctrine\ODM\MongoDB\Tests\Mocks\DocumentManagerMock;
  8. use Doctrine\ODM\MongoDB\Tests\Mocks\ConnectionMock;
  9. use Doctrine\ODM\MongoDB\Tests\Mocks\UnitOfWorkMock;
  10. use Doctrine\ODM\MongoDB\Tests\Mocks\DocumentPersisterMock;
  11. use Documents\ForumUser;
  12. use Documents\ForumAvatar;
  13. class UnitOfWorkTest extends \PHPUnit_Framework_TestCase
  14. {
  15. private $dm;
  16. private $uow;
  17. protected function setUp()
  18. {
  19. parent::setUp();
  20. $this->dm = DocumentManagerMock::create(new ConnectionMock());
  21. $this->uow = $this->dm->getUnitOfWork();
  22. }
  23. protected function tearDown() {
  24. unset($this->dm, $this->uow);
  25. }
  26. public function testRegisterRemovedOnNewEntityIsIgnored()
  27. {
  28. $user = new ForumUser();
  29. $user->username = 'romanb';
  30. $this->assertFalse($this->uow->isScheduledForDelete($user));
  31. $this->uow->scheduleForDelete($user);
  32. $this->assertFalse($this->uow->isScheduledForDelete($user));
  33. }
  34. /* Operational tests */
  35. public function testSavingSingleEntityWithIdentityColumnForcesInsert()
  36. {
  37. // Setup fake persister and id generator for identity generation
  38. $pb = $this->getMockPersistenceBuilder();
  39. $class = $this->dm->getClassMetadata('Documents\ForumUser');
  40. $userPersister = $this->getMockDocumentPersister($pb, $class);
  41. $this->uow->setDocumentPersister('Documents\ForumUser', $userPersister);
  42. // Test
  43. $user = new ForumUser();
  44. $user->username = 'romanb';
  45. $this->uow->persist($user);
  46. // Check
  47. $this->assertEquals(0, count($userPersister->getInserts()));
  48. $this->assertEquals(0, count($userPersister->getUpdates()));
  49. $this->assertEquals(0, count($userPersister->getDeletes()));
  50. $this->assertFalse($this->uow->isInIdentityMap($user));
  51. // should no longer be scheduled for insert
  52. $this->assertTrue($this->uow->isScheduledForInsert($user));
  53. // Now lets check whether a subsequent commit() does anything
  54. $userPersister->reset();
  55. // Test
  56. $this->uow->commit();
  57. // Check.
  58. $this->assertEquals(1, count($userPersister->getInserts()));
  59. $this->assertEquals(0, count($userPersister->getUpdates()));
  60. $this->assertEquals(0, count($userPersister->getDeletes()));
  61. // should have an id
  62. $this->assertTrue(is_numeric($user->id));
  63. }
  64. /**
  65. * Tests a scenario where a save() operation is cascaded from a ForumUser
  66. * to its associated ForumAvatar, both entities using IDENTITY id generation.
  67. */
  68. public function testCascadedIdentityColumnInsert()
  69. {
  70. // Setup fake persister and id generator for identity generation
  71. //ForumUser
  72. $pb = $this->getMockPersistenceBuilder();
  73. $class = $this->dm->getClassMetadata('Documents\ForumUser');
  74. $userPersister = $this->getMockDocumentPersister($pb, $class);
  75. $this->uow->setDocumentPersister('Documents\ForumUser', $userPersister);
  76. // ForumAvatar
  77. $pb = $this->getMockPersistenceBuilder();
  78. $class = $this->dm->getClassMetadata('Documents\ForumAvatar');
  79. $avatarPersister = $this->getMockDocumentPersister($pb, $class);
  80. $this->uow->setDocumentPersister('Documents\ForumAvatar', $avatarPersister);
  81. // Test
  82. $user = new ForumUser();
  83. $user->username = 'romanb';
  84. $avatar = new ForumAvatar();
  85. $user->avatar = $avatar;
  86. $this->uow->persist($user); // save cascaded to avatar
  87. $this->uow->commit();
  88. $this->assertTrue(is_numeric($user->id));
  89. $this->assertTrue(is_numeric($avatar->id));
  90. $this->assertEquals(1, count($userPersister->getInserts()));
  91. $this->assertEquals(0, count($userPersister->getUpdates()));
  92. $this->assertEquals(0, count($userPersister->getDeletes()));
  93. $this->assertEquals(1, count($avatarPersister->getInserts()));
  94. $this->assertEquals(0, count($avatarPersister->getUpdates()));
  95. $this->assertEquals(0, count($avatarPersister->getDeletes()));
  96. }
  97. public function testChangeTrackingNotify()
  98. {
  99. $pb = $this->getMockPersistenceBuilder();
  100. $class = $this->dm->getClassMetadata("Doctrine\ODM\MongoDB\Tests\NotifyChangedDocument");
  101. $persister = $this->getMockDocumentPersister($pb, $class);
  102. $this->uow->setDocumentPersister('Doctrine\ODM\MongoDB\Tests\NotifyChangedDocument', $persister);
  103. $pb = $this->getMockPersistenceBuilder();
  104. $class = $this->dm->getClassMetadata("Doctrine\ODM\MongoDB\Tests\NotifyChangedRelatedItem");
  105. $itemPersister = $this->getMockDocumentPersister($pb, $class);
  106. $this->uow->setDocumentPersister('Doctrine\ODM\MongoDB\Tests\NotifyChangedRelatedItem', $itemPersister);
  107. $entity = new NotifyChangedDocument;
  108. $entity->setData('thedata');
  109. $this->uow->persist($entity);
  110. $this->uow->commit();
  111. $this->assertEquals(1, count($persister->getInserts()));
  112. $persister->reset();
  113. $this->assertTrue($this->uow->isInIdentityMap($entity));
  114. $entity->setData('newdata');
  115. $entity->setTransient('newtransientvalue');
  116. $this->assertTrue($this->uow->isScheduledForDirtyCheck($entity));
  117. $this->assertEquals(array('data' => array('thedata', 'newdata')), $this->uow->getDocumentChangeSet($entity));
  118. $item = new NotifyChangedRelatedItem();
  119. $entity->getItems()->add($item);
  120. $item->setOwner($entity);
  121. $this->uow->persist($item);
  122. $this->uow->commit();
  123. $this->assertEquals(1, count($itemPersister->getInserts()));
  124. $persister->reset();
  125. $itemPersister->reset();
  126. $entity->getItems()->removeElement($item);
  127. $item->setOwner(null);
  128. $this->assertTrue($entity->getItems()->isDirty());
  129. $this->uow->commit();
  130. $updates = $itemPersister->getUpdates();
  131. $this->assertEquals(1, count($updates));
  132. $this->assertTrue($updates[0] === $item);
  133. }
  134. public function testGetDocumentStateWithAssignedIdentity()
  135. {
  136. $pb = $this->getMockPersistenceBuilder();
  137. $class = $this->dm->getClassMetadata("Documents\CmsPhonenumber");
  138. $persister = $this->getMockDocumentPersister($pb, $class);
  139. $this->uow->setDocumentPersister('Documents\CmsPhonenumber', $persister);
  140. $ph = new \Documents\CmsPhonenumber();
  141. $ph->phonenumber = '12345';
  142. $this->assertEquals(UnitOfWork::STATE_NEW, $this->uow->getDocumentState($ph));
  143. $this->assertTrue($persister->isExistsCalled());
  144. $persister->reset();
  145. // if the document is already managed the exists() check should be skipped
  146. $this->uow->registerManaged($ph, '12345', array());
  147. $this->assertEquals(UnitOfWork::STATE_MANAGED, $this->uow->getDocumentState($ph));
  148. $this->assertFalse($persister->isExistsCalled());
  149. $ph2 = new \Documents\CmsPhonenumber();
  150. $ph2->phonenumber = '12345';
  151. $this->assertEquals(UnitOfWork::STATE_DETACHED, $this->uow->getDocumentState($ph2));
  152. $this->assertFalse($persister->isExistsCalled());
  153. }
  154. /**
  155. * @expectedException Doctrine\ODM\MongoDB\MongoDBException
  156. */
  157. public function testThrowsOnPersistOfMappedSuperclass()
  158. {
  159. $documentManager = $this->getDocumentManager();
  160. $documentManager->setClassMetadata('Documents\Address', $this->getClassMetadata('Documents\Address', 'MappedSuperclass'));
  161. $unitOfWork = $this->getUnitOfWork($documentManager);
  162. $unitOfWork->persist(new \Documents\Address());
  163. }
  164. public function testParentAssociations()
  165. {
  166. $a = new ParentAssociationTest('a');
  167. $b = new ParentAssociationTest('b');
  168. $c = new ParentAssociationTest('c');
  169. $d = new ParentAssociationTest('c');
  170. $documentManager = $this->getDocumentManager();
  171. $unitOfWork = $this->getUnitOfWork($documentManager);
  172. $unitOfWork->setParentAssociation($b, array('name' => 'b'), $a, 'b');
  173. $unitOfWork->setParentAssociation($c, array('name' => 'c'), $b, 'b.c');
  174. $unitOfWork->setParentAssociation($d, array('name' => 'd'), $c, 'b.c.d');
  175. $this->assertEquals(array(array('name' => 'd'), $c, 'b.c.d'), $unitOfWork->getParentAssociation($d));
  176. }
  177. protected function getDocumentManager()
  178. {
  179. return new \Stubs\DocumentManager();
  180. }
  181. protected function getUnitOfWork(DocumentManager $dm)
  182. {
  183. return new UnitOfWork($dm, $this->getMockEventManager(), $this->getMockHydratorFactory(), '$');
  184. }
  185. /**
  186. * Gets mock HydratorFactory instance
  187. *
  188. * @return Doctrine\ODM\MongoDB\Hydrator\HydratorFactory
  189. */
  190. private function getMockHydratorFactory()
  191. {
  192. return $this->getMockBuilder('Doctrine\ODM\MongoDB\Hydrator\HydratorFactory')
  193. ->disableOriginalClone()
  194. ->disableOriginalConstructor()
  195. ->getMock();
  196. }
  197. /**
  198. * Gets mock EventManager instance
  199. *
  200. * @return Doctrine\Common\EventManager
  201. */
  202. private function getMockEventManager()
  203. {
  204. return $this->getMockBuilder('Doctrine\Common\EventManager')
  205. ->disableOriginalClone()
  206. ->disableOriginalConstructor()
  207. ->getMock();
  208. }
  209. private function getMockPersistenceBuilder()
  210. {
  211. return $this->getMock('Doctrine\ODM\MongoDB\Persisters\PersistenceBuilder', array(), array(), '', false, false);
  212. }
  213. private function getMockDocumentPersister(PersistenceBuilder $pb, ClassMetadata $class)
  214. {
  215. return new DocumentPersisterMock($pb, $this->dm, $this->dm->getEventManager(), $this->uow, $this->dm->getHydratorFactory(), $class, '$');
  216. }
  217. protected function getClassMetadata($class, $flag)
  218. {
  219. $classMetadata = new ClassMetadata($class);
  220. $classMetadata->{'is' . ucfirst($flag)} = true;
  221. return $classMetadata;
  222. }
  223. }
  224. class ParentAssociationTest
  225. {
  226. public $name;
  227. public function __construct($name)
  228. {
  229. $this->name = $name;
  230. }
  231. }
  232. /**
  233. * @Document
  234. */
  235. class NotifyChangedDocument implements \Doctrine\Common\NotifyPropertyChanged
  236. {
  237. private $_listeners = array();
  238. /**
  239. * @Id
  240. */
  241. private $id;
  242. /**
  243. * @String
  244. */
  245. private $data;
  246. private $transient; // not persisted
  247. /** @ReferenceMany(targetDocument="NotifyChangedRelatedItem") */
  248. private $items;
  249. public function __construct() {
  250. $this->items = new \Doctrine\Common\Collections\ArrayCollection;
  251. }
  252. public function getId() {
  253. return $this->id;
  254. }
  255. public function getItems() {
  256. return $this->items;
  257. }
  258. public function setTransient($value) {
  259. if ($value != $this->transient) {
  260. $this->_onPropertyChanged('transient', $this->transient, $value);
  261. $this->transient = $value;
  262. }
  263. }
  264. public function getData() {
  265. return $this->data;
  266. }
  267. public function setData($data) {
  268. if ($data != $this->data) {
  269. $this->_onPropertyChanged('data', $this->data, $data);
  270. $this->data = $data;
  271. }
  272. }
  273. public function addPropertyChangedListener(\Doctrine\Common\PropertyChangedListener $listener)
  274. {
  275. $this->_listeners[] = $listener;
  276. }
  277. protected function _onPropertyChanged($propName, $oldValue, $newValue) {
  278. if ($this->_listeners) {
  279. foreach ($this->_listeners as $listener) {
  280. $listener->propertyChanged($this, $propName, $oldValue, $newValue);
  281. }
  282. }
  283. }
  284. }
  285. /** @Document */
  286. class NotifyChangedRelatedItem
  287. {
  288. /**
  289. * @Id
  290. */
  291. private $id;
  292. /** @ReferenceOne(targetDocument="NotifyChangedDocument") */
  293. private $owner;
  294. public function getId() {
  295. return $this->id;
  296. }
  297. public function getOwner() {
  298. return $this->owner;
  299. }
  300. public function setOwner($owner) {
  301. $this->owner = $owner;
  302. }
  303. }