Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
12345 anikendra 1
<?php
2
/**
3
 * ModelWriteTest file
4
 *
5
 * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
6
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
7
 *
8
 * Licensed under The MIT License
9
 * For full copyright and license information, please see the LICENSE.txt
10
 * Redistributions of files must retain the above copyright notice
11
 *
12
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
13
 * @link          http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
14
 * @package       Cake.Test.Case.Model
15
 * @since         CakePHP(tm) v 1.2.0.4206
16
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
 */
18
 
19
App::uses('MockTransactionDboSource', 'Model/Datasource');
20
App::uses('MockTransactionAssociatedDboSource', 'Model/Datasource');
21
App::uses('MockManyTransactionDboSource', 'Model/Datasource');
22
App::uses('MockAssociatedTransactionDboSource', 'Model/Datasource');
23
 
24
require_once dirname(__FILE__) . DS . 'ModelTestBase.php';
25
 
26
/**
27
 * Helper class for testing with mocked datasources
28
 */
29
class TestAuthor extends Author {
30
 
31
	public $hasMany = array(
32
		'Post' => array(
33
			'className' => 'TestPost'
34
		)
35
	);
36
 
37
	protected $_dataSourceObject;
38
 
39
/**
40
 * Helper method to set a datasource object
41
 *
42
 * @param Object $object The datasource object
43
 * @return void
44
 */
45
	public function setDataSourceObject($object) {
46
		$this->_dataSourceObject = $object;
47
	}
48
 
49
/**
50
 * Overwritten in order to return the directly set datasource object if
51
 * available
52
 *
53
 * @return DataSource
54
 */
55
	public function getDataSource() {
56
		if ($this->_dataSourceObject !== null) {
57
			return $this->_dataSourceObject;
58
		}
59
		return parent::getDataSource();
60
	}
61
 
62
}
63
 
64
/**
65
 * Helper class for testing with mocked datasources
66
 */
67
class TestPost extends Post {
68
 
69
	public $belongsTo = array(
70
		'Author' => array(
71
			'className' => 'TestAuthor'
72
		)
73
	);
74
 
75
	protected $_dataSourceObject;
76
 
77
/**
78
 * Helper method to set a datasource object
79
 *
80
 * @param Object $object The datasource object
81
 * @return void
82
 */
83
	public function setDataSourceObject($object) {
84
		$this->_dataSourceObject = $object;
85
	}
86
 
87
/**
88
 * Overwritten in order to return the directly set datasource object if
89
 * available
90
 *
91
 * @return DataSource
92
 */
93
	public function getDataSource() {
94
		if ($this->_dataSourceObject !== null) {
95
			return $this->_dataSourceObject;
96
		}
97
		return parent::getDataSource();
98
	}
99
 
100
}
101
 
102
/**
103
 * ModelWriteTest
104
 *
105
 * @package       Cake.Test.Case.Model
106
 */
107
class ModelWriteTest extends BaseModelTest {
108
 
109
/**
110
 * override locale to the default (eng).
111
 *
112
 * @return void
113
 */
114
	public function setUp() {
115
		parent::setUp();
116
		Configure::write('Config.language', 'eng');
117
	}
118
 
119
/**
120
 * Test save() failing when there is no data.
121
 *
122
 * @return void
123
 */
124
	public function testInsertNoData() {
125
		$this->loadFixtures('Bid');
126
		$Bid = ClassRegistry::init('Bid');
127
 
128
		$this->assertFalse($Bid->save());
129
 
130
		$result = $Bid->save(array('Bid' => array()));
131
		$this->assertFalse($result);
132
 
133
		$result = $Bid->save(array('Bid' => array('not in schema' => 1)));
134
		$this->assertFalse($result);
135
	}
136
 
137
/**
138
 * testInsertAnotherHabtmRecordWithSameForeignKey method
139
 *
140
 * @return void
141
 */
142
	public function testInsertAnotherHabtmRecordWithSameForeignKey() {
143
		$this->loadFixtures('JoinA', 'JoinB', 'JoinAB', 'JoinC', 'JoinAC');
144
		$TestModel = new JoinA();
145
 
146
		$result = $TestModel->JoinAsJoinB->findById(1);
147
		$expected = array(
148
			'JoinAsJoinB' => array(
149
				'id' => 1,
150
				'join_a_id' => 1,
151
				'join_b_id' => 2,
152
				'other' => 'Data for Join A 1 Join B 2',
153
				'created' => '2008-01-03 10:56:33',
154
				'updated' => '2008-01-03 10:56:33'
155
		));
156
		$this->assertEquals($expected, $result);
157
 
158
		$TestModel->JoinAsJoinB->create();
159
		$data = array(
160
			'join_a_id' => 1,
161
			'join_b_id' => 1,
162
			'other' => 'Data for Join A 1 Join B 1',
163
			'created' => '2008-01-03 10:56:44',
164
			'updated' => '2008-01-03 10:56:44'
165
		);
166
		$result = $TestModel->JoinAsJoinB->save($data);
167
		$lastInsertId = $TestModel->JoinAsJoinB->getLastInsertID();
168
		$data['id'] = $lastInsertId;
169
		$this->assertEquals(array('JoinAsJoinB' => $data), $result);
170
		$this->assertTrue($lastInsertId > 0);
171
 
172
		$result = $TestModel->JoinAsJoinB->findById(1);
173
		$expected = array(
174
			'JoinAsJoinB' => array(
175
				'id' => 1,
176
				'join_a_id' => 1,
177
				'join_b_id' => 2,
178
				'other' => 'Data for Join A 1 Join B 2',
179
				'created' => '2008-01-03 10:56:33',
180
				'updated' => '2008-01-03 10:56:33'
181
		));
182
		$this->assertEquals($expected, $result);
183
 
184
		$updatedValue = 'UPDATED Data for Join A 1 Join B 2';
185
		$TestModel->JoinAsJoinB->id = 1;
186
		$result = $TestModel->JoinAsJoinB->saveField('other', $updatedValue, false);
187
		$this->assertFalse(empty($result));
188
 
189
		$result = $TestModel->JoinAsJoinB->findById(1);
190
		$this->assertEquals($updatedValue, $result['JoinAsJoinB']['other']);
191
	}
192
 
193
/**
194
 * testSaveDateAsFirstEntry method
195
 *
196
 * @return void
197
 */
198
	public function testSaveDateAsFirstEntry() {
199
		$this->loadFixtures('Article', 'User', 'Comment', 'Attachment', 'Tag', 'ArticlesTag');
200
 
201
		$Article = new Article();
202
 
203
		$data = array(
204
			'Article' => array(
205
				'created' => array(
206
					'day' => '1',
207
					'month' => '1',
208
					'year' => '2008'
209
				),
210
				'title' => 'Test Title',
211
				'user_id' => 1
212
		));
213
		$Article->create();
214
		$result = $Article->save($data);
215
		$this->assertFalse(empty($result));
216
 
217
		$testResult = $Article->find('first', array('conditions' => array('Article.title' => 'Test Title')));
218
 
219
		$this->assertEquals($data['Article']['title'], $testResult['Article']['title']);
220
		$this->assertEquals('2008-01-01 00:00:00', $testResult['Article']['created']);
221
	}
222
 
223
/**
224
 * testUnderscoreFieldSave method
225
 *
226
 * @return void
227
 */
228
	public function testUnderscoreFieldSave() {
229
		$this->loadFixtures('UnderscoreField');
230
		$UnderscoreField = new UnderscoreField();
231
 
232
		$currentCount = $UnderscoreField->find('count');
233
		$this->assertEquals(3, $currentCount);
234
		$data = array('UnderscoreField' => array(
235
			'user_id' => '1',
236
			'my_model_has_a_field' => 'Content here',
237
			'body' => 'Body',
238
			'published' => 'Y',
239
			'another_field' => 4
240
		));
241
		$ret = $UnderscoreField->save($data);
242
		$this->assertFalse(empty($ret));
243
 
244
		$currentCount = $UnderscoreField->find('count');
245
		$this->assertEquals(4, $currentCount);
246
	}
247
 
248
/**
249
 * testAutoSaveUuid method
250
 *
251
 * @return void
252
 */
253
	public function testAutoSaveUuid() {
254
		// SQLite does not support non-integer primary keys
255
		$this->skipIf($this->db instanceof Sqlite, 'This test is not compatible with SQLite.');
256
 
257
		$this->loadFixtures('Uuid');
258
		$TestModel = new Uuid();
259
 
260
		$TestModel->save(array('title' => 'Test record'));
261
		$result = $TestModel->findByTitle('Test record');
262
		$this->assertEquals(
263
			array('id', 'title', 'count', 'created', 'updated'),
264
			array_keys($result['Uuid'])
265
		);
266
		$this->assertEquals(36, strlen($result['Uuid']['id']));
267
	}
268
 
269
/**
270
 * Ensure that if the id key is null but present the save doesn't fail (with an
271
 * x sql error: "Column id specified twice")
272
 *
273
 * @return void
274
 */
275
	public function testSaveUuidNull() {
276
		// SQLite does not support non-integer primary keys
277
		$this->skipIf($this->db instanceof Sqlite, 'This test is not compatible with SQLite.');
278
 
279
		$this->loadFixtures('Uuid');
280
		$TestModel = new Uuid();
281
 
282
		$TestModel->save(array('title' => 'Test record', 'id' => null));
283
		$result = $TestModel->findByTitle('Test record');
284
		$this->assertEquals(
285
			array('id', 'title', 'count', 'created', 'updated'),
286
			array_keys($result['Uuid'])
287
		);
288
		$this->assertEquals(36, strlen($result['Uuid']['id']));
289
	}
290
 
291
/**
292
 * testZeroDefaultFieldValue method
293
 *
294
 * @return void
295
 */
296
	public function testZeroDefaultFieldValue() {
297
		$this->skipIf($this->db instanceof Sqlite, 'SQLite uses loose typing, this operation is unsupported.');
298
 
299
		$this->loadFixtures('DataTest');
300
		$TestModel = new DataTest();
301
 
302
		$TestModel->create(array());
303
		$TestModel->save();
304
		$result = $TestModel->findById($TestModel->id);
305
		$this->assertEquals(0, $result['DataTest']['count']);
306
		$this->assertEquals(0, $result['DataTest']['float']);
307
	}
308
 
309
/**
310
 * Tests validation parameter order in custom validation methods
311
 *
312
 * @return void
313
 */
314
	public function testAllowSimulatedFields() {
315
		$TestModel = new ValidationTest1();
316
 
317
		$TestModel->create(array(
318
			'title' => 'foo',
319
			'bar' => 'baz'
320
		));
321
		$expected = array(
322
			'ValidationTest1' => array(
323
				'title' => 'foo',
324
				'bar' => 'baz'
325
		));
326
		$this->assertEquals($expected, $TestModel->data);
327
	}
328
 
329
/**
330
 * test that Caches are getting cleared on save().
331
 * ensure that both inflections of controller names are getting cleared
332
 * as URL for controller could be either overallFavorites/index or overall_favorites/index
333
 *
334
 * @return void
335
 */
336
	public function testCacheClearOnSave() {
337
		$_back = array(
338
			'check' => Configure::read('Cache.check'),
339
			'disable' => Configure::read('Cache.disable'),
340
		);
341
		Configure::write('Cache.check', true);
342
		Configure::write('Cache.disable', false);
343
 
344
		$this->loadFixtures('OverallFavorite');
345
		$OverallFavorite = new OverallFavorite();
346
 
347
		touch(CACHE . 'views' . DS . 'some_dir_overallfavorites_index.php');
348
		touch(CACHE . 'views' . DS . 'some_dir_overall_favorites_index.php');
349
 
350
		$data = array(
351
			'OverallFavorite' => array(
352
				'id' => 22,
353
				'model_type' => '8-track',
354
				'model_id' => '3',
355
				'priority' => '1'
356
			)
357
		);
358
		$OverallFavorite->create($data);
359
		$OverallFavorite->save();
360
 
361
		$this->assertFalse(file_exists(CACHE . 'views' . DS . 'some_dir_overallfavorites_index.php'));
362
		$this->assertFalse(file_exists(CACHE . 'views' . DS . 'some_dir_overall_favorites_index.php'));
363
 
364
		Configure::write('Cache.check', $_back['check']);
365
		Configure::write('Cache.disable', $_back['disable']);
366
	}
367
 
368
/**
369
 * test that save() resets whitelist on failed save
370
 *
371
 * @return void
372
 */
373
	public function testSaveFieldListResetsWhitelistOnFailedSave() {
374
		$this->loadFixtures('Bidding');
375
		$model = new Bidding();
376
		$whitelist = array('title');
377
		$model->whitelist = $whitelist;
378
		$result = $model->save(
379
			array(),
380
			array('fieldList' => array('body'))
381
		);
382
		$this->assertFalse($result);
383
		$this->assertEquals($whitelist, $model->whitelist);
384
	}
385
 
386
/**
387
 * testSaveWithCounterCache method
388
 *
389
 * @return void
390
 */
391
	public function testSaveWithCounterCache() {
392
		$this->loadFixtures('Syfile', 'Item', 'Image', 'Portfolio', 'ItemsPortfolio');
393
		$TestModel = new Syfile();
394
		$TestModel2 = new Item();
395
 
396
		$result = $TestModel->findById(1);
397
		$this->assertNull($result['Syfile']['item_count']);
398
 
399
		$TestModel2->save(array(
400
			'name' => 'Item 7',
401
			'syfile_id' => 1,
402
			'published' => false
403
		));
404
 
405
		$result = $TestModel->findById(1);
406
		$this->assertEquals(2, $result['Syfile']['item_count']);
407
 
408
		$TestModel2->delete(1);
409
		$result = $TestModel->findById(1);
410
		$this->assertEquals(1, $result['Syfile']['item_count']);
411
 
412
		$TestModel2->id = 2;
413
		$TestModel2->saveField('syfile_id', 1);
414
 
415
		$result = $TestModel->findById(1);
416
		$this->assertEquals(2, $result['Syfile']['item_count']);
417
 
418
		$result = $TestModel->findById(2);
419
		$this->assertEquals(0, $result['Syfile']['item_count']);
420
	}
421
 
422
/**
423
 * Tests that counter caches are updated when records are added
424
 *
425
 * @return void
426
 */
427
	public function testCounterCacheIncrease() {
428
		$this->loadFixtures('CounterCacheUser', 'CounterCachePost');
429
		$User = new CounterCacheUser();
430
		$Post = new CounterCachePost();
431
		$data = array('Post' => array(
432
			'id' => 22,
433
			'title' => 'New Post',
434
			'user_id' => 66
435
		));
436
 
437
		$Post->save($data);
438
		$user = $User->find('first', array(
439
			'conditions' => array('id' => 66),
440
			'recursive' => -1
441
		));
442
 
443
		$result = $user[$User->alias]['post_count'];
444
		$expected = 3;
445
		$this->assertEquals($expected, $result);
446
	}
447
 
448
/**
449
 * Tests that counter caches are updated when records are deleted
450
 *
451
 * @return void
452
 */
453
	public function testCounterCacheDecrease() {
454
		$this->loadFixtures('CounterCacheUser', 'CounterCachePost');
455
		$User = new CounterCacheUser();
456
		$Post = new CounterCachePost();
457
 
458
		$Post->delete(2);
459
		$user = $User->find('first', array(
460
			'conditions' => array('id' => 66),
461
			'recursive' => -1
462
		));
463
 
464
		$result = $user[$User->alias]['post_count'];
465
		$expected = 1;
466
		$this->assertEquals($expected, $result);
467
	}
468
 
469
/**
470
 * Tests that counter caches are updated when foreign keys of counted records change
471
 *
472
 * @return void
473
 */
474
	public function testCounterCacheUpdated() {
475
		$this->loadFixtures('CounterCacheUser', 'CounterCachePost');
476
		$User = new CounterCacheUser();
477
		$Post = new CounterCachePost();
478
 
479
		$data = $Post->find('first', array(
480
			'conditions' => array('id' => 1),
481
			'recursive' => -1
482
		));
483
		$data[$Post->alias]['user_id'] = 301;
484
		$Post->save($data);
485
 
486
		$users = $User->find('all', array('order' => 'User.id'));
487
		$this->assertEquals(1, $users[0]['User']['post_count']);
488
		$this->assertEquals(2, $users[1]['User']['post_count']);
489
	}
490
 
491
/**
492
 * Test counter cache with models that use a non-standard (i.e. not using 'id')
493
 * as their primary key.
494
 *
495
 * @return void
496
 */
497
	public function testCounterCacheWithNonstandardPrimaryKey() {
498
		$this->loadFixtures(
499
			'CounterCacheUserNonstandardPrimaryKey',
500
			'CounterCachePostNonstandardPrimaryKey'
501
		);
502
 
503
		$User = new CounterCacheUserNonstandardPrimaryKey();
504
		$Post = new CounterCachePostNonstandardPrimaryKey();
505
 
506
		$data = $Post->find('first', array(
507
			'conditions' => array('pid' => 1),
508
			'recursive' => -1
509
		));
510
		$data[$Post->alias]['uid'] = 301;
511
		$Post->save($data);
512
 
513
		$users = $User->find('all', array('order' => 'User.uid'));
514
		$this->assertEquals(1, $users[0]['User']['post_count']);
515
		$this->assertEquals(2, $users[1]['User']['post_count']);
516
	}
517
 
518
/**
519
 * test Counter Cache With Self Joining table
520
 *
521
 * @return void
522
 */
523
	public function testCounterCacheWithSelfJoin() {
524
		$this->skipIf($this->db instanceof Sqlite, 'SQLite 2.x does not support ALTER TABLE ADD COLUMN');
525
 
526
		$this->loadFixtures('CategoryThread');
527
		$column = 'COLUMN ';
528
		if ($this->db instanceof Sqlserver) {
529
			$column = '';
530
		}
531
		$column .= $this->db->buildColumn(array('name' => 'child_count', 'type' => 'integer'));
532
		$this->db->query('ALTER TABLE ' . $this->db->fullTableName('category_threads') . ' ADD ' . $column);
533
		$this->db->flushMethodCache();
534
		$Category = new CategoryThread();
535
		$result = $Category->updateAll(array('CategoryThread.name' => "'updated'"), array('CategoryThread.parent_id' => 5));
536
		$this->assertFalse(empty($result));
537
 
538
		$Category = new CategoryThread();
539
		$Category->belongsTo['ParentCategory']['counterCache'] = 'child_count';
540
		$Category->updateCounterCache(array('parent_id' => 5));
541
		$result = Hash::extract($Category->find('all', array('conditions' => array('CategoryThread.id' => 5))), '{n}.CategoryThread.child_count');
542
		$expected = array(1);
543
		$this->assertEquals($expected, $result);
544
	}
545
 
546
/**
547
 * testSaveWithCounterCacheScope method
548
 *
549
 * @return void
550
 */
551
	public function testSaveWithCounterCacheScope() {
552
		$this->loadFixtures('Syfile', 'Item', 'Image', 'ItemsPortfolio', 'Portfolio');
553
		$TestModel = new Syfile();
554
		$TestModel2 = new Item();
555
		$TestModel2->belongsTo['Syfile']['counterCache'] = true;
556
		$TestModel2->belongsTo['Syfile']['counterScope'] = array('published' => true);
557
 
558
		$result = $TestModel->findById(1);
559
		$this->assertNull($result['Syfile']['item_count']);
560
 
561
		$TestModel2->save(array(
562
			'name' => 'Item 7',
563
			'syfile_id' => 1,
564
			'published' => true
565
		));
566
 
567
		$result = $TestModel->findById(1);
568
 
569
		$this->assertEquals(1, $result['Syfile']['item_count']);
570
 
571
		$TestModel2->id = 1;
572
		$TestModel2->saveField('published', true);
573
		$result = $TestModel->findById(1);
574
		$this->assertEquals(2, $result['Syfile']['item_count']);
575
 
576
		$TestModel2->save(array(
577
			'id' => 1,
578
			'syfile_id' => 1,
579
			'published' => false
580
		));
581
 
582
		$result = $TestModel->findById(1);
583
		$this->assertEquals(1, $result['Syfile']['item_count']);
584
	}
585
 
586
/**
587
 * Tests having multiple counter caches for an associated model
588
 *
589
 * @return void
590
 */
591
	public function testCounterCacheMultipleCaches() {
592
		$this->loadFixtures('CounterCacheUser', 'CounterCachePost');
593
		$User = new CounterCacheUser();
594
		$Post = new CounterCachePost();
595
		$Post->unbindModel(array('belongsTo' => array('User')), false);
596
		$Post->bindModel(array(
597
			'belongsTo' => array(
598
				'User' => array(
599
					'className' => 'CounterCacheUser',
600
					'foreignKey' => 'user_id',
601
					'counterCache' => array(
602
						true,
603
						'posts_published' => array('Post.published' => true)
604
					)
605
				)
606
			)
607
		), false);
608
 
609
		// Count Increase
610
		$data = array('Post' => array(
611
			'id' => 22,
612
			'title' => 'New Post',
613
			'user_id' => 66,
614
			'published' => true
615
		));
616
		$Post->save($data);
617
		$result = $User->find('first', array(
618
			'conditions' => array('id' => 66),
619
			'recursive' => -1
620
		));
621
		$this->assertEquals(3, $result[$User->alias]['post_count']);
622
		$this->assertEquals(2, $result[$User->alias]['posts_published']);
623
 
624
		// Count decrease
625
		$Post->delete(1);
626
		$result = $User->find('first', array(
627
			'conditions' => array('id' => 66),
628
			'recursive' => -1
629
		));
630
		$this->assertEquals(2, $result[$User->alias]['post_count']);
631
		$this->assertEquals(2, $result[$User->alias]['posts_published']);
632
 
633
		// Count update
634
		$data = $Post->find('first', array(
635
			'conditions' => array('id' => 1),
636
			'recursive' => -1
637
		));
638
		$data[$Post->alias]['user_id'] = 301;
639
		$Post->save($data);
640
		$result = $User->find('all', array('order' => 'User.id'));
641
		$this->assertEquals(2, $result[0]['User']['post_count']);
642
		$this->assertEquals(1, $result[1]['User']['posts_published']);
643
	}
644
 
645
/**
646
 * Tests that counter caches are unchanged when using 'counterCache' => false
647
 *
648
 * @return void
649
 */
650
	public function testCounterCacheSkip() {
651
		$this->loadFixtures('CounterCacheUser', 'CounterCachePost');
652
		$User = new CounterCacheUser();
653
		$Post = new CounterCachePost();
654
 
655
		$data = $Post->find('first', array(
656
			'conditions' => array('id' => 1),
657
			'recursive' => -1
658
		));
659
		$data[$Post->alias]['user_id'] = 301;
660
		$Post->save($data, array('counterCache' => false));
661
 
662
		$users = $User->find('all', array('order' => 'User.id'));
663
		$this->assertEquals(2, $users[0]['User']['post_count']);
664
		$this->assertEquals(1, $users[1]['User']['post_count']);
665
	}
666
 
667
/**
668
 * test that beforeValidate returning false can abort saves.
669
 *
670
 * @return void
671
 */
672
	public function testBeforeValidateSaveAbortion() {
673
		$this->loadFixtures('Post');
674
		$Model = new CallbackPostTestModel();
675
		$Model->beforeValidateReturn = false;
676
 
677
		$data = array(
678
			'title' => 'new article',
679
			'body' => 'this is some text.'
680
		);
681
		$Model->create();
682
		$result = $Model->save($data);
683
		$this->assertFalse($result);
684
	}
685
 
686
/**
687
 * test that beforeSave returning false can abort saves.
688
 *
689
 * @return void
690
 */
691
	public function testBeforeSaveSaveAbortion() {
692
		$this->loadFixtures('Post');
693
		$Model = new CallbackPostTestModel();
694
		$Model->beforeSaveReturn = false;
695
 
696
		$data = array(
697
			'title' => 'new article',
698
			'body' => 'this is some text.'
699
		);
700
		$Model->create();
701
		$result = $Model->save($data);
702
		$this->assertFalse($result);
703
	}
704
 
705
/**
706
 * testSaveField method
707
 *
708
 * @return void
709
 */
710
	public function testSaveField() {
711
		$this->loadFixtures('Article');
712
		$TestModel = new Article();
713
 
714
		$TestModel->id = 1;
715
		$result = $TestModel->saveField('title', 'New First Article');
716
		$this->assertFalse(empty($result));
717
 
718
		$TestModel->recursive = -1;
719
		$result = $TestModel->read(array('id', 'user_id', 'title', 'body'), 1);
720
		$expected = array('Article' => array(
721
			'id' => '1',
722
			'user_id' => '1',
723
			'title' => 'New First Article',
724
			'body' => 'First Article Body'
725
		));
726
		$this->assertEquals($expected, $result);
727
 
728
		$TestModel->id = 1;
729
		$result = $TestModel->saveField('title', '');
730
		$this->assertFalse(empty($result));
731
 
732
		$TestModel->recursive = -1;
733
		$result = $TestModel->read(array('id', 'user_id', 'title', 'body'), 1);
734
		$expected = array('Article' => array(
735
			'id' => '1',
736
			'user_id' => '1',
737
			'title' => '',
738
			'body' => 'First Article Body'
739
		));
740
		$result['Article']['title'] = trim($result['Article']['title']);
741
		$this->assertEquals($expected, $result);
742
 
743
		$TestModel->id = 1;
744
		$TestModel->set('body', 'Messed up data');
745
		$result = $TestModel->saveField('title', 'First Article');
746
		$this->assertFalse(empty($result));
747
		$result = $TestModel->read(array('id', 'user_id', 'title', 'body'), 1);
748
		$expected = array('Article' => array(
749
			'id' => '1',
750
			'user_id' => '1',
751
			'title' => 'First Article',
752
			'body' => 'First Article Body'
753
		));
754
		$this->assertEquals($expected, $result);
755
 
756
		$TestModel->recursive = -1;
757
		$TestModel->read(array('id', 'user_id', 'title', 'body'), 1);
758
 
759
		$TestModel->id = 1;
760
		$result = $TestModel->saveField('title', '', true);
761
		$this->assertFalse($result);
762
 
763
		$TestModel->recursive = -1;
764
		$TestModel->id = 1;
765
		$result = $TestModel->saveField('user_id', 9999);
766
		$this->assertTrue((bool)$result);
767
 
768
		$result = $TestModel->read(array('id', 'user_id'), 1);
769
		$expected = array('Article' => array(
770
			'id' => '1',
771
			'user_id' => '9999',
772
		));
773
		$this->assertEquals($expected, $result);
774
 
775
		$this->loadFixtures('Node', 'Dependency');
776
		$Node = new Node();
777
		$Node->set('id', 1);
778
		$result = $Node->read();
779
		$this->assertEquals(array('Second'), Hash::extract($result, 'ParentNode.{n}.name'));
780
 
781
		$Node->saveField('state', 10);
782
		$result = $Node->read();
783
		$this->assertEquals(array('Second'), Hash::extract($result, 'ParentNode.{n}.name'));
784
	}
785
 
786
/**
787
 * testSaveWithCreate method
788
 *
789
 * @return void
790
 */
791
	public function testSaveWithCreate() {
792
		$this->loadFixtures(
793
			'User',
794
			'Article',
795
			'User',
796
			'Comment',
797
			'Tag',
798
			'ArticlesTag',
799
			'Attachment'
800
		);
801
		$TestModel = new User();
802
 
803
		$data = array('User' => array(
804
			'user' => 'user',
805
			'password' => ''
806
		));
807
		$result = $TestModel->save($data);
808
		$this->assertFalse($result);
809
		$this->assertTrue(!empty($TestModel->validationErrors));
810
 
811
		$TestModel = new Article();
812
 
813
		$data = array('Article' => array(
814
			'user_id' => '',
815
			'title' => '',
816
			'body' => ''
817
		));
818
		$result = $TestModel->create($data) && $TestModel->save();
819
		$this->assertFalse($result);
820
		$this->assertTrue(!empty($TestModel->validationErrors));
821
 
822
		$data = array('Article' => array(
823
			'id' => 1,
824
			'user_id' => '1',
825
			'title' => 'New First Article',
826
			'body' => ''
827
		));
828
		$result = $TestModel->create($data) && $TestModel->save();
829
		$this->assertFalse($result);
830
 
831
		$data = array('Article' => array(
832
			'id' => 1,
833
			'title' => 'New First Article'
834
		));
835
		$result = $TestModel->create() && $TestModel->save($data, false);
836
		$this->assertFalse(empty($result));
837
 
838
		$TestModel->recursive = -1;
839
		$result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 1);
840
		$expected = array('Article' => array(
841
			'id' => '1',
842
			'user_id' => '1',
843
			'title' => 'New First Article',
844
			'body' => 'First Article Body',
845
			'published' => 'N'
846
		));
847
		$this->assertEquals($expected, $result);
848
 
849
		$data = array('Article' => array(
850
			'id' => 1,
851
			'user_id' => '2',
852
			'title' => 'First Article',
853
			'body' => 'New First Article Body',
854
			'published' => 'Y'
855
		));
856
		$result = $TestModel->create() && $TestModel->save($data, true, array('id', 'title', 'published'));
857
		$this->assertFalse(empty($result));
858
 
859
		$TestModel->recursive = -1;
860
		$result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 1);
861
		$expected = array('Article' => array(
862
			'id' => '1',
863
			'user_id' => '1',
864
			'title' => 'First Article',
865
			'body' => 'First Article Body',
866
			'published' => 'Y'
867
		));
868
		$this->assertEquals($expected, $result);
869
 
870
		$data = array(
871
			'Article' => array(
872
				'user_id' => '2',
873
				'title' => 'New Article',
874
				'body' => 'New Article Body',
875
				'created' => '2007-03-18 14:55:23',
876
				'updated' => '2007-03-18 14:57:31'
877
			),
878
			'Tag' => array('Tag' => array(1, 3))
879
		);
880
		$TestModel->create();
881
		$result = $TestModel->create() && $TestModel->save($data);
882
		$this->assertFalse(empty($result));
883
 
884
		$TestModel->recursive = 2;
885
		$result = $TestModel->read(null, 4);
886
		$expected = array(
887
			'Article' => array(
888
				'id' => '4',
889
				'user_id' => '2',
890
				'title' => 'New Article',
891
				'body' => 'New Article Body',
892
				'published' => 'N',
893
				'created' => '2007-03-18 14:55:23',
894
				'updated' => '2007-03-18 14:57:31'
895
			),
896
			'User' => array(
897
				'id' => '2',
898
				'user' => 'nate',
899
				'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
900
				'created' => '2007-03-17 01:18:23',
901
				'updated' => '2007-03-17 01:20:31'
902
			),
903
			'Comment' => array(),
904
			'Tag' => array(
905
				array(
906
					'id' => '1',
907
					'tag' => 'tag1',
908
					'created' => '2007-03-18 12:22:23',
909
					'updated' => '2007-03-18 12:24:31'
910
				),
911
				array(
912
					'id' => '3',
913
					'tag' => 'tag3',
914
					'created' => '2007-03-18 12:26:23',
915
					'updated' => '2007-03-18 12:28:31'
916
		)));
917
		$this->assertEquals($expected, $result);
918
 
919
		$data = array('Comment' => array(
920
			'article_id' => '4',
921
			'user_id' => '1',
922
			'comment' => 'Comment New Article',
923
			'published' => 'Y',
924
			'created' => '2007-03-18 14:57:23',
925
			'updated' => '2007-03-18 14:59:31'
926
		));
927
		$result = $TestModel->Comment->create() && $TestModel->Comment->save($data);
928
		$this->assertFalse(empty($result));
929
 
930
		$data = array('Attachment' => array(
931
			'comment_id' => '7',
932
			'attachment' => 'newattachment.zip',
933
			'created' => '2007-03-18 15:02:23',
934
			'updated' => '2007-03-18 15:04:31'
935
		));
936
		$result = $TestModel->Comment->Attachment->save($data);
937
		$this->assertFalse(empty($result));
938
 
939
		$TestModel->recursive = 2;
940
		$result = $TestModel->read(null, 4);
