Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14098 anikendra 1
<?php
2
/**
3
 * Test cases for the Cakephp mongoDB datasource.
4
 *
5
 * This datasource uses Pecl Mongo (http://php.net/mongo)
6
 * and is thus dependent on PHP 5.0 and greater.
7
 *
8
 * Copyright 2010, Yasushi Ichikawa http://github.com/ichikaway/
9
 *
10
 * Licensed under The MIT License
11
 * Redistributions of files must retain the above copyright notice.
12
 *
13
 * @copyright     Copyright (c) 2010, Yasushi Ichikawa http://github.com/ichikaway/
14
 * @package       mongodb
15
 * @subpackage    mongodb.tests.cases.datasources
16
 * @license       http://www.opensource.org/licenses/mit-license.php The MIT License
17
 */
18
 
19
/**
20
 * Import relevant classes for testing
21
 */
22
App::uses('Model', 'Model');
23
App::uses('AppModel', 'Model');
24
App::uses('MongodbSource', 'Mongodb.Model/Datasource');
25
 
26
 
27
/**
28
 * Post Model for the test
29
 *
30
 * @package       app
31
 * @subpackage    app.model.post
32
 */
33
class Post extends AppModel {
34
 
35
	public $useDbConfig = 'test_mongo';
36
 
37
/**
38
 * mongoSchema property
39
 *
40
 * @public array
41
 * @access public
42
 */
43
	public $primaryKey='_id';
44
 
45
	public $validate = array(
46
 		'uniquefield1' => array(
47
 			'rule' => 'isUnique',
48
 			'required' => false
49
 		),
50
 		'uniquefield2' => array(
51
 			'rule' => 'manualUniqueValidation',
52
 			'required' => false
53
 		),
54
	);
55
 
56
	public $mongoSchema = array(
57
		'title' => array('type' => 'string'),
58
		'body' => array('type' => 'string'),
59
		'text' => array('type' => 'text'),
60
		'uniquefield1' => array('type' => 'text'),
61
		'uniquefield2' => array('type' => 'text'),
62
		'count' => array('type' => 'integer'),
63
		'created' => array('type' => 'datetime'),
64
		'modified' => array('type' => 'datetime'),
65
	);
66
 
67
	function manualUniqueValidation($check) {
68
 		$c = $this->find('count', array(
69
 			'conditions' => array(
70
 				'uniquefield2' => $check['uniquefield2']
71
 			)
72
 		));
73
		if ($c === 0) {
74
			return true;
75
		}
76
 		return false;
77
 	}
78
}
79
 
80
/**
81
 * Comment Model for the test
82
 *
83
 * @package       app
84
 * @subpackage    app.model.post
85
 */
86
class Comment extends AppModel {
87
 
88
	public $useDbConfig = 'test_mongo';
89
 
90
	public $primaryKey = '_id';
91
 
92
	public $mongoSchema = array(
93
		'post_id' => array('type' => 'integer'),
94
		'comment' => array('type' => 'string'),
95
		'comment_at' => array('type' => 'datetime'),
96
 
97
		'created' => array('type' => 'datetime'),
98
		'modified' => array('type' => 'datetime'),
99
	);
100
}
101
 
102
/**
103
 * MongoArticle class
104
 *
105
 * @uses          AppModel
106
 * @package       mongodb
107
 * @subpackage    mongodb.tests.cases.datasources
108
 */
109
class MongoArticle extends AppModel {
110
 
111
	public $useDbConfig = 'test_mongo';
112
}
113
 
114
/**
115
 * MongoDB Source test class
116
 *
117
 * @package       app
118
 * @subpackage    app.model.datasources
119
 */
