Blame | Last modification | View Log | RSS feed
<?php/*** Test cases for the Cakephp mongoDB datasource.** This datasource uses Pecl Mongo (http://php.net/mongo)* and is thus dependent on PHP 5.0 and greater.** Copyright 2010, Yasushi Ichikawa http://github.com/ichikaway/** Licensed under The MIT License* Redistributions of files must retain the above copyright notice.** @copyright Copyright (c) 2010, Yasushi Ichikawa http://github.com/ichikaway/* @package mongodb* @subpackage mongodb.tests.cases.datasources* @license http://www.opensource.org/licenses/mit-license.php The MIT License*//*** Import relevant classes for testing*/App::uses('Model', 'Model');App::uses('AppModel', 'Model');App::uses('MongodbSource', 'Mongodb.Model/Datasource');/*** Post Model for the test** @package app* @subpackage app.model.post*/class Post extends AppModel {public $useDbConfig = 'test_mongo';/*** mongoSchema property** @public array* @access public*/public $primaryKey='_id';public $validate = array('uniquefield1' => array('rule' => 'isUnique','required' => false),'uniquefield2' => array('rule' => 'manualUniqueValidation','required' => false),);public $mongoSchema = array('title' => array('type' => 'string'),'body' => array('type' => 'string'),'text' => array('type' => 'text'),'uniquefield1' => array('type' => 'text'),'uniquefield2' => array('type' => 'text'),'count' => array('type' => 'integer'),'created' => array('type' => 'datetime'),'modified' => array('type' => 'datetime'),);function manualUniqueValidation($check) {$c = $this->find('count', array('conditions' => array('uniquefield2' => $check['uniquefield2'])));if ($c === 0) {return true;}return false;}}/*** Comment Model for the test** @package app* @subpackage app.model.post*/class Comment extends AppModel {public $useDbConfig = 'test_mongo';public $primaryKey = '_id';public $mongoSchema = array('post_id' => array('type' => 'integer'),'comment' => array('type' => 'string'),'comment_at' => array('type' => 'datetime'),'created' => array('type' => 'datetime'),'modified' => array('type' => 'datetime'),);}/*** MongoArticle class** @uses AppModel* @package mongodb* @subpackage mongodb.tests.cases.datasources*/class MongoArticle extends AppModel {public $useDbConfig = 'test_mongo';}/*** MongoDB Source test class** @package app* @subpackage app.model.datasources*/class MongodbSourceTest extends CakeTestCase {/*** Database Instance** @var resource* @access public*/public $mongodb;/*** Base Config** @var array* @access public**/protected $_config = array('datasource' => 'Mongodb.MongodbSource','host' => 'localhost','login' => '','password' => '','database' => 'test_mongo','port' => 27017,'prefix' => '','persistent' => true,);/*** Sets up the environment for each test method** @return void* @access public*/public function setUp() {$connections = ConnectionManager::enumConnectionObjects();if (!empty($connections['test']['classname']) && $connections['test']['classname'] === 'mongodbSource') {$config = new DATABASE_CONFIG();$this->_config = $config->test;} elseif (isset($connections['test_mongo'])) {$this->_config = $connections['test_mongo'];}if(!isset($connections['test_mongo'])) {ConnectionManager::create('test_mongo', $this->_config);}$this->Mongo = new MongodbSource($this->_config);$this->Post = ClassRegistry::init(array('class' => 'Post', 'alias' => 'Post', 'ds' => 'test_mongo'), true);$this->MongoArticle = ClassRegistry::init(array('class' => 'MongoArticle', 'alias' => 'MongoArticle', 'ds' => 'test_mongo'), true);$this->mongodb = ConnectionManager::getDataSource($this->Post->useDbConfig);$this->mongodb->connect();}/*** Destroys the environment after each test method is run** @return void* @access public*/public function tearDown() {$this->dropData();unset($this->Post);unset($this->MongoArticle);unset($this->Mongo);unset($this->mongodb);ClassRegistry::flush();}/*** get Mongod server version** @return numeric* @access public*/public function getMongodVersion() {$mongo = $this->Post->getDataSource();return $mongo->execute('db.version()');}/*** Insert data method for mongodb.** @param array insert data* @return void* @access public*/public function insertData($data) {$version = Mongo::VERSION;try {if ($version >= '1.3.0') {$this->mongodb->connection->selectDB($this->_config['database'])->selectCollection($this->Post->table)->insert($data, array('safe' => true));} else {$this->mongodb->connection->selectDB($this->_config['database'])->selectCollection($this->Post->table)->insert($data, true);}} catch (MongoException $e) {trigger_error($e->getMessage());}}/*** Drop database** @return void* @access public*/public function dropData() {try {$db = $this->mongodb->connection->selectDB($this->_config['database']);foreach($db->listCollections() as $collection) {$response = $collection->drop();}} catch (MongoException $e) {trigger_error($e->getMessage());}}/*** testCreateConnectionName** @return void* @access public*/public function testCreateConnectionName() {$config = array('datasource' => 'mongodb','host' => 'localhost','login' => '','password' => '','database' => 'test_mongo','port' => 27017,'prefix' => '','persistent' => false,);$version = '1.2.2';$expect = 'mongodb://localhost:27017';$host = $this->mongodb->createConnectionName($config, $version);$this->assertIdentical($expect, $host);$config = array('datasource' => 'mongodb','host' => 'localhost','login' => 'user','password' => 'pass','database' => 'test_mongo','port' => 27017,'prefix' => '','persistent' => false,);$version = '1.2.2';$expect = 'mongodb://user:pass@localhost:27017/test_mongo';$host = $this->mongodb->createConnectionName($config, $version);$this->assertIdentical($expect, $host);$config = array('datasource' => 'mongodb','host' => 'localhost','login' => 'user','password' => 'pass','database' => 'test_mongo','port' => 27017,'prefix' => '','persistent' => false,);$version = '1.0.0';$expect = 'user:pass@localhost:27017/test_mongo';$host = $this->mongodb->createConnectionName($config, $version);$this->assertIdentical($expect, $host);}/*** Tests connection** @return void* @access public*/public function testConnect() {$result = $this->Mongo->connect();$this->assertTrue($result);$this->assertTrue($this->Mongo->connected);$this->assertTrue($this->Mongo->isConnected());}/*** Tests the disconnect method of the Mongodb DataSource** @return void* @access public*/public function testDisconnect() {$result = $this->Mongo->disconnect();$this->assertTrue($result);$this->assertNull($this->Mongo->connected);}/*** Tests the listSources method of the Mongodb DataSource** @return void* @access public*/public function testListSources() {$this->assertTrue($this->mongodb->listSources());}/*** Tests the getMongoDb method of the Mongodb DataSource** @return void* @access public*/public function testGetMongoDb() {$obj = $this->mongodb->getMongoDb();$this->assertTrue(is_object($obj));$objName = get_class($obj);$this->assertEqual('MongoDB', $objName);}/*** Tests the Model::getMongoDb() call MongodbSource::getMongoDb** @return void* @access public*/public function testGetMongoDbFromModel() {$obj = $this->Post->getMongoDb();$this->assertTrue(is_object($obj));$objName = get_class($obj);$this->assertEqual('MongoDB', $objName);}/*** Tests the getMongoCollection method of the Mongodb DataSource** @return void* @access public*/public function testGetMongoCollection() {$obj = $this->mongodb->getMongoCollection($this->Post);$this->assertTrue(is_object($obj));$objName = get_class($obj);$this->assertEqual('MongoCollection', $objName);}/*** Tests the describe method of the Mongodb DataSource** @return void* @access public*/public function testDescribe() {$mockObj = $this->getMock('AppModel');$result = $this->mongodb->describe($mockObj);$expected = array('_id' => array('type' => 'string', 'length' => 24, 'key' => 'primary'),'created' => array('type' => 'datetime', 'default' => null),'modified' => array('type' => 'datetime', 'default' => null),);$this->assertEqual($expected, $result);$result = $this->mongodb->describe($this->Post);$expect = array('_id' => array('type' => 'string', 'length' => 24, 'key' => 'primary'),'title' => array('type' => 'string'),'body' => array('type' => 'string'),'text' => array('type' => 'text'),'uniquefield1' => array('type' => 'text'),'uniquefield2' => array('type' => 'text'),'count' => array('type' => 'integer'),'created' => array('type' => 'datetime'),'modified' => array('type' => 'datetime'),);ksort($result);ksort($expect);$this->assertEqual($expect, $result);}/*** Test truncate method*/public function testTruncate() {$this->insertData(array('title' => 'test','body' => 'aaaa','text' => 'bbbb',));$this->assertSame(1, $this->Post->find('count'));$this->mongodb->truncate($this->Post);$this->assertSame(0, $this->Post->find('count'));}/*** Test truncate method using mock*/public function testTruncateStatement() {$connection = $this->mongodb->connection;$dbname = $this->mongodb->config['database'];$tableName = $this->mongodb->fullTableName($this->Post);$this->mongodb = $this->getMock('MongodbSource',array('getMongoDb'),array($this->_config));$mongo = $this->getMock('MongoDB',array('selectCollection'),array($connection, $dbname));$mongoCollection = $this->getMock('MongoCollection',array('remove'),array($mongo, $tableName));// truncate method call MongoCollection::remove()$mongoCollection->expects($this->once())->method('remove')->with(array())->will($this->returnValue(true));$mongo->expects($this->once())->method('selectCollection')->with($tableName)->will($this->returnValue($mongoCollection));$this->mongodb->expects($this->once())->method('getMongoDb')->will($this->returnValue($mongo));$this->mongodb->truncate($this->Post);}/*** Tests find method.** @return void* @access public*/public function testFind() {$data = array('title' => 'test','body' => 'aaaa','text' => 'bbbb');$this->insertData($data);$result = $this->Post->find('all');$this->assertEqual(1, count($result));$resultData = $result[0]['Post'];$this->assertEqual(4, count($resultData));$this->assertTrue(!empty($resultData['_id']));$this->assertEqual($data['title'], $resultData['title']);$this->assertEqual($data['body'], $resultData['body']);$this->assertEqual($data['text'], $resultData['text']);}/*** Tests findBy* method** @return void* @access public*/public function testFindBy() {$data = array(array('title' => 'test','body' => 'aaaa','text' => 'bbbb'),array('title' => 'test2','body' => 'abab','text' => 'bcbc'),);foreach($data as $set) {$this->insertData($set);}$result = $this->Post->findByTitle('test');$this->assertEqual(1, count($result));$resultData = $result['Post'];$this->assertEqual(4, count($resultData));$this->assertTrue(!empty($resultData['_id']));$this->assertEqual($resultData['title'], $data[0]['title']);$this->assertEqual($resultData['body'], $data[0]['body']);$this->assertEqual($resultData['text'], $data[0]['text']);$result = $this->Post->findByBody('abab');$this->assertEqual(1, count($result));$resultData = $result['Post'];$this->assertEqual(4, count($resultData));$this->assertTrue(!empty($resultData['_id']));$this->assertEqual($data[1]['title'], $resultData['title']);$this->assertEqual($data[1]['body'], $resultData['body']);$this->assertEqual($data[1]['text'], $resultData['text']);}/*** Tests findAllBy* method** @return void* @access public*/public function testFindAllBy() {$data = array(array('title' => 'test','body' => 'abab','text' => 'bbbb'),array('title' => 'test2','body' => 'abab','text' => 'bcbc'),);foreach($data as $set) {$this->insertData($set);}$result = $this->Post->findAllByBody('abab');$this->assertEqual(2, count($result));$result = $this->Post->findAllByTitle('test2');$this->assertEqual(1, count($result));}/*** Tests save method.** @return void* @access public*/public function testSave() {$data = array('title' => 'test','body' => 'aaaa','text' => 'bbbb');$saveData['Post'] = $data;$this->Post->create();$saveResult = $this->Post->save($saveData);$this->assertTrue(!empty($saveResult) && is_array($saveResult));$result = $this->Post->find('all');$this->assertEqual(1, count($result));$resultData = $result[0]['Post'];$this->assertEqual(6, count($resultData));$this->assertTrue(!empty($resultData['_id']));$this->assertEqual($this->Post->id, $resultData['_id']);$this->assertEqual($data['title'], $resultData['title']);$this->assertEqual($data['body'], $resultData['body']);$this->assertEqual($data['text'], $resultData['text']);$this->assertTrue(is_a($resultData['created'], 'MongoDate'));$this->assertTrue(is_a($resultData['modified'], 'MongoDate'));}/*** Tests insertId after saving** @return void* @access public*/public function testCheckInsertIdAfterSaving() {$saveData['Post'] = array('title' => 'test','body' => 'aaaa','text' => 'bbbb');$this->Post->create();$saveResult = $this->Post->save($saveData);$this->assertTrue(!empty($saveResult) && is_array($saveResult));$this->assertEqual($this->Post->id, $this->Post->getInsertId());$this->assertTrue(is_string($this->Post->id));$this->assertTrue(is_string($this->Post->getInsertId()));//set Numeric _id$saveData['Post'] = array('_id' => 123456789,'title' => 'test','body' => 'aaaa','text' => 'bbbb');$this->Post->create();$saveResult = $this->Post->save($saveData);$this->assertTrue(!empty($saveResult) && is_array($saveResult));$this->assertEqual($saveData['Post']['_id'] ,$this->Post->id);$this->assertEqual($this->Post->id, $this->Post->getInsertId());$this->assertTrue(is_numeric($this->Post->id));$this->assertTrue(is_numeric($this->Post->getInsertId()));$readArray1 = $this->Post->read();$readArray2 = $this->Post->read(null, $saveData['Post']['_id']);$this->assertEqual($readArray1, $readArray2);$this->assertEqual($saveData['Post']['_id'], $readArray2['Post']['_id']);}/*** Tests saveAll method.** @return void* @access public*/public function testSaveAll() {$saveData[0]['Post'] = array('title' => 'test1','body' => 'aaaa1','text' => 'bbbb1');$saveData[1]['Post'] = array('title' => 'test2','body' => 'aaaa2','text' => 'bbbb2');$this->Post->create();$saveResult = $this->Post->saveAll($saveData);$result = $this->Post->find('all');$this->assertEqual(2, count($result));$resultData = $result[0]['Post'];$this->assertEqual(6, count($resultData));$this->assertTrue(!empty($resultData['_id']));$data = $saveData[0]['Post'];$this->assertEqual($data['title'], $resultData['title']);$this->assertEqual($data['body'], $resultData['body']);$this->assertEqual($data['text'], $resultData['text']);$this->assertTrue(is_a($resultData['created'], 'MongoDate'));$this->assertTrue(is_a($resultData['modified'], 'MongoDate'));$resultData = $result[1]['Post'];$this->assertEqual(6, count($resultData));$this->assertTrue(!empty($resultData['_id']));$data = $saveData[1]['Post'];$this->assertEqual($data['title'], $resultData['title']);$this->assertEqual($data['body'], $resultData['body']);$this->assertEqual($data['text'], $resultData['text']);$this->assertTrue(is_a($resultData['created'], 'MongoDate'));$this->assertTrue(is_a($resultData['modified'], 'MongoDate'));}/*** Tests update method.** @return void* @access public*/public function testUpdate() {$count0 = $this->Post->find('count');$data = array('title' => 'test','body' => 'aaaa','text' => 'bbbb','count' => 0);$saveData['Post'] = $data;$this->Post->create();$saveResult = $this->Post->save($saveData);$postId = $this->Post->id;$count1 = $this->Post->find('count');$this->assertIdentical($count1 - $count0, 1, 'Save failed to create one row');$this->assertTrue(!empty($saveResult) && is_array($saveResult));$this->assertTrue(!empty($postId) && is_string($postId));$findresult = $this->Post->find('all');$this->assertEqual(0, $findresult[0]['Post']['count']);$updatedata = array('title' => 'test2','body' => 'aaaa2','text' => 'bbbb2');$saveData['Post'] = $updatedata;$saveResult = $this->Post->save($saveData);$count2 = $this->Post->find('count');$this->assertIdentical($count2 - $count1, 0, 'Save test 2 created another row, it did not update the existing row');$this->assertTrue(!empty($saveResult) && is_array($saveResult));$this->assertIdentical($this->Post->id, $postId);$this->Post->create();$updatedata = array('_id' => $postId,'title' => 'test3','body' => 'aaaa3','text' => 'bbbb3');$saveData['Post'] = $updatedata;$saveResult = $this->Post->save($saveData);$count3 = $this->Post->find('count');$this->assertIdentical($count3 - $count2, 0, 'Saving with the id in the data created another row');$this->assertTrue(!empty($saveResult) && is_array($saveResult));$this->assertIdentical($this->Post->id, $postId);$this->Post->create();$updatedata = array('title' => 'test4','body' => 'aaaa4','text' => 'bbbb4');$saveData['Post'] = $updatedata;$this->Post->id = $postId;$saveResult = $this->Post->save($saveData);$count4 = $this->Post->find('count');$this->assertIdentical($count4 - $count3, 0, 'Saving with $Model->id set and no id in the data created another row');$this->assertTrue(!empty($saveResult) && is_array($saveResult));$this->assertIdentical($this->Post->id, $postId);$result = $this->Post->find('all');$this->assertEqual(1, count($result));$resultData = $result[0]['Post'];$this->assertEqual(7, count($resultData));$this->assertTrue(!empty($resultData['_id']));$this->assertEqual($this->Post->id, $resultData['_id']);$this->assertEqual($updatedata['title'], $resultData['title']);$this->assertEqual($updatedata['body'], $resultData['body']);$this->assertEqual($updatedata['text'], $resultData['text']);$this->assertEqual(0, $resultData['count']);// using $inc operator$this->Post->mongoNoSetOperator = '$inc';$this->Post->create();$updatedataIncrement = array('_id' => $postId,'count' => 1,);$saveData['Post'] = $updatedataIncrement;$saveResult = $this->Post->save($saveData);$this->assertTrue(!empty($saveResult) && is_array($saveResult));$this->assertIdentical($this->Post->id, $postId);$result = $this->Post->find('all');$this->assertEqual(1, count($result));$resultData = $result[0]['Post'];$this->assertEqual(7, count($resultData));$this->assertTrue(!empty($resultData['_id']));$this->assertEqual($this->Post->id, $resultData['_id']);$this->assertEqual($updatedata['title'], $resultData['title']); //not update$this->assertEqual($updatedata['body'], $resultData['body']); //not update$this->assertEqual($updatedata['text'], $resultData['text']); //not update$this->assertEqual(1, $resultData['count']); //incrementunset($this->Post->mongoNoSetOperator);}/*** Tests updateAll method.** @return void* @access public*/public function testUpdateAll() {$saveData[0]['Post'] = array('title' => 'test','name' => 'ichi','body' => 'aaaa1','text' => 'bbbb1');$saveData[1]['Post'] = array('title' => 'test','name' => 'ichi','body' => 'aaaa2','text' => 'bbbb2');$this->Post->create();$this->Post->saveAll($saveData);$updateData = array('name' => 'ichikawa');$conditions = array('title' => 'test');$resultUpdateAll = $this->Post->updateAll($updateData, $conditions);$this->assertTrue($resultUpdateAll);$result = $this->Post->find('all');$this->assertEqual(2, count($result));$resultData = $result[0]['Post'];$this->assertEqual(7, count($resultData));$this->assertTrue(!empty($resultData['_id']));$data = $saveData[0]['Post'];$this->assertEqual($data['title'], $resultData['title']);$this->assertEqual('ichikawa', $resultData['name']);$this->assertEqual($data['body'], $resultData['body']);$this->assertEqual($data['text'], $resultData['text']);$this->assertTrue(is_a($resultData['created'], 'MongoDate'));$this->assertTrue(is_a($resultData['modified'], 'MongoDate'));$resultData = $result[1]['Post'];$this->assertEqual(7, count($resultData));$this->assertTrue(!empty($resultData['_id']));$data = $saveData[1]['Post'];$this->assertEqual($data['title'], $resultData['title']);$this->assertEqual('ichikawa', $resultData['name']);$this->assertEqual($data['body'], $resultData['body']);$this->assertEqual($data['text'], $resultData['text']);$this->assertTrue(is_a($resultData['created'], 'MongoDate'));$this->assertTrue(is_a($resultData['modified'], 'MongoDate'));}/*** Tests updateAll method.** @return void* @access public*/public function testSetMongoUpdateOperator() {$ds = $this->Post->getDataSource();//normal$data = array('title' => 'test1', 'name' => 'ichikawa');$expect = array('$set' => array('title' => 'test1', 'name' => 'ichikawa'));$result = $ds->setMongoUpdateOperator($this->Post, $data);$this->assertEqual($expect, $result);//using $inc$data = array('title' => 'test1', 'name' => 'ichikawa', '$inc' => array('count' => 1));$expect = array('title' => 'test1', 'name' => 'ichikawa', '$inc' => array('count' => 1));$result = $ds->setMongoUpdateOperator($this->Post, $data);$this->assertEqual($expect, $result);//using $inc and modified$data = array('modified' => '2011/8/1', '$inc' => array('count' => 1));$expect = array('$set' => array('modified' => '2011/8/1'), '$inc' => array('count' => 1));$result = $ds->setMongoUpdateOperator($this->Post, $data);$this->assertEqual($expect, $result);//using $inc and updated$data = array('updated' => '2011/8/1', '$inc' => array('count' => 1));$expect = array('$set' => array('updated' => '2011/8/1'), '$inc' => array('count' => 1));$result = $ds->setMongoUpdateOperator($this->Post, $data);$this->assertEqual($expect, $result);//using $inc, $push and modified$data = array('$push' => array('tag' => 'tag1'), 'modified' => '2011/8/1', '$inc' => array('count' => 1));$expect = array('$push' => array('tag' => 'tag1'),'$set' => array('modified' => '2011/8/1'), '$inc' => array('count' => 1));$result = $ds->setMongoUpdateOperator($this->Post, $data);$this->assertEqual($expect, $result);//mongoNoSetOperator is true,// using $inc, $push and modified$this->Post->mongoNoSetOperator = true;$data = array('$push' => array('tag' => 'tag1'), 'modified' => '2011/8/1', '$inc' => array('count' => 1));$expect = array('$push' => array('tag' => 'tag1'),'modified' => '2011/8/1', '$inc' => array('count' => 1));$result = $ds->setMongoUpdateOperator($this->Post, $data);$this->assertEqual($expect, $result);//mongoNoSetOperator is $inc,$this->Post->mongoNoSetOperator = '$inc';$data = array('count' => 1);$expect = array('$inc' => array('count' => 1));$result = $ds->setMongoUpdateOperator($this->Post, $data);$this->assertEqual($expect, $result);//mongoNoSetOperator is $inc,// with modified field$this->Post->mongoNoSetOperator = '$inc';$data = array('count' => 1, 'modified' => '2011/8/1');$expect = array('$inc' => array('count' => 1),'$set' => array('modified' => '2011/8/1'));$result = $ds->setMongoUpdateOperator($this->Post, $data);$this->assertEqual($expect, $result);//mongoNoSetOperator is $inc,// with updated field$this->Post->mongoNoSetOperator = '$inc';$data = array('count' => 1, 'updated' => '2011/8/1');$expect = array('$inc' => array('count' => 1),'$set' => array('updated' => '2011/8/1'));$result = $ds->setMongoUpdateOperator($this->Post, $data);$this->assertEqual($expect, $result);}/*** Tests update method without $set operator.** @return void* @access public*/public function testUpdateWithoutMongoSchemaProperty() {$data = array('title' => 'test','body' => 'aaaa','text' => 'bbbb','count' => 0,'created' => new mongoDate(),'modified' => new mongoDate(),);$saveData['MongoArticle'] = $data;$this->MongoArticle->create();$saveResult = $this->MongoArticle->save($saveData);$postId = $this->MongoArticle->id;//using $set operator$this->MongoArticle->create();$updatedata = array('id' => $postId,'title' => 'test3','body' => 'aaaa3',);$saveData['MongoArticle'] = $updatedata;$saveResult = $this->MongoArticle->save($saveData); // using $set operator$this->assertTrue(!empty($saveResult) && is_array($saveResult));$this->assertIdentical($this->MongoArticle->id, $postId);$result = null;$result = $this->MongoArticle->find('all');$this->assertEqual(1, count($result));$resultData = $result[0]['MongoArticle'];$this->assertEqual($this->MongoArticle->id, $resultData['id']);$this->assertEqual($updatedata['title'], $resultData['title']); //update$this->assertEqual($updatedata['body'], $resultData['body']); //update$this->assertEqual($data['text'], $resultData['text']); //not update$this->assertEqual($data['count'], $resultData['count']); //not update//using $inc operator insted of $set operator$this->MongoArticle->create();$updatedataInc = array('id' => $postId,'$inc' => array('count' => 1),);$saveData['MongoArticle'] = $updatedataInc;$saveResult = $this->MongoArticle->save($saveData); // using $set operator$this->assertTrue(!empty($saveResult) && is_array($saveResult));$this->assertIdentical($this->MongoArticle->id, $postId);$result = null;$result = $this->MongoArticle->find('all');$this->assertEqual(1, count($result));$resultData = $result[0]['MongoArticle'];$this->assertEqual($this->MongoArticle->id, $resultData['id']);$this->assertEqual($updatedata['title'], $resultData['title']); //not update$this->assertEqual($updatedata['body'], $resultData['body']); //not update$this->assertEqual($data['text'], $resultData['text']); //not update$this->assertEqual(1, $resultData['count']); //increment//using $inc and $push$this->MongoArticle->create();$updatedataInc = array('id' => $postId,'$push' => array('comments' => array('_id' => new MongoId(),'created' => new MongoDate(),'vote_count' => 0,'user' => 'user1','body' => 'comment',)),'$inc' => array('count' => 1),);$saveData['MongoArticle'] = $updatedataInc;$saveResult = $this->MongoArticle->save($saveData); // using $set operator$this->assertTrue(!empty($saveResult) && is_array($saveResult));$this->assertIdentical($this->MongoArticle->id, $postId);$result = null;$result = $this->MongoArticle->find('all');$this->assertEqual(1, count($result));$resultData = $result[0]['MongoArticle'];$this->assertEqual($this->MongoArticle->id, $resultData['id']);$this->assertEqual($updatedata['title'], $resultData['title']); //not update$this->assertEqual($updatedata['body'], $resultData['body']); //not update$this->assertEqual($data['text'], $resultData['text']); //not update$this->assertEqual(2, $resultData['count']); //increment$this->assertEqual('user1', $resultData['comments'][0]['user']); //push$this->assertEqual('comment', $resultData['comments'][0]['body']); //push$this->assertEqual(1, count($resultData['comments'])); //push$this->assertTrue(!empty($resultData['created']));$this->assertTrue(!empty($resultData['modified']));//no $set operator$this->MongoArticle->mongoNoSetOperator = true;$this->MongoArticle->create();$updatedata = array('id' => $postId,'title' => 'test4','body' => 'aaaa4','count' => '1',);$saveData['MongoArticle'] = $updatedata;$saveResult = $this->MongoArticle->save($saveData);$this->assertTrue(!empty($saveResult) && is_array($saveResult));$this->assertIdentical($this->MongoArticle->id, $postId);$result = null;$result = $this->MongoArticle->find('all');$this->assertEqual(1, count($result));$resultData = $result[0]['MongoArticle'];$this->assertEqual($this->MongoArticle->id, $resultData['id']);$this->assertEqual($updatedata['title'], $resultData['title']); //update$this->assertEqual($updatedata['body'], $resultData['body']); //update$this->assertTrue(empty($resultData['text']));$this->assertEqual(1, $resultData['count']);$this->MongoArticle->mongoNoSetOperator = null;//use $push$this->MongoArticle->create();$updatedata = array('id' => $postId,'push_column' => array('push1'),);$saveData['MongoArticle'] = $updatedata;$saveResult = $this->MongoArticle->save($saveData); //use $set$result = $this->MongoArticle->find('all');$resultData = $result[0]['MongoArticle'];$this->assertEqual('test4', $resultData['title']); // no update$this->assertEqual(array('push1'), $resultData['push_column']);$this->MongoArticle->mongoNoSetOperator = '$push';$this->MongoArticle->create();$updatedata = array('id' => $postId,'push_column' => 'push2',);$saveData['MongoArticle'] = $updatedata;$saveResult = $this->MongoArticle->save($saveData); //use $push$this->assertTrue(!empty($saveResult) && is_array($saveResult));$this->assertIdentical($this->MongoArticle->id, $postId);$result = null;$result = $this->MongoArticle->find('all');$this->assertEqual(1, count($result));$resultData = $result[0]['MongoArticle'];$this->assertEqual($this->MongoArticle->id, $resultData['id']);$this->assertEqual('test4', $resultData['title']); // no update$this->assertEqual(array('push1','push2'), $resultData['push_column']); //update$this->MongoArticle->mongoNoSetOperator = null;unset($this->MongoArticle);}/*** Tests groupBy** @return void* @access public*/public function testGroupBy() {for($i = 0 ; $i < 30 ; $i++) {$saveData[$i]['Post'] = array('title' => 'test'.$i,'body' => 'aaaa'.$i,'text' => 'bbbb'.$i,'count' => $i,);}$saveData[30]['Post'] = array('title' => 'test1','body' => 'aaaa1','text' => 'bbbb1','count' => 1,);$saveData[31]['Post'] = array('title' => 'test2','body' => 'aaaa2','text' => 'bbbb2','count' => 2,);$this->Post->create();$saveResult = $this->Post->saveAll($saveData);$cond_count = 5;$query = array('key' => array('title' => true ),'initial' => array('csum' => 0),'reduce' => 'function(obj, prev){prev.csum += 1;}','options' => array('condition' => array('count' => array('$lt' => $cond_count)),),);$mongo = $this->Post->getDataSource();$result = $mongo->group($query, $this->Post);$this->assertTrue($result['ok'] == 1 && count($result['retval']) > 0);$this->assertEqual($cond_count, count($result['retval']));$this->assertEqual('test0', $result['retval'][0]['title']);$this->assertEqual('test1', $result['retval'][1]['title']);$this->assertEqual('test2', $result['retval'][2]['title']);$this->assertEqual(1, $result['retval'][0]['csum']);$this->assertEqual(2, $result['retval'][1]['csum']);$this->assertEqual(2, $result['retval'][2]['csum']);}/*** Tests query* Distinct, Group** @return void* @access public*/public function testQuery() {for($i = 0 ; $i < 30 ; $i++) {$saveData[$i]['Post'] = array('title' => 'test'.$i,'body' => 'aaaa'.$i,'text' => 'bbbb'.$i,'count' => $i,);}$saveData[30]['Post'] = array('title' => 'test1','body' => 'aaaa1','text' => 'bbbb1','count' => 1,);$saveData[31]['Post'] = array('title' => 'test2','body' => 'aaaa2','text' => 'bbbb2','count' => 2,);$saveData[32]['Post'] = array('title' => 'test2','body' => 'aaaa2','text' => 'bbbb2','count' => 32,);$this->Post->create();$saveResult = $this->Post->saveAll($saveData);//using query() Distinct$params = array('distinct' => 'posts','key' => 'count',);$result = $this->Post->query( $params );$this->assertEqual(1, $result['values'][1]);$this->assertEqual(2, $result['values'][2]);$this->assertEqual(32, $result['values'][30]);//using query() group$cond_count = 5;$reduce = "function(obj,prev){prev.csum++;}";$params = array('group'=>array('ns'=>'posts','cond'=>array('count' => array('$lt' => $cond_count)),'key'=>array('title'=>true),'initial'=>array('csum'=>0),'$reduce'=>$reduce));$result = $this->Post->query( $params );$this->assertTrue($result['ok'] == 1 && count($result['retval']) > 0);$this->assertEqual($cond_count, count($result['retval']));$this->assertEqual('test0', $result['retval'][0]['title']);$this->assertEqual('test1', $result['retval'][1]['title']);$this->assertEqual('test2', $result['retval'][2]['title']);$this->assertEqual(1, $result['retval'][0]['csum']);$this->assertEqual(2, $result['retval'][1]['csum']);$this->assertEqual(2, $result['retval'][2]['csum']);}/*** Tests MapReduce** @return void* @access public*/public function testMapReduce() {for($i = 0 ; $i < 30 ; $i++) {$saveData[$i]['Post'] = array('title' => 'test'.$i,'body' => 'aaaa'.$i,'text' => 'bbbb'.$i,'count' => $i,);}$saveData[30]['Post'] = array('title' => 'test1','body' => 'aaaa1','text' => 'bbbb1','count' => 1,);$saveData[31]['Post'] = array('title' => 'test2','body' => 'aaaa2','text' => 'bbbb2','count' => 2,);$saveData[32]['Post'] = array('title' => 'test2','body' => 'aaaa2','text' => 'bbbb2','count' => 32,);$this->Post->create();$saveResult = $this->Post->saveAll($saveData);$map = new MongoCode("function() { emit(this.title,1); }");$reduce = new MongoCode("function(k, vals) { "."var sum = 0;"."for (var i in vals) {"."sum += vals[i];"."}"."return sum; }");$params = array("mapreduce" => "posts","map" => $map,"reduce" => $reduce,"query" => array("count" => array('$gt' => -2),),'out' => 'test_mapreduce_posts',);$mongo = $this->Post->getDataSource();$results = $mongo->mapReduce($params);$posts = array();foreach ($results as $post) {$posts[$post['_id']] = $post['value'];}$this->assertEqual(30, count($posts));$this->assertEqual(1, $posts['test0']);$this->assertEqual(2, $posts['test1']);$this->assertEqual(3, $posts['test2']);$this->assertEqual(1, $posts['test3']);//set timeout$results = $mongo->mapReduce($params, 100); //set timeout 100msec$posts = array();foreach ($results as $post) {$posts[$post['_id']] = $post['value'];}$this->assertEqual(30, count($posts));$this->assertEqual(1, $posts['test0']);$this->assertEqual(2, $posts['test1']);$this->assertEqual(3, $posts['test2']);$this->assertEqual(1, $posts['test3']);//get results as inline data$version = $this->getMongodVersion();if( $version >= '1.7.4') {$params = array("mapreduce" => "posts","map" => $map,"reduce" => $reduce,"query" => array("count" => array('$gt' => -2),),'out' => array('inline' => 1),);$results = $mongo->mapReduce($params);$posts = array();foreach ($results as $post) {$posts[$post['_id']] = $post['value'];}$this->assertEqual(30, count($posts));$this->assertEqual(1, $posts['test0']);$this->assertEqual(2, $posts['test1']);$this->assertEqual(3, $posts['test2']);$this->assertEqual(1, $posts['test3']);}}/*** testSort method** @return void* @access public*/public function testSort() {$data = array('title' => 'AAA','body' => 'aaaa','text' => 'aaaa');$saveData['Post'] = $data;$this->Post->create();$this->Post->save($saveData);$data = array('title' => 'CCC','body' => 'cccc','text' => 'cccc');$saveData['Post'] = $data;$this->Post->create();$this->Post->save($saveData);$this->Post->create();$data = array('title' => 'BBB','body' => 'bbbb','text' => 'bbbb');$saveData['Post'] = $data;$this->Post->create();$this->Post->save($saveData);$expected = array('AAA', 'BBB', 'CCC');$result = $this->Post->find('all', array('fields' => array('_id', 'title'),'order' => array('title' => 1)));$result = Hash::extract($result, '{n}.Post.title');$this->assertEqual($expected, $result);$result = $this->Post->find('all', array('fields' => array('_id', 'title'),'order' => array('title' => 'ASC')));$result = Hash::extract($result, '{n}.Post.title');$expected = array_reverse($expected);$result = $this->Post->find('all', array('fields' => array('_id', 'title'),'order' => array('title' => '-1')));$result = Hash::extract($result, '{n}.Post.title');$this->assertEqual($expected, $result);$result = $this->Post->find('all', array('fields' => array('_id', 'title'),'order' => array('title' => 'DESC')));$result = Hash::extract($result, '{n}.Post.title');$this->assertEqual($expected, $result);}/*** testSchemaless method** Test you can save to a model without specifying mongodb.** @return void* @access public*/public function testSchemaless() {$toSave = array('title' => 'A test article','body' => str_repeat('Lorum ipsum ', 100),'tags' => array('one','two','three'),'modified' => null,'created' => null);$this->MongoArticle = ClassRegistry::init('MongoArticle');$this->MongoArticle->create();$saveResult = $this->MongoArticle->save($toSave);$this->assertTrue(!empty($saveResult) && is_array($saveResult));$expected = array_intersect_key($toSave, array_flip(array('title', 'body', 'tags')));$result = $this->MongoArticle->read(array('title', 'body', 'tags'));unset ($result['MongoArticle']['id']); // prevent auto added field from screwing things up$this->assertEqual($expected, $result['MongoArticle']);$toSave = array('title' => 'Another test article','body' => str_repeat('Lorum pipsum ', 100),'tags' => array('four','five','six'),'starts' => date('Y-M-d H:i:s'),'modified' => null,'created' => null);$this->MongoArticle->create();$saveResult = $this->MongoArticle->save($toSave);$this->assertTrue(!empty($saveResult) && is_array($saveResult));$starts = $this->MongoArticle->field('starts');$this->assertEqual($toSave['starts'], $starts);}/*** testSpecificId method** Test you can save specifying your own _id values - and update by _id** @return void* @access public*/public function testSpecificId() {$data = array('_id' => 123,'title' => 'test','body' => 'aaaa','text' => 'bbbb');$saveData['Post'] = $data;$this->Post->create();$saveResult = $this->Post->save($saveData);$this->assertTrue(!empty($saveResult) && is_array($saveResult));$found = $this->Post->find('first', array('fields' => array('_id', 'title', 'body', 'text'),'conditions' => array('_id' => 123)));$this->assertEqual($found, $saveData);$data = array('_id' => 123,'title' => 'test2','body' => 'aaaa2','text' => 'bbbb2');$saveData['Post'] = $data;$this->Post->create();$saveResult = $this->Post->save($saveData);$this->assertTrue(!empty($saveResult) && is_array($saveResult));$found = $this->Post->find('first', array('fields' => array('_id', 'title', 'body', 'text'),'conditions' => array('_id' => 123)));$this->assertEqual($found, $saveData);}/*** testOr method** @return void* @access public*/public function testOr() {$mongoVersion = $this->mongodb->execute('db.version()');$shouldSkip = version_compare($mongoVersion, '1.5.3', '<');if ($this->skipIf($shouldSkip, '$or tests require at least version mongo version 1.5.3, currently using ' . $mongoVersion . ' %s')) {return;}$this->MongoArticle = ClassRegistry::init('MongoArticle');$this->MongoArticle->create();for ($i = 1; $i <= 20; $i++) {$data = array('title' => "Article $i",'subtitle' => "Sub Article $i",);$saveData['MongoArticle'] = $data;$this->MongoArticle->create();$this->MongoArticle->save($saveData);}$expected = $this->MongoArticle->find('all', array('conditions' => array('title' => array('$in' => array('Article 1', 'Article 10'))),'order' => array('number' => 'ASC')));$this->assertEqual(count($expected), 2);$result = $this->MongoArticle->find('all', array('conditions' => array('$or' => array(array('title' => 'Article 1'),array('title' => 'Article 10'),)),'order' => array('number' => 'ASC')));$this->assertEqual($result, $expected);}/*** testDeleteAll method** @return void* @access public*/function testDeleteAll($cascade = true) {$this->MongoArticle = ClassRegistry::init('MongoArticle');$this->MongoArticle->create(array('title' => 'Article 1', 'cat' => 1));$this->MongoArticle->save();$this->MongoArticle->create(array('title' => 'Article 2', 'cat' => 1));$this->MongoArticle->save();$this->MongoArticle->create(array('title' => 'Article 3', 'cat' => 2));$this->MongoArticle->save();$this->MongoArticle->create(array('title' => 'Article 4', 'cat' => 2));$this->MongoArticle->save();$count = $this->MongoArticle->find('count');$this->assertEqual($count, 4);$this->MongoArticle->deleteAll(array('cat' => 2), $cascade);$count = $this->MongoArticle->find('count');$this->assertEqual($count, 2);$this->MongoArticle->deleteAll(true, $cascade);$count = $this->MongoArticle->find('count');$this->assertEqual($count, 0);}/*** testDeleteAllNoCascade method** @return void* @access public*/function testDeleteAllNoCascade() {$this->testDeleteAll(false);}/*** testRegexSearch method** @return void* @access public*/public function testRegexSearch() {$this->MongoArticle = ClassRegistry::init('MongoArticle');$this->MongoArticle->create(array('title' => 'Article 1', 'cat' => 1));$this->MongoArticle->save();$this->MongoArticle->create(array('title' => 'Article 2', 'cat' => 1));$this->MongoArticle->save();$this->MongoArticle->create(array('title' => 'Article 3', 'cat' => 2));$this->MongoArticle->save();$count=$this->MongoArticle->find('count',array('conditions'=>array('title'=>'Article 2')));$this->assertEqual($count, 1);$count = $this->MongoArticle->find('count',array('conditions'=>array('title'=> new MongoRegex('/^Article/'))));$this->assertEqual($count, 3);}/*** testEmptyReturn method* inserts article into table. searches for a different non existing article. should return an empty array in the same that that it does from other datasources* @return void* @access public*/public function testEmptyReturn() {$this->MongoArticle = ClassRegistry::init('MongoArticle');$this->MongoArticle->create(array('title' => 'Article 1', 'cat' => 1));$this->MongoArticle->save();$articles=$this->MongoArticle->find('all',array('conditions'=>array('title'=>'Article 2')));$this->assertTrue(is_array($articles) && empty($articles));$articles=$this->MongoArticle->find('first',array('conditions'=>array('title'=>'Article 2')));$this->assertTrue(is_array($articles) && empty($articles));}/*** Tests isUnique validation.** @return void* @access public*/public function testSaveUniques() {$data = array('title' => 'test','body' => 'aaaa','text' => 'bbbb','uniquefield1'=>'uniquenameforthistest');$saveData['Post'] = $data;$this->Post->Behaviors->attach('Mongodb.SqlCompatible');$this->Post->create();$saveResult = $this->Post->save($saveData);$this->assertTrue(!empty($saveResult) && is_array($saveResult));$data = array('title' => 'test','body' => 'asdf','text' => 'bbbb','uniquefield1'=>'uniquenameforthistest');$saveData['Post'] = $data;$this->Post->create();$saveResult = $this->Post->save($saveData);$this->assertFalse($saveResult);}/*** Tests isUnique validation with custom validation.** @return void* @access public*/public function testSaveUniquesCustom() {$data = array('title' => 'test','body' => 'aaaa','text' => 'bbbb','uniquefield2' => 'someunqiuename');$saveData['Post'] = $data;$this->Post->create();$saveResult = $this->Post->save($saveData);$this->assertTrue(!empty($saveResult) && is_array($saveResult));$data = array('title' => 'test','body' => 'asdf','text' => 'bbbb','uniquefield2' => 'someunqiuename');$saveData['Post'] = $data;$this->Post->create();$saveResult = $this->Post->save($saveData);$this->assertFalse($saveResult);}public function testReturn() {$this->MongoArticle = ClassRegistry::init('MongoArticle');$this->MongoArticle->create(array('title' => 'Article 1', 'cat' => 1));$this->MongoArticle->save();$this->MongoArticle->create(array('title' => 'Article 2', 'cat' => 1));$this->MongoArticle->save();$return = $this->MongoArticle->find('all', array('conditions' => array('title' => 'Article 2')));$this->assertTrue(is_array($return));$return = $this->MongoArticle->find('first', array('conditions' => array('title' => 'Article 2')));$this->assertTrue(is_array($return));$return = $this->MongoArticle->find('first', array('conditions' => array('title' => 'Article 2')));$this->assertTrue(is_array($return));$return = $this->MongoArticle->find('count', array('conditions' => array('title' => 'Article 2')));$this->assertTrue(is_int($return));$return = $this->MongoArticle->find('neighbors', array('conditions' => array('title' => 'Article 2')));$this->assertTrue(is_array($return));$return = $this->MongoArticle->find('list', array('conditions' => array('title' => 'Article 2')));$this->assertTrue(is_array($return));$return = $this->MongoArticle->find('all', array('conditions' => array('title' => 'Doesn\'t exist')));$this->assertTrue(is_array($return));$return = $this->MongoArticle->find('first', array('conditions' => array('title' => 'Doesn\'t exist')));$this->assertTrue(is_array($return) && empty($return));$return = $this->MongoArticle->find('count', array('conditions' => array('title' => 'Doesn\'t exist')));$this->assertTrue(is_int($return));$return = $this->MongoArticle->find('neighbors', array('conditions' => array('title' => 'Doesn\'t exist')));$this->assertTrue(is_array($return));$return = $this->MongoArticle->find('list', array('conditions' => array('title' => 'Doesn\'t exist')));$this->assertTrue(is_array($return));}public function testDatetimeFieldUsingMongoDate() {$this->Comment = ClassRegistry::init(array('class' => 'Comment', 'alias' => 'Comment', 'ds' => 'test_mongo'), true);$ds = $this->Comment->getDataSource();$fields = array('post_id','comment','comment_at',);$values = array(array( 1, 'comment 1', '2014-02-21 01:02:03Z'),array( 1, 'comment 2', '2014-02-22 01:02:03Z'),array( 1, 'comment 3', '2014-02-23 01:02:03Z'),array( 1, 'comment 4', '2014-02-24 01:02:03Z'),array( 1, 'comment 5', '2014-02-25 01:02:03Z'));$ds->insertMulti('comments', $fields, $values);$result = $this->Comment->find('all');$this->assertEqual(count($result), 5);$this->assertTrue(is_a($result[0]['Comment']['comment_at'], 'MongoDate'));$this->assertTrue(is_a($result[1]['Comment']['comment_at'], 'MongoDate'));$this->assertTrue(is_a($result[2]['Comment']['comment_at'], 'MongoDate'));$this->assertTrue(is_a($result[3]['Comment']['comment_at'], 'MongoDate'));$this->assertTrue(is_a($result[4]['Comment']['comment_at'], 'MongoDate'));$values = array(array( 2, 'comment 2 1', new MongoDate(strtotime('2014-02-21 02:02:01Z'))),);$ds->insertMulti('comments', $fields, $values);$conditions = array('post_id' => 2);$result = $this->Comment->find('all', array('conditions' => $conditions));$this->assertEqual(count($result), 1);$this->assertTrue(is_a($result[0]['Comment']['comment_at'], 'MongoDate'));$data = array('Comment' => array('user_id' => 3,'comment' => 'comment 3 1','comment_at' => new MongoDate(strtotime('2014-02-26 03:02:01Z')),));$this->Comment->create();$result = $this->Comment->save($data);$expected = array('Comment' => array('user_id' => 3,'comment' => 'comment 3 1','comment_at' => new MongoDate(strtotime('2014-02-26 03:02:01Z')),'created' => Hash::get($result, 'Comment.created'),'modified' => Hash::get($result, 'Comment.modified'),'_id' => Hash::get($result, 'Comment._id'),));$this->assertEquals($result, $expected);}public function testReadUsingHint() {$index = array('count' => 1, 'created' => -1);$this->Post->getDataSource()->ensureIndex($this->Post, $index);$data = array(array('title' => 'test1','body' => 'aaaa','text' => 'bbbb','count' => 3),array('title' => 'test2','body' => 'cccc','text' => 'dddd','count' => 4),array('title' => 'test1','body' => 'eeee','text' => 'ffff','count' => 5),);foreach ($data as $set) {$this->insertData($set);}$result = $this->Post->find('all', array('conditions' => array('count' => array('$gt' => 3)),'hint' => $index,));$this->assertCount(2, $result);$result = $this->Post->find('count', array('conditions' => array('count' => array('$gt' => 3)),'hint' => $index,));$this->assertSame(2, $result);}public function testReadUsingHintThrowExceptionWhenNonExistsIndex() {$index = array('count' => 1, 'created' => -1);$this->Post->getDataSource()->ensureIndex($this->Post, $index);$invalidIndex = array('count' => 1, 'created' => 1);try {$result = $this->Post->find('all', array('conditions' => array('count' => array('$gt' => 3)),'hint' => $invalidIndex,));} catch (MongoCursorException $e) {$this->assertTextContains('bad hint', $e->getMessage());}try {$result = $this->Post->find('count', array('conditions' => array('count' => array('$gt' => 3)),'hint' => $invalidIndex,));} catch (MongoCursorException $e) {$this->assertTextContains('bad hint', $e->getMessage());}}}