941
		$expected = array(
942
			'Article' => array(
943
				'id' => '4',
944
				'user_id' => '2',
945
				'title' => 'New Article',
946
				'body' => 'New Article Body',
947
				'published' => 'N',
948
				'created' => '2007-03-18 14:55:23',
949
				'updated' => '2007-03-18 14:57:31'
950
			),
951
			'User' => array(
952
				'id' => '2',
953
				'user' => 'nate',
954
				'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
955
				'created' => '2007-03-17 01:18:23',
956
				'updated' => '2007-03-17 01:20:31'
957
			),
958
			'Comment' => array(
959
				array(
960
					'id' => '7',
961
					'article_id' => '4',
962
					'user_id' => '1',
963
					'comment' => 'Comment New Article',
964
					'published' => 'Y',
965
					'created' => '2007-03-18 14:57:23',
966
					'updated' => '2007-03-18 14:59:31',
967
					'Article' => array(
968
						'id' => '4',
969
						'user_id' => '2',
970
						'title' => 'New Article',
971
						'body' => 'New Article Body',
972
						'published' => 'N',
973
						'created' => '2007-03-18 14:55:23',
974
						'updated' => '2007-03-18 14:57:31'
975
					),
976
					'User' => array(
977
						'id' => '1',
978
						'user' => 'mariano',
979
						'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
980
						'created' => '2007-03-17 01:16:23',
981
						'updated' => '2007-03-17 01:18:31'
982
					),
983
					'Attachment' => array(
984
						'id' => '2',
985
						'comment_id' => '7',
986
						'attachment' => 'newattachment.zip',
987
						'created' => '2007-03-18 15:02:23',
988
						'updated' => '2007-03-18 15:04:31'
989
			))),
990
			'Tag' => array(
991
				array(
992
					'id' => '1',
993
					'tag' => 'tag1',
994
					'created' => '2007-03-18 12:22:23',
995
					'updated' => '2007-03-18 12:24:31'
996
				),
997
				array(
998
					'id' => '3',
999
					'tag' => 'tag3',
1000
					'created' => '2007-03-18 12:26:23',
1001
					'updated' => '2007-03-18 12:28:31'
1002
		)));
1003
 
1004
		$this->assertEquals($expected, $result);
1005
	}
1006
 
1007
/**
1008
 * test that a null Id doesn't cause errors
1009
 *
1010
 * @return void
1011
 */
1012
	public function testSaveWithNullId() {
1013
		$this->loadFixtures('User');
1014
		$User = new User();
1015
		$User->read(null, 1);
1016
		$User->data['User']['id'] = null;
1017
		$result = $User->save(array('password' => 'test'));
1018
		$this->assertFalse(empty($result));
1019
		$this->assertTrue($User->id > 0);
1020
 
1021
		$User->read(null, 2);
1022
		$User->data['User']['id'] = null;
1023
		$result = $User->save(array('password' => 'test'));
1024
		$this->assertFalse(empty($result));
1025
		$this->assertTrue($User->id > 0);
1026
 
1027
		$User->data['User'] = array('password' => 'something');
1028
		$result = $User->save();
1029
		$this->assertFalse(empty($result));
1030
		$result = $User->read();
1031
		$this->assertEquals('something', $User->data['User']['password']);
1032
	}
1033
 
1034
/**
1035
 * testSaveWithSet method
1036
 *
1037
 * @return void
1038
 */
1039
	public function testSaveWithSet() {
1040
		$this->loadFixtures('Article');
1041
		$TestModel = new Article();
1042
 
1043
		// Create record we will be updating later
1044
 
1045
		$data = array('Article' => array(
1046
			'user_id' => '1',
1047
			'title' => 'Fourth Article',
1048
			'body' => 'Fourth Article Body',
1049
			'published' => 'Y'
1050
		));
1051
		$result = $TestModel->create() && $TestModel->save($data);
1052
		$this->assertFalse(empty($result));
1053
 
1054
		// Check record we created
1055
 
1056
		$TestModel->recursive = -1;
1057
		$result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 4);
1058
		$expected = array('Article' => array(
1059
			'id' => '4',
1060
			'user_id' => '1',
1061
			'title' => 'Fourth Article',
1062
			'body' => 'Fourth Article Body',
1063
			'published' => 'Y'
1064
		));
1065
		$this->assertEquals($expected, $result);
1066
 
1067
		// Create new record just to overlap Model->id on previously created record
1068
 
1069
		$data = array('Article' => array(
1070
			'user_id' => '4',
1071
			'title' => 'Fifth Article',
1072
			'body' => 'Fifth Article Body',
1073
			'published' => 'Y'
1074
		));
1075
		$result = $TestModel->create() && $TestModel->save($data);
1076
		$this->assertFalse(empty($result));
1077
 
1078
		$TestModel->recursive = -1;
1079
		$result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 5);
1080
		$expected = array('Article' => array(
1081
			'id' => '5',
1082
			'user_id' => '4',
1083
			'title' => 'Fifth Article',
1084
			'body' => 'Fifth Article Body',
1085
			'published' => 'Y'
1086
		));
1087
		$this->assertEquals($expected, $result);
1088
 
1089
		// Go back and edit the first article we created, starting by checking it's still there
1090
 
1091
		$TestModel->recursive = -1;
1092
		$result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 4);
1093
		$expected = array('Article' => array(
1094
			'id' => '4',
1095
			'user_id' => '1',
1096
			'title' => 'Fourth Article',
1097
			'body' => 'Fourth Article Body',
1098
			'published' => 'Y'
1099
		));
1100
		$this->assertEquals($expected, $result);
1101
 
1102
		// And now do the update with set()
1103
 
1104
		$data = array('Article' => array(
1105
			'id' => '4',
1106
			'title' => 'Fourth Article - New Title',
1107
			'published' => 'N'
1108
		));
1109
		$result = $TestModel->set($data) && $TestModel->save();
1110
		$this->assertFalse(empty($result));
1111
 
1112
		$TestModel->recursive = -1;
1113
		$result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 4);
1114
		$expected = array('Article' => array(
1115
			'id' => '4',
1116
			'user_id' => '1',
1117
			'title' => 'Fourth Article - New Title',
1118
			'body' => 'Fourth Article Body',
1119
			'published' => 'N'
1120
		));
1121
		$this->assertEquals($expected, $result);
1122
 
1123
		$TestModel->recursive = -1;
1124
		$result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 5);
1125
		$expected = array('Article' => array(
1126
			'id' => '5',
1127
			'user_id' => '4',
1128
			'title' => 'Fifth Article',
1129
			'body' => 'Fifth Article Body',
1130
			'published' => 'Y'
1131
		));
1132
		$this->assertEquals($expected, $result);
1133
 
1134
		$data = array('Article' => array('id' => '5', 'title' => 'Fifth Article - New Title 5'));
1135
		$result = ($TestModel->set($data) && $TestModel->save());
1136
		$this->assertFalse(empty($result));
1137
 
1138
		$TestModel->recursive = -1;
1139
		$result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 5);
1140
		$expected = array('Article' => array(
1141
			'id' => '5',
1142
			'user_id' => '4',
1143
			'title' => 'Fifth Article - New Title 5',
1144
			'body' => 'Fifth Article Body',
1145
			'published' => 'Y'
1146
		));
1147
		$this->assertEquals($expected, $result);
1148
 
1149
		$TestModel->recursive = -1;
1150
		$result = $TestModel->find('all', array(
1151
			'fields' => array('id', 'title'),
1152
			'order' => array('Article.id' => 'ASC')
1153
		));
1154
		$expected = array(
1155
			array('Article' => array('id' => 1, 'title' => 'First Article')),
1156
			array('Article' => array('id' => 2, 'title' => 'Second Article')),
1157
			array('Article' => array('id' => 3, 'title' => 'Third Article')),
1158
			array('Article' => array('id' => 4, 'title' => 'Fourth Article - New Title')),
1159
			array('Article' => array('id' => 5, 'title' => 'Fifth Article - New Title 5'))
1160
		);
1161
		$this->assertEquals($expected, $result);
1162
	}
1163
 
1164
/**
1165
 * testSaveWithNonExistentFields method
1166
 *
1167
 * @return void
1168
 */
1169
	public function testSaveWithNonExistentFields() {
1170
		$this->loadFixtures('Article');
1171
		$TestModel = new Article();
1172
		$TestModel->recursive = -1;
1173
 
1174
		$data = array(
1175
			'non_existent' => 'This field does not exist',
1176
			'user_id' => '1',
1177
			'title' => 'Fourth Article - New Title',
1178
			'body' => 'Fourth Article Body',
1179
			'published' => 'N'
1180
		);
1181
		$result = $TestModel->create() && $TestModel->save($data);
1182
		$this->assertFalse(empty($result));
1183
 
1184
		$expected = array('Article' => array(
1185
			'id' => '4',
1186
			'user_id' => '1',
1187
			'title' => 'Fourth Article - New Title',
1188
			'body' => 'Fourth Article Body',
1189
			'published' => 'N'
1190
		));
1191
		$result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 4);
1192
		$this->assertEquals($expected, $result);
1193
 
1194
		$data = array(
1195
			'user_id' => '1',
1196
			'non_existent' => 'This field does not exist',
1197
			'title' => 'Fifth Article - New Title',
1198
			'body' => 'Fifth Article Body',
1199
			'published' => 'N'
1200
		);
1201
		$result = $TestModel->create() && $TestModel->save($data);
1202
		$this->assertFalse(empty($result));
1203
 
1204
		$expected = array('Article' => array(
1205
			'id' => '5',
1206
			'user_id' => '1',
1207
			'title' => 'Fifth Article - New Title',
1208
			'body' => 'Fifth Article Body',
1209
			'published' => 'N'
1210
		));
1211
		$result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 5);
1212
		$this->assertEquals($expected, $result);
1213
	}
1214
 
1215
/**
1216
 * testSaveFromXml method
1217
 *
1218
 * @return void
1219
 */
1220
	public function testSaveFromXml() {
1221
		$this->markTestSkipped('This feature needs to be fixed or dropped');
1222
		$this->loadFixtures('Article');
1223
		App::uses('Xml', 'Utility');
1224
 
1225
		$Article = new Article();
1226
		$result = $Article->save(Xml::build('<article title="test xml" user_id="5" />'));
1227
		$this->assertFalse(empty($result));
1228
		$results = $Article->find('first', array('conditions' => array('Article.title' => 'test xml')));
1229
		$this->assertFalse(empty($results));
1230
 
1231
		$result = $Article->save(Xml::build('<article><title>testing</title><user_id>6</user_id></article>'));
1232
		$this->assertFalse(empty($result));
1233
		$results = $Article->find('first', array('conditions' => array('Article.title' => 'testing')));
1234
		$this->assertFalse(empty($results));
1235
 
1236
		$result = $Article->save(Xml::build('<article><title>testing with DOMDocument</title><user_id>7</user_id></article>', array('return' => 'domdocument')));
1237
		$this->assertFalse(empty($result));
1238
		$results = $Article->find('first', array('conditions' => array('Article.title' => 'testing with DOMDocument')));
1239
		$this->assertFalse(empty($results));
1240
	}
1241
 
1242
/**
1243
 * testSaveHabtm method
1244
 *
1245
 * @return void
1246
 */
1247
	public function testSaveHabtm() {
1248
		$this->loadFixtures('Article', 'User', 'Comment', 'Tag', 'ArticlesTag');
1249
		$TestModel = new Article();
1250
 
1251
		$result = $TestModel->findById(2);
1252
		$expected = array(
1253
			'Article' => array(
1254
				'id' => '2',
1255
				'user_id' => '3',
1256
				'title' => 'Second Article',
1257
				'body' => 'Second Article Body',
1258
				'published' => 'Y',
1259
				'created' => '2007-03-18 10:41:23',
1260
				'updated' => '2007-03-18 10:43:31'
1261
			),
1262
			'User' => array(
1263
				'id' => '3',
1264
				'user' => 'larry',
1265
				'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
1266
				'created' => '2007-03-17 01:20:23',
1267
				'updated' => '2007-03-17 01:22:31'
1268
			),
1269
			'Comment' => array(
1270
				array(
1271
					'id' => '5',
1272
					'article_id' => '2',
1273
					'user_id' => '1',
1274
					'comment' => 'First Comment for Second Article',
1275
					'published' => 'Y',
1276
					'created' => '2007-03-18 10:53:23',
1277
					'updated' => '2007-03-18 10:55:31'
1278
				),
1279
				array(
1280
					'id' => '6',
1281
					'article_id' => '2',
1282
					'user_id' => '2',
1283
					'comment' => 'Second Comment for Second Article',
1284
					'published' => 'Y',
1285
					'created' => '2007-03-18 10:55:23',
1286
					'updated' => '2007-03-18 10:57:31'
1287
			)),
1288
			'Tag' => array(
1289
				array(
1290
					'id' => '1',
1291
					'tag' => 'tag1',
1292
					'created' => '2007-03-18 12:22:23',
1293
					'updated' => '2007-03-18 12:24:31'
1294
				),
1295
				array(
1296
					'id' => '3',
1297
					'tag' => 'tag3',
1298
					'created' => '2007-03-18 12:26:23',
1299
					'updated' => '2007-03-18 12:28:31'
1300
				)
1301
			)
1302
		);
1303
		$this->assertEquals($expected, $result);
1304
 
1305
		$data = array(
1306
			'Article' => array(
1307
				'id' => '2',
1308
				'title' => 'New Second Article'
1309
			),
1310
			'Tag' => array('Tag' => array(1, 2))
1311
		);
1312
 
1313
		$result = $TestModel->set($data);
1314
		$this->assertFalse(empty($result));
1315
		$result = $TestModel->save();
1316
		$this->assertFalse(empty($result));
1317
		$this->assertEquals($data['Tag'], $result['Tag']);
1318
 
1319
		$TestModel->unbindModel(array('belongsTo' => array('User'), 'hasMany' => array('Comment')));
1320
		$result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
1321
		$expected = array(
1322
			'Article' => array(
1323
				'id' => '2',
1324
				'user_id' => '3',
1325
				'title' => 'New Second Article',
1326
				'body' => 'Second Article Body'
1327
			),
1328
			'Tag' => array(
1329
				array(
1330
					'id' => '1',
1331
					'tag' => 'tag1',
1332
					'created' => '2007-03-18 12:22:23',
1333
					'updated' => '2007-03-18 12:24:31'
1334
				),
1335
				array(
1336
					'id' => '2',
1337
					'tag' => 'tag2',
1338
					'created' => '2007-03-18 12:24:23',
1339
					'updated' => '2007-03-18 12:26:31'
1340
		)));
1341
		$this->assertEquals($expected, $result);
1342
 
1343
		$data = array('Article' => array('id' => '2'), 'Tag' => array('Tag' => array(2, 3)));
1344
		$result = $TestModel->set($data);
1345
		$this->assertFalse(empty($result));
1346
 
1347
		$result = $TestModel->save();
1348
		$this->assertFalse(empty($result));
1349
 
1350
		$TestModel->unbindModel(array(
1351
			'belongsTo' => array('User'),
1352
			'hasMany' => array('Comment')
1353
		));
1354
		$result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
1355
		$expected = array(
1356
			'Article' => array(
1357
				'id' => '2',
1358
				'user_id' => '3',
1359
				'title' => 'New Second Article',
1360
				'body' => 'Second Article Body'
1361
			),
1362
			'Tag' => array(
1363
				array(
1364
					'id' => '2',
1365
					'tag' => 'tag2',
1366
					'created' => '2007-03-18 12:24:23',
1367
					'updated' => '2007-03-18 12:26:31'
1368
				),
1369
				array(
1370
					'id' => '3',
1371
					'tag' => 'tag3',
1372
					'created' => '2007-03-18 12:26:23',
1373
					'updated' => '2007-03-18 12:28:31'
1374
		)));
1375
		$this->assertEquals($expected, $result);
1376
 
1377
		$data = array('Tag' => array('Tag' => array(1, 2, 3)));
1378
 
1379
		$result = $TestModel->set($data);
1380
		$this->assertFalse(empty($result));
1381
 
1382
		$result = $TestModel->save();
1383
		$this->assertFalse(empty($result));
1384
 
1385
		$TestModel->unbindModel(array(
1386
			'belongsTo' => array('User'),
1387
			'hasMany' => array('Comment')
1388
		));
1389
		$result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
1390
		$expected = array(
1391
			'Article' => array(
1392
				'id' => '2',
1393
				'user_id' => '3',
1394
				'title' => 'New Second Article',
1395
				'body' => 'Second Article Body'
1396
			),
1397
			'Tag' => array(
1398
				array(
1399
					'id' => '1',
1400
					'tag' => 'tag1',
1401
					'created' => '2007-03-18 12:22:23',
1402
					'updated' => '2007-03-18 12:24:31'
1403
				),
1404
				array(
1405
					'id' => '2',
1406
					'tag' => 'tag2',
1407
					'created' => '2007-03-18 12:24:23',
1408
					'updated' => '2007-03-18 12:26:31'
1409
				),
1410
				array(
1411
					'id' => '3',
1412
					'tag' => 'tag3',
1413
					'created' => '2007-03-18 12:26:23',
1414
					'updated' => '2007-03-18 12:28:31'
1415
		)));
1416
		$this->assertEquals($expected, $result);
1417
 
1418
		$data = array('Tag' => array('Tag' => array()));
1419
		$result = $TestModel->set($data);
1420
		$this->assertFalse(empty($result));
1421
 
1422
		$result = $TestModel->save();
1423
		$this->assertFalse(empty($result));
1424
 
1425
		$data = array('Tag' => array('Tag' => ''));
1426
		$result = $TestModel->set($data);
1427
		$this->assertFalse(empty($result));
1428
 
1429
		$result = $TestModel->save();
1430
		$this->assertFalse(empty($result));
1431
 
1432
		$TestModel->unbindModel(array(
1433
			'belongsTo' => array('User'),
1434
			'hasMany' => array('Comment')
1435
		));
1436
		$result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
1437
		$expected = array(
1438
			'Article' => array(
1439
				'id' => '2',
1440
				'user_id' => '3',
1441
				'title' => 'New Second Article',
1442
				'body' => 'Second Article Body'
1443
			),
1444
			'Tag' => array()
1445
		);
1446
		$this->assertEquals($expected, $result);
1447
 
1448
		$data = array('Tag' => array('Tag' => array(2, 3)));
1449
		$result = $TestModel->set($data);
1450
		$this->assertFalse(empty($result));
1451
 
1452
		$result = $TestModel->save();
1453
		$this->assertFalse(empty($result));
1454
 
1455
		$TestModel->unbindModel(array(
1456
			'belongsTo' => array('User'),
1457
			'hasMany' => array('Comment')
1458
		));
1459
		$result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
1460
		$expected = array(
1461
			'Article' => array(
1462
				'id' => '2',
1463
				'user_id' => '3',
1464
				'title' => 'New Second Article',
1465
				'body' => 'Second Article Body'
1466
			),
1467
			'Tag' => array(
1468
				array(
1469
					'id' => '2',
1470
					'tag' => 'tag2',
1471
					'created' => '2007-03-18 12:24:23',
1472
					'updated' => '2007-03-18 12:26:31'
1473
				),
1474
				array(
1475
					'id' => '3',
1476
					'tag' => 'tag3',
1477
					'created' => '2007-03-18 12:26:23',
1478
					'updated' => '2007-03-18 12:28:31'
1479
		)));
1480
		$this->assertEquals($expected, $result);
1481
 
1482
		$data = array(
1483
			'Tag' => array(
1484
				'Tag' => array(1, 2)
1485
			),
1486
			'Article' => array(
1487
				'id' => '2',
1488
				'title' => 'New Second Article'
1489
		));
1490
		$result = $TestModel->set($data);
1491
		$this->assertFalse(empty($result));
1492
		$result = $TestModel->save();
1493
		$this->assertFalse(empty($result));
1494
 
1495
		$TestModel->unbindModel(array(
1496
			'belongsTo' => array('User'),
1497
			'hasMany' => array('Comment')
1498
		));
1499
		$result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
1500
		$expected = array(
1501
			'Article' => array(
1502
				'id' => '2',
1503
				'user_id' => '3',
1504
				'title' => 'New Second Article',
1505
				'body' => 'Second Article Body'
1506
			),
1507
			'Tag' => array(
1508
				array(
1509
					'id' => '1',
1510
					'tag' => 'tag1',
1511
					'created' => '2007-03-18 12:22:23',
1512
					'updated' => '2007-03-18 12:24:31'
1513
				),
1514
				array(
1515
					'id' => '2',
1516
					'tag' => 'tag2',
1517
					'created' => '2007-03-18 12:24:23',
1518
					'updated' => '2007-03-18 12:26:31'
1519
		)));
1520
		$this->assertEquals($expected, $result);
1521
 
1522
		$data = array(
1523
			'Tag' => array(
1524
				'Tag' => array(1, 2)
1525
			),
1526
			'Article' => array(
1527
				'id' => '2',
1528
				'title' => 'New Second Article Title'
1529
		));
1530
		$result = $TestModel->set($data);
1531
		$this->assertFalse(empty($result));
1532
		$result = $TestModel->save();
1533
		$this->assertFalse(empty($result));
1534
 
1535
		$TestModel->unbindModel(array(
1536
			'belongsTo' => array('User'),
1537
			'hasMany' => array('Comment')
1538
		));
1539
		$result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
1540
		$expected = array(
1541
			'Article' => array(
1542
				'id' => '2',
1543
				'user_id' => '3',
1544
				'title' => 'New Second Article Title',
1545
				'body' => 'Second Article Body'
1546
			),
1547
			'Tag' => array(
1548
				array(
1549
					'id' => '1',
1550
					'tag' => 'tag1',
1551
					'created' => '2007-03-18 12:22:23',
1552
					'updated' => '2007-03-18 12:24:31'
1553
				),
1554
				array(
1555
					'id' => '2',
1556
					'tag' => 'tag2',
1557
					'created' => '2007-03-18 12:24:23',
1558
					'updated' => '2007-03-18 12:26:31'
1559
				)
1560
			)
1561
		);
1562
		$this->assertEquals($expected, $result);
1563
 
1564
		$data = array(
1565
			'Tag' => array(
1566
				'Tag' => array(2, 3)
1567
			),
1568
			'Article' => array(
1569
				'id' => '2',
1570
				'title' => 'Changed Second Article'
1571
		));
1572
		$result = $TestModel->set($data);
1573
		$this->assertFalse(empty($result));
1574
		$result = $TestModel->save();
1575
		$this->assertFalse(empty($result));
1576
 
1577
		$TestModel->unbindModel(array(
1578
			'belongsTo' => array('User'),
1579
			'hasMany' => array('Comment')
1580
		));
1581
		$result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
1582
		$expected = array(
1583
			'Article' => array(
1584
				'id' => '2',
1585
				'user_id' => '3',
1586
				'title' => 'Changed Second Article',
1587
				'body' => 'Second Article Body'
1588
			),
1589
			'Tag' => array(
1590
				array(
1591
					'id' => '2',
1592
					'tag' => 'tag2',
1593
					'created' => '2007-03-18 12:24:23',
1594
					'updated' => '2007-03-18 12:26:31'
1595
				),
1596
				array(
1597
					'id' => '3',
1598
					'tag' => 'tag3',
1599
					'created' => '2007-03-18 12:26:23',
1600
					'updated' => '2007-03-18 12:28:31'
1601
				)
1602
			)
1603
		);
1604
		$this->assertEquals($expected, $result);
1605
 
1606
		$data = array(
1607
			'Tag' => array(
1608
				'Tag' => array(1, 3)
1609
			),
1610
			'Article' => array('id' => '2'),
1611
		);
1612
 
1613
		$result = $TestModel->set($data);
1614
		$this->assertFalse(empty($result));
1615
 
1616
		$result = $TestModel->save();
1617
		$this->assertFalse(empty($result));
1618
 
1619
		$TestModel->unbindModel(array(
1620
			'belongsTo' => array('User'),
1621
			'hasMany' => array('Comment')
1622
		));
1623
		$result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
1624
		$expected = array(
1625
			'Article' => array(
1626
				'id' => '2',
1627
				'user_id' => '3',
1628
				'title' => 'Changed Second Article',
1629
				'body' => 'Second Article Body'
1630
			),
1631
			'Tag' => array(
1632
				array(
1633
					'id' => '1',
1634
					'tag' => 'tag1',
1635
					'created' => '2007-03-18 12:22:23',
1636
					'updated' => '2007-03-18 12:24:31'
1637
				),
1638
				array(
1639
					'id' => '3',
1640
					'tag' => 'tag3',
1641
					'created' => '2007-03-18 12:26:23',
1642
					'updated' => '2007-03-18 12:28:31'
1643
		)));
1644
		$this->assertEquals($expected, $result);
1645
 
1646
		$data = array(
1647
			'Article' => array(
1648
				'id' => 10,
1649
				'user_id' => '2',
1650
				'title' => 'New Article With Tags and fieldList',
1651
				'body' => 'New Article Body with Tags and fieldList',
1652
				'created' => '2007-03-18 14:55:23',
1653
				'updated' => '2007-03-18 14:57:31'
1654
			),
1655
			'Tag' => array(
1656
				'Tag' => array(1, 2, 3)
1657
			)
1658
		);
1659
		$result = $TestModel->create()
1660
				&& $TestModel->save($data, true, array('user_id', 'title', 'published'));
1661
		$this->assertFalse(empty($result));
1662
 
1663
		$TestModel->unbindModel(array(
1664
			'belongsTo' => array('User'),
1665
			'hasMany' => array('Comment')
1666
		));
1667
		$result = $TestModel->read();
1668
		$expected = array(
1669
			'Article' => array(
1670
				'id' => 4,
1671
				'user_id' => 2,
1672
				'title' => 'New Article With Tags and fieldList',
1673
				'body' => '',
1674
				'published' => 'N',
1675
				'created' => '',
1676
				'updated' => ''
1677
			),
1678
			'Tag' => array(
1679
 
1680
					'id' => 1,
1681
					'tag' => 'tag1',
1682
					'created' => '2007-03-18 12:22:23',
1683
					'updated' => '2007-03-18 12:24:31'
1684
				),
1685
				1 => array(
1686
					'id' => 2,
1687
					'tag' => 'tag2',
1688
					'created' => '2007-03-18 12:24:23',
1689
					'updated' => '2007-03-18 12:26:31'
1690
				),
1691
				2 => array(
1692
					'id' => 3,
1693
					'tag' => 'tag3',
1694
					'created' => '2007-03-18 12:26:23',
1695
					'updated' => '2007-03-18 12:28:31'
1696
		)));
1697
		$this->assertEquals($expected, $result);
1698
 
1699
		$this->loadFixtures('JoinA', 'JoinC', 'JoinAC', 'JoinB', 'JoinAB');
1700
		$TestModel = new JoinA();
1701
		$TestModel->hasBelongsToMany = array('JoinC' => array('unique' => true));
1702
		$data = array(
1703
			'JoinA' => array(
1704
				'id' => 1,
1705
				'name' => 'Join A 1',
1706
				'body' => 'Join A 1 Body',
1707
			),
1708
			'JoinC' => array(
1709
				'JoinC' => array(
1710
					array('join_c_id' => 2, 'other' => 'new record'),
1711
					array('join_c_id' => 3, 'other' => 'new record')
1712
				)
1713
			)
1714
		);
1715
		$TestModel->save($data);
1716
		$result = $TestModel->read(null, 1);
1717
		$expected = array(4, 5);
1718
		$this->assertEquals($expected, Hash::extract($result, 'JoinC.{n}.JoinAsJoinC.id'));
1719
		$expected = array('new record', 'new record');
1720
		$this->assertEquals($expected, Hash::extract($result, 'JoinC.{n}.JoinAsJoinC.other'));
1721
	}
1722
 
1723
/**
1724
 * testSaveHabtmNoPrimaryData method
1725
 *
1726
 * @return void
1727
 */
1728
	public function testSaveHabtmNoPrimaryData() {
1729
		$this->loadFixtures('Article', 'User', 'Comment', 'Tag', 'ArticlesTag');
1730
		$TestModel = new Article();
1731
 
1732
		$TestModel->unbindModel(array('belongsTo' => array('User'), 'hasMany' => array('Comment')), false);
1733
		$result = $TestModel->findById(2);
1734
		$expected = array(
1735
			'Article' => array(
1736
				'id' => '2',
1737
				'user_id' => '3',
1738
				'title' => 'Second Article',
1739
				'body' => 'Second Article Body',
1740
				'published' => 'Y',
1741
				'created' => '2007-03-18 10:41:23',
1742
				'updated' => '2007-03-18 10:43:31'
1743
			),
1744
			'Tag' => array(
1745
				array(
1746
					'id' => '1',
1747
					'tag' => 'tag1',
1748
					'created' => '2007-03-18 12:22:23',
1749
					'updated' => '2007-03-18 12:24:31'
1750
				),
1751
				array(
1752
					'id' => '3',
1753
					'tag' => 'tag3',
1754
					'created' => '2007-03-18 12:26:23',
1755
					'updated' => '2007-03-18 12:28:31'
1756
				)
1757
			)
1758
		);
1759
		$this->assertEquals($expected, $result);
1760
 
1761
		$TestModel->id = 2;
1762
		$data = array('Tag' => array('Tag' => array(2)));
1763
		$result = $TestModel->save($data);
1764
 
1765
		$this->assertEquals($data['Tag'], $result['Tag']);
1766
 
1767
		$result = $TestModel->findById(2);
1768
		$expected = array(
1769
			'Article' => array(
1770
				'id' => '2',
1771
				'user_id' => '3',
1772
				'title' => 'Second Article',
1773
				'body' => 'Second Article Body',
1774
				'published' => 'Y',
1775
				'created' => '2007-03-18 10:41:23',
1776
				'updated' => self::date()
1777
			),
1778
			'Tag' => array(
1779
				array(
1780
					'id' => '2',
1781
					'tag' => 'tag2',
1782
					'created' => '2007-03-18 12:24:23',
1783
					'updated' => '2007-03-18 12:26:31'
1784
				)
1785
			)
1786
		);
1787
		$this->assertEquals($expected, $result);
1788
 
1789
		$this->loadFixtures('Portfolio', 'Item', 'ItemsPortfolio');
1790
		$TestModel = new Portfolio();
1791
		$result = $TestModel->findById(2);
1792
		$expected = array(
1793
			'Portfolio' => array(
1794
				'id' => 2,
1795
				'seller_id' => 1,
1796
				'name' => 'Portfolio 2'
1797
			),
1798
			'Item' => array(
1799
				array(
1800
					'id' => 2,
1801
					'syfile_id' => 2,
1802
					'published' => '',
1803
					'name' => 'Item 2',
1804
					'ItemsPortfolio' => array(
1805
						'id' => 2,
1806
						'item_id' => 2,
1807
						'portfolio_id' => 2
1808
					)
1809
				),
1810
				array(
1811
					'id' => 6,
1812
					'syfile_id' => 6,
1813
					'published' => '',
1814
					'name' => 'Item 6',
1815
					'ItemsPortfolio' => array(
1816
						'id' => 6,
1817
						'item_id' => 6,
1818
						'portfolio_id' => 2
1819
					)
1820
				)
1821
			)
1822
		);
1823
		$this->assertEquals($expected, $result);
1824
 
1825
		$data = array('Item' => array('Item' => array(1, 2)));
1826
		$TestModel->id = 2;
1827
		$TestModel->save($data);
1828
		$result = $TestModel->findById(2);
1829
		$result['Item'] = Hash::sort($result['Item'], '{n}.id', 'asc');
1830
		$expected = array(
1831
			'Portfolio' => array(
1832
				'id' => 2,
1833
				'seller_id' => 1,
1834
				'name' => 'Portfolio 2'
1835
			),
1836
			'Item' => array(
1837
				array(
1838
					'id' => 1,
1839
					'syfile_id' => 1,
1840
					'published' => '',
1841
					'name' => 'Item 1',
1842
					'ItemsPortfolio' => array(
1843
						'id' => 7,
1844
						'item_id' => 1,
1845
						'portfolio_id' => 2
1846
					)
1847
				),
1848
				array(
1849
					'id' => 2,
1850
					'syfile_id' => 2,
1851
					'published' => '',
1852
					'name' => 'Item 2',
1853
					'ItemsPortfolio' => array(
1854
						'id' => 8,
1855
						'item_id' => 2,
1856
						'portfolio_id' => 2
1857
					)
1858
				)
1859
			)
1860
		);
1861
		$this->assertEquals($expected, $result);
1862
	}
1863
 
1864
/**
1865
 * testSaveHabtmCustomKeys method
1866
 *
1867
 * @return void
1868
 */
