PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/tests/Shanty/Mongo/DocumentTest.php

https://github.com/joedevon/Shanty-Mongo
PHP | 1202 lines | 906 code | 186 blank | 110 comment | 3 complexity | 3facb97d1da19ec2e01c3c0a57a377e0 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'TestSetup.php';
  3. require_once 'Shanty/Mongo/Collection.php';
  4. require_once 'Shanty/Mongo/Document.php';
  5. require_once 'Shanty/Mongo/Connection/StackTest.php';
  6. require_once 'Shanty/Mongo/Connection/GroupTest.php';
  7. class Shanty_Mongo_DocumentTest extends Shanty_Mongo_TestSetup
  8. {
  9. public function setUp()
  10. {
  11. parent::setUp();
  12. $this->_bob = My_ShantyMongo_User::find('4c04516a1f5f5e21361e3ab0');
  13. $this->_cherry = My_ShantyMongo_User::find('4c04516f1f5f5e21361e3ab1');
  14. $this->_roger = My_ShantyMongo_User::find('4c0451791f5f5e21361e3ab2');
  15. $this->_articleRegular = My_ShantyMongo_Article::find('4c04516f1f5f5e21361e3ac1');
  16. $this->_articleBroken = My_ShantyMongo_Article::find('4c04516f1f5f5e21361e3ac2');
  17. }
  18. public function testHasReference()
  19. {
  20. $this->assertFalse($this->_roger->hasReference('bestFriend'));
  21. $this->assertTrue($this->_bob->hasReference('bestFriend'));
  22. }
  23. public function testConstruct()
  24. {
  25. $student = new My_ShantyMongo_Student();
  26. $this->assertTrue($student->isNewDocument());
  27. $this->assertTrue($student->isRootDocument());
  28. $this->assertTrue($student->isConnected());
  29. $this->assertTrue($student->hasKey());
  30. $this->assertTrue($student->hasId());
  31. $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_OBJECT, $student->getId());
  32. $this->assertEquals('MongoId', get_class($student->getId()));
  33. $this->assertEquals(My_ShantyMongo_Student::getCollectionRequirements(), $student->getRequirements());
  34. $type = array(
  35. 'My_ShantyMongo_Student',
  36. 'My_ShantyMongo_User'
  37. );
  38. $this->assertEquals($type, $student->getInheritance());
  39. $criteria = $student->getCriteria();
  40. $this->assertTrue(array_key_exists('_id', $criteria));
  41. $this->assertEquals($student->getId()->__toString(), $criteria['_id']->__toString());
  42. $name = new My_ShantyMongo_Name();
  43. $this->assertTrue($name->isNewDocument());
  44. $this->assertTrue($name->isRootDocument());
  45. $this->assertFalse($name->isConnected());
  46. $this->assertFalse($name->hasKey());
  47. $this->assertFalse($name->hasId());
  48. $this->assertEquals(array(), $name->getInheritance());
  49. $config = array(
  50. 'new' => false,
  51. 'connectionGroup' => 'default',
  52. 'db' => TESTS_SHANTY_MONGO_DB,
  53. 'collection' => 'user',
  54. 'pathToDocument' => 'name',
  55. 'requirementModifiers' => array(
  56. 'middle' => array('Required' => null)
  57. )
  58. );
  59. $name = new My_ShantyMongo_Name(array('first'=>'Jerry'), $config);
  60. $this->assertFalse($name->isNewDocument());
  61. $this->assertFalse($name->isRootDocument());
  62. $this->assertTrue($name->isConnected());
  63. $this->assertEquals($name->first, 'Jerry');
  64. $requirements = array(
  65. '_id' => array('Validator:MongoId' => null),
  66. '_type' => array('Array' => null),
  67. 'first' => array('Required' => null),
  68. 'last' => array('Required' => null),
  69. 'middle' => array('Required' => null),
  70. );
  71. $this->assertEquals($requirements, $name->getRequirements());
  72. // Test input data initialisation
  73. $data = array(
  74. 'name' => array('first'=>'Jerry', 'last' => 'Springer'),
  75. 'addresses' => array(
  76. array(
  77. 'street' => '35 Sheep Lane',
  78. 'suburb' => 'Sheep Heaven',
  79. 'state' => 'New Zealand',
  80. 'postcode' => '2345',
  81. 'country' => 'New Zealand',
  82. )
  83. ),
  84. 'friends' => array(
  85. MongoDBRef::create('user', new MongoId('4c04516f1f5f5e21361e3ab1')),
  86. MongoDBRef::create('user', new MongoId('4c0451791f5f5e21361e3ab2')),
  87. ),
  88. );
  89. $student = new My_ShantyMongo_Student($data);
  90. $this->assertNotNull($student->name);
  91. $this->assertEquals('My_ShantyMongo_Name', get_class($student->name));
  92. $this->assertEquals('Sheep Heaven', $student->addresses[0]->suburb);
  93. $this->assertEquals('My_ShantyMongo_ArtStudent', get_class($student->friends[1]));
  94. }
  95. public function testGetHasId()
  96. {
  97. $this->assertTrue($this->_bob->hasId());
  98. $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_OBJECT, $this->_bob->getId());
  99. $this->assertEquals('MongoId', get_class($this->_bob->getId()));
  100. }
  101. public function testGetInheritance()
  102. {
  103. $type = array(
  104. 'My_ShantyMongo_Teacher',
  105. 'My_ShantyMongo_User'
  106. );
  107. $this->assertEquals($type, $this->_bob->getInheritance());
  108. }
  109. public function testGetSetHasConfigAttribute()
  110. {
  111. $this->assertFalse($this->_bob->hasConfigAttribute('magic'));
  112. $this->assertNull($this->_bob->getConfigAttribute('magic'));
  113. $this->_bob->setConfigAttribute('magic', 'somevalue');
  114. $this->assertTrue($this->_bob->hasConfigAttribute('magic'));
  115. $this->assertEquals('somevalue', $this->_bob->getConfigAttribute('magic'));
  116. }
  117. public function testGetPathToDocument()
  118. {
  119. $this->assertNull($this->_bob->getPathToDocument());
  120. $this->_bob->setPathToDocument('stange path');
  121. $this->assertEquals('stange path', $this->_bob->getPathToDocument());
  122. }
  123. public function testGetPathToProperty()
  124. {
  125. $this->assertEquals('name', $this->_bob->getPathToProperty('name'));
  126. $this->assertEquals('name.first', $this->_bob->name->getPathToProperty('first'));
  127. }
  128. public function testIsRootDocument()
  129. {
  130. $this->assertTrue($this->_bob->isRootDocument());
  131. $this->assertFalse($this->_bob->name->isRootDocument());
  132. }
  133. public function hasKey()
  134. {
  135. $this->assertTrue($this->_bob->hasKey());
  136. $this->assertFalse($this->_bob->name->hasKey());
  137. }
  138. public function testIsParentDocumentSet()
  139. {
  140. $this->assertFalse($this->_bob->isParentDocumentSet());
  141. // Butcher an instance so it thinks it's parent is a document set
  142. $sarah = new My_ShantyMongo_User(null, array('parentIsDocumentSet' => true));
  143. $this->assertTrue($sarah->isParentDocumentSet());
  144. }
  145. public function testGetSetHasCriteria()
  146. {
  147. $this->assertEquals(array('_id' => new MongoId('4c04516a1f5f5e21361e3ab0')), $this->_bob->getCriteria());
  148. $this->assertFalse($this->_bob->hasCriteria('username'));
  149. $this->_bob->setCriteria('username', 'bobjones');
  150. $this->assertTrue($this->_bob->hasCriteria('username'));
  151. $this->assertEquals('bobjones', $this->_bob->getCriteria('username'));
  152. $this->assertEquals(array('_id' => new MongoId('4c04516a1f5f5e21361e3ab0'), 'username' => 'bobjones'), $this->_bob->getCriteria());
  153. }
  154. public function test_GetMongoDb()
  155. {
  156. $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_OBJECT, $this->_bob->_getMongoDb());
  157. $this->assertEquals(TESTS_SHANTY_MONGO_DB, $this->_bob->_getMongoDb()->__toString());
  158. $connection = new Shanty_Mongo_Connection('localhost');
  159. Shanty_Mongo::addSlave($connection);
  160. $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_OBJECT, $this->_bob->_getMongoDb(false));
  161. $this->assertEquals(TESTS_SHANTY_MONGO_DB, $this->_bob->_getMongoDb(false)->__toString());
  162. }
  163. /**
  164. * @expectedException Shanty_Mongo_Exception
  165. */
  166. public function test_GetMongoDbException()
  167. {
  168. $name = new My_ShantyMongo_Name();
  169. $name->_getMongoDb();
  170. }
  171. public function test_GetMongoCollection()
  172. {
  173. $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_OBJECT, $this->_bob->_getMongoCollection());
  174. $this->assertEquals(TESTS_SHANTY_MONGO_DB.'.user', $this->_bob->_getMongoCollection()->__toString());
  175. }
  176. /**
  177. * @expectedException Shanty_Mongo_Exception
  178. */
  179. public function testGetMongoCollectionException()
  180. {
  181. $name = new My_ShantyMongo_Name();
  182. $name->_getMongoCollection();
  183. }
  184. public function testGetRequirements()
  185. {
  186. $requirements = array(
  187. '_id' => array('Validator:MongoId' => null),
  188. '_type' => array('Array' => null),
  189. 'name' => array('Document:My_ShantyMongo_Name' => null, 'Required' => null),
  190. 'email' => array('Required' => null, 'Validator:EmailAddress' => null),
  191. 'addresses' => array('DocumentSet' => null),
  192. 'addresses.$.street' => array('Required' => null),
  193. 'addresses.$.state' => array('Required' => null),
  194. 'addresses.$.suburb' => array('Required' => null),
  195. 'addresses.$.postcode' => array('Required' => null),
  196. 'friends' => array('DocumentSet:My_ShantyMongo_Users' => null),
  197. 'friends.$' => array('Document:My_ShantyMongo_User' => null, 'AsReference' => null),
  198. 'sex' => array('Required' => null, 'Validator:InArray' => array('F', 'M')),
  199. 'partner' => array('Document:My_ShantyMongo_User' => null, 'AsReference' => null),
  200. 'faculty' => array('Required' => null)
  201. );
  202. $this->assertEquals($requirements, $this->_bob->getRequirements());
  203. $requirements2 = $requirements = array(
  204. '$.street' => array('Required' => null),
  205. '$.state' => array('Required' => null),
  206. '$.suburb' => array('Required' => null),
  207. '$.postcode' => array('Required' => null),
  208. );
  209. $this->assertEquals($requirements2, $this->_bob->getRequirements('addresses.'));
  210. }
  211. public function testHasRequirement()
  212. {
  213. $this->assertTrue($this->_bob->hasRequirement('name', 'Required'));
  214. $this->assertEquals('My_ShantyMongo_Name', $this->_bob->hasRequirement('name', 'Document'));
  215. $this->assertEquals('My_ShantyMongo_Users', $this->_bob->hasRequirement('friends', 'DocumentSet'));
  216. $this->assertEquals('Shanty_Mongo_DocumentSet', $this->_bob->hasRequirement('addresses', 'DocumentSet'));
  217. $this->assertFalse($this->_bob->hasRequirement('age', 'Required'));
  218. $this->assertFalse($this->_bob->hasRequirement('name', 'Validator:EmailAddress'));
  219. $this->assertFalse($this->_bob->hasRequirement('sex', 'Document'));
  220. }
  221. /**
  222. * @expectedException Shanty_Mongo_Exception
  223. */
  224. public function testHasRequirementNoClassException()
  225. {
  226. $this->_bob->addRequirement('preferences', 'Document:My_ShantyMongo_Preferences');
  227. $this->_bob->hasRequirement('preferences', 'Document');
  228. }
  229. /**
  230. * @expectedException Shanty_Mongo_Exception
  231. */
  232. public function testHasRequirementInvalidDocumentException()
  233. {
  234. $this->_bob->addRequirement('preferences', 'Document:My_ShantyMongo_InvalidDocument');
  235. $this->_bob->hasRequirement('preferences', 'Document');
  236. }
  237. /**
  238. * @depends testGetRequirements
  239. */
  240. public function testApplyRequirementsDirty()
  241. {
  242. $totalRequirements = array(
  243. '_id' => array('Validator:MongoId' => null),
  244. '_type' => array('Array' => null),
  245. 'name' => array('Document:My_ShantyMongo_Name' => null, 'Required' => null),
  246. 'email' => array('Required' => null, 'Validator:EmailAddress' => null),
  247. 'addresses' => array('DocumentSet' => null),
  248. 'addresses.$.street' => array('Required' => null),
  249. 'addresses.$.state' => array('Required' => null),
  250. 'addresses.$.suburb' => array('Required' => null),
  251. 'addresses.$.postcode' => array('Required' => null),
  252. 'friends' => array('DocumentSet:My_ShantyMongo_Users' => null),
  253. 'friends.$' => array('Document:My_ShantyMongo_User' => null, 'AsReference' => null),
  254. 'sex' => array('Required' => null, 'Validator:InArray' => array('F', 'M')),
  255. 'partner' => array('Document:My_ShantyMongo_User' => null, 'AsReference' => null),
  256. 'faculty' => array('Required' => null),
  257. 'birthday' => array('Required' => null),
  258. 'mobile' => array('Required' => null, 'Validator:Digits' => null)
  259. );
  260. $this->_bob->applyRequirements(array(
  261. 'birthday' => 'Required',
  262. 'mobile' => array('Required', 'Validator:Digits')
  263. ));
  264. $this->assertEquals($totalRequirements, $this->_bob->getRequirements());
  265. }
  266. /**
  267. * @depends testGetRequirements
  268. */
  269. public function testApplyRequirementsClean()
  270. {
  271. $totalRequirements = array(
  272. '_id' => array('Validator:MongoId' => null),
  273. '_type' => array('Array' => null),
  274. 'name' => array('Document:My_ShantyMongo_Name' => null, 'Required' => null),
  275. 'email' => array('Required' => null, 'Validator:EmailAddress' => null),
  276. 'addresses' => array('DocumentSet' => null),
  277. 'addresses.$.street' => array('Required' => null),
  278. 'addresses.$.state' => array('Required' => null),
  279. 'addresses.$.suburb' => array('Required' => null),
  280. 'addresses.$.postcode' => array('Required' => null),
  281. 'friends' => array('DocumentSet:My_ShantyMongo_Users' => null),
  282. 'friends.$' => array('Document:My_ShantyMongo_User' => null, 'AsReference' => null),
  283. 'sex' => array('Required' => null, 'Validator:InArray' => array('F', 'M')),
  284. 'partner' => array('Document:My_ShantyMongo_User' => null, 'AsReference' => null),
  285. 'faculty' => array('Required' => null),
  286. 'birthday' => array('Required' => null),
  287. 'mobile' => array('Required' => null, 'Validator:Digits' => null)
  288. );
  289. $this->_bob->applyRequirements(array(
  290. 'birthday' => array('Required' => null),
  291. 'mobile' => array('Required' => null, 'Validator:Digits' => null)
  292. ), false);
  293. $this->assertEquals($totalRequirements, $this->_bob->getRequirements());
  294. }
  295. /**
  296. * @depends testHasRequirement
  297. */
  298. public function testAddRequirement()
  299. {
  300. $this->assertFalse($this->_bob->hasRequirement('mobile', 'Validator:Digits'));
  301. $this->_bob->addRequirement('mobile', 'Validator:Digits');
  302. $this->assertTrue($this->_bob->hasRequirement('mobile', 'Validator:Digits'));
  303. }
  304. /**
  305. * @depends testHasRequirement
  306. */
  307. public function testRemoveRequirement()
  308. {
  309. $this->assertTrue($this->_bob->hasRequirement('name', 'Required'));
  310. $this->_bob->removeRequirement('name', 'Required');
  311. $this->assertFalse($this->_bob->hasRequirement('name', 'Required'));
  312. }
  313. public function testGetPropertiesWithRequirement()
  314. {
  315. $reqiredProperties = array(
  316. 'name',
  317. 'email',
  318. 'sex',
  319. 'faculty'
  320. );
  321. $this->assertEquals($reqiredProperties, $this->_bob->getPropertiesWithRequirement('Required'));
  322. }
  323. public function testGetValidators()
  324. {
  325. $validatorChain = $this->_bob->getValidators('email');
  326. $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_OBJECT, $validatorChain);
  327. $this->assertEquals('Zend_Validate', get_class($validatorChain));
  328. $this->assertTrue($validatorChain->isValid('email@domain.com'));
  329. $this->assertFalse($validatorChain->isValid('email#domain.com'));
  330. }
  331. public function testGetFilters()
  332. {
  333. $this->_bob->addRequirement('username', 'Filter:StringToUpper');
  334. $filterChain = $this->_bob->getFilters('username');
  335. $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_OBJECT, $filterChain);
  336. $this->assertEquals('Zend_Filter', get_class($filterChain));
  337. $this->assertEquals('BOBJONES', $filterChain->filter('bobjones'));
  338. }
  339. public function testIsValid()
  340. {
  341. $this->assertTrue($this->_bob->isValid('email', 'email@domain.com'));
  342. $this->assertFalse($this->_bob->isValid('email', 'email#domain.com'));
  343. }
  344. public function testGetProperty()
  345. {
  346. // $bob->email
  347. $this->assertEquals('bob.jones@domain.com', $this->_bob->getProperty('email'));
  348. // $bob->name->first
  349. $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_OBJECT, $this->_bob->getProperty('name'));
  350. $this->assertEquals('My_ShantyMongo_Name', get_class($this->_bob->getProperty('name')));
  351. $this->assertEquals('Bob', $this->_bob->getProperty('name')->getProperty('first'));
  352. $this->assertTrue($this->_bob->getProperty('name')->isConnected());
  353. $this->assertEquals('default', $this->_bob->getProperty('name')->getConfigAttribute('connectionGroup'));
  354. $this->assertEquals(TESTS_SHANTY_MONGO_DB, $this->_bob->getProperty('name')->getConfigAttribute('db'));
  355. $this->assertEquals('user', $this->_bob->getProperty('name')->getConfigAttribute('collection'));
  356. $this->assertEquals('name', $this->_bob->getProperty('name')->getPathToDocument());
  357. $this->assertFalse($this->_bob->getProperty('name')->getConfigAttribute('hasId'));
  358. $this->assertFalse($this->_bob->getProperty('name')->isNewDocument());
  359. // $bob->partner->name->first
  360. $cherry = $this->_bob->getProperty('partner');
  361. $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_OBJECT, $cherry);
  362. $this->assertEquals('My_ShantyMongo_User', get_class($cherry));
  363. $this->assertEquals('Cherry', $cherry->getProperty('name')->getProperty('first'));
  364. $this->assertTrue($cherry->isRootDocument());
  365. $this->assertEquals('default', $cherry->getProperty('name')->getConfigAttribute('connectionGroup'));
  366. $this->assertEquals(TESTS_SHANTY_MONGO_DB, $cherry->getProperty('name')->getConfigAttribute('db'));
  367. $this->assertEquals('user', $cherry->getProperty('name')->getConfigAttribute('collection'));
  368. // $bob->addresses[1]->street
  369. $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_OBJECT, $this->_bob->getProperty('addresses'));
  370. $this->assertEquals('Shanty_Mongo_DocumentSet', get_class($this->_bob->getProperty('addresses')));
  371. $this->assertEquals('addresses', $this->_bob->getProperty('addresses')->getPathToDocument());
  372. $this->assertEquals(2, count($this->_bob->getProperty('addresses')));
  373. $this->assertEquals('742 Evergreen Terrace', $this->_bob->getProperty('addresses')->getProperty(1)->getProperty('street'));
  374. $this->assertEquals('default', $this->_bob->getProperty('addresses')->getConfigAttribute('connectionGroup'));
  375. $this->assertEquals(TESTS_SHANTY_MONGO_DB, $this->_bob->getProperty('addresses')->getConfigAttribute('db'));
  376. $this->assertEquals('user', $this->_bob->getProperty('addresses')->getConfigAttribute('collection'));
  377. // Test get on new documents
  378. $sarah = new My_ShantyMongo_User();
  379. // $sarah->email
  380. $this->assertNull($sarah->getProperty('email'));
  381. // $sarah->name
  382. $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_OBJECT, $sarah->getProperty('name'));
  383. $this->assertEquals('My_ShantyMongo_Name', get_class($sarah->getProperty('name')));
  384. // $sarah->addresses
  385. $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_OBJECT, $sarah->getProperty('addresses'));
  386. $this->assertEquals('Shanty_Mongo_DocumentSet', get_class($sarah->getProperty('addresses')));
  387. $this->assertEquals(0, count($sarah->getProperty('addresses')));
  388. // Test Array's
  389. $this->assertTrue(is_array($this->_articleRegular->tags));
  390. $this->assertEquals(array('awesome', 'howto', 'mongodb'), $this->_articleRegular->tags);
  391. // Test broken references
  392. $this->assertNull($this->_articleBroken->author);
  393. }
  394. /**
  395. * @depends testGetProperty
  396. */
  397. public function testSetProperty()
  398. {
  399. $this->_bob->email = null;
  400. $this->assertNull($this->_bob->email);
  401. $objStorage = new SplObjectStorage();
  402. $objStorage->attach($this->_cherry);
  403. $this->_articleRegular->stakeholder = $this->_cherry;
  404. $this->assertFalse($objStorage->contains($this->_articleRegular->stakeholder));
  405. $this->assertFalse($this->_articleRegular->stakeholder->isNewDocument());
  406. $this->assertEquals($this->_users['cherry'], $this->_articleRegular->stakeholder->export());
  407. $this->assertEquals('default', $this->_articleRegular->stakeholder->getConfigAttribute('connectionGroup'));
  408. $this->assertEquals(TESTS_SHANTY_MONGO_DB, $this->_articleRegular->stakeholder->getConfigAttribute('db'));
  409. $this->assertEquals('article', $this->_articleRegular->stakeholder->getConfigAttribute('collection'));
  410. $this->assertEquals('stakeholder', $this->_articleRegular->stakeholder->getPathToDocument());
  411. $article = new My_ShantyMongo_Article();
  412. $article->title = 'Mongodb Awesomeness';
  413. $objStorage = new SplObjectStorage();
  414. $objStorage->attach($article);
  415. $this->_roger->favouriteArticle = $article;
  416. $this->assertTrue($objStorage->contains($this->_roger->favouriteArticle));
  417. $this->assertTrue($this->_roger->favouriteArticle->isNewDocument());
  418. $this->assertEquals($article->export(), $this->_roger->favouriteArticle->export());
  419. $this->assertEquals('default', $this->_roger->favouriteArticle->getConfigAttribute('connectionGroup'));
  420. $this->assertEquals(TESTS_SHANTY_MONGO_DB, $this->_roger->favouriteArticle->getConfigAttribute('db'));
  421. $this->assertEquals('user', $this->_roger->favouriteArticle->getConfigAttribute('collection'));
  422. $this->assertEquals('favouriteArticle', $this->_roger->favouriteArticle->getPathToDocument());
  423. $this->_bob->addRequirement('config', 'Document');
  424. $this->_bob->addRequirement('config.date', 'Required');
  425. $this->_bob->config = new Shanty_Mongo_Document();
  426. $requirements = array(
  427. '_id' => array('Validator:MongoId' => null),
  428. '_type' => array('Array' => null),
  429. 'date' => array('Required' => null)
  430. );
  431. $this->assertEquals($requirements, $this->_bob->config->getRequirements());
  432. }
  433. /**
  434. * @expectedException Shanty_Mongo_Exception
  435. */
  436. public function testSetPropertyPrivateProperty()
  437. {
  438. $this->_bob->_private = 'invalid email';
  439. }
  440. /**
  441. * @expectedException Shanty_Mongo_Exception
  442. */
  443. public function testSetPropertyInvalidValueException()
  444. {
  445. $this->_bob->email = 'invalid email';
  446. }
  447. public function testHasProperty()
  448. {
  449. $this->assertTrue($this->_bob->hasProperty('email'));
  450. $this->assertFalse($this->_bob->hasProperty('birthday'));
  451. $this->_bob->email = null;
  452. $this->assertFalse($this->_bob->hasProperty('email'));
  453. $this->_bob->email = 'email@domain.com';
  454. $this->assertTrue($this->_bob->hasProperty('email'));
  455. }
  456. public function testGetPropertyKeys()
  457. {
  458. $properties = array(
  459. '_id',
  460. '_type',
  461. 'name',
  462. 'addresses',
  463. 'friends',
  464. 'faculty',
  465. 'email',
  466. 'sex',
  467. 'partner',
  468. 'bestFriend'
  469. );
  470. $this->assertEquals($properties, $this->_bob->getPropertyKeys());
  471. $properties = array(
  472. '_id',
  473. 'birthday',
  474. 'preferences',
  475. '_type',
  476. 'name',
  477. 'addresses',
  478. 'friends',
  479. 'faculty',
  480. 'sex',
  481. 'partner',
  482. 'bestFriend'
  483. );
  484. $this->_bob->email = null;
  485. $this->_bob->birthday = 'November';
  486. $this->_bob->preferences = new Shanty_Mongo_Document();
  487. $this->_bob->preferences->color = 'Blue';
  488. $this->_bob->crimes = new Shanty_Mongo_Document();
  489. $this->assertEquals($properties, $this->_bob->getPropertyKeys());
  490. }
  491. public function testCreateReference()
  492. {
  493. $reference = $this->_bob->createReference();
  494. $this->assertTrue(MongoDBRef::isRef($reference));
  495. $this->assertEquals('user', $reference['$ref']);;
  496. $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_OBJECT, $reference['$id']);
  497. $this->assertEquals('MongoId', get_class($reference['$id']));
  498. $this->assertEquals('4c04516a1f5f5e21361e3ab0', $reference['$id']->__toString());
  499. }
  500. /**
  501. * @expectedException Shanty_Mongo_Exception
  502. */
  503. public function testCreateReferenceNotRootDocumentException()
  504. {
  505. $this->_bob->name->createReference();
  506. }
  507. /**
  508. * @expectedException Shanty_Mongo_Exception
  509. */
  510. public function testCreateReferenceNoCollectionException()
  511. {
  512. $name = new My_ShantyMongo_Name();
  513. $name->createReference();
  514. }
  515. public function testIsReference()
  516. {
  517. $roger = $this->_bob->bestFriend;
  518. $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_OBJECT, $roger);
  519. $this->assertEquals('Shanty_Mongo_Document', get_class($roger));
  520. $this->assertTrue($this->_bob->isReference($roger));
  521. }
  522. public function testExport()
  523. {
  524. $this->assertEquals($this->_users['bob'], $this->_bob->export());
  525. $this->_bob->name->first = 'Bobby';
  526. $this->_bob->addresses = null;
  527. $this->_bob->favouriteColour = 'Blue';
  528. $this->_bob->config = new Shanty_Mongo_Document(); // Empty documents don't get saved
  529. // Load references into memory to make sure they are exported correctly as references
  530. $this->_bob->partner;
  531. $this->_bob->bestFriend;
  532. $bobRaw = $this->_users['bob'];
  533. $bobRaw['name']['first'] = 'Bobby';
  534. unset($bobRaw['addresses']);
  535. $bobRaw['favouriteColour'] = 'Blue';
  536. $this->assertEquals($bobRaw, $this->_bob->export());
  537. }
  538. /**
  539. * @expectedException Shanty_Mongo_Exception
  540. */
  541. public function testExportRequiredException()
  542. {
  543. $this->_bob->email = null;
  544. $this->_bob->export();
  545. }
  546. public function testIsNewDocument()
  547. {
  548. $this->assertFalse($this->_bob->isNewDocument());
  549. $this->assertFalse($this->_bob->name->isNewDocument());
  550. $sarah = new My_ShantyMongo_User();
  551. $this->assertTrue($sarah->isNewDocument());
  552. $this->assertTrue($sarah->name->isNewDocument());
  553. }
  554. public function testIsEmpty()
  555. {
  556. $this->assertFalse($this->_bob->isEmpty());
  557. $this->assertFalse($this->_bob->name->isEmpty());
  558. $this->_bob->name->first = null;
  559. $this->_bob->name->last = null;
  560. $this->assertTrue($this->_bob->name->isEmpty());
  561. $this->_bob->name->first = 'Bob';
  562. $this->assertFalse($this->_bob->name->isEmpty());
  563. $this->assertFalse($this->_bob->addresses->isEmpty());
  564. $this->_bob->addresses[0]->street = null;
  565. $this->_bob->addresses[0]->suburb = null;
  566. $this->_bob->addresses[0]->state = null;
  567. $this->_bob->addresses[0]->postcode = null;
  568. $this->_bob->addresses[0]->country = null;
  569. $this->_bob->addresses[1] = null;
  570. $this->assertTrue($this->_bob->addresses->isEmpty());
  571. $user = new My_ShantyMongo_User();
  572. $this->assertFalse($user->isEmpty());
  573. $user->name->first = 'Madeline';
  574. $this->assertFalse($user->name->isEmpty());
  575. $this->assertFalse($user->isEmpty());
  576. $user->name->first = null;
  577. $this->assertTrue($user->name->isEmpty());
  578. }
  579. public function testSaveBasic()
  580. {
  581. $this->_bob->name->first = 'Bobby';
  582. $this->_bob->addresses = null;
  583. $this->_bob->save();
  584. $bobRaw = $this->_users['bob'];
  585. $bobRaw['name']['first'] = 'Bobby';
  586. unset($bobRaw['addresses']);
  587. $this->assertEquals($bobRaw, $this->_userCollection->findOne(array('_id' => new MongoId('4c04516a1f5f5e21361e3ab0'))));
  588. }
  589. public function testSaveWholeDocument()
  590. {
  591. $this->_bob->name->last = 'Johnes';
  592. $this->_bob->addresses = null;
  593. $this->_bob->save(true);
  594. $bobRaw = $this->_users['bob'];
  595. $bobRaw['name']['last'] = 'Johnes';
  596. unset($bobRaw['addresses']);
  597. $this->assertEquals($bobRaw, $this->_userCollection->findOne(array('_id' => new MongoId('4c04516a1f5f5e21361e3ab0'))));
  598. }
  599. public function testSaveUnchangedDocument()
  600. {
  601. $this->_bob->save();
  602. $this->assertEquals($this->_users['bob'], $this->_userCollection->findOne(array('_id' => new MongoId('4c04516a1f5f5e21361e3ab0'))));
  603. }
  604. /**
  605. * Test newly added documents to a document set
  606. */
  607. public function testSaveChildOfDocumentSet()
  608. {
  609. $address = $this->_bob->addresses->new();
  610. $address->street = '35 Sheep Lane';
  611. $address->suburb = 'Sheep Heaven';
  612. $address->state = 'New Zealand';
  613. $address->postcode = '2345';
  614. $address->country = 'New Zealand';
  615. $address->save();
  616. $bobRaw = $this->_users['bob'];
  617. $addressRaw = array(
  618. 'street' => '35 Sheep Lane',
  619. 'suburb' => 'Sheep Heaven',
  620. 'state' => 'New Zealand',
  621. 'postcode' => '2345',
  622. 'country' => 'New Zealand',
  623. );
  624. $bobRaw['addresses'][] = $addressRaw;
  625. $this->assertEquals($bobRaw, $this->_userCollection->findOne(array('_id' => new MongoId('4c04516a1f5f5e21361e3ab0'))));
  626. }
  627. /**
  628. * @expectedException Shanty_Mongo_Exception
  629. */
  630. public function testSaveChildOfDocumentSetSaveException()
  631. {
  632. $address = $this->_bob->addresses->new();
  633. $address->street = '35 Sheep Lane';
  634. $address->suburb = 'Sheep Heaven';
  635. $address->state = 'New Zealand';
  636. $address->postcode = '2345';
  637. $address->country = 'New Zealand';
  638. $address->save();
  639. $address->save(); // Should throw an exception because this document will be locked
  640. }
  641. /**
  642. * @expectedException Shanty_Mongo_Exception
  643. */
  644. public function testSaveChildOfDocumentSetDeleteException()
  645. {
  646. $address = $this->_bob->addresses->new();
  647. $address->street = '35 Sheep Lane';
  648. $address->suburb = 'Sheep Heaven';
  649. $address->state = 'New Zealand';
  650. $address->postcode = '2345';
  651. $address->country = 'New Zealand';
  652. $address->save();
  653. $address->delete(); // Should throw an exception because this document will be locked
  654. }
  655. public function testSaveNewDocument()
  656. {
  657. $user = new My_ShantyMongo_User();
  658. $user->email = 'email@domain.com';
  659. $user->sex = 'F';
  660. $user->name->first = 'Madeline';
  661. $user->name->last = 'Veenstra';
  662. $user->save();
  663. $userId = $user->getId();
  664. $userRaw = array(
  665. '_id' => new MongoId($userId->__toString()),
  666. '_type' => array(
  667. 'My_ShantyMongo_User'
  668. ),
  669. 'name' => array(
  670. 'first' => 'Madeline',
  671. 'last' => 'Veenstra',
  672. ),
  673. 'email' => 'email@domain.com',
  674. 'sex' => 'F'
  675. );
  676. $this->assertEquals($userRaw, $this->_userCollection->findOne(array('_id' => new MongoId($userId->__toString()))));
  677. }
  678. public function testSaveSafe() {
  679. $reader = new Mongo('mongodb://' . TESTS_SHANTY_MONGO_CONNECTIONSTRING);
  680. $readerDB = $reader->{TESTS_SHANTY_MONGO_DB};
  681. for($nr = 0; $nr < 1000; $nr++) {
  682. $entry = new My_ShantyMongo_Simple(array('data' => '123'));
  683. $entry->save();
  684. $found = $readerDB->simple->findOne(array('_id' => $entry->getId()));
  685. $this->assertTrue(is_array($found));
  686. $this->assertEquals($entry->export(), $found);
  687. }
  688. }
  689. /**
  690. * @expectedException Shanty_Mongo_Exception
  691. */
  692. public function testSaveNotConnectedException()
  693. {
  694. $name = new My_ShantyMongo_Name();
  695. $name->save();
  696. }
  697. public function testDelete()
  698. {
  699. // Delete subdocument
  700. $this->_roger->name->delete();
  701. $roger = $this->_userCollection->findOne(array('_id' => new MongoId('4c0451791f5f5e21361e3ab2')));
  702. $rogerData = array(
  703. '_id' => new MongoId('4c0451791f5f5e21361e3ab2'),
  704. '_type' => array(
  705. 'My_ShantyMongo_ArtStudent',
  706. 'My_ShantyMongo_Student',
  707. 'My_ShantyMongo_User'
  708. ),
  709. 'concession' => false,
  710. 'email' => 'roger.smith@domain.com',
  711. 'sex' => 'M'
  712. );
  713. $this->assertEquals($rogerData, $roger);
  714. $this->_roger->delete();
  715. $this->assertNull($this->_userCollection->findOne(array('_id' => new MongoId('4c0451791f5f5e21361e3ab2'))));
  716. }
  717. /**
  718. * Make sure an exception is thrown if document does not belong to a collection
  719. *
  720. * @expectedException Shanty_Mongo_Exception
  721. */
  722. public function testDeleteException()
  723. {
  724. $name = new My_ShantyMongo_Name();
  725. $name->delete();
  726. }
  727. public function testDeleteSafe() {
  728. $reader = new Mongo('mongodb://' . TESTS_SHANTY_MONGO_CONNECTIONSTRING);
  729. $readerDB = $reader->{TESTS_SHANTY_MONGO_DB};
  730. for($nr = 0; $nr < 1000; $nr++) {
  731. $entry = new My_ShantyMongo_Simple(array('data' => '123'));
  732. $entry->save();
  733. $entry->delete();
  734. $found = $readerDB->simple->findOne(array('_id' => $entry->getId()));
  735. if (!is_null($found)) {
  736. print($nr);
  737. die();
  738. }
  739. $this->assertNull($found);
  740. }
  741. }
  742. public function testMagicGetAndSet()
  743. {
  744. $this->assertEquals('bob.jones@domain.com', $this->_bob->email);
  745. $this->_bob->email = 'newemail@domain.com';
  746. $this->assertEquals('newemail@domain.com', $this->_bob->email);
  747. }
  748. public function testMagicIssetAndUnset()
  749. {
  750. $this->assertTrue(isset($this->_bob->email));
  751. unset($this->_bob->email);
  752. $this->assertFalse(isset($this->_bob->email));
  753. }
  754. public function testOffsetGetAndSet()
  755. {
  756. $this->assertEquals('bob.jones@domain.com', $this->_bob['email']);
  757. $this->_bob['email'] = 'newemail@domain.com';
  758. $this->assertEquals('newemail@domain.com', $this->_bob['email']);
  759. }
  760. public function testOffsetExistsAndUnset()
  761. {
  762. $this->assertTrue(isset($this->_bob['email']));
  763. unset($this->_bob['email']);
  764. $this->assertFalse(isset($this->_bob['email']));
  765. }
  766. public function testGetIterator()
  767. {
  768. $iterator = $this->_bob->getIterator();
  769. $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_OBJECT, $iterator);
  770. $this->assertEquals('Shanty_Mongo_Iterator_Default', get_class($iterator));
  771. }
  772. public function testOperations()
  773. {
  774. $this->assertEquals(array(), $this->_bob->getOperations(true));
  775. $this->assertEquals(array(), $this->_bob->name->getOperations());
  776. $this->_bob->name->addOperation('$set', 'first', 'Bobster');
  777. $this->_bob->addOperation('$set', 'email', 'email@domain.com');
  778. $operations = array(
  779. '$set' => array(
  780. 'name.first' => 'Bobster',
  781. )
  782. );
  783. $this->assertEquals($operations, $this->_bob->name->getOperations());
  784. $operations = array(
  785. '$set' => array(
  786. 'name.first' => 'Bobster',
  787. 'email' => 'email@domain.com'
  788. )
  789. );
  790. $this->assertEquals($operations, $this->_bob->getOperations(true));
  791. $this->_bob->addOperation('$inc', 'count', 3);
  792. $this->_bob->addOperation('$inc', 'age', 1);
  793. $address = array(
  794. 'street' => '2352 Long St',
  795. 'suburb' => 'Brisbane',
  796. 'state' => 'QLD',
  797. 'postcode' => '4000',
  798. 'country' => 'Australia'
  799. );
  800. $this->_bob->addOperation('$push', 'addresses', $address);
  801. $operations = array(
  802. '$inc' => array(
  803. 'count' => 3,
  804. 'age' => 1,
  805. ),
  806. '$push' => array(
  807. 'addresses' => $address
  808. ),
  809. '$set' => array(
  810. 'name.first' => 'Bobster',
  811. 'email' => 'email@domain.com'
  812. )
  813. );
  814. $this->assertEquals($operations, $this->_bob->getOperations(true));
  815. $this->_bob->purgeOperations(true);
  816. $this->assertEquals(array(), $this->_bob->getOperations(true));
  817. // Test operations of the document it's self.
  818. $address = array(
  819. 'street' => '2352 Long St',
  820. 'suburb' => 'Brisbane',
  821. 'state' => 'QLD',
  822. 'postcode' => '4000',
  823. 'country' => 'Australia'
  824. );
  825. $this->_bob->addresses->addOperation('$push', null, $address);
  826. $operations = array(
  827. '$push' => array(
  828. 'addresses' => $address
  829. )
  830. );
  831. $this->assertEquals($operations, $this->_bob->getOperations(true));
  832. }
  833. /**
  834. * @expectedException Shanty_Mongo_Exception
  835. */
  836. public function testInvalidOperation()
  837. {
  838. $this->_bob->addOperation('invalid operation', 'count', 3);
  839. }
  840. /**
  841. * @depends testOperations
  842. */
  843. public function testIncOperation()
  844. {
  845. $this->_bob->inc('count', 3);
  846. $operations = array(
  847. '$inc' => array(
  848. 'count' => 3
  849. )
  850. );
  851. $this->assertEquals($operations, $this->_bob->getOperations());
  852. }
  853. /**
  854. * @depends testOperations
  855. */
  856. public function testPushOperation()
  857. {
  858. $address = array(
  859. 'street' => '2352 Long St',
  860. 'suburb' => 'Brisbane',
  861. 'state' => 'QLD',
  862. 'postcode' => '4000',
  863. 'country' => 'Australia'
  864. );
  865. $this->_bob->push('addresses', $address);
  866. $operations = array(
  867. '$pushAll' => array(
  868. 'addresses' => array($address)
  869. )
  870. );
  871. $this->assertEquals($operations, $this->_bob->getOperations());
  872. $this->_bob->purgeOperations();
  873. $address = new Shanty_Mongo_Document();
  874. $address->street = '2352 Long St';
  875. $address->suburb = 'Brisbane';
  876. $address->state = 'QLD';
  877. $address->postcode = '4000';
  878. $address->country = 'Australia';
  879. $this->_bob->push('addresses', $address);
  880. $this->assertEquals($operations, $this->_bob->getOperations());
  881. }
  882. /**
  883. * @depends testOperations
  884. */
  885. public function testPullOperation()
  886. {
  887. $this->_bob->pull('tags', 'sexy');
  888. $operations = array(
  889. '$pullAll' => array(
  890. 'tags' => 'sexy'
  891. )
  892. );
  893. $this->assertEquals($operations, $this->_bob->getOperations());
  894. }
  895. /**
  896. * @depends testOperations
  897. */
  898. public function testAddToSetOperation()
  899. {
  900. $this->_bob->addToSet('tags', 'sexy');
  901. $operations = array(
  902. '$addToSet' => array(
  903. 'tags' => 'sexy'
  904. )
  905. );
  906. $this->assertEquals($operations, $this->_bob->getOperations());
  907. }
  908. /**
  909. * @depends testOperations
  910. */
  911. public function testPopOperation()
  912. {
  913. $this->_bob->pop('addresses', 1);
  914. $operations = array(
  915. '$pop' => array(
  916. 'addresses' => 1
  917. )
  918. );
  919. $this->assertEquals($operations, $this->_bob->getOperations());
  920. }
  921. /**
  922. * @depends testOperations
  923. */
  924. public function testProcessChanges()
  925. {
  926. $newRoger = $this->_users['roger'];
  927. $newRoger['name']['first'] = 'Bagger';
  928. $newRoger['favouriteColour'] = 'Blue';
  929. unset($newRoger['email']);
  930. $this->_roger->processChanges($newRoger);
  931. $operations = array(
  932. '$set' => array(
  933. 'name' => array(
  934. 'first' => 'Bagger',
  935. 'last' => 'Smith'
  936. ),
  937. 'favouriteColour' => 'Blue'
  938. ),
  939. '$unset' => array(
  940. 'email' => 1
  941. )
  942. );
  943. $this->assertEquals($operations, $this->_roger->getOperations());
  944. }
  945. /**
  946. * @depends testOperations
  947. * @depends testExport
  948. */
  949. public function testProcessChangesNoChanges()
  950. {
  951. $this->_bob->processChanges($this->_bob->export());
  952. $this->assertEquals(array(), $this->_bob->getOperations(true));
  953. }
  954. /**
  955. * @depends testOperations
  956. * @depends testExport
  957. */
  958. public function testProcessChangesNoChangesDataInit()
  959. {
  960. // Initialise all properties
  961. foreach ($this->_bob as $property => $value) {
  962. }
  963. $this->_bob->processChanges($this->_bob->export());
  964. $this->assertEquals(array(), $this->_bob->getOperations(true));
  965. }
  966. public function testInitHook()
  967. {
  968. $this->assertEquals(1, $this->_bob->_hookCounter['init']);
  969. }
  970. public function testPrePostInsertUpdateSaveHook()
  971. {
  972. $user = new My_ShantyMongo_User();
  973. $user->name->first = 'Stranger';
  974. $user->name->last = 'Jill';
  975. $user->email = 'jill@domain.com';
  976. $user->sex = 'M';
  977. $user->save();
  978. $user->email = 'jill@address.com';
  979. $user->save();
  980. $this->assertEquals(1, $user->_hookCounter['preInsert']);
  981. $this->assertEquals(1, $user->_hookCounter['postInsert']);
  982. $this->assertEquals(1, $user->_hookCounter['preUpdate']);
  983. $this->assertEquals(1, $user->_hookCounter['postUpdate']);
  984. $this->assertEquals(2, $user->_hookCounter['preSave']);
  985. $this->assertEquals(2, $user->_hookCounter['postSave']);
  986. }
  987. /**
  988. * Test for issue https://github.com/coen-hyde/Shanty-Mongo/issues/50
  989. *
  990. * @return void
  991. * @author Tom Holder
  992. **/
  993. public function testConcreteClassFromArray()
  994. {
  995. $data = array(
  996. 'title' => '101 reasons mongo is the bomb digidy',
  997. 'relatedArticles' => array(
  998. array(
  999. 'title' => '102 reasons mongo is the bomb digidy',
  1000. 'relatedArticles' => array(
  1001. array(
  1002. 'title' => '103 reasons mongo is the bomb digidy',
  1003. )
  1004. )
  1005. )
  1006. )
  1007. );
  1008. $article = new My_ShantyMongo_Article($data);
  1009. $this->assertInstanceOf('Shanty_Mongo_DocumentSet', $article->relatedArticles);
  1010. $this->assertInstanceOf('My_ShantyMongo_Article', $article->relatedArticles[0]);
  1011. $this->assertEquals('102 reasons mongo is the bomb digidy', $article->relatedArticles[0]->title);
  1012. $this->assertEquals('103 reasons mongo is the bomb digidy', $article->relatedArticles[0]->relatedArticles[0]->title);
  1013. $exportedData = $article->export();
  1014. $this->assertEquals('102 reasons mongo is the bomb digidy', $exportedData['relatedArticles'][0]['title']);
  1015. }
  1016. }