120
class MongodbSourceTest extends CakeTestCase {
121
 
122
/**
123
 * Database Instance
124
 *
125
 * @var resource
126
 * @access public
127
 */
128
	public $mongodb;
129
 
130
/**
131
 * Base Config
132
 *
133
 * @var array
134
 * @access public
135
 *
136
 */
137
	protected $_config = array(
138
		'datasource' => 'Mongodb.MongodbSource',
139
		'host' => 'localhost',
140
		'login' => '',
141
		'password' => '',
142
		'database' => 'test_mongo',
143
		'port' => 27017,
144
		'prefix' => '',
145
		'persistent' => true,
146
	);
147
 
148
/**
149
 * Sets up the environment for each test method
150
 *
151
 * @return void
152
 * @access public
153
 */
154
	public function setUp() {
155
		$connections = ConnectionManager::enumConnectionObjects();
156
 
157
		if (!empty($connections['test']['classname']) && $connections['test']['classname'] === 'mongodbSource') {
158
			$config = new DATABASE_CONFIG();
159
			$this->_config = $config->test;
160
		} elseif (isset($connections['test_mongo'])) {
161
			$this->_config = $connections['test_mongo'];
162
		}
163
 
164
		if(!isset($connections['test_mongo'])) {
165
			ConnectionManager::create('test_mongo', $this->_config);
166
		}
167
 
168
		$this->Mongo = new MongodbSource($this->_config);
169
 
170
		$this->Post = ClassRegistry::init(array('class' => 'Post', 'alias' => 'Post', 'ds' => 'test_mongo'), true);
171
		$this->MongoArticle = ClassRegistry::init(array('class' => 'MongoArticle', 'alias' => 'MongoArticle', 'ds' => 'test_mongo'), true);
172
 
173
		$this->mongodb = ConnectionManager::getDataSource($this->Post->useDbConfig);
174
		$this->mongodb->connect();
175
 
176
	}
177
 
178
/**
179
 * Destroys the environment after each test method is run
180
 *
181
 * @return void
182
 * @access public
183
 */
184
	public function tearDown() {
185
		$this->dropData();
186
		unset($this->Post);
187
		unset($this->MongoArticle);
188
		unset($this->Mongo);
189
		unset($this->mongodb);
190
		ClassRegistry::flush();
191
	}
192
 
193
 
194
/**
195
 * get Mongod server version
196
 *
197
 * @return numeric
198
 * @access public
199
 */
200
	public function getMongodVersion() {
201
		$mongo = $this->Post->getDataSource();
202
		return $mongo->execute('db.version()');
203
	}
204
 
205
/**
206
 * Insert data method for mongodb.
207
 *
208
 * @param array insert data
209
 * @return void
210
 * @access public
211
 */
212
	public function insertData($data) {
213
		$version = Mongo::VERSION;
214
		try {
215
			if ($version  >= '1.3.0') {
216
				$this->mongodb
217
					->connection
218
					->selectDB($this->_config['database'])
219
					->selectCollection($this->Post->table)
220
					->insert($data, array('safe' => true));
221
			} else {
222
				$this->mongodb
223
					->connection
224
					->selectDB($this->_config['database'])
225
					->selectCollection($this->Post->table)
226
					->insert($data, true);
227
			}
228
		} catch (MongoException $e) {
229
			trigger_error($e->getMessage());
230
		}
231
	}
232
 
233
/**
234
 * Drop database
235
 *
236
 * @return void
237
 * @access public
238
 */
239
	public function dropData() {
240
		try {
241
			$db = $this->mongodb
242
				->connection
243
				->selectDB($this->_config['database']);
244
 
245
			foreach($db->listCollections() as $collection) {
246
				$response = $collection->drop();
247
			}
248
		} catch (MongoException $e) {
249
			trigger_error($e->getMessage());
250
		}
251
	}
252
 
253
 
254
/**
255
 * testCreateConnectionName
256
 *
257
 * @return void
258
 * @access public
259
 */
260
 public function testCreateConnectionName() {
261
	 $config = array(
262
			 'datasource' => 'mongodb',
263
			 'host' => 'localhost',
264
			 'login' => '',
265
			 'password' => '',
266
			 'database' => 'test_mongo',
267
			 'port' => 27017,
268
			 'prefix' => '',
269
			 'persistent' => false,
270
			 );
271
		$version = '1.2.2';
272
		$expect = 'mongodb://localhost:27017';
273
		$host = $this->mongodb->createConnectionName($config, $version);
274
		$this->assertIdentical($expect, $host);
275
 
276
		 $config = array(
277
			 'datasource' => 'mongodb',
278
			 'host' => 'localhost',
279
			 'login' => 'user',
280
			 'password' => 'pass',
281
			 'database' => 'test_mongo',
282
			 'port' => 27017,
283
			 'prefix' => '',
284
			 'persistent' => false,
285
			 );
286
		$version = '1.2.2';
287
		$expect = 'mongodb://user:pass@localhost:27017/test_mongo';
288
		$host = $this->mongodb->createConnectionName($config, $version);
289
		$this->assertIdentical($expect, $host);
290
 
291
 
292
		 $config = array(
293
			 'datasource' => 'mongodb',
294
			 'host' => 'localhost',
295
			 'login' => 'user',
296
			 'password' => 'pass',
297
			 'database' => 'test_mongo',
298
			 'port' => 27017,
299
			 'prefix' => '',
300
			 'persistent' => false,
301
			 );
302
		$version = '1.0.0';
303
		$expect = 'user:pass@localhost:27017/test_mongo';
304
		$host = $this->mongodb->createConnectionName($config, $version);
305
		$this->assertIdentical($expect, $host);
306
 }
307
 
308
 
309
/**
310
 * Tests connection
311
 *
312
 * @return void
313
 * @access public
314
 */
315
	public function testConnect() {
316
		$result = $this->Mongo->connect();
317
		$this->assertTrue($result);
318
 
319
		$this->assertTrue($this->Mongo->connected);
320
		$this->assertTrue($this->Mongo->isConnected());
321
	}
322
 
323
/**
324
 * Tests the disconnect method of the Mongodb DataSource
325
 *
326
 * @return void
327
 * @access public
328
 */
329
	public function testDisconnect() {
330
		$result = $this->Mongo->disconnect();
331
		$this->assertTrue($result);
332
		$this->assertNull($this->Mongo->connected);
333
	}
334
 
335
/**
336
 * Tests the listSources method of the Mongodb DataSource
337
 *
338
 * @return void
339
 * @access public
340
 */
341
	public function testListSources() {
342
		$this->assertTrue($this->mongodb->listSources());
343
	}
344
 
345
/**
346
 * Tests the getMongoDb method of the Mongodb DataSource
347
 *
348
 * @return void
349
 * @access public
350
 */
351
	public function testGetMongoDb() {
352
		$obj = $this->mongodb->getMongoDb();
353
		$this->assertTrue(is_object($obj));
354
		$objName = get_class($obj);
355
		$this->assertEqual('MongoDB', $objName);
356
	}
357
 
358
/**
359
 * Tests the Model::getMongoDb() call MongodbSource::getMongoDb
360
 *
361
 * @return void
362
 * @access public
363
 */
364
	public function testGetMongoDbFromModel() {
365
 
366
		$obj = $this->Post->getMongoDb();
367
		$this->assertTrue(is_object($obj));
368
		$objName = get_class($obj);
369
		$this->assertEqual('MongoDB', $objName);
370
	}
371
 
372
/**
373
 * Tests the getMongoCollection method of the Mongodb DataSource
374
 *
375
 * @return void
376
 * @access public
377
 */
378
	public function testGetMongoCollection() {
379
		$obj = $this->mongodb->getMongoCollection($this->Post);
380
		$this->assertTrue(is_object($obj));
381
		$objName = get_class($obj);
382
		$this->assertEqual('MongoCollection', $objName);
383
	}
384
 
385
/**
386
 * Tests the describe method of the Mongodb DataSource
387
 *
388
 * @return void
389
 * @access public
390
 */
391
 
392
	public function testDescribe() {
393
		$mockObj = $this->getMock('AppModel');
394
 
395
		$result = $this->mongodb->describe($mockObj);
396
		$expected = array(
397
			'_id' => array('type' => 'string', 'length' => 24, 'key' => 'primary'),
398
			'created' => array('type' => 'datetime', 'default' => null),
399
			'modified' => array('type' => 'datetime', 'default' => null),
400
		);
401
		$this->assertEqual($expected, $result);
402
 
403
		$result = $this->mongodb->describe($this->Post);
404
		$expect = array(
405
			'_id' => array('type' => 'string', 'length' => 24, 'key' => 'primary'),
406
			'title' => array('type' => 'string'),
407
			'body' => array('type' => 'string'),
408
			'text' => array('type' => 'text'),
409
			'uniquefield1' => array('type' => 'text'),
410
			'uniquefield2' => array('type' => 'text'),
411
			'count' => array('type' => 'integer'),
412
			'created' => array('type' => 'datetime'),
413
			'modified' => array('type' => 'datetime'),
414
		);
415
		ksort($result);
416
		ksort($expect);
417
		$this->assertEqual($expect, $result);
418
	}
419
 
420
/**
421
 * Test truncate method
422
 */
423
	public function testTruncate() {
424
		$this->insertData(array(
425
			'title' => 'test',
426
			'body' => 'aaaa',
427
			'text' => 'bbbb',
428
		));
429
		$this->assertSame(1, $this->Post->find('count'));
430
 
431
		$this->mongodb->truncate($this->Post);
432
		$this->assertSame(0, $this->Post->find('count'));
433
	}
434
 
435
/**
436
 * Test truncate method using mock
437
 */
438
	public function testTruncateStatement() {
439
		$connection = $this->mongodb->connection;
440
		$dbname = $this->mongodb->config['database'];
441
		$tableName = $this->mongodb->fullTableName($this->Post);
442
 
443
		$this->mongodb = $this->getMock(
444
			'MongodbSource',
445
			array('getMongoDb'),
446
			array($this->_config)
447
		);
448
		$mongo = $this->getMock(
449
			'MongoDB',
450
			array('selectCollection'),
451
			array($connection, $dbname)
452
		);
453
		$mongoCollection = $this->getMock(
454
			'MongoCollection',
455
			array('remove'),
456
			array($mongo, $tableName)
457
		);
458
 
459
		// truncate method call MongoCollection::remove()
460
		$mongoCollection->expects($this->once())->method('remove')
461
			->with(array())->will($this->returnValue(true));
462
		$mongo->expects($this->once())->method('selectCollection')
463
			->with($tableName)->will($this->returnValue($mongoCollection));
464
		$this->mongodb->expects($this->once())->method('getMongoDb')
465
			->will($this->returnValue($mongo));
466
 
467
		$this->mongodb->truncate($this->Post);
468
	}
469
 
470
/**
471
 * Tests find method.
472
 *
473
 * @return void
474
 * @access public
475
 */
476
	public function testFind() {
477
		$data = array(
478
			'title' => 'test',
479
			'body' => 'aaaa',
480
			'text' => 'bbbb'
481
		);
482
		$this->insertData($data);
483
		$result = $this->Post->find('all');
484
		$this->assertEqual(1, count($result));
485
		$resultData = $result[0]['Post'];
486
		$this->assertEqual(4, count($resultData));
487
		$this->assertTrue(!empty($resultData['_id']));
488
		$this->assertEqual($data['title'], $resultData['title']);
489
		$this->assertEqual($data['body'], $resultData['body']);
490
		$this->assertEqual($data['text'], $resultData['text']);
491
	}
492
 
493
/**
494
 * Tests findBy* method
495
 *
496
 * @return void
497
 * @access public
498
 */
499
	public function testFindBy() {
500
		$data = array(
501
			array(
502
				'title' => 'test',
503
				'body' => 'aaaa',
504
				'text' => 'bbbb'
505
			),
506
			array(
507
				'title' => 'test2',
508
				'body' => 'abab',
509
				'text' => 'bcbc'
510
			),
511
		);
512
 
513
		foreach($data as $set) {
514
			$this->insertData($set);
515
		}
516
 
517
		$result = $this->Post->findByTitle('test');
518
		$this->assertEqual(1, count($result));
519
		$resultData = $result['Post'];
520
		$this->assertEqual(4, count($resultData));
521
		$this->assertTrue(!empty($resultData['_id']));
522
		$this->assertEqual($resultData['title'], $data[0]['title']);
523
		$this->assertEqual($resultData['body'], $data[0]['body']);
524
		$this->assertEqual($resultData['text'], $data[0]['text']);
525
 
526
		$result = $this->Post->findByBody('abab');
527
		$this->assertEqual(1, count($result));
528
		$resultData = $result['Post'];
529
		$this->assertEqual(4, count($resultData));
530
		$this->assertTrue(!empty($resultData['_id']));
531
		$this->assertEqual($data[1]['title'], $resultData['title']);
532
		$this->assertEqual($data[1]['body'], $resultData['body']);
533
		$this->assertEqual($data[1]['text'], $resultData['text']);
534
	}
535
 
536
/**
537
 * Tests findAllBy* method
538
 *
539
 * @return void
540
 * @access public
541
 */
542
	public function testFindAllBy() {
543
		$data = array(
544
			array(
545
				'title' => 'test',
546
				'body' => 'abab',
547
				'text' => 'bbbb'
548
			),
549
			array(
550
				'title' => 'test2',
551
				'body' => 'abab',
552
				'text' => 'bcbc'
553
			),
554
		);
555
 
556
		foreach($data as $set) {
557
			$this->insertData($set);
558
		}
559
 
560
		$result = $this->Post->findAllByBody('abab');
561
		$this->assertEqual(2, count($result));
562
 
563
		$result = $this->Post->findAllByTitle('test2');
564
		$this->assertEqual(1, count($result));
565
	}
566
 
567
/**
568
 * Tests save method.
569
 *
570
 * @return void
571
 * @access public
572
 */
573
	public function testSave() {
574
		$data = array(
575
			'title' => 'test',
576
			'body' => 'aaaa',
577
			'text' => 'bbbb'
578
		);
579
		$saveData['Post'] = $data;
580
 
581
		$this->Post->create();
582
		$saveResult = $this->Post->save($saveData);
583
		$this->assertTrue(!empty($saveResult) && is_array($saveResult));
584
 
585
		$result = $this->Post->find('all');
586
 
587
		$this->assertEqual(1, count($result));
588
		$resultData = $result[0]['Post'];
589
		$this->assertEqual(6, count($resultData));
590
		$this->assertTrue(!empty($resultData['_id']));
591
		$this->assertEqual($this->Post->id, $resultData['_id']);
592
		$this->assertEqual($data['title'], $resultData['title']);
593
		$this->assertEqual($data['body'], $resultData['body']);
594
		$this->assertEqual($data['text'], $resultData['text']);
595
 
596
		$this->assertTrue(is_a($resultData['created'], 'MongoDate'));
597
		$this->assertTrue(is_a($resultData['modified'], 'MongoDate'));
598
	}
599
 
600
/**
601
 * Tests insertId after saving
602
 *
603
 * @return void
604
 * @access public
605
 */
606
	public function testCheckInsertIdAfterSaving() {
607
		$saveData['Post'] = array(
608
			'title' => 'test',
609
			'body' => 'aaaa',
610
			'text' => 'bbbb'
611
		);
612
 
613
		$this->Post->create();
614
		$saveResult = $this->Post->save($saveData);
615
		$this->assertTrue(!empty($saveResult) && is_array($saveResult));
616
 
617
 
618
		$this->assertEqual($this->Post->id, $this->Post->getInsertId());
619
		$this->assertTrue(is_string($this->Post->id));
620
		$this->assertTrue(is_string($this->Post->getInsertId()));
621
 
622
		//set Numeric _id
623
		$saveData['Post'] = array(
624
			'_id' => 123456789,
625
			'title' => 'test',
626
			'body' => 'aaaa',
627
			'text' => 'bbbb'
628
		);
629
 
630
		$this->Post->create();
631
		$saveResult = $this->Post->save($saveData);
632
		$this->assertTrue(!empty($saveResult) && is_array($saveResult));
633
 
634
		$this->assertEqual($saveData['Post']['_id'] ,$this->Post->id);
635
		$this->assertEqual($this->Post->id, $this->Post->getInsertId());
636
		$this->assertTrue(is_numeric($this->Post->id));
637
		$this->assertTrue(is_numeric($this->Post->getInsertId()));
638
 
639
		$readArray1 = $this->Post->read();
640
		$readArray2 = $this->Post->read(null, $saveData['Post']['_id']);
641
		$this->assertEqual($readArray1, $readArray2);
642
		$this->assertEqual($saveData['Post']['_id'], $readArray2['Post']['_id']);
643
 
644
	}
645
 
646
 
647
 
648
/**
649
 * Tests saveAll method.
650
 *
651
 * @return void
652
 * @access public
653
 */
654
	public function testSaveAll() {
655
		$saveData[0]['Post'] = array(
656
			'title' => 'test1',
657
			'body' => 'aaaa1',
658
			'text' => 'bbbb1'
659
		);
660
 
661
		$saveData[1]['Post'] = array(
662
			'title' => 'test2',
663
			'body' => 'aaaa2',
664
			'text' => 'bbbb2'
665
		);
666
 
667
		$this->Post->create();
668
		$saveResult = $this->Post->saveAll($saveData);
669
		$result = $this->Post->find('all');
670
 
671
		$this->assertEqual(2, count($result));
672
 
673
		$resultData = $result[0]['Post'];
674
		$this->assertEqual(6, count($resultData));
675
		$this->assertTrue(!empty($resultData['_id']));
676
		$data = $saveData[0]['Post'];
677
		$this->assertEqual($data['title'], $resultData['title']);
678
		$this->assertEqual($data['body'], $resultData['body']);
679
		$this->assertEqual($data['text'], $resultData['text']);
680
 
681
		$this->assertTrue(is_a($resultData['created'], 'MongoDate'));
682
		$this->assertTrue(is_a($resultData['modified'], 'MongoDate'));
683
 
684
		$resultData = $result[1]['Post'];
685
		$this->assertEqual(6, count($resultData));
686
		$this->assertTrue(!empty($resultData['_id']));
687
		$data = $saveData[1]['Post'];
688
		$this->assertEqual($data['title'], $resultData['title']);
689
		$this->assertEqual($data['body'], $resultData['body']);
690
		$this->assertEqual($data['text'], $resultData['text']);
691
 
692
		$this->assertTrue(is_a($resultData['created'], 'MongoDate'));
693
		$this->assertTrue(is_a($resultData['modified'], 'MongoDate'));
694
	}
695
 
696
/**
697
 * Tests update method.
698
 *
699
 * @return void
700
 * @access public
701
 */
702
	public function testUpdate() {
703
		$count0 = $this->Post->find('count');
704
 
705
		$data = array(
706
			'title' => 'test',
707
			'body' => 'aaaa',
708
			'text' => 'bbbb',
709
			'count' => 0
710
		);
711
		$saveData['Post'] = $data;
712
 
713
		$this->Post->create();
714
		$saveResult = $this->Post->save($saveData);
715
		$postId = $this->Post->id;
716
 
717
		$count1 = $this->Post->find('count');
718
		$this->assertIdentical($count1 - $count0, 1, 'Save failed to create one row');
719
 
720
		$this->assertTrue(!empty($saveResult) && is_array($saveResult));
721
		$this->assertTrue(!empty($postId) && is_string($postId));
722
		$findresult = $this->Post->find('all');
723
		$this->assertEqual(0, $findresult[0]['Post']['count']);
724
 
725
		$updatedata = array(
726
			'title' => 'test2',
727
			'body' => 'aaaa2',
728
			'text' => 'bbbb2'
729
		);
730
		$saveData['Post'] = $updatedata;
731
 
732
		$saveResult = $this->Post->save($saveData);
733
 
734
		$count2 = $this->Post->find('count');
735
		$this->assertIdentical($count2 - $count1, 0, 'Save test 2 created another row, it did not update the existing row');
736
 
737
		$this->assertTrue(!empty($saveResult) && is_array($saveResult));
738
		$this->assertIdentical($this->Post->id, $postId);
739
 
740
		$this->Post->create();
741
		$updatedata = array(
742
			'_id' => $postId,
743
			'title' => 'test3',
744
			'body' => 'aaaa3',
745
			'text' => 'bbbb3'
746
		);
747
		$saveData['Post'] = $updatedata;
748
		$saveResult = $this->Post->save($saveData);
749
 
750
		$count3 = $this->Post->find('count');
751
		$this->assertIdentical($count3 - $count2, 0, 'Saving with the id in the data created another row');
752
 
753
		$this->assertTrue(!empty($saveResult) && is_array($saveResult));
754
		$this->assertIdentical($this->Post->id, $postId);
755
 
756
		$this->Post->create();
757
		$updatedata = array(
758
			'title' => 'test4',
759
			'body' => 'aaaa4',
760
			'text' => 'bbbb4'
761
		);
762
		$saveData['Post'] = $updatedata;
763
		$this->Post->id = $postId;
764
		$saveResult = $this->Post->save($saveData);
765
 
766
		$count4 = $this->Post->find('count');
767
		$this->assertIdentical($count4 - $count3, 0, 'Saving with $Model->id set and no id in the data created another row');
768
 
769
		$this->assertTrue(!empty($saveResult) && is_array($saveResult));
770
		$this->assertIdentical($this->Post->id, $postId);
771
 
772
		$result = $this->Post->find('all');
773
 
774
		$this->assertEqual(1, count($result));
775
		$resultData = $result[0]['Post'];
776
		$this->assertEqual(7, count($resultData));
777
		$this->assertTrue(!empty($resultData['_id']));
778
		$this->assertEqual($this->Post->id, $resultData['_id']);
779
		$this->assertEqual($updatedata['title'], $resultData['title']);
780
		$this->assertEqual($updatedata['body'], $resultData['body']);
781
		$this->assertEqual($updatedata['text'], $resultData['text']);
782
		$this->assertEqual(0, $resultData['count']);
783
 
784
		// using $inc operator
785
		$this->Post->mongoNoSetOperator = '$inc';
786
		$this->Post->create();
787
		$updatedataIncrement = array(
788
			'_id' => $postId,
789
			'count' => 1,
790
		);
791
		$saveData['Post'] = $updatedataIncrement;
792
		$saveResult = $this->Post->save($saveData);
793
 
794
		$this->assertTrue(!empty($saveResult) && is_array($saveResult));
795
		$this->assertIdentical($this->Post->id, $postId);
796
 
797
		$result = $this->Post->find('all');
798
 
799
		$this->assertEqual(1, count($result));
800
		$resultData = $result[0]['Post'];
801
		$this->assertEqual(7, count($resultData));
802
		$this->assertTrue(!empty($resultData['_id']));
803
		$this->assertEqual($this->Post->id, $resultData['_id']);
804
		$this->assertEqual($updatedata['title'], $resultData['title']); //not update
805
		$this->assertEqual($updatedata['body'], $resultData['body']); //not update
806
		$this->assertEqual($updatedata['text'], $resultData['text']); //not update
807
		$this->assertEqual(1, $resultData['count']); //increment
808
		unset($this->Post->mongoNoSetOperator);
809
	}
810
 
811
 
812
/**
813
 * Tests updateAll method.
814
 *
815
 * @return void
816
 * @access public
817
 */
818
	public function testUpdateAll() {
819
		$saveData[0]['Post'] = array(
820
			'title' => 'test',
821
			'name' => 'ichi',
822
			'body' => 'aaaa1',
823
			'text' => 'bbbb1'
824
		);
825
 
826
		$saveData[1]['Post'] = array(
827
			'title' => 'test',
828
			'name' => 'ichi',
829
			'body' => 'aaaa2',
830
			'text' => 'bbbb2'
831
		);
832
 
833
		$this->Post->create();
834
		$this->Post->saveAll($saveData);
835
 
836
		$updateData = array('name' => 'ichikawa');
837
		$conditions = array('title' => 'test');
838
		$resultUpdateAll = $this->Post->updateAll($updateData, $conditions);
839
		$this->assertTrue($resultUpdateAll);
840
 
841
		$result = $this->Post->find('all');
842
		$this->assertEqual(2, count($result));
843
		$resultData = $result[0]['Post'];
844
		$this->assertEqual(7, count($resultData));
845
		$this->assertTrue(!empty($resultData['_id']));
846
		$data = $saveData[0]['Post'];
847
		$this->assertEqual($data['title'], $resultData['title']);
848
		$this->assertEqual('ichikawa', $resultData['name']);
849
		$this->assertEqual($data['body'], $resultData['body']);
850
		$this->assertEqual($data['text'], $resultData['text']);
851
		$this->assertTrue(is_a($resultData['created'], 'MongoDate'));
852
		$this->assertTrue(is_a($resultData['modified'], 'MongoDate'));
853
 
854
 
855
		$resultData = $result[1]['Post'];
856
		$this->assertEqual(7, count($resultData));
857
		$this->assertTrue(!empty($resultData['_id']));
858
		$data = $saveData[1]['Post'];
859
		$this->assertEqual($data['title'], $resultData['title']);
860
		$this->assertEqual('ichikawa', $resultData['name']);
861
		$this->assertEqual($data['body'], $resultData['body']);
862
		$this->assertEqual($data['text'], $resultData['text']);
863
		$this->assertTrue(is_a($resultData['created'], 'MongoDate'));
864
		$this->assertTrue(is_a($resultData['modified'], 'MongoDate'));
865
	}
866
 
867
/**
868
 * Tests updateAll method.
869
 *
870
 * @return void
871
 * @access public
872
 */
873
	public function testSetMongoUpdateOperator() {
874
 
875
		$ds = $this->Post->getDataSource();
876
 
877
		//normal
878
		$data = array('title' => 'test1', 'name' => 'ichikawa');
879
		$expect = array('$set' => array('title' => 'test1', 'name' => 'ichikawa'));
880
		$result = $ds->setMongoUpdateOperator($this->Post, $data);
881
		$this->assertEqual($expect, $result);
882
 
883
		//using $inc
884
		$data = array('title' => 'test1', 'name' => 'ichikawa', '$inc' => array('count' => 1));
885
		$expect = array('title' => 'test1', 'name' => 'ichikawa', '$inc' => array('count' => 1));
886
		$result = $ds->setMongoUpdateOperator($this->Post, $data);
887
		$this->assertEqual($expect, $result);
888
 
889
		//using $inc and modified
890
		$data = array('modified' => '2011/8/1', '$inc' => array('count' => 1));
891
		$expect = array('$set' => array('modified' => '2011/8/1'), '$inc' => array('count' => 1));
892
		$result = $ds->setMongoUpdateOperator($this->Post, $data);
893
		$this->assertEqual($expect, $result);
894
 
895
		//using $inc and updated
896
		$data = array('updated' => '2011/8/1', '$inc' => array('count' => 1));
897
		$expect = array('$set' => array('updated' => '2011/8/1'), '$inc' => array('count' => 1));
898
		$result = $ds->setMongoUpdateOperator($this->Post, $data);
899
		$this->assertEqual($expect, $result);
900
 
901
		//using $inc, $push and modified
902
		$data = array('$push' => array('tag' => 'tag1'), 'modified' => '2011/8/1', '$inc' => array('count' => 1));
903
		$expect = array('$push' => array('tag' => 'tag1'),'$set' => array('modified' => '2011/8/1'), '$inc' => array('count' => 1));
904
		$result = $ds->setMongoUpdateOperator($this->Post, $data);
905
		$this->assertEqual($expect, $result);
906
 
907
		//mongoNoSetOperator is true,
908
		// using $inc, $push and modified
909
		$this->Post->mongoNoSetOperator = true;
910
		$data = array('$push' => array('tag' => 'tag1'), 'modified' => '2011/8/1', '$inc' => array('count' => 1));
911
		$expect = array('$push' => array('tag' => 'tag1'),'modified' => '2011/8/1', '$inc' => array('count' => 1));
912
		$result = $ds->setMongoUpdateOperator($this->Post, $data);
913
		$this->assertEqual($expect, $result);
914
 
915
 
916
		//mongoNoSetOperator is $inc,
917
		$this->Post->mongoNoSetOperator = '$inc';
918
		$data = array('count' => 1);
919
		$expect = array('$inc' => array('count' => 1));
920
		$result = $ds->setMongoUpdateOperator($this->Post, $data);
921
		$this->assertEqual($expect, $result);
922
 
923
 
924
		//mongoNoSetOperator is $inc,
925
		// with modified field
926
		$this->Post->mongoNoSetOperator = '$inc';
927
		$data = array('count' => 1, 'modified' => '2011/8/1');
928
		$expect = array('$inc' => array('count' => 1),'$set' => array('modified' => '2011/8/1'));
929
		$result = $ds->setMongoUpdateOperator($this->Post, $data);
930
		$this->assertEqual($expect, $result);
931
 
932
		//mongoNoSetOperator is $inc,
933
		// with updated field
934
		$this->Post->mongoNoSetOperator = '$inc';
935
		$data = array('count' => 1, 'updated' => '2011/8/1');
936
		$expect = array('$inc' => array('count' => 1),'$set' => array('updated' => '2011/8/1'));
937
		$result = $ds->setMongoUpdateOperator($this->Post, $data);
938
		$this->assertEqual($expect, $result);
939
	}
940
 
941
 
942
/**
943
 * Tests update method without $set operator.
944
 *
945
 * @return void
946
 * @access public
947
 */
948
	public function testUpdateWithoutMongoSchemaProperty() {
949
		$data = array(
950
			'title' => 'test',
951
			'body' => 'aaaa',
952
			'text' => 'bbbb',
953
			'count' => 0,
954
			'created' => new mongoDate(),
955
			'modified' => new mongoDate(),
956
		);
957
		$saveData['MongoArticle'] = $data;
958
 
959
		$this->MongoArticle->create();
960
		$saveResult = $this->MongoArticle->save($saveData);
961
		$postId = $this->MongoArticle->id;
962
 
963
		//using $set operator
964
		$this->MongoArticle->create();
965
		$updatedata = array(
966
			'id' => $postId,
967
			'title' => 'test3',
968
			'body' => 'aaaa3',
969
		);
970
		$saveData['MongoArticle'] = $updatedata;
971
		$saveResult = $this->MongoArticle->save($saveData); // using $set operator
972
 
973
		$this->assertTrue(!empty($saveResult) && is_array($saveResult));
974
		$this->assertIdentical($this->MongoArticle->id, $postId);
975
 
976
		$result = null;
977
		$result = $this->MongoArticle->find('all');
978
 
979
		$this->assertEqual(1, count($result));
980
		$resultData = $result[0]['MongoArticle'];
981
		$this->assertEqual($this->MongoArticle->id, $resultData['id']);
982
		$this->assertEqual($updatedata['title'], $resultData['title']); //update
983
		$this->assertEqual($updatedata['body'], $resultData['body']); //update
984
		$this->assertEqual($data['text'], $resultData['text']); //not update
985
		$this->assertEqual($data['count'], $resultData['count']); //not update
986
 
987
 
988
 
989
		//using $inc operator insted of $set operator
990
		$this->MongoArticle->create();
991
		$updatedataInc = array(
992
			'id' => $postId,
993
			'$inc' => array('count' => 1),
994
		);
995
		$saveData['MongoArticle'] = $updatedataInc;
996
		$saveResult = $this->MongoArticle->save($saveData); // using $set operator
997
 
998
		$this->assertTrue(!empty($saveResult) && is_array($saveResult));
999
		$this->assertIdentical($this->MongoArticle->id, $postId);
1000
		$result = null;
1001
		$result = $this->MongoArticle->find('all');
1002
 
1003
		$this->assertEqual(1, count($result));
1004
		$resultData = $result[0]['MongoArticle'];
1005
		$this->assertEqual($this->MongoArticle->id, $resultData['id']);
1006
		$this->assertEqual($updatedata['title'], $resultData['title']); //not update
1007
		$this->assertEqual($updatedata['body'], $resultData['body']); //not update
1008
		$this->assertEqual($data['text'], $resultData['text']); //not update
1009
		$this->assertEqual(1, $resultData['count']); //increment
1010
 
1011
		//using $inc and $push
1012
		$this->MongoArticle->create();
1013
		$updatedataInc = array(
1014
				'id' => $postId,
1015
				'$push' => array(
1016
					'comments' => array(
1017
						'_id' => new MongoId(),
1018
						'created' => new MongoDate(),
1019
						'vote_count' => 0,
1020
						'user' => 'user1',
1021
						'body' => 'comment',
1022
						)
1023
					),
1024
				'$inc' => array('count' => 1),
1025
				);
1026
		$saveData['MongoArticle'] = $updatedataInc;
1027
		$saveResult = $this->MongoArticle->save($saveData); // using $set operator
1028
 
1029
		$this->assertTrue(!empty($saveResult) && is_array($saveResult));
1030
		$this->assertIdentical($this->MongoArticle->id, $postId);
1031
		$result = null;
1032
		$result = $this->MongoArticle->find('all');
1033
 
1034
		$this->assertEqual(1, count($result));
1035
		$resultData = $result[0]['MongoArticle'];
1036
		$this->assertEqual($this->MongoArticle->id, $resultData['id']);
1037
		$this->assertEqual($updatedata['title'], $resultData['title']); //not update
1038
		$this->assertEqual($updatedata['body'], $resultData['body']); //not update
1039
		$this->assertEqual($data['text'], $resultData['text']); //not update
1040
		$this->assertEqual(2, $resultData['count']); //increment
1041
		$this->assertEqual('user1', $resultData['comments'][0]['user']); //push
1042
		$this->assertEqual('comment', $resultData['comments'][0]['body']); //push
1043
		$this->assertEqual(1, count($resultData['comments'])); //push
1044
		$this->assertTrue(!empty($resultData['created']));
1045
		$this->assertTrue(!empty($resultData['modified']));
1046
 
1047
 
1048
		//no $set operator
1049
		$this->MongoArticle->mongoNoSetOperator = true;
1050
 
1051
		$this->MongoArticle->create();
1052
		$updatedata = array(
1053
			'id' => $postId,
1054
			'title' => 'test4',
1055
			'body' => 'aaaa4',
1056
			'count' => '1',
1057
		);
1058
		$saveData['MongoArticle'] = $updatedata;
1059
		$saveResult = $this->MongoArticle->save($saveData);
1060
 
1061
		$this->assertTrue(!empty($saveResult) && is_array($saveResult));
1062
		$this->assertIdentical($this->MongoArticle->id, $postId);
1063
 
1064
		$result = null;
1065
		$result = $this->MongoArticle->find('all');
1066
 
1067
		$this->assertEqual(1, count($result));
1068
		$resultData = $result[0]['MongoArticle'];
1069
		$this->assertEqual($this->MongoArticle->id, $resultData['id']);
1070
		$this->assertEqual($updatedata['title'], $resultData['title']); //update
1071
		$this->assertEqual($updatedata['body'], $resultData['body']); //update
1072
		$this->assertTrue(empty($resultData['text']));
1073
		$this->assertEqual(1, $resultData['count']);
1074
 
1075
		$this->MongoArticle->mongoNoSetOperator = null;
1076
 
1077
 
1078
		//use $push
1079
		$this->MongoArticle->create();
1080
		$updatedata = array(
1081
			'id' => $postId,
1082
			'push_column' => array('push1'),
1083
		);
1084
		$saveData['MongoArticle'] = $updatedata;
1085
		$saveResult = $this->MongoArticle->save($saveData); //use $set
1086
 
1087
		$result = $this->MongoArticle->find('all');
1088
		$resultData = $result[0]['MongoArticle'];
1089
		$this->assertEqual('test4', $resultData['title']); // no update
1090
		$this->assertEqual(array('push1'), $resultData['push_column']);
1091
 
1092
 
1093
		$this->MongoArticle->mongoNoSetOperator = '$push';
1094
		$this->MongoArticle->create();
1095
		$updatedata = array(
1096
			'id' => $postId,
1097
			'push_column' => 'push2',
1098
		);
1099
		$saveData['MongoArticle'] = $updatedata;
1100
		$saveResult = $this->MongoArticle->save($saveData); //use $push
1101
 
1102
		$this->assertTrue(!empty($saveResult) && is_array($saveResult));
1103
		$this->assertIdentical($this->MongoArticle->id, $postId);
1104
 
1105
		$result = null;
1106
		$result = $this->MongoArticle->find('all');
1107
 
1108
 
1109
		$this->assertEqual(1, count($result));
1110
		$resultData = $result[0]['MongoArticle'];
1111
		$this->assertEqual($this->MongoArticle->id, $resultData['id']);
1112
		$this->assertEqual('test4', $resultData['title']); // no update
1113
		$this->assertEqual(array('push1','push2'), $resultData['push_column']); //update
1114
 
1115
		$this->MongoArticle->mongoNoSetOperator = null;
1116
 
1117
 
1118
		unset($this->MongoArticle);
1119
	}
1120
 
1121
 
1122
/**
1123
 * Tests groupBy
1124
 *
1125
 * @return void
1126
 * @access public
1127
 */
1128
	public function testGroupBy() {
1129
		for($i = 0 ; $i < 30 ; $i++) {
1130
			$saveData[$i]['Post'] = array(
1131
					'title' => 'test'.$i,
1132
					'body' => 'aaaa'.$i,
1133
					'text' => 'bbbb'.$i,
1134
					'count' => $i,
1135
					);
1136
		}
1137
 
1138
		$saveData[30]['Post'] = array(
1139
			'title' => 'test1',
1140
			'body' => 'aaaa1',
1141
			'text' => 'bbbb1',
1142
			'count' => 1,
1143
		);
1144
		$saveData[31]['Post'] = array(
1145
			'title' => 'test2',
1146
			'body' => 'aaaa2',
1147
			'text' => 'bbbb2',
1148
			'count' => 2,
1149
		);
1150
 
1151
		$this->Post->create();
1152
		$saveResult = $this->Post->saveAll($saveData);
1153
 
1154
		$cond_count = 5;
1155
		$query = array(
1156
				'key' => array('title' => true ),
1157
				'initial' => array('csum' => 0),
1158
				'reduce' => 'function(obj, prev){prev.csum += 1;}',
1159
				'options' => array(
1160
					'condition' => array('count' => array('$lt' => $cond_count)),
1161
					),
1162
				);
1163
 
1164
		$mongo = $this->Post->getDataSource();
1165
		$result =  $mongo->group($query, $this->Post);
1166
 
1167
		$this->assertTrue($result['ok'] == 1 && count($result['retval']) > 0);
1168
		$this->assertEqual($cond_count, count($result['retval']));
1169
		$this->assertEqual('test0', $result['retval'][0]['title']);
1170
		$this->assertEqual('test1', $result['retval'][1]['title']);
1171
		$this->assertEqual('test2', $result['retval'][2]['title']);
1172
		$this->assertEqual(1, $result['retval'][0]['csum']);
1173
		$this->assertEqual(2, $result['retval'][1]['csum']);
1174
		$this->assertEqual(2, $result['retval'][2]['csum']);
1175
	}
1176
 
1177
 
1178
 
1179
/**
1180
 * Tests query
1181
 *  Distinct, Group
1182
 *
1183
 * @return void
1184
 * @access public
1185
 */
1186
	public function testQuery() {
1187
		for($i = 0 ; $i < 30 ; $i++) {
1188
			$saveData[$i]['Post'] = array(
1189
					'title' => 'test'.$i,
1190
					'body' => 'aaaa'.$i,
1191
					'text' => 'bbbb'.$i,
1192
					'count' => $i,
1193
					);
1194
		}
1195
 
1196
		$saveData[30]['Post'] = array(
1197
			'title' => 'test1',
1198
			'body' => 'aaaa1',
1199
			'text' => 'bbbb1',
1200
			'count' => 1,
1201
		);
1202
		$saveData[31]['Post'] = array(
1203
			'title' => 'test2',
1204
			'body' => 'aaaa2',
1205
			'text' => 'bbbb2',
1206
			'count' => 2,
1207
		);
1208
 
1209
		$saveData[32]['Post'] = array(
1210
			'title' => 'test2',
1211
			'body' => 'aaaa2',
1212
			'text' => 'bbbb2',
1213
			'count' => 32,
1214
		);
1215
 
1216
		$this->Post->create();
1217
		$saveResult = $this->Post->saveAll($saveData);
1218
 
1219
 
1220
		//using query() Distinct
1221
		$params = array(
1222
				'distinct' => 'posts',
1223
				'key' => 'count',
1224
				);
1225
		$result = $this->Post->query( $params );
1226
		$this->assertEqual(1, $result['values'][1]);
1227
		$this->assertEqual(2, $result['values'][2]);
1228
		$this->assertEqual(32, $result['values'][30]);
1229
 
1230
 
1231
		//using query() group
1232
		$cond_count = 5;
1233
		$reduce = "function(obj,prev){prev.csum++;}";
1234
		$params = array(
1235
				'group'=>array(
1236
					'ns'=>'posts',
1237
					'cond'=>array('count' => array('$lt' => $cond_count)),
1238
					'key'=>array('title'=>true),
1239
					'initial'=>array('csum'=>0),
1240
					'$reduce'=>$reduce
1241
					)
1242
				);
1243
 
1244
		$result = $this->Post->query( $params );
1245
 
1246
		$this->assertTrue($result['ok'] == 1 && count($result['retval']) > 0);
1247
		$this->assertEqual($cond_count, count($result['retval']));
1248
		$this->assertEqual('test0', $result['retval'][0]['title']);
1249
		$this->assertEqual('test1', $result['retval'][1]['title']);
1250
		$this->assertEqual('test2', $result['retval'][2]['title']);
1251
		$this->assertEqual(1, $result['retval'][0]['csum']);
1252
		$this->assertEqual(2, $result['retval'][1]['csum']);
1253
		$this->assertEqual(2, $result['retval'][2]['csum']);
1254
	}
1255
 
1256
/**
1257
 * Tests MapReduce
1258
 *
1259
 * @return void
1260
 * @access public
1261
 */
1262
	public function testMapReduce() {
1263
		for($i = 0 ; $i < 30 ; $i++) {
1264
			$saveData[$i]['Post'] = array(
1265
					'title' => 'test'.$i,
1266
					'body' => 'aaaa'.$i,
1267
					'text' => 'bbbb'.$i,
1268
					'count' => $i,
1269
					);
1270
		}
1271
 
1272
		$saveData[30]['Post'] = array(
1273
				'title' => 'test1',
1274
				'body' => 'aaaa1',
1275
				'text' => 'bbbb1',
1276
				'count' => 1,
1277
				);
1278
		$saveData[31]['Post'] = array(
1279
				'title' => 'test2',
1280
				'body' => 'aaaa2',
1281
				'text' => 'bbbb2',
1282
				'count' => 2,
1283
				);
1284
 
1285
		$saveData[32]['Post'] = array(
1286
				'title' => 'test2',
1287
				'body' => 'aaaa2',
1288
				'text' => 'bbbb2',
1289
				'count' => 32,
1290
				);
1291
 
1292
		$this->Post->create();
1293
		$saveResult = $this->Post->saveAll($saveData);
1294
 
1295
		$map = new MongoCode("function() { emit(this.title,1); }");
1296
		$reduce = new MongoCode("function(k, vals) { ".
1297
				"var sum = 0;".
1298
				"for (var i in vals) {".
1299
				"sum += vals[i];".
1300
				"}".
1301
				"return sum; }"
1302
				);
1303
 
1304
		$params = array(
1305
				"mapreduce" => "posts",
1306
				"map" => $map,
1307
				"reduce" => $reduce,
1308
				"query" => array(
1309
					"count" => array('$gt' => -2),
1310
					),
1311
				'out' => 'test_mapreduce_posts',
1312
				);
1313
 
1314
		$mongo = $this->Post->getDataSource();
1315
		$results = $mongo->mapReduce($params);
1316
 
1317
		$posts = array();
1318
		foreach ($results as $post) {
1319
			$posts[$post['_id']] = $post['value'];
1320
		}
1321
 
1322
		$this->assertEqual(30, count($posts));
1323
		$this->assertEqual(1, $posts['test0']);
1324
		$this->assertEqual(2, $posts['test1']);
1325
		$this->assertEqual(3, $posts['test2']);
1326
		$this->assertEqual(1, $posts['test3']);
1327
 
1328
 
1329
		//set timeout
1330
		$results = $mongo->mapReduce($params, 100); //set timeout 100msec
1331
		$posts = array();
1332
		foreach ($results as $post) {
1333
			$posts[$post['_id']] = $post['value'];
1334
		}
1335
 
1336
		$this->assertEqual(30, count($posts));
1337
		$this->assertEqual(1, $posts['test0']);
1338
		$this->assertEqual(2, $posts['test1']);
1339
		$this->assertEqual(3, $posts['test2']);
1340
		$this->assertEqual(1, $posts['test3']);
1341
 
1342
 
1343
		//get results as inline data
1344
		$version = $this->getMongodVersion();
1345
		if( $version >= '1.7.4') {
1346
			$params = array(
1347
					"mapreduce" => "posts",
1348
					"map" => $map,
1349
					"reduce" => $reduce,
1350
					"query" => array(
1351
						"count" => array('$gt' => -2),
1352
						),
1353
					'out' => array('inline' => 1),
1354
					);
1355
 
1356
			$results = $mongo->mapReduce($params);
1357
 
1358
			$posts = array();
1359
			foreach ($results as $post) {
1360
				$posts[$post['_id']] = $post['value'];
1361
			}
1362
 
1363
			$this->assertEqual(30, count($posts));
1364
			$this->assertEqual(1, $posts['test0']);
1365
			$this->assertEqual(2, $posts['test1']);
1366
			$this->assertEqual(3, $posts['test2']);
1367
			$this->assertEqual(1, $posts['test3']);
1368
		}
1369
	}
1370
 
1371
 
1372
 
1373
/**
1374
 * testSort method
1375
 *
1376
 * @return void
1377
 * @access public
1378
 */
1379
	public function testSort() {
1380
		$data = array(
1381
			'title' => 'AAA',
1382
			'body' => 'aaaa',
1383
			'text' => 'aaaa'
1384
		);
1385
		$saveData['Post'] = $data;
1386
		$this->Post->create();
1387
		$this->Post->save($saveData);
1388
 
1389
		$data = array(
1390
			'title' => 'CCC',
1391
			'body' => 'cccc',
1392
			'text' => 'cccc'
1393
		);
1394
		$saveData['Post'] = $data;
1395
		$this->Post->create();
1396
		$this->Post->save($saveData);
1397
 
1398
		$this->Post->create();
1399
		$data = array(
1400
			'title' => 'BBB',
1401
			'body' => 'bbbb',
1402
			'text' => 'bbbb'
1403
		);
1404
		$saveData['Post'] = $data;
1405
		$this->Post->create();
1406
		$this->Post->save($saveData);
1407
 
1408
		$expected = array('AAA', 'BBB', 'CCC');
1409
		$result = $this->Post->find('all', array(
1410
			'fields' => array('_id', 'title'),
1411
			'order' => array('title' => 1)
1412
		));
1413
		$result = Hash::extract($result, '{n}.Post.title');
1414
 
1415
		$this->assertEqual($expected, $result);
1416
		$result = $this->Post->find('all', array(
1417
			'fields' => array('_id', 'title'),
1418
			'order' => array('title' => 'ASC')
1419
		));
1420
		$result = Hash::extract($result, '{n}.Post.title');
1421
 
1422
		$expected = array_reverse($expected);
1423
		$result = $this->Post->find('all', array(
1424
			'fields' => array('_id', 'title'),
1425
			'order' => array('title' => '-1')
1426
		));
1427
		$result = Hash::extract($result, '{n}.Post.title');
1428
		$this->assertEqual($expected, $result);
1429
 
1430
		$result = $this->Post->find('all', array(
1431
			'fields' => array('_id', 'title'),
1432
			'order' => array('title' => 'DESC')
1433
		));
1434
		$result = Hash::extract($result, '{n}.Post.title');
1435
		$this->assertEqual($expected, $result);
1436
	}
1437
 
1438
/**
1439
 * testSchemaless method
1440
 *
1441
 * Test you can save to a model without specifying mongodb.
1442
 *
1443
 * @return void
1444
 * @access public
1445
 */
1446
	public function testSchemaless() {
1447
		$toSave = array(
1448
			'title' => 'A test article',
1449
			'body' => str_repeat('Lorum ipsum ', 100),
1450
			'tags' => array(
1451
				'one',
1452
				'two',
1453
				'three'
1454
			),
1455
			'modified' => null,
1456
			'created' => null
1457
		);
1458
 
1459
		$this->MongoArticle = ClassRegistry::init('MongoArticle');
1460
		$this->MongoArticle->create();
1461
		$saveResult = $this->MongoArticle->save($toSave);
1462
		$this->assertTrue(!empty($saveResult) && is_array($saveResult));
1463
 
1464
		$expected = array_intersect_key($toSave, array_flip(array('title', 'body', 'tags')));
1465
		$result = $this->MongoArticle->read(array('title', 'body', 'tags'));
1466
		unset ($result['MongoArticle']['id']); // prevent auto added field from screwing things up
1467
		$this->assertEqual($expected, $result['MongoArticle']);
1468
 
1469
		$toSave = array(
1470
			'title' => 'Another test article',
1471
			'body' => str_repeat('Lorum pipsum ', 100),
1472
			'tags' => array(
1473
				'four',
1474
				'five',
1475
				'six'
1476
			),
1477
			'starts' => date('Y-M-d H:i:s'),
1478
			'modified' => null,
1479
			'created' => null
1480
		);
1481
		$this->MongoArticle->create();
1482
    $saveResult = $this->MongoArticle->save($toSave);
1483
    $this->assertTrue(!empty($saveResult) && is_array($saveResult));
1484
 
1485
		$starts = $this->MongoArticle->field('starts');
1486
		$this->assertEqual($toSave['starts'], $starts);
1487
	}
1488
 
1489
/**
1490
 * testSpecificId method
1491
 *
1492
 * Test you can save specifying your own _id values - and update by _id
1493
 *
1494
 * @return void
1495
 * @access public
1496
 */
1497
	public function testSpecificId() {
1498
		$data = array(
1499
			'_id' => 123,
1500
			'title' => 'test',
1501
			'body' => 'aaaa',
1502
			'text' => 'bbbb'
1503
		);
1504
		$saveData['Post'] = $data;
1505
 
1506
		$this->Post->create();
1507
		$saveResult = $this->Post->save($saveData);
1508
		$this->assertTrue(!empty($saveResult) && is_array($saveResult));
1509
 
1510
 
1511
		$found = $this->Post->find('first', array(
1512
			'fields' => array('_id', 'title', 'body', 'text'),
1513
			'conditions' => array('_id' => 123)
1514
		));
1515
 
1516
		$this->assertEqual($found, $saveData);
1517
 
1518
		$data = array(
1519
			'_id' => 123,
1520
			'title' => 'test2',
1521
			'body' => 'aaaa2',
1522
			'text' => 'bbbb2'
1523
		);
1524
		$saveData['Post'] = $data;
1525
 
1526
		$this->Post->create();
1527
		$saveResult = $this->Post->save($saveData);
1528
		$this->assertTrue(!empty($saveResult) && is_array($saveResult));
1529
 
1530
		$found = $this->Post->find('first', array(
1531
			'fields' => array('_id', 'title', 'body', 'text'),
1532
			'conditions' => array('_id' => 123)
1533
		));
1534
		$this->assertEqual($found, $saveData);
1535
	}
1536
 
1537
/**
1538
 * testOr method
1539
 *
1540
 * @return void
1541
 * @access public
1542
 */
1543
	public function testOr() {
1544
		$mongoVersion = $this->mongodb->execute('db.version()');
1545
		$shouldSkip = version_compare($mongoVersion, '1.5.3', '<');
1546
		if ($this->skipIf($shouldSkip, '$or tests require at least version mongo version 1.5.3, currently using ' . $mongoVersion . ' %s')) {
1547
			return;
1548
		}
1549
 
1550
		$this->MongoArticle = ClassRegistry::init('MongoArticle');
1551
		$this->MongoArticle->create();
1552
 
1553
		for ($i = 1; $i <= 20; $i++) {
1554
			$data = array(
1555
				'title' => "Article $i",
1556
				'subtitle' => "Sub Article $i",
1557
			);
1558
			$saveData['MongoArticle'] = $data;
1559
			$this->MongoArticle->create();
1560
			$this->MongoArticle->save($saveData);
1561
		}
1562
		$expected = $this->MongoArticle->find('all', array(
1563
			'conditions' => array(
1564
				'title' => array('$in' => array('Article 1', 'Article 10'))
1565
			),
1566
			'order' => array('number' => 'ASC')
1567
		));
1568
 
1569
		$this->assertEqual(count($expected), 2);
1570
 
1571
		$result = $this->MongoArticle->find('all', array(
1572
			'conditions' => array(
1573
				'$or' => array(
1574
					array('title' => 'Article 1'),
1575
					array('title' => 'Article 10'),
1576
				)
1577
			),
1578
			'order' => array('number' => 'ASC')
1579
		));
1580
		$this->assertEqual($result, $expected);
1581
	}
1582
 
1583
/**
1584
 * testDeleteAll method
1585
 *
1586
 * @return void
1587
 * @access public
1588
 */
1589
	function testDeleteAll($cascade = true) {
1590
		$this->MongoArticle = ClassRegistry::init('MongoArticle');
1591
		$this->MongoArticle->create(array('title' => 'Article 1', 'cat' => 1));
1592
		$this->MongoArticle->save();
1593
 
1594
		$this->MongoArticle->create(array('title' => 'Article 2', 'cat' => 1));
1595
		$this->MongoArticle->save();
1596
 
1597
		$this->MongoArticle->create(array('title' => 'Article 3', 'cat' => 2));
1598
		$this->MongoArticle->save();
1599
 
1600
		$this->MongoArticle->create(array('title' => 'Article 4', 'cat' => 2));
1601
		$this->MongoArticle->save();
1602
 
1603
		$count = $this->MongoArticle->find('count');
1604
		$this->assertEqual($count, 4);
1605
 
1606
		$this->MongoArticle->deleteAll(array('cat' => 2), $cascade);
1607
 
1608
		$count = $this->MongoArticle->find('count');
1609
		$this->assertEqual($count, 2);
1610
 
1611
		$this->MongoArticle->deleteAll(true, $cascade);
1612
 
1613
		$count = $this->MongoArticle->find('count');
1614
		$this->assertEqual($count, 0);
1615
	}
1616
 
1617
/**
1618
 * testDeleteAllNoCascade method
1619
 *
1620
 * @return void
1621
 * @access public
1622
 */
1623
	function testDeleteAllNoCascade() {
1624
		$this->testDeleteAll(false);
1625
	}
1626
 
1627
/**
1628
 * testRegexSearch method
1629
 *
1630
 * @return void
1631
 * @access public
1632
 */
1633
	public function testRegexSearch() {
1634
		$this->MongoArticle = ClassRegistry::init('MongoArticle');
1635
		$this->MongoArticle->create(array('title' => 'Article 1', 'cat' => 1));
1636
		$this->MongoArticle->save();
1637
		$this->MongoArticle->create(array('title' => 'Article 2', 'cat' => 1));
1638
		$this->MongoArticle->save();
1639
		$this->MongoArticle->create(array('title' => 'Article 3', 'cat' => 2));
1640
		$this->MongoArticle->save();
1641
 
1642
		$count=$this->MongoArticle->find('count',array(
1643
			'conditions'=>array(
1644
				'title'=>'Article 2'
1645
			)
1646
		));
1647
		$this->assertEqual($count, 1);
1648
 
1649
		$count = $this->MongoArticle->find('count',array(
1650
			'conditions'=>array(
1651
				'title'=> new MongoRegex('/^Article/')
1652
			)
1653
		));
1654
		$this->assertEqual($count, 3);
1655
	}
1656
 
1657
/**
1658
 * testEmptyReturn method
1659
 * 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
1660
 * @return void
1661
 * @access public
1662
 */
1663
	public function testEmptyReturn() {
1664
		$this->MongoArticle = ClassRegistry::init('MongoArticle');
1665
		$this->MongoArticle->create(array('title' => 'Article 1', 'cat' => 1));
1666
		$this->MongoArticle->save();
1667
		$articles=$this->MongoArticle->find('all',array(
1668
			'conditions'=>array(
1669
				'title'=>'Article 2'
1670
			)
1671
		));
1672
		$this->assertTrue(is_array($articles) && empty($articles));
1673
		$articles=$this->MongoArticle->find('first',array(
1674
			'conditions'=>array(
1675
				'title'=>'Article 2'
1676
			)
1677
		));
1678
		$this->assertTrue(is_array($articles) && empty($articles));
1679
	}
1680
 
1681
/**
1682
 * Tests isUnique validation.
1683
 *
1684
 * @return void
1685
 * @access public
1686
 */
1687
	public function testSaveUniques() {
1688
		$data = array(
1689
			'title' => 'test',
1690
			'body' => 'aaaa',
1691
			'text' => 'bbbb',
1692
			'uniquefield1'=>'uniquenameforthistest'
1693
		);
1694
		$saveData['Post'] = $data;
1695
 
1696
		$this->Post->Behaviors->attach('Mongodb.SqlCompatible');
1697
		$this->Post->create();
1698
		$saveResult = $this->Post->save($saveData);
1699
    $this->assertTrue(!empty($saveResult) && is_array($saveResult));
1700
 
1701
		$data = array(
1702
			'title' => 'test',
1703
			'body' => 'asdf',
1704
			'text' => 'bbbb',
1705
			'uniquefield1'=>'uniquenameforthistest'
1706
		);
1707
		$saveData['Post'] = $data;
1708
 
1709
		$this->Post->create();
1710
		$saveResult = $this->Post->save($saveData);
1711
		$this->assertFalse($saveResult);
1712
	}
1713
 
1714
/**
1715
 * Tests isUnique validation with custom validation.
1716
 *
1717
 * @return void
1718
 * @access public
1719
 */
1720
	public function testSaveUniquesCustom() {
1721
		$data = array(
1722
			'title' => 'test',
1723
			'body' => 'aaaa',
1724
			'text' => 'bbbb',
1725
			'uniquefield2' => 'someunqiuename'
1726
		);
1727
		$saveData['Post'] = $data;
1728
		$this->Post->create();
1729
		$saveResult = $this->Post->save($saveData);
1730
		$this->assertTrue(!empty($saveResult) && is_array($saveResult));
1731
 
1732
		$data = array(
1733
			'title' => 'test',
1734
			'body' => 'asdf',
1735
			'text' => 'bbbb',
1736
			'uniquefield2' => 'someunqiuename'
1737
		);
1738
		$saveData['Post'] = $data;
1739
		$this->Post->create();
1740
		$saveResult = $this->Post->save($saveData);
1741
		$this->assertFalse($saveResult);
1742
	}
1743
 
1744
	public function testReturn() {
1745
		$this->MongoArticle = ClassRegistry::init('MongoArticle');
1746
		$this->MongoArticle->create(array('title' => 'Article 1', 'cat' => 1));
1747
		$this->MongoArticle->save();
1748
		$this->MongoArticle->create(array('title' => 'Article 2', 'cat' => 1));
1749
		$this->MongoArticle->save();
1750
 
1751
		$return = $this->MongoArticle->find('all', array(
1752
			'conditions' => array(
1753
				'title' => 'Article 2'
1754
			)
1755
		));
1756
		$this->assertTrue(is_array($return));
1757
 
1758
		$return = $this->MongoArticle->find('first', array(
1759
			'conditions' => array(
1760
				'title' => 'Article 2'
1761
			)
1762
		));
1763
		$this->assertTrue(is_array($return));
1764
 
1765
		$return = $this->MongoArticle->find('first', array(
1766
			'conditions' => array(
1767
				'title' => 'Article 2'
1768
			)
1769
		));
1770
		$this->assertTrue(is_array($return));
1771
 
1772
		$return = $this->MongoArticle->find('count', array(
1773
			'conditions' => array(
1774
				'title' => 'Article 2'
1775
			)
1776
		));
1777
		$this->assertTrue(is_int($return));
1778
 
1779
		$return = $this->MongoArticle->find('neighbors', array(
1780
			'conditions' => array(
1781
				'title' => 'Article 2'
1782
			)
1783
		));
1784
		$this->assertTrue(is_array($return));
1785
 
1786
		$return = $this->MongoArticle->find('list', array(
1787
			'conditions' => array(
1788
				'title' => 'Article 2'
1789
			)
1790
		));
1791
		$this->assertTrue(is_array($return));
1792
 
1793
		$return = $this->MongoArticle->find('all', array(
1794
			'conditions' => array(
1795
				'title' => 'Doesn\'t exist'
1796
			)
1797
		));
1798
		$this->assertTrue(is_array($return));
1799
 
1800
		$return = $this->MongoArticle->find('first', array(
1801
			'conditions' => array(
1802
				'title' => 'Doesn\'t exist'
1803
			)
1804
		));
1805
		$this->assertTrue(is_array($return) && empty($return));
1806
 
1807
		$return = $this->MongoArticle->find('count', array(
1808
			'conditions' => array(
1809
				'title' => 'Doesn\'t exist'
1810
			)
1811
		));
1812
		$this->assertTrue(is_int($return));
1813
 
1814
		$return = $this->MongoArticle->find('neighbors', array(
1815
			'conditions' => array(
1816
				'title' => 'Doesn\'t exist'
1817
			)
1818
		));
1819
		$this->assertTrue(is_array($return));
1820
 
1821
		$return = $this->MongoArticle->find('list', array(
1822
			'conditions' => array(
1823
				'title' => 'Doesn\'t exist'
1824
			)
1825
		));
1826
		$this->assertTrue(is_array($return));
1827
	}
1828
 
1829
	public function testDatetimeFieldUsingMongoDate() {
1830
		$this->Comment = ClassRegistry::init(array('class' => 'Comment', 'alias' => 'Comment', 'ds' => 'test_mongo'), true);
1831
		$ds = $this->Comment->getDataSource();
1832
 
1833
		$fields = array(
1834
			'post_id',
1835
			'comment',
1836
			'comment_at',
1837
		);
1838
 
1839
		$values = array(
1840
			array( 1, 'comment 1', '2014-02-21 01:02:03Z'),
1841
			array( 1, 'comment 2', '2014-02-22 01:02:03Z'),
1842
			array( 1, 'comment 3', '2014-02-23 01:02:03Z'),
1843
			array( 1, 'comment 4', '2014-02-24 01:02:03Z'),
1844
			array( 1, 'comment 5', '2014-02-25 01:02:03Z')
1845
		);
1846
 
1847
		$ds->insertMulti('comments', $fields, $values);
1848
		$result = $this->Comment->find('all');
1849
		$this->assertEqual(count($result), 5);
1850
 
1851
		$this->assertTrue(is_a($result[0]['Comment']['comment_at'], 'MongoDate'));
1852
		$this->assertTrue(is_a($result[1]['Comment']['comment_at'], 'MongoDate'));
1853
		$this->assertTrue(is_a($result[2]['Comment']['comment_at'], 'MongoDate'));
1854
		$this->assertTrue(is_a($result[3]['Comment']['comment_at'], 'MongoDate'));
1855
		$this->assertTrue(is_a($result[4]['Comment']['comment_at'], 'MongoDate'));
1856
 
1857
		$values = array(
1858
			array( 2, 'comment 2 1', new MongoDate(strtotime('2014-02-21 02:02:01Z'))),
1859
		);
1860
 
1861
		$ds->insertMulti('comments', $fields, $values);
1862
 
1863
		$conditions = array('post_id' => 2);
1864
		$result = $this->Comment->find('all', array('conditions' => $conditions));
1865
		$this->assertEqual(count($result), 1);
1866
		$this->assertTrue(is_a($result[0]['Comment']['comment_at'], 'MongoDate'));
1867
 
1868
		$data = array(
1869
			'Comment' => array(
1870
				'user_id' => 3,
1871
				'comment' => 'comment 3 1',
1872
				'comment_at' => new MongoDate(strtotime('2014-02-26 03:02:01Z')),
1873
			)
1874
		);
1875
 
1876
		$this->Comment->create();
1877
		$result = $this->Comment->save($data);
1878
 
1879
		$expected = array(
1880
			'Comment' => array(
1881
				'user_id' => 3,
1882
				'comment' => 'comment 3 1',
1883
				'comment_at' => new MongoDate(strtotime('2014-02-26 03:02:01Z')),
1884
				'created' => Hash::get($result, 'Comment.created'),
1885
				'modified' => Hash::get($result, 'Comment.modified'),
1886
				'_id' => Hash::get($result, 'Comment._id'),
1887
			)
1888
		);
1889
		$this->assertEquals($result, $expected);
1890
	}
1891
 
1892
	public function testReadUsingHint() {
1893
		$index = array('count' => 1, 'created' => -1);
1894
		$this->Post->getDataSource()->ensureIndex($this->Post, $index);
1895
 
1896
		$data = array(
1897
			array(
1898
				'title' => 'test1',
1899
				'body' => 'aaaa',
1900
				'text' => 'bbbb',
1901
				'count' => 3
1902
			),
1903
			array(
1904
				'title' => 'test2',
1905
				'body' => 'cccc',
1906
				'text' => 'dddd',
1907
				'count' => 4
1908
			),
1909
			array(
1910
				'title' => 'test1',
1911
				'body' => 'eeee',
1912
				'text' => 'ffff',
1913
				'count' => 5
1914
			),
1915
		);
1916
		foreach ($data as $set) {
1917
			$this->insertData($set);
1918
		}
1919
 
1920
		$result = $this->Post->find('all', array(
1921
			'conditions' => array('count' => array('$gt' => 3)),
1922
			'hint' => $index,
1923
		));
1924
		$this->assertCount(2, $result);
1925
 
1926
		$result = $this->Post->find('count', array(
1927
			'conditions' => array('count' => array('$gt' => 3)),
1928
			'hint' => $index,
1929
		));
1930
		$this->assertSame(2, $result);
1931
	}
1932
 
1933
	public function testReadUsingHintThrowExceptionWhenNonExistsIndex() {
1934
		$index = array('count' => 1, 'created' => -1);
1935
		$this->Post->getDataSource()->ensureIndex($this->Post, $index);
1936
 
1937
		$invalidIndex = array('count' => 1, 'created' => 1);
1938
		try {
1939
			$result = $this->Post->find('all', array(
1940
				'conditions' => array('count' => array('$gt' => 3)),
1941
				'hint' => $invalidIndex,
1942
			));
1943
		} catch (MongoCursorException $e) {
1944
			$this->assertTextContains('bad hint', $e->getMessage());
1945
		}
1946
 
1947
		try {
1948
			$result = $this->Post->find('count', array(
1949
				'conditions' => array('count' => array('$gt' => 3)),
1950
				'hint' => $invalidIndex,
1951
			));
1952
		} catch (MongoCursorException $e) {
1953
			$this->assertTextContains('bad hint', $e->getMessage());
1954
		}
1955
	}
1956
}