1869
	public function testSaveHabtmCustomKeys() {
1870
		$this->loadFixtures('Story', 'StoriesTag', 'Tag');
1871
		$Story = new Story();
1872
 
1873
		$data = array(
1874
			'Story' => array('story' => '1'),
1875
			'Tag' => array(
1876
				'Tag' => array(2, 3)
1877
		));
1878
		$result = $Story->set($data);
1879
		$this->assertFalse(empty($result));
1880
 
1881
		$result = $Story->save();
1882
		$this->assertFalse(empty($result));
1883
 
1884
		$result = $Story->find('all', array('order' => array('Story.story')));
1885
		$expected = array(
1886
			array(
1887
				'Story' => array(
1888
					'story' => 1,
1889
					'title' => 'First Story'
1890
				),
1891
				'Tag' => array(
1892
					array(
1893
						'id' => 2,
1894
						'tag' => 'tag2',
1895
						'created' => '2007-03-18 12:24:23',
1896
						'updated' => '2007-03-18 12:26:31'
1897
					),
1898
					array(
1899
						'id' => 3,
1900
						'tag' => 'tag3',
1901
						'created' => '2007-03-18 12:26:23',
1902
						'updated' => '2007-03-18 12:28:31'
1903
			))),
1904
			array(
1905
				'Story' => array(
1906
					'story' => 2,
1907
					'title' => 'Second Story'
1908
				),
1909
				'Tag' => array()
1910
		));
1911
		$this->assertEquals($expected, $result);
1912
	}
1913
 
1914
/**
1915
 * test that saving habtm records respects conditions set in the 'conditions' key
1916
 * for the association.
1917
 *
1918
 * @return void
1919
 */
1920
	public function testHabtmSaveWithConditionsInAssociation() {
1921
		$this->loadFixtures('JoinThing', 'Something', 'SomethingElse');
1922
		$Something = new Something();
1923
		$Something->unbindModel(array('hasAndBelongsToMany' => array('SomethingElse')), false);
1924
 
1925
		$Something->bindModel(array(
1926
			'hasAndBelongsToMany' => array(
1927
				'DoomedSomethingElse' => array(
1928
					'className' => 'SomethingElse',
1929
					'joinTable' => 'join_things',
1930
					'conditions' => array('JoinThing.doomed' => true),
1931
					'unique' => true
1932
				),
1933
				'NotDoomedSomethingElse' => array(
1934
					'className' => 'SomethingElse',
1935
					'joinTable' => 'join_things',
1936
					'conditions' => array('JoinThing.doomed' => 0),
1937
					'unique' => true
1938
				)
1939
			)
1940
		), false);
1941
		$result = $Something->read(null, 1);
1942
		$this->assertTrue(empty($result['NotDoomedSomethingElse']));
1943
		$this->assertEquals(1, count($result['DoomedSomethingElse']));
1944
 
1945
		$data = array(
1946
			'Something' => array('id' => 1),
1947
			'NotDoomedSomethingElse' => array(
1948
				'NotDoomedSomethingElse' => array(
1949
					array('something_else_id' => 2, 'doomed' => 0),
1950
					array('something_else_id' => 3, 'doomed' => 0)
1951
				)
1952
			)
1953
		);
1954
		$Something->create($data);
1955
		$result = $Something->save();
1956
		$this->assertFalse(empty($result));
1957
 
1958
		$result = $Something->read(null, 1);
1959
		$this->assertEquals(2, count($result['NotDoomedSomethingElse']));
1960
		$this->assertEquals(1, count($result['DoomedSomethingElse']));
1961
	}
1962
 
1963
/**
1964
 * testHabtmSaveKeyResolution method
1965
 *
1966
 * @return void
1967
 */
1968
	public function testHabtmSaveKeyResolution() {
1969
		$this->loadFixtures('Apple', 'Device', 'ThePaperMonkies');
1970
		$ThePaper = new ThePaper();
1971
 
1972
		$ThePaper->id = 1;
1973
		$ThePaper->save(array('Monkey' => array(2, 3)));
1974
 
1975
		$result = $ThePaper->findById(1);
1976
		$expected = array(
1977
			array(
1978
				'id' => '2',
1979
				'device_type_id' => '1',
1980
				'name' => 'Device 2',
1981
				'typ' => '1'
1982
			),
1983
			array(
1984
				'id' => '3',
1985
				'device_type_id' => '1',
1986
				'name' => 'Device 3',
1987
				'typ' => '2'
1988
		));
1989
		$this->assertEquals($expected, $result['Monkey']);
1990
 
1991
		$ThePaper->id = 2;
1992
		$ThePaper->save(array('Monkey' => array(1, 2, 3)));
1993
 
1994
		$result = $ThePaper->findById(2);
1995
		$expected = array(
1996
			array(
1997
				'id' => '1',
1998
				'device_type_id' => '1',
1999
				'name' => 'Device 1',
2000
				'typ' => '1'
2001
			),
2002
			array(
2003
				'id' => '2',
2004
				'device_type_id' => '1',
2005
				'name' => 'Device 2',
2006
				'typ' => '1'
2007
			),
2008
			array(
2009
				'id' => '3',
2010
				'device_type_id' => '1',
2011
				'name' => 'Device 3',
2012
				'typ' => '2'
2013
		));
2014
		$this->assertEquals($expected, $result['Monkey']);
2015
 
2016
		$ThePaper->id = 2;
2017
		$ThePaper->save(array('Monkey' => array(1, 3)));
2018
 
2019
		$result = $ThePaper->findById(2);
2020
		$expected = array(
2021
			array(
2022
				'id' => '1',
2023
				'device_type_id' => '1',
2024
				'name' => 'Device 1',
2025
				'typ' => '1'
2026
			),
2027
			array(
2028
				'id' => '3',
2029
				'device_type_id' => '1',
2030
				'name' => 'Device 3',
2031
				'typ' => '2'
2032
			));
2033
		$this->assertEquals($expected, $result['Monkey']);
2034
 
2035
		$result = $ThePaper->findById(1);
2036
		$expected = array(
2037
			array(
2038
				'id' => '2',
2039
				'device_type_id' => '1',
2040
				'name' => 'Device 2',
2041
				'typ' => '1'
2042
			),
2043
			array(
2044
				'id' => '3',
2045
				'device_type_id' => '1',
2046
				'name' => 'Device 3',
2047
				'typ' => '2'
2048
		));
2049
		$this->assertEquals($expected, $result['Monkey']);
2050
	}
2051
 
2052
/**
2053
 * testCreationOfEmptyRecord method
2054
 *
2055
 * @return void
2056
 */
2057
	public function testCreationOfEmptyRecord() {
2058
		$this->loadFixtures('Author');
2059
		$TestModel = new Author();
2060
		$this->assertEquals(4, $TestModel->find('count'));
2061
 
2062
		$TestModel->deleteAll(true, false, false);
2063
		$this->assertEquals(0, $TestModel->find('count'));
2064
 
2065
		$result = $TestModel->save();
2066
		$this->assertTrue(isset($result['Author']['created']));
2067
		$this->assertTrue(isset($result['Author']['updated']));
2068
		$this->assertEquals(1, $TestModel->find('count'));
2069
	}
2070
 
2071
/**
2072
 * testCreateWithPKFiltering method
2073
 *
2074
 * @return void
2075
 */
2076
	public function testCreateWithPKFiltering() {
2077
		$TestModel = new Article();
2078
		$data = array(
2079
			'id' => 5,
2080
			'user_id' => 2,
2081
			'title' => 'My article',
2082
			'body' => 'Some text'
2083
		);
2084
 
2085
		$result = $TestModel->create($data);
2086
		$expected = array(
2087
			'Article' => array(
2088
				'published' => 'N',
2089
				'id' => 5,
2090
				'user_id' => 2,
2091
				'title' => 'My article',
2092
				'body' => 'Some text'
2093
		));
2094
 
2095
		$this->assertEquals($expected, $result);
2096
		$this->assertEquals(5, $TestModel->id);
2097
 
2098
		$result = $TestModel->create($data, true);
2099
		$expected = array(
2100
			'Article' => array(
2101
				'published' => 'N',
2102
				'id' => false,
2103
				'user_id' => 2,
2104
				'title' => 'My article',
2105
				'body' => 'Some text'
2106
		));
2107
 
2108
		$this->assertEquals($expected, $result);
2109
		$this->assertFalse($TestModel->id);
2110
 
2111
		$result = $TestModel->create(array('Article' => $data), true);
2112
		$expected = array(
2113
			'Article' => array(
2114
				'published' => 'N',
2115
				'id' => false,
2116
				'user_id' => 2,
2117
				'title' => 'My article',
2118
				'body' => 'Some text'
2119
		));
2120
 
2121
		$this->assertEquals($expected, $result);
2122
		$this->assertFalse($TestModel->id);
2123
 
2124
		$data = array(
2125
			'id' => 6,
2126
			'user_id' => 2,
2127
			'title' => 'My article',
2128
			'body' => 'Some text',
2129
			'created' => '1970-01-01 00:00:00',
2130
			'updated' => '1970-01-01 12:00:00',
2131
			'modified' => '1970-01-01 12:00:00'
2132
		);
2133
 
2134
		$result = $TestModel->create($data);
2135
		$expected = array(
2136
			'Article' => array(
2137
				'published' => 'N',
2138
				'id' => 6,
2139
				'user_id' => 2,
2140
				'title' => 'My article',
2141
				'body' => 'Some text',
2142
				'created' => '1970-01-01 00:00:00',
2143
				'updated' => '1970-01-01 12:00:00',
2144
				'modified' => '1970-01-01 12:00:00'
2145
		));
2146
		$this->assertEquals($expected, $result);
2147
		$this->assertEquals(6, $TestModel->id);
2148
 
2149
		$result = $TestModel->create(array(
2150
			'Article' => array_diff_key($data, array(
2151
				'created' => true,
2152
				'updated' => true,
2153
				'modified' => true
2154
		))), true);
2155
		$expected = array(
2156
			'Article' => array(
2157
				'published' => 'N',
2158
				'id' => false,
2159
				'user_id' => 2,
2160
				'title' => 'My article',
2161
				'body' => 'Some text'
2162
		));
2163
		$this->assertEquals($expected, $result);
2164
		$this->assertFalse($TestModel->id);
2165
	}
2166
 
2167
/**
2168
 * testCreationWithMultipleData method
2169
 *
2170
 * @return void
2171
 */
2172
	public function testCreationWithMultipleData() {
2173
		$this->loadFixtures('Article', 'Comment');
2174
		$Article = new Article();
2175
		$Comment = new Comment();
2176
 
2177
		$articles = $Article->find('all', array(
2178
			'fields' => array('id', 'title'),
2179
			'recursive' => -1,
2180
			'order' => array('Article.id' => 'ASC')
2181
		));
2182
		$expected = array(
2183
			array('Article' => array(
2184
				'id' => 1,
2185
				'title' => 'First Article'
2186
			)),
2187
			array('Article' => array(
2188
				'id' => 2,
2189
				'title' => 'Second Article'
2190
			)),
2191
			array('Article' => array(
2192
				'id' => 3,
2193
				'title' => 'Third Article'
2194
		)));
2195
		$this->assertEquals($expected, $articles);
2196
 
2197
		$comments = $Comment->find('all', array(
2198
			'fields' => array('id', 'article_id', 'user_id', 'comment', 'published'),
2199
			'recursive' => -1,
2200
			'order' => array('Comment.id' => 'ASC')
2201
		));
2202
		$expected = array(
2203
			array('Comment' => array(
2204
				'id' => 1,
2205
				'article_id' => 1,
2206
				'user_id' => 2,
2207
				'comment' => 'First Comment for First Article',
2208
				'published' => 'Y'
2209
			)),
2210
			array('Comment' => array(
2211
				'id' => 2,
2212
				'article_id' => 1,
2213
				'user_id' => 4,
2214
				'comment' => 'Second Comment for First Article',
2215
				'published' => 'Y'
2216
			)),
2217
			array('Comment' => array(
2218
				'id' => 3,
2219
				'article_id' => 1,
2220
				'user_id' => 1,
2221
				'comment' => 'Third Comment for First Article',
2222
				'published' => 'Y'
2223
			)),
2224
			array('Comment' => array(
2225
				'id' => 4,
2226
				'article_id' => 1,
2227
				'user_id' => 1,
2228
				'comment' => 'Fourth Comment for First Article',
2229
				'published' => 'N'
2230
			)),
2231
			array('Comment' => array(
2232
				'id' => 5,
2233
				'article_id' => 2,
2234
				'user_id' => 1,
2235
				'comment' => 'First Comment for Second Article',
2236
				'published' => 'Y'
2237
			)),
2238
			array('Comment' => array(
2239
				'id' => 6,
2240
				'article_id' => 2,
2241
				'user_id' => 2,
2242
				'comment' => 'Second Comment for Second Article',
2243
				'published' => 'Y'
2244
		)));
2245
		$this->assertEquals($expected, $comments);
2246
 
2247
		$data = array(
2248
			'Comment' => array(
2249
				'article_id' => 2,
2250
				'user_id' => 4,
2251
				'comment' => 'Brand New Comment',
2252
				'published' => 'N'
2253
			),
2254
			'Article' => array(
2255
				'id' => 2,
2256
				'title' => 'Second Article Modified'
2257
		));
2258
		$result = $Comment->create($data);
2259
		$this->assertFalse(empty($result));
2260
 
2261
		$result = $Comment->save();
2262
		$this->assertFalse(empty($result));
2263
 
2264
		$articles = $Article->find('all', array(
2265
			'fields' => array('id', 'title'),
2266
			'recursive' => -1,
2267
			'order' => array('Article.id' => 'ASC')
2268
		));
2269
		$expected = array(
2270
			array('Article' => array(
2271
				'id' => 1,
2272
				'title' => 'First Article'
2273
			)),
2274
			array('Article' => array(
2275
				'id' => 2,
2276
				'title' => 'Second Article'
2277
			)),
2278
			array('Article' => array(
2279
				'id' => 3,
2280
				'title' => 'Third Article'
2281
		)));
2282
		$this->assertEquals($expected, $articles);
2283
 
2284
		$comments = $Comment->find('all', array(
2285
			'fields' => array('id', 'article_id', 'user_id', 'comment', 'published'),
2286
			'recursive' => -1,
2287
			'order' => array('Comment.id' => 'ASC')
2288
		));
2289
		$expected = array(
2290
			array('Comment' => array(
2291
				'id' => 1,
2292
				'article_id' => 1,
2293
				'user_id' => 2,
2294
				'comment' => 'First Comment for First Article',
2295
				'published' => 'Y'
2296
			)),
2297
			array('Comment' => array(
2298
				'id' => 2,
2299
				'article_id' => 1,
2300
				'user_id' => 4,
2301
				'comment' => 'Second Comment for First Article',
2302
				'published' => 'Y'
2303
			)),
2304
			array('Comment' => array(
2305
				'id' => 3,
2306
				'article_id' => 1,
2307
				'user_id' => 1,
2308
				'comment' => 'Third Comment for First Article',
2309
				'published' => 'Y'
2310
			)),
2311
			array('Comment' => array(
2312
				'id' => 4,
2313
				'article_id' => 1,
2314
				'user_id' => 1,
2315
				'comment' => 'Fourth Comment for First Article',
2316
				'published' => 'N'
2317
			)),
2318
			array('Comment' => array(
2319
				'id' => 5,
2320
				'article_id' => 2,
2321
				'user_id' => 1,
2322
				'comment' => 'First Comment for Second Article',
2323
				'published' => 'Y'
2324
			)),
2325
			array('Comment' => array(
2326
				'id' => 6,
2327
				'article_id' => 2,
2328
				'user_id' => 2, 'comment' =>
2329
				'Second Comment for Second Article',
2330
				'published' => 'Y'
2331
			)),
2332
			array('Comment' => array(
2333
				'id' => 7,
2334
				'article_id' => 2,
2335
				'user_id' => 4,
2336
				'comment' => 'Brand New Comment',
2337
				'published' => 'N'
2338
		)));
2339
		$this->assertEquals($expected, $comments);
2340
	}
2341
 
2342
/**
2343
 * testCreationWithMultipleDataSameModel method
2344
 *
2345
 * @return void
2346
 */
2347
	public function testCreationWithMultipleDataSameModel() {
2348
		$this->loadFixtures('Article');
2349
		$Article = new Article();
2350
 
2351
		$result = $Article->field('title', array('id' => 1));
2352
		$this->assertEquals('First Article', $result);
2353
 
2354
		$data = array(
2355
			'Article' => array(
2356
				'user_id' => 2,
2357
				'title' => 'Brand New Article',
2358
				'body' => 'Brand New Article Body',
2359
				'published' => 'Y'
2360
			),
2361
			'SecondaryArticle' => array(
2362
				'id' => 1
2363
		));
2364
 
2365
		$Article->create();
2366
		$result = $Article->save($data);
2367
		$this->assertFalse(empty($result));
2368
 
2369
		$result = $Article->getInsertID();
2370
		$this->assertTrue(!empty($result));
2371
 
2372
		$result = $Article->field('title', array('id' => 1));
2373
		$this->assertEquals('First Article', $result);
2374
 
2375
		$articles = $Article->find('all', array(
2376
			'fields' => array('id', 'title'),
2377
			'recursive' => -1,
2378
			'order' => array('Article.id' => 'ASC')
2379
		));
2380
		$expected = array(
2381
			array('Article' => array(
2382
				'id' => 1,
2383
				'title' => 'First Article'
2384
			)),
2385
			array('Article' => array(
2386
				'id' => 2,
2387
				'title' => 'Second Article'
2388
			)),
2389
			array('Article' => array(
2390
				'id' => 3,
2391
				'title' => 'Third Article'
2392
			)),
2393
			array('Article' => array(
2394
				'id' => 4,
2395
				'title' => 'Brand New Article'
2396
		)));
2397
 
2398
		$this->assertEquals($expected, $articles);
2399
	}
2400
 
2401
/**
2402
 * testCreationWithMultipleDataSameModelManualInstances method
2403
 *
2404
 * @return void
2405
 */
2406
	public function testCreationWithMultipleDataSameModelManualInstances() {
2407
		$this->loadFixtures('PrimaryModel');
2408
		$Primary = new PrimaryModel();
2409
 
2410
		$result = $Primary->field('primary_name', array('id' => 1));
2411
		$this->assertEquals('Primary Name Existing', $result);
2412
 
2413
		$data = array(
2414
			'PrimaryModel' => array(
2415
				'primary_name' => 'Primary Name New'
2416
			),
2417
			'SecondaryModel' => array(
2418
				'id' => array(1)
2419
		));
2420
 
2421
		$Primary->create();
2422
		$result = $Primary->save($data);
2423
		$this->assertFalse(empty($result));
2424
 
2425
		$result = $Primary->field('primary_name', array('id' => 1));
2426
		$this->assertEquals('Primary Name Existing', $result);
2427
 
2428
		$result = $Primary->getInsertID();
2429
		$this->assertTrue(!empty($result));
2430
 
2431
		$result = $Primary->field('primary_name', array('id' => $result));
2432
		$this->assertEquals('Primary Name New', $result);
2433
 
2434
		$result = $Primary->find('count');
2435
		$this->assertEquals(2, $result);
2436
	}
2437
 
2438
/**
2439
 * testRecordExists method
2440
 *
2441
 * @return void
2442
 */
2443
	public function testRecordExists() {
2444
		$this->loadFixtures('User');
2445
		$TestModel = new User();
2446
 
2447
		$this->assertFalse($TestModel->exists());
2448
		$TestModel->read(null, 1);
2449
		$this->assertTrue($TestModel->exists());
2450
		$TestModel->create();
2451
		$this->assertFalse($TestModel->exists());
2452
		$TestModel->id = 4;
2453
		$this->assertTrue($TestModel->exists());
2454
 
2455
		$TestModel = new TheVoid();
2456
		$this->assertFalse($TestModel->exists());
2457
	}
2458
 
2459
/**
2460
 * testRecordExistsMissingTable method
2461
 *
2462
 * @expectedException PDOException
2463
 * @return void
2464
 */
2465
	public function testRecordExistsMissingTable() {
2466
		$TestModel = new TheVoid();
2467
		$TestModel->id = 5;
2468
		$TestModel->exists();
2469
	}
2470
 
2471
/**
2472
 * testUpdateExisting method
2473
 *
2474
 * @return void
2475
 */
2476
	public function testUpdateExisting() {
2477
		$this->loadFixtures('User', 'Article', 'Comment');
2478
		$TestModel = new User();
2479
		$TestModel->create();
2480
 
2481
		$TestModel->save(array(
2482
			'User' => array(
2483
				'user' => 'some user',
2484
				'password' => 'some password'
2485
		)));
2486
		$this->assertTrue(is_int($TestModel->id) || (intval($TestModel->id) === 5));
2487
		$id = $TestModel->id;
2488
 
2489
		$TestModel->save(array(
2490
			'User' => array(
2491
				'user' => 'updated user'
2492
		)));
2493
		$this->assertEquals($id, $TestModel->id);
2494
 
2495
		$result = $TestModel->findById($id);
2496
		$this->assertEquals('updated user', $result['User']['user']);
2497
		$this->assertEquals('some password', $result['User']['password']);
2498
 
2499
		$Article = new Article();
2500
		$Comment = new Comment();
2501
		$data = array(
2502
			'Comment' => array(
2503
				'id' => 1,
2504
				'comment' => 'First Comment for First Article'
2505
			),
2506
			'Article' => array(
2507
				'id' => 2,
2508
				'title' => 'Second Article'
2509
		));
2510
 
2511
		$result = $Article->save($data);
2512
		$this->assertFalse(empty($result));
2513
 
2514
		$result = $Comment->save($data);
2515
		$this->assertFalse(empty($result));
2516
	}
2517
 
2518
/**
2519
 * test updating records and saving blank values.
2520
 *
2521
 * @return void
2522
 */
2523
	public function testUpdateSavingBlankValues() {
2524
		$this->loadFixtures('Article');
2525
		$Article = new Article();
2526
		$Article->validate = array();
2527
		$Article->create();
2528
		$result = $Article->save(array(
2529
			'id' => 1,
2530
			'title' => '',
2531
			'body' => ''
2532
		));
2533
		$this->assertTrue((bool)$result);
2534
		$result = $Article->find('first', array('conditions' => array('Article.id' => 1)));
2535
		$this->assertEquals('', $result['Article']['title'], 'Title is not blank');
2536
		$this->assertEquals('', $result['Article']['body'], 'Body is not blank');
2537
	}
2538
 
2539
/**
2540
 * testUpdateMultiple method
2541
 *
2542
 * @return void
2543
 */
2544
	public function testUpdateMultiple() {
2545
		$this->loadFixtures('Comment', 'Article', 'User', 'CategoryThread');
2546
		$TestModel = new Comment();
2547
		$result = Hash::extract($TestModel->find('all'), '{n}.Comment.user_id');
2548
		$expected = array('2', '4', '1', '1', '1', '2');
2549
		$this->assertEquals($expected, $result);
2550
 
2551
		$TestModel->updateAll(array('Comment.user_id' => 5), array('Comment.user_id' => 2));
2552
		$result = Hash::combine($TestModel->find('all'), '{n}.Comment.id', '{n}.Comment.user_id');
2553
		$expected = array(1 => 5, 2 => 4, 3 => 1, 4 => 1, 5 => 1, 6 => 5);
2554
		$this->assertEquals($expected, $result);
2555
 
2556
		$result = $TestModel->updateAll(
2557
			array('Comment.comment' => "'Updated today'"),
2558
			array('Comment.user_id' => 5)
2559
		);
2560
		$this->assertFalse(empty($result));
2561
		$result = Hash::extract(
2562
			$TestModel->find('all', array(
2563
				'conditions' => array(
2564
					'Comment.user_id' => 5
2565
			))),
2566
			'{n}.Comment.comment'
2567
		);
2568
		$expected = array_fill(0, 2, 'Updated today');
2569
		$this->assertEquals($expected, $result);
2570
	}
2571
 
2572
/**
2573
 * testHabtmUuidWithUuidId method
2574
 *
2575
 * @return void
2576
 */
2577
	public function testHabtmUuidWithUuidId() {
2578
		$this->loadFixtures('Uuidportfolio', 'Uuiditem', 'UuiditemsUuidportfolio', 'UuiditemsUuidportfolioNumericid');
2579
		$TestModel = new Uuidportfolio();
2580
 
2581
		$data = array('Uuidportfolio' => array('name' => 'Portfolio 3'));
2582
		$data['Uuiditem']['Uuiditem'] = array('483798c8-c7cc-430e-8cf9-4fcc40cf8569');
2583
		$TestModel->create($data);
2584
		$TestModel->save();
2585
		$id = $TestModel->id;
2586
		$result = $TestModel->read(null, $id);
2587
		$this->assertEquals(1, count($result['Uuiditem']));
2588
		$this->assertEquals(36, strlen($result['Uuiditem'][0]['UuiditemsUuidportfolio']['id']));
2589
	}
2590
 
2591
/**
2592
 * test HABTM saving when join table has no primary key and only 2 columns.
2593
 *
2594
 * @return void
2595
 */
2596
	public function testHabtmSavingWithNoPrimaryKeyUuidJoinTable() {
2597
		$this->loadFixtures('UuidTag', 'Fruit', 'FruitsUuidTag');
2598
		$Fruit = new Fruit();
2599
		$Fruit->FruitsUuidTag->order = null;
2600
		$data = array(
2601
			'Fruit' => array(
2602
				'color' => 'Red',
2603
				'shape' => 'Heart-shaped',
2604
				'taste' => 'sweet',
2605
				'name' => 'Strawberry',
2606
			),
2607
			'UuidTag' => array(
2608
				'UuidTag' => array(
2609
					'481fc6d0-b920-43e0-e50f-6d1740cf8569'
2610
				)
2611
			)
2612
		);
2613
		$result = $Fruit->save($data);
2614
		$this->assertFalse(empty($result));
2615
	}
2616
 
2617
/**
2618
 * test HABTM saving when join table has no primary key and only 2 columns, no with model is used.
2619
 *
2620
 * @return void
2621
 */
2622
	public function testHabtmSavingWithNoPrimaryKeyUuidJoinTableNoWith() {
2623
		$this->loadFixtures('UuidTag', 'Fruit', 'FruitsUuidTag');
2624
		$Fruit = new FruitNoWith();
2625
		$data = array(
2626
			'Fruit' => array(
2627
				'color' => 'Red',
2628
				'shape' => 'Heart-shaped',
2629
				'taste' => 'sweet',
2630
				'name' => 'Strawberry',
2631
			),
2632
			'UuidTag' => array(
2633
				'UuidTag' => array(
2634
					'481fc6d0-b920-43e0-e50f-6d1740cf8569'
2635
				)
2636
			)
2637
		);
2638
		$result = $Fruit->save($data);
2639
		$this->assertFalse(empty($result));
2640
	}
2641
 
2642
/**
2643
 * testHabtmUuidWithNumericId method
2644
 *
2645
 * @return void
2646
 */
2647
	public function testHabtmUuidWithNumericId() {
2648
		$this->loadFixtures('Uuidportfolio', 'Uuiditem', 'UuiditemsUuidportfolioNumericid');
2649
		$TestModel = new Uuiditem();
2650
 
2651
		$data = array('Uuiditem' => array('name' => 'Item 7', 'published' => 0));
2652
		$data['Uuidportfolio']['Uuidportfolio'] = array('480af662-eb8c-47d3-886b-230540cf8569');
2653
		$TestModel->create($data);
2654
		$TestModel->save();
2655
		$id = $TestModel->id;
2656
		$result = $TestModel->read(null, $id);
2657
		$this->assertEquals(1, count($result['Uuidportfolio']));
2658
	}
2659
 
2660
/**
2661
 * testSaveMultipleHabtm method
2662
 *
2663
 * @return void
2664
 */
2665
	public function testSaveMultipleHabtm() {
2666
		$this->loadFixtures('JoinA', 'JoinB', 'JoinC', 'JoinAB', 'JoinAC');
2667
		$TestModel = new JoinA();
2668
		$result = $TestModel->findById(1);
2669
 
2670
		$expected = array(
2671
			'JoinA' => array(
2672
				'id' => 1,
2673
				'name' => 'Join A 1',
2674
				'body' => 'Join A 1 Body',
2675
				'created' => '2008-01-03 10:54:23',
2676
				'updated' => '2008-01-03 10:54:23'
2677
			),
2678
			'JoinB' => array(
2679
 
2680
					'id' => 2,
2681
					'name' => 'Join B 2',
2682
					'created' => '2008-01-03 10:55:02',
2683
					'updated' => '2008-01-03 10:55:02',
2684
					'JoinAsJoinB' => array(
2685
						'id' => 1,
2686
						'join_a_id' => 1,
2687
						'join_b_id' => 2,
2688
						'other' => 'Data for Join A 1 Join B 2',
2689
						'created' => '2008-01-03 10:56:33',
2690
						'updated' => '2008-01-03 10:56:33'
2691
			))),
2692
			'JoinC' => array(
2693
 
2694
					'id' => 2,
2695
					'name' => 'Join C 2',
2696
					'created' => '2008-01-03 10:56:12',
2697
					'updated' => '2008-01-03 10:56:12',
2698
					'JoinAsJoinC' => array(
2699
						'id' => 1,
2700
						'join_a_id' => 1,
2701
						'join_c_id' => 2,
2702
						'other' => 'Data for Join A 1 Join C 2',
2703
						'created' => '2008-01-03 10:57:22',
2704
						'updated' => '2008-01-03 10:57:22'
2705
		))));
2706
 
2707
		$this->assertEquals($expected, $result);
2708
 
2709
		$TestModel->id = 1;
2710
		$data = array(
2711
			'JoinA' => array(
2712
				'id' => '1',
2713
				'name' => 'New name for Join A 1',
2714
				'updated' => self::date()
2715
			),
2716
			'JoinB' => array(
2717
				array(
2718
					'id' => 1,
2719
					'join_b_id' => 2,
2720
					'other' => 'New data for Join A 1 Join B 2',
2721
					'created' => self::date(),
2722
					'updated' => self::date()
2723
			)),
2724
			'JoinC' => array(
2725
				array(
2726
					'id' => 1,
2727
					'join_c_id' => 2,
2728
					'other' => 'New data for Join A 1 Join C 2',
2729
					'created' => self::date(),
2730
					'updated' => self::date()
2731
		)));
2732
 
2733
		$TestModel->set($data);
2734
		$TestModel->save();
2735
 
2736
		$result = $TestModel->findById(1);
2737
		$expected = array(
2738
			'JoinA' => array(
2739
				'id' => 1,
2740
				'name' => 'New name for Join A 1',
2741
				'body' => 'Join A 1 Body',
2742
				'created' => '2008-01-03 10:54:23',
2743
				'updated' => self::date()
2744
			),
2745
			'JoinB' => array(
2746
 
2747
					'id' => 2,
2748
					'name' => 'Join B 2',
2749
					'created' => '2008-01-03 10:55:02',
2750
					'updated' => '2008-01-03 10:55:02',
2751
					'JoinAsJoinB' => array(
2752
						'id' => 1,
2753
						'join_a_id' => 1,
2754
						'join_b_id' => 2,
2755
						'other' => 'New data for Join A 1 Join B 2',
2756
						'created' => self::date(),
2757
						'updated' => self::date()
2758
			))),
2759
			'JoinC' => array(
2760
 
2761
					'id' => 2,
2762
					'name' => 'Join C 2',
2763
					'created' => '2008-01-03 10:56:12',
2764
					'updated' => '2008-01-03 10:56:12',
2765
					'JoinAsJoinC' => array(
2766
						'id' => 1,
2767
						'join_a_id' => 1,
2768
						'join_c_id' => 2,
2769
						'other' => 'New data for Join A 1 Join C 2',
2770
						'created' => self::date(),
2771
						'updated' => self::date()
2772
		))));
2773
 
2774
		$this->assertEquals($expected, $result);
2775
	}
2776
 
2777
/**
2778
 * testSaveAll method
2779
 *
2780
 * @return void
2781
 */
2782
	public function testSaveAll() {
2783
		$this->loadFixtures('Post', 'Author', 'Comment', 'Attachment', 'Article', 'User');
2784
		$TestModel = new Post();
2785
 
2786
		$result = $TestModel->find('all');
2787
		$this->assertEquals(3, count($result));
2788
		$this->assertFalse(isset($result[3]));
2789
 
2790
		$TestModel->saveAll(array(
2791
			'Post' => array(
2792
				'title' => 'Post with Author',
2793
				'body' => 'This post will be saved with an author'
2794
			),
2795
			'Author' => array(
2796
				'user' => 'bob',
2797
				'password' => '5f4dcc3b5aa765d61d8327deb882cf90'
2798
		)));
2799
 
2800
		$result = $TestModel->find('all');
2801
		$expected = array(
2802
			'Post' => array(
2803
				'id' => '4',
2804
				'author_id' => '5',
2805
				'title' => 'Post with Author',
2806
				'body' => 'This post will be saved with an author',
2807
				'published' => 'N'
2808
			),
2809
			'Author' => array(
2810
				'id' => '5',
2811
				'user' => 'bob',
2812
				'password' => '5f4dcc3b5aa765d61d8327deb882cf90',
2813
				'test' => 'working'
2814
		));
2815
		$this->assertEquals(self::date(), $result[3]['Post']['created']);
2816
		$this->assertEquals(self::date(), $result[3]['Post']['updated']);
2817
		$this->assertEquals(self::date(), $result[3]['Author']['created']);
2818
		$this->assertEquals(self::date(), $result[3]['Author']['updated']);
2819
		unset($result[3]['Post']['created'], $result[3]['Post']['updated']);
2820
		unset($result[3]['Author']['created'], $result[3]['Author']['updated']);
2821
		$this->assertEquals($expected, $result[3]);
2822
		$this->assertEquals(4, count($result));
2823
 
2824
		$TestModel->deleteAll(true);
2825
		$this->assertEquals(array(), $TestModel->find('all'));
2826
 
2827
		// SQLite seems to reset the PK counter when that happens, so we need this to make the tests pass
2828
		$this->db->truncate($TestModel);
2829
 
2830
		$TestModel->saveAll(array(
2831
			array(
2832
				'title' => 'Multi-record post 1',
2833
				'body' => 'First multi-record post',
2834
				'author_id' => 2
2835
			),
2836
			array(
2837
				'title' => 'Multi-record post 2',
2838
				'body' => 'Second multi-record post',
2839
				'author_id' => 2
2840
		)));
2841
 
2842
		$result = $TestModel->find('all', array(
2843
			'recursive' => -1,
2844
			'order' => 'Post.id ASC'
2845
		));
2846
		$expected = array(
2847
			array(
2848
				'Post' => array(
2849
					'id' => '1',
2850
					'author_id' => '2',
2851
					'title' => 'Multi-record post 1',
2852
					'body' => 'First multi-record post',
2853
					'published' => 'N'
2854
			)),
2855
			array(
2856
				'Post' => array(
2857
					'id' => '2',
2858
					'author_id' => '2',
2859
					'title' => 'Multi-record post 2',
2860
					'body' => 'Second multi-record post',
2861
					'published' => 'N'
2862
		)));
2863
		$this->assertEquals(self::date(), $result[0]['Post']['created']);
2864
		$this->assertEquals(self::date(), $result[0]['Post']['updated']);
2865
		$this->assertEquals(self::date(), $result[1]['Post']['created']);
2866
		$this->assertEquals(self::date(), $result[1]['Post']['updated']);
2867
		unset($result[0]['Post']['created'], $result[0]['Post']['updated']);
2868
		unset($result[1]['Post']['created'], $result[1]['Post']['updated']);
2869
		$this->assertEquals($expected, $result);
2870
 
2871
		$TestModel = new Comment();
2872
		$result = $TestModel->saveAll(array(
2873
			'Comment' => array(
2874
				'article_id' => 2,
2875
				'user_id' => 2,
2876
				'comment' => 'New comment with attachment',
2877
				'published' => 'Y'
2878
			),
2879
			'Attachment' => array(
2880
				'attachment' => 'some_file.tgz'
2881
			)));
2882
		$this->assertFalse(empty($result));
2883
 
2884
		$result = $TestModel->find('all');
2885
		$expected = array(
2886
			'id' => '7',
2887
			'article_id' => '2',
2888
			'user_id' => '2',
2889
			'comment' => 'New comment with attachment',
2890
			'published' => 'Y'
2891
		);
2892
		$this->assertEquals(self::date(), $result[6]['Comment']['created']);
2893
		$this->assertEquals(self::date(), $result[6]['Comment']['updated']);
2894
		unset($result[6]['Comment']['created'], $result[6]['Comment']['updated']);
2895
		$this->assertEquals($expected, $result[6]['Comment']);
2896
 
2897
		$expected = array(
2898
			'id' => '2',
2899
			'comment_id' => '7',
2900
			'attachment' => 'some_file.tgz'
2901
		);
2902
		$this->assertEquals(self::date(), $result[6]['Attachment']['created']);
2903
		$this->assertEquals(self::date(), $result[6]['Attachment']['updated']);
2904
		unset($result[6]['Attachment']['created'], $result[6]['Attachment']['updated']);
2905
		$this->assertEquals($expected, $result[6]['Attachment']);
2906
	}
2907
 
2908
/**
2909
 * Test SaveAll with Habtm relations
2910
 *
2911
 * @return void
2912
 */
2913
	public function testSaveAllHabtm() {
2914
		$this->loadFixtures('Article', 'Tag', 'Comment', 'User', 'ArticlesTag');
2915
		$data = array(
2916
			'Article' => array(
2917
				'user_id' => 1,
2918
				'title' => 'Article Has and belongs to Many Tags'
2919
			),
2920
			'Tag' => array(
2921
				'Tag' => array(1, 2)
2922
			),
2923
			'Comment' => array(
2924
				array(
2925
					'comment' => 'Article comment',
2926
					'user_id' => 1
2927
		)));
2928
		$Article = new Article();
2929
		$result = $Article->saveAll($data);
2930
		$this->assertFalse(empty($result));
2931
 
2932
		$result = $Article->read();
2933
		$this->assertEquals(2, count($result['Tag']));
2934
		$this->assertEquals('tag1', $result['Tag'][0]['tag']);
2935
		$this->assertEquals(1, count($result['Comment']));
2936
		$this->assertEquals(1, count($result['Comment'][0]['comment']));
2937
	}
2938
 
2939
/**
2940
 * Test SaveAll with Habtm relations and extra join table fields
2941
 *
2942
 * @return void
2943
 */
2944
	public function testSaveAllHabtmWithExtraJoinTableFields() {
2945
		$this->loadFixtures('Something', 'SomethingElse', 'JoinThing');
2946
 
2947
		$data = array(
2948
			'Something' => array(
2949
				'id' => 4,
2950
				'title' => 'Extra Fields',
2951
				'body' => 'Extra Fields Body',
2952
				'published' => '1'
2953
			),
2954
			'SomethingElse' => array(
2955
				array('something_else_id' => 1, 'doomed' => '1'),
2956
				array('something_else_id' => 2, 'doomed' => '0'),
2957
				array('something_else_id' => 3, 'doomed' => '1')
2958
			)
2959
		);
2960
 
2961
		$Something = new Something();
2962
		$result = $Something->saveAll($data);
2963
		$this->assertFalse(empty($result));
2964
		$result = $Something->read();
2965
 
2966
		$this->assertEquals(3, count($result['SomethingElse']));
2967
		$this->assertTrue(Set::matches('/Something[id=4]', $result));
2968
 
2969
		$this->assertTrue(Set::matches('/SomethingElse[id=1]', $result));
2970
		$this->assertTrue(Set::matches('/SomethingElse[id=1]/JoinThing[something_else_id=1]', $result));
2971
		$this->assertTrue(Set::matches('/SomethingElse[id=1]/JoinThing[doomed=1]', $result));
2972
 
2973
		$this->assertTrue(Set::matches('/SomethingElse[id=2]', $result));
2974
		$this->assertTrue(Set::matches('/SomethingElse[id=2]/JoinThing[something_else_id=2]', $result));
2975
		$this->assertTrue(Set::matches('/SomethingElse[id=2]/JoinThing[doomed=0]', $result));
2976
 
2977
		$this->assertTrue(Set::matches('/SomethingElse[id=3]', $result));
2978
		$this->assertTrue(Set::matches('/SomethingElse[id=3]/JoinThing[something_else_id=3]', $result));
2979
		$this->assertTrue(Set::matches('/SomethingElse[id=3]/JoinThing[doomed=1]', $result));
2980
	}
2981
 
2982
/**
2983
 * testSaveAllHasOne method
2984
 *
2985
 * @return void
2986
 */
2987
	public function testSaveAllHasOne() {
2988
		$model = new Comment();
2989
		$model->deleteAll(true);
2990
		$this->assertEquals(array(), $model->find('all'));
2991
 
2992
		$model->Attachment->deleteAll(true);
2993
		$this->assertEquals(array(), $model->Attachment->find('all'));
2994
 
2995
		$this->assertTrue($model->saveAll(array(
2996
			'Comment' => array(
2997
				'comment' => 'Comment with attachment',
2998
				'article_id' => 1,
2999
				'user_id' => 1
3000
			),
3001
			'Attachment' => array(
3002
				'attachment' => 'some_file.zip'
3003
		))));
3004
		$result = $model->find('all', array('fields' => array(
3005
			'Comment.id', 'Comment.comment', 'Attachment.id',
3006
			'Attachment.comment_id', 'Attachment.attachment'
3007
		)));
3008
		$expected = array(array(
3009
			'Comment' => array(
3010
				'id' => '1',
3011
				'comment' => 'Comment with attachment'
3012
			),
3013
			'Attachment' => array(
3014
				'id' => '1',
3015
				'comment_id' => '1',
3016
				'attachment' => 'some_file.zip'
3017
		)));
3018
		$this->assertEquals($expected, $result);
3019
 
3020
		$model->Attachment->bindModel(array('belongsTo' => array('Comment')), false);
3021
		$data = array(
3022
			'Comment' => array(
3023
				'comment' => 'Comment with attachment',
3024
				'article_id' => 1,
3025
				'user_id' => 1
3026
			),
3027
			'Attachment' => array(
3028
				'attachment' => 'some_file.zip'
3029
		));
3030
		$this->assertTrue($model->saveAll($data, array('validate' => 'first')));
3031
	}
3032
 
3033
/**
3034
 * testSaveAllBelongsTo method
3035
 *
3036
 * @return void
3037
 */
3038
	public function testSaveAllBelongsTo() {
3039
		$model = new Comment();
3040
		$model->deleteAll(true);
3041
		$this->assertEquals(array(), $model->find('all'));
3042
 
3043
		$model->Article->deleteAll(true);
3044
		$this->assertEquals(array(), $model->Article->find('all'));
3045
 
3046
		$this->assertTrue($model->saveAll(array(
3047
			'Comment' => array(
3048
				'comment' => 'Article comment',
3049
				'article_id' => 1,
3050
				'user_id' => 1
3051
			),
3052
			'Article' => array(
3053
				'title' => 'Model Associations 101',
3054
				'user_id' => 1
3055
		))));
3056
		$result = $model->find('all', array('fields' => array(
3057
			'Comment.id', 'Comment.comment', 'Comment.article_id', 'Article.id', 'Article.title'
3058
		)));
3059
		$expected = array(array(
3060
			'Comment' => array(
3061
				'id' => '1',
3062
				'article_id' => '1',
3063
				'comment' => 'Article comment'
3064
			),
3065
			'Article' => array(
3066
				'id' => '1',
3067
				'title' => 'Model Associations 101'
3068
		)));
3069
		$this->assertEquals($expected, $result);
3070
	}
3071
 
3072
/**
3073
 * testSaveAllHasOneValidation method
3074
 *
3075
 * @return void
3076
 */
3077
	public function testSaveAllHasOneValidation() {
3078
		$model = new Comment();
3079
		$model->deleteAll(true);
3080
		$this->assertEquals(array(), $model->find('all'));
3081
 
3082
		$model->Attachment->deleteAll(true);
3083
		$this->assertEquals(array(), $model->Attachment->find('all'));
3084
 
3085
		$model->validate = array('comment' => 'notEmpty');
3086
		$model->Attachment->validate = array('attachment' => 'notEmpty');
3087
		$model->Attachment->bindModel(array('belongsTo' => array('Comment')));
3088
 
3089
		$result = $model->saveAll(
3090
			array(
3091
				'Comment' => array(
3092
					'comment' => '',
3093
					'article_id' => 1,
3094
					'user_id' => 1
3095
				),
3096
				'Attachment' => array('attachment' => '')
3097
			),
3098
			array('validate' => 'first')
3099
		);
3100
		$this->assertEquals(false, $result);
3101
		$expected = array(
3102
			'comment' => array('This field cannot be left blank'),
3103
			'Attachment' => array(
3104
				'attachment' => array('This field cannot be left blank')
3105
			)
3106
		);
3107
		$this->assertEquals($expected, $model->validationErrors);
3108
		$this->assertEquals($expected['Attachment'], $model->Attachment->validationErrors);
3109
	}
3110
 
3111
/**
3112
 * testSaveAllAtomic method
3113
 *
3114
 * @return void
3115
 */
3116
	public function testSaveAllAtomic() {
3117
		$this->loadFixtures('Article', 'User', 'Comment');
3118
		$TestModel = new Article();
3119
 
3120
		$result = $TestModel->saveAll(array(
3121
			'Article' => array(
3122
				'title' => 'Post with Author',
3123
				'body' => 'This post will be saved with an author',
3124
				'user_id' => 2
3125
			),
3126
			'Comment' => array(
3127
				array('comment' => 'First new comment', 'user_id' => 2))
3128
		), array('atomic' => false));
3129
 
3130
		$this->assertSame($result, array('Article' => true, 'Comment' => array(true)));
3131
 
3132
		$result = $TestModel->saveAll(array(
3133
			array(
3134
				'id' => '1',
3135
				'title' => 'Baleeted First Post',
3136
				'body' => 'Baleeted!',
3137
				'published' => 'N'
3138
			),
3139
			array(
3140
				'id' => '2',
3141
				'title' => 'Just update the title'
3142
			),
3143
			array(
3144
				'title' => 'Creating a fourth post',
3145
				'body' => 'Fourth post body',
3146
				'user_id' => 2
3147
			)
3148
		), array('atomic' => false));
3149
		$this->assertSame($result, array(true, true, true));
3150
 
3151
		$result = $TestModel->saveAll(array(
3152
			'Article' => array('id' => 2),
3153
			'Comment' => array(
3154
				array(
3155
					'comment' => 'First new comment',
3156
					'published' => 'Y',
3157
					'user_id' => 1
3158
				),
3159
				array(
3160
					'comment' => 'Second new comment',
3161
					'published' => 'Y',
3162
					'user_id' => 2
3163
			))
3164
		), array('validate' => true, 'atomic' => false));
3165
		$this->assertSame($result, array('Article' => true, 'Comment' => array(true, true)));
3166
 
3167
		$TestModel->validate = array(
3168
			'title' => 'notEmpty',
3169
			'author_id' => 'numeric'
3170
		);
3171
		$result = $TestModel->saveAll(array(
3172
			array(
3173
				'id' => '1',
3174
				'title' => 'Un-Baleeted First Post',
3175
				'body' => 'Not Baleeted!',
3176
				'published' => 'Y'
3177
			),
3178
			array(
3179
				'id' => '2',
3180
				'title' => '',
3181
				'body' => 'Trying to get away with an empty title'
3182
			)
3183
		), array('validate' => true, 'atomic' => false));
3184
		$this->assertSame(array(true, false), $result);
3185
	}
3186
 
3187
/**
3188
 * testSaveAllDeepAssociated method
3189
 *
3190
 * @return void
3191
 */
3192
	public function testSaveAllDeepAssociated() {
3193
		$this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
3194
		$TestModel = new Article();
3195
		$TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
3196
		$TestModel->hasAndBelongsToMany = array();
3197
 
3198
		$result = $TestModel->saveAll(array(
3199
			'Article' => array('id' => 2),
3200
			'Comment' => array(
3201
				array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => 'newuser', 'password' => 'newuserpass')),
3202
				array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
3203
			)
3204
		), array('deep' => true));
3205
		$this->assertTrue($result);
3206
 
3207
		$result = $TestModel->findById(2);
3208
		$expected = array(
3209
			'First Comment for Second Article',
3210
			'Second Comment for Second Article',
3211
			'First new comment',
3212
			'Second new comment'
3213
		);
3214
		$result = Hash::extract(Hash::sort($result['Comment'], '{n}.id', 'ASC'), '{n}.comment');
3215
		$this->assertEquals($expected, $result);
3216
 
3217
		$result = $TestModel->Comment->User->field('id', array('user' => 'newuser', 'password' => 'newuserpass'));
3218
		$this->assertEquals(5, $result);
3219
		$result = $TestModel->saveAll(array(
3220
			'Article' => array('id' => 2),
3221
			'Comment' => array(
3222
				array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
3223
				array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => 'deepsaved'))
3224
			)
3225
		), array('deep' => true));
3226
		$this->assertTrue($result);
3227
 
3228
		$result = $TestModel->findById(2);
3229
		$expected = array(
3230
			'First Comment for Second Article',
3231
			'Second Comment for Second Article',
3232
			'First new comment',
3233
			'Second new comment',
3234
			'Third new comment',
3235
			'Fourth new comment'
3236
		);
3237
		$result = Hash::extract(Hash::sort($result['Comment'], '{n}.id', 'ASC'), '{n}.comment');
3238
		$this->assertEquals($expected, $result);
3239
 
3240
		$result = $TestModel->Comment->Attachment->field('id', array('attachment' => 'deepsaved'));
3241
		$this->assertEquals(2, $result);
3242
		$data = array(
3243
			'Attachment' => array(
3244
				'attachment' => 'deepsave insert',
3245
			),
3246
			'Comment' => array(
3247
				'comment' => 'First comment deepsave insert',
3248
				'published' => 'Y',
3249
				'user_id' => 5,
3250
				'Article' => array(
3251
					'title' => 'First Article deepsave insert',
3252
					'body' => 'First Article Body deepsave insert',
3253
					'User' => array(
3254
						'user' => '',
3255
						'password' => 'magic'
3256
					),
3257
				),
3258
			)
3259
		);
3260
 
3261
		$TestModel->Comment->Attachment->create();
3262
		$result = $TestModel->Comment->Attachment->saveAll($data, array('deep' => true));
3263
		$this->assertFalse($result);
3264
 
3265
		$expected = array('User' => array('user' => array('This field cannot be left blank')));
3266
		$this->assertEquals($expected, $TestModel->validationErrors);
3267
 
3268
		$data['Comment']['Article']['User']['user'] = 'deepsave';
3269
		$TestModel->Comment->Attachment->create();
3270
		$result = $TestModel->Comment->Attachment->saveAll($data, array('deep' => true));
3271
		$this->assertTrue($result);
3272
 
3273
		$result = $TestModel->Comment->Attachment->findById($TestModel->Comment->Attachment->id);
3274
		$expected = array(
3275
			'Attachment' => array(
3276
				'id' => '3',
3277
				'comment_id' => '11',
3278
				'attachment' => 'deepsave insert',
3279
			),
3280
			'Comment' => array(
3281
				'id' => '11',
3282
				'article_id' => '4',
3283
				'user_id' => '5',
3284
				'comment' => 'First comment deepsave insert',
3285
				'published' => 'Y',
3286
			)
3287
		);
3288
		unset($result['Attachment']['created'], $result['Attachment']['updated']);
3289
		$this->assertEquals($expected['Attachment'], $result['Attachment']);
3290
 
3291
		unset($result['Comment']['created'], $result['Comment']['updated']);
3292
		$this->assertEquals($expected['Comment'], $result['Comment']);
3293
 
3294
		$result = $TestModel->findById($result['Comment']['article_id']);
3295
		$expected = array(
3296
			'Article' => array(
3297
				'id' => '4',
3298
				'user_id' => '6',
3299
				'title' => 'First Article deepsave insert',
3300
				'body' => 'First Article Body deepsave insert',
3301
				'published' => 'N',
3302
			),
3303
			'User' => array(
3304
				'id' => '6',
3305
				'user' => 'deepsave',
3306
				'password' => 'magic',
3307
			),
3308
			'Comment' => array(
3309
				array(
3310
					'id' => '11',
3311
					'article_id' => '4',
3312
					'user_id' => '5',
3313
					'comment' => 'First comment deepsave insert',
3314
					'published' => 'Y',
3315
				)
3316
			)
3317
		);
3318
		unset(
3319
			$result['Article']['created'], $result['Article']['updated'],
3320
			$result['User']['created'], $result['User']['updated'],
3321
			$result['Comment'][0]['created'], $result['Comment'][0]['updated']
3322
		);
3323
		$this->assertEquals($expected, $result);
3324
	}
3325
 
3326
/**
3327
 * testSaveAllDeepMany
3328
 * tests the validate methods with deeper recursive data
3329
 *
3330
 * @return void
3331
 */
3332
	public function testSaveAllDeepMany() {
3333
		$this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
3334
		$TestModel = new Article();
3335
		$TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
3336
		$TestModel->hasAndBelongsToMany = array();
3337
 
3338
		$data = array(
3339
			array(
3340
				'Article' => array('id' => 1),
3341
				'Comment' => array(
3342
					array('comment' => 'First comment deepsaved article 1', 'published' => 'Y', 'User' => array('user' => 'savemany', 'password' => 'manysaved')),
3343
					array('comment' => 'Second comment deepsaved article 1', 'published' => 'Y', 'user_id' => 2)
3344
				)
3345
			),
3346
			array(
3347
				'Article' => array('id' => 2),
3348
				'Comment' => array(
3349
					array('comment' => 'First comment deepsaved article 2', 'published' => 'Y', 'User' => array('user' => 'savemore', 'password' => 'moresaved')),
3350
					array('comment' => 'Second comment deepsaved article 2', 'published' => 'Y', 'user_id' => 2)
3351
				)
3352
			)
3353
		);
3354
		$result = $TestModel->saveAll($data, array('deep' => true));
3355
		$this->assertTrue($result);
3356
 
3357
		$data = array(
3358
			array(
3359
				'id' => 1, 'body' => '',
3360
				'Comment' => array(
3361
					array('comment' => '', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'manysaved')),
3362
					array('comment' => 'Second comment deepsaved article 1', 'published' => 'Y', 'user_id' => 2)
3363
				)
3364
			),
3365
			array(
3366
				'Article' => array('id' => 2),
3367
				'Comment' => array(
3368
					array('comment' => 'First comment deepsaved article 2', 'published' => 'Y', 'User' => array('user' => 'savemore', 'password' => '')),
3369
					array('comment' => '', 'published' => 'Y', 'user_id' => 2)
3370
				)
3371
			)
3372
		);
3373
		$TestModel->Comment->validate['comment'] = 'notEmpty';
3374
		$result = $TestModel->saveAll($data, array('deep' => true));
3375
		$this->assertFalse($result);
3376
 
3377
		$expected = array(
3378
 
3379
				'body' => array('This field cannot be left blank'),
3380
				'Comment' => array(
3381
 
3382
						'comment' => array('This field cannot be left blank'),
3383
						'User' => array(
3384
							'user' => array('This field cannot be left blank')
3385
						)
3386
					)
3387
				)
3388
			),
3389
			1 => array(
3390
				'Comment' => array(
3391
 
3392
						'User' => array(
3393
							'password' => array('This field cannot be left blank')
3394
						)
3395
					),
3396
					1 => array(
3397
						'comment' => array('This field cannot be left blank')
3398
					)
3399
				)
3400
			)
3401
		);
3402
		$result = $TestModel->validationErrors;
3403
		$this->assertSame($expected, $result);
3404
	}
3405
/**
3406
 * testSaveAllDeepValidateOnly
3407
 * tests the validate methods with deeper recursive data
3408
 *
3409
 * @return void
3410
 */
3411
	public function testSaveAllDeepValidateOnly() {
3412
		$this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
3413
		$TestModel = new Article();
3414
		$TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
3415
		$TestModel->hasAndBelongsToMany = array();
3416
		$TestModel->Comment->Attachment->validate['attachment'] = 'notEmpty';
3417
		$TestModel->Comment->validate['comment'] = 'notEmpty';
3418
 
3419
		$result = $TestModel->saveAll(
3420
			array(
3421
				'Article' => array('id' => 2),
3422
				'Comment' => array(
3423
					array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => 'newuser', 'password' => 'newuserpass')),
3424
					array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
3425
				)
3426
			),
3427
			array('validate' => 'only', 'deep' => true)
3428
		);
3429
		$this->assertTrue($result);
3430
 
3431
		$result = $TestModel->saveAll(
3432
			array(
3433
				'Article' => array('id' => 2),
3434
				'Comment' => array(
3435
					array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
3436
					array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
3437
				)
3438
			),
3439
			array('validate' => 'only', 'deep' => true)
3440
		);
3441
		$this->assertFalse($result);
3442
 
3443
		$result = $TestModel->saveAll(
3444
			array(
3445
				'Article' => array('id' => 2),
3446
				'Comment' => array(
3447
					array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => 'newuser', 'password' => 'newuserpass')),
3448
					array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
3449
				)
3450
			),
3451
			array('validate' => 'only', 'atomic' => false, 'deep' => true)
3452
		);
3453
		$expected = array(
3454
			'Article' => true,
3455
			'Comment' => array(
3456
				true,
3457
				true
3458
			)
3459
		);
3460
		$this->assertSame($expected, $result);
3461
 
3462
		$result = $TestModel->saveAll(
3463
			array(
3464
				'Article' => array('id' => 2),
3465
				'Comment' => array(
3466
					array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
3467
					array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
3468
				)
3469
			),
3470
			array('validate' => 'only', 'atomic' => false, 'deep' => true)
3471
		);
3472
		$expected = array(
3473
			'Article' => true,
3474
			'Comment' => array(
3475
				false,
3476
				true
3477
			)
3478
		);
3479
		$this->assertSame($expected, $result);
3480
 
3481
		$result = $TestModel->saveAll(array(
3482
			'Article' => array('id' => 2),
3483
			'Comment' => array(
3484
				array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
3485
				array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => 'deepsaved'))
3486
			)
3487
		),
3488
		array('validate' => 'only', 'deep' => true)
3489
		);
3490
		$this->assertTrue($result);
3491
 
3492
		$result = $TestModel->saveAll(array(
3493
			'Article' => array('id' => 2),
3494
			'Comment' => array(
3495
				array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
3496
				array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
3497
			)
3498
		),
3499
		array('validate' => 'only', 'deep' => true)
3500
		);
3501
		$this->assertFalse($result);
3502
 
3503
		$result = $TestModel->saveAll(array(
3504
			'Article' => array('id' => 2),
3505
			'Comment' => array(
3506
				array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
3507
				array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => 'deepsave'))
3508
			)
3509
		),
3510
		array('validate' => 'only', 'atomic' => false, 'deep' => true)
3511
		);
3512
		$expected = array(
3513
			'Article' => true,
3514
			'Comment' => array(
3515
				true,
3516
				true
3517
			)
3518
		);
3519
		$this->assertSame($expected, $result);
3520
 
3521
		$result = $TestModel->saveAll(array(
3522
			'Article' => array('id' => 2),
3523
			'Comment' => array(
3524
				array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
3525
				array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
3526
			)
3527
		),
3528
		array('validate' => 'only', 'atomic' => false, 'deep' => true)
3529
		);
3530
		$expected = array(
3531
			'Article' => true,
3532
			'Comment' => array(
3533
				true,
3534
				false
3535
			)
3536
		);
3537
		$this->assertSame($expected, $result);
3538
 
3539
		$expected = array(
3540
			'Comment' => array(
3541
				1 => array(
3542
					'Attachment' => array(
3543
						'attachment' => array('This field cannot be left blank')
3544
					)
3545
				)
3546
			)
3547
		);
3548
		$result = $TestModel->validationErrors;
3549
		$this->assertSame($expected, $result);
3550
 
3551
		$data = array(
3552
			'Attachment' => array(
3553
				'attachment' => 'deepsave insert',
3554
			),
3555
			'Comment' => array(
3556
				'comment' => 'First comment deepsave insert',
3557
				'published' => 'Y',
3558
				'user_id' => 5,
3559
				'Article' => array(
3560
					'title' => 'First Article deepsave insert',
3561
					'body' => 'First Article Body deepsave insert',
3562
					'User' => array(
3563
						'user' => 'deepsave',
3564
						'password' => 'magic'
3565
					),
3566
				),
3567
			)
3568
		);
3569
 
3570
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
3571
		$this->assertTrue($result);
3572
 
3573
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
3574
		$expected = array(
3575
			'Attachment' => true,
3576
			'Comment' => true
3577
		);
3578
		$this->assertSame($expected, $result);
3579
 
3580
		$data = array(
3581
			'Attachment' => array(
3582
				'attachment' => 'deepsave insert',
3583
			),
3584
			'Comment' => array(
3585
				'comment' => 'First comment deepsave insert',
3586
				'published' => 'Y',
3587
				'user_id' => 5,
3588
				'Article' => array(
3589
					'title' => 'First Article deepsave insert',
3590
					'body' => 'First Article Body deepsave insert',
3591
					'User' => array(
3592
						'user' => '',
3593
						'password' => 'magic'
3594
					),
3595
				),
3596
			)
3597
		);
3598
 
3599
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
3600
		$this->assertFalse($result);
3601
 
3602
		$result = $TestModel->Comment->Attachment->validationErrors;
3603
		$expected = array(
3604
			'Comment' => array(
3605
				'Article' => array(
3606
					'User' => array(
3607
						'user' => array('This field cannot be left blank')
3608
					)
3609
				)
3610
			)
3611
		);
3612
		$this->assertSame($expected, $result);
3613
 
3614
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
3615
		$expected = array(
3616
			'Attachment' => true,
3617
			'Comment' => false
3618
		);
3619
		$this->assertEquals($expected, $result);
3620
 
3621
		$data['Comment']['Article']['body'] = '';
3622
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
3623
		$this->assertFalse($result);
3624
 
3625
		$result = $TestModel->Comment->Attachment->validationErrors;
3626
		$expected = array(
3627
			'Comment' => array(
3628
				'Article' => array(
3629
					'body' => array('This field cannot be left blank'),
3630
					'User' => array(
3631
						'user' => array('This field cannot be left blank')
3632
					)
3633
				)
3634
			)
3635
		);
3636
		$this->assertSame($expected, $result);
3637
 
3638
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
3639
		$expected = array(
3640
			'Attachment' => true,
3641
			'Comment' => false
3642
		);
3643
		$this->assertEquals($expected, $result);
3644
 
3645
		$data['Comment']['comment'] = '';
3646
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
3647
		$this->assertFalse($result);
3648
 
3649
		$result = $TestModel->Comment->Attachment->validationErrors;
3650
		$expected = array(
3651
			'Comment' => array(
3652
				'comment' => array('This field cannot be left blank'),
3653
				'Article' => array(
3654
					'body' => array('This field cannot be left blank'),
3655
					'User' => array(
3656
						'user' => array('This field cannot be left blank')
3657
					)
3658
				)
3659
			)
3660
		);
3661
		$this->assertSame($expected, $result);
3662
 
3663
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
3664
		$expected = array(
3665
			'Attachment' => true,
3666
			'Comment' => false
3667
		);
3668
		$this->assertEquals($expected, $result);
3669
 
3670
		$data['Attachment']['attachment'] = '';
3671
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
3672
		$this->assertFalse($result);
3673
 
3674
		$result = $TestModel->Comment->Attachment->validationErrors;
3675
		$expected = array(
3676
			'attachment' => array('This field cannot be left blank'),
3677
			'Comment' => array(
3678
				'comment' => array('This field cannot be left blank'),
3679
				'Article' => array(
3680
					'body' => array('This field cannot be left blank'),
3681
					'User' => array(
3682
						'user' => array('This field cannot be left blank')
3683
					)
3684
				)
3685
			)
3686
		);
3687
		$this->assertSame($expected, $result);
3688
 
3689
		$result = $TestModel->Comment->validationErrors;
3690
		$expected = array(
3691
			'comment' => array('This field cannot be left blank'),
3692
			'Article' => array(
3693
				'body' => array('This field cannot be left blank'),
3694
				'User' => array(
3695
					'user' => array('This field cannot be left blank')
3696
				)
3697
			)
3698
		);
3699
		$this->assertSame($expected, $result);
3700
 
3701
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
3702
		$expected = array(
3703
			'Attachment' => false,
3704
			'Comment' => false
3705
		);
3706
		$this->assertEquals($expected, $result);
3707
	}
3708
 
3709
/**
3710
 * testSaveAllNotDeepAssociated method
3711
 * test that only directly associated data gets saved
3712
 *
3713
 * @return void
3714
 */
3715
	public function testSaveAllNotDeepAssociated() {
3716
		$this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
3717
		$TestModel = new Article();
3718
		$TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
3719
		$TestModel->hasAndBelongsToMany = array();
3720
 
3721
		$result = $TestModel->saveAll(array(
3722
			'Article' => array('id' => 2),
3723
			'Comment' => array(
3724
				array(
3725
					'comment' => 'First new comment', 'published' => 'Y', 'user_id' => 2,
3726
					'User' => array('user' => 'newuser', 'password' => 'newuserpass')
3727
				),
3728
				array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
3729
			)
3730
		), array('deep' => false));
3731
		$this->assertTrue($result);
3732
 
3733
		$result = $TestModel->Comment->User->field('id', array('user' => 'newuser', 'password' => 'newuserpass'));
3734
		$this->assertFalse($result);
3735
 
3736
		$result = $TestModel->saveAll(array(
3737
			'Article' => array('id' => 2),
3738
			'Comment' => array(
3739
				array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 4),
3740
				array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => 'deepsaved'))
3741
			)
3742
		), array('deep' => false));
3743
		$this->assertTrue($result);
3744
 
3745
		$result = $TestModel->Comment->Attachment->field('id', array('attachment' => 'deepsaved'));
3746
		$this->assertFalse($result);
3747
 
3748
		$data = array(
3749
			'Attachment' => array(
3750
				'attachment' => 'deepsave insert',
3751
			),
3752
			'Comment' => array(
3753
				'comment' => 'First comment deepsave insert',
3754
				'published' => 'Y',
3755
				'user_id' => 4,
3756
				'article_id' => 1,
3757
				'Article' => array(
3758
					'title' => 'First Article deepsave insert',
3759
					'body' => 'First Article Body deepsave insert',
3760
					'User' => array(
3761
						'user' => 'deepsave',
3762
						'password' => 'magic'
3763
					),
3764
				),
3765
			)
3766
		);
3767
		$expected = $TestModel->User->find('count');
3768
 
3769
		$TestModel->Comment->Attachment->create();
3770
		$result = $TestModel->Comment->Attachment->saveAll($data, array('deep' => false));
3771
		$this->assertTrue($result);
3772
 
3773
		$result = $TestModel->User->find('count');
3774
		$this->assertEquals($expected, $result);
3775
 
3776
		$result = $TestModel->Comment->Attachment->findById($TestModel->Comment->Attachment->id);
3777
		$expected = array(
3778
			'Attachment' => array(
3779
				'id' => '2',
3780
				'comment_id' => '11',
3781
				'attachment' => 'deepsave insert',
3782
			),
3783
			'Comment' => array(
3784
				'id' => '11',
3785
				'article_id' => 1,
3786
				'user_id' => '4',
3787
				'comment' => 'First comment deepsave insert',
3788
				'published' => 'Y',
3789
			)
3790
		);
3791
		unset($result['Attachment']['created'], $result['Attachment']['updated']);
3792
		$this->assertEquals($expected['Attachment'], $result['Attachment']);
3793
 
3794
		unset($result['Comment']['created'], $result['Comment']['updated']);
3795
		$this->assertEquals($expected['Comment'], $result['Comment']);
3796
	}
3797
 
3798
/**
3799
 * testSaveAllNotDeepMany
3800
 * tests the save methods to not save deeper recursive data
3801
 *
3802
 * @return void
3803
 */
3804
	public function testSaveAllNotDeepMany() {
3805
		$this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
3806
		$TestModel = new Article();
3807
		$TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
3808
		$TestModel->hasAndBelongsToMany = array();
3809
 
3810
		$data = array(
3811
			array(
3812
				'id' => 1,
3813
				'body' => '',
3814
				'Comment' => array(
3815
					array('comment' => '', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'manysaved')),
3816
					array('comment' => 'Second comment deepsaved article 1', 'published' => 'Y', 'user_id' => 2)
3817
				)
3818
			),
3819
			array(
3820
				'Article' => array('id' => 2),
3821
				'Comment' => array(
3822
					array('comment' => 'First comment deepsaved article 2', 'published' => 'Y', 'User' => array('user' => 'savemore', 'password' => '')),
3823
					array('comment' => '', 'published' => 'Y', 'user_id' => 2)
3824
				)
3825
			)
3826
		);
3827
		$TestModel->Comment->validate['comment'] = 'notEmpty';
3828
		$result = $TestModel->saveAll($data, array('deep' => false));
3829
		$this->assertFalse($result);
3830
 
3831
		$expected = array(
3832
 
3833
				'body' => array('This field cannot be left blank')
3834
			)
3835
		);
3836
		$result = $TestModel->validationErrors;
3837
		$this->assertSame($expected, $result);
3838
 
3839
		$data = array(
3840
			array(
3841
				'Article' => array('id' => 1, 'body' => 'Ignore invalid comment'),
3842
				'Comment' => array(
3843
					array('comment' => '', 'published' => 'Y', 'user_id' => 2)
3844
				)
3845
			),
3846
			array(
3847
				'Article' => array('id' => 2),
3848
				'Comment' => array(
3849
					array('comment' => '', 'published' => 'Y', 'user_id' => 2)
3850
				)
3851
			)
3852
		);
3853
		$result = $TestModel->saveAll($data, array('deep' => false));
3854
		$this->assertTrue($result);
3855
	}
3856
/**
3857
 * testSaveAllNotDeepValidateOnly
3858
 * tests the validate methods to not validate deeper recursive data
3859
 *
3860
 * @return void
3861
 */
3862
	public function testSaveAllNotDeepValidateOnly() {
3863
		$this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
3864
		$TestModel = new Article();
3865
		$TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
3866
		$TestModel->hasAndBelongsToMany = array();
3867
		$TestModel->Comment->Attachment->validate['attachment'] = 'notEmpty';
3868
		$TestModel->Comment->validate['comment'] = 'notEmpty';
3869
 
3870
		$result = $TestModel->saveAll(
3871
			array(
3872
				'Article' => array('id' => 2, 'body' => ''),
3873
				'Comment' => array(
3874
					array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
3875
					array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
3876
				)
3877
			),
3878
			array('validate' => 'only', 'deep' => false)
3879
		);
3880
		$this->assertFalse($result);
3881
 
3882
		$expected = array('body' => array('This field cannot be left blank'));
3883
		$result = $TestModel->validationErrors;
3884
		$this->assertSame($expected, $result);
3885
 
3886
		$result = $TestModel->saveAll(
3887
			array(
3888
				'Article' => array('id' => 2, 'body' => 'Ignore invalid user data'),
3889
				'Comment' => array(
3890
					array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
3891
					array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
3892
				)
3893
			),
3894
			array('validate' => 'only', 'deep' => false)
3895
		);
3896
		$this->assertTrue($result);
3897
 
3898
		$result = $TestModel->saveAll(
3899
			array(
3900
				'Article' => array('id' => 2, 'body' => 'Ignore invalid user data'),
3901
				'Comment' => array(
3902
					array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
3903
					array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
3904
				)
3905
			),
3906
			array('validate' => 'only', 'atomic' => false, 'deep' => false)
3907
		);
3908
		$expected = array(
3909
			'Article' => true,
3910
			'Comment' => array(
3911
				true,
3912
				true
3913
			)
3914
		);
3915
		$this->assertSame($expected, $result);
3916
 
3917
		$result = $TestModel->saveAll(array(
3918
			'Article' => array('id' => 2, 'body' => 'Ignore invalid attachment data'),
3919
			'Comment' => array(
3920
				array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
3921
				array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
3922
			)
3923
		),
3924
		array('validate' => 'only', 'deep' => false)
3925
		);
3926
		$this->assertTrue($result);
3927
 
3928
		$result = $TestModel->saveAll(array(
3929
			'Article' => array('id' => 2, 'body' => 'Ignore invalid attachment data'),
3930
			'Comment' => array(
3931
				array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
3932
				array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
3933
			)
3934
		),
3935
		array('validate' => 'only', 'atomic' => false, 'deep' => false)
3936
		);
3937
		$expected = array(
3938
			'Article' => true,
3939
			'Comment' => array(
3940
				true,
3941
				true
3942
			)
3943
		);
3944
		$this->assertSame($expected, $result);
3945
 
3946
		$expected = array();
3947
		$result = $TestModel->validationErrors;
3948
		$this->assertSame($expected, $result);
3949
 
3950
		$data = array(
3951
			'Attachment' => array(
3952
				'attachment' => 'deepsave insert',
3953
			),
3954
			'Comment' => array(
3955
				'comment' => 'First comment deepsave insert',
3956
				'published' => 'Y',
3957
				'user_id' => 5,
3958
				'Article' => array(
3959
					'title' => 'First Article deepsave insert ignored',
3960
					'body' => 'First Article Body deepsave insert',
3961
					'User' => array(
3962
						'user' => '',
3963
						'password' => 'magic'
3964
					),
3965
				),
3966
			)
3967
		);
3968
 
3969
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => false));
3970
		$this->assertTrue($result);
3971
 
3972
		$result = $TestModel->Comment->Attachment->validationErrors;
3973
		$expected = array();
3974
		$this->assertSame($expected, $result);
3975
 
3976
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => false));
3977
		$expected = array(
3978
			'Attachment' => true,
3979
			'Comment' => true
3980
		);
3981
		$this->assertEquals($expected, $result);
3982
 
3983
		$data['Comment']['Article']['body'] = '';
3984
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => false));
3985
		$this->assertTrue($result);
3986
 
3987
		$result = $TestModel->Comment->Attachment->validationErrors;
3988
		$expected = array();
3989
		$this->assertSame($expected, $result);
3990
 
3991
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => false));
3992
		$expected = array(
3993
			'Attachment' => true,
3994
			'Comment' => true
3995
		);
3996
		$this->assertEquals($expected, $result);
3997
	}
3998
 
3999
/**
4000
 * testSaveAllHasMany method
4001
 *
4002
 * @return void
4003
 */
4004
	public function testSaveAllHasMany() {
4005
		$this->loadFixtures('Article', 'Comment');
4006
		$TestModel = new Article();
4007
		$TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
4008
		$TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
4009
 
4010
		$result = $TestModel->saveAll(array(
4011
			'Article' => array('id' => 2),
4012
			'Comment' => array(
4013
				array('comment' => 'First new comment', 'published' => 'Y', 'user_id' => 1),
4014
				array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
4015
			)
4016
		));
4017
		$this->assertFalse(empty($result));
4018
 
4019
		$result = $TestModel->findById(2);
4020
		$expected = array(
4021
			'First Comment for Second Article',
4022
			'Second Comment for Second Article',
4023
			'First new comment',
4024
			'Second new comment'
4025
		);
4026
		$result = Hash::extract(Hash::sort($result['Comment'], '{n}.id', 'ASC'), '{n}.comment');
4027
		$this->assertEquals($expected, $result);
4028
 
4029
		$result = $TestModel->saveAll(
4030
			array(
4031
				'Article' => array('id' => 2),
4032
				'Comment' => array(
4033
					array(
4034
						'comment' => 'Third new comment',
4035
						'published' => 'Y',
4036
						'user_id' => 1
4037
			))),
4038
			array('atomic' => false)
4039
		);
4040
		$this->assertFalse(empty($result));
4041
 
4042
		$result = $TestModel->findById(2);
4043
		$expected = array(
4044
			'First Comment for Second Article',
4045
			'Second Comment for Second Article',
4046
			'First new comment',
4047
			'Second new comment',
4048
			'Third new comment'
4049
		);
4050
		$result = Hash::extract(Hash::sort($result['Comment'], '{n}.id', 'ASC'), '{n}.comment');
4051
		$this->assertEquals($expected, $result);
4052
 
4053
		$TestModel->beforeSaveReturn = false;
4054
		$result = $TestModel->saveAll(
4055
			array(
4056
				'Article' => array('id' => 2),
4057
				'Comment' => array(
4058
					array(
4059
						'comment' => 'Fourth new comment',
4060
						'published' => 'Y',
4061
						'user_id' => 1
4062
			))),
4063
			array('atomic' => false)
4064
		);
4065
		$this->assertEquals(array('Article' => false), $result);
4066
 
4067
		$result = $TestModel->findById(2);
4068
		$expected = array(
4069
			'First Comment for Second Article',
4070
			'Second Comment for Second Article',
4071
			'First new comment',
4072
			'Second new comment',
4073
			'Third new comment'
4074
		);
4075
		$result = Hash::extract(Hash::sort($result['Comment'], '{n}.id', 'ASC'), '{n}.comment');
4076
		$this->assertEquals($expected, $result);
4077
	}
4078
 
4079
/**
4080
 * testSaveAllHasManyValidation method
4081
 *
4082
 * @return void
4083
 */
4084
	public function testSaveAllHasManyValidation() {
4085
		$this->loadFixtures('Article', 'Comment');
4086
		$TestModel = new Article();
4087
		$TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
4088
		$TestModel->Comment->validate = array('comment' => 'notEmpty');
4089
 
4090
		$result = $TestModel->saveAll(array(
4091
			'Article' => array('id' => 2),
4092
			'Comment' => array(
4093
				array('comment' => '', 'published' => 'Y', 'user_id' => 1),
4094
			)
4095
		), array('validate' => true));
4096
		$this->assertFalse($result);
4097
 
4098
		$expected = array('Comment' => array(
4099
			array('comment' => array('This field cannot be left blank'))
4100
		));
4101
		$this->assertEquals($expected, $TestModel->validationErrors);
4102
		$expected = array(
4103
			array('comment' => array('This field cannot be left blank'))
4104
		);
4105
		$this->assertEquals($expected, $TestModel->Comment->validationErrors);
4106
 
4107
		$result = $TestModel->saveAll(array(
4108
			'Article' => array('id' => 2),
4109
			'Comment' => array(
4110
				array(
4111
					'comment' => '',
4112
					'published' => 'Y',
4113
					'user_id' => 1
4114
			))
4115
		), array('validate' => 'first'));
4116
		$this->assertFalse($result);
4117
	}
4118
 
4119
/**
4120
 * test saveAll with transactions and ensure there is no missing rollback.
4121
 *
4122
 * @return void
4123
 */
4124
	public function testSaveAllManyRowsTransactionNoRollback() {
4125
		$this->loadFixtures('Post');
4126
 
4127
		$db = $this->getMock('DboSource', array('begin', 'connect', 'rollback', 'describe'));
4128
 
4129
		$db->expects($this->once())
4130
			->method('describe')
4131
			->will($this->returnValue(array()));
4132
		$db->expects($this->once())->method('rollback');
4133
 
4134
		$Post = new TestPost();
4135
		$Post->setDataSourceObject($db);
4136
 
4137
		$Post->validate = array(
4138
			'title' => array('rule' => array('notEmpty'))
4139
		);
4140
 
4141
		$data = array(
4142
			array('author_id' => 1, 'title' => 'New Fourth Post'),
4143
			array('author_id' => 1, 'title' => '')
4144
		);
4145
		$Post->saveAll($data, array('atomic' => true, 'validate' => true));
4146
	}
4147
 
4148
/**
4149
 * test saveAll with transactions and ensure there is no missing rollback.
4150
 *
4151
 * @return void
4152
 */
4153
	public function testSaveAllAssociatedTransactionNoRollback() {
4154
		$testDb = ConnectionManager::getDataSource('test');
4155
 
4156
		$db = $this->getMock('DboSource', array('connect', 'rollback', 'describe', 'create', 'update', 'begin'));
4157
		$db->columns = $testDb->columns;
4158
 
4159
		$db->expects($this->once())->method('rollback');
4160
		$db->expects($this->any())->method('describe')
4161
			->will($this->returnValue(array(
4162
				'id' => array('type' => 'integer', 'length' => 11),
4163
				'title' => array('type' => 'string'),
4164
				'body' => array('type' => 'text'),
4165
				'published' => array('type' => 'string')
4166
			)));
4167
 
4168
		$Post = new TestPost();
4169
		$Post->setDataSourceObject($db);
4170
		$Post->Author->setDataSourceObject($db);
4171
 
4172
		$Post->Author->validate = array(
4173
			'user' => array('rule' => array('notEmpty'))
4174
		);
4175
 
4176
		$data = array(
4177
			'Post' => array(
4178
				'title' => 'New post',
4179
				'body' => 'Content',
4180
				'published' => 'Y'
4181
			),
4182
			'Author' => array(
4183
				'user' => '',
4184
				'password' => "sekret"
4185
			)
4186
		);
4187
		$Post->saveAll($data, array('validate' => true));
4188
	}
4189
 
4190
/**
4191
 * test saveAll with nested saveAll call.
4192
 *
4193
 * @return void
4194
 */
4195
	public function testSaveAllNestedSaveAll() {
4196
		$this->loadFixtures('Sample');
4197
		$TransactionTestModel = new TransactionTestModel();
4198
 
4199
		$data = array(
4200
			array('apple_id' => 1, 'name' => 'sample5'),
4201
		);
4202
 
4203
		$this->assertTrue($TransactionTestModel->saveAll($data, array('atomic' => true)));
4204
	}
4205
 
4206
/**
4207
 * testSaveAllTransaction method
4208
 *
4209
 * @return void
4210
 */
4211
	public function testSaveAllTransaction() {
4212
		$this->loadFixtures('Post', 'Author', 'Comment', 'Attachment');
4213
		$TestModel = new Post();
4214
 
4215
		$TestModel->validate = array('title' => 'notEmpty');
4216
		$data = array(
4217
			array('author_id' => 1, 'title' => 'New Fourth Post'),
4218
			array('author_id' => 1, 'title' => 'New Fifth Post'),
4219
			array('author_id' => 1, 'title' => '')
4220
		);
4221
		$this->assertFalse($TestModel->saveAll($data));
4222
 
4223
		$result = $TestModel->find('all', array('recursive' => -1));
4224
		$expected = array(
4225
			array('Post' => array(
4226
				'id' => '1',
4227
				'author_id' => 1,
4228
				'title' => 'First Post',
4229
				'body' => 'First Post Body',
4230
				'published' => 'Y',
4231
				'created' => '2007-03-18 10:39:23',
4232
				'updated' => '2007-03-18 10:41:31'
4233
			)),
4234
			array('Post' => array(
4235
				'id' => '2',
4236
				'author_id' => 3,
4237
				'title' => 'Second Post',
4238
				'body' => 'Second Post Body',
4239
				'published' => 'Y',
4240
				'created' => '2007-03-18 10:41:23',
4241
				'updated' => '2007-03-18 10:43:31'
4242
			)),
4243
			array('Post' => array(
4244
				'id' => '3',
4245
				'author_id' => 1,
4246
				'title' => 'Third Post',
4247
				'body' => 'Third Post Body',
4248
				'published' => 'Y',
4249
				'created' => '2007-03-18 10:43:23',
4250
				'updated' => '2007-03-18 10:45:31'
4251
		)));
4252
 
4253
		if (count($result) != 3) {
4254
			// Database doesn't support transactions
4255
			$expected[] = array(
4256
				'Post' => array(
4257
					'id' => '4',
4258
					'author_id' => 1,
4259
					'title' => 'New Fourth Post',
4260
					'body' => null,
4261
					'published' => 'N',
4262
					'created' => self::date(),
4263
					'updated' => self::date()
4264
			));
4265
 
4266
			$expected[] = array(
4267
				'Post' => array(
4268
					'id' => '5',
4269
					'author_id' => 1,
4270
					'title' => 'New Fifth Post',
4271
					'body' => null,
4272
					'published' => 'N',
4273
					'created' => self::date(),
4274
					'updated' => self::date()
4275
			));
4276
 
4277
			$this->assertEquals($expected, $result);
4278
			// Skip the rest of the transactional tests
4279
			return;
4280
		}
4281
 
4282
		$this->assertEquals($expected, $result);
4283
 
4284
		$data = array(
4285
			array('author_id' => 1, 'title' => 'New Fourth Post'),
4286
			array('author_id' => 1, 'title' => ''),
4287
			array('author_id' => 1, 'title' => 'New Sixth Post')
4288
		);
4289
		$this->assertFalse($TestModel->saveAll($data));
4290
 
4291
		$result = $TestModel->find('all', array('recursive' => -1));
4292
		$expected = array(
4293
			array('Post' => array(
4294
				'id' => '1',
4295
				'author_id' => 1,
4296
				'title' => 'First Post',
4297
				'body' => 'First Post Body',
4298
				'published' => 'Y',
4299
				'created' => '2007-03-18 10:39:23',
4300
				'updated' => '2007-03-18 10:41:31'
4301
			)),
4302
			array('Post' => array(
4303
				'id' => '2',
4304
				'author_id' => 3,
4305
				'title' => 'Second Post',
4306
				'body' => 'Second Post Body',
4307
				'published' => 'Y',
4308
				'created' => '2007-03-18 10:41:23',
4309
				'updated' => '2007-03-18 10:43:31'
4310
			)),
4311
			array('Post' => array(
4312
				'id' => '3',
4313
				'author_id' => 1,
4314
				'title' => 'Third Post',
4315
				'body' => 'Third Post Body',
4316
				'published' => 'Y',
4317
				'created' => '2007-03-18 10:43:23',
4318
				'updated' => '2007-03-18 10:45:31'
4319
		)));
4320
 
4321
		if (count($result) != 3) {
4322
			// Database doesn't support transactions
4323
			$expected[] = array(
4324
				'Post' => array(
4325
					'id' => '4',
4326
					'author_id' => 1,
4327
					'title' => 'New Fourth Post',
4328
					'body' => 'Third Post Body',
4329
					'published' => 'N',
4330
					'created' => self::date(),
4331
					'updated' => self::date()
4332
			));
4333
 
4334
			$expected[] = array(
4335
				'Post' => array(
4336
					'id' => '5',
4337
					'author_id' => 1,
4338
					'title' => 'Third Post',
4339
					'body' => 'Third Post Body',
4340
					'published' => 'N',
4341
					'created' => self::date(),
4342
					'updated' => self::date()
4343
			));
4344
		}
4345
		$this->assertEquals($expected, $result);
4346
 
4347
		$TestModel->validate = array('title' => 'notEmpty');
4348
		$data = array(
4349
			array('author_id' => 1, 'title' => 'New Fourth Post'),
4350
			array('author_id' => 1, 'title' => 'New Fifth Post'),
4351
			array('author_id' => 1, 'title' => 'New Sixth Post')
4352
		);
4353
		$this->assertTrue($TestModel->saveAll($data));
4354
 
4355
		$result = $TestModel->find('all', array(
4356
			'recursive' => -1,
4357
			'fields' => array('author_id', 'title', 'body', 'published'),
4358
			'order' => array('Post.created' => 'ASC')
4359
		));
4360
 
4361
		$expected = array(
4362
			array('Post' => array(
4363
				'author_id' => 1,
4364
				'title' => 'First Post',
4365
				'body' => 'First Post Body',
4366
				'published' => 'Y'
4367
			)),
4368
			array('Post' => array(
4369
				'author_id' => 3,
4370
				'title' => 'Second Post',
4371
				'body' => 'Second Post Body',
4372
				'published' => 'Y'
4373
			)),
4374
			array('Post' => array(
4375
				'author_id' => 1,
4376
				'title' => 'Third Post',
4377
				'body' => 'Third Post Body',
4378
				'published' => 'Y'
4379
			)),
4380
			array('Post' => array(
4381
				'author_id' => 1,
4382
				'title' => 'New Fourth Post',
4383
				'body' => '',
4384
				'published' => 'N'
4385
			)),
4386
			array('Post' => array(
4387
				'author_id' => 1,
4388
				'title' => 'New Fifth Post',
4389
				'body' => '',
4390
				'published' => 'N'
4391
			)),
4392
			array('Post' => array(
4393
				'author_id' => 1,
4394
				'title' => 'New Sixth Post',
4395
				'body' => '',
4396
				'published' => 'N'
4397
		)));
4398
		$this->assertEquals($expected, $result);
4399
	}
4400
 
4401
/**
4402
 * testSaveAllValidation method
4403
 *
4404
 * @return void
4405
 */
4406
	public function testSaveAllValidation() {
4407
		$this->loadFixtures('Post', 'Author', 'Comment', 'Attachment');
4408
		$TestModel = new Post();
4409
 
4410
		$data = array(
4411
			array(
4412
				'id' => '1',
4413
				'title' => 'Baleeted First Post',
4414
				'body' => 'Baleeted!',
4415
				'published' => 'N'
4416
			),
4417
			array(
4418
				'id' => '2',
4419
				'title' => 'Just update the title'
4420
			),
4421
			array(
4422
				'title' => 'Creating a fourth post',
4423
				'body' => 'Fourth post body',
4424
				'author_id' => 2
4425
		));
4426
 
4427
		$this->assertTrue($TestModel->saveAll($data));
4428
 
4429
		$result = $TestModel->find('all', array('recursive' => -1, 'order' => 'Post.id ASC'));
4430
		$expected = array(
4431
			array(
4432
				'Post' => array(
4433
					'id' => '1',
4434
					'author_id' => '1',
4435
					'title' => 'Baleeted First Post',
4436
					'body' => 'Baleeted!',
4437
					'published' => 'N',
4438
					'created' => '2007-03-18 10:39:23'
4439
			)),
4440
			array(
4441
				'Post' => array(
4442
					'id' => '2',
4443
					'author_id' => '3',
4444
					'title' => 'Just update the title',
4445
					'body' => 'Second Post Body',
4446
					'published' => 'Y',
4447
					'created' => '2007-03-18 10:41:23'
4448
			)),
4449
			array(
4450
				'Post' => array(
4451
					'id' => '3',
4452
					'author_id' => '1',
4453
					'title' => 'Third Post',
4454
					'body' => 'Third Post Body',
4455
					'published' => 'Y',
4456
					'created' => '2007-03-18 10:43:23',
4457
					'updated' => '2007-03-18 10:45:31'
4458
			)),
4459
			array(
4460
				'Post' => array(
4461
					'id' => '4',
4462
					'author_id' => '2',
4463
					'title' => 'Creating a fourth post',
4464
					'body' => 'Fourth post body',
4465
					'published' => 'N'
4466
		)));
4467
		$this->assertEquals(self::date(), $result[0]['Post']['updated']);
4468
		$this->assertEquals(self::date(), $result[1]['Post']['updated']);
4469
		$this->assertEquals(self::date(), $result[3]['Post']['created']);
4470
		$this->assertEquals(self::date(), $result[3]['Post']['updated']);
4471
		unset($result[0]['Post']['updated'], $result[1]['Post']['updated']);
4472
		unset($result[3]['Post']['created'], $result[3]['Post']['updated']);
4473
		$this->assertEquals($expected, $result);
4474
 
4475
		$TestModel->validate = array('title' => 'notEmpty', 'author_id' => 'numeric');
4476
		$data = array(
4477
			array(
4478
				'id' => '1',
4479
				'title' => 'Un-Baleeted First Post',
4480
				'body' => 'Not Baleeted!',
4481
				'published' => 'Y'
4482
			),
4483
			array(
4484
				'id' => '2',
4485
				'title' => '',
4486
				'body' => 'Trying to get away with an empty title'
4487
		));
4488
		$result = $TestModel->saveAll($data);
4489
		$this->assertFalse($result);
4490
 
4491
		$result = $TestModel->find('all', array('recursive' => -1, 'order' => 'Post.id ASC'));
4492
		$errors = array(1 => array('title' => array('This field cannot be left blank')));
4493
		$transactionWorked = Set::matches('/Post[1][title=Baleeted First Post]', $result);
4494
		if (!$transactionWorked) {
4495
			$this->assertTrue(Set::matches('/Post[1][title=Un-Baleeted First Post]', $result));
4496
			$this->assertTrue(Set::matches('/Post[2][title=Just update the title]', $result));
4497
		}
4498
 
4499
		$this->assertEquals($errors, $TestModel->validationErrors);
4500
 
4501
		$TestModel->validate = array('title' => 'notEmpty', 'author_id' => 'numeric');
4502
		$data = array(
4503
			array(
4504
				'id' => '1',
4505
				'title' => 'Un-Baleeted First Post',
4506
				'body' => 'Not Baleeted!',
4507
				'published' => 'Y'
4508
			),
4509
			array(
4510
				'id' => '2',
4511
				'title' => '',
4512
				'body' => 'Trying to get away with an empty title'
4513
		));
4514
		$result = $TestModel->saveAll($data, array('validate' => true, 'atomic' => false));
4515
		$this->assertEquals(array(true, false), $result);
4516
		$result = $TestModel->find('all', array('recursive' => -1, 'order' => 'Post.id ASC'));
4517
		$errors = array(1 => array('title' => array('This field cannot be left blank')));
4518
		$expected = array(
4519
			array(
4520
				'Post' => array(
4521
					'id' => '1',
4522
					'author_id' => '1',
4523
					'title' => 'Un-Baleeted First Post',
4524
					'body' => 'Not Baleeted!',
4525
					'published' => 'Y',
4526
					'created' => '2007-03-18 10:39:23'
4527
				)
4528
			),
4529
			array(
4530
				'Post' => array(
4531
					'id' => '2',
4532
					'author_id' => '3',
4533
					'title' => 'Just update the title',
4534
					'body' => 'Second Post Body',
4535
					'published' => 'Y',
4536
					'created' => '2007-03-18 10:41:23'
4537
				)
4538
			),
4539
			array(
4540
				'Post' => array(
4541
					'id' => '3',
4542
					'author_id' => '1',
4543
					'title' => 'Third Post',
4544
					'body' => 'Third Post Body',
4545
					'published' => 'Y',
4546
					'created' => '2007-03-18 10:43:23',
4547
					'updated' => '2007-03-18 10:45:31'
4548
				)
4549
			),
4550
			array(
4551
				'Post' => array(
4552
					'id' => '4',
4553
					'author_id' => '2',
4554
					'title' => 'Creating a fourth post',
4555
					'body' => 'Fourth post body',
4556
					'published' => 'N'
4557
				)
4558
			)
4559
		);
4560
 
4561
		$this->assertEquals(self::date(), $result[0]['Post']['updated']);
4562
		$this->assertEquals(self::date(), $result[1]['Post']['updated']);
4563
		$this->assertEquals(self::date(), $result[3]['Post']['updated']);
4564
		$this->assertEquals(self::date(), $result[3]['Post']['created']);
4565
		unset(
4566
			$result[0]['Post']['updated'], $result[1]['Post']['updated'],
4567
			$result[3]['Post']['updated'], $result[3]['Post']['created']
4568
		);
4569
		$this->assertEquals($expected, $result);
4570
		$this->assertEquals($errors, $TestModel->validationErrors);
4571
 
4572
		$data = array(
4573
			array(
4574
				'id' => '1',
4575
				'title' => 'Re-Baleeted First Post',
4576
				'body' => 'Baleeted!',
4577
				'published' => 'N'
4578
			),
4579
			array(
4580
				'id' => '2',
4581
				'title' => '',
4582
				'body' => 'Trying to get away with an empty title'
4583
		));
4584
		$this->assertFalse($TestModel->saveAll($data, array('validate' => 'first')));
4585
 
4586
		$result = $TestModel->find('all', array('recursive' => -1, 'order' => 'Post.id ASC'));
4587
		unset(
4588
			$result[0]['Post']['updated'], $result[1]['Post']['updated'],
4589
			$result[3]['Post']['updated'], $result[3]['Post']['created']
4590
		);
4591
		$this->assertEquals($expected, $result);
4592
		$this->assertEquals($errors, $TestModel->validationErrors);
4593
	}
4594
 
4595
/**
4596
 * testSaveAllValidationOnly method
4597
 *
4598
 * @return void
4599
 */
4600
	public function testSaveAllValidationOnly() {
4601
		$this->loadFixtures('Comment', 'Attachment');
4602
		$TestModel = new Comment();
4603
		$TestModel->Attachment->validate = array('attachment' => 'notEmpty');
4604
 
4605
		$data = array(
4606
			'Comment' => array(
4607
				'comment' => 'This is the comment'
4608
			),
4609
			'Attachment' => array(
4610
				'attachment' => ''
4611
			)
4612
		);
4613
 
4614
		$result = $TestModel->saveAll($data, array('validate' => 'only'));
4615
		$this->assertFalse($result);
4616
 
4617
		$TestModel = new Article();
4618
		$TestModel->validate = array('title' => 'notEmpty');
4619
		$result = $TestModel->saveAll(
4620
			array(
4621
 
4622
				1 => array('title' => 'title 1'),
4623
				2 => array('title' => 'title 2'),
4624
			),
4625
			array('validate' => 'only')
4626
		);
4627
		$this->assertFalse($result);
4628
		$expected = array(
4629
 
4630
		);
4631
		$this->assertEquals($expected, $TestModel->validationErrors);
4632
 
4633
		$result = $TestModel->saveAll(
4634
			array(
4635
 
4636
				1 => array('title' => ''),
4637
				2 => array('title' => 'title 2'),
4638
			),
4639
			array('validate' => 'only')
4640
		);
4641
		$this->assertFalse($result);
4642
		$expected = array(
4643
			1 => array('title' => array('This field cannot be left blank')),
4644
		);
4645
		$this->assertEquals($expected, $TestModel->validationErrors);
4646
	}
4647
 
4648
/**
4649
 * testSaveAllValidateFirst method
4650
 *
4651
 * @return void
4652
 */
4653
	public function testSaveAllValidateFirst() {
4654
		$this->loadFixtures('Article', 'Comment', 'Attachment', 'User', 'ArticlesTag', 'Tag');
4655
		$model = new Article();
4656
		$model->deleteAll(true);
4657
 
4658
		$model->Comment->validate = array('comment' => 'notEmpty');
4659
		$result = $model->saveAll(array(
4660
			'Article' => array(
4661
				'title' => 'Post with Author',
4662
				'body' => 'This post will be saved author'
4663
			),
4664
			'Comment' => array(
4665
				array('comment' => 'First new comment'),
4666
				array('comment' => '')
4667
			)
4668
		), array('validate' => 'first'));
4669
 
4670
		$this->assertFalse($result);
4671
 
4672
		$result = $model->find('all');
4673
		$this->assertSame(array(), $result);
4674
		$expected = array('Comment' => array(
4675
			1 => array('comment' => array('This field cannot be left blank'))
4676
		));
4677
 
4678
		$this->assertEquals($expected['Comment'], $model->Comment->validationErrors);
4679
 
4680
		$this->assertSame($model->Comment->find('count'), 0);
4681
 
4682
		$result = $model->saveAll(
4683
			array(
4684
				'Article' => array(
4685
					'title' => 'Post with Author',
4686
					'body' => 'This post will be saved with an author',
4687
					'user_id' => 2
4688
				),
4689
				'Comment' => array(
4690
					array(
4691
						'comment' => 'Only new comment',
4692
						'user_id' => 2
4693
			))),
4694
			array('validate' => 'first')
4695
		);
4696
 
4697
		$this->assertTrue($result);
4698
 
4699
		$result = $model->Comment->find('all');
4700
		$this->assertSame(count($result), 1);
4701
		$result = Hash::extract($result, '{n}.Comment.article_id');
4702
		$this->assertEquals(4, $result[0]);
4703
 
4704
		$model->deleteAll(true);
4705
		$data = array(
4706
			'Article' => array(
4707
				'title' => 'Post with Author saveAlled from comment',
4708
				'body' => 'This post will be saved with an author',
4709
				'user_id' => 2
4710
			),
4711
			'Comment' => array(
4712
				'comment' => 'Only new comment', 'user_id' => 2
4713
		));
4714
 
4715
		$result = $model->Comment->saveAll($data, array('validate' => 'first'));
4716
		$this->assertFalse(empty($result));
4717
 
4718
		$result = $model->find('all');
4719
		$this->assertEquals(
4720
			$result[0]['Article']['title'],
4721
			'Post with Author saveAlled from comment'
4722
		);
4723
		$this->assertEquals('Only new comment', $result[0]['Comment'][0]['comment']);
4724
	}
4725
 
4726
/**
4727
 * test saveAll()'s return is correct when using atomic = false and validate = first.
4728
 *
4729
 * @return void
4730
 */
4731
	public function testSaveAllValidateFirstAtomicFalse() {
4732
		$this->loadFixtures('Something');
4733
		$Something = new Something();
4734
		$invalidData = array(
4735
			array(
4736
				'title' => 'foo',
4737
				'body' => 'bar',
4738
				'published' => 'baz',
4739
			),
4740
			array(
4741
				'body' => 3,
4742
				'published' => 'sd',
4743
			),
4744
		);
4745
		$Something->create();
4746
		$Something->validate = array(
4747
			'title' => array(
4748
				'rule' => 'alphaNumeric',
4749
				'required' => true,
4750
			),
4751
			'body' => array(
4752
				'rule' => 'alphaNumeric',
4753
				'required' => true,
4754
				'allowEmpty' => true,
4755
			),
4756
		);
4757
		$result = $Something->saveAll($invalidData, array(
4758
			'atomic' => false,
4759
			'validate' => 'first',
4760
		));
4761
		$expected = array(true, false);
4762
		$this->assertEquals($expected, $result);
4763
 
4764
		$Something = new Something();
4765
		$validData = array(
4766
			array(
4767
				'title' => 'title value',
4768
				'body' => 'body value',
4769
				'published' => 'baz',
4770
			),
4771
			array(
4772
				'title' => 'valid',
4773
				'body' => 'this body',
4774
				'published' => 'sd',
4775
			),
4776
		);
4777
		$Something->create();
4778
		$result = $Something->saveAll($validData, array(
4779
			'atomic' => false,
4780
			'validate' => 'first',
4781
		));
4782
		$expected = array(true, true);
4783
		$this->assertEquals($expected, $result);
4784
	}
4785
 
4786
/**
4787
 * testSaveAllHasManyValidationOnly method
4788
 *
4789
 * @return void
4790
 */
4791
	public function testSaveAllHasManyValidationOnly() {
4792
		$this->loadFixtures('Article', 'Comment', 'Attachment');
4793
		$TestModel = new Article();
4794
		$TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
4795
		$TestModel->Comment->validate = array('comment' => 'notEmpty');
4796
 
4797
		$result = $TestModel->saveAll(
4798
			array(
4799
				'Article' => array('id' => 2),
4800
				'Comment' => array(
4801
					array(
4802
						'id' => 1,
4803
						'comment' => '',
4804
						'published' => 'Y',
4805
						'user_id' => 1),
4806
					array(
4807
						'id' => 2,
4808
						'comment' =>
4809
						'comment',
4810
						'published' => 'Y',
4811
						'user_id' => 1
4812
			))),
4813
			array('validate' => 'only')
4814
		);
4815
		$this->assertFalse($result);
4816
 
4817
		$result = $TestModel->saveAll(
4818
			array(
4819
				'Article' => array('id' => 2),
4820
				'Comment' => array(
4821
					array(
4822
						'id' => 1,
4823
						'comment' => '',
4824
						'published' => 'Y',
4825
						'user_id' => 1
4826
					),
4827
					array(
4828
						'id' => 2,
4829
						'comment' => 'comment',
4830
						'published' => 'Y',
4831
						'user_id' => 1
4832
					),
4833
					array(
4834
						'id' => 3,
4835
						'comment' => '',
4836
						'published' => 'Y',
4837
						'user_id' => 1
4838
			))),
4839
			array(
4840
				'validate' => 'only',
4841
				'atomic' => false
4842
		));
4843
		$expected = array(
4844
			'Article' => true,
4845
			'Comment' => array(false, true, false)
4846
		);
4847
		$this->assertSame($expected, $result);
4848
 
4849
		$expected = array('Comment' => array(
4850
 
4851
			2 => array('comment' => array('This field cannot be left blank'))
4852
		));
4853
		$this->assertEquals($expected, $TestModel->validationErrors);
4854
 
4855
		$expected = array(
4856
 
4857
			2 => array('comment' => array('This field cannot be left blank'))
4858
		);
4859
		$this->assertEquals($expected, $TestModel->Comment->validationErrors);
4860
	}
4861
 
4862
/**
4863
 * test that saveAll still behaves like previous versions (does not necessarily need a first argument)
4864
 *
4865
 * @return void
4866
 */
4867
	public function testSaveAllWithSet() {
4868
		$this->loadFixtures('Article', 'Tag', 'Comment', 'User', 'ArticlesTag');
4869
		$data = array(
4870
			'Article' => array(
4871
				'user_id' => 1,
4872
				'title' => 'Article Has and belongs to Many Tags'
4873
			),
4874
			'Tag' => array(
4875
				'Tag' => array(1, 2)
4876
			),
4877
			'Comment' => array(
4878
				array(
4879
					'comment' => 'Article comment',
4880
					'user_id' => 1
4881
		)));
4882
		$Article = new Article();
4883
		$Article->set($data);
4884
		$result = $Article->saveAll();
4885
		$this->assertFalse(empty($result));
4886
	}
4887
 
4888
/**
4889
 * test that saveAll behaves like plain save() when supplied empty data
4890
 *
4891
 * @link https://cakephp.lighthouseapp.com/projects/42648/tickets/277-test-saveall-with-validation-returns-incorrect-boolean-when-saving-empty-data
4892
 * @return void
4893
 */
4894
	public function testSaveAllEmptyData() {
4895
		$this->skipIf($this->db instanceof Sqlserver, 'This test is not compatible with SQL Server.');
4896
 
4897
		$this->loadFixtures('Article', 'ProductUpdateAll', 'Comment', 'Attachment');
4898
		$model = new Article();
4899
		$result = $model->saveAll(array(), array('validate' => 'first'));
4900
		$this->assertFalse(empty($result));
4901
 
4902
		$model = new ProductUpdateAll();
4903
		$result = $model->saveAll();
4904
		$this->assertFalse($result);
4905
	}
4906
 
4907
/**
4908
 * testSaveAssociated method
4909
 *
4910
 * @return void
4911
 */
4912
	public function testSaveAssociated() {
4913
		$this->loadFixtures('Post', 'Author', 'Comment', 'Attachment', 'Article', 'User');
4914
		$TestModel = new Post();
4915
 
4916
		$result = $TestModel->find('all');
4917
		$this->assertEquals(3, count($result));
4918
		$this->assertFalse(isset($result[3]));
4919
 
4920
		$TestModel->saveAssociated(array(
4921
			'Post' => array(
4922
				'title' => 'Post with Author',
4923
				'body' => 'This post will be saved with an author'
4924
			),
4925
			'Author' => array(
4926
				'user' => 'bob',
4927
				'password' => '5f4dcc3b5aa765d61d8327deb882cf90'
4928
		)));
4929
 
4930
		$result = $TestModel->find('all', array('order' => array('Post.id ' => 'ASC')));
4931
		$expected = array(
4932
			'Post' => array(
4933
				'id' => '4',
4934
				'author_id' => '5',
4935
				'title' => 'Post with Author',
4936
				'body' => 'This post will be saved with an author',
4937
				'published' => 'N'
4938
			),
4939
			'Author' => array(
4940
				'id' => '5',
4941
				'user' => 'bob',
4942
				'password' => '5f4dcc3b5aa765d61d8327deb882cf90',
4943
				'test' => 'working'
4944
		));
4945
		$this->assertEquals(self::date(), $result[3]['Post']['updated']);
4946
		$this->assertEquals(self::date(), $result[3]['Post']['created']);
4947
		$this->assertEquals(self::date(), $result[3]['Author']['created']);
4948
		$this->assertEquals(self::date(), $result[3]['Author']['updated']);
4949
		unset(
4950
			$result[3]['Post']['updated'], $result[3]['Post']['created'],
4951
			$result[3]['Author']['updated'], $result[3]['Author']['created']
4952
		);
4953
		$this->assertEquals($expected, $result[3]);
4954
		$this->assertEquals(4, count($result));
4955
 
4956
		$TestModel = new Comment();
4957
		$result = $TestModel->saveAssociated(array(
4958
			'Comment' => array(
4959
				'article_id' => 2,
4960
				'user_id' => 2,
4961
				'comment' => 'New comment with attachment',
4962
				'published' => 'Y'
4963
			),
4964
			'Attachment' => array(
4965
				'attachment' => 'some_file.tgz'
4966
			)));
4967
		$this->assertFalse(empty($result));
4968
 
4969
		$result = $TestModel->find('all');
4970
		$expected = array(
4971
			'id' => '7',
4972
			'article_id' => '2',
4973
			'user_id' => '2',
4974
			'comment' => 'New comment with attachment',
4975
			'published' => 'Y'
4976
		);
4977
		$this->assertEquals(self::date(), $result[6]['Comment']['updated']);
4978
		$this->assertEquals(self::date(), $result[6]['Comment']['created']);
4979
		unset($result[6]['Comment']['updated'], $result[6]['Comment']['created']);
4980
		$this->assertEquals($expected, $result[6]['Comment']);
4981
 
4982
		$expected = array(
4983
			'id' => '2',
4984
			'comment_id' => '7',
4985
			'attachment' => 'some_file.tgz'
4986
		);
4987
		$this->assertEquals(self::date(), $result[6]['Attachment']['updated']);
4988
		$this->assertEquals(self::date(), $result[6]['Attachment']['created']);
4989
		unset($result[6]['Attachment']['updated'], $result[6]['Attachment']['created']);
4990
		$this->assertEquals($expected, $result[6]['Attachment']);
4991
	}
4992
 
4993
/**
4994
 * Test that validate = first, atomic = false works when associated records
4995
 * fail validation.
4996
 *
4997
 * @return void
4998
 */
4999
	public function testSaveAssociatedAtomicFalseValidateFirstWithErrors() {
5000
		$this->loadFixtures('Comment', 'Article', 'User');
5001
		$Article = ClassRegistry::init('Article');
5002
		$Article->Comment->validator()->add('comment', array(
5003
			array('rule' => 'notEmpty')
5004
		));
5005
 
5006
		$data = array(
5007
			'Article' => array(
5008
				'user_id' => 1,
5009
				'title' => 'Foo',
5010
				'body' => 'text',
5011
				'published' => 'N'
5012
			),
5013
			'Comment' => array(
5014
				array(
5015
					'user_id' => 1,
5016
					'comment' => '',
5017
					'published' => 'N',
5018
				)
5019
			),
5020
		);
5021
 
5022
		$Article->saveAssociated(
5023
			$data,
5024
			array('validate' => 'first', 'atomic' => false)
5025
		);
5026
 
5027
		$result = $Article->validationErrors;
5028
		$expected = array(
5029
			'Comment' => array(
5030
				array(
5031
					'comment' => array('This field cannot be left blank')
5032
				)
5033
			)
5034
		);
5035
		$this->assertEquals($expected, $result);
5036
	}
5037
 
5038
/**
5039
 * testSaveMany method
5040
 *
5041
 * @return void
5042
 */
5043
	public function testSaveMany() {
5044
		$this->loadFixtures('Post');
5045
		$TestModel = new Post();
5046
		$TestModel->deleteAll(true);
5047
		$this->assertEquals(array(), $TestModel->find('all'));
5048
 
5049
		// SQLite seems to reset the PK counter when that happens, so we need this to make the tests pass
5050
		$this->db->truncate($TestModel);
5051
 
5052
		$TestModel->saveMany(array(
5053
			array(
5054
				'title' => 'Multi-record post 1',
5055
				'body' => 'First multi-record post',
5056
				'author_id' => 2
5057
			),
5058
			array(
5059
				'title' => 'Multi-record post 2',
5060
				'body' => 'Second multi-record post',
5061
				'author_id' => 2
5062
		)));
5063
 
5064
		$result = $TestModel->find('all', array(
5065
			'recursive' => -1,
5066
			'order' => 'Post.id ASC'
5067
		));
5068
		$expected = array(
5069
			array(
5070
				'Post' => array(
5071
					'id' => '1',
5072
					'author_id' => '2',
5073
					'title' => 'Multi-record post 1',
5074
					'body' => 'First multi-record post',
5075
					'published' => 'N'
5076
				)
5077
			),
5078
			array(
5079
				'Post' => array(
5080
					'id' => '2',
5081
					'author_id' => '2',
5082
					'title' => 'Multi-record post 2',
5083
					'body' => 'Second multi-record post',
5084
					'published' => 'N'
5085
				)
5086
			)
5087
		);
5088
		$this->assertEquals(self::date(), $result[0]['Post']['updated']);
5089
		$this->assertEquals(self::date(), $result[0]['Post']['created']);
5090
		$this->assertEquals(self::date(), $result[1]['Post']['updated']);
5091
		$this->assertEquals(self::date(), $result[1]['Post']['created']);
5092
		unset($result[0]['Post']['updated'], $result[0]['Post']['created']);
5093
		unset($result[1]['Post']['updated'], $result[1]['Post']['created']);
5094
		$this->assertEquals($expected, $result);
5095
	}
5096
 
5097
/**
5098
 * Test SaveMany with validate=false.
5099
 *
5100
 * @return void
5101
 */
5102
	public function testSaveManyValidateFalse() {
5103
		$this->loadFixtures('Post');
5104
		$TestModel = new Post();
5105
		$TestModel->deleteAll(true);
5106
		$data = array(
5107
			array('id' => 1, 'author_id' => 1, 'title' => 'hi'),
5108
			array('id' => 2, 'author_id' => 1, 'title' => 'bye')
5109
		);
5110
		$result = $TestModel->saveAll($data, array('validate' => false));
5111
		$this->assertTrue($result);
5112
	}
5113
 
5114
/**
5115
 * Test SaveAssociated with Habtm relations
5116
 *
5117
 * @return void
5118
 */
5119
	public function testSaveAssociatedHabtm() {
5120
		$this->loadFixtures('Article', 'Tag', 'Comment', 'User', 'ArticlesTag');
5121
		$data = array(
5122
			'Article' => array(
5123
				'user_id' => 1,
5124
				'title' => 'Article Has and belongs to Many Tags'
5125
			),
5126
			'Tag' => array(
5127
				'Tag' => array(1, 2)
5128
			),
5129
			'Comment' => array(
5130
				array(
5131
					'comment' => 'Article comment',
5132
					'user_id' => 1
5133
		)));
5134
		$Article = new Article();
5135
		$result = $Article->saveAssociated($data);
5136
		$this->assertFalse(empty($result));
5137
 
5138
		$result = $Article->read();
5139
		$this->assertEquals(2, count($result['Tag']));
5140
		$this->assertEquals('tag1', $result['Tag'][0]['tag']);
5141
		$this->assertEquals(1, count($result['Comment']));
5142
		$this->assertEquals(1, count($result['Comment'][0]['comment']));
5143
	}
5144
 
5145
/**
5146
 * Test SaveAssociated with Habtm relations and extra join table fields
5147
 *
5148
 * @return void
5149
 */
5150
	public function testSaveAssociatedHabtmWithExtraJoinTableFields() {
5151
		$this->loadFixtures('Something', 'SomethingElse', 'JoinThing');
5152
 
5153
		$data = array(
5154
			'Something' => array(
5155
				'id' => 4,
5156
				'title' => 'Extra Fields',
5157
				'body' => 'Extra Fields Body',
5158
				'published' => '1'
5159
			),
5160
			'SomethingElse' => array(
5161
				array('something_else_id' => 1, 'doomed' => '1'),
5162
				array('something_else_id' => 2, 'doomed' => '0'),
5163
				array('something_else_id' => 3, 'doomed' => '1')
5164
			)
5165
		);
5166
 
5167
		$Something = new Something();
5168
		$result = $Something->saveAssociated($data);
5169
		$this->assertFalse(empty($result));
5170
		$result = $Something->read();
5171
 
5172
		$this->assertEquals(3, count($result['SomethingElse']));
5173
		$this->assertTrue(Set::matches('/Something[id=4]', $result));
5174
 
5175
		$this->assertTrue(Set::matches('/SomethingElse[id=1]', $result));
5176
		$this->assertTrue(Set::matches('/SomethingElse[id=1]/JoinThing[something_else_id=1]', $result));
5177
		$this->assertTrue(Set::matches('/SomethingElse[id=1]/JoinThing[doomed=1]', $result));
5178
 
5179
		$this->assertTrue(Set::matches('/SomethingElse[id=2]', $result));
5180
		$this->assertTrue(Set::matches('/SomethingElse[id=2]/JoinThing[something_else_id=2]', $result));
5181
		$this->assertTrue(Set::matches('/SomethingElse[id=2]/JoinThing[doomed=0]', $result));
5182
 
5183
		$this->assertTrue(Set::matches('/SomethingElse[id=3]', $result));
5184
		$this->assertTrue(Set::matches('/SomethingElse[id=3]/JoinThing[something_else_id=3]', $result));
5185
		$this->assertTrue(Set::matches('/SomethingElse[id=3]/JoinThing[doomed=1]', $result));
5186
	}
5187
 
5188
/**
5189
 * testSaveAssociatedHasOne method
5190
 *
5191
 * @return void
5192
 */
5193
	public function testSaveAssociatedHasOne() {
5194
		$model = new Comment();
5195
		$model->deleteAll(true);
5196
		$this->assertEquals(array(), $model->find('all'));
5197
 
5198
		$model->Attachment->deleteAll(true);
5199
		$this->assertEquals(array(), $model->Attachment->find('all'));
5200
 
5201
		$this->assertTrue($model->saveAssociated(array(
5202
			'Comment' => array(
5203
				'comment' => 'Comment with attachment',
5204
				'article_id' => 1,
5205
				'user_id' => 1
5206
			),
5207
			'Attachment' => array(
5208
				'attachment' => 'some_file.zip'
5209
		))));
5210
		$result = $model->find('all', array('fields' => array(
5211
			'Comment.id', 'Comment.comment', 'Attachment.id',
5212
			'Attachment.comment_id', 'Attachment.attachment'
5213
		)));
5214
		$expected = array(array(
5215
			'Comment' => array(
5216
				'id' => '1',
5217
				'comment' => 'Comment with attachment'
5218
			),
5219
			'Attachment' => array(
5220
				'id' => '1',
5221
				'comment_id' => '1',
5222
				'attachment' => 'some_file.zip'
5223
		)));
5224
		$this->assertEquals($expected, $result);
5225
 
5226
		$model->Attachment->bindModel(array('belongsTo' => array('Comment')), false);
5227
		$data = array(
5228
			'Comment' => array(
5229
				'comment' => 'Comment with attachment',
5230
				'article_id' => 1,
5231
				'user_id' => 1
5232
			),
5233
			'Attachment' => array(
5234
				'attachment' => 'some_file.zip'
5235
		));
5236
		$this->assertTrue($model->saveAssociated($data, array('validate' => 'first')));
5237
	}
5238
 
5239
/**
5240
 * testSaveAssociatedBelongsTo method
5241
 *
5242
 * @return void
5243
 */
5244
	public function testSaveAssociatedBelongsTo() {
5245
		$model = new Comment();
5246
		$model->deleteAll(true);
5247
		$this->assertEquals(array(), $model->find('all'));
5248
 
5249
		$model->Article->deleteAll(true);
5250
		$this->assertEquals(array(), $model->Article->find('all'));
5251
 
5252
		$this->assertTrue($model->saveAssociated(array(
5253
			'Comment' => array(
5254
				'comment' => 'Article comment',
5255
				'article_id' => 1,
5256
				'user_id' => 1
5257
			),
5258
			'Article' => array(
5259
				'title' => 'Model Associations 101',
5260
				'user_id' => 1
5261
		))));
5262
		$result = $model->find('all', array('fields' => array(
5263
			'Comment.id', 'Comment.comment', 'Comment.article_id', 'Article.id', 'Article.title'
5264
		)));
5265
		$expected = array(array(
5266
			'Comment' => array(
5267
				'id' => '1',
5268
				'article_id' => '1',
5269
				'comment' => 'Article comment'
5270
			),
5271
			'Article' => array(
5272
				'id' => '1',
5273
				'title' => 'Model Associations 101'
5274
		)));
5275
		$this->assertEquals($expected, $result);
5276
	}
5277
 
5278
/**
5279
 * testSaveAssociatedHasOneValidation method
5280
 *
5281
 * @return void
5282
 */
5283
	public function testSaveAssociatedHasOneValidation() {
5284
		$model = new Comment();
5285
		$model->deleteAll(true);
5286
		$this->assertEquals(array(), $model->find('all'));
5287
 
5288
		$model->Attachment->deleteAll(true);
5289
		$this->assertEquals(array(), $model->Attachment->find('all'));
5290
 
5291
		$model->validate = array('comment' => 'notEmpty');
5292
		$model->Attachment->validate = array('attachment' => 'notEmpty');
5293
		$model->Attachment->bindModel(array('belongsTo' => array('Comment')));
5294
 
5295
		$result = $model->saveAssociated(
5296
			array(
5297
				'Comment' => array(
5298
					'comment' => '',
5299
					'article_id' => 1,
5300
					'user_id' => 1
5301
				),
5302
				'Attachment' => array('attachment' => '')
5303
			)
5304
		);
5305
		$this->assertFalse($result);
5306
		$expected = array(
5307
			'comment' => array(
5308
				'This field cannot be left blank'
5309
			),
5310
			'Attachment' => array(
5311
				'attachment' => array(
5312
					'This field cannot be left blank'
5313
				)
5314
			)
5315
		);
5316
		$this->assertEquals($expected, $model->validationErrors);
5317
		$this->assertEquals($expected['Attachment'], $model->Attachment->validationErrors);
5318
	}
5319
 
5320
/**
5321
 * testSaveAssociatedAtomic method
5322
 *
5323
 * @return void
5324
 */
5325
	public function testSaveAssociatedAtomic() {
5326
		$this->loadFixtures('Article', 'User');
5327
		$TestModel = new Article();
5328
 
5329
		$result = $TestModel->saveAssociated(array(
5330
			'Article' => array(
5331
				'title' => 'Post with Author',
5332
				'body' => 'This post will be saved with an author',
5333
				'user_id' => 2
5334
			),
5335
			'Comment' => array(
5336
				array('comment' => 'First new comment', 'user_id' => 2))
5337
		), array('atomic' => false));
5338
 
5339
		$this->assertSame($result, array('Article' => true, 'Comment' => array(true)));
5340
 
5341
		$result = $TestModel->saveAssociated(array(
5342
			'Article' => array('id' => 2),
5343
			'Comment' => array(
5344
				array(
5345
					'comment' => 'First new comment',
5346
					'published' => 'Y',
5347
					'user_id' => 1
5348
				),
5349
				array(
5350
					'comment' => 'Second new comment',
5351
					'published' => 'Y',
5352
					'user_id' => 2
5353
			))
5354
		), array('validate' => true, 'atomic' => false));
5355
		$this->assertSame($result, array('Article' => true, 'Comment' => array(true, true)));
5356
	}
5357
 
5358
/**
5359
 * testSaveManyAtomic method
5360
 *
5361
 * @return void
5362
 */
5363
	public function testSaveManyAtomic() {
5364
		$this->loadFixtures('Article', 'User');
5365
		$TestModel = new Article();
5366
 
5367
		$result = $TestModel->saveMany(array(
5368
			array(
5369
				'id' => '1',
5370
				'title' => 'Baleeted First Post',
5371
				'body' => 'Baleeted!',
5372
				'published' => 'N'
5373
			),
5374
			array(
5375
				'id' => '2',
5376
				'title' => 'Just update the title'
5377
			),
5378
			array(
5379
				'title' => 'Creating a fourth post',
5380
				'body' => 'Fourth post body',
5381
				'user_id' => 2
5382
			)
5383
		), array('atomic' => false));
5384
		$this->assertSame($result, array(true, true, true));
5385
 
5386
		$TestModel->validate = array('title' => 'notEmpty', 'author_id' => 'numeric');
5387
		$result = $TestModel->saveMany(array(
5388
			array(
5389
				'id' => '1',
5390
				'title' => 'Un-Baleeted First Post',
5391
				'body' => 'Not Baleeted!',
5392
				'published' => 'Y'
5393
			),
5394
			array(
5395
				'id' => '2',
5396
				'title' => '',
5397
				'body' => 'Trying to get away with an empty title'
5398
			)
5399
		), array('validate' => true, 'atomic' => false));
5400
 
5401
		$this->assertSame(array(true, false), $result);
5402
	}
5403
 
5404
/**
5405
 * testSaveAssociatedHasMany method
5406
 *
5407
 * @return void
5408
 */
5409
	public function testSaveAssociatedHasMany() {
5410
		$this->loadFixtures('Article', 'Comment');
5411
		$TestModel = new Article();
5412
		$TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
5413
 
5414
		$result = $TestModel->saveAssociated(array(
5415
			'Article' => array('id' => 2),
5416
			'Comment' => array(
5417
				array('comment' => 'First new comment', 'published' => 'Y', 'user_id' => 1),
5418
				array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
5419
			)
5420
		));
5421
		$this->assertFalse(empty($result));
5422
 
5423
		$result = $TestModel->findById(2);
5424
		$expected = array(
5425
			'First Comment for Second Article',
5426
			'Second Comment for Second Article',
5427
			'First new comment',
5428
			'Second new comment'
5429
		);
5430
		$this->assertEquals($expected, Hash::extract($result['Comment'], '{n}.comment'));
5431
 
5432
		$result = $TestModel->saveAssociated(
5433
			array(
5434
				'Article' => array('id' => 2),
5435
				'Comment' => array(
5436
					array(
5437
						'comment' => 'Third new comment',
5438
						'published' => 'Y',
5439
						'user_id' => 1
5440
			))),
5441
			array('atomic' => false)
5442
		);
5443
		$this->assertFalse(empty($result));
5444
 
5445
		$result = $TestModel->findById(2);
5446
		$expected = array(
5447
			'First Comment for Second Article',
5448
			'Second Comment for Second Article',
5449
			'First new comment',
5450
			'Second new comment',
5451
			'Third new comment'
5452
		);
5453
		$this->assertEquals($expected, Hash::extract($result['Comment'], '{n}.comment'));
5454
 
5455
		$TestModel->beforeSaveReturn = false;
5456
		$result = $TestModel->saveAssociated(
5457
			array(
5458
				'Article' => array('id' => 2),
5459
				'Comment' => array(
5460
					array(
5461
						'comment' => 'Fourth new comment',
5462
						'published' => 'Y',
5463
						'user_id' => 1
5464
			))),
5465
			array('atomic' => false)
5466
		);
5467
		$this->assertEquals(array('Article' => false), $result);
5468
 
5469
		$result = $TestModel->findById(2);
5470
		$expected = array(
5471
			'First Comment for Second Article',
5472
			'Second Comment for Second Article',
5473
			'First new comment',
5474
			'Second new comment',
5475
			'Third new comment'
5476
		);
5477
		$this->assertEquals($expected, Hash::extract($result['Comment'], '{n}.comment'));
5478
	}
5479
 
5480
/**
5481
 * testSaveAssociatedHasManyEmpty method
5482
 *
5483
 * @return void
5484
 */
5485
	public function testSaveAssociatedHasManyEmpty() {
5486
		$this->loadFixtures('Article', 'Comment');
5487
		$TestModel = new Article();
5488
		$TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
5489
		$TestModel->validate = $TestModel->Comment->validate = array('user_id' => array('notEmpty' => array('rule' => 'notEmpty', 'required' => true)));
5490
 
5491
		//empty hasMany data is ignored in save
5492
		$result = $TestModel->saveAssociated(array(
5493
			'Article' => array('title' => 'title', 'user_id' => 1),
5494
			'Comment' => array()
5495
		), array('validate' => true));
5496
		$this->assertTrue($result);
5497
 
5498
		$result = $TestModel->saveAssociated(array(
5499
			'Article' => array('title' => 'title', 'user_id' => 1),
5500
			'Comment' => array()
5501
		), array('validate' => true, 'atomic' => false));
5502
		$this->assertEquals(array('Article' => true), $result);
5503
 
5504
		//empty primary data is not ignored
5505
		$result = $TestModel->saveAssociated(array('Article' => array()), array('validate' => true));
5506
		$this->assertFalse($result);
5507
 
5508
		$result = $TestModel->saveAssociated(array('Article' => array()), array('validate' => true, 'atomic' => false));
5509
		$this->assertEquals(array('Article' => false), $result);
5510
	}
5511
 
5512
/**
5513
 * testSaveAssociatedHasManyValidation method
5514
 *
5515
 * @return void
5516
 */
5517
	public function testSaveAssociatedHasManyValidation() {
5518
		$this->loadFixtures('Article', 'Comment');
5519
		$TestModel = new Article();
5520
		$TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
5521
		$TestModel->Comment->validate = array('comment' => 'notEmpty');
5522
 
5523
		$result = $TestModel->saveAssociated(array(
5524
			'Article' => array('id' => 2),
5525
			'Comment' => array(
5526
				array('comment' => '', 'published' => 'Y', 'user_id' => 1),
5527
			)
5528
		), array('validate' => true));
5529
		$this->assertFalse($result);
5530
 
5531
		$expected = array('Comment' => array(
5532
			array('comment' => array('This field cannot be left blank'))
5533
		));
5534
		$this->assertEquals($expected, $TestModel->validationErrors);
5535
		$expected = array(
5536
			array('comment' => array('This field cannot be left blank'))
5537
		);
5538
		$this->assertEquals($expected, $TestModel->Comment->validationErrors);
5539
 
5540
		$result = $TestModel->saveAssociated(array(
5541
			'Article' => array('id' => 2),
5542
			'Comment' => array(
5543
				array(
5544
					'comment' => '',
5545
					'published' => 'Y',
5546
					'user_id' => 1
5547
			))
5548
		), array('validate' => 'first'));
5549
		$this->assertFalse($result);
5550
	}
5551
 
5552
/**
5553
 * test saveMany with transactions and ensure there is no missing rollback.
5554
 *
5555
 * @return void
5556
 */
5557
	public function testSaveManyTransactionNoRollback() {
5558
		$this->loadFixtures('Post');
5559
 
5560
		$db = $this->getMock('DboSource', array('begin', 'connect', 'rollback', 'describe'));
5561
 
5562
		$db->expects($this->once())
5563
			->method('describe')
5564
			->will($this->returnValue(array()));
5565
		$db->expects($this->once())->method('rollback');
5566
 
5567
		$Post = new TestPost();
5568
		$Post->setDataSourceObject($db);
5569
 
5570
		$Post->validate = array(
5571
			'title' => array('rule' => array('notEmpty'))
5572
		);
5573
 
5574
		$data = array(
5575
			array('author_id' => 1, 'title' => 'New Fourth Post'),
5576
			array('author_id' => 1, 'title' => '')
5577
		);
5578
		$Post->saveMany($data, array('validate' => true));
5579
	}
5580
 
5581
/**
5582
 * test saveAssociated with transactions and ensure there is no missing rollback.
5583
 *
5584
 * @return void
5585
 */
5586
	public function testSaveAssociatedTransactionNoRollback() {
5587
		$testDb = ConnectionManager::getDataSource('test');
5588
 
5589
		$db = $this->getMock('DboSource', array('connect', 'rollback', 'describe', 'create', 'begin'));
5590
		$db->columns = $testDb->columns;
5591
 
5592
		$db->expects($this->once())->method('rollback');
5593
		$db->expects($this->any())->method('describe')
5594
			->will($this->returnValue(array(
5595
				'id' => array('type' => 'integer', 'length' => 11),
5596
				'title' => array('type' => 'string'),
5597
				'body' => array('type' => 'text'),
5598
				'published' => array('type' => 'string')
5599
			)));
5600
 
5601
		$Post = new TestPost();
5602
		$Post->setDataSourceObject($db);
5603
		$Post->Author->setDataSourceObject($db);
5604
 
5605
		$Post->Author->validate = array(
5606
			'user' => array('rule' => array('notEmpty'))
5607
		);
5608
 
5609
		$data = array(
5610
			'Post' => array(
5611
				'title' => 'New post',
5612
				'body' => 'Content',
5613
				'published' => 'Y'
5614
			),
5615
			'Author' => array(
5616
				'user' => '',
5617
				'password' => "sekret"
5618
			)
5619
		);
5620
		$Post->saveAssociated($data, array('validate' => true, 'atomic' => true));
5621
	}
5622
 
5623
/**
5624
 * test saveMany with nested saveMany call.
5625
 *
5626
 * @return void
5627
 */
5628
	public function testSaveManyNestedSaveMany() {
5629
		$this->loadFixtures('Sample');
5630
		$TransactionManyTestModel = new TransactionManyTestModel();
5631
 
5632
		$data = array(
5633
			array('apple_id' => 1, 'name' => 'sample5'),
5634
		);
5635
 
5636
		$this->assertTrue($TransactionManyTestModel->saveMany($data, array('atomic' => true)));
5637
	}
5638
 
5639
/**
5640
 * testSaveManyTransaction method
5641
 *
5642
 * @return void
5643
 */
5644
	public function testSaveManyTransaction() {
5645
		$this->loadFixtures('Post', 'Author', 'Comment', 'Attachment');
5646
		$TestModel = new Post();
5647
 
5648
		$TestModel->validate = array('title' => 'notEmpty');
5649
		$data = array(
5650
			array('author_id' => 1, 'title' => 'New Fourth Post'),
5651
			array('author_id' => 1, 'title' => 'New Fifth Post'),
5652
			array('author_id' => 1, 'title' => '')
5653
		);
5654
		$this->assertFalse($TestModel->saveMany($data));
5655
 
5656
		$result = $TestModel->find('all', array('recursive' => -1));
5657
		$expected = array(
5658
			array('Post' => array(
5659
				'id' => '1',
5660
				'author_id' => 1,
5661
				'title' => 'First Post',
5662
				'body' => 'First Post Body',
5663
				'published' => 'Y',
5664
				'created' => '2007-03-18 10:39:23',
5665
				'updated' => '2007-03-18 10:41:31'
5666
			)),
5667
			array('Post' => array(
5668
				'id' => '2',
5669
				'author_id' => 3,
5670
				'title' => 'Second Post',
5671
				'body' => 'Second Post Body',
5672
				'published' => 'Y',
5673
				'created' => '2007-03-18 10:41:23',
5674
				'updated' => '2007-03-18 10:43:31'
5675
			)),
5676
			array('Post' => array(
5677
				'id' => '3',
5678
				'author_id' => 1,
5679
				'title' => 'Third Post',
5680
				'body' => 'Third Post Body',
5681
				'published' => 'Y',
5682
				'created' => '2007-03-18 10:43:23',
5683
				'updated' => '2007-03-18 10:45:31'
5684
		)));
5685
 
5686
		if (count($result) != 3) {
5687
			// Database doesn't support transactions
5688
			$expected[] = array(
5689
				'Post' => array(
5690
					'id' => '4',
5691
					'author_id' => 1,
5692
					'title' => 'New Fourth Post',
5693
					'body' => null,
5694
					'published' => 'N'
5695
			));
5696
 
5697
			$expected[] = array(
5698
				'Post' => array(
5699
					'id' => '5',
5700
					'author_id' => 1,
5701
					'title' => 'New Fifth Post',
5702
					'body' => null,
5703
					'published' => 'N',
5704
			));
5705
 
5706
			$this->assertEquals(self::date(), $result[3]['Post']['created']);
5707
			$this->assertEquals(self::date(), $result[3]['Post']['updated']);
5708
			$this->assertEquals(self::date(), $result[4]['Post']['created']);
5709
			$this->assertEquals(self::date(), $result[4]['Post']['updated']);
5710
			unset($result[3]['Post']['created'], $result[3]['Post']['updated']);
5711
			unset($result[4]['Post']['created'], $result[4]['Post']['updated']);
5712
			$this->assertEquals($expected, $result);
5713
			// Skip the rest of the transactional tests
5714
			return;
5715
		}
5716
 
5717
		$this->assertEquals($expected, $result);
5718
 
5719
		$data = array(
5720
			array('author_id' => 1, 'title' => 'New Fourth Post'),
5721
			array('author_id' => 1, 'title' => ''),
5722
			array('author_id' => 1, 'title' => 'New Sixth Post')
5723
		);
5724
		$this->assertFalse($TestModel->saveMany($data));
5725
 
5726
		$result = $TestModel->find('all', array('recursive' => -1));
5727
		$expected = array(
5728
			array('Post' => array(
5729
				'id' => '1',
5730
				'author_id' => 1,
5731
				'title' => 'First Post',
5732
				'body' => 'First Post Body',
5733
				'published' => 'Y',
5734
				'created' => '2007-03-18 10:39:23',
5735
				'updated' => '2007-03-18 10:41:31'
5736
			)),
5737
			array('Post' => array(
5738
				'id' => '2',
5739
				'author_id' => 3,
5740
				'title' => 'Second Post',
5741
				'body' => 'Second Post Body',
5742
				'published' => 'Y',
5743
				'created' => '2007-03-18 10:41:23',
5744
				'updated' => '2007-03-18 10:43:31'
5745
			)),
5746
			array('Post' => array(
5747
				'id' => '3',
5748
				'author_id' => 1,
5749
				'title' => 'Third Post',
5750
				'body' => 'Third Post Body',
5751
				'published' => 'Y',
5752
				'created' => '2007-03-18 10:43:23',
5753
				'updated' => '2007-03-18 10:45:31'
5754
		)));
5755
 
5756
		if (count($result) != 3) {
5757
			// Database doesn't support transactions
5758
			$expected[] = array(
5759
				'Post' => array(
5760
					'id' => '4',
5761
					'author_id' => 1,
5762
					'title' => 'New Fourth Post',
5763
					'body' => 'Third Post Body',
5764
					'published' => 'N'
5765
			));
5766
 
5767
			$expected[] = array(
5768
				'Post' => array(
5769
					'id' => '5',
5770
					'author_id' => 1,
5771
					'title' => 'Third Post',
5772
					'body' => 'Third Post Body',
5773
					'published' => 'N'
5774
			));
5775
			$this->assertEquals(self::date(), $result[3]['Post']['created']);
5776
			$this->assertEquals(self::date(), $result[3]['Post']['updated']);
5777
			$this->assertEquals(self::date(), $result[4]['Post']['created']);
5778
			$this->assertEquals(self::date(), $result[4]['Post']['updated']);
5779
			unset($result[3]['Post']['created'], $result[3]['Post']['updated']);
5780
			unset($result[4]['Post']['created'], $result[4]['Post']['updated']);
5781
		}
5782
		$this->assertEquals($expected, $result);
5783
 
5784
		$TestModel->validate = array('title' => 'notEmpty');
5785
		$data = array(
5786
			array('author_id' => 1, 'title' => 'New Fourth Post'),
5787
			array('author_id' => 1, 'title' => 'New Fifth Post'),
5788
			array('author_id' => 1, 'title' => 'New Sixth Post')
5789
		);
5790
		$this->assertTrue($TestModel->saveMany($data));
5791
 
5792
		$result = $TestModel->find('all', array(
5793
			'recursive' => -1,
5794
			'fields' => array('author_id', 'title', 'body', 'published'),
5795
			'order' => array('Post.created' => 'ASC')
5796
		));
5797
 
5798
		$expected = array(
5799
			array('Post' => array(
5800
				'author_id' => 1,
5801
				'title' => 'First Post',
5802
				'body' => 'First Post Body',
5803
				'published' => 'Y'
5804
			)),
5805
			array('Post' => array(
5806
				'author_id' => 3,
5807
				'title' => 'Second Post',
5808
				'body' => 'Second Post Body',
5809
				'published' => 'Y'
5810
			)),
5811
			array('Post' => array(
5812
				'author_id' => 1,
5813
				'title' => 'Third Post',
5814
				'body' => 'Third Post Body',
5815
				'published' => 'Y'
5816
			)),
5817
			array('Post' => array(
5818
				'author_id' => 1,
5819
				'title' => 'New Fourth Post',
5820
				'body' => '',
5821
				'published' => 'N'
5822
			)),
5823
			array('Post' => array(
5824
				'author_id' => 1,
5825
				'title' => 'New Fifth Post',
5826
				'body' => '',
5827
				'published' => 'N'
5828
			)),
5829
			array('Post' => array(
5830
				'author_id' => 1,
5831
				'title' => 'New Sixth Post',
5832
				'body' => '',
5833
				'published' => 'N'
5834
		)));
5835
		$this->assertEquals($expected, $result);
5836
	}
5837
 
5838
/**
5839
 * testSaveManyValidation method
5840
 *
5841
 * @return void
5842
 */
5843
	public function testSaveManyValidation() {
5844
		$this->loadFixtures('Post', 'Author', 'Comment', 'Attachment');
5845
		$TestModel = new Post();
5846
 
5847
		$data = array(
5848
			array(
5849
				'id' => '1',
5850
				'title' => 'Baleeted First Post',
5851
				'body' => 'Baleeted!',
5852
				'published' => 'N'
5853
			),
5854
			array(
5855
				'id' => '2',
5856
				'title' => 'Just update the title'
5857
			),
5858
			array(
5859
				'title' => 'Creating a fourth post',
5860
				'body' => 'Fourth post body',
5861
				'author_id' => 2
5862
		));
5863
 
5864
		$this->assertTrue($TestModel->saveMany($data));
5865
 
5866
		$result = $TestModel->find('all', array('recursive' => -1, 'order' => 'Post.id ASC'));
5867
		$expected = array(
5868
			array(
5869
				'Post' => array(
5870
					'id' => '1',
5871
					'author_id' => '1',
5872
					'title' => 'Baleeted First Post',
5873
					'body' => 'Baleeted!',
5874
					'published' => 'N',
5875
					'created' => '2007-03-18 10:39:23'
5876
				)
5877
			),
5878
			array(
5879
				'Post' => array(
5880
					'id' => '2',
5881
					'author_id' => '3',
5882
					'title' => 'Just update the title',
5883
					'body' => 'Second Post Body',
5884
					'published' => 'Y',
5885
					'created' => '2007-03-18 10:41:23'
5886
				)
5887
			),
5888
			array(
5889
				'Post' => array(
5890
					'id' => '3',
5891
					'author_id' => '1',
5892
					'title' => 'Third Post',
5893
					'body' => 'Third Post Body',
5894
					'published' => 'Y',
5895
					'created' => '2007-03-18 10:43:23',
5896
					'updated' => '2007-03-18 10:45:31'
5897
			)),
5898
			array(
5899
				'Post' => array(
5900
					'id' => '4',
5901
					'author_id' => '2',
5902
					'title' => 'Creating a fourth post',
5903
					'body' => 'Fourth post body',
5904
					'published' => 'N'
5905
				)
5906
			)
5907
		);
5908
 
5909
		$this->assertEquals(self::date(), $result[0]['Post']['updated']);
5910
		$this->assertEquals(self::date(), $result[1]['Post']['updated']);
5911
		$this->assertEquals(self::date(), $result[3]['Post']['created']);
5912
		$this->assertEquals(self::date(), $result[3]['Post']['updated']);
5913
		unset($result[0]['Post']['updated'], $result[1]['Post']['updated']);
5914
		unset($result[3]['Post']['created'], $result[3]['Post']['updated']);
5915
		$this->assertEquals($expected, $result);
5916
 
5917
		$TestModel->validate = array('title' => 'notEmpty', 'author_id' => 'numeric');
5918
		$data = array(
5919
			array(
5920
				'id' => '1',
5921
				'title' => 'Un-Baleeted First Post',
5922
				'body' => 'Not Baleeted!',
5923
				'published' => 'Y'
5924
			),
5925
			array(
5926
				'id' => '2',
5927
				'title' => '',
5928
				'body' => 'Trying to get away with an empty title'
5929
		));
5930
		$result = $TestModel->saveMany($data);
5931
		$this->assertFalse($result);
5932
 
5933
		$result = $TestModel->find('all', array('recursive' => -1, 'order' => 'Post.id ASC'));
5934
		$errors = array(1 => array('title' => array('This field cannot be left blank')));
5935
		$transactionWorked = Set::matches('/Post[1][title=Baleeted First Post]', $result);
5936
		if (!$transactionWorked) {
5937
			$this->assertTrue(Set::matches('/Post[1][title=Un-Baleeted First Post]', $result));
5938
			$this->assertTrue(Set::matches('/Post[2][title=Just update the title]', $result));
5939
		}
5940
 
5941
		$this->assertEquals($errors, $TestModel->validationErrors);
5942
 
5943
		$TestModel->validate = array('title' => 'notEmpty', 'author_id' => 'numeric');
5944
		$data = array(
5945
			array(
5946
				'id' => '1',
5947
				'title' => 'Un-Baleeted First Post',
5948
				'body' => 'Not Baleeted!',
5949
				'published' => 'Y'
5950
			),
5951
			array(
5952
				'id' => '2',
5953
				'title' => '',
5954
				'body' => 'Trying to get away with an empty title'
5955
		));
5956
		$result = $TestModel->saveMany($data, array('validate' => true, 'atomic' => false));
5957
		$this->assertEquals(array(true, false), $result);
5958
 
5959
		$result = $TestModel->find('all', array(
5960
			'fields' => array('id', 'author_id', 'title', 'body', 'published'),
5961
			'recursive' => -1,
5962
			'order' => 'Post.id ASC'
5963
		));
5964
		$errors = array(1 => array('title' => array('This field cannot be left blank')));
5965
		$expected = array(
5966
			array(
5967
				'Post' => array(
5968
					'id' => '1',
5969
					'author_id' => '1',
5970
					'title' => 'Un-Baleeted First Post',
5971
					'body' => 'Not Baleeted!',
5972
					'published' => 'Y',
5973
			)),
5974
			array(
5975
				'Post' => array(
5976
					'id' => '2',
5977
					'author_id' => '3',
5978
					'title' => 'Just update the title',
5979
					'body' => 'Second Post Body',
5980
					'published' => 'Y',
5981
			)),
5982
			array(
5983
				'Post' => array(
5984
					'id' => '3',
5985
					'author_id' => '1',
5986
					'title' => 'Third Post',
5987
					'body' => 'Third Post Body',
5988
					'published' => 'Y',
5989
			)),
5990
			array(
5991
				'Post' => array(
5992
					'id' => '4',
5993
					'author_id' => '2',
5994
					'title' => 'Creating a fourth post',
5995
					'body' => 'Fourth post body',
5996
					'published' => 'N',
5997
		)));
5998
		$this->assertEquals($expected, $result);
5999
		$this->assertEquals($errors, $TestModel->validationErrors);
6000
 
6001
		$data = array(
6002
			array(
6003
				'id' => '1',
6004
				'title' => 'Re-Baleeted First Post',
6005
				'body' => 'Baleeted!',
6006
				'published' => 'N'
6007
			),
6008
			array(
6009
				'id' => '2',
6010
				'title' => '',
6011
				'body' => 'Trying to get away with an empty title'
6012
		));
6013
		$this->assertFalse($TestModel->saveMany($data, array('validate' => 'first')));
6014
 
6015
		$result = $TestModel->find('all', array(
6016
			'fields' => array('id', 'author_id', 'title', 'body', 'published'),
6017
			'recursive' => -1,
6018
			'order' => 'Post.id ASC'
6019
		));
6020
		$this->assertEquals($expected, $result);
6021
		$this->assertEquals($errors, $TestModel->validationErrors);
6022
	}
6023
 
6024
/**
6025
 * testValidateMany method
6026
 *
6027
 * @return void
6028
 */
6029
	public function testValidateMany() {
6030
		$TestModel = new Article();
6031
		$TestModel->validate = array('title' => 'notEmpty');
6032
		$data = array(
6033
 
6034
				1 => array('title' => 'title 1'),
6035
				2 => array('title' => 'title 2'),
6036
		);
6037
		$result = $TestModel->validateMany($data);
6038
		$this->assertFalse($result);
6039
		$expected = array(
6040
 
6041
		);
6042
		$this->assertEquals($expected, $TestModel->validationErrors);
6043
 
6044
		$data = array(
6045
 
6046
				1 => array('title' => ''),
6047
				2 => array('title' => 'title 2'),
6048
		);
6049
		$result = $TestModel->validateMany($data);
6050
		$this->assertFalse($result);
6051
		$expected = array(
6052
			1 => array('title' => array('This field cannot be left blank')),
6053
		);
6054
		$this->assertEquals($expected, $TestModel->validationErrors);
6055
	}
6056
 
6057
/**
6058
 * testSaveAssociatedValidateFirst method
6059
 *
6060
 * @return void
6061
 */
6062
	public function testSaveAssociatedValidateFirst() {
6063
		$this->loadFixtures('Article', 'Comment', 'Attachment');
6064
		$model = new Article();
6065
		$model->deleteAll(true);
6066
 
6067
		$model->Comment->validate = array('comment' => 'notEmpty');
6068
		$result = $model->saveAssociated(array(
6069
			'Article' => array(
6070
				'title' => 'Post with Author',
6071
				'body' => 'This post will be saved author'
6072
			),
6073
			'Comment' => array(
6074
				array('comment' => 'First new comment'),
6075
				array('comment' => '')
6076
			)
6077
		), array('validate' => 'first'));
6078
 
6079
		$this->assertFalse($result);
6080
 
6081
		$result = $model->find('all');
6082
		$this->assertSame(array(), $result);
6083
		$expected = array('Comment' => array(
6084
			1 => array('comment' => array('This field cannot be left blank'))
6085
		));
6086
 
6087
		$this->assertEquals($expected['Comment'], $model->Comment->validationErrors);
6088
 
6089
		$this->assertSame($model->Comment->find('count'), 0);
6090
 
6091
		$result = $model->saveAssociated(
6092
			array(
6093
				'Article' => array(
6094
					'title' => 'Post with Author',
6095
					'body' => 'This post will be saved with an author',
6096
					'user_id' => 2
6097
				),
6098
				'Comment' => array(
6099
					array(
6100
						'comment' => 'Only new comment',
6101
						'user_id' => 2
6102
			))),
6103
			array('validate' => 'first')
6104
		);
6105
 
6106
		$this->assertTrue($result);
6107
 
6108
		$result = $model->Comment->find('all');
6109
		$this->assertSame(count($result), 1);
6110
		$result = Hash::extract($result, '{n}.Comment.article_id');
6111
		$this->assertEquals(4, $result[0]);
6112
 
6113
		$model->deleteAll(true);
6114
		$data = array(
6115
			'Article' => array(
6116
				'title' => 'Post with Author saveAlled from comment',
6117
				'body' => 'This post will be saved with an author',
6118
				'user_id' => 2
6119
			),
6120
			'Comment' => array(
6121
				'comment' => 'Only new comment', 'user_id' => 2
6122
		));
6123
 
6124
		$result = $model->Comment->saveAssociated($data, array('validate' => 'first'));
6125
		$this->assertFalse(empty($result));
6126
 
6127
		$result = $model->find('all');
6128
		$this->assertEquals(
6129
			'Post with Author saveAlled from comment',
6130
			$result[0]['Article']['title']
6131
		);
6132
		$this->assertEquals('Only new comment', $result[0]['Comment'][0]['comment']);
6133
	}
6134
 
6135
/**
6136
 * test saveMany()'s return is correct when using atomic = false and validate = first.
6137
 *
6138
 * @return void
6139
 */
6140
	public function testSaveManyValidateFirstAtomicFalse() {
6141
		$Something = new Something();
6142
		$invalidData = array(
6143
			array(
6144
				'title' => 'foo',
6145
				'body' => 'bar',
6146
				'published' => 'baz',
6147
			),
6148
			array(
6149
				'body' => 3,
6150
				'published' => 'sd',
6151
			),
6152
		);
6153
		$Something->create();
6154
		$Something->validate = array(
6155
			'title' => array(
6156
				'rule' => 'alphaNumeric',
6157
				'required' => true,
6158
			),
6159
			'body' => array(
6160
				'rule' => 'alphaNumeric',
6161
				'required' => true,
6162
				'allowEmpty' => true,
6163
			),
6164
		);
6165
		$result = $Something->saveMany($invalidData, array(
6166
			'atomic' => false,
6167
			'validate' => 'first',
6168
		));
6169
		$expected = array(true, false);
6170
		$this->assertEquals($expected, $result);
6171
 
6172
		$Something = new Something();
6173
		$validData = array(
6174
			array(
6175
				'title' => 'title value',
6176
				'body' => 'body value',
6177
				'published' => 'baz',
6178
			),
6179
			array(
6180
				'title' => 'valid',
6181
				'body' => 'this body',
6182
				'published' => 'sd',
6183
			),
6184
		);
6185
		$Something->create();
6186
		$result = $Something->saveMany($validData, array(
6187
			'atomic' => false,
6188
			'validate' => 'first',
6189
		));
6190
		$expected = array(true, true);
6191
		$this->assertEquals($expected, $result);
6192
	}
6193
 
6194
/**
6195
 * testValidateAssociated method
6196
 *
6197
 * @return void
6198
 */
6199
	public function testValidateAssociated() {
6200
		$this->loadFixtures('Attachment', 'Article', 'Comment');
6201
		$TestModel = new Comment();
6202
		$TestModel->Attachment->validate = array('attachment' => 'notEmpty');
6203
 
6204
		$data = array(
6205
			'Comment' => array(
6206
				'comment' => 'This is the comment'
6207
			),
6208
			'Attachment' => array(
6209
				'attachment' => ''
6210
			)
6211
		);
6212
 
6213
		$result = $TestModel->validateAssociated($data);
6214
		$this->assertFalse($result);
6215
 
6216
		$TestModel = new Article();
6217
		$TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
6218
		$TestModel->Comment->validate = array('comment' => 'notEmpty');
6219
 
6220
		$data = array(
6221
			'Article' => array('id' => 2),
6222
			'Comment' => array(
6223
				array(
6224
					'id' => 1,
6225
					'comment' => '',
6226
					'published' => 'Y',
6227
					'user_id' => 1),
6228
				array(
6229
					'id' => 2,
6230
					'comment' =>
6231
					'comment',
6232
					'published' => 'Y',
6233
					'user_id' => 1
6234
		)));
6235
		$result = $TestModel->validateAssociated($data);
6236
		$this->assertFalse($result);
6237
 
6238
		$data = array(
6239
			'Article' => array('id' => 2),
6240
			'Comment' => array(
6241
				array(
6242
					'id' => 1,
6243
					'comment' => '',
6244
					'published' => 'Y',
6245
					'user_id' => 1
6246
				),
6247
				array(
6248
					'id' => 2,
6249
					'comment' => 'comment',
6250
					'published' => 'Y',
6251
					'user_id' => 1
6252
				),
6253
				array(
6254
					'id' => 3,
6255
					'comment' => '',
6256
					'published' => 'Y',
6257
					'user_id' => 1
6258
		)));
6259
		$result = $TestModel->validateAssociated($data, array(
6260
				'atomic' => false
6261
		));
6262
		$expected = array(
6263
			'Article' => true,
6264
			'Comment' => array(false, true, false)
6265
		);
6266
		$this->assertSame($expected, $result);
6267
 
6268
		$expected = array('Comment' => array(
6269
 
6270
			2 => array('comment' => array('This field cannot be left blank'))
6271
		));
6272
		$this->assertEquals($expected, $TestModel->validationErrors);
6273
 
6274
		$expected = array(
6275
 
6276
			2 => array('comment' => array('This field cannot be left blank'))
6277
		);
6278
		$this->assertEquals($expected, $TestModel->Comment->validationErrors);
6279
	}
6280
 
6281
/**
6282
 * test that saveMany behaves like plain save() when suplied empty data
6283
 *
6284
 * @link https://cakephp.lighthouseapp.com/projects/42648/tickets/277-test-saveall-with-validation-returns-incorrect-boolean-when-saving-empty-data
6285
 * @return void
6286
 */
6287
	public function testSaveManyEmptyData() {
6288
		$this->skipIf($this->db instanceof Sqlserver, 'This test is not compatible with SQL Server.');
6289
 
6290
		$this->loadFixtures('Article', 'ProductUpdateAll', 'Comment', 'Attachment');
6291
		$model = new Article();
6292
		$result = $model->saveMany(array(), array('validate' => true));
6293
		$this->assertFalse(empty($result));
6294
 
6295
		$model = new ProductUpdateAll();
6296
		$result = $model->saveMany(array());
6297
		$this->assertFalse($result);
6298
	}
6299
 
6300
/**
6301
 * test that saveAssociated behaves like plain save() when supplied empty data
6302
 *
6303
 * @link https://cakephp.lighthouseapp.com/projects/42648/tickets/277-test-saveall-with-validation-returns-incorrect-boolean-when-saving-empty-data
6304
 * @return void
6305
 */
6306
	public function testSaveAssociatedEmptyData() {
6307
		$this->skipIf($this->db instanceof Sqlserver, 'This test is not compatible with SQL Server.');
6308
 
6309
		$this->loadFixtures('Article', 'ProductUpdateAll', 'Comment', 'Attachment');
6310
		$model = new Article();
6311
		$result = $model->saveAssociated(array(), array('validate' => true));
6312
		$this->assertFalse(empty($result));
6313
 
6314
		$model = new ProductUpdateAll();
6315
		$result = $model->saveAssociated(array());
6316
		$this->assertFalse($result);
6317
	}
6318
 
6319
/**
6320
 * Test that saveAssociated will accept expression object values when saving.
6321
 *
6322
 * @return void
6323
 */
6324
	public function testSaveAssociatedExpressionObjects() {
6325
		$this->loadFixtures('Post', 'Author', 'Comment', 'Attachment', 'Article', 'User');
6326
		$TestModel = new Post();
6327
		$db = $TestModel->getDataSource();
6328
 
6329
		$TestModel->saveAssociated(array(
6330
			'Post' => array(
6331
				'title' => $db->expression("(SELECT 'Post with Author')"),
6332
				'body' => 'This post will be saved with an author'
6333
			),
6334
			'Author' => array(
6335
				'user' => 'bob',
6336
				'password' => '5f4dcc3b5aa765d61d8327deb882cf90'
6337
		)), array('atomic' => false));
6338
 
6339
		$result = $TestModel->find('first', array(
6340
			'order' => array('Post.id ' => 'DESC')
6341
		));
6342
		$this->assertEquals('Post with Author', $result['Post']['title']);
6343
	}
6344
 
6345
/**
6346
 * testUpdateWithCalculation method
6347
 *
6348
 * @return void
6349
 */
6350
	public function testUpdateWithCalculation() {
6351
		$this->loadFixtures('DataTest');
6352
		$model = new DataTest();
6353
		$model->deleteAll(true);
6354
		$result = $model->saveMany(array(
6355
			array('count' => 5, 'float' => 1.1),
6356
			array('count' => 3, 'float' => 1.2),
6357
			array('count' => 4, 'float' => 1.3),
6358
			array('count' => 1, 'float' => 2.0),
6359
		));
6360
		$this->assertFalse(empty($result));
6361
 
6362
		$result = Hash::extract($model->find('all', array('fields' => 'count')), '{n}.DataTest.count');
6363
		$this->assertEquals(array(5, 3, 4, 1), $result);
6364
 
6365
		$this->assertTrue($model->updateAll(array('count' => 'count + 2')));
6366
		$result = Hash::extract($model->find('all', array('fields' => 'count')), '{n}.DataTest.count');
6367
		$this->assertEquals(array(7, 5, 6, 3), $result);
6368
 
6369
		$this->assertTrue($model->updateAll(array('DataTest.count' => 'DataTest.count - 1')));
6370
		$result = Hash::extract($model->find('all', array('fields' => 'count')), '{n}.DataTest.count');
6371
		$this->assertEquals(array(6, 4, 5, 2), $result);
6372
	}
6373
 
6374
/**
6375
 * testToggleBoolFields method
6376
 *
6377
 * @return void
6378
 */
6379
	public function testToggleBoolFields() {
6380
		$this->loadFixtures('CounterCacheUser', 'CounterCachePost');
6381
		$Post = new CounterCachePost();
6382
		$Post->unbindModel(array('belongsTo' => array('User')), true);
6383
 
6384
		$true = array('Post' => array('published' => true, 'id' => 2));
6385
		$false = array('Post' => array('published' => false, 'id' => 2));
6386
		$fields = array('Post.published', 'Post.id');
6387
		$updateConditions = array('Post.id' => 2);
6388
 
6389
		// check its true
6390
		$result = $Post->find('first', array('conditions' => $updateConditions, 'fields' => $fields));
6391
		$this->assertEquals($true, $result);
6392
 
6393
		// Testing without the alias
6394
		$this->assertTrue($Post->updateAll(array('published' => 'NOT published'), $updateConditions));
6395
		$result = $Post->find('first', array('conditions' => $updateConditions, 'fields' => $fields));
6396
		$this->assertEquals($false, $result);
6397
 
6398
		$this->assertTrue($Post->updateAll(array('published' => 'NOT published'), $updateConditions));
6399
		$result = $Post->find('first', array('conditions' => $updateConditions, 'fields' => $fields));
6400
		$this->assertEquals($true, $result);
6401
 
6402
		$db = ConnectionManager::getDataSource('test');
6403
		$alias = $db->name('Post.published');
6404
 
6405
		// Testing with the alias
6406
		$this->assertTrue($Post->updateAll(array('Post.published' => "NOT $alias"), $updateConditions));
6407
		$result = $Post->find('first', array('conditions' => $updateConditions, 'fields' => $fields));
6408
		$this->assertEquals($false, $result);
6409
 
6410
		$this->assertTrue($Post->updateAll(array('Post.published' => "NOT $alias"), $updateConditions));
6411
		$result = $Post->find('first', array('conditions' => $updateConditions, 'fields' => $fields));
6412
		$this->assertEquals($true, $result);
6413
	}
6414
 
6415
/**
6416
 * TestFindAllWithoutForeignKey
6417
 *
6418
 * @return void
6419
 */
6420
	public function testFindAllForeignKey() {
6421
		$this->loadFixtures('ProductUpdateAll', 'GroupUpdateAll');
6422
		$ProductUpdateAll = new ProductUpdateAll();
6423
 
6424
		$conditions = array('Group.name' => 'group one');
6425
 
6426
		$ProductUpdateAll->bindModel(array(
6427
			'belongsTo' => array(
6428
				'Group' => array('className' => 'GroupUpdateAll')
6429
			)
6430
		));
6431
 
6432
		$ProductUpdateAll->belongsTo = array(
6433
			'Group' => array('className' => 'GroupUpdateAll', 'foreignKey' => 'group_id')
6434
		);
6435
 
6436
		$results = $ProductUpdateAll->find('all', compact('conditions'));
6437
		$this->assertTrue(!empty($results));
6438
 
6439
		$ProductUpdateAll->bindModel(array('belongsTo' => array('Group')));
6440
		$ProductUpdateAll->belongsTo = array(
6441
			'Group' => array(
6442
				'className' => 'GroupUpdateAll',
6443
				'foreignKey' => false,
6444
				'conditions' => 'ProductUpdateAll.groupcode = Group.code'
6445
			));
6446
 
6447
		$resultsFkFalse = $ProductUpdateAll->find('all', compact('conditions'));
6448
		$this->assertTrue(!empty($resultsFkFalse));
6449
		$expected = array(
6450
			'0' => array(
6451
				'ProductUpdateAll' => array(
6452
					'id' => 1,
6453
					'name'	=> 'product one',
6454
					'groupcode' => 120,
6455
					'group_id' => 1),
6456
				'Group' => array(
6457
					'id' => 1,
6458
					'name' => 'group one',
6459
					'code' => 120)
6460
				),
6461
			'1' => array(
6462
				'ProductUpdateAll' => array(
6463
					'id' => 2,
6464
					'name'	=> 'product two',
6465
					'groupcode'	=> 120,
6466
					'group_id'	=> 1),
6467
				'Group' => array(
6468
					'id' => 1,
6469
					'name' => 'group one',
6470
					'code' => 120)
6471
				)
6472
 
6473
			);
6474
		$this->assertEquals($expected, $results);
6475
		$this->assertEquals($expected, $resultsFkFalse);
6476
	}
6477
 
6478
/**
6479
 * test updateAll with empty values.
6480
 *
6481
 * @return void
6482
 */
6483
	public function testUpdateAllEmptyValues() {
6484
		$this->skipIf($this->db instanceof Sqlserver || $this->db instanceof Postgres, 'This test is not compatible with Postgres or SQL Server.');
6485
 
6486
		$this->loadFixtures('Author', 'Post');
6487
		$model = new Author();
6488
		$result = $model->updateAll(array('user' => '""'));
6489
		$this->assertTrue($result);
6490
	}
6491
 
6492
/**
6493
 * testUpdateAllWithJoins
6494
 *
6495
 * @return void
6496
 */
6497
	public function testUpdateAllWithJoins() {
6498
		$this->skipIf(!$this->db instanceof Mysql, 'Currently, there is no way of doing joins in an update statement in postgresql or sqlite');
6499
 
6500
		$this->loadFixtures('ProductUpdateAll', 'GroupUpdateAll');
6501
		$ProductUpdateAll = new ProductUpdateAll();
6502
 
6503
		$conditions = array('Group.name' => 'group one');
6504
 
6505
		$ProductUpdateAll->bindModel(array('belongsTo' => array(
6506
			'Group' => array('className' => 'GroupUpdateAll')))
6507
		);
6508
 
6509
		$ProductUpdateAll->updateAll(array('name' => "'new product'"), $conditions);
6510
		$results = $ProductUpdateAll->find('all', array(
6511
			'conditions' => array('ProductUpdateAll.name' => 'new product')
6512
		));
6513
		$expected = array(
6514
			'0' => array(
6515
				'ProductUpdateAll' => array(
6516
					'id' => 1,
6517
					'name' => 'new product',
6518
					'groupcode'	=> 120,
6519
					'group_id' => 1),
6520
				'Group' => array(
6521
					'id' => 1,
6522
					'name' => 'group one',
6523
					'code' => 120)
6524
				),
6525
			'1' => array(
6526
				'ProductUpdateAll' => array(
6527
					'id' => 2,
6528
					'name' => 'new product',
6529
					'groupcode' => 120,
6530
					'group_id' => 1),
6531
				'Group' => array(
6532
					'id' => 1,
6533
					'name' => 'group one',
6534
					'code' => 120)));
6535
 
6536
		$this->assertEquals($expected, $results);
6537
	}
6538
 
6539
/**
6540
 * testUpdateAllWithoutForeignKey
6541
 *
6542
 * @return void
6543
 */
6544
	public function testUpdateAllWithoutForeignKey() {
6545
		$this->skipIf(!$this->db instanceof Mysql, 'Currently, there is no way of doing joins in an update statement in postgresql');
6546
 
6547
		$this->loadFixtures('ProductUpdateAll', 'GroupUpdateAll');
6548
		$ProductUpdateAll = new ProductUpdateAll();
6549
 
6550
		$conditions = array('Group.name' => 'group one');
6551
 
6552
		$ProductUpdateAll->bindModel(array('belongsTo' => array(
6553
			'Group' => array('className' => 'GroupUpdateAll')
6554
		)));
6555
 
6556
		$ProductUpdateAll->belongsTo = array(
6557
			'Group' => array(
6558
				'className' => 'GroupUpdateAll',
6559
				'foreignKey' => false,
6560
				'conditions' => 'ProductUpdateAll.groupcode = Group.code'
6561
			)
6562
		);
6563
 
6564
		$ProductUpdateAll->updateAll(array('name' => "'new product'"), $conditions);
6565
		$resultsFkFalse = $ProductUpdateAll->find('all', array('conditions' => array('ProductUpdateAll.name' => 'new product')));
6566
		$expected = array(
6567
			'0' => array(
6568
				'ProductUpdateAll' => array(
6569
					'id' => 1,
6570
					'name' => 'new product',
6571
					'groupcode'	=> 120,
6572
					'group_id' => 1),
6573
				'Group' => array(
6574
					'id' => 1,
6575
					'name' => 'group one',
6576
					'code' => 120)
6577
				),
6578
			'1' => array(
6579
				'ProductUpdateAll' => array(
6580
					'id' => 2,
6581
					'name' => 'new product',
6582
					'groupcode' => 120,
6583
					'group_id' => 1),
6584
				'Group' => array(
6585
					'id' => 1,
6586
					'name' => 'group one',
6587
					'code' => 120)));
6588
		$this->assertEquals($expected, $resultsFkFalse);
6589
	}
6590
 
6591
/**
6592
 * test writing floats in german locale.
6593
 *
6594
 * @return void
6595
 */
6596
	public function testWriteFloatAsGerman() {
6597
		$restore = setlocale(LC_NUMERIC, 0);
6598
 
6599
		$this->skipIf(setlocale(LC_NUMERIC, 'de_DE') === false, "The German locale isn't available.");
6600
 
6601
		$model = new DataTest();
6602
		$result = $model->save(array(
6603
			'count' => 1,
6604
			'float' => 3.14593
6605
		));
6606
		$this->assertTrue((bool)$result);
6607
		setlocale(LC_NUMERIC, $restore);
6608
	}
6609
 
6610
/**
6611
 * Test returned array contains primary key when save creates a new record
6612
 *
6613
 * @return void
6614
 */
6615
	public function testPkInReturnArrayForCreate() {
6616
		$this->loadFixtures('Article');
6617
		$TestModel = new Article();
6618
 
6619
		$data = array('Article' => array(
6620
			'user_id' => '1',
6621
			'title' => 'Fourth Article',
6622
			'body' => 'Fourth Article Body',
6623
			'published' => 'Y'
6624
		));
6625
		$result = $TestModel->save($data);
6626
		$this->assertSame($result['Article']['id'], $TestModel->id);
6627
	}
6628
 
6629
/**
6630
 * testSaveAllFieldListValidateBelongsTo
6631
 *
6632
 * @return void
6633
 */
6634
	public function testSaveAllFieldListValidateBelongsTo() {
6635
		$this->loadFixtures('Post', 'Author', 'Comment', 'Attachment');
6636
		$TestModel = new Post();
6637
 
6638
		$result = $TestModel->find('all');
6639
		$this->assertEquals(3, count($result));
6640
		$this->assertFalse(isset($result[3]));
6641
 
6642
		// test belongsTo
6643
		$fieldList = array(
6644
			'Post' => array('title'),
6645
			'Author' => array('user')
6646
		);
6647
		$data = array(
6648
			'Post' => array(
6649
				'title' => 'Post without body',
6650
				'body' => 'This will not be saved',
6651
			),
6652
			'Author' => array(
6653
				'user' => 'bob',
6654
				'test' => 'This will not be saved',
6655
 
6656
		));
6657
		$TestModel->saveAll($data, array('fieldList' => $fieldList));
6658
 
6659
		$result = $TestModel->find('all', array(
6660
			'order' => 'Post.id ASC',
6661
		));
6662
		$expected = array(
6663
			'Post' => array(
6664
				'id' => '4',
6665
				'author_id' => '5',
6666
				'title' => 'Post without body',
6667
				'body' => null,
6668
				'published' => 'N',
6669
				'created' => self::date(),
6670
				'updated' => self::date(),
6671
			),
6672
			'Author' => array(
6673
				'id' => '5',
6674
				'user' => 'bob',
6675
				'password' => null,
6676
				'created' => self::date(),
6677
				'updated' => self::date(),
6678
				'test' => 'working',
6679
			),
6680
		);
6681
		$this->assertEquals($expected, $result[3]);
6682
		$this->assertEquals(4, count($result));
6683
		$this->assertEquals('', $result[3]['Post']['body']);
6684
		$this->assertEquals('working', $result[3]['Author']['test']);
6685
 
6686
		$fieldList = array(
6687
			'Post' => array('title')
6688
		);
6689
		$data = array(
6690
			'Post' => array(
6691
				'title' => 'Post without body 2',
6692
				'body' => 'This will not be saved'
6693
			),
6694
			'Author' => array(
6695
				'user' => 'jack'
6696
			)
6697
		);
6698
		$TestModel->saveAll($data, array('fieldList' => $fieldList));
6699
		$result = $TestModel->find('all', array(
6700
			'order' => 'Post.id ASC',
6701
		));
6702
		$this->assertNull($result[4]['Post']['body']);
6703
 
6704
		$fieldList = array(
6705
			'Author' => array('password')
6706
		);
6707
		$data = array(
6708
			'Post' => array(
6709
				'id' => '5',
6710
				'title' => 'Post title',
6711
				'body' => 'Post body'
6712
			),
6713
			'Author' => array(
6714
				'id' => '6',
6715
				'user' => 'will not change',
6716
				'password' => 'foobar'
6717
			)
6718
		);
6719
		$result = $TestModel->saveAll($data, array('fieldList' => $fieldList));
6720
		$this->assertTrue($result);
6721
 
6722
		$result = $TestModel->find('all', array(
6723
			'order' => 'Post.id ASC',
6724
		));
6725
		$expected = array(
6726
			'Post' => array(
6727
				'id' => '5',
6728
				'author_id' => '6',
6729
				'title' => 'Post title',
6730
				'body' => 'Post body',
6731
				'published' => 'N',
6732
				'created' => self::date(),
6733
				'updated' => self::date()
6734
			),
6735
			'Author' => array(
6736
				'id' => '6',
6737
				'user' => 'jack',
6738
				'password' => 'foobar',
6739
				'created' => self::date(),
6740
				'updated' => self::date(),
6741
				'test' => 'working'
6742
			),
6743
		);
6744
		$this->assertEquals($expected, $result[4]);
6745
 
6746
		// test multirecord
6747
		$this->db->truncate($TestModel);
6748
 
6749
		$fieldList = array('title', 'author_id');
6750
		$TestModel->saveAll(array(
6751
			array(
6752
				'title' => 'Multi-record post 1',
6753
				'body' => 'First multi-record post',
6754
				'author_id' => 2
6755
			),
6756
			array(
6757
				'title' => 'Multi-record post 2',
6758
				'body' => 'Second multi-record post',
6759
				'author_id' => 2
6760
		)), array('fieldList' => $fieldList));
6761
 
6762
		$result = $TestModel->find('all', array(
6763
			'recursive' => -1,
6764
			'order' => 'Post.id ASC'
6765
		));
6766
		$expected = array(
6767
			array(
6768
				'Post' => array(
6769
					'id' => '1',
6770
					'author_id' => '2',
6771
					'title' => 'Multi-record post 1',
6772
					'body' => '',
6773
					'published' => 'N',
6774
					'created' => self::date(),
6775
					'updated' => self::date()
6776
				)
6777
			),
6778
			array(
6779
				'Post' => array(
6780
					'id' => '2',
6781
					'author_id' => '2',
6782
					'title' => 'Multi-record post 2',
6783
					'body' => '',
6784
					'published' => 'N',
6785
					'created' => self::date(),
6786
					'updated' => self::date()
6787
				)
6788
			)
6789
		);
6790
		$this->assertEquals($expected, $result);
6791
	}
6792
 
6793
/**
6794
 * testSaveAllFieldListHasMany method
6795
 *
6796
 * @return void
6797
 */
6798
	public function testSaveAllFieldListHasMany() {
6799
		$this->loadFixtures('Article', 'Comment');
6800
		$TestModel = new Article();
6801
		$TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
6802
 
6803
		$this->db->truncate($TestModel);
6804
		$this->db->truncate(new Comment());
6805
 
6806
		$data = array(
6807
			'Article' => array('title' => 'I will not save'),
6808
			'Comment' => array(
6809
				array('comment' => 'First new comment', 'published' => 'Y', 'user_id' => 1),
6810
				array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
6811
			)
6812
		);
6813
 
6814
		$fieldList = array(
6815
			'Article' => array('id'),
6816
			'Comment' => array('article_id', 'user_id')
6817
		);
6818
		$TestModel->saveAll($data, array('fieldList' => $fieldList));
6819
 
6820
		$result = $TestModel->find('all');
6821
		$this->assertEquals('', $result[0]['Article']['title']);
6822
		$this->assertEquals('', $result[0]['Comment'][0]['comment']);
6823
		$this->assertEquals('', $result[0]['Comment'][1]['comment']);
6824
 
6825
		$fieldList = array(
6826
			'Article' => array('id'),
6827
			'Comment' => array('user_id')
6828
		);
6829
		$TestModel->saveAll($data, array('fieldList' => $fieldList));
6830
		$result = $TestModel->find('all');
6831
 
6832
		$this->assertEquals('', $result[1]['Article']['title']);
6833
		$this->assertEquals(2, count($result[1]['Comment']));
6834
 
6835
		$TestModel->whitelist = array('id');
6836
		$TestModel->Comment->whitelist = array('user_id');
6837
		$TestModel->saveAll($data);
6838
		$result = $TestModel->find('all');
6839
 
6840
		$this->assertEquals('', $result[2]['Article']['title']);
6841
		$this->assertEquals(2, count($result[2]['Comment']));
6842
	}
6843
 
6844
/**
6845
 * testSaveAllFieldListHasOne method
6846
 *
6847
 * @return void
6848
 */
6849
	public function testSaveAllFieldListHasOne() {
6850
		$this->loadFixtures('Attachment', 'Comment', 'Article', 'User');
6851
		$TestModel = new Comment();
6852
 
6853
		$TestModel->validate = array('comment' => 'notEmpty');
6854
		$TestModel->Attachment->validate = array('attachment' => 'notEmpty');
6855
 
6856
		$record = array(
6857
			'Comment' => array(
6858
				'user_id' => 1,
6859
				'article_id' => 1,
6860
				'comment' => '',
6861
			),
6862
			'Attachment' => array(
6863
				'attachment' => ''
6864
			)
6865
		);
6866
		$result = $TestModel->saveAll($record, array('validate' => 'only'));
6867
		$this->assertFalse($result);
6868
 
6869
		$fieldList = array(
6870
			'Comment' => array('id', 'article_id', 'user_id'),
6871
			'Attachment' => array('comment_id')
6872
		);
6873
		$result = $TestModel->saveAll($record, array(
6874
			'fieldList' => $fieldList, 'validate' => 'only'
6875
		));
6876
		$this->assertTrue($result);
6877
		$this->assertEmpty($TestModel->validationErrors);
6878
	}
6879
 
6880
/**
6881
 * testSaveAllFieldListHasOneAddFkToWhitelist method
6882
 *
6883
 * @return void
6884
 */
6885
	public function testSaveAllFieldListHasOneAddFkToWhitelist() {
6886
		$this->loadFixtures('ArticleFeatured', 'Featured');
6887
		$Article = new ArticleFeatured();
6888
		$Article->belongsTo = $Article->hasMany = array();
6889
		$Article->Featured->validate = array('end_date' => 'notEmpty');
6890
 
6891
		$record = array(
6892
			'ArticleFeatured' => array(
6893
				'user_id' => 1,
6894
				'title' => 'First Article',
6895
				'body' => '',
6896
				'published' => 'Y'
6897
			),
6898
			'Featured' => array(
6899
				'category_id' => 1,
6900
				'end_date' => ''
6901
			)
6902
		);
6903
		$result = $Article->saveAll($record, array('validate' => 'only'));
6904
		$this->assertFalse($result);
6905
		$expected = array(
6906
			'body' => array(
6907
				'This field cannot be left blank'
6908
			),
6909
			'Featured' => array(
6910
				'end_date' => array(
6911
					'This field cannot be left blank'
6912
				)
6913
			)
6914
		);
6915
		$this->assertEquals($expected, $Article->validationErrors);
6916
 
6917
		$fieldList = array(
6918
			'ArticleFeatured' => array('user_id', 'title'),
6919
			'Featured' => array('category_id')
6920
		);
6921
 
6922
		$result = $Article->saveAll($record, array(
6923
			'fieldList' => $fieldList, 'validate' => 'first'
6924
		));
6925
		$this->assertTrue($result);
6926
		$this->assertEmpty($Article->validationErrors);
6927
 
6928
		$Article->recursive = 0;
6929
		$result = $Article->find('first', array('order' => array('ArticleFeatured.created' => 'DESC')));
6930
		$this->assertSame($result['ArticleFeatured']['id'], $result['Featured']['article_featured_id']);
6931
	}
6932
 
6933
/**
6934
 * testSaveAllDeepFieldListValidateBelongsTo
6935
 *
6936
 * @return void
6937
 */
6938
	public function testSaveAllDeepFieldListValidateBelongsTo() {
6939
		$this->loadFixtures('Post', 'Author', 'Comment', 'Attachment', 'Article', 'User');
6940
		$TestModel = new Post();
6941
		$TestModel->Author->bindModel(array('hasMany' => array('Comment' => array('foreignKey' => 'user_id'))), false);
6942
		$TestModel->recursive = 2;
6943
 
6944
		$result = $TestModel->find('all');
6945
		$this->assertEquals(3, count($result));
6946
		$this->assertFalse(isset($result[3]));
6947
 
6948
		// test belongsTo
6949
		$fieldList = array(
6950
			'Post' => array('title', 'author_id'),
6951
			'Author' => array('user'),
6952
			'Comment' => array('comment')
6953
		);
6954
		$TestModel->saveAll(array(
6955
			'Post' => array(
6956
				'title' => 'Post without body',
6957
				'body' => 'This will not be saved',
6958
			),
6959
			'Author' => array(
6960
				'user' => 'bob',
6961
				'test' => 'This will not be saved',
6962
				'Comment' => array(
6963
					array('id' => 5, 'comment' => 'I am still published', 'published' => 'N'))
6964
 
6965
		)), array('fieldList' => $fieldList, 'deep' => true));
6966
 
6967
		$result = $TestModel->Author->Comment->find('first', array(
6968
			'conditions' => array('Comment.id' => 5),
6969
			'fields' => array('comment', 'published')
6970
		));
6971
		$expected = array(
6972
			'Comment' => array(
6973
				'comment' => 'I am still published',
6974
				'published' => 'Y'
6975
			)
6976
		);
6977
		$this->assertEquals($expected, $result);
6978
	}
6979
 
6980
/**
6981
 * testSaveAllDeepFieldListHasMany method
6982
 *
6983
 * @return void
6984
 */
6985
	public function testSaveAllDeepFieldListHasMany() {
6986
		$this->loadFixtures('Article', 'Comment', 'User');
6987
		$TestModel = new Article();
6988
		$TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
6989
 
6990
		$this->db->truncate($TestModel);
6991
		$this->db->truncate(new Comment());
6992
 
6993
		$fieldList = array(
6994
			'Article' => array('id'),
6995
			'Comment' => array('article_id', 'user_id'),
6996
			'User' => array('user')
6997
		);
6998
 
6999
		$result = $TestModel->saveAll(array(
7000
			'Article' => array('id' => 2, 'title' => 'I will not save'),
7001
			'Comment' => array(
7002
				array('comment' => 'First new comment', 'published' => 'Y', 'user_id' => 1),
7003
				array(
7004
					'comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2,
7005
					'User' => array('user' => 'nopassword', 'password' => 'not saved')
7006
				)
7007
			)
7008
		), array('fieldList' => $fieldList, 'deep' => true));
7009
 
7010
		$result = $TestModel->Comment->User->find('first', array(
7011
			'conditions' => array('User.user' => 'nopassword'),
7012
			'fields' => array('user', 'password')
7013
		));
7014
		$expected = array(
7015
			'User' => array(
7016
				'user' => 'nopassword',
7017
				'password' => ''
7018
			)
7019
		);
7020
		$this->assertEquals($expected, $result);
7021
	}
7022
 
7023
/**
7024
 * testSaveAllDeepHasManyBelongsTo method
7025
 *
7026
 * @return void
7027
 */
7028
	public function testSaveAllDeepHasManyBelongsTo() {
7029
		$this->loadFixtures('Article', 'Comment', 'User');
7030
		$TestModel = new Article();
7031
		$TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
7032
 
7033
		$this->db->truncate($TestModel);
7034
		$this->db->truncate(new Comment());
7035
 
7036
		$result = $TestModel->saveAll(array(
7037
			'Article' => array('id' => 2, 'title' => 'The title'),
7038
			'Comment' => array(
7039
				array('comment' => 'First new comment', 'published' => 'Y', 'user_id' => 1),
7040
				array(
7041
					'comment' => 'belongsto', 'published' => 'Y',
7042
					'User' => array('user' => 'findme', 'password' => 'somepass')
7043
				)
7044
			)
7045
		), array('deep' => true));
7046
 
7047
		$result = $TestModel->Comment->User->find('first', array(
7048
			'conditions' => array('User.user' => 'findme'),
7049
			'fields' => array('id', 'user', 'password')
7050
		));
7051
		$expected = array(
7052
			'User' => array(
7053
				'id' => 5,
7054
				'user' => 'findme',
7055
				'password' => 'somepass',
7056
			)
7057
		);
7058
		$this->assertEquals($expected, $result);
7059
 
7060
		$result = $TestModel->Comment->find('first', array(
7061
			'conditions' => array('Comment.user_id' => 5),
7062
			'fields' => array('id', 'comment', 'published', 'user_id')
7063
		));
7064
		$expected = array(
7065
			'Comment' => array(
7066
				'id' => 2,
7067
				'comment' => 'belongsto',
7068
				'published' => 'Y',
7069
				'user_id' => 5
7070
			)
7071
		);
7072
		$this->assertEquals($expected, $result);
7073
	}
7074
 
7075
/**
7076
 * testSaveAllDeepHasManyhasMany method
7077
 *
7078
 * @return void
7079
 */
7080
	public function testSaveAllDeepHasManyHasMany() {
7081
		$this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
7082
		$TestModel = new Article();
7083
		$TestModel->belongsTo = $TestModel->hasAndBelongsToMany = $TestModel->Comment->belongsTo = array();
7084
		$TestModel->Comment->unbindModel(array('hasOne' => array('Attachment')), false);
7085
		$TestModel->Comment->bindModel(array('hasMany' => array('Attachment')), false);
7086
 
7087
		$this->db->truncate($TestModel);
7088
		$this->db->truncate(new Comment());
7089
		$this->db->truncate(new Attachment());
7090
 
7091
		$result = $TestModel->saveAll(array(
7092
			'Article' => array('id' => 2, 'title' => 'The title'),
7093
			'Comment' => array(
7094
				array('comment' => 'First new comment', 'published' => 'Y', 'user_id' => 1),
7095
				array(
7096
					'comment' => 'hasmany', 'published' => 'Y', 'user_id' => 5,
7097
					'Attachment' => array(
7098
						array('attachment' => 'first deep attachment'),
7099
						array('attachment' => 'second deep attachment'),
7100
					)
7101
				)
7102
			)
7103
		), array('deep' => true));
7104
 
7105
		$result = $TestModel->Comment->find('first', array(
7106
			'conditions' => array('Comment.comment' => 'hasmany'),
7107
			'fields' => array('id', 'comment', 'published', 'user_id'),
7108
			'recursive' => -1
7109
		));
7110
		$expected = array(
7111
			'Comment' => array(
7112
				'id' => 2,
7113
				'comment' => 'hasmany',
7114
				'published' => 'Y',
7115
				'user_id' => 5
7116
			)
7117
		);
7118
		$this->assertEquals($expected, $result);
7119
 
7120
		$result = $TestModel->Comment->Attachment->find('all', array(
7121
			'fields' => array('attachment', 'comment_id'),
7122
			'order' => array('Attachment.id' => 'ASC')
7123
		));
7124
		$expected = array(
7125
			array('Attachment' => array('attachment' => 'first deep attachment', 'comment_id' => 2)),
7126
			array('Attachment' => array('attachment' => 'second deep attachment', 'comment_id' => 2)),
7127
		);
7128
		$this->assertEquals($expected, $result);
7129
	}
7130
 
7131
/**
7132
 * testSaveAllDeepOrderHasManyHasMany method
7133
 *
7134
 * @return void
7135
 */
7136
	public function testSaveAllDeepOrderHasManyHasMany() {
7137
		$this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
7138
		$TestModel = new Article();
7139
		$TestModel->belongsTo = $TestModel->hasAndBelongsToMany = $TestModel->Comment->belongsTo = array();
7140
		$TestModel->Comment->unbindModel(array('hasOne' => array('Attachment')), false);
7141
		$TestModel->Comment->bindModel(array('hasMany' => array('Attachment')), false);
7142
 
7143
		$this->db->truncate($TestModel);
7144
		$this->db->truncate(new Comment());
7145
		$this->db->truncate(new Attachment());
7146
 
7147
		$result = $TestModel->saveAll(array(
7148
			'Article' => array('id' => 2, 'title' => 'Comment has its data after Attachment'),
7149
			'Comment' => array(
7150
				array(
7151
					'Attachment' => array(
7152
						array('attachment' => 'attachment should be created with comment_id'),
7153
						array('attachment' => 'comment should be created with article_id'),
7154
					),
7155
					'comment' => 'after associated data',
7156
					'user_id' => 1
7157
				)
7158
			)
7159
		), array('deep' => true));
7160
		$result = $TestModel->Comment->find('first', array(
7161
			'conditions' => array('Comment.article_id' => 2),
7162
		));
7163
 
7164
		$this->assertEquals(2, $result['Comment']['article_id']);
7165
		$this->assertEquals(2, count($result['Attachment']));
7166
	}
7167
 
7168
/**
7169
 * testSaveAllDeepEmptyHasManyHasMany method
7170
 *
7171
 * @return void
7172
 */
7173
	public function testSaveAllDeepEmptyHasManyHasMany() {
7174
		$this->skipIf(!$this->db instanceof Mysql, 'This test is only compatible with Mysql.');
7175
 
7176
		$this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
7177
		$TestModel = new Article();
7178
		$TestModel->belongsTo = $TestModel->hasAndBelongsToMany = $TestModel->Comment->belongsTo = array();
7179
		$TestModel->Comment->unbindModel(array('hasOne' => array('Attachment')), false);
7180
		$TestModel->Comment->bindModel(array('hasMany' => array('Attachment')), false);
7181
 
7182
		$this->db->truncate($TestModel);
7183
		$this->db->truncate(new Comment());
7184
		$this->db->truncate(new Attachment());
7185
 
7186
		$result = $TestModel->saveAll(array(
7187
			'Article' => array('id' => 3, 'user_id' => 1, 'title' => 'Comment has no data'),
7188
			'Comment' => array(
7189
				array(
7190
					'user_id' => 1,
7191
					'Attachment' => array(
7192
						array('attachment' => 'attachment should be created with comment_id'),
7193
						array('attachment' => 'comment should be created with article_id'),
7194
					),
7195
				)
7196
			)
7197
		), array('deep' => true));
7198
		$result = $TestModel->Comment->find('first', array(
7199
			'conditions' => array('Comment.article_id' => 3),
7200
		));
7201
 
7202
		$this->assertEquals(3, $result['Comment']['article_id']);
7203
		$this->assertEquals(2, count($result['Attachment']));
7204
	}
7205
 
7206
/**
7207
 * testUpdateAllBoolean
7208
 *
7209
 * @return void
7210
 */
7211
	public function testUpdateAllBoolean() {
7212
		$this->loadFixtures('Item', 'Syfile', 'Portfolio', 'Image', 'ItemsPortfolio');
7213
		$TestModel = new Item();
7214
		$result = $TestModel->updateAll(array('published' => true));
7215
		$this->assertTrue($result);
7216
 
7217
		$result = $TestModel->find('first', array('fields' => array('id', 'published')));
7218
		$this->assertEquals(true, $result['Item']['published']);
7219
	}
7220
 
7221
/**
7222
 * testUpdateAllBooleanConditions
7223
 *
7224
 * @return void
7225
 */
7226
	public function testUpdateAllBooleanConditions() {
7227
		$this->loadFixtures('Item', 'Syfile', 'Portfolio', 'Image', 'ItemsPortfolio');
7228
		$TestModel = new Item();
7229
 
7230
		$result = $TestModel->updateAll(array('published' => true), array('Item.id' => 1));
7231
		$this->assertTrue($result);
7232
		$result = $TestModel->find('first', array(
7233
			'fields' => array('id', 'published'),
7234
			'conditions' => array('Item.id' => 1)));
7235
		$this->assertEquals(true, $result['Item']['published']);
7236
	}
7237
 
7238
/**
7239
 * testUpdateBoolean
7240
 *
7241
 * @return void
7242
 */
7243
	public function testUpdateBoolean() {
7244
		$this->loadFixtures('Item', 'Syfile', 'Portfolio', 'Image', 'ItemsPortfolio');
7245
		$TestModel = new Item();
7246
 
7247
		$result = $TestModel->save(array('published' => true, 'id' => 1));
7248
		$this->assertTrue((bool)$result);
7249
		$result = $TestModel->find('first', array(
7250
			'fields' => array('id', 'published'),
7251
			'conditions' => array('Item.id' => 1)));
7252
		$this->assertEquals(true, $result['Item']['published']);
7253
	}
7254
 
7255
/**
7256
 * Test the clear() method.
7257
 *
7258
 * @return void
7259
 */
7260
	public function testClear() {
7261
		$this->loadFixtures('Bid');
7262
		$model = ClassRegistry::init('Bid');
7263
		$model->set(array('name' => 'Testing', 'message_id' => 3));
7264
		$this->assertTrue(isset($model->data['Bid']['name']));
7265
		$this->assertTrue($model->clear());
7266
		$this->assertFalse(isset($model->data['Bid']['name']));
7267
		$this->assertFalse(isset($model->data['Bid']['message_id']));
7268
	}
7269
 
7270
/**
7271
 * Test that Model::save() doesn't generate a query with WHERE 1 = 1 on race condition.
7272
 *
7273
 * @link https://github.com/cakephp/cakephp/issues/3857
7274
 * @return void
7275
 */
7276
	public function testSafeUpdateMode() {
7277
		$this->loadFixtures('User');
7278
 
7279
		$User = ClassRegistry::init('User');
7280
		$this->assertFalse($User->__safeUpdateMode);
7281
 
7282
		$User->getEventManager()->attach(array($this, 'deleteMe'), 'Model.beforeSave');
7283
 
7284
		$User->id = 1;
7285
		$User->set(array('user' => 'nobody'));
7286
		$User->save();
7287
 
7288
		$users = $User->find('list', array('fields' => 'User.user'));
7289
 
7290
		$expected = array(
7291
			2 => 'nate',
7292
			3 => 'larry',
7293
			4 => 'garrett',
7294
		);
7295
		$this->assertEquals($expected, $users);
7296
		$this->assertFalse($User->__safeUpdateMode);
7297
 
7298
		$User->id = 2;
7299
		$User->set(array('user' => $User->getDataSource()->expression('PDO_EXCEPTION()')));
7300
		try {
7301
			$User->save(null, false);
7302
			$this->fail('No exception thrown');
7303
		} catch (PDOException $e) {
7304
			$this->assertFalse($User->__safeUpdateMode);
7305
		}
7306
	}
7307
 
7308
/**
7309
 * Emulates race condition
7310
 *
7311
 * @param CakeEvent $event containing the Model
7312
 * @return void
7313
 */
7314
	public function deleteMe($event) {
7315
		$Model = $event->subject;
7316
		$Model->getDataSource()->delete($Model, array($Model->alias . '.' . $Model->primaryKey => $Model->id));
7317
	}
7318
}