統計
| ブランチ: | リビジョン:

pictcode / lib / Cake / Test / Case / Model / ModelWriteTest.php @ 0b1b8047

履歴 | 表示 | アノテート | ダウンロード (222.805 KB)

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
        public $dataForAfterSave;
40

    
41
/**
42
 * Helper method to set a datasource object
43
 *
44
 * @param Object $object The datasource object
45
 * @return void
46
 */
47
        public function setDataSourceObject($object) {
48
                $this->_dataSourceObject = $object;
49
        }
50

    
51
/**
52
 * Overwritten in order to return the directly set datasource object if
53
 * available
54
 *
55
 * @return DataSource
56
 */
57
        public function getDataSource() {
58
                if ($this->_dataSourceObject !== null) {
59
                        return $this->_dataSourceObject;
60
                }
61
                return parent::getDataSource();
62
        }
63

    
64
}
65

    
66
/**
67
 * Helper class for testing with mocked datasources
68
 */
69
class TestPost extends Post {
70

    
71
        public $belongsTo = array(
72
                'Author' => array(
73
                        'className' => 'TestAuthor'
74
                )
75
        );
76

    
77
        protected $_dataSourceObject;
78

    
79
        public $dataForAfterSave;
80

    
81
/**
82
 * Helper method to set a datasource object
83
 *
84
 * @param Object $object The datasource object
85
 * @return void
86
 */
87
        public function setDataSourceObject($object) {
88
                $this->_dataSourceObject = $object;
89
        }
90

    
91
/**
92
 * Overwritten in order to return the directly set datasource object if
93
 * available
94
 *
95
 * @return DataSource
96
 */
97
        public function getDataSource() {
98
                if ($this->_dataSourceObject !== null) {
99
                        return $this->_dataSourceObject;
100
                }
101
                return parent::getDataSource();
102
        }
103

    
104
}
105

    
106
/**
107
 * ModelWriteTest
108
 *
109
 * @package       Cake.Test.Case.Model
110
 */
111
class ModelWriteTest extends BaseModelTest {
112

    
113
/**
114
 * override locale to the default (eng).
115
 *
116
 * @return void
117
 */
118
        public function setUp() {
119
                parent::setUp();
120
                Configure::write('Config.language', 'eng');
121
        }
122

    
123
/**
124
 * Test save() failing when there is no data.
125
 *
126
 * @return void
127
 */
128
        public function testInsertNoData() {
129
                $this->loadFixtures('Bid');
130
                $Bid = ClassRegistry::init('Bid');
131

    
132
                $this->assertFalse($Bid->save());
133

    
134
                $result = $Bid->save(array('Bid' => array()));
135
                $this->assertFalse($result);
136

    
137
                $result = $Bid->save(array('Bid' => array('not in schema' => 1)));
138
                $this->assertFalse($result);
139
        }
140

    
141
/**
142
 * testInsertAnotherHabtmRecordWithSameForeignKey method
143
 *
144
 * @return void
145
 */
146
        public function testInsertAnotherHabtmRecordWithSameForeignKey() {
147
                $this->loadFixtures('JoinA', 'JoinB', 'JoinAB', 'JoinC', 'JoinAC');
148
                $TestModel = new JoinA();
149

    
150
                $result = $TestModel->JoinAsJoinB->findById(1);
151
                $expected = array(
152
                        'JoinAsJoinB' => array(
153
                                'id' => 1,
154
                                'join_a_id' => 1,
155
                                'join_b_id' => 2,
156
                                'other' => 'Data for Join A 1 Join B 2',
157
                                'created' => '2008-01-03 10:56:33',
158
                                'updated' => '2008-01-03 10:56:33'
159
                ));
160
                $this->assertEquals($expected, $result);
161

    
162
                $TestModel->JoinAsJoinB->create();
163
                $data = array(
164
                        'join_a_id' => 1,
165
                        'join_b_id' => 1,
166
                        'other' => 'Data for Join A 1 Join B 1',
167
                        'created' => '2008-01-03 10:56:44',
168
                        'updated' => '2008-01-03 10:56:44'
169
                );
170
                $result = $TestModel->JoinAsJoinB->save($data);
171
                $lastInsertId = $TestModel->JoinAsJoinB->getLastInsertID();
172
                $data['id'] = $lastInsertId;
173
                $this->assertEquals(array('JoinAsJoinB' => $data), $result);
174
                $this->assertTrue($lastInsertId > 0);
175

    
176
                $result = $TestModel->JoinAsJoinB->findById(1);
177
                $expected = array(
178
                        'JoinAsJoinB' => array(
179
                                'id' => 1,
180
                                'join_a_id' => 1,
181
                                'join_b_id' => 2,
182
                                'other' => 'Data for Join A 1 Join B 2',
183
                                'created' => '2008-01-03 10:56:33',
184
                                'updated' => '2008-01-03 10:56:33'
185
                ));
186
                $this->assertEquals($expected, $result);
187

    
188
                $updatedValue = 'UPDATED Data for Join A 1 Join B 2';
189
                $TestModel->JoinAsJoinB->id = 1;
190
                $result = $TestModel->JoinAsJoinB->saveField('other', $updatedValue, false);
191
                $this->assertFalse(empty($result));
192

    
193
                $result = $TestModel->JoinAsJoinB->findById(1);
194
                $this->assertEquals($updatedValue, $result['JoinAsJoinB']['other']);
195
        }
196

    
197
/**
198
 * testSaveDateAsFirstEntry method
199
 *
200
 * @return void
201
 */
202
        public function testSaveDateAsFirstEntry() {
203
                $this->loadFixtures('Article', 'User', 'Comment', 'Attachment', 'Tag', 'ArticlesTag');
204

    
205
                $Article = new Article();
206

    
207
                $data = array(
208
                        'Article' => array(
209
                                'created' => array(
210
                                        'day' => '1',
211
                                        'month' => '1',
212
                                        'year' => '2008'
213
                                ),
214
                                'title' => 'Test Title',
215
                                'user_id' => 1
216
                ));
217
                $Article->create();
218
                $result = $Article->save($data);
219
                $this->assertFalse(empty($result));
220

    
221
                $testResult = $Article->find('first', array('conditions' => array('Article.title' => 'Test Title')));
222

    
223
                $this->assertEquals($data['Article']['title'], $testResult['Article']['title']);
224
                $this->assertEquals('2008-01-01 00:00:00', $testResult['Article']['created']);
225
        }
226

    
227
/**
228
 * testUnderscoreFieldSave method
229
 *
230
 * @return void
231
 */
232
        public function testUnderscoreFieldSave() {
233
                $this->loadFixtures('UnderscoreField');
234
                $UnderscoreField = new UnderscoreField();
235

    
236
                $currentCount = $UnderscoreField->find('count');
237
                $this->assertEquals(3, $currentCount);
238
                $data = array('UnderscoreField' => array(
239
                        'user_id' => '1',
240
                        'my_model_has_a_field' => 'Content here',
241
                        'body' => 'Body',
242
                        'published' => 'Y',
243
                        'another_field' => 4
244
                ));
245
                $ret = $UnderscoreField->save($data);
246
                $this->assertFalse(empty($ret));
247

    
248
                $currentCount = $UnderscoreField->find('count');
249
                $this->assertEquals(4, $currentCount);
250
        }
251

    
252
/**
253
 * testAutoSaveUuid method
254
 *
255
 * @return void
256
 */
257
        public function testAutoSaveUuid() {
258
                // SQLite does not support non-integer primary keys
259
                $this->skipIf($this->db instanceof Sqlite, 'This test is not compatible with SQLite.');
260

    
261
                $this->loadFixtures('Uuid');
262
                $TestModel = new Uuid();
263

    
264
                $TestModel->save(array('title' => 'Test record'));
265
                $result = $TestModel->findByTitle('Test record');
266
                $this->assertEquals(
267
                        array('id', 'title', 'count', 'created', 'updated'),
268
                        array_keys($result['Uuid'])
269
                );
270
                $this->assertEquals(36, strlen($result['Uuid']['id']));
271
        }
272

    
273
/**
274
 * Ensure that if the id key is null but present the save doesn't fail (with an
275
 * x sql error: "Column id specified twice")
276
 *
277
 * @return void
278
 */
279
        public function testSaveUuidNull() {
280
                // SQLite does not support non-integer primary keys
281
                $this->skipIf($this->db instanceof Sqlite, 'This test is not compatible with SQLite.');
282

    
283
                $this->loadFixtures('Uuid');
284
                $TestModel = new Uuid();
285

    
286
                $TestModel->save(array('title' => 'Test record', 'id' => null));
287
                $result = $TestModel->findByTitle('Test record');
288
                $this->assertEquals(
289
                        array('id', 'title', 'count', 'created', 'updated'),
290
                        array_keys($result['Uuid'])
291
                );
292
                $this->assertEquals(36, strlen($result['Uuid']['id']));
293
        }
294

    
295
/**
296
 * testZeroDefaultFieldValue method
297
 *
298
 * @return void
299
 */
300
        public function testZeroDefaultFieldValue() {
301
                $this->skipIf($this->db instanceof Sqlite, 'SQLite uses loose typing, this operation is unsupported.');
302

    
303
                $this->loadFixtures('DataTest');
304
                $TestModel = new DataTest();
305

    
306
                $TestModel->create(array());
307
                $TestModel->save();
308
                $result = $TestModel->findById($TestModel->id);
309
                $this->assertEquals(0, $result['DataTest']['count']);
310
                $this->assertEquals(0, $result['DataTest']['float']);
311
        }
312

    
313
/**
314
 * Tests validation parameter order in custom validation methods
315
 *
316
 * @return void
317
 */
318
        public function testAllowSimulatedFields() {
319
                $TestModel = new ValidationTest1();
320

    
321
                $TestModel->create(array(
322
                        'title' => 'foo',
323
                        'bar' => 'baz'
324
                ));
325
                $expected = array(
326
                        'ValidationTest1' => array(
327
                                'title' => 'foo',
328
                                'bar' => 'baz'
329
                ));
330
                $this->assertEquals($expected, $TestModel->data);
331
        }
332

    
333
/**
334
 * test that Caches are getting cleared on save().
335
 * ensure that both inflections of controller names are getting cleared
336
 * as URL for controller could be either overallFavorites/index or overall_favorites/index
337
 *
338
 * @return void
339
 */
340
        public function testCacheClearOnSave() {
341
                $_back = array(
342
                        'check' => Configure::read('Cache.check'),
343
                        'disable' => Configure::read('Cache.disable'),
344
                );
345
                Configure::write('Cache.check', true);
346
                Configure::write('Cache.disable', false);
347

    
348
                $this->loadFixtures('OverallFavorite');
349
                $OverallFavorite = new OverallFavorite();
350

    
351
                touch(CACHE . 'views' . DS . 'some_dir_overallfavorites_index.php');
352
                touch(CACHE . 'views' . DS . 'some_dir_overall_favorites_index.php');
353

    
354
                $data = array(
355
                        'OverallFavorite' => array(
356
                                'id' => 22,
357
                                'model_type' => '8-track',
358
                                'model_id' => '3',
359
                                'priority' => '1'
360
                        )
361
                );
362
                $OverallFavorite->create($data);
363
                $OverallFavorite->save();
364

    
365
                $this->assertFalse(file_exists(CACHE . 'views' . DS . 'some_dir_overallfavorites_index.php'));
366
                $this->assertFalse(file_exists(CACHE . 'views' . DS . 'some_dir_overall_favorites_index.php'));
367

    
368
                Configure::write('Cache.check', $_back['check']);
369
                Configure::write('Cache.disable', $_back['disable']);
370
        }
371

    
372
/**
373
 * test that save() resets whitelist on failed save
374
 *
375
 * @return void
376
 */
377
        public function testSaveFieldListResetsWhitelistOnFailedSave() {
378
                $this->loadFixtures('Bidding');
379
                $model = new Bidding();
380
                $whitelist = array('title');
381
                $model->whitelist = $whitelist;
382
                $result = $model->save(
383
                        array(),
384
                        array('fieldList' => array('body'))
385
                );
386
                $this->assertFalse($result);
387
                $this->assertEquals($whitelist, $model->whitelist);
388
        }
389

    
390
/**
391
 * Test that save() with a fieldList continues to write
392
 * updated in all cases.
393
 *
394
 * @return void
395
 */
396
        public function testSaveUpdatedWithFieldList() {
397
                $this->loadFixtures('Post', 'Author');
398
                $model = ClassRegistry::init('Post');
399
                $original = $model->find('first', array(
400
                        'conditions' => array('Post.id' => 1)
401
                ));
402
                $data = array(
403
                        'Post' => array(
404
                                'id' => 1,
405
                                'title' => 'New title',
406
                                'updated' => '1999-01-01 00:00:00',
407
                        )
408
                );
409
                $model->save($data, array(
410
                        'fieldList' => array('title')
411
                ));
412
                $new = $model->find('first', array(
413
                        'conditions' => array('Post.id' => 1)
414
                ));
415
                $this->assertGreaterThan($original['Post']['updated'], $new['Post']['updated']);
416
        }
417

    
418
/**
419
 * Test save() resets the whitelist after afterSave
420
 *
421
 * @return void
422
 */
423
        public function testSaveResetWhitelistOnSuccess() {
424
                $this->loadFixtures('Post');
425

    
426
                $callback = array($this, 'callbackForWhitelistReset');
427
                $model = ClassRegistry::init('Post');
428
                $model->whitelist = array('author_id', 'title', 'body');
429
                $model->getEventManager()->attach($callback, 'Model.afterSave');
430
                $data = array(
431
                        'title' => 'New post',
432
                        'body' => 'Post body',
433
                        'author_id' => 1
434
                );
435
                $result = $model->save($data);
436
                $this->assertNotEmpty($result);
437
        }
438

    
439
/**
440
 * Callback for testing whitelist in afterSave
441
 *
442
 * @param Model $model The model having save called.
443
 * @return void
444
 */
445
        public function callbackForWhitelistReset($event) {
446
                $expected = array('author_id', 'title', 'body', 'updated', 'created');
447
                $this->assertEquals($expected, $event->subject()->whitelist);
448
        }
449

    
450
/**
451
 * testSaveWithCounterCache method
452
 *
453
 * @return void
454
 */
455
        public function testSaveWithCounterCache() {
456
                $this->loadFixtures('Syfile', 'Item', 'Image', 'Portfolio', 'ItemsPortfolio');
457
                $TestModel = new Syfile();
458
                $TestModel2 = new Item();
459

    
460
                $result = $TestModel->findById(1);
461
                $this->assertNull($result['Syfile']['item_count']);
462

    
463
                $TestModel2->save(array(
464
                        'name' => 'Item 7',
465
                        'syfile_id' => 1,
466
                        'published' => false
467
                ));
468

    
469
                $result = $TestModel->findById(1);
470
                $this->assertEquals(2, $result['Syfile']['item_count']);
471

    
472
                $TestModel2->delete(1);
473
                $result = $TestModel->findById(1);
474
                $this->assertEquals(1, $result['Syfile']['item_count']);
475

    
476
                $TestModel2->id = 2;
477
                $TestModel2->saveField('syfile_id', 1);
478

    
479
                $result = $TestModel->findById(1);
480
                $this->assertEquals(2, $result['Syfile']['item_count']);
481

    
482
                $result = $TestModel->findById(2);
483
                $this->assertEquals(0, $result['Syfile']['item_count']);
484
        }
485

    
486
/**
487
 * Tests that counter caches are updated when records are added
488
 *
489
 * @return void
490
 */
491
        public function testCounterCacheIncrease() {
492
                $this->loadFixtures('CounterCacheUser', 'CounterCachePost');
493
                $User = new CounterCacheUser();
494
                $Post = new CounterCachePost();
495
                $data = array('Post' => array(
496
                        'id' => 22,
497
                        'title' => 'New Post',
498
                        'user_id' => 66
499
                ));
500

    
501
                $Post->save($data);
502
                $user = $User->find('first', array(
503
                        'conditions' => array('id' => 66),
504
                        'recursive' => -1
505
                ));
506

    
507
                $result = $user[$User->alias]['post_count'];
508
                $expected = 3;
509
                $this->assertEquals($expected, $result);
510
        }
511

    
512
/**
513
 * Tests that counter caches are updated when records are deleted
514
 *
515
 * @return void
516
 */
517
        public function testCounterCacheDecrease() {
518
                $this->loadFixtures('CounterCacheUser', 'CounterCachePost');
519
                $User = new CounterCacheUser();
520
                $Post = new CounterCachePost();
521

    
522
                $Post->delete(2);
523
                $user = $User->find('first', array(
524
                        'conditions' => array('id' => 66),
525
                        'recursive' => -1
526
                ));
527

    
528
                $result = $user[$User->alias]['post_count'];
529
                $expected = 1;
530
                $this->assertEquals($expected, $result);
531
        }
532

    
533
/**
534
 * Tests that counter caches are updated when foreign keys of counted records change
535
 *
536
 * @return void
537
 */
538
        public function testCounterCacheUpdated() {
539
                $this->loadFixtures('CounterCacheUser', 'CounterCachePost');
540
                $User = new CounterCacheUser();
541
                $Post = new CounterCachePost();
542

    
543
                $data = $Post->find('first', array(
544
                        'conditions' => array('id' => 1),
545
                        'recursive' => -1
546
                ));
547
                $data[$Post->alias]['user_id'] = 301;
548
                $Post->save($data);
549

    
550
                $users = $User->find('all', array('order' => 'User.id'));
551
                $this->assertEquals(1, $users[0]['User']['post_count']);
552
                $this->assertEquals(2, $users[1]['User']['post_count']);
553
        }
554

    
555
/**
556
 * Test counter cache with models that use a non-standard (i.e. not using 'id')
557
 * as their primary key.
558
 *
559
 * @return void
560
 */
561
        public function testCounterCacheWithNonstandardPrimaryKey() {
562
                $this->loadFixtures(
563
                        'CounterCacheUserNonstandardPrimaryKey',
564
                        'CounterCachePostNonstandardPrimaryKey'
565
                );
566

    
567
                $User = new CounterCacheUserNonstandardPrimaryKey();
568
                $Post = new CounterCachePostNonstandardPrimaryKey();
569

    
570
                $data = $Post->find('first', array(
571
                        'conditions' => array('pid' => 1),
572
                        'recursive' => -1
573
                ));
574
                $data[$Post->alias]['uid'] = 301;
575
                $Post->save($data);
576

    
577
                $users = $User->find('all', array('order' => 'User.uid'));
578
                $this->assertEquals(1, $users[0]['User']['post_count']);
579
                $this->assertEquals(2, $users[1]['User']['post_count']);
580
        }
581

    
582
/**
583
 * test Counter Cache With Self Joining table
584
 *
585
 * @return void
586
 */
587
        public function testCounterCacheWithSelfJoin() {
588
                $this->skipIf($this->db instanceof Sqlite, 'SQLite 2.x does not support ALTER TABLE ADD COLUMN');
589

    
590
                $this->loadFixtures('CategoryThread');
591
                $column = 'COLUMN ';
592
                if ($this->db instanceof Sqlserver) {
593
                        $column = '';
594
                }
595
                $column .= $this->db->buildColumn(array('name' => 'child_count', 'type' => 'integer'));
596
                $this->db->query('ALTER TABLE ' . $this->db->fullTableName('category_threads') . ' ADD ' . $column);
597
                $this->db->flushMethodCache();
598
                $Category = new CategoryThread();
599
                $result = $Category->updateAll(array('CategoryThread.name' => "'updated'"), array('CategoryThread.parent_id' => 5));
600
                $this->assertFalse(empty($result));
601

    
602
                $Category = new CategoryThread();
603
                $Category->belongsTo['ParentCategory']['counterCache'] = 'child_count';
604
                $Category->updateCounterCache(array('parent_id' => 5));
605
                $result = Hash::extract($Category->find('all', array('conditions' => array('CategoryThread.id' => 5))), '{n}.CategoryThread.child_count');
606
                $expected = array(1);
607
                $this->assertEquals($expected, $result);
608
        }
609

    
610
/**
611
 * testSaveWithCounterCacheScope method
612
 *
613
 * @return void
614
 */
615
        public function testSaveWithCounterCacheScope() {
616
                $this->loadFixtures('Syfile', 'Item', 'Image', 'ItemsPortfolio', 'Portfolio');
617
                $TestModel = new Syfile();
618
                $TestModel2 = new Item();
619
                $TestModel2->belongsTo['Syfile']['counterCache'] = true;
620
                $TestModel2->belongsTo['Syfile']['counterScope'] = array('published' => true);
621

    
622
                $result = $TestModel->findById(1);
623
                $this->assertNull($result['Syfile']['item_count']);
624

    
625
                $TestModel2->save(array(
626
                        'name' => 'Item 7',
627
                        'syfile_id' => 1,
628
                        'published' => true
629
                ));
630

    
631
                $result = $TestModel->findById(1);
632

    
633
                $this->assertEquals(1, $result['Syfile']['item_count']);
634

    
635
                $TestModel2->id = 1;
636
                $TestModel2->saveField('published', true);
637
                $result = $TestModel->findById(1);
638
                $this->assertEquals(2, $result['Syfile']['item_count']);
639

    
640
                $TestModel2->save(array(
641
                        'id' => 1,
642
                        'syfile_id' => 1,
643
                        'published' => false
644
                ));
645

    
646
                $result = $TestModel->findById(1);
647
                $this->assertEquals(1, $result['Syfile']['item_count']);
648
        }
649

    
650
/**
651
 * Tests having multiple counter caches for an associated model
652
 *
653
 * @return void
654
 */
655
        public function testCounterCacheMultipleCaches() {
656
                $this->loadFixtures('CounterCacheUser', 'CounterCachePost');
657
                $User = new CounterCacheUser();
658
                $Post = new CounterCachePost();
659
                $Post->unbindModel(array('belongsTo' => array('User')), false);
660
                $Post->bindModel(array(
661
                        'belongsTo' => array(
662
                                'User' => array(
663
                                        'className' => 'CounterCacheUser',
664
                                        'foreignKey' => 'user_id',
665
                                        'counterCache' => array(
666
                                                true,
667
                                                'posts_published' => array('Post.published' => true)
668
                                        )
669
                                )
670
                        )
671
                ), false);
672

    
673
                // Count Increase
674
                $data = array('Post' => array(
675
                        'id' => 22,
676
                        'title' => 'New Post',
677
                        'user_id' => 66,
678
                        'published' => true
679
                ));
680
                $Post->save($data);
681
                $result = $User->find('first', array(
682
                        'conditions' => array('id' => 66),
683
                        'recursive' => -1
684
                ));
685
                $this->assertEquals(3, $result[$User->alias]['post_count']);
686
                $this->assertEquals(2, $result[$User->alias]['posts_published']);
687

    
688
                // Count decrease
689
                $Post->delete(1);
690
                $result = $User->find('first', array(
691
                        'conditions' => array('id' => 66),
692
                        'recursive' => -1
693
                ));
694
                $this->assertEquals(2, $result[$User->alias]['post_count']);
695
                $this->assertEquals(2, $result[$User->alias]['posts_published']);
696

    
697
                // Count update
698
                $data = $Post->find('first', array(
699
                        'conditions' => array('id' => 1),
700
                        'recursive' => -1
701
                ));
702
                $data[$Post->alias]['user_id'] = 301;
703
                $Post->save($data);
704
                $result = $User->find('all', array('order' => 'User.id'));
705
                $this->assertEquals(2, $result[0]['User']['post_count']);
706
                $this->assertEquals(1, $result[1]['User']['posts_published']);
707
        }
708

    
709
/**
710
 * Tests that counter caches are unchanged when using 'counterCache' => false
711
 *
712
 * @return void
713
 */
714
        public function testCounterCacheSkip() {
715
                $this->loadFixtures('CounterCacheUser', 'CounterCachePost');
716
                $User = new CounterCacheUser();
717
                $Post = new CounterCachePost();
718

    
719
                $data = $Post->find('first', array(
720
                        'conditions' => array('id' => 1),
721
                        'recursive' => -1
722
                ));
723
                $data[$Post->alias]['user_id'] = 301;
724
                $Post->save($data, array('counterCache' => false));
725

    
726
                $users = $User->find('all', array('order' => 'User.id'));
727
                $this->assertEquals(2, $users[0]['User']['post_count']);
728
                $this->assertEquals(1, $users[1]['User']['post_count']);
729
        }
730

    
731
/**
732
 * test that beforeValidate returning false can abort saves.
733
 *
734
 * @return void
735
 */
736
        public function testBeforeValidateSaveAbortion() {
737
                $this->loadFixtures('Post');
738
                $Model = new CallbackPostTestModel();
739
                $Model->beforeValidateReturn = false;
740

    
741
                $data = array(
742
                        'title' => 'new article',
743
                        'body' => 'this is some text.'
744
                );
745
                $Model->create();
746
                $result = $Model->save($data);
747
                $this->assertFalse($result);
748
        }
749

    
750
/**
751
 * test that beforeSave returning false can abort saves.
752
 *
753
 * @return void
754
 */
755
        public function testBeforeSaveSaveAbortion() {
756
                $this->loadFixtures('Post');
757
                $Model = new CallbackPostTestModel();
758
                $Model->beforeSaveReturn = false;
759

    
760
                $data = array(
761
                        'title' => 'new article',
762
                        'body' => 'this is some text.'
763
                );
764
                $Model->create();
765
                $result = $Model->save($data);
766
                $this->assertFalse($result);
767
        }
768

    
769
/**
770
 * testSaveAtomic method
771
 *
772
 * @return void
773
 */
774
        public function testSaveAtomic() {
775
                $this->loadFixtures('Article');
776
                $TestModel = new Article();
777

    
778
                // Create record with 'atomic' = false
779

    
780
                $data = array(
781
                        'Article' => array(
782
                                'user_id' => '1',
783
                                'title' => 'Fourth Article',
784
                                'body' => 'Fourth Article Body',
785
                                'published' => 'Y'
786
                        )
787
                );
788
                $TestModel->create();
789
                $result = $TestModel->save($data, array('atomic' => false));
790
                $this->assertTrue((bool)$result);
791

    
792
                // Check record we created
793

    
794
                $TestModel->recursive = -1;
795
                $result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 4);
796
                $expected = array(
797
                        'Article' => array(
798
                                'id' => '4',
799
                                'user_id' => '1',
800
                                'title' => 'Fourth Article',
801
                                'body' => 'Fourth Article Body',
802
                                'published' => 'Y'
803
                        )
804
                );
805
                $this->assertEquals($expected, $result);
806

    
807
                // Create record with 'atomic' = true
808

    
809
                $data = array(
810
                        'Article' => array(
811
                                'user_id' => '4',
812
                                'title' => 'Fifth Article',
813
                                'body' => 'Fifth Article Body',
814
                                'published' => 'Y'
815
                        )
816
                );
817
                $TestModel->create();
818
                $result = $TestModel->save($data, array('atomic' => true));
819
                $this->assertTrue((bool)$result);
820

    
821
                // Check record we created
822

    
823
                $TestModel->recursive = -1;
824
                $result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 5);
825
                $expected = array(
826
                        'Article' => array(
827
                                'id' => '5',
828
                                'user_id' => '4',
829
                                'title' => 'Fifth Article',
830
                                'body' => 'Fifth Article Body',
831
                                'published' => 'Y'
832
                        )
833
                );
834
                $this->assertEquals($expected, $result);
835
        }
836

    
837
/**
838
 * test save with transaction and ensure there is no missing rollback.
839
 *
840
 * @return void
841
 */
842
        public function testSaveTransactionNoRollback() {
843
                $this->loadFixtures('Post', 'Article');
844

    
845
                $db = $this->getMock('DboSource', array('begin', 'connect', 'rollback', 'describe'));
846

    
847
                $db->expects($this->once())
848
                        ->method('describe')
849
                        ->will($this->returnValue(array()));
850
                $db->expects($this->once())
851
                        ->method('begin')
852
                        ->will($this->returnValue(true));
853
                $db->expects($this->once())
854
                        ->method('rollback');
855

    
856
                $Post = new TestPost();
857
                $Post->setDataSourceObject($db);
858

    
859
                $callback = array($this, 'callbackForTestSaveTransaction');
860
                $Post->getEventManager()->attach($callback, 'Model.beforeSave');
861

    
862
                $data = array(
863
                        'Post' => array(
864
                                'author_id' => 1,
865
                                'title' => 'New Fourth Post'
866
                        )
867
                );
868
                $Post->save($data, array('atomic' => true));
869
        }
870

    
871
/**
872
 * test callback used in testSaveTransaction method
873
 *
874
 * @return bool false to stop event propagation
875
 */
876
        public function callbackForTestSaveTransaction($event) {
877
                $TestModel = new Article();
878

    
879
                // Create record. Do not use same model as in testSaveTransaction
880
                // to avoid infinite loop.
881

    
882
                $data = array(
883
                        'Article' => array(
884
                                'user_id' => '1',
885
                                'title' => 'Fourth Article',
886
                                'body' => 'Fourth Article Body',
887
                                'published' => 'Y'
888
                        )
889
                );
890
                $TestModel->create();
891
                $result = $TestModel->save($data);
892
                $this->assertTrue((bool)$result);
893

    
894
                // force transaction to be rolled back in Post model
895
                $event->stopPropagation();
896
                return false;
897
        }
898

    
899
/**
900
 * testSaveTransaction method
901
 *
902
 * @return void
903
 */
904
        public function testSaveTransaction() {
905
                $this->loadFixtures('Post', 'Article');
906
                $PostModel = new Post();
907

    
908
                // Check if Database supports transactions
909

    
910
                $PostModel->validate = array('title' => 'notBlank');
911
                $data = array(
912
                        array('author_id' => 1, 'title' => 'New Fourth Post'),
913
                        array('author_id' => 1, 'title' => 'New Fifth Post'),
914
                        array('author_id' => 1, 'title' => '')
915
                );
916
                $this->assertFalse($PostModel->saveAll($data));
917

    
918
                $result = $PostModel->find('all', array('recursive' => -1));
919
                $expectedPosts = array(
920
                        array(
921
                                'Post' => array(
922
                                        'id' => '1',
923
                                        'author_id' => 1,
924
                                        'title' => 'First Post',
925
                                        'body' => 'First Post Body',
926
                                        'published' => 'Y',
927
                                        'created' => '2007-03-18 10:39:23',
928
                                        'updated' => '2007-03-18 10:41:31'
929
                                )
930
                        ),
931
                        array(
932
                                'Post' => array(
933
                                        'id' => '2',
934
                                        'author_id' => 3,
935
                                        'title' => 'Second Post',
936
                                        'body' => 'Second Post Body',
937
                                        'published' => 'Y',
938
                                        'created' => '2007-03-18 10:41:23',
939
                                        'updated' => '2007-03-18 10:43:31'
940
                                )
941
                        ),
942
                        array(
943
                                'Post' => array(
944
                                        'id' => '3',
945
                                        'author_id' => 1,
946
                                        'title' => 'Third Post',
947
                                        'body' => 'Third Post Body',
948
                                        'published' => 'Y',
949
                                        'created' => '2007-03-18 10:43:23',
950
                                        'updated' => '2007-03-18 10:45:31'
951
                                )
952
                        )
953
                );
954

    
955
                $this->skipIf(count($result) !== 3, 'Database does not support transactions.');
956

    
957
                $this->assertEquals($expectedPosts, $result);
958

    
959
                // Database supports transactions --> continue tests
960

    
961
                $data = array(
962
                        'Post' => array(
963
                                'author_id' => 1,
964
                                'title' => 'New Fourth Post'
965
                        )
966
                );
967

    
968
                $callback = array($this, 'callbackForTestSaveTransaction');
969
                $PostModel->getEventManager()->attach($callback, 'Model.beforeSave');
970

    
971
                $PostModel->create();
972
                $result = $PostModel->save($data, array('atomic' => true));
973
                $this->assertFalse($result);
974

    
975
                $result = $PostModel->find('all', array('recursive' => -1));
976
                $this->assertEquals($expectedPosts, $result);
977

    
978
                // Check record we created in callbackForTestSaveTransaction method.
979
                // record should not exist due to rollback
980

    
981
                $ArticleModel = new Article();
982
                $result = $ArticleModel->find('all', array('recursive' => -1));
983
                $expectedArticles = array(
984
                        array(
985
                                'Article' => array(
986
                                        'user_id' => '1',
987
                                        'title' => 'First Article',
988
                                        'body' => 'First Article Body',
989
                                        'published' => 'Y',
990
                                        'created' => '2007-03-18 10:39:23',
991
                                        'updated' => '2007-03-18 10:41:31',
992
                                        'id' => '1'
993
                                )
994
                        ),
995
                        array(
996
                                'Article' => array(
997
                                        'user_id' => '3',
998
                                        'title' => 'Second Article',
999
                                        'body' => 'Second Article Body',
1000
                                        'published' => 'Y',
1001
                                        'created' => '2007-03-18 10:41:23',
1002
                                        'updated' => '2007-03-18 10:43:31',
1003
                                        'id' => '2'
1004
                                )
1005
                        ),
1006
                        array(
1007
                                'Article' => array(
1008
                                        'user_id' => '1',
1009
                                        'title' => 'Third Article',
1010
                                        'body' => 'Third Article Body',
1011
                                        'published' => 'Y',
1012
                                        'created' => '2007-03-18 10:43:23',
1013
                                        'updated' => '2007-03-18 10:45:31',
1014
                                        'id' => '3'
1015
                                )
1016
                        )
1017
                );
1018
                $this->assertEquals($expectedArticles, $result);
1019
        }
1020

    
1021
/**
1022
 * testSaveField method
1023
 *
1024
 * @return void
1025
 */
1026
        public function testSaveField() {
1027
                $this->loadFixtures('Article');
1028
                $TestModel = new Article();
1029

    
1030
                $TestModel->id = 1;
1031
                $result = $TestModel->saveField('title', 'New First Article');
1032
                $this->assertFalse(empty($result));
1033

    
1034
                $TestModel->recursive = -1;
1035
                $result = $TestModel->read(array('id', 'user_id', 'title', 'body'), 1);
1036
                $expected = array('Article' => array(
1037
                        'id' => '1',
1038
                        'user_id' => '1',
1039
                        'title' => 'New First Article',
1040
                        'body' => 'First Article Body'
1041
                ));
1042
                $this->assertEquals($expected, $result);
1043

    
1044
                $TestModel->id = 1;
1045
                $result = $TestModel->saveField('title', '');
1046
                $this->assertFalse(empty($result));
1047

    
1048
                $TestModel->recursive = -1;
1049
                $result = $TestModel->read(array('id', 'user_id', 'title', 'body'), 1);
1050
                $expected = array('Article' => array(
1051
                        'id' => '1',
1052
                        'user_id' => '1',
1053
                        'title' => '',
1054
                        'body' => 'First Article Body'
1055
                ));
1056
                $result['Article']['title'] = trim($result['Article']['title']);
1057
                $this->assertEquals($expected, $result);
1058

    
1059
                $TestModel->id = 1;
1060
                $TestModel->set('body', 'Messed up data');
1061
                $result = $TestModel->saveField('title', 'First Article');
1062
                $this->assertFalse(empty($result));
1063
                $result = $TestModel->read(array('id', 'user_id', 'title', 'body'), 1);
1064
                $expected = array('Article' => array(
1065
                        'id' => '1',
1066
                        'user_id' => '1',
1067
                        'title' => 'First Article',
1068
                        'body' => 'First Article Body'
1069
                ));
1070
                $this->assertEquals($expected, $result);
1071

    
1072
                $TestModel->recursive = -1;
1073
                $TestModel->read(array('id', 'user_id', 'title', 'body'), 1);
1074

    
1075
                $TestModel->id = 1;
1076
                $result = $TestModel->saveField('title', '', true);
1077
                $this->assertFalse($result);
1078

    
1079
                $TestModel->recursive = -1;
1080
                $TestModel->id = 1;
1081
                $result = $TestModel->saveField('user_id', 9999);
1082
                $this->assertTrue((bool)$result);
1083

    
1084
                $result = $TestModel->read(array('id', 'user_id'), 1);
1085
                $expected = array('Article' => array(
1086
                        'id' => '1',
1087
                        'user_id' => '9999',
1088
                ));
1089
                $this->assertEquals($expected, $result);
1090

    
1091
                $this->loadFixtures('Node', 'Dependency');
1092
                $Node = new Node();
1093
                $Node->set('id', 1);
1094
                $result = $Node->read();
1095
                $this->assertEquals(array('Second'), Hash::extract($result, 'ParentNode.{n}.name'));
1096

    
1097
                $Node->saveField('state', 10);
1098
                $result = $Node->read();
1099
                $this->assertEquals(array('Second'), Hash::extract($result, 'ParentNode.{n}.name'));
1100
        }
1101

    
1102
/**
1103
 * testSaveWithCreate method
1104
 *
1105
 * @return void
1106
 */
1107
        public function testSaveWithCreate() {
1108
                $this->loadFixtures(
1109
                        'User',
1110
                        'Article',
1111
                        'User',
1112
                        'Comment',
1113
                        'Tag',
1114
                        'ArticlesTag',
1115
                        'Attachment'
1116
                );
1117
                $TestModel = new User();
1118

    
1119
                $data = array('User' => array(
1120
                        'user' => 'user',
1121
                        'password' => ''
1122
                ));
1123
                $result = $TestModel->save($data);
1124
                $this->assertFalse($result);
1125
                $this->assertTrue(!empty($TestModel->validationErrors));
1126

    
1127
                $TestModel = new Article();
1128

    
1129
                $data = array('Article' => array(
1130
                        'user_id' => '',
1131
                        'title' => '',
1132
                        'body' => ''
1133
                ));
1134
                $result = $TestModel->create($data) && $TestModel->save();
1135
                $this->assertFalse($result);
1136
                $this->assertTrue(!empty($TestModel->validationErrors));
1137

    
1138
                $data = array('Article' => array(
1139
                        'id' => 1,
1140
                        'user_id' => '1',
1141
                        'title' => 'New First Article',
1142
                        'body' => ''
1143
                ));
1144
                $result = $TestModel->create($data) && $TestModel->save();
1145
                $this->assertFalse($result);
1146

    
1147
                $data = array('Article' => array(
1148
                        'id' => 1,
1149
                        'title' => 'New First Article'
1150
                ));
1151
                $result = $TestModel->create() && $TestModel->save($data, false);
1152
                $this->assertFalse(empty($result));
1153

    
1154
                $TestModel->recursive = -1;
1155
                $result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 1);
1156
                $expected = array('Article' => array(
1157
                        'id' => '1',
1158
                        'user_id' => '1',
1159
                        'title' => 'New First Article',
1160
                        'body' => 'First Article Body',
1161
                        'published' => 'N'
1162
                ));
1163
                $this->assertEquals($expected, $result);
1164

    
1165
                $data = array('Article' => array(
1166
                        'id' => 1,
1167
                        'user_id' => '2',
1168
                        'title' => 'First Article',
1169
                        'body' => 'New First Article Body',
1170
                        'published' => 'Y'
1171
                ));
1172
                $result = $TestModel->create() && $TestModel->save($data, true, array('id', 'title', 'published'));
1173
                $this->assertFalse(empty($result));
1174

    
1175
                $TestModel->recursive = -1;
1176
                $result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 1);
1177
                $expected = array('Article' => array(
1178
                        'id' => '1',
1179
                        'user_id' => '1',
1180
                        'title' => 'First Article',
1181
                        'body' => 'First Article Body',
1182
                        'published' => 'Y'
1183
                ));
1184
                $this->assertEquals($expected, $result);
1185

    
1186
                $data = array(
1187
                        'Article' => array(
1188
                                'user_id' => '2',
1189
                                'title' => 'New Article',
1190
                                'body' => 'New Article Body',
1191
                                'created' => '2007-03-18 14:55:23',
1192
                                'updated' => '2007-03-18 14:57:31'
1193
                        ),
1194
                        'Tag' => array('Tag' => array(1, 3))
1195
                );
1196
                $TestModel->create();
1197
                $result = $TestModel->create() && $TestModel->save($data);
1198
                $this->assertFalse(empty($result));
1199

    
1200
                $TestModel->recursive = 2;
1201
                $result = $TestModel->read(null, 4);
1202
                $expected = array(
1203
                        'Article' => array(
1204
                                'id' => '4',
1205
                                'user_id' => '2',
1206
                                'title' => 'New Article',
1207
                                'body' => 'New Article Body',
1208
                                'published' => 'N',
1209
                                'created' => '2007-03-18 14:55:23',
1210
                                'updated' => '2007-03-18 14:57:31'
1211
                        ),
1212
                        'User' => array(
1213
                                'id' => '2',
1214
                                'user' => 'nate',
1215
                                'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
1216
                                'created' => '2007-03-17 01:18:23',
1217
                                'updated' => '2007-03-17 01:20:31'
1218
                        ),
1219
                        'Comment' => array(),
1220
                        'Tag' => array(
1221
                                array(
1222
                                        'id' => '1',
1223
                                        'tag' => 'tag1',
1224
                                        'created' => '2007-03-18 12:22:23',
1225
                                        'updated' => '2007-03-18 12:24:31'
1226
                                ),
1227
                                array(
1228
                                        'id' => '3',
1229
                                        'tag' => 'tag3',
1230
                                        'created' => '2007-03-18 12:26:23',
1231
                                        'updated' => '2007-03-18 12:28:31'
1232
                )));
1233
                $this->assertEquals($expected, $result);
1234

    
1235
                $data = array('Comment' => array(
1236
                        'article_id' => '4',
1237
                        'user_id' => '1',
1238
                        'comment' => 'Comment New Article',
1239
                        'published' => 'Y',
1240
                        'created' => '2007-03-18 14:57:23',
1241
                        'updated' => '2007-03-18 14:59:31'
1242
                ));
1243
                $result = $TestModel->Comment->create() && $TestModel->Comment->save($data);
1244
                $this->assertFalse(empty($result));
1245

    
1246
                $data = array('Attachment' => array(
1247
                        'comment_id' => '7',
1248
                        'attachment' => 'newattachment.zip',
1249
                        'created' => '2007-03-18 15:02:23',
1250
                        'updated' => '2007-03-18 15:04:31'
1251
                ));
1252
                $result = $TestModel->Comment->Attachment->save($data);
1253
                $this->assertFalse(empty($result));
1254

    
1255
                $TestModel->recursive = 2;
1256
                $result = $TestModel->read(null, 4);
1257
                $expected = array(
1258
                        'Article' => array(
1259
                                'id' => '4',
1260
                                'user_id' => '2',
1261
                                'title' => 'New Article',
1262
                                'body' => 'New Article Body',
1263
                                'published' => 'N',
1264
                                'created' => '2007-03-18 14:55:23',
1265
                                'updated' => '2007-03-18 14:57:31'
1266
                        ),
1267
                        'User' => array(
1268
                                'id' => '2',
1269
                                'user' => 'nate',
1270
                                'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
1271
                                'created' => '2007-03-17 01:18:23',
1272
                                'updated' => '2007-03-17 01:20:31'
1273
                        ),
1274
                        'Comment' => array(
1275
                                array(
1276
                                        'id' => '7',
1277
                                        'article_id' => '4',
1278
                                        'user_id' => '1',
1279
                                        'comment' => 'Comment New Article',
1280
                                        'published' => 'Y',
1281
                                        'created' => '2007-03-18 14:57:23',
1282
                                        'updated' => '2007-03-18 14:59:31',
1283
                                        'Article' => array(
1284
                                                'id' => '4',
1285
                                                'user_id' => '2',
1286
                                                'title' => 'New Article',
1287
                                                'body' => 'New Article Body',
1288
                                                'published' => 'N',
1289
                                                'created' => '2007-03-18 14:55:23',
1290
                                                'updated' => '2007-03-18 14:57:31'
1291
                                        ),
1292
                                        'User' => array(
1293
                                                'id' => '1',
1294
                                                'user' => 'mariano',
1295
                                                'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
1296
                                                'created' => '2007-03-17 01:16:23',
1297
                                                'updated' => '2007-03-17 01:18:31'
1298
                                        ),
1299
                                        'Attachment' => array(
1300
                                                'id' => '2',
1301
                                                'comment_id' => '7',
1302
                                                'attachment' => 'newattachment.zip',
1303
                                                'created' => '2007-03-18 15:02:23',
1304
                                                'updated' => '2007-03-18 15:04:31'
1305
                        ))),
1306
                        'Tag' => array(
1307
                                array(
1308
                                        'id' => '1',
1309
                                        'tag' => 'tag1',
1310
                                        'created' => '2007-03-18 12:22:23',
1311
                                        'updated' => '2007-03-18 12:24:31'
1312
                                ),
1313
                                array(
1314
                                        'id' => '3',
1315
                                        'tag' => 'tag3',
1316
                                        'created' => '2007-03-18 12:26:23',
1317
                                        'updated' => '2007-03-18 12:28:31'
1318
                )));
1319

    
1320
                $this->assertEquals($expected, $result);
1321
        }
1322

    
1323
/**
1324
 * test that a null Id doesn't cause errors
1325
 *
1326
 * @return void
1327
 */
1328
        public function testSaveWithNullId() {
1329
                $this->loadFixtures('User');
1330
                $User = new User();
1331
                $User->read(null, 1);
1332
                $User->data['User']['id'] = null;
1333
                $result = $User->save(array('password' => 'test'));
1334
                $this->assertFalse(empty($result));
1335
                $this->assertTrue($User->id > 0);
1336

    
1337
                $User->read(null, 2);
1338
                $User->data['User']['id'] = null;
1339
                $result = $User->save(array('password' => 'test'));
1340
                $this->assertFalse(empty($result));
1341
                $this->assertTrue($User->id > 0);
1342

    
1343
                $User->data['User'] = array('password' => 'something');
1344
                $result = $User->save();
1345
                $this->assertFalse(empty($result));
1346
                $result = $User->read();
1347
                $this->assertEquals('something', $User->data['User']['password']);
1348
        }
1349

    
1350
/**
1351
 * testSaveWithSet method
1352
 *
1353
 * @return void
1354
 */
1355
        public function testSaveWithSet() {
1356
                $this->loadFixtures('Article');
1357
                $TestModel = new Article();
1358

    
1359
                // Create record we will be updating later
1360

    
1361
                $data = array('Article' => array(
1362
                        'user_id' => '1',
1363
                        'title' => 'Fourth Article',
1364
                        'body' => 'Fourth Article Body',
1365
                        'published' => 'Y'
1366
                ));
1367
                $result = $TestModel->create() && $TestModel->save($data);
1368
                $this->assertFalse(empty($result));
1369

    
1370
                // Check record we created
1371

    
1372
                $TestModel->recursive = -1;
1373
                $result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 4);
1374
                $expected = array('Article' => array(
1375
                        'id' => '4',
1376
                        'user_id' => '1',
1377
                        'title' => 'Fourth Article',
1378
                        'body' => 'Fourth Article Body',
1379
                        'published' => 'Y'
1380
                ));
1381
                $this->assertEquals($expected, $result);
1382

    
1383
                // Create new record just to overlap Model->id on previously created record
1384

    
1385
                $data = array('Article' => array(
1386
                        'user_id' => '4',
1387
                        'title' => 'Fifth Article',
1388
                        'body' => 'Fifth Article Body',
1389
                        'published' => 'Y'
1390
                ));
1391
                $result = $TestModel->create() && $TestModel->save($data);
1392
                $this->assertFalse(empty($result));
1393

    
1394
                $TestModel->recursive = -1;
1395
                $result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 5);
1396
                $expected = array('Article' => array(
1397
                        'id' => '5',
1398
                        'user_id' => '4',
1399
                        'title' => 'Fifth Article',
1400
                        'body' => 'Fifth Article Body',
1401
                        'published' => 'Y'
1402
                ));
1403
                $this->assertEquals($expected, $result);
1404

    
1405
                // Go back and edit the first article we created, starting by checking it's still there
1406

    
1407
                $TestModel->recursive = -1;
1408
                $result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 4);
1409
                $expected = array('Article' => array(
1410
                        'id' => '4',
1411
                        'user_id' => '1',
1412
                        'title' => 'Fourth Article',
1413
                        'body' => 'Fourth Article Body',
1414
                        'published' => 'Y'
1415
                ));
1416
                $this->assertEquals($expected, $result);
1417

    
1418
                // And now do the update with set()
1419

    
1420
                $data = array('Article' => array(
1421
                        'id' => '4',
1422
                        'title' => 'Fourth Article - New Title',
1423
                        'published' => 'N'
1424
                ));
1425
                $result = $TestModel->set($data) && $TestModel->save();
1426
                $this->assertFalse(empty($result));
1427

    
1428
                $TestModel->recursive = -1;
1429
                $result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 4);
1430
                $expected = array('Article' => array(
1431
                        'id' => '4',
1432
                        'user_id' => '1',
1433
                        'title' => 'Fourth Article - New Title',
1434
                        'body' => 'Fourth Article Body',
1435
                        'published' => 'N'
1436
                ));
1437
                $this->assertEquals($expected, $result);
1438

    
1439
                $TestModel->recursive = -1;
1440
                $result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 5);
1441
                $expected = array('Article' => array(
1442
                        'id' => '5',
1443
                        'user_id' => '4',
1444
                        'title' => 'Fifth Article',
1445
                        'body' => 'Fifth Article Body',
1446
                        'published' => 'Y'
1447
                ));
1448
                $this->assertEquals($expected, $result);
1449

    
1450
                $data = array('Article' => array('id' => '5', 'title' => 'Fifth Article - New Title 5'));
1451
                $result = ($TestModel->set($data) && $TestModel->save());
1452
                $this->assertFalse(empty($result));
1453

    
1454
                $TestModel->recursive = -1;
1455
                $result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 5);
1456
                $expected = array('Article' => array(
1457
                        'id' => '5',
1458
                        'user_id' => '4',
1459
                        'title' => 'Fifth Article - New Title 5',
1460
                        'body' => 'Fifth Article Body',
1461
                        'published' => 'Y'
1462
                ));
1463
                $this->assertEquals($expected, $result);
1464

    
1465
                $TestModel->recursive = -1;
1466
                $result = $TestModel->find('all', array(
1467
                        'fields' => array('id', 'title'),
1468
                        'order' => array('Article.id' => 'ASC')
1469
                ));
1470
                $expected = array(
1471
                        array('Article' => array('id' => 1, 'title' => 'First Article')),
1472
                        array('Article' => array('id' => 2, 'title' => 'Second Article')),
1473
                        array('Article' => array('id' => 3, 'title' => 'Third Article')),
1474
                        array('Article' => array('id' => 4, 'title' => 'Fourth Article - New Title')),
1475
                        array('Article' => array('id' => 5, 'title' => 'Fifth Article - New Title 5'))
1476
                );
1477
                $this->assertEquals($expected, $result);
1478
        }
1479

    
1480
/**
1481
 * testSaveWithNonExistentFields method
1482
 *
1483
 * @return void
1484
 */
1485
        public function testSaveWithNonExistentFields() {
1486
                $this->loadFixtures('Article');
1487
                $TestModel = new Article();
1488
                $TestModel->recursive = -1;
1489

    
1490
                $data = array(
1491
                        'non_existent' => 'This field does not exist',
1492
                        'user_id' => '1',
1493
                        'title' => 'Fourth Article - New Title',
1494
                        'body' => 'Fourth Article Body',
1495
                        'published' => 'N'
1496
                );
1497
                $result = $TestModel->create() && $TestModel->save($data);
1498
                $this->assertFalse(empty($result));
1499

    
1500
                $expected = array('Article' => array(
1501
                        'id' => '4',
1502
                        'user_id' => '1',
1503
                        'title' => 'Fourth Article - New Title',
1504
                        'body' => 'Fourth Article Body',
1505
                        'published' => 'N'
1506
                ));
1507
                $result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 4);
1508
                $this->assertEquals($expected, $result);
1509

    
1510
                $data = array(
1511
                        'user_id' => '1',
1512
                        'non_existent' => 'This field does not exist',
1513
                        'title' => 'Fifth Article - New Title',
1514
                        'body' => 'Fifth Article Body',
1515
                        'published' => 'N'
1516
                );
1517
                $result = $TestModel->create() && $TestModel->save($data);
1518
                $this->assertFalse(empty($result));
1519

    
1520
                $expected = array('Article' => array(
1521
                        'id' => '5',
1522
                        'user_id' => '1',
1523
                        'title' => 'Fifth Article - New Title',
1524
                        'body' => 'Fifth Article Body',
1525
                        'published' => 'N'
1526
                ));
1527
                $result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 5);
1528
                $this->assertEquals($expected, $result);
1529
        }
1530

    
1531
/**
1532
 * testSaveFromXml method
1533
 *
1534
 * @return void
1535
 */
1536
        public function testSaveFromXml() {
1537
                $this->markTestSkipped('This feature needs to be fixed or dropped');
1538
                $this->loadFixtures('Article');
1539
                App::uses('Xml', 'Utility');
1540

    
1541
                $Article = new Article();
1542
                $result = $Article->save(Xml::build('<article title="test xml" user_id="5" />'));
1543
                $this->assertFalse(empty($result));
1544
                $results = $Article->find('first', array('conditions' => array('Article.title' => 'test xml')));
1545
                $this->assertFalse(empty($results));
1546

    
1547
                $result = $Article->save(Xml::build('<article><title>testing</title><user_id>6</user_id></article>'));
1548
                $this->assertFalse(empty($result));
1549
                $results = $Article->find('first', array('conditions' => array('Article.title' => 'testing')));
1550
                $this->assertFalse(empty($results));
1551

    
1552
                $result = $Article->save(Xml::build('<article><title>testing with DOMDocument</title><user_id>7</user_id></article>', array('return' => 'domdocument')));
1553
                $this->assertFalse(empty($result));
1554
                $results = $Article->find('first', array('conditions' => array('Article.title' => 'testing with DOMDocument')));
1555
                $this->assertFalse(empty($results));
1556
        }
1557

    
1558
/**
1559
 * testSaveHabtm method
1560
 *
1561
 * @return void
1562
 */
1563
        public function testSaveHabtm() {
1564
                $this->loadFixtures('Article', 'User', 'Comment', 'Tag', 'ArticlesTag');
1565
                $TestModel = new Article();
1566

    
1567
                $result = $TestModel->findById(2);
1568
                $expected = array(
1569
                        'Article' => array(
1570
                                'id' => '2',
1571
                                'user_id' => '3',
1572
                                'title' => 'Second Article',
1573
                                'body' => 'Second Article Body',
1574
                                'published' => 'Y',
1575
                                'created' => '2007-03-18 10:41:23',
1576
                                'updated' => '2007-03-18 10:43:31'
1577
                        ),
1578
                        'User' => array(
1579
                                'id' => '3',
1580
                                'user' => 'larry',
1581
                                'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
1582
                                'created' => '2007-03-17 01:20:23',
1583
                                'updated' => '2007-03-17 01:22:31'
1584
                        ),
1585
                        'Comment' => array(
1586
                                array(
1587
                                        'id' => '5',
1588
                                        'article_id' => '2',
1589
                                        'user_id' => '1',
1590
                                        'comment' => 'First Comment for Second Article',
1591
                                        'published' => 'Y',
1592
                                        'created' => '2007-03-18 10:53:23',
1593
                                        'updated' => '2007-03-18 10:55:31'
1594
                                ),
1595
                                array(
1596
                                        'id' => '6',
1597
                                        'article_id' => '2',
1598
                                        'user_id' => '2',
1599
                                        'comment' => 'Second Comment for Second Article',
1600
                                        'published' => 'Y',
1601
                                        'created' => '2007-03-18 10:55:23',
1602
                                        'updated' => '2007-03-18 10:57:31'
1603
                        )),
1604
                        'Tag' => array(
1605
                                array(
1606
                                        'id' => '1',
1607
                                        'tag' => 'tag1',
1608
                                        'created' => '2007-03-18 12:22:23',
1609
                                        'updated' => '2007-03-18 12:24:31'
1610
                                ),
1611
                                array(
1612
                                        'id' => '3',
1613
                                        'tag' => 'tag3',
1614
                                        'created' => '2007-03-18 12:26:23',
1615
                                        'updated' => '2007-03-18 12:28:31'
1616
                                )
1617
                        )
1618
                );
1619
                $this->assertEquals($expected, $result);
1620

    
1621
                $data = array(
1622
                        'Article' => array(
1623
                                'id' => '2',
1624
                                'title' => 'New Second Article'
1625
                        ),
1626
                        'Tag' => array('Tag' => array(1, 2))
1627
                );
1628

    
1629
                $result = $TestModel->set($data);
1630
                $this->assertFalse(empty($result));
1631
                $result = $TestModel->save();
1632
                $this->assertFalse(empty($result));
1633
                $this->assertEquals($data['Tag'], $result['Tag']);
1634

    
1635
                $TestModel->unbindModel(array('belongsTo' => array('User'), 'hasMany' => array('Comment')));
1636
                $result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
1637
                $expected = array(
1638
                        'Article' => array(
1639
                                'id' => '2',
1640
                                'user_id' => '3',
1641
                                'title' => 'New Second Article',
1642
                                'body' => 'Second Article Body'
1643
                        ),
1644
                        'Tag' => array(
1645
                                array(
1646
                                        'id' => '1',
1647
                                        'tag' => 'tag1',
1648
                                        'created' => '2007-03-18 12:22:23',
1649
                                        'updated' => '2007-03-18 12:24:31'
1650
                                ),
1651
                                array(
1652
                                        'id' => '2',
1653
                                        'tag' => 'tag2',
1654
                                        'created' => '2007-03-18 12:24:23',
1655
                                        'updated' => '2007-03-18 12:26:31'
1656
                )));
1657
                $this->assertEquals($expected, $result);
1658

    
1659
                $data = array('Article' => array('id' => '2'), 'Tag' => array('Tag' => array(2, 3)));
1660
                $result = $TestModel->set($data);
1661
                $this->assertFalse(empty($result));
1662

    
1663
                $result = $TestModel->save();
1664
                $this->assertFalse(empty($result));
1665

    
1666
                $TestModel->unbindModel(array(
1667
                        'belongsTo' => array('User'),
1668
                        'hasMany' => array('Comment')
1669
                ));
1670
                $result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
1671
                $expected = array(
1672
                        'Article' => array(
1673
                                'id' => '2',
1674
                                'user_id' => '3',
1675
                                'title' => 'New Second Article',
1676
                                'body' => 'Second Article Body'
1677
                        ),
1678
                        'Tag' => array(
1679
                                array(
1680
                                        'id' => '2',
1681
                                        'tag' => 'tag2',
1682
                                        'created' => '2007-03-18 12:24:23',
1683
                                        'updated' => '2007-03-18 12:26:31'
1684
                                ),
1685
                                array(
1686
                                        'id' => '3',
1687
                                        'tag' => 'tag3',
1688
                                        'created' => '2007-03-18 12:26:23',
1689
                                        'updated' => '2007-03-18 12:28:31'
1690
                )));
1691
                $this->assertEquals($expected, $result);
1692

    
1693
                $data = array('Tag' => array('Tag' => array(1, 2, 3)));
1694

    
1695
                $result = $TestModel->set($data);
1696
                $this->assertFalse(empty($result));
1697

    
1698
                $result = $TestModel->save();
1699
                $this->assertFalse(empty($result));
1700

    
1701
                $TestModel->unbindModel(array(
1702
                        'belongsTo' => array('User'),
1703
                        'hasMany' => array('Comment')
1704
                ));
1705
                $result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
1706
                $expected = array(
1707
                        'Article' => array(
1708
                                'id' => '2',
1709
                                'user_id' => '3',
1710
                                'title' => 'New Second Article',
1711
                                'body' => 'Second Article Body'
1712
                        ),
1713
                        'Tag' => array(
1714
                                array(
1715
                                        'id' => '1',
1716
                                        'tag' => 'tag1',
1717
                                        'created' => '2007-03-18 12:22:23',
1718
                                        'updated' => '2007-03-18 12:24:31'
1719
                                ),
1720
                                array(
1721
                                        'id' => '2',
1722
                                        'tag' => 'tag2',
1723
                                        'created' => '2007-03-18 12:24:23',
1724
                                        'updated' => '2007-03-18 12:26:31'
1725
                                ),
1726
                                array(
1727
                                        'id' => '3',
1728
                                        'tag' => 'tag3',
1729
                                        'created' => '2007-03-18 12:26:23',
1730
                                        'updated' => '2007-03-18 12:28:31'
1731
                )));
1732
                $this->assertEquals($expected, $result);
1733

    
1734
                $data = array('Tag' => array('Tag' => array()));
1735
                $result = $TestModel->set($data);
1736
                $this->assertFalse(empty($result));
1737

    
1738
                $result = $TestModel->save();
1739
                $this->assertFalse(empty($result));
1740

    
1741
                $data = array('Tag' => array('Tag' => ''));
1742
                $result = $TestModel->set($data);
1743
                $this->assertFalse(empty($result));
1744

    
1745
                $result = $TestModel->save();
1746
                $this->assertFalse(empty($result));
1747

    
1748
                $TestModel->unbindModel(array(
1749
                        'belongsTo' => array('User'),
1750
                        'hasMany' => array('Comment')
1751
                ));
1752
                $result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
1753
                $expected = array(
1754
                        'Article' => array(
1755
                                'id' => '2',
1756
                                'user_id' => '3',
1757
                                'title' => 'New Second Article',
1758
                                'body' => 'Second Article Body'
1759
                        ),
1760
                        'Tag' => array()
1761
                );
1762
                $this->assertEquals($expected, $result);
1763

    
1764
                $data = array('Tag' => array('Tag' => array(2, 3)));
1765
                $result = $TestModel->set($data);
1766
                $this->assertFalse(empty($result));
1767

    
1768
                $result = $TestModel->save();
1769
                $this->assertFalse(empty($result));
1770

    
1771
                $TestModel->unbindModel(array(
1772
                        'belongsTo' => array('User'),
1773
                        'hasMany' => array('Comment')
1774
                ));
1775
                $result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
1776
                $expected = array(
1777
                        'Article' => array(
1778
                                'id' => '2',
1779
                                'user_id' => '3',
1780
                                'title' => 'New Second Article',
1781
                                'body' => 'Second Article Body'
1782
                        ),
1783
                        'Tag' => array(
1784
                                array(
1785
                                        'id' => '2',
1786
                                        'tag' => 'tag2',
1787
                                        'created' => '2007-03-18 12:24:23',
1788
                                        'updated' => '2007-03-18 12:26:31'
1789
                                ),
1790
                                array(
1791
                                        'id' => '3',
1792
                                        'tag' => 'tag3',
1793
                                        'created' => '2007-03-18 12:26:23',
1794
                                        'updated' => '2007-03-18 12:28:31'
1795
                )));
1796
                $this->assertEquals($expected, $result);
1797

    
1798
                $data = array(
1799
                        'Tag' => array(
1800
                                'Tag' => array(1, 2)
1801
                        ),
1802
                        'Article' => array(
1803
                                'id' => '2',
1804
                                'title' => 'New Second Article'
1805
                ));
1806
                $result = $TestModel->set($data);
1807
                $this->assertFalse(empty($result));
1808
                $result = $TestModel->save();
1809
                $this->assertFalse(empty($result));
1810

    
1811
                $TestModel->unbindModel(array(
1812
                        'belongsTo' => array('User'),
1813
                        'hasMany' => array('Comment')
1814
                ));
1815
                $result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
1816
                $expected = array(
1817
                        'Article' => array(
1818
                                'id' => '2',
1819
                                'user_id' => '3',
1820
                                'title' => 'New Second Article',
1821
                                'body' => 'Second Article Body'
1822
                        ),
1823
                        'Tag' => array(
1824
                                array(
1825
                                        'id' => '1',
1826
                                        'tag' => 'tag1',
1827
                                        'created' => '2007-03-18 12:22:23',
1828
                                        'updated' => '2007-03-18 12:24:31'
1829
                                ),
1830
                                array(
1831
                                        'id' => '2',
1832
                                        'tag' => 'tag2',
1833
                                        'created' => '2007-03-18 12:24:23',
1834
                                        'updated' => '2007-03-18 12:26:31'
1835
                )));
1836
                $this->assertEquals($expected, $result);
1837

    
1838
                $data = array(
1839
                        'Tag' => array(
1840
                                'Tag' => array(1, 2)
1841
                        ),
1842
                        'Article' => array(
1843
                                'id' => '2',
1844
                                'title' => 'New Second Article Title'
1845
                ));
1846
                $result = $TestModel->set($data);
1847
                $this->assertFalse(empty($result));
1848
                $result = $TestModel->save();
1849
                $this->assertFalse(empty($result));
1850

    
1851
                $TestModel->unbindModel(array(
1852
                        'belongsTo' => array('User'),
1853
                        'hasMany' => array('Comment')
1854
                ));
1855
                $result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
1856
                $expected = array(
1857
                        'Article' => array(
1858
                                'id' => '2',
1859
                                'user_id' => '3',
1860
                                'title' => 'New Second Article Title',
1861
                                'body' => 'Second Article Body'
1862
                        ),
1863
                        'Tag' => array(
1864
                                array(
1865
                                        'id' => '1',
1866
                                        'tag' => 'tag1',
1867
                                        'created' => '2007-03-18 12:22:23',
1868
                                        'updated' => '2007-03-18 12:24:31'
1869
                                ),
1870
                                array(
1871
                                        'id' => '2',
1872
                                        'tag' => 'tag2',
1873
                                        'created' => '2007-03-18 12:24:23',
1874
                                        'updated' => '2007-03-18 12:26:31'
1875
                                )
1876
                        )
1877
                );
1878
                $this->assertEquals($expected, $result);
1879

    
1880
                $data = array(
1881
                        'Tag' => array(
1882
                                'Tag' => array(2, 3)
1883
                        ),
1884
                        'Article' => array(
1885
                                'id' => '2',
1886
                                'title' => 'Changed Second Article'
1887
                ));
1888
                $result = $TestModel->set($data);
1889
                $this->assertFalse(empty($result));
1890
                $result = $TestModel->save();
1891
                $this->assertFalse(empty($result));
1892

    
1893
                $TestModel->unbindModel(array(
1894
                        'belongsTo' => array('User'),
1895
                        'hasMany' => array('Comment')
1896
                ));
1897
                $result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
1898
                $expected = array(
1899
                        'Article' => array(
1900
                                'id' => '2',
1901
                                'user_id' => '3',
1902
                                'title' => 'Changed Second Article',
1903
                                'body' => 'Second Article Body'
1904
                        ),
1905
                        'Tag' => array(
1906
                                array(
1907
                                        'id' => '2',
1908
                                        'tag' => 'tag2',
1909
                                        'created' => '2007-03-18 12:24:23',
1910
                                        'updated' => '2007-03-18 12:26:31'
1911
                                ),
1912
                                array(
1913
                                        'id' => '3',
1914
                                        'tag' => 'tag3',
1915
                                        'created' => '2007-03-18 12:26:23',
1916
                                        'updated' => '2007-03-18 12:28:31'
1917
                                )
1918
                        )
1919
                );
1920
                $this->assertEquals($expected, $result);
1921

    
1922
                $data = array(
1923
                        'Tag' => array(
1924
                                'Tag' => array(1, 3)
1925
                        ),
1926
                        'Article' => array('id' => '2'),
1927
                );
1928

    
1929
                $result = $TestModel->set($data);
1930
                $this->assertFalse(empty($result));
1931

    
1932
                $result = $TestModel->save();
1933
                $this->assertFalse(empty($result));
1934

    
1935
                $TestModel->unbindModel(array(
1936
                        'belongsTo' => array('User'),
1937
                        'hasMany' => array('Comment')
1938
                ));
1939
                $result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
1940
                $expected = array(
1941
                        'Article' => array(
1942
                                'id' => '2',
1943
                                'user_id' => '3',
1944
                                'title' => 'Changed Second Article',
1945
                                'body' => 'Second Article Body'
1946
                        ),
1947
                        'Tag' => array(
1948
                                array(
1949
                                        'id' => '1',
1950
                                        'tag' => 'tag1',
1951
                                        'created' => '2007-03-18 12:22:23',
1952
                                        'updated' => '2007-03-18 12:24:31'
1953
                                ),
1954
                                array(
1955
                                        'id' => '3',
1956
                                        'tag' => 'tag3',
1957
                                        'created' => '2007-03-18 12:26:23',
1958
                                        'updated' => '2007-03-18 12:28:31'
1959
                )));
1960
                $this->assertEquals($expected, $result);
1961

    
1962
                $data = array(
1963
                        'Article' => array(
1964
                                'id' => 10,
1965
                                'user_id' => '2',
1966
                                'title' => 'New Article With Tags and fieldList',
1967
                                'body' => 'New Article Body with Tags and fieldList',
1968
                                'created' => '2007-03-18 14:55:23',
1969
                                'updated' => '2007-03-18 14:57:31'
1970
                        ),
1971
                        'Tag' => array(
1972
                                'Tag' => array(1, 2, 3)
1973
                        )
1974
                );
1975
                $result = $TestModel->create()
1976
                                && $TestModel->save($data, true, array('user_id', 'title', 'published'));
1977
                $this->assertFalse(empty($result));
1978

    
1979
                $TestModel->unbindModel(array(
1980
                        'belongsTo' => array('User'),
1981
                        'hasMany' => array('Comment')
1982
                ));
1983
                $result = $TestModel->read();
1984
                $expected = array(
1985
                        'Article' => array(
1986
                                'id' => 4,
1987
                                'user_id' => 2,
1988
                                'title' => 'New Article With Tags and fieldList',
1989
                                'body' => '',
1990
                                'published' => 'N',
1991
                                'created' => static::date(),
1992
                                'updated' => static::date(),
1993
                        ),
1994
                        'Tag' => array(
1995
                                0 => array(
1996
                                        'id' => 1,
1997
                                        'tag' => 'tag1',
1998
                                        'created' => '2007-03-18 12:22:23',
1999
                                        'updated' => '2007-03-18 12:24:31'
2000
                                ),
2001
                                1 => array(
2002
                                        'id' => 2,
2003
                                        'tag' => 'tag2',
2004
                                        'created' => '2007-03-18 12:24:23',
2005
                                        'updated' => '2007-03-18 12:26:31'
2006
                                ),
2007
                                2 => array(
2008
                                        'id' => 3,
2009
                                        'tag' => 'tag3',
2010
                                        'created' => '2007-03-18 12:26:23',
2011
                                        'updated' => '2007-03-18 12:28:31'
2012
                )));
2013
                $this->assertEquals($expected, $result);
2014

    
2015
                $this->loadFixtures('JoinA', 'JoinC', 'JoinAC', 'JoinB', 'JoinAB');
2016
                $TestModel = new JoinA();
2017
                $TestModel->hasBelongsToMany = array('JoinC' => array('unique' => true));
2018
                $data = array(
2019
                        'JoinA' => array(
2020
                                'id' => 1,
2021
                                'name' => 'Join A 1',
2022
                                'body' => 'Join A 1 Body',
2023
                        ),
2024
                        'JoinC' => array(
2025
                                'JoinC' => array(
2026
                                        array('join_c_id' => 2, 'other' => 'new record'),
2027
                                        array('join_c_id' => 3, 'other' => 'new record')
2028
                                )
2029
                        )
2030
                );
2031
                $TestModel->save($data);
2032
                $result = $TestModel->read(null, 1);
2033
                $expected = array(4, 5);
2034
                $this->assertEquals($expected, Hash::extract($result, 'JoinC.{n}.JoinAsJoinC.id'));
2035
                $expected = array('new record', 'new record');
2036
                $this->assertEquals($expected, Hash::extract($result, 'JoinC.{n}.JoinAsJoinC.other'));
2037
        }
2038

    
2039
/**
2040
 * test that saving HABTM with an empty array will clear existing HABTM if
2041
 * unique is true
2042
 *
2043
 * @return void
2044
 */
2045
        public function testSaveHabtmEmptyData() {
2046
                $this->loadFixtures('Node', 'Dependency');
2047
                $Node = new Node();
2048

    
2049
                $data = array(
2050
                        'Node' => array('name' => 'New First')
2051
                );
2052
                $Node->id = 1;
2053
                $Node->save($data);
2054

    
2055
                $node = $Node->find('first', array(
2056
                        'conditions' => array('Node.id' => 1),
2057
                        'contain' => array('ParentNode')
2058
                ));
2059

    
2060
                $result = Hash::extract($node, 'ParentNode.{n}.id');
2061
                $expected = array(2);
2062
                $this->assertEquals($expected, $result);
2063

    
2064
                $data = array(
2065
                        'ParentNode' => array()
2066
                );
2067
                $Node->id = 1;
2068
                $Node->save($data);
2069

    
2070
                $node = $Node->find('first', array(
2071
                        'conditions' => array('Node.id' => 1),
2072
                        'contain' => array('ParentNode')
2073
                ));
2074

    
2075
                $result = Hash::extract($node, 'ParentNode.{n}.id');
2076
                $expected = array();
2077
                $this->assertEquals($expected, $result);
2078
        }
2079

    
2080
/**
2081
 * testSaveHabtmNoPrimaryData method
2082
 *
2083
 * @return void
2084
 */
2085
        public function testSaveHabtmNoPrimaryData() {
2086
                $this->loadFixtures('Article', 'User', 'Comment', 'Tag', 'ArticlesTag');
2087
                $TestModel = new Article();
2088

    
2089
                $TestModel->unbindModel(array('belongsTo' => array('User'), 'hasMany' => array('Comment')), false);
2090
                $result = $TestModel->findById(2);
2091
                $expected = array(
2092
                        'Article' => array(
2093
                                'id' => '2',
2094
                                'user_id' => '3',
2095
                                'title' => 'Second Article',
2096
                                'body' => 'Second Article Body',
2097
                                'published' => 'Y',
2098
                                'created' => '2007-03-18 10:41:23',
2099
                                'updated' => '2007-03-18 10:43:31'
2100
                        ),
2101
                        'Tag' => array(
2102
                                array(
2103
                                        'id' => '1',
2104
                                        'tag' => 'tag1',
2105
                                        'created' => '2007-03-18 12:22:23',
2106
                                        'updated' => '2007-03-18 12:24:31'
2107
                                ),
2108
                                array(
2109
                                        'id' => '3',
2110
                                        'tag' => 'tag3',
2111
                                        'created' => '2007-03-18 12:26:23',
2112
                                        'updated' => '2007-03-18 12:28:31'
2113
                                )
2114
                        )
2115
                );
2116
                $this->assertEquals($expected, $result);
2117

    
2118
                $TestModel->id = 2;
2119
                $data = array('Tag' => array('Tag' => array(2)));
2120
                $result = $TestModel->save($data);
2121

    
2122
                $this->assertEquals($data['Tag'], $result['Tag']);
2123

    
2124
                $result = $TestModel->findById(2);
2125
                $expected = array(
2126
                        'Article' => array(
2127
                                'id' => '2',
2128
                                'user_id' => '3',
2129
                                'title' => 'Second Article',
2130
                                'body' => 'Second Article Body',
2131
                                'published' => 'Y',
2132
                                'created' => '2007-03-18 10:41:23',
2133
                                'updated' => static::date()
2134
                        ),
2135
                        'Tag' => array(
2136
                                array(
2137
                                        'id' => '2',
2138
                                        'tag' => 'tag2',
2139
                                        'created' => '2007-03-18 12:24:23',
2140
                                        'updated' => '2007-03-18 12:26:31'
2141
                                )
2142
                        )
2143
                );
2144
                $this->assertEquals($expected, $result);
2145

    
2146
                $this->loadFixtures('Portfolio', 'Item', 'ItemsPortfolio');
2147
                $TestModel = new Portfolio();
2148
                $result = $TestModel->findById(2);
2149
                $expected = array(
2150
                        'Portfolio' => array(
2151
                                'id' => 2,
2152
                                'seller_id' => 1,
2153
                                'name' => 'Portfolio 2'
2154
                        ),
2155
                        'Item' => array(
2156
                                array(
2157
                                        'id' => 2,
2158
                                        'syfile_id' => 2,
2159
                                        'published' => '',
2160
                                        'name' => 'Item 2',
2161
                                        'ItemsPortfolio' => array(
2162
                                                'id' => 2,
2163
                                                'item_id' => 2,
2164
                                                'portfolio_id' => 2
2165
                                        )
2166
                                ),
2167
                                array(
2168
                                        'id' => 6,
2169
                                        'syfile_id' => 6,
2170
                                        'published' => '',
2171
                                        'name' => 'Item 6',
2172
                                        'ItemsPortfolio' => array(
2173
                                                'id' => 6,
2174
                                                'item_id' => 6,
2175
                                                'portfolio_id' => 2
2176
                                        )
2177
                                )
2178
                        )
2179
                );
2180
                $this->assertEquals($expected, $result);
2181

    
2182
                $data = array('Item' => array('Item' => array(1, 2)));
2183
                $TestModel->id = 2;
2184
                $result = $TestModel->save($data);
2185
                $this->assertTrue((bool)$result);
2186

    
2187
                $result = $TestModel->findById(2);
2188
                $result['Item'] = Hash::sort($result['Item'], '{n}.id', 'asc');
2189
                $expected = array(
2190
                        'Portfolio' => array(
2191
                                'id' => 2,
2192
                                'seller_id' => 1,
2193
                                'name' => 'Portfolio 2'
2194
                        ),
2195
                        'Item' => array(
2196
                                array(
2197
                                        'id' => 1,
2198
                                        'syfile_id' => 1,
2199
                                        'published' => '',
2200
                                        'name' => 'Item 1',
2201
                                        'ItemsPortfolio' => array(
2202
                                                'id' => 7,
2203
                                                'item_id' => 1,
2204
                                                'portfolio_id' => 2
2205
                                        )
2206
                                ),
2207
                                array(
2208
                                        'id' => 2,
2209
                                        'syfile_id' => 2,
2210
                                        'published' => '',
2211
                                        'name' => 'Item 2',
2212
                                        'ItemsPortfolio' => array(
2213
                                                'id' => 8,
2214
                                                'item_id' => 2,
2215
                                                'portfolio_id' => 2
2216
                                        )
2217
                                )
2218
                        )
2219
                );
2220
                $this->assertEquals($expected, $result);
2221
        }
2222

    
2223
/**
2224
 * testSaveHabtmCustomKeys method
2225
 *
2226
 * @return void
2227
 */
2228
        public function testSaveHabtmCustomKeys() {
2229
                $this->loadFixtures('Story', 'StoriesTag', 'Tag');
2230
                $Story = new Story();
2231

    
2232
                $data = array(
2233
                        'Story' => array('story' => '1'),
2234
                        'Tag' => array(
2235
                                'Tag' => array(2, 3)
2236
                ));
2237
                $result = $Story->set($data);
2238
                $this->assertFalse(empty($result));
2239

    
2240
                $result = $Story->save();
2241
                $this->assertFalse(empty($result));
2242

    
2243
                $result = $Story->find('all', array('order' => array('Story.story')));
2244
                $expected = array(
2245
                        array(
2246
                                'Story' => array(
2247
                                        'story' => 1,
2248
                                        'title' => 'First Story'
2249
                                ),
2250
                                'Tag' => array(
2251
                                        array(
2252
                                                'id' => 2,
2253
                                                'tag' => 'tag2',
2254
                                                'created' => '2007-03-18 12:24:23',
2255
                                                'updated' => '2007-03-18 12:26:31'
2256
                                        ),
2257
                                        array(
2258
                                                'id' => 3,
2259
                                                'tag' => 'tag3',
2260
                                                'created' => '2007-03-18 12:26:23',
2261
                                                'updated' => '2007-03-18 12:28:31'
2262
                        ))),
2263
                        array(
2264
                                'Story' => array(
2265
                                        'story' => 2,
2266
                                        'title' => 'Second Story'
2267
                                ),
2268
                                'Tag' => array()
2269
                ));
2270
                $this->assertEquals($expected, $result);
2271
        }
2272

    
2273
/**
2274
 * test that saving habtm records respects conditions set in the 'conditions' key
2275
 * for the association.
2276
 *
2277
 * @return void
2278
 */
2279
        public function testHabtmSaveWithConditionsInAssociation() {
2280
                $this->loadFixtures('JoinThing', 'Something', 'SomethingElse');
2281
                $Something = new Something();
2282
                $Something->unbindModel(array('hasAndBelongsToMany' => array('SomethingElse')), false);
2283

    
2284
                $Something->bindModel(array(
2285
                        'hasAndBelongsToMany' => array(
2286
                                'DoomedSomethingElse' => array(
2287
                                        'className' => 'SomethingElse',
2288
                                        'joinTable' => 'join_things',
2289
                                        'conditions' => array('JoinThing.doomed' => true),
2290
                                        'unique' => true
2291
                                ),
2292
                                'NotDoomedSomethingElse' => array(
2293
                                        'className' => 'SomethingElse',
2294
                                        'joinTable' => 'join_things',
2295
                                        'conditions' => array('JoinThing.doomed' => 0),
2296
                                        'unique' => true
2297
                                )
2298
                        )
2299
                ), false);
2300
                $result = $Something->read(null, 1);
2301
                $this->assertTrue(empty($result['NotDoomedSomethingElse']));
2302
                $this->assertEquals(1, count($result['DoomedSomethingElse']));
2303

    
2304
                $data = array(
2305
                        'Something' => array('id' => 1),
2306
                        'NotDoomedSomethingElse' => array(
2307
                                'NotDoomedSomethingElse' => array(
2308
                                        array('something_else_id' => 2, 'doomed' => 0),
2309
                                        array('something_else_id' => 3, 'doomed' => 0)
2310
                                )
2311
                        )
2312
                );
2313
                $Something->create($data);
2314
                $result = $Something->save();
2315
                $this->assertFalse(empty($result));
2316

    
2317
                $result = $Something->read(null, 1);
2318
                $this->assertEquals(2, count($result['NotDoomedSomethingElse']));
2319
                $this->assertEquals(1, count($result['DoomedSomethingElse']));
2320
        }
2321

    
2322
/**
2323
 * testHabtmSaveKeyResolution method
2324
 *
2325
 * @return void
2326
 */
2327
        public function testHabtmSaveKeyResolution() {
2328
                $this->loadFixtures('Apple', 'Device', 'ThePaperMonkies');
2329
                $ThePaper = new ThePaper();
2330

    
2331
                $ThePaper->id = 1;
2332
                $ThePaper->save(array('Monkey' => array(2, 3)));
2333

    
2334
                $result = $ThePaper->findById(1);
2335
                $expected = array(
2336
                        array(
2337
                                'id' => '2',
2338
                                'device_type_id' => '1',
2339
                                'name' => 'Device 2',
2340
                                'typ' => '1'
2341
                        ),
2342
                        array(
2343
                                'id' => '3',
2344
                                'device_type_id' => '1',
2345
                                'name' => 'Device 3',
2346
                                'typ' => '2'
2347
                ));
2348
                $this->assertEquals($expected, $result['Monkey']);
2349

    
2350
                $ThePaper->id = 2;
2351
                $ThePaper->save(array('Monkey' => array(1, 2, 3)));
2352

    
2353
                $result = $ThePaper->findById(2);
2354
                $expected = array(
2355
                        array(
2356
                                'id' => '1',
2357
                                'device_type_id' => '1',
2358
                                'name' => 'Device 1',
2359
                                'typ' => '1'
2360
                        ),
2361
                        array(
2362
                                'id' => '2',
2363
                                'device_type_id' => '1',
2364
                                'name' => 'Device 2',
2365
                                'typ' => '1'
2366
                        ),
2367
                        array(
2368
                                'id' => '3',
2369
                                'device_type_id' => '1',
2370
                                'name' => 'Device 3',
2371
                                'typ' => '2'
2372
                ));
2373
                $this->assertEquals($expected, $result['Monkey']);
2374

    
2375
                $ThePaper->id = 2;
2376
                $ThePaper->save(array('Monkey' => array(1, 3)));
2377

    
2378
                $result = $ThePaper->findById(2);
2379
                $expected = array(
2380
                        array(
2381
                                'id' => '1',
2382
                                'device_type_id' => '1',
2383
                                'name' => 'Device 1',
2384
                                'typ' => '1'
2385
                        ),
2386
                        array(
2387
                                'id' => '3',
2388
                                'device_type_id' => '1',
2389
                                'name' => 'Device 3',
2390
                                'typ' => '2'
2391
                        ));
2392
                $this->assertEquals($expected, $result['Monkey']);
2393

    
2394
                $result = $ThePaper->findById(1);
2395
                $expected = array(
2396
                        array(
2397
                                'id' => '2',
2398
                                'device_type_id' => '1',
2399
                                'name' => 'Device 2',
2400
                                'typ' => '1'
2401
                        ),
2402
                        array(
2403
                                'id' => '3',
2404
                                'device_type_id' => '1',
2405
                                'name' => 'Device 3',
2406
                                'typ' => '2'
2407
                ));
2408
                $this->assertEquals($expected, $result['Monkey']);
2409
        }
2410

    
2411
/**
2412
 * testCreationOfEmptyRecord method
2413
 *
2414
 * @return void
2415
 */
2416
        public function testCreationOfEmptyRecord() {
2417
                $this->loadFixtures('Author');
2418
                $TestModel = new Author();
2419
                $this->assertEquals(4, $TestModel->find('count'));
2420

    
2421
                $TestModel->deleteAll(true, false, false);
2422
                $this->assertEquals(0, $TestModel->find('count'));
2423

    
2424
                $result = $TestModel->save();
2425
                $this->assertTrue(isset($result['Author']['created']));
2426
                $this->assertTrue(isset($result['Author']['updated']));
2427
                $this->assertEquals(1, $TestModel->find('count'));
2428
        }
2429

    
2430
/**
2431
 * testCreateWithPKFiltering method
2432
 *
2433
 * @return void
2434
 */
2435
        public function testCreateWithPKFiltering() {
2436
                $TestModel = new Article();
2437
                $data = array(
2438
                        'id' => 5,
2439
                        'user_id' => 2,
2440
                        'title' => 'My article',
2441
                        'body' => 'Some text'
2442
                );
2443

    
2444
                $result = $TestModel->create($data);
2445
                $expected = array(
2446
                        'Article' => array(
2447
                                'published' => 'N',
2448
                                'id' => 5,
2449
                                'user_id' => 2,
2450
                                'title' => 'My article',
2451
                                'body' => 'Some text'
2452
                ));
2453

    
2454
                $this->assertEquals($expected, $result);
2455
                $this->assertEquals(5, $TestModel->id);
2456

    
2457
                $result = $TestModel->create($data, true);
2458
                $expected = array(
2459
                        'Article' => array(
2460
                                'published' => 'N',
2461
                                'id' => false,
2462
                                'user_id' => 2,
2463
                                'title' => 'My article',
2464
                                'body' => 'Some text'
2465
                ));
2466

    
2467
                $this->assertEquals($expected, $result);
2468
                $this->assertFalse($TestModel->id);
2469

    
2470
                $result = $TestModel->create(array('Article' => $data), true);
2471
                $expected = array(
2472
                        'Article' => array(
2473
                                'published' => 'N',
2474
                                'id' => false,
2475
                                'user_id' => 2,
2476
                                'title' => 'My article',
2477
                                'body' => 'Some text'
2478
                ));
2479

    
2480
                $this->assertEquals($expected, $result);
2481
                $this->assertFalse($TestModel->id);
2482

    
2483
                $data = array(
2484
                        'id' => 6,
2485
                        'user_id' => 2,
2486
                        'title' => 'My article',
2487
                        'body' => 'Some text',
2488
                        'created' => '1970-01-01 00:00:00',
2489
                        'updated' => '1970-01-01 12:00:00',
2490
                        'modified' => '1970-01-01 12:00:00'
2491
                );
2492

    
2493
                $result = $TestModel->create($data);
2494
                $expected = array(
2495
                        'Article' => array(
2496
                                'published' => 'N',
2497
                                'id' => 6,
2498
                                'user_id' => 2,
2499
                                'title' => 'My article',
2500
                                'body' => 'Some text',
2501
                                'created' => '1970-01-01 00:00:00',
2502
                                'updated' => '1970-01-01 12:00:00',
2503
                                'modified' => '1970-01-01 12:00:00'
2504
                ));
2505
                $this->assertEquals($expected, $result);
2506
                $this->assertEquals(6, $TestModel->id);
2507

    
2508
                $result = $TestModel->create(array(
2509
                        'Article' => array_diff_key($data, array(
2510
                                'created' => true,
2511
                                'updated' => true,
2512
                                'modified' => true
2513
                ))), true);
2514
                $expected = array(
2515
                        'Article' => array(
2516
                                'published' => 'N',
2517
                                'id' => false,
2518
                                'user_id' => 2,
2519
                                'title' => 'My article',
2520
                                'body' => 'Some text'
2521
                ));
2522
                $this->assertEquals($expected, $result);
2523
                $this->assertFalse($TestModel->id);
2524
        }
2525

    
2526
/**
2527
 * testCreationWithMultipleData method
2528
 *
2529
 * @return void
2530
 */
2531
        public function testCreationWithMultipleData() {
2532
                $this->loadFixtures('Article', 'Comment');
2533
                $Article = new Article();
2534
                $Comment = new Comment();
2535

    
2536
                $articles = $Article->find('all', array(
2537
                        'fields' => array('id', 'title'),
2538
                        'recursive' => -1,
2539
                        'order' => array('Article.id' => 'ASC')
2540
                ));
2541
                $expected = array(
2542
                        array('Article' => array(
2543
                                'id' => 1,
2544
                                'title' => 'First Article'
2545
                        )),
2546
                        array('Article' => array(
2547
                                'id' => 2,
2548
                                'title' => 'Second Article'
2549
                        )),
2550
                        array('Article' => array(
2551
                                'id' => 3,
2552
                                'title' => 'Third Article'
2553
                )));
2554
                $this->assertEquals($expected, $articles);
2555

    
2556
                $comments = $Comment->find('all', array(
2557
                        'fields' => array('id', 'article_id', 'user_id', 'comment', 'published'),
2558
                        'recursive' => -1,
2559
                        'order' => array('Comment.id' => 'ASC')
2560
                ));
2561
                $expected = array(
2562
                        array('Comment' => array(
2563
                                'id' => 1,
2564
                                'article_id' => 1,
2565
                                'user_id' => 2,
2566
                                'comment' => 'First Comment for First Article',
2567
                                'published' => 'Y'
2568
                        )),
2569
                        array('Comment' => array(
2570
                                'id' => 2,
2571
                                'article_id' => 1,
2572
                                'user_id' => 4,
2573
                                'comment' => 'Second Comment for First Article',
2574
                                'published' => 'Y'
2575
                        )),
2576
                        array('Comment' => array(
2577
                                'id' => 3,
2578
                                'article_id' => 1,
2579
                                'user_id' => 1,
2580
                                'comment' => 'Third Comment for First Article',
2581
                                'published' => 'Y'
2582
                        )),
2583
                        array('Comment' => array(
2584
                                'id' => 4,
2585
                                'article_id' => 1,
2586
                                'user_id' => 1,
2587
                                'comment' => 'Fourth Comment for First Article',
2588
                                'published' => 'N'
2589
                        )),
2590
                        array('Comment' => array(
2591
                                'id' => 5,
2592
                                'article_id' => 2,
2593
                                'user_id' => 1,
2594
                                'comment' => 'First Comment for Second Article',
2595
                                'published' => 'Y'
2596
                        )),
2597
                        array('Comment' => array(
2598
                                'id' => 6,
2599
                                'article_id' => 2,
2600
                                'user_id' => 2,
2601
                                'comment' => 'Second Comment for Second Article',
2602
                                'published' => 'Y'
2603
                )));
2604
                $this->assertEquals($expected, $comments);
2605

    
2606
                $data = array(
2607
                        'Comment' => array(
2608
                                'article_id' => 2,
2609
                                'user_id' => 4,
2610
                                'comment' => 'Brand New Comment',
2611
                                'published' => 'N'
2612
                        ),
2613
                        'Article' => array(
2614
                                'id' => 2,
2615
                                'title' => 'Second Article Modified'
2616
                ));
2617
                $result = $Comment->create($data);
2618
                $this->assertFalse(empty($result));
2619

    
2620
                $result = $Comment->save();
2621
                $this->assertFalse(empty($result));
2622

    
2623
                $articles = $Article->find('all', array(
2624
                        'fields' => array('id', 'title'),
2625
                        'recursive' => -1,
2626
                        'order' => array('Article.id' => 'ASC')
2627
                ));
2628
                $expected = array(
2629
                        array('Article' => array(
2630
                                'id' => 1,
2631
                                'title' => 'First Article'
2632
                        )),
2633
                        array('Article' => array(
2634
                                'id' => 2,
2635
                                'title' => 'Second Article'
2636
                        )),
2637
                        array('Article' => array(
2638
                                'id' => 3,
2639
                                'title' => 'Third Article'
2640
                )));
2641
                $this->assertEquals($expected, $articles);
2642

    
2643
                $comments = $Comment->find('all', array(
2644
                        'fields' => array('id', 'article_id', 'user_id', 'comment', 'published'),
2645
                        'recursive' => -1,
2646
                        'order' => array('Comment.id' => 'ASC')
2647
                ));
2648
                $expected = array(
2649
                        array('Comment' => array(
2650
                                'id' => 1,
2651
                                'article_id' => 1,
2652
                                'user_id' => 2,
2653
                                'comment' => 'First Comment for First Article',
2654
                                'published' => 'Y'
2655
                        )),
2656
                        array('Comment' => array(
2657
                                'id' => 2,
2658
                                'article_id' => 1,
2659
                                'user_id' => 4,
2660
                                'comment' => 'Second Comment for First Article',
2661
                                'published' => 'Y'
2662
                        )),
2663
                        array('Comment' => array(
2664
                                'id' => 3,
2665
                                'article_id' => 1,
2666
                                'user_id' => 1,
2667
                                'comment' => 'Third Comment for First Article',
2668
                                'published' => 'Y'
2669
                        )),
2670
                        array('Comment' => array(
2671
                                'id' => 4,
2672
                                'article_id' => 1,
2673
                                'user_id' => 1,
2674
                                'comment' => 'Fourth Comment for First Article',
2675
                                'published' => 'N'
2676
                        )),
2677
                        array('Comment' => array(
2678
                                'id' => 5,
2679
                                'article_id' => 2,
2680
                                'user_id' => 1,
2681
                                'comment' => 'First Comment for Second Article',
2682
                                'published' => 'Y'
2683
                        )),
2684
                        array('Comment' => array(
2685
                                'id' => 6,
2686
                                'article_id' => 2,
2687
                                'user_id' => 2, 'comment' =>
2688
                                'Second Comment for Second Article',
2689
                                'published' => 'Y'
2690
                        )),
2691
                        array('Comment' => array(
2692
                                'id' => 7,
2693
                                'article_id' => 2,
2694
                                'user_id' => 4,
2695
                                'comment' => 'Brand New Comment',
2696
                                'published' => 'N'
2697
                )));
2698
                $this->assertEquals($expected, $comments);
2699
        }
2700

    
2701
/**
2702
 * testCreationWithMultipleDataSameModel method
2703
 *
2704
 * @return void
2705
 */
2706
        public function testCreationWithMultipleDataSameModel() {
2707
                $this->loadFixtures('Article');
2708
                $Article = new Article();
2709

    
2710
                $result = $Article->field('title', array('id' => 1));
2711
                $this->assertEquals('First Article', $result);
2712

    
2713
                $data = array(
2714
                        'Article' => array(
2715
                                'user_id' => 2,
2716
                                'title' => 'Brand New Article',
2717
                                'body' => 'Brand New Article Body',
2718
                                'published' => 'Y'
2719
                        ),
2720
                        'SecondaryArticle' => array(
2721
                                'id' => 1
2722
                ));
2723

    
2724
                $Article->create();
2725
                $result = $Article->save($data);
2726
                $this->assertFalse(empty($result));
2727

    
2728
                $result = $Article->getInsertID();
2729
                $this->assertTrue(!empty($result));
2730

    
2731
                $result = $Article->field('title', array('id' => 1));
2732
                $this->assertEquals('First Article', $result);
2733

    
2734
                $articles = $Article->find('all', array(
2735
                        'fields' => array('id', 'title'),
2736
                        'recursive' => -1,
2737
                        'order' => array('Article.id' => 'ASC')
2738
                ));
2739
                $expected = array(
2740
                        array('Article' => array(
2741
                                'id' => 1,
2742
                                'title' => 'First Article'
2743
                        )),
2744
                        array('Article' => array(
2745
                                'id' => 2,
2746
                                'title' => 'Second Article'
2747
                        )),
2748
                        array('Article' => array(
2749
                                'id' => 3,
2750
                                'title' => 'Third Article'
2751
                        )),
2752
                        array('Article' => array(
2753
                                'id' => 4,
2754
                                'title' => 'Brand New Article'
2755
                )));
2756

    
2757
                $this->assertEquals($expected, $articles);
2758
        }
2759

    
2760
/**
2761
 * testCreationWithMultipleDataSameModelManualInstances method
2762
 *
2763
 * @return void
2764
 */
2765
        public function testCreationWithMultipleDataSameModelManualInstances() {
2766
                $this->loadFixtures('PrimaryModel');
2767
                $Primary = new PrimaryModel();
2768

    
2769
                $result = $Primary->field('primary_name', array('id' => 1));
2770
                $this->assertEquals('Primary Name Existing', $result);
2771

    
2772
                $data = array(
2773
                        'PrimaryModel' => array(
2774
                                'primary_name' => 'Primary Name New'
2775
                        ),
2776
                        'SecondaryModel' => array(
2777
                                'id' => array(1)
2778
                ));
2779

    
2780
                $Primary->create();
2781
                $result = $Primary->save($data);
2782
                $this->assertFalse(empty($result));
2783

    
2784
                $result = $Primary->field('primary_name', array('id' => 1));
2785
                $this->assertEquals('Primary Name Existing', $result);
2786

    
2787
                $result = $Primary->getInsertID();
2788
                $this->assertTrue(!empty($result));
2789

    
2790
                $result = $Primary->field('primary_name', array('id' => $result));
2791
                $this->assertEquals('Primary Name New', $result);
2792

    
2793
                $result = $Primary->find('count');
2794
                $this->assertEquals(2, $result);
2795
        }
2796

    
2797
/**
2798
 * testRecordExists method
2799
 *
2800
 * @return void
2801
 */
2802
        public function testRecordExists() {
2803
                $this->loadFixtures('User');
2804
                $TestModel = new User();
2805

    
2806
                $this->assertFalse($TestModel->exists());
2807
                $TestModel->read(null, 1);
2808
                $this->assertTrue($TestModel->exists());
2809
                $TestModel->create();
2810
                $this->assertFalse($TestModel->exists());
2811
                $TestModel->id = 4;
2812
                $this->assertTrue($TestModel->exists());
2813

    
2814
                $TestModel = new TheVoid();
2815
                $this->assertFalse($TestModel->exists());
2816

    
2817
                $TestModel->id = 5;
2818
                $this->assertFalse($TestModel->exists());
2819
        }
2820

    
2821
/**
2822
 * testUpdateExisting method
2823
 *
2824
 * @return void
2825
 */
2826
        public function testUpdateExisting() {
2827
                $this->loadFixtures('User', 'Article', 'Comment');
2828
                $TestModel = new User();
2829
                $TestModel->create();
2830

    
2831
                $TestModel->save(array(
2832
                        'User' => array(
2833
                                'user' => 'some user',
2834
                                'password' => 'some password'
2835
                )));
2836
                $this->assertTrue(is_int($TestModel->id) || ((int)$TestModel->id === 5));
2837
                $id = $TestModel->id;
2838

    
2839
                $TestModel->save(array(
2840
                        'User' => array(
2841
                                'user' => 'updated user'
2842
                )));
2843
                $this->assertEquals($id, $TestModel->id);
2844

    
2845
                $result = $TestModel->findById($id);
2846
                $this->assertEquals('updated user', $result['User']['user']);
2847
                $this->assertEquals('some password', $result['User']['password']);
2848

    
2849
                $Article = new Article();
2850
                $Comment = new Comment();
2851
                $data = array(
2852
                        'Comment' => array(
2853
                                'id' => 1,
2854
                                'comment' => 'First Comment for First Article'
2855
                        ),
2856
                        'Article' => array(
2857
                                'id' => 2,
2858
                                'title' => 'Second Article'
2859
                ));
2860

    
2861
                $result = $Article->save($data);
2862
                $this->assertFalse(empty($result));
2863

    
2864
                $result = $Comment->save($data);
2865
                $this->assertFalse(empty($result));
2866
        }
2867

    
2868
/**
2869
 * test updating records and saving blank values.
2870
 *
2871
 * @return void
2872
 */
2873
        public function testUpdateSavingBlankValues() {
2874
                $this->loadFixtures('Article');
2875
                $Article = new Article();
2876
                $Article->validate = array();
2877
                $Article->create();
2878
                $result = $Article->save(array(
2879
                        'id' => 1,
2880
                        'title' => '',
2881
                        'body' => ''
2882
                ));
2883
                $this->assertTrue((bool)$result);
2884
                $result = $Article->find('first', array('conditions' => array('Article.id' => 1)));
2885
                $this->assertEquals('', $result['Article']['title'], 'Title is not blank');
2886
                $this->assertEquals('', $result['Article']['body'], 'Body is not blank');
2887
        }
2888

    
2889
/**
2890
 * testUpdateMultiple method
2891
 *
2892
 * @return void
2893
 */
2894
        public function testUpdateMultiple() {
2895
                $this->loadFixtures('Comment', 'Article', 'User', 'CategoryThread');
2896
                $TestModel = new Comment();
2897
                $result = Hash::extract($TestModel->find('all'), '{n}.Comment.user_id');
2898
                $expected = array('2', '4', '1', '1', '1', '2');
2899
                $this->assertEquals($expected, $result);
2900

    
2901
                $TestModel->updateAll(array('Comment.user_id' => 5), array('Comment.user_id' => 2));
2902
                $result = Hash::combine($TestModel->find('all'), '{n}.Comment.id', '{n}.Comment.user_id');
2903
                $expected = array(1 => 5, 2 => 4, 3 => 1, 4 => 1, 5 => 1, 6 => 5);
2904
                $this->assertEquals($expected, $result);
2905

    
2906
                $result = $TestModel->updateAll(
2907
                        array('Comment.comment' => "'Updated today'"),
2908
                        array('Comment.user_id' => 5)
2909
                );
2910
                $this->assertFalse(empty($result));
2911
                $result = Hash::extract(
2912
                        $TestModel->find('all', array(
2913
                                'conditions' => array(
2914
                                        'Comment.user_id' => 5
2915
                        ))),
2916
                        '{n}.Comment.comment'
2917
                );
2918
                $expected = array_fill(0, 2, 'Updated today');
2919
                $this->assertEquals($expected, $result);
2920
        }
2921

    
2922
/**
2923
 * testHabtmUuidWithUuidId method
2924
 *
2925
 * @return void
2926
 */
2927
        public function testHabtmUuidWithUuidId() {
2928
                $this->loadFixtures('Uuidportfolio', 'Uuiditem', 'UuiditemsUuidportfolio', 'UuiditemsUuidportfolioNumericid');
2929
                $TestModel = new Uuidportfolio();
2930

    
2931
                $data = array('Uuidportfolio' => array('name' => 'Portfolio 3'));
2932
                $data['Uuiditem']['Uuiditem'] = array('483798c8-c7cc-430e-8cf9-4fcc40cf8569');
2933
                $TestModel->create($data);
2934
                $TestModel->save();
2935
                $id = $TestModel->id;
2936
                $result = $TestModel->read(null, $id);
2937
                $this->assertEquals(1, count($result['Uuiditem']));
2938
                $this->assertEquals(36, strlen($result['Uuiditem'][0]['UuiditemsUuidportfolio']['id']));
2939
        }
2940

    
2941
/**
2942
 * test HABTM saving when join table has no primary key and only 2 columns.
2943
 *
2944
 * @return void
2945
 */
2946
        public function testHabtmSavingWithNoPrimaryKeyUuidJoinTable() {
2947
                $this->loadFixtures('UuidTag', 'Fruit', 'FruitsUuidTag');
2948
                $Fruit = new Fruit();
2949
                $Fruit->FruitsUuidTag->order = null;
2950
                $data = array(
2951
                        'Fruit' => array(
2952
                                'color' => 'Red',
2953
                                'shape' => 'Heart-shaped',
2954
                                'taste' => 'sweet',
2955
                                'name' => 'Strawberry',
2956
                        ),
2957
                        'UuidTag' => array(
2958
                                'UuidTag' => array(
2959
                                        '481fc6d0-b920-43e0-e50f-6d1740cf8569'
2960
                                )
2961
                        )
2962
                );
2963
                $result = $Fruit->save($data);
2964
                $this->assertFalse(empty($result));
2965
        }
2966

    
2967
/**
2968
 * test HABTM saving when join table has no primary key and only 2 columns, no with model is used.
2969
 *
2970
 * @return void
2971
 */
2972
        public function testHabtmSavingWithNoPrimaryKeyUuidJoinTableNoWith() {
2973
                $this->loadFixtures('UuidTag', 'Fruit', 'FruitsUuidTag');
2974
                $Fruit = new FruitNoWith();
2975
                $data = array(
2976
                        'Fruit' => array(
2977
                                'color' => 'Red',
2978
                                'shape' => 'Heart-shaped',
2979
                                'taste' => 'sweet',
2980
                                'name' => 'Strawberry',
2981
                        ),
2982
                        'UuidTag' => array(
2983
                                'UuidTag' => array(
2984
                                        '481fc6d0-b920-43e0-e50f-6d1740cf8569'
2985
                                )
2986
                        )
2987
                );
2988
                $result = $Fruit->save($data);
2989
                $this->assertFalse(empty($result));
2990
        }
2991

    
2992
/**
2993
 * testHabtmUuidWithNumericId method
2994
 *
2995
 * @return void
2996
 */
2997
        public function testHabtmUuidWithNumericId() {
2998
                $this->loadFixtures('Uuidportfolio', 'Uuiditem', 'UuiditemsUuidportfolioNumericid');
2999
                $TestModel = new Uuiditem();
3000

    
3001
                $data = array('Uuiditem' => array('name' => 'Item 7', 'published' => 0));
3002
                $data['Uuidportfolio']['Uuidportfolio'] = array('480af662-eb8c-47d3-886b-230540cf8569');
3003
                $TestModel->create($data);
3004
                $TestModel->save();
3005
                $id = $TestModel->id;
3006
                $result = $TestModel->read(null, $id);
3007
                $this->assertEquals(1, count($result['Uuidportfolio']));
3008
        }
3009

    
3010
/**
3011
 * testSaveMultipleHabtm method
3012
 *
3013
 * @return void
3014
 */
3015
        public function testSaveMultipleHabtm() {
3016
                $this->loadFixtures('JoinA', 'JoinB', 'JoinC', 'JoinAB', 'JoinAC');
3017
                $TestModel = new JoinA();
3018
                $result = $TestModel->findById(1);
3019

    
3020
                $expected = array(
3021
                        'JoinA' => array(
3022
                                'id' => 1,
3023
                                'name' => 'Join A 1',
3024
                                'body' => 'Join A 1 Body',
3025
                                'created' => '2008-01-03 10:54:23',
3026
                                'updated' => '2008-01-03 10:54:23'
3027
                        ),
3028
                        'JoinB' => array(
3029
                                0 => array(
3030
                                        'id' => 2,
3031
                                        'name' => 'Join B 2',
3032
                                        'created' => '2008-01-03 10:55:02',
3033
                                        'updated' => '2008-01-03 10:55:02',
3034
                                        'JoinAsJoinB' => array(
3035
                                                'id' => 1,
3036
                                                'join_a_id' => 1,
3037
                                                'join_b_id' => 2,
3038
                                                'other' => 'Data for Join A 1 Join B 2',
3039
                                                'created' => '2008-01-03 10:56:33',
3040
                                                'updated' => '2008-01-03 10:56:33'
3041
                        ))),
3042
                        'JoinC' => array(
3043
                                0 => array(
3044
                                        'id' => 2,
3045
                                        'name' => 'Join C 2',
3046
                                        'created' => '2008-01-03 10:56:12',
3047
                                        'updated' => '2008-01-03 10:56:12',
3048
                                        'JoinAsJoinC' => array(
3049
                                                'id' => 1,
3050
                                                'join_a_id' => 1,
3051
                                                'join_c_id' => 2,
3052
                                                'other' => 'Data for Join A 1 Join C 2',
3053
                                                'created' => '2008-01-03 10:57:22',
3054
                                                'updated' => '2008-01-03 10:57:22'
3055
                ))));
3056

    
3057
                $this->assertEquals($expected, $result);
3058

    
3059
                $TestModel->id = 1;
3060
                $data = array(
3061
                        'JoinA' => array(
3062
                                'id' => '1',
3063
                                'name' => 'New name for Join A 1',
3064
                                'updated' => static::date()
3065
                        ),
3066
                        'JoinB' => array(
3067
                                array(
3068
                                        'id' => 1,
3069
                                        'join_b_id' => 2,
3070
                                        'other' => 'New data for Join A 1 Join B 2',
3071
                                        'created' => static::date(),
3072
                                        'updated' => static::date()
3073
                        )),
3074
                        'JoinC' => array(
3075
                                array(
3076
                                        'id' => 1,
3077
                                        'join_c_id' => 2,
3078
                                        'other' => 'New data for Join A 1 Join C 2',
3079
                                        'created' => static::date(),
3080
                                        'updated' => static::date()
3081
                )));
3082

    
3083
                $TestModel->set($data);
3084
                $TestModel->save();
3085

    
3086
                $result = $TestModel->findById(1);
3087
                $expected = array(
3088
                        'JoinA' => array(
3089
                                'id' => 1,
3090
                                'name' => 'New name for Join A 1',
3091
                                'body' => 'Join A 1 Body',
3092
                                'created' => '2008-01-03 10:54:23',
3093
                                'updated' => static::date()
3094
                        ),
3095
                        'JoinB' => array(
3096
                                0 => array(
3097
                                        'id' => 2,
3098
                                        'name' => 'Join B 2',
3099
                                        'created' => '2008-01-03 10:55:02',
3100
                                        'updated' => '2008-01-03 10:55:02',
3101
                                        'JoinAsJoinB' => array(
3102
                                                'id' => 1,
3103
                                                'join_a_id' => 1,
3104
                                                'join_b_id' => 2,
3105
                                                'other' => 'New data for Join A 1 Join B 2',
3106
                                                'created' => static::date(),
3107
                                                'updated' => static::date()
3108
                        ))),
3109
                        'JoinC' => array(
3110
                                0 => array(
3111
                                        'id' => 2,
3112
                                        'name' => 'Join C 2',
3113
                                        'created' => '2008-01-03 10:56:12',
3114
                                        'updated' => '2008-01-03 10:56:12',
3115
                                        'JoinAsJoinC' => array(
3116
                                                'id' => 1,
3117
                                                'join_a_id' => 1,
3118
                                                'join_c_id' => 2,
3119
                                                'other' => 'New data for Join A 1 Join C 2',
3120
                                                'created' => static::date(),
3121
                                                'updated' => static::date()
3122
                ))));
3123

    
3124
                $this->assertEquals($expected, $result);
3125
        }
3126

    
3127
/**
3128
 * testSaveAll method
3129
 *
3130
 * @return void
3131
 */
3132
        public function testSaveAll() {
3133
                $this->loadFixtures('Post', 'Author', 'Comment', 'Attachment', 'Article', 'User');
3134
                $TestModel = new Post();
3135

    
3136
                $result = $TestModel->find('all');
3137
                $this->assertEquals(3, count($result));
3138
                $this->assertFalse(isset($result[3]));
3139

    
3140
                $TestModel->saveAll(array(
3141
                        'Post' => array(
3142
                                'title' => 'Post with Author',
3143
                                'body' => 'This post will be saved with an author'
3144
                        ),
3145
                        'Author' => array(
3146
                                'user' => 'bob',
3147
                                'password' => '5f4dcc3b5aa765d61d8327deb882cf90'
3148
                )));
3149

    
3150
                $result = $TestModel->find('all');
3151
                $expected = array(
3152
                        'Post' => array(
3153
                                'id' => '4',
3154
                                'author_id' => '5',
3155
                                'title' => 'Post with Author',
3156
                                'body' => 'This post will be saved with an author',
3157
                                'published' => 'N'
3158
                        ),
3159
                        'Author' => array(
3160
                                'id' => '5',
3161
                                'user' => 'bob',
3162
                                'password' => '5f4dcc3b5aa765d61d8327deb882cf90',
3163
                                'test' => 'working'
3164
                ));
3165
                $this->assertEquals(static::date(), $result[3]['Post']['created']);
3166
                $this->assertEquals(static::date(), $result[3]['Post']['updated']);
3167
                $this->assertEquals(static::date(), $result[3]['Author']['created']);
3168
                $this->assertEquals(static::date(), $result[3]['Author']['updated']);
3169
                unset($result[3]['Post']['created'], $result[3]['Post']['updated']);
3170
                unset($result[3]['Author']['created'], $result[3]['Author']['updated']);
3171
                $this->assertEquals($expected, $result[3]);
3172
                $this->assertEquals(4, count($result));
3173

    
3174
                $TestModel->deleteAll(true);
3175
                $this->assertEquals(array(), $TestModel->find('all'));
3176

    
3177
                // SQLite seems to reset the PK counter when that happens, so we need this to make the tests pass
3178
                $this->db->truncate($TestModel);
3179

    
3180
                $TestModel->saveAll(array(
3181
                        array(
3182
                                'title' => 'Multi-record post 1',
3183
                                'body' => 'First multi-record post',
3184
                                'author_id' => 2
3185
                        ),
3186
                        array(
3187
                                'title' => 'Multi-record post 2',
3188
                                'body' => 'Second multi-record post',
3189
                                'author_id' => 2
3190
                )));
3191

    
3192
                $result = $TestModel->find('all', array(
3193
                        'recursive' => -1,
3194
                        'order' => 'Post.id ASC'
3195
                ));
3196
                $expected = array(
3197
                        array(
3198
                                'Post' => array(
3199
                                        'id' => '1',
3200
                                        'author_id' => '2',
3201
                                        'title' => 'Multi-record post 1',
3202
                                        'body' => 'First multi-record post',
3203
                                        'published' => 'N'
3204
                        )),
3205
                        array(
3206
                                'Post' => array(
3207
                                        'id' => '2',
3208
                                        'author_id' => '2',
3209
                                        'title' => 'Multi-record post 2',
3210
                                        'body' => 'Second multi-record post',
3211
                                        'published' => 'N'
3212
                )));
3213
                $this->assertEquals(static::date(), $result[0]['Post']['created']);
3214
                $this->assertEquals(static::date(), $result[0]['Post']['updated']);
3215
                $this->assertEquals(static::date(), $result[1]['Post']['created']);
3216
                $this->assertEquals(static::date(), $result[1]['Post']['updated']);
3217
                unset($result[0]['Post']['created'], $result[0]['Post']['updated']);
3218
                unset($result[1]['Post']['created'], $result[1]['Post']['updated']);
3219
                $this->assertEquals($expected, $result);
3220

    
3221
                $TestModel = new Comment();
3222
                $result = $TestModel->saveAll(array(
3223
                        'Comment' => array(
3224
                                'article_id' => 2,
3225
                                'user_id' => 2,
3226
                                'comment' => 'New comment with attachment',
3227
                                'published' => 'Y'
3228
                        ),
3229
                        'Attachment' => array(
3230
                                'attachment' => 'some_file.tgz'
3231
                        )));
3232
                $this->assertFalse(empty($result));
3233

    
3234
                $result = $TestModel->find('all');
3235
                $expected = array(
3236
                        'id' => '7',
3237
                        'article_id' => '2',
3238
                        'user_id' => '2',
3239
                        'comment' => 'New comment with attachment',
3240
                        'published' => 'Y'
3241
                );
3242
                $this->assertEquals(static::date(), $result[6]['Comment']['created']);
3243
                $this->assertEquals(static::date(), $result[6]['Comment']['updated']);
3244
                unset($result[6]['Comment']['created'], $result[6]['Comment']['updated']);
3245
                $this->assertEquals($expected, $result[6]['Comment']);
3246

    
3247
                $expected = array(
3248
                        'id' => '2',
3249
                        'comment_id' => '7',
3250
                        'attachment' => 'some_file.tgz'
3251
                );
3252
                $this->assertEquals(static::date(), $result[6]['Attachment']['created']);
3253
                $this->assertEquals(static::date(), $result[6]['Attachment']['updated']);
3254
                unset($result[6]['Attachment']['created'], $result[6]['Attachment']['updated']);
3255
                $this->assertEquals($expected, $result[6]['Attachment']);
3256
        }
3257

    
3258
/**
3259
 * Test SaveAll with Habtm relations
3260
 *
3261
 * @return void
3262
 */
3263
        public function testSaveAllHabtm() {
3264
                $this->loadFixtures('Article', 'Tag', 'Comment', 'User', 'ArticlesTag');
3265
                $data = array(
3266
                        'Article' => array(
3267
                                'user_id' => 1,
3268
                                'title' => 'Article Has and belongs to Many Tags'
3269
                        ),
3270
                        'Tag' => array(
3271
                                'Tag' => array(1, 2)
3272
                        ),
3273
                        'Comment' => array(
3274
                                array(
3275
                                        'comment' => 'Article comment',
3276
                                        'user_id' => 1
3277
                )));
3278
                $Article = new Article();
3279
                $result = $Article->saveAll($data);
3280
                $this->assertFalse(empty($result));
3281

    
3282
                $result = $Article->read();
3283
                $this->assertEquals(2, count($result['Tag']));
3284
                $this->assertEquals('tag1', $result['Tag'][0]['tag']);
3285
                $this->assertEquals(1, count($result['Comment']));
3286
                $this->assertEquals(1, count($result['Comment'][0]['comment']));
3287
        }
3288

    
3289
/**
3290
 * Test SaveAll with Habtm relations and extra join table fields
3291
 *
3292
 * @return void
3293
 */
3294
        public function testSaveAllHabtmWithExtraJoinTableFields() {
3295
                $this->loadFixtures('Something', 'SomethingElse', 'JoinThing');
3296

    
3297
                $data = array(
3298
                        'Something' => array(
3299
                                'id' => 4,
3300
                                'title' => 'Extra Fields',
3301
                                'body' => 'Extra Fields Body',
3302
                                'published' => '1'
3303
                        ),
3304
                        'SomethingElse' => array(
3305
                                array('something_else_id' => 1, 'doomed' => '1'),
3306
                                array('something_else_id' => 2, 'doomed' => '0'),
3307
                                array('something_else_id' => 3, 'doomed' => '1')
3308
                        )
3309
                );
3310

    
3311
                $Something = new Something();
3312
                $result = $Something->saveAll($data);
3313
                $this->assertFalse(empty($result));
3314
                $result = $Something->read();
3315

    
3316
                $this->assertEquals(3, count($result['SomethingElse']));
3317
                $this->assertTrue(Set::matches('/Something[id=4]', $result));
3318

    
3319
                $this->assertTrue(Set::matches('/SomethingElse[id=1]', $result));
3320
                $this->assertTrue(Set::matches('/SomethingElse[id=1]/JoinThing[something_else_id=1]', $result));
3321
                $this->assertTrue(Set::matches('/SomethingElse[id=1]/JoinThing[doomed=1]', $result));
3322

    
3323
                $this->assertTrue(Set::matches('/SomethingElse[id=2]', $result));
3324
                $this->assertTrue(Set::matches('/SomethingElse[id=2]/JoinThing[something_else_id=2]', $result));
3325
                $this->assertTrue(Set::matches('/SomethingElse[id=2]/JoinThing[doomed=0]', $result));
3326

    
3327
                $this->assertTrue(Set::matches('/SomethingElse[id=3]', $result));
3328
                $this->assertTrue(Set::matches('/SomethingElse[id=3]/JoinThing[something_else_id=3]', $result));
3329
                $this->assertTrue(Set::matches('/SomethingElse[id=3]/JoinThing[doomed=1]', $result));
3330
        }
3331

    
3332
/**
3333
 * testSaveAllHasOne method
3334
 *
3335
 * @return void
3336
 */
3337
        public function testSaveAllHasOne() {
3338
                $model = new Comment();
3339
                $model->deleteAll(true);
3340
                $this->assertEquals(array(), $model->find('all'));
3341

    
3342
                $model->Attachment->deleteAll(true);
3343
                $this->assertEquals(array(), $model->Attachment->find('all'));
3344

    
3345
                $this->assertTrue($model->saveAll(array(
3346
                        'Comment' => array(
3347
                                'comment' => 'Comment with attachment',
3348
                                'article_id' => 1,
3349
                                'user_id' => 1
3350
                        ),
3351
                        'Attachment' => array(
3352
                                'attachment' => 'some_file.zip'
3353
                ))));
3354
                $result = $model->find('all', array('fields' => array(
3355
                        'Comment.id', 'Comment.comment', 'Attachment.id',
3356
                        'Attachment.comment_id', 'Attachment.attachment'
3357
                )));
3358
                $expected = array(array(
3359
                        'Comment' => array(
3360
                                'id' => '1',
3361
                                'comment' => 'Comment with attachment'
3362
                        ),
3363
                        'Attachment' => array(
3364
                                'id' => '1',
3365
                                'comment_id' => '1',
3366
                                'attachment' => 'some_file.zip'
3367
                )));
3368
                $this->assertEquals($expected, $result);
3369

    
3370
                $model->Attachment->bindModel(array('belongsTo' => array('Comment')), false);
3371
                $data = array(
3372
                        'Comment' => array(
3373
                                'comment' => 'Comment with attachment',
3374
                                'article_id' => 1,
3375
                                'user_id' => 1
3376
                        ),
3377
                        'Attachment' => array(
3378
                                'attachment' => 'some_file.zip'
3379
                ));
3380
                $this->assertTrue($model->saveAll($data, array('validate' => 'first')));
3381
        }
3382

    
3383
/**
3384
 * testSaveAllBelongsTo method
3385
 *
3386
 * @return void
3387
 */
3388
        public function testSaveAllBelongsTo() {
3389
                $model = new Comment();
3390
                $model->deleteAll(true);
3391
                $this->assertEquals(array(), $model->find('all'));
3392

    
3393
                $model->Article->deleteAll(true);
3394
                $this->assertEquals(array(), $model->Article->find('all'));
3395

    
3396
                $this->assertTrue($model->saveAll(array(
3397
                        'Comment' => array(
3398
                                'comment' => 'Article comment',
3399
                                'article_id' => 1,
3400
                                'user_id' => 1
3401
                        ),
3402
                        'Article' => array(
3403
                                'title' => 'Model Associations 101',
3404
                                'user_id' => 1
3405
                ))));
3406
                $result = $model->find('all', array('fields' => array(
3407
                        'Comment.id', 'Comment.comment', 'Comment.article_id', 'Article.id', 'Article.title'
3408
                )));
3409
                $expected = array(array(
3410
                        'Comment' => array(
3411
                                'id' => '1',
3412
                                'article_id' => '1',
3413
                                'comment' => 'Article comment'
3414
                        ),
3415
                        'Article' => array(
3416
                                'id' => '1',
3417
                                'title' => 'Model Associations 101'
3418
                )));
3419
                $this->assertEquals($expected, $result);
3420
        }
3421

    
3422
/**
3423
 * testSaveAllHasOneValidation method
3424
 *
3425
 * @return void
3426
 */
3427
        public function testSaveAllHasOneValidation() {
3428
                $model = new Comment();
3429
                $model->deleteAll(true);
3430
                $this->assertEquals(array(), $model->find('all'));
3431

    
3432
                $model->Attachment->deleteAll(true);
3433
                $this->assertEquals(array(), $model->Attachment->find('all'));
3434

    
3435
                $model->validate = array('comment' => 'notBlank');
3436
                $model->Attachment->validate = array('attachment' => 'notBlank');
3437
                $model->Attachment->bindModel(array('belongsTo' => array('Comment')));
3438

    
3439
                $result = $model->saveAll(
3440
                        array(
3441
                                'Comment' => array(
3442
                                        'comment' => '',
3443
                                        'article_id' => 1,
3444
                                        'user_id' => 1
3445
                                ),
3446
                                'Attachment' => array('attachment' => '')
3447
                        ),
3448
                        array('validate' => 'first')
3449
                );
3450
                $this->assertEquals(false, $result);
3451
                $expected = array(
3452
                        'comment' => array('This field cannot be left blank'),
3453
                        'Attachment' => array(
3454
                                'attachment' => array('This field cannot be left blank')
3455
                        )
3456
                );
3457
                $this->assertEquals($expected, $model->validationErrors);
3458
                $this->assertEquals($expected['Attachment'], $model->Attachment->validationErrors);
3459
        }
3460

    
3461
/**
3462
 * testSaveAllAtomic method
3463
 *
3464
 * @return void
3465
 */
3466
        public function testSaveAllAtomic() {
3467
                $this->loadFixtures('Article', 'User', 'Comment');
3468
                $TestModel = new Article();
3469

    
3470
                $result = $TestModel->saveAll(array(
3471
                        'Article' => array(
3472
                                'title' => 'Post with Author',
3473
                                'body' => 'This post will be saved with an author',
3474
                                'user_id' => 2
3475
                        ),
3476
                        'Comment' => array(
3477
                                array('comment' => 'First new comment', 'user_id' => 2))
3478
                ), array('atomic' => false));
3479

    
3480
                $this->assertSame($result, array('Article' => true, 'Comment' => array(true)));
3481

    
3482
                $result = $TestModel->saveAll(array(
3483
                        array(
3484
                                'id' => '1',
3485
                                'title' => 'Baleeted First Post',
3486
                                'body' => 'Baleeted!',
3487
                                'published' => 'N'
3488
                        ),
3489
                        array(
3490
                                'id' => '2',
3491
                                'title' => 'Just update the title'
3492
                        ),
3493
                        array(
3494
                                'title' => 'Creating a fourth post',
3495
                                'body' => 'Fourth post body',
3496
                                'user_id' => 2
3497
                        )
3498
                ), array('atomic' => false));
3499
                $this->assertSame($result, array(true, true, true));
3500

    
3501
                $result = $TestModel->saveAll(array(
3502
                        'Article' => array('id' => 2),
3503
                        'Comment' => array(
3504
                                array(
3505
                                        'comment' => 'First new comment',
3506
                                        'published' => 'Y',
3507
                                        'user_id' => 1
3508
                                ),
3509
                                array(
3510
                                        'comment' => 'Second new comment',
3511
                                        'published' => 'Y',
3512
                                        'user_id' => 2
3513
                        ))
3514
                ), array('validate' => true, 'atomic' => false));
3515
                $this->assertSame($result, array('Article' => true, 'Comment' => array(true, true)));
3516

    
3517
                $TestModel->validate = array(
3518
                        'title' => 'notBlank',
3519
                        'author_id' => 'numeric'
3520
                );
3521
                $result = $TestModel->saveAll(array(
3522
                        array(
3523
                                'id' => '1',
3524
                                'title' => 'Un-Baleeted First Post',
3525
                                'body' => 'Not Baleeted!',
3526
                                'published' => 'Y'
3527
                        ),
3528
                        array(
3529
                                'id' => '2',
3530
                                'title' => '',
3531
                                'body' => 'Trying to get away with an empty title'
3532
                        )
3533
                ), array('validate' => true, 'atomic' => false));
3534
                $this->assertSame(array(true, false), $result);
3535
        }
3536

    
3537
/**
3538
 * testSaveAllDeepAssociated method
3539
 *
3540
 * @return void
3541
 */
3542
        public function testSaveAllDeepAssociated() {
3543
                $this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
3544
                $TestModel = new Article();
3545
                $TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
3546
                $TestModel->hasAndBelongsToMany = array();
3547

    
3548
                $result = $TestModel->saveAll(array(
3549
                        'Article' => array('id' => 2),
3550
                        'Comment' => array(
3551
                                array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => 'newuser', 'password' => 'newuserpass')),
3552
                                array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
3553
                        )
3554
                ), array('deep' => true));
3555
                $this->assertTrue($result);
3556

    
3557
                $result = $TestModel->findById(2);
3558
                $expected = array(
3559
                        'First Comment for Second Article',
3560
                        'Second Comment for Second Article',
3561
                        'First new comment',
3562
                        'Second new comment'
3563
                );
3564
                $result = Hash::extract(Hash::sort($result['Comment'], '{n}.id', 'ASC'), '{n}.comment');
3565
                $this->assertEquals($expected, $result);
3566

    
3567
                $result = $TestModel->Comment->User->field('id', array('user' => 'newuser', 'password' => 'newuserpass'));
3568
                $this->assertEquals(5, $result);
3569
                $result = $TestModel->saveAll(array(
3570
                        'Article' => array('id' => 2),
3571
                        'Comment' => array(
3572
                                array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
3573
                                array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => 'deepsaved'))
3574
                        )
3575
                ), array('deep' => true));
3576
                $this->assertTrue($result);
3577

    
3578
                $result = $TestModel->findById(2);
3579
                $expected = array(
3580
                        'First Comment for Second Article',
3581
                        'Second Comment for Second Article',
3582
                        'First new comment',
3583
                        'Second new comment',
3584
                        'Third new comment',
3585
                        'Fourth new comment'
3586
                );
3587
                $result = Hash::extract(Hash::sort($result['Comment'], '{n}.id', 'ASC'), '{n}.comment');
3588
                $this->assertEquals($expected, $result);
3589

    
3590
                $result = $TestModel->Comment->Attachment->field('id', array('attachment' => 'deepsaved'));
3591
                $this->assertEquals(2, $result);
3592
                $data = array(
3593
                        'Attachment' => array(
3594
                                'attachment' => 'deepsave insert',
3595
                        ),
3596
                        'Comment' => array(
3597
                                'comment' => 'First comment deepsave insert',
3598
                                'published' => 'Y',
3599
                                'user_id' => 5,
3600
                                'Article' => array(
3601
                                        'title' => 'First Article deepsave insert',
3602
                                        'body' => 'First Article Body deepsave insert',
3603
                                        'User' => array(
3604
                                                'user' => '',
3605
                                                'password' => 'magic'
3606
                                        ),
3607
                                ),
3608
                        )
3609
                );
3610

    
3611
                $TestModel->Comment->Attachment->create();
3612
                $result = $TestModel->Comment->Attachment->saveAll($data, array('deep' => true));
3613
                $this->assertFalse($result);
3614

    
3615
                $expected = array('User' => array('user' => array('This field cannot be left blank')));
3616
                $this->assertEquals($expected, $TestModel->validationErrors);
3617

    
3618
                $data['Comment']['Article']['User']['user'] = 'deepsave';
3619
                $TestModel->Comment->Attachment->create();
3620
                $result = $TestModel->Comment->Attachment->saveAll($data, array('deep' => true));
3621
                $this->assertTrue($result);
3622

    
3623
                $result = $TestModel->Comment->Attachment->findById($TestModel->Comment->Attachment->id);
3624
                $expected = array(
3625
                        'Attachment' => array(
3626
                                'id' => '3',
3627
                                'comment_id' => '11',
3628
                                'attachment' => 'deepsave insert',
3629
                        ),
3630
                        'Comment' => array(
3631
                                'id' => '11',
3632
                                'article_id' => '4',
3633
                                'user_id' => '5',
3634
                                'comment' => 'First comment deepsave insert',
3635
                                'published' => 'Y',
3636
                        )
3637
                );
3638
                unset($result['Attachment']['created'], $result['Attachment']['updated']);
3639
                $this->assertEquals($expected['Attachment'], $result['Attachment']);
3640

    
3641
                unset($result['Comment']['created'], $result['Comment']['updated']);
3642
                $this->assertEquals($expected['Comment'], $result['Comment']);
3643

    
3644
                $result = $TestModel->findById($result['Comment']['article_id']);
3645
                $expected = array(
3646
                        'Article' => array(
3647
                                'id' => '4',
3648
                                'user_id' => '6',
3649
                                'title' => 'First Article deepsave insert',
3650
                                'body' => 'First Article Body deepsave insert',
3651
                                'published' => 'N',
3652
                        ),
3653
                        'User' => array(
3654
                                'id' => '6',
3655
                                'user' => 'deepsave',
3656
                                'password' => 'magic',
3657
                        ),
3658
                        'Comment' => array(
3659
                                array(
3660
                                        'id' => '11',
3661
                                        'article_id' => '4',
3662
                                        'user_id' => '5',
3663
                                        'comment' => 'First comment deepsave insert',
3664
                                        'published' => 'Y',
3665
                                )
3666
                        )
3667
                );
3668
                unset(
3669
                        $result['Article']['created'], $result['Article']['updated'],
3670
                        $result['User']['created'], $result['User']['updated'],
3671
                        $result['Comment'][0]['created'], $result['Comment'][0]['updated']
3672
                );
3673
                $this->assertEquals($expected, $result);
3674
        }
3675

    
3676
/**
3677
 * testSaveAllDeepMany
3678
 * tests the validate methods with deeper recursive data
3679
 *
3680
 * @return void
3681
 */
3682
        public function testSaveAllDeepMany() {
3683
                $this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
3684
                $TestModel = new Article();
3685
                $TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
3686
                $TestModel->hasAndBelongsToMany = array();
3687

    
3688
                $data = array(
3689
                        array(
3690
                                'Article' => array('id' => 1),
3691
                                'Comment' => array(
3692
                                        array('comment' => 'First comment deepsaved article 1', 'published' => 'Y', 'User' => array('user' => 'savemany', 'password' => 'manysaved')),
3693
                                        array('comment' => 'Second comment deepsaved article 1', 'published' => 'Y', 'user_id' => 2)
3694
                                )
3695
                        ),
3696
                        array(
3697
                                'Article' => array('id' => 2),
3698
                                'Comment' => array(
3699
                                        array('comment' => 'First comment deepsaved article 2', 'published' => 'Y', 'User' => array('user' => 'savemore', 'password' => 'moresaved')),
3700
                                        array('comment' => 'Second comment deepsaved article 2', 'published' => 'Y', 'user_id' => 2)
3701
                                )
3702
                        )
3703
                );
3704
                $result = $TestModel->saveAll($data, array('deep' => true));
3705
                $this->assertTrue($result);
3706

    
3707
                $data = array(
3708
                        array(
3709
                                'id' => 1, 'body' => '',
3710
                                'Comment' => array(
3711
                                        array('comment' => '', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'manysaved')),
3712
                                        array('comment' => 'Second comment deepsaved article 1', 'published' => 'Y', 'user_id' => 2)
3713
                                )
3714
                        ),
3715
                        array(
3716
                                'Article' => array('id' => 2),
3717
                                'Comment' => array(
3718
                                        array('comment' => 'First comment deepsaved article 2', 'published' => 'Y', 'User' => array('user' => 'savemore', 'password' => '')),
3719
                                        array('comment' => '', 'published' => 'Y', 'user_id' => 2)
3720
                                )
3721
                        )
3722
                );
3723
                $TestModel->Comment->validate['comment'] = 'notBlank';
3724
                $result = $TestModel->saveAll($data, array('deep' => true));
3725
                $this->assertFalse($result);
3726

    
3727
                $expected = array(
3728
                        0 => array(
3729
                                'body' => array('This field cannot be left blank'),
3730
                                'Comment' => array(
3731
                                        0 => array(
3732
                                                'comment' => array('This field cannot be left blank'),
3733
                                                'User' => array(
3734
                                                        'user' => array('This field cannot be left blank')
3735
                                                )
3736
                                        )
3737
                                )
3738
                        ),
3739
                        1 => array(
3740
                                'Comment' => array(
3741
                                        0 => array(
3742
                                                'User' => array(
3743
                                                        'password' => array('This field cannot be left blank')
3744
                                                )
3745
                                        ),
3746
                                        1 => array(
3747
                                                'comment' => array('This field cannot be left blank')
3748
                                        )
3749
                                )
3750
                        )
3751
                );
3752
                $result = $TestModel->validationErrors;
3753
                $this->assertSame($expected, $result);
3754
        }
3755
/**
3756
 * testSaveAllDeepValidateOnly
3757
 * tests the validate methods with deeper recursive data
3758
 *
3759
 * @return void
3760
 */
3761
        public function testSaveAllDeepValidateOnly() {
3762
                $this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
3763
                $TestModel = new Article();
3764
                $TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
3765
                $TestModel->hasAndBelongsToMany = array();
3766
                $TestModel->Comment->Attachment->validate['attachment'] = 'notBlank';
3767
                $TestModel->Comment->validate['comment'] = 'notBlank';
3768

    
3769
                $result = $TestModel->saveAll(
3770
                        array(
3771
                                'Article' => array('id' => 2),
3772
                                'Comment' => array(
3773
                                        array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => 'newuser', 'password' => 'newuserpass')),
3774
                                        array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
3775
                                )
3776
                        ),
3777
                        array('validate' => 'only', 'deep' => true)
3778
                );
3779
                $this->assertTrue($result);
3780

    
3781
                $result = $TestModel->saveAll(
3782
                        array(
3783
                                'Article' => array('id' => 2),
3784
                                'Comment' => array(
3785
                                        array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
3786
                                        array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
3787
                                )
3788
                        ),
3789
                        array('validate' => 'only', 'deep' => true)
3790
                );
3791
                $this->assertFalse($result);
3792

    
3793
                $result = $TestModel->saveAll(
3794
                        array(
3795
                                'Article' => array('id' => 2),
3796
                                'Comment' => array(
3797
                                        array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => 'newuser', 'password' => 'newuserpass')),
3798
                                        array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
3799
                                )
3800
                        ),
3801
                        array('validate' => 'only', 'atomic' => false, 'deep' => true)
3802
                );
3803
                $expected = array(
3804
                        'Article' => true,
3805
                        'Comment' => array(
3806
                                true,
3807
                                true
3808
                        )
3809
                );
3810
                $this->assertSame($expected, $result);
3811

    
3812
                $result = $TestModel->saveAll(
3813
                        array(
3814
                                'Article' => array('id' => 2),
3815
                                'Comment' => array(
3816
                                        array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
3817
                                        array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
3818
                                )
3819
                        ),
3820
                        array('validate' => 'only', 'atomic' => false, 'deep' => true)
3821
                );
3822
                $expected = array(
3823
                        'Article' => true,
3824
                        'Comment' => array(
3825
                                false,
3826
                                true
3827
                        )
3828
                );
3829
                $this->assertSame($expected, $result);
3830

    
3831
                $result = $TestModel->saveAll(array(
3832
                        'Article' => array('id' => 2),
3833
                        'Comment' => array(
3834
                                array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
3835
                                array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => 'deepsaved'))
3836
                        )
3837
                ),
3838
                array('validate' => 'only', 'deep' => true)
3839
                );
3840
                $this->assertTrue($result);
3841

    
3842
                $result = $TestModel->saveAll(array(
3843
                        'Article' => array('id' => 2),
3844
                        'Comment' => array(
3845
                                array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
3846
                                array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
3847
                        )
3848
                ),
3849
                array('validate' => 'only', 'deep' => true)
3850
                );
3851
                $this->assertFalse($result);
3852

    
3853
                $result = $TestModel->saveAll(array(
3854
                        'Article' => array('id' => 2),
3855
                        'Comment' => array(
3856
                                array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
3857
                                array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => 'deepsave'))
3858
                        )
3859
                ),
3860
                array('validate' => 'only', 'atomic' => false, 'deep' => true)
3861
                );
3862
                $expected = array(
3863
                        'Article' => true,
3864
                        'Comment' => array(
3865
                                true,
3866
                                true
3867
                        )
3868
                );
3869
                $this->assertSame($expected, $result);
3870

    
3871
                $result = $TestModel->saveAll(array(
3872
                        'Article' => array('id' => 2),
3873
                        'Comment' => array(
3874
                                array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
3875
                                array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
3876
                        )
3877
                ),
3878
                array('validate' => 'only', 'atomic' => false, 'deep' => true)
3879
                );
3880
                $expected = array(
3881
                        'Article' => true,
3882
                        'Comment' => array(
3883
                                true,
3884
                                false
3885
                        )
3886
                );
3887
                $this->assertSame($expected, $result);
3888

    
3889
                $expected = array(
3890
                        'Comment' => array(
3891
                                1 => array(
3892
                                        'Attachment' => array(
3893
                                                'attachment' => array('This field cannot be left blank')
3894
                                        )
3895
                                )
3896
                        )
3897
                );
3898
                $result = $TestModel->validationErrors;
3899
                $this->assertSame($expected, $result);
3900

    
3901
                $data = array(
3902
                        'Attachment' => array(
3903
                                'attachment' => 'deepsave insert',
3904
                        ),
3905
                        'Comment' => array(
3906
                                'comment' => 'First comment deepsave insert',
3907
                                'published' => 'Y',
3908
                                'user_id' => 5,
3909
                                'Article' => array(
3910
                                        'title' => 'First Article deepsave insert',
3911
                                        'body' => 'First Article Body deepsave insert',
3912
                                        'User' => array(
3913
                                                'user' => 'deepsave',
3914
                                                'password' => 'magic'
3915
                                        ),
3916
                                ),
3917
                        )
3918
                );
3919

    
3920
                $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
3921
                $this->assertTrue($result);
3922

    
3923
                $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
3924
                $expected = array(
3925
                        'Attachment' => true,
3926
                        'Comment' => true
3927
                );
3928
                $this->assertSame($expected, $result);
3929

    
3930
                $data = array(
3931
                        'Attachment' => array(
3932
                                'attachment' => 'deepsave insert',
3933
                        ),
3934
                        'Comment' => array(
3935
                                'comment' => 'First comment deepsave insert',
3936
                                'published' => 'Y',
3937
                                'user_id' => 5,
3938
                                'Article' => array(
3939
                                        'title' => 'First Article deepsave insert',
3940
                                        'body' => 'First Article Body deepsave insert',
3941
                                        'User' => array(
3942
                                                'user' => '',
3943
                                                'password' => 'magic'
3944
                                        ),
3945
                                ),
3946
                        )
3947
                );
3948

    
3949
                $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
3950
                $this->assertFalse($result);
3951

    
3952
                $result = $TestModel->Comment->Attachment->validationErrors;
3953
                $expected = array(
3954
                        'Comment' => array(
3955
                                'Article' => array(
3956
                                        'User' => array(
3957
                                                'user' => array('This field cannot be left blank')
3958
                                        )
3959
                                )
3960
                        )
3961
                );
3962
                $this->assertSame($expected, $result);
3963

    
3964
                $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
3965
                $expected = array(
3966
                        'Attachment' => true,
3967
                        'Comment' => false
3968
                );
3969
                $this->assertEquals($expected, $result);
3970

    
3971
                $data['Comment']['Article']['body'] = '';
3972
                $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
3973
                $this->assertFalse($result);
3974

    
3975
                $result = $TestModel->Comment->Attachment->validationErrors;
3976
                $expected = array(
3977
                        'Comment' => array(
3978
                                'Article' => array(
3979
                                        'body' => array('This field cannot be left blank'),
3980
                                        'User' => array(
3981
                                                'user' => array('This field cannot be left blank')
3982
                                        )
3983
                                )
3984
                        )
3985
                );
3986
                $this->assertSame($expected, $result);
3987

    
3988
                $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
3989
                $expected = array(
3990
                        'Attachment' => true,
3991
                        'Comment' => false
3992
                );
3993
                $this->assertEquals($expected, $result);
3994

    
3995
                $data['Comment']['comment'] = '';
3996
                $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
3997
                $this->assertFalse($result);
3998

    
3999
                $result = $TestModel->Comment->Attachment->validationErrors;
4000
                $expected = array(
4001
                        'Comment' => array(
4002
                                'comment' => array('This field cannot be left blank'),
4003
                                'Article' => array(
4004
                                        'body' => array('This field cannot be left blank'),
4005
                                        'User' => array(
4006
                                                'user' => array('This field cannot be left blank')
4007
                                        )
4008
                                )
4009
                        )
4010
                );
4011
                $this->assertSame($expected, $result);
4012

    
4013
                $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
4014
                $expected = array(
4015
                        'Attachment' => true,
4016
                        'Comment' => false
4017
                );
4018
                $this->assertEquals($expected, $result);
4019

    
4020
                $data['Attachment']['attachment'] = '';
4021
                $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
4022
                $this->assertFalse($result);
4023

    
4024
                $result = $TestModel->Comment->Attachment->validationErrors;
4025
                $expected = array(
4026
                        'attachment' => array('This field cannot be left blank'),
4027
                        'Comment' => array(
4028
                                'comment' => array('This field cannot be left blank'),
4029
                                'Article' => array(
4030
                                        'body' => array('This field cannot be left blank'),
4031
                                        'User' => array(
4032
                                                'user' => array('This field cannot be left blank')
4033
                                        )
4034
                                )
4035
                        )
4036
                );
4037
                $this->assertSame($expected, $result);
4038

    
4039
                $result = $TestModel->Comment->validationErrors;
4040
                $expected = array(
4041
                        'comment' => array('This field cannot be left blank'),
4042
                        'Article' => array(
4043
                                'body' => array('This field cannot be left blank'),
4044
                                'User' => array(
4045
                                        'user' => array('This field cannot be left blank')
4046
                                )
4047
                        )
4048
                );
4049
                $this->assertSame($expected, $result);
4050

    
4051
                $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
4052
                $expected = array(
4053
                        'Attachment' => false,
4054
                        'Comment' => false
4055
                );
4056
                $this->assertEquals($expected, $result);
4057
        }
4058

    
4059
/**
4060
 * testSaveAllNotDeepAssociated method
4061
 * test that only directly associated data gets saved
4062
 *
4063
 * @return void
4064
 */
4065
        public function testSaveAllNotDeepAssociated() {
4066
                $this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
4067
                $TestModel = new Article();
4068
                $TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
4069
                $TestModel->hasAndBelongsToMany = array();
4070

    
4071
                $result = $TestModel->saveAll(array(
4072
                        'Article' => array('id' => 2),
4073
                        'Comment' => array(
4074
                                array(
4075
                                        'comment' => 'First new comment', 'published' => 'Y', 'user_id' => 2,
4076
                                        'User' => array('user' => 'newuser', 'password' => 'newuserpass')
4077
                                ),
4078
                                array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
4079
                        )
4080
                ), array('deep' => false));
4081
                $this->assertTrue($result);
4082

    
4083
                $result = $TestModel->Comment->User->field('id', array('user' => 'newuser', 'password' => 'newuserpass'));
4084
                $this->assertFalse($result);
4085

    
4086
                $result = $TestModel->saveAll(array(
4087
                        'Article' => array('id' => 2),
4088
                        'Comment' => array(
4089
                                array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 4),
4090
                                array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => 'deepsaved'))
4091
                        )
4092
                ), array('deep' => false));
4093
                $this->assertTrue($result);
4094

    
4095
                $result = $TestModel->Comment->Attachment->field('id', array('attachment' => 'deepsaved'));
4096
                $this->assertFalse($result);
4097

    
4098
                $data = array(
4099
                        'Attachment' => array(
4100
                                'attachment' => 'deepsave insert',
4101
                        ),
4102
                        'Comment' => array(
4103
                                'comment' => 'First comment deepsave insert',
4104
                                'published' => 'Y',
4105
                                'user_id' => 4,
4106
                                'article_id' => 1,
4107
                                'Article' => array(
4108
                                        'title' => 'First Article deepsave insert',
4109
                                        'body' => 'First Article Body deepsave insert',
4110
                                        'User' => array(
4111
                                                'user' => 'deepsave',
4112
                                                'password' => 'magic'
4113
                                        ),
4114
                                ),
4115
                        )
4116
                );
4117
                $expected = $TestModel->User->find('count');
4118

    
4119
                $TestModel->Comment->Attachment->create();
4120
                $result = $TestModel->Comment->Attachment->saveAll($data, array('deep' => false));
4121
                $this->assertTrue($result);
4122

    
4123
                $result = $TestModel->User->find('count');
4124
                $this->assertEquals($expected, $result);
4125

    
4126
                $result = $TestModel->Comment->Attachment->findById($TestModel->Comment->Attachment->id);
4127
                $expected = array(
4128
                        'Attachment' => array(
4129
                                'id' => '2',
4130
                                'comment_id' => '11',
4131
                                'attachment' => 'deepsave insert',
4132
                        ),
4133
                        'Comment' => array(
4134
                                'id' => '11',
4135
                                'article_id' => 1,
4136
                                'user_id' => '4',
4137
                                'comment' => 'First comment deepsave insert',
4138
                                'published' => 'Y',
4139
                        )
4140
                );
4141
                unset($result['Attachment']['created'], $result['Attachment']['updated']);
4142
                $this->assertEquals($expected['Attachment'], $result['Attachment']);
4143

    
4144
                unset($result['Comment']['created'], $result['Comment']['updated']);
4145
                $this->assertEquals($expected['Comment'], $result['Comment']);
4146
        }
4147

    
4148
/**
4149
 * testSaveAllNotDeepMany
4150
 * tests the save methods to not save deeper recursive data
4151
 *
4152
 * @return void
4153
 */
4154
        public function testSaveAllNotDeepMany() {
4155
                $this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
4156
                $TestModel = new Article();
4157
                $TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
4158
                $TestModel->hasAndBelongsToMany = array();
4159

    
4160
                $data = array(
4161
                        array(
4162
                                'id' => 1,
4163
                                'body' => '',
4164
                                'Comment' => array(
4165
                                        array('comment' => '', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'manysaved')),
4166
                                        array('comment' => 'Second comment deepsaved article 1', 'published' => 'Y', 'user_id' => 2)
4167
                                )
4168
                        ),
4169
                        array(
4170
                                'Article' => array('id' => 2),
4171
                                'Comment' => array(
4172
                                        array('comment' => 'First comment deepsaved article 2', 'published' => 'Y', 'User' => array('user' => 'savemore', 'password' => '')),
4173
                                        array('comment' => '', 'published' => 'Y', 'user_id' => 2)
4174
                                )
4175
                        )
4176
                );
4177
                $TestModel->Comment->validate['comment'] = 'notBlank';
4178
                $result = $TestModel->saveAll($data, array('deep' => false));
4179
                $this->assertFalse($result);
4180

    
4181
                $expected = array(
4182
                        0 => array(
4183
                                'body' => array('This field cannot be left blank')
4184
                        )
4185
                );
4186
                $result = $TestModel->validationErrors;
4187
                $this->assertSame($expected, $result);
4188

    
4189
                $data = array(
4190
                        array(
4191
                                'Article' => array('id' => 1, 'body' => 'Ignore invalid comment'),
4192
                                'Comment' => array(
4193
                                        array('comment' => '', 'published' => 'Y', 'user_id' => 2)
4194
                                )
4195
                        ),
4196
                        array(
4197
                                'Article' => array('id' => 2),
4198
                                'Comment' => array(
4199
                                        array('comment' => '', 'published' => 'Y', 'user_id' => 2)
4200
                                )
4201
                        )
4202
                );
4203
                $result = $TestModel->saveAll($data, array('deep' => false));
4204
                $this->assertTrue($result);
4205
        }
4206
/**
4207
 * testSaveAllNotDeepValidateOnly
4208
 * tests the validate methods to not validate deeper recursive data
4209
 *
4210
 * @return void
4211
 */
4212
        public function testSaveAllNotDeepValidateOnly() {
4213
                $this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
4214
                $TestModel = new Article();
4215
                $TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
4216
                $TestModel->hasAndBelongsToMany = array();
4217
                $TestModel->Comment->Attachment->validate['attachment'] = 'notBlank';
4218
                $TestModel->Comment->validate['comment'] = 'notBlank';
4219

    
4220
                $result = $TestModel->saveAll(
4221
                        array(
4222
                                'Article' => array('id' => 2, 'body' => ''),
4223
                                'Comment' => array(
4224
                                        array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
4225
                                        array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
4226
                                )
4227
                        ),
4228
                        array('validate' => 'only', 'deep' => false)
4229
                );
4230
                $this->assertFalse($result);
4231

    
4232
                $expected = array('body' => array('This field cannot be left blank'));
4233
                $result = $TestModel->validationErrors;
4234
                $this->assertSame($expected, $result);
4235

    
4236
                $result = $TestModel->saveAll(
4237
                        array(
4238
                                'Article' => array('id' => 2, 'body' => 'Ignore invalid user data'),
4239
                                'Comment' => array(
4240
                                        array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
4241
                                        array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
4242
                                )
4243
                        ),
4244
                        array('validate' => 'only', 'deep' => false)
4245
                );
4246
                $this->assertTrue($result);
4247

    
4248
                $result = $TestModel->saveAll(
4249
                        array(
4250
                                'Article' => array('id' => 2, 'body' => 'Ignore invalid user data'),
4251
                                'Comment' => array(
4252
                                        array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
4253
                                        array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
4254
                                )
4255
                        ),
4256
                        array('validate' => 'only', 'atomic' => false, 'deep' => false)
4257
                );
4258
                $expected = array(
4259
                        'Article' => true,
4260
                        'Comment' => array(
4261
                                true,
4262
                                true
4263
                        )
4264
                );
4265
                $this->assertSame($expected, $result);
4266

    
4267
                $result = $TestModel->saveAll(array(
4268
                        'Article' => array('id' => 2, 'body' => 'Ignore invalid attachment data'),
4269
                        'Comment' => array(
4270
                                array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
4271
                                array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
4272
                        )
4273
                ),
4274
                array('validate' => 'only', 'deep' => false)
4275
                );
4276
                $this->assertTrue($result);
4277

    
4278
                $result = $TestModel->saveAll(array(
4279
                        'Article' => array('id' => 2, 'body' => 'Ignore invalid attachment data'),
4280
                        'Comment' => array(
4281
                                array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
4282
                                array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
4283
                        )
4284
                ),
4285
                array('validate' => 'only', 'atomic' => false, 'deep' => false)
4286
                );
4287
                $expected = array(
4288
                        'Article' => true,
4289
                        'Comment' => array(
4290
                                true,
4291
                                true
4292
                        )
4293
                );
4294
                $this->assertSame($expected, $result);
4295

    
4296
                $expected = array();
4297
                $result = $TestModel->validationErrors;
4298
                $this->assertSame($expected, $result);
4299

    
4300
                $data = array(
4301
                        'Attachment' => array(
4302
                                'attachment' => 'deepsave insert',
4303
                        ),
4304
                        'Comment' => array(
4305
                                'comment' => 'First comment deepsave insert',
4306
                                'published' => 'Y',
4307
                                'user_id' => 5,
4308
                                'Article' => array(
4309
                                        'title' => 'First Article deepsave insert ignored',
4310
                                        'body' => 'First Article Body deepsave insert',
4311
                                        'User' => array(
4312
                                                'user' => '',
4313
                                                'password' => 'magic'
4314
                                        ),
4315
                                ),
4316
                        )
4317
                );
4318

    
4319
                $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => false));
4320
                $this->assertTrue($result);
4321

    
4322
                $result = $TestModel->Comment->Attachment->validationErrors;
4323
                $expected = array();
4324
                $this->assertSame($expected, $result);
4325

    
4326
                $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => false));
4327
                $expected = array(
4328
                        'Attachment' => true,
4329
                        'Comment' => true
4330
                );
4331
                $this->assertEquals($expected, $result);
4332

    
4333
                $data['Comment']['Article']['body'] = '';
4334
                $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => false));
4335
                $this->assertTrue($result);
4336

    
4337
                $result = $TestModel->Comment->Attachment->validationErrors;
4338
                $expected = array();
4339
                $this->assertSame($expected, $result);
4340

    
4341
                $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => false));
4342
                $expected = array(
4343
                        'Attachment' => true,
4344
                        'Comment' => true
4345
                );
4346
                $this->assertEquals($expected, $result);
4347
        }
4348

    
4349
/**
4350
 * testSaveAllHasMany method
4351
 *
4352
 * @return void
4353
 */
4354
        public function testSaveAllHasMany() {
4355
                $this->loadFixtures('Article', 'Comment');
4356
                $TestModel = new Article();
4357
                $TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
4358
                $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
4359

    
4360
                $result = $TestModel->saveAll(array(
4361
                        'Article' => array('id' => 2),
4362
                        'Comment' => array(
4363
                                array('comment' => 'First new comment', 'published' => 'Y', 'user_id' => 1),
4364
                                array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
4365
                        )
4366
                ));
4367
                $this->assertFalse(empty($result));
4368

    
4369
                $result = $TestModel->findById(2);
4370
                $expected = array(
4371
                        'First Comment for Second Article',
4372
                        'Second Comment for Second Article',
4373
                        'First new comment',
4374
                        'Second new comment'
4375
                );
4376
                $result = Hash::extract(Hash::sort($result['Comment'], '{n}.id', 'ASC'), '{n}.comment');
4377
                $this->assertEquals($expected, $result);
4378

    
4379
                $result = $TestModel->saveAll(
4380
                        array(
4381
                                'Article' => array('id' => 2),
4382
                                'Comment' => array(
4383
                                        array(
4384
                                                'comment' => 'Third new comment',
4385
                                                'published' => 'Y',
4386
                                                'user_id' => 1
4387
                        ))),
4388
                        array('atomic' => false)
4389
                );
4390
                $this->assertFalse(empty($result));
4391

    
4392
                $result = $TestModel->findById(2);
4393
                $expected = array(
4394
                        'First Comment for Second Article',
4395
                        'Second Comment for Second Article',
4396
                        'First new comment',
4397
                        'Second new comment',
4398
                        'Third new comment'
4399
                );
4400
                $result = Hash::extract(Hash::sort($result['Comment'], '{n}.id', 'ASC'), '{n}.comment');
4401
                $this->assertEquals($expected, $result);
4402

    
4403
                $TestModel->beforeSaveReturn = false;
4404
                $result = $TestModel->saveAll(
4405
                        array(
4406
                                'Article' => array('id' => 2),
4407
                                'Comment' => array(
4408
                                        array(
4409
                                                'comment' => 'Fourth new comment',
4410
                                                'published' => 'Y',
4411
                                                'user_id' => 1
4412
                        ))),
4413
                        array('atomic' => false)
4414
                );
4415
                $this->assertEquals(array('Article' => false), $result);
4416

    
4417
                $result = $TestModel->findById(2);
4418
                $expected = array(
4419
                        'First Comment for Second Article',
4420
                        'Second Comment for Second Article',
4421
                        'First new comment',
4422
                        'Second new comment',
4423
                        'Third new comment'
4424
                );
4425
                $result = Hash::extract(Hash::sort($result['Comment'], '{n}.id', 'ASC'), '{n}.comment');
4426
                $this->assertEquals($expected, $result);
4427
        }
4428

    
4429
/**
4430
 * testSaveAllHasManyValidation method
4431
 *
4432
 * @return void
4433
 */
4434
        public function testSaveAllHasManyValidation() {
4435
                $this->loadFixtures('Article', 'Comment');
4436
                $TestModel = new Article();
4437
                $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
4438
                $TestModel->Comment->validate = array('comment' => 'notBlank');
4439

    
4440
                $result = $TestModel->saveAll(array(
4441
                        'Article' => array('id' => 2),
4442
                        'Comment' => array(
4443
                                array('comment' => '', 'published' => 'Y', 'user_id' => 1),
4444
                        )
4445
                ), array('validate' => true));
4446
                $this->assertFalse($result);
4447

    
4448
                $expected = array('Comment' => array(
4449
                        array('comment' => array('This field cannot be left blank'))
4450
                ));
4451
                $this->assertEquals($expected, $TestModel->validationErrors);
4452
                $expected = array(
4453
                        array('comment' => array('This field cannot be left blank'))
4454
                );
4455
                $this->assertEquals($expected, $TestModel->Comment->validationErrors);
4456

    
4457
                $result = $TestModel->saveAll(array(
4458
                        'Article' => array('id' => 2),
4459
                        'Comment' => array(
4460
                                array(
4461
                                        'comment' => '',
4462
                                        'published' => 'Y',
4463
                                        'user_id' => 1
4464
                        ))
4465
                ), array('validate' => 'first'));
4466
                $this->assertFalse($result);
4467
        }
4468

    
4469
/**
4470
 * test saveAll with transactions and ensure there is no missing rollback.
4471
 *
4472
 * @return void
4473
 */
4474
        public function testSaveAllManyRowsTransactionNoRollback() {
4475
                $this->loadFixtures('Post');
4476

    
4477
                $Post = new TestPost();
4478
                $Post->validate = array(
4479
                        'title' => array('rule' => array('notBlank'))
4480
                );
4481

    
4482
                // If validation error occurs, rollback() should be called.
4483
                $db = $this->_getMockDboSource(array('begin', 'commit', 'rollback'));
4484
                $db->expects($this->once())->method('begin')->will($this->returnValue(true));
4485
                $db->expects($this->never())->method('commit');
4486
                $db->expects($this->once())->method('rollback');
4487

    
4488
                $Post->setDataSourceObject($db);
4489

    
4490
                $data = array(
4491
                        array('author_id' => 1, 'title' => 'New Fourth Post'),
4492
                        array('author_id' => 1, 'title' => '')
4493
                );
4494
                $Post->saveAll($data, array('atomic' => true, 'validate' => true));
4495

    
4496
                // If exception thrown, rollback() should be called too.
4497
                $db = $this->_getMockDboSource(array('begin', 'commit', 'rollback'));
4498
                $db->expects($this->once())->method('begin')->will($this->returnValue(true));
4499
                $db->expects($this->never())->method('commit');
4500
                $db->expects($this->once())->method('rollback');
4501

    
4502
                $Post->setDataSourceObject($db);
4503

    
4504
                $data = array(
4505
                        array('author_id' => 1, 'title' => 'New Fourth Post'),
4506
                        array('author_id' => 1, 'title' => 'New Fifth Post', 'body' => $db->expression('PDO_EXCEPTION()'))
4507
                );
4508

    
4509
                try {
4510
                        $Post->saveAll($data, array('atomic' => true, 'validate' => true));
4511
                        $this->fail('No exception thrown');
4512
                } catch (PDOException $e) {
4513
                }
4514

    
4515
                // Otherwise, commit() should be called.
4516
                $db = $this->_getMockDboSource(array('begin', 'commit', 'rollback'));
4517
                $db->expects($this->once())->method('begin')->will($this->returnValue(true));
4518
                $db->expects($this->once())->method('commit');
4519
                $db->expects($this->never())->method('rollback');
4520

    
4521
                $Post->setDataSourceObject($db);
4522

    
4523
                $data = array(
4524
                        array('author_id' => 1, 'title' => 'New Fourth Post'),
4525
                        array('author_id' => 1, 'title' => 'New Fifth Post')
4526
                );
4527
                $Post->saveAll($data, array('atomic' => true, 'validate' => true));
4528
        }
4529

    
4530
/**
4531
 * test saveAll with transactions and ensure there is no missing rollback.
4532
 *
4533
 * @return void
4534
 */
4535
        public function testSaveAllAssociatedTransactionNoRollback() {
4536
                $this->loadFixtures('Post', 'Author');
4537

    
4538
                $Post = new TestPost();
4539
                $Post->Author->validate = array(
4540
                        'user' => array('rule' => array('notBlank'))
4541
                );
4542

    
4543
                // If validation error occurs, rollback() should be called.
4544
                $db = $this->_getMockDboSource(array('begin', 'commit', 'rollback'));
4545
                $db->expects($this->once())->method('begin')->will($this->returnValue(true));
4546
                $db->expects($this->never())->method('commit');
4547
                $db->expects($this->once())->method('rollback');
4548

    
4549
                $Post->setDataSourceObject($db);
4550
                $Post->Author->setDataSourceObject($db);
4551

    
4552
                $data = array(
4553
                        'Post' => array(
4554
                                'title' => 'New post',
4555
                                'body' => 'Content',
4556
                                'published' => 'Y'
4557
                        ),
4558
                        'Author' => array(
4559
                                'user' => '',
4560
                                'password' => "sekret"
4561
                        )
4562
                );
4563
                $Post->saveAll($data, array('validate' => true));
4564

    
4565
                // If exception thrown, rollback() should be called too.
4566
                $db = $this->_getMockDboSource(array('begin', 'commit', 'rollback'));
4567
                $db->expects($this->once())->method('begin')->will($this->returnValue(true));
4568
                $db->expects($this->never())->method('commit');
4569
                $db->expects($this->once())->method('rollback');
4570

    
4571
                $Post->setDataSourceObject($db);
4572
                $Post->Author->setDataSourceObject($db);
4573

    
4574
                $data = array(
4575
                        'Post' => array(
4576
                                'title' => 'New post',
4577
                                'body' => $db->expression('PDO_EXCEPTION()'),
4578
                                'published' => 'Y'
4579
                        ),
4580
                        'Author' => array(
4581
                                'user' => 'New user',
4582
                                'password' => "sekret"
4583
                        )
4584
                );
4585

    
4586
                try {
4587
                        $Post->saveAll($data, array('validate' => true));
4588
                        $this->fail('No exception thrown');
4589
                } catch (PDOException $e) {
4590
                }
4591

    
4592
                // Otherwise, commit() should be called.
4593
                $db = $this->_getMockDboSource(array('begin', 'commit', 'rollback'));
4594
                $db->expects($this->once())->method('begin')->will($this->returnValue(true));
4595
                $db->expects($this->once())->method('commit');
4596
                $db->expects($this->never())->method('rollback');
4597

    
4598
                $Post->setDataSourceObject($db);
4599
                $Post->Author->setDataSourceObject($db);
4600

    
4601
                $data = array(
4602
                        'Post' => array(
4603
                                'title' => 'New post',
4604
                                'body' => 'Content',
4605
                                'published' => 'Y'
4606
                        ),
4607
                        'Author' => array(
4608
                                'user' => 'New user',
4609
                                'password' => "sekret"
4610
                        )
4611
                );
4612
                $Post->saveAll($data, array('validate' => true));
4613
        }
4614

    
4615
/**
4616
 * test saveAll with nested saveAll call.
4617
 *
4618
 * @return void
4619
 */
4620
        public function testSaveAllNestedSaveAll() {
4621
                $this->loadFixtures('Sample');
4622
                $TransactionTestModel = new TransactionTestModel();
4623

    
4624
                $data = array(
4625
                        array('apple_id' => 1, 'name' => 'sample5'),
4626
                );
4627

    
4628
                $this->assertTrue($TransactionTestModel->saveAll($data, array('atomic' => true)));
4629
        }
4630

    
4631
/**
4632
 * testSaveAllTransaction method
4633
 *
4634
 * @return void
4635
 */
4636
        public function testSaveAllTransaction() {
4637
                $this->loadFixtures('Post', 'Author', 'Comment', 'Attachment');
4638
                $TestModel = new Post();
4639

    
4640
                $TestModel->validate = array('title' => 'notBlank');
4641
                $data = array(
4642
                        array('author_id' => 1, 'title' => 'New Fourth Post'),
4643
                        array('author_id' => 1, 'title' => 'New Fifth Post'),
4644
                        array('author_id' => 1, 'title' => '')
4645
                );
4646
                $this->assertFalse($TestModel->saveAll($data));
4647

    
4648
                $result = $TestModel->find('all', array('recursive' => -1));
4649
                $expected = array(
4650
                        array('Post' => array(
4651
                                'id' => '1',
4652
                                'author_id' => 1,
4653
                                'title' => 'First Post',
4654
                                'body' => 'First Post Body',
4655
                                'published' => 'Y',
4656
                                'created' => '2007-03-18 10:39:23',
4657
                                'updated' => '2007-03-18 10:41:31'
4658
                        )),
4659
                        array('Post' => array(
4660
                                'id' => '2',
4661
                                'author_id' => 3,
4662
                                'title' => 'Second Post',
4663
                                'body' => 'Second Post Body',
4664
                                'published' => 'Y',
4665
                                'created' => '2007-03-18 10:41:23',
4666
                                'updated' => '2007-03-18 10:43:31'
4667
                        )),
4668
                        array('Post' => array(
4669
                                'id' => '3',
4670
                                'author_id' => 1,
4671
                                'title' => 'Third Post',
4672
                                'body' => 'Third Post Body',
4673
                                'published' => 'Y',
4674
                                'created' => '2007-03-18 10:43:23',
4675
                                'updated' => '2007-03-18 10:45:31'
4676
                )));
4677

    
4678
                if (count($result) != 3) {
4679
                        // Database doesn't support transactions
4680
                        $expected[] = array(
4681
                                'Post' => array(
4682
                                        'id' => '4',
4683
                                        'author_id' => 1,
4684
                                        'title' => 'New Fourth Post',
4685
                                        'body' => null,
4686
                                        'published' => 'N',
4687
                                        'created' => static::date(),
4688
                                        'updated' => static::date()
4689
                        ));
4690

    
4691
                        $expected[] = array(
4692
                                'Post' => array(
4693
                                        'id' => '5',
4694
                                        'author_id' => 1,
4695
                                        'title' => 'New Fifth Post',
4696
                                        'body' => null,
4697
                                        'published' => 'N',
4698
                                        'created' => static::date(),
4699
                                        'updated' => static::date()
4700
                        ));
4701

    
4702
                        $this->assertEquals($expected, $result);
4703
                        // Skip the rest of the transactional tests
4704
                        return;
4705
                }
4706

    
4707
                $this->assertEquals($expected, $result);
4708

    
4709
                $data = array(
4710
                        array('author_id' => 1, 'title' => 'New Fourth Post'),
4711
                        array('author_id' => 1, 'title' => ''),
4712
                        array('author_id' => 1, 'title' => 'New Sixth Post')
4713
                );
4714
                $this->assertFalse($TestModel->saveAll($data));
4715

    
4716
                $result = $TestModel->find('all', array('recursive' => -1));
4717
                $expected = array(
4718
                        array('Post' => array(
4719
                                'id' => '1',
4720
                                'author_id' => 1,
4721
                                'title' => 'First Post',
4722
                                'body' => 'First Post Body',
4723
                                'published' => 'Y',
4724
                                'created' => '2007-03-18 10:39:23',
4725
                                'updated' => '2007-03-18 10:41:31'
4726
                        )),
4727
                        array('Post' => array(
4728
                                'id' => '2',
4729
                                'author_id' => 3,
4730
                                'title' => 'Second Post',
4731
                                'body' => 'Second Post Body',
4732
                                'published' => 'Y',
4733
                                'created' => '2007-03-18 10:41:23',
4734
                                'updated' => '2007-03-18 10:43:31'
4735
                        )),
4736
                        array('Post' => array(
4737
                                'id' => '3',
4738
                                'author_id' => 1,
4739
                                'title' => 'Third Post',
4740
                                'body' => 'Third Post Body',
4741
                                'published' => 'Y',
4742
                                'created' => '2007-03-18 10:43:23',
4743
                                'updated' => '2007-03-18 10:45:31'
4744
                )));
4745

    
4746
                if (count($result) != 3) {
4747
                        // Database doesn't support transactions
4748
                        $expected[] = array(
4749
                                'Post' => array(
4750
                                        'id' => '4',
4751
                                        'author_id' => 1,
4752
                                        'title' => 'New Fourth Post',
4753
                                        'body' => 'Third Post Body',
4754
                                        'published' => 'N',
4755
                                        'created' => static::date(),
4756
                                        'updated' => static::date()
4757
                        ));
4758

    
4759
                        $expected[] = array(
4760
                                'Post' => array(
4761
                                        'id' => '5',
4762
                                        'author_id' => 1,
4763
                                        'title' => 'Third Post',
4764
                                        'body' => 'Third Post Body',
4765
                                        'published' => 'N',
4766
                                        'created' => static::date(),
4767
                                        'updated' => static::date()
4768
                        ));
4769
                }
4770
                $this->assertEquals($expected, $result);
4771

    
4772
                $TestModel->validate = array('title' => 'notBlank');
4773
                $data = array(
4774
                        array('author_id' => 1, 'title' => 'New Fourth Post'),
4775
                        array('author_id' => 1, 'title' => 'New Fifth Post'),
4776
                        array('author_id' => 1, 'title' => 'New Sixth Post')
4777
                );
4778
                $this->assertTrue($TestModel->saveAll($data));
4779

    
4780
                $result = $TestModel->find('all', array(
4781
                        'recursive' => -1,
4782
                        'fields' => array('author_id', 'title', 'body', 'published'),
4783
                        'order' => array('Post.created' => 'ASC')
4784
                ));
4785

    
4786
                $expected = array(
4787
                        array('Post' => array(
4788
                                'author_id' => 1,
4789
                                'title' => 'First Post',
4790
                                'body' => 'First Post Body',
4791
                                'published' => 'Y'
4792
                        )),
4793
                        array('Post' => array(
4794
                                'author_id' => 3,
4795
                                'title' => 'Second Post',
4796
                                'body' => 'Second Post Body',
4797
                                'published' => 'Y'
4798
                        )),
4799
                        array('Post' => array(
4800
                                'author_id' => 1,
4801
                                'title' => 'Third Post',
4802
                                'body' => 'Third Post Body',
4803
                                'published' => 'Y'
4804
                        )),
4805
                        array('Post' => array(
4806
                                'author_id' => 1,
4807
                                'title' => 'New Fourth Post',
4808
                                'body' => '',
4809
                                'published' => 'N'
4810
                        )),
4811
                        array('Post' => array(
4812
                                'author_id' => 1,
4813
                                'title' => 'New Fifth Post',
4814
                                'body' => '',
4815
                                'published' => 'N'
4816
                        )),
4817
                        array('Post' => array(
4818
                                'author_id' => 1,
4819
                                'title' => 'New Sixth Post',
4820
                                'body' => '',
4821
                                'published' => 'N'
4822
                )));
4823
                $this->assertEquals($expected, $result);
4824
        }
4825

    
4826
/**
4827
 * testSaveAllValidation method
4828
 *
4829
 * @return void
4830
 */
4831
        public function testSaveAllValidation() {
4832
                $this->loadFixtures('Post', 'Author', 'Comment', 'Attachment');
4833
                $TestModel = new Post();
4834

    
4835
                $data = array(
4836
                        array(
4837
                                'id' => '1',
4838
                                'title' => 'Baleeted First Post',
4839
                                'body' => 'Baleeted!',
4840
                                'published' => 'N'
4841
                        ),
4842
                        array(
4843
                                'id' => '2',
4844
                                'title' => 'Just update the title'
4845
                        ),
4846
                        array(
4847
                                'title' => 'Creating a fourth post',
4848
                                'body' => 'Fourth post body',
4849
                                'author_id' => 2
4850
                ));
4851

    
4852
                $this->assertTrue($TestModel->saveAll($data));
4853

    
4854
                $result = $TestModel->find('all', array('recursive' => -1, 'order' => 'Post.id ASC'));
4855
                $expected = array(
4856
                        array(
4857
                                'Post' => array(
4858
                                        'id' => '1',
4859
                                        'author_id' => '1',
4860
                                        'title' => 'Baleeted First Post',
4861
                                        'body' => 'Baleeted!',
4862
                                        'published' => 'N',
4863
                                        'created' => '2007-03-18 10:39:23'
4864
                        )),
4865
                        array(
4866
                                'Post' => array(
4867
                                        'id' => '2',
4868
                                        'author_id' => '3',
4869
                                        'title' => 'Just update the title',
4870
                                        'body' => 'Second Post Body',
4871
                                        'published' => 'Y',
4872
                                        'created' => '2007-03-18 10:41:23'
4873
                        )),
4874
                        array(
4875
                                'Post' => array(
4876
                                        'id' => '3',
4877
                                        'author_id' => '1',
4878
                                        'title' => 'Third Post',
4879
                                        'body' => 'Third Post Body',
4880
                                        'published' => 'Y',
4881
                                        'created' => '2007-03-18 10:43:23',
4882
                                        'updated' => '2007-03-18 10:45:31'
4883
                        )),
4884
                        array(
4885
                                'Post' => array(
4886
                                        'id' => '4',
4887
                                        'author_id' => '2',
4888
                                        'title' => 'Creating a fourth post',
4889
                                        'body' => 'Fourth post body',
4890
                                        'published' => 'N'
4891
                )));
4892
                $this->assertEquals(static::date(), $result[0]['Post']['updated']);
4893
                $this->assertEquals(static::date(), $result[1]['Post']['updated']);
4894
                $this->assertEquals(static::date(), $result[3]['Post']['created']);
4895
                $this->assertEquals(static::date(), $result[3]['Post']['updated']);
4896
                unset($result[0]['Post']['updated'], $result[1]['Post']['updated']);
4897
                unset($result[3]['Post']['created'], $result[3]['Post']['updated']);
4898
                $this->assertEquals($expected, $result);
4899

    
4900
                $TestModel->validate = array('title' => 'notBlank', 'author_id' => 'numeric');
4901
                $data = array(
4902
                        array(
4903
                                'id' => '1',
4904
                                'title' => 'Un-Baleeted First Post',
4905
                                'body' => 'Not Baleeted!',
4906
                                'published' => 'Y'
4907
                        ),
4908
                        array(
4909
                                'id' => '2',
4910
                                'title' => '',
4911
                                'body' => 'Trying to get away with an empty title'
4912
                ));
4913
                $result = $TestModel->saveAll($data);
4914
                $this->assertFalse($result);
4915

    
4916
                $result = $TestModel->find('all', array('recursive' => -1, 'order' => 'Post.id ASC'));
4917
                $errors = array(1 => array('title' => array('This field cannot be left blank')));
4918
                $transactionWorked = Set::matches('/Post[1][title=Baleeted First Post]', $result);
4919
                if (!$transactionWorked) {
4920
                        $this->assertTrue(Set::matches('/Post[1][title=Un-Baleeted First Post]', $result));
4921
                        $this->assertTrue(Set::matches('/Post[2][title=Just update the title]', $result));
4922
                }
4923

    
4924
                $this->assertEquals($errors, $TestModel->validationErrors);
4925

    
4926
                $TestModel->validate = array('title' => 'notBlank', 'author_id' => 'numeric');
4927
                $data = array(
4928
                        array(
4929
                                'id' => '1',
4930
                                'title' => 'Un-Baleeted First Post',
4931
                                'body' => 'Not Baleeted!',
4932
                                'published' => 'Y'
4933
                        ),
4934
                        array(
4935
                                'id' => '2',
4936
                                'title' => '',
4937
                                'body' => 'Trying to get away with an empty title'
4938
                ));
4939
                $result = $TestModel->saveAll($data, array('validate' => true, 'atomic' => false));
4940
                $this->assertEquals(array(true, false), $result);
4941
                $result = $TestModel->find('all', array('recursive' => -1, 'order' => 'Post.id ASC'));
4942
                $errors = array(1 => array('title' => array('This field cannot be left blank')));
4943
                $expected = array(
4944
                        array(
4945
                                'Post' => array(
4946
                                        'id' => '1',
4947
                                        'author_id' => '1',
4948
                                        'title' => 'Un-Baleeted First Post',
4949
                                        'body' => 'Not Baleeted!',
4950
                                        'published' => 'Y',
4951
                                        'created' => '2007-03-18 10:39:23'
4952
                                )
4953
                        ),
4954
                        array(
4955
                                'Post' => array(
4956
                                        'id' => '2',
4957
                                        'author_id' => '3',
4958
                                        'title' => 'Just update the title',
4959
                                        'body' => 'Second Post Body',
4960
                                        'published' => 'Y',
4961
                                        'created' => '2007-03-18 10:41:23'
4962
                                )
4963
                        ),
4964
                        array(
4965
                                'Post' => array(
4966
                                        'id' => '3',
4967
                                        'author_id' => '1',
4968
                                        'title' => 'Third Post',
4969
                                        'body' => 'Third Post Body',
4970
                                        'published' => 'Y',
4971
                                        'created' => '2007-03-18 10:43:23',
4972
                                        'updated' => '2007-03-18 10:45:31'
4973
                                )
4974
                        ),
4975
                        array(
4976
                                'Post' => array(
4977
                                        'id' => '4',
4978
                                        'author_id' => '2',
4979
                                        'title' => 'Creating a fourth post',
4980
                                        'body' => 'Fourth post body',
4981
                                        'published' => 'N'
4982
                                )
4983
                        )
4984
                );
4985

    
4986
                $this->assertEquals(static::date(), $result[0]['Post']['updated']);
4987
                $this->assertEquals(static::date(), $result[1]['Post']['updated']);
4988
                $this->assertEquals(static::date(), $result[3]['Post']['updated']);
4989
                $this->assertEquals(static::date(), $result[3]['Post']['created']);
4990
                unset(
4991
                        $result[0]['Post']['updated'], $result[1]['Post']['updated'],
4992
                        $result[3]['Post']['updated'], $result[3]['Post']['created']
4993
                );
4994
                $this->assertEquals($expected, $result);
4995
                $this->assertEquals($errors, $TestModel->validationErrors);
4996

    
4997
                $data = array(
4998
                        array(
4999
                                'id' => '1',
5000
                                'title' => 'Re-Baleeted First Post',
5001
                                'body' => 'Baleeted!',
5002
                                'published' => 'N'
5003
                        ),
5004
                        array(
5005
                                'id' => '2',
5006
                                'title' => '',
5007
                                'body' => 'Trying to get away with an empty title'
5008
                ));
5009
                $this->assertFalse($TestModel->saveAll($data, array('validate' => 'first')));
5010

    
5011
                $result = $TestModel->find('all', array('recursive' => -1, 'order' => 'Post.id ASC'));
5012
                unset(
5013
                        $result[0]['Post']['updated'], $result[1]['Post']['updated'],
5014
                        $result[3]['Post']['updated'], $result[3]['Post']['created']
5015
                );
5016
                $this->assertEquals($expected, $result);
5017
                $this->assertEquals($errors, $TestModel->validationErrors);
5018
        }
5019

    
5020
/**
5021
 * testSaveAllValidationOnly method
5022
 *
5023
 * @return void
5024
 */
5025
        public function testSaveAllValidationOnly() {
5026
                $this->loadFixtures('Comment', 'Attachment');
5027
                $TestModel = new Comment();
5028
                $TestModel->Attachment->validate = array('attachment' => 'notBlank');
5029

    
5030
                $data = array(
5031
                        'Comment' => array(
5032
                                'comment' => 'This is the comment'
5033
                        ),
5034
                        'Attachment' => array(
5035
                                'attachment' => ''
5036
                        )
5037
                );
5038

    
5039
                $result = $TestModel->saveAll($data, array('validate' => 'only'));
5040
                $this->assertFalse($result);
5041

    
5042
                $TestModel = new Article();
5043
                $TestModel->validate = array('title' => 'notBlank');
5044
                $result = $TestModel->saveAll(
5045
                        array(
5046
                                0 => array('title' => ''),
5047
                                1 => array('title' => 'title 1'),
5048
                                2 => array('title' => 'title 2'),
5049
                        ),
5050
                        array('validate' => 'only')
5051
                );
5052
                $this->assertFalse($result);
5053
                $expected = array(
5054
                        0 => array('title' => array('This field cannot be left blank')),
5055
                );
5056
                $this->assertEquals($expected, $TestModel->validationErrors);
5057

    
5058
                $result = $TestModel->saveAll(
5059
                        array(
5060
                                0 => array('title' => 'title 0'),
5061
                                1 => array('title' => ''),
5062
                                2 => array('title' => 'title 2'),
5063
                        ),
5064
                        array('validate' => 'only')
5065
                );
5066
                $this->assertFalse($result);
5067
                $expected = array(
5068
                        1 => array('title' => array('This field cannot be left blank')),
5069
                );
5070
                $this->assertEquals($expected, $TestModel->validationErrors);
5071
        }
5072

    
5073
/**
5074
 * testSaveAllValidateFirst method
5075
 *
5076
 * @return void
5077
 */
5078
        public function testSaveAllValidateFirst() {
5079
                $this->loadFixtures('Article', 'Comment', 'Attachment', 'User', 'ArticlesTag', 'Tag');
5080
                $model = new Article();
5081
                $model->deleteAll(true);
5082

    
5083
                $model->Comment->validate = array('comment' => 'notBlank');
5084
                $result = $model->saveAll(array(
5085
                        'Article' => array(
5086
                                'title' => 'Post with Author',
5087
                                'body' => 'This post will be saved author'
5088
                        ),
5089
                        'Comment' => array(
5090
                                array('comment' => 'First new comment'),
5091
                                array('comment' => '')
5092
                        )
5093
                ), array('validate' => 'first'));
5094

    
5095
                $this->assertFalse($result);
5096

    
5097
                $result = $model->find('all');
5098
                $this->assertSame(array(), $result);
5099
                $expected = array('Comment' => array(
5100
                        1 => array('comment' => array('This field cannot be left blank'))
5101
                ));
5102

    
5103
                $this->assertEquals($expected['Comment'], $model->Comment->validationErrors);
5104

    
5105
                $this->assertSame($model->Comment->find('count'), 0);
5106

    
5107
                $result = $model->saveAll(
5108
                        array(
5109
                                'Article' => array(
5110
                                        'title' => 'Post with Author',
5111
                                        'body' => 'This post will be saved with an author',
5112
                                        'user_id' => 2
5113
                                ),
5114
                                'Comment' => array(
5115
                                        array(
5116
                                                'comment' => 'Only new comment',
5117
                                                'user_id' => 2
5118
                        ))),
5119
                        array('validate' => 'first')
5120
                );
5121

    
5122
                $this->assertTrue($result);
5123

    
5124
                $result = $model->Comment->find('all');
5125
                $this->assertSame(count($result), 1);
5126
                $result = Hash::extract($result, '{n}.Comment.article_id');
5127
                $this->assertEquals(4, $result[0]);
5128

    
5129
                $model->deleteAll(true);
5130
                $data = array(
5131
                        'Article' => array(
5132
                                'title' => 'Post with Author saveAlled from comment',
5133
                                'body' => 'This post will be saved with an author',
5134
                                'user_id' => 2
5135
                        ),
5136
                        'Comment' => array(
5137
                                'comment' => 'Only new comment', 'user_id' => 2
5138
                ));
5139

    
5140
                $result = $model->Comment->saveAll($data, array('validate' => 'first'));
5141
                $this->assertFalse(empty($result));
5142

    
5143
                $result = $model->find('all');
5144
                $this->assertEquals(
5145
                        $result[0]['Article']['title'],
5146
                        'Post with Author saveAlled from comment'
5147
                );
5148
                $this->assertEquals('Only new comment', $result[0]['Comment'][0]['comment']);
5149
        }
5150

    
5151
/**
5152
 * test saveAll()'s return is correct when using atomic = false and validate = first.
5153
 *
5154
 * @return void
5155
 */
5156
        public function testSaveAllValidateFirstAtomicFalse() {
5157
                $this->loadFixtures('Something');
5158
                $Something = new Something();
5159
                $invalidData = array(
5160
                        array(
5161
                                'title' => 'foo',
5162
                                'body' => 'bar',
5163
                                'published' => 'baz',
5164
                        ),
5165
                        array(
5166
                                'body' => 3,
5167
                                'published' => 'sd',
5168
                        ),
5169
                );
5170
                $Something->create();
5171
                $Something->validate = array(
5172
                        'title' => array(
5173
                                'rule' => 'alphaNumeric',
5174
                                'required' => true,
5175
                        ),
5176
                        'body' => array(
5177
                                'rule' => 'alphaNumeric',
5178
                                'required' => true,
5179
                                'allowEmpty' => true,
5180
                        ),
5181
                );
5182
                $result = $Something->saveAll($invalidData, array(
5183
                        'atomic' => false,
5184
                        'validate' => 'first',
5185
                ));
5186
                $expected = array(true, false);
5187
                $this->assertEquals($expected, $result);
5188

    
5189
                $Something = new Something();
5190
                $validData = array(
5191
                        array(
5192
                                'title' => 'title value',
5193
                                'body' => 'body value',
5194
                                'published' => 'baz',
5195
                        ),
5196
                        array(
5197
                                'title' => 'valid',
5198
                                'body' => 'this body',
5199
                                'published' => 'sd',
5200
                        ),
5201
                );
5202
                $Something->create();
5203
                $result = $Something->saveAll($validData, array(
5204
                        'atomic' => false,
5205
                        'validate' => 'first',
5206
                ));
5207
                $expected = array(true, true);
5208
                $this->assertEquals($expected, $result);
5209
        }
5210

    
5211
/**
5212
 * testSaveAllHasManyValidationOnly method
5213
 *
5214
 * @return void
5215
 */
5216
        public function testSaveAllHasManyValidationOnly() {
5217
                $this->loadFixtures('Article', 'Comment', 'Attachment');
5218
                $TestModel = new Article();
5219
                $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
5220
                $TestModel->Comment->validate = array('comment' => 'notBlank');
5221

    
5222
                $result = $TestModel->saveAll(
5223
                        array(
5224
                                'Article' => array('id' => 2),
5225
                                'Comment' => array(
5226
                                        array(
5227
                                                'id' => 1,
5228
                                                'comment' => '',
5229
                                                'published' => 'Y',
5230
                                                'user_id' => 1),
5231
                                        array(
5232
                                                'id' => 2,
5233
                                                'comment' =>
5234
                                                'comment',
5235
                                                'published' => 'Y',
5236
                                                'user_id' => 1
5237
                        ))),
5238
                        array('validate' => 'only')
5239
                );
5240
                $this->assertFalse($result);
5241

    
5242
                $result = $TestModel->saveAll(
5243
                        array(
5244
                                'Article' => array('id' => 2),
5245
                                'Comment' => array(
5246
                                        array(
5247
                                                'id' => 1,
5248
                                                'comment' => '',
5249
                                                'published' => 'Y',
5250
                                                'user_id' => 1
5251
                                        ),
5252
                                        array(
5253
                                                'id' => 2,
5254
                                                'comment' => 'comment',
5255
                                                'published' => 'Y',
5256
                                                'user_id' => 1
5257
                                        ),
5258
                                        array(
5259
                                                'id' => 3,
5260
                                                'comment' => '',
5261
                                                'published' => 'Y',
5262
                                                'user_id' => 1
5263
                        ))),
5264
                        array(
5265
                                'validate' => 'only',
5266
                                'atomic' => false
5267
                ));
5268
                $expected = array(
5269
                        'Article' => true,
5270
                        'Comment' => array(false, true, false)
5271
                );
5272
                $this->assertSame($expected, $result);
5273

    
5274
                $expected = array('Comment' => array(
5275
                        0 => array('comment' => array('This field cannot be left blank')),
5276
                        2 => array('comment' => array('This field cannot be left blank'))
5277
                ));
5278
                $this->assertEquals($expected, $TestModel->validationErrors);
5279

    
5280
                $expected = array(
5281
                        0 => array('comment' => array('This field cannot be left blank')),
5282
                        2 => array('comment' => array('This field cannot be left blank'))
5283
                );
5284
                $this->assertEquals($expected, $TestModel->Comment->validationErrors);
5285
        }
5286

    
5287
/**
5288
 * test that saveAll still behaves like previous versions (does not necessarily need a first argument)
5289
 *
5290
 * @return void
5291
 */
5292
        public function testSaveAllWithSet() {
5293
                $this->loadFixtures('Article', 'Tag', 'Comment', 'User', 'ArticlesTag');
5294
                $data = array(
5295
                        'Article' => array(
5296
                                'user_id' => 1,
5297
                                'title' => 'Article Has and belongs to Many Tags'
5298
                        ),
5299
                        'Tag' => array(
5300
                                'Tag' => array(1, 2)
5301
                        ),
5302
                        'Comment' => array(
5303
                                array(
5304
                                        'comment' => 'Article comment',
5305
                                        'user_id' => 1
5306
                )));
5307
                $Article = new Article();
5308
                $Article->set($data);
5309
                $result = $Article->saveAll();
5310
                $this->assertFalse(empty($result));
5311
        }
5312

    
5313
/**
5314
 * test that saveAll behaves like plain save() when supplied empty data
5315
 *
5316
 * @link https://cakephp.lighthouseapp.com/projects/42648/tickets/277-test-saveall-with-validation-returns-incorrect-boolean-when-saving-empty-data
5317
 * @return void
5318
 */
5319
        public function testSaveAllEmptyData() {
5320
                $this->skipIf($this->db instanceof Sqlserver, 'This test is not compatible with SQL Server.');
5321

    
5322
                $this->loadFixtures('Article', 'ProductUpdateAll', 'Comment', 'Attachment');
5323
                $model = new Article();
5324
                $result = $model->saveAll(array(), array('validate' => 'first'));
5325
                $this->assertFalse(empty($result));
5326

    
5327
                $model = new ProductUpdateAll();
5328
                $result = $model->saveAll();
5329
                $this->assertFalse($result);
5330
        }
5331

    
5332
/**
5333
 * testSaveAssociated method
5334
 *
5335
 * @return void
5336
 */
5337
        public function testSaveAssociated() {
5338
                $this->loadFixtures('Post', 'Author', 'Comment', 'Attachment', 'Article', 'User');
5339
                $TestModel = new Post();
5340

    
5341
                $result = $TestModel->find('all');
5342
                $this->assertEquals(3, count($result));
5343
                $this->assertFalse(isset($result[3]));
5344

    
5345
                $TestModel->saveAssociated(array(
5346
                        'Post' => array(
5347
                                'title' => 'Post with Author',
5348
                                'body' => 'This post will be saved with an author'
5349
                        ),
5350
                        'Author' => array(
5351
                                'user' => 'bob',
5352
                                'password' => '5f4dcc3b5aa765d61d8327deb882cf90'
5353
                )));
5354

    
5355
                $result = $TestModel->find('all', array('order' => array('Post.id ' => 'ASC')));
5356
                $expected = array(
5357
                        'Post' => array(
5358
                                'id' => '4',
5359
                                'author_id' => '5',
5360
                                'title' => 'Post with Author',
5361
                                'body' => 'This post will be saved with an author',
5362
                                'published' => 'N'
5363
                        ),
5364
                        'Author' => array(
5365
                                'id' => '5',
5366
                                'user' => 'bob',
5367
                                'password' => '5f4dcc3b5aa765d61d8327deb882cf90',
5368
                                'test' => 'working'
5369
                ));
5370
                $this->assertEquals(static::date(), $result[3]['Post']['updated']);
5371
                $this->assertEquals(static::date(), $result[3]['Post']['created']);
5372
                $this->assertEquals(static::date(), $result[3]['Author']['created']);
5373
                $this->assertEquals(static::date(), $result[3]['Author']['updated']);
5374
                unset(
5375
                        $result[3]['Post']['updated'], $result[3]['Post']['created'],
5376
                        $result[3]['Author']['updated'], $result[3]['Author']['created']
5377
                );
5378
                $this->assertEquals($expected, $result[3]);
5379
                $this->assertEquals(4, count($result));
5380

    
5381
                $TestModel = new Comment();
5382
                $result = $TestModel->saveAssociated(array(
5383
                        'Comment' => array(
5384
                                'article_id' => 2,
5385
                                'user_id' => 2,
5386
                                'comment' => 'New comment with attachment',
5387
                                'published' => 'Y'
5388
                        ),
5389
                        'Attachment' => array(
5390
                                'attachment' => 'some_file.tgz'
5391
                        )));
5392
                $this->assertFalse(empty($result));
5393

    
5394
                $result = $TestModel->find('all');
5395
                $expected = array(
5396
                        'id' => '7',
5397
                        'article_id' => '2',
5398
                        'user_id' => '2',
5399
                        'comment' => 'New comment with attachment',
5400
                        'published' => 'Y'
5401
                );
5402
                $this->assertEquals(static::date(), $result[6]['Comment']['updated']);
5403
                $this->assertEquals(static::date(), $result[6]['Comment']['created']);
5404
                unset($result[6]['Comment']['updated'], $result[6]['Comment']['created']);
5405
                $this->assertEquals($expected, $result[6]['Comment']);
5406

    
5407
                $expected = array(
5408
                        'id' => '2',
5409
                        'comment_id' => '7',
5410
                        'attachment' => 'some_file.tgz'
5411
                );
5412
                $this->assertEquals(static::date(), $result[6]['Attachment']['updated']);
5413
                $this->assertEquals(static::date(), $result[6]['Attachment']['created']);
5414
                unset($result[6]['Attachment']['updated'], $result[6]['Attachment']['created']);
5415
                $this->assertEquals($expected, $result[6]['Attachment']);
5416
        }
5417

    
5418
/**
5419
 * Test that validate = first, atomic = false works when associated records
5420
 * fail validation.
5421
 *
5422
 * @return void
5423
 */
5424
        public function testSaveAssociatedAtomicFalseValidateFirstWithErrors() {
5425
                $this->loadFixtures('Comment', 'Article', 'User');
5426
                $Article = ClassRegistry::init('Article');
5427
                $Article->Comment->validator()->add('comment', array(
5428
                        array('rule' => 'notBlank')
5429
                ));
5430

    
5431
                $data = array(
5432
                        'Article' => array(
5433
                                'user_id' => 1,
5434
                                'title' => 'Foo',
5435
                                'body' => 'text',
5436
                                'published' => 'N'
5437
                        ),
5438
                        'Comment' => array(
5439
                                array(
5440
                                        'user_id' => 1,
5441
                                        'comment' => '',
5442
                                        'published' => 'N',
5443
                                )
5444
                        ),
5445
                );
5446

    
5447
                $Article->saveAssociated(
5448
                        $data,
5449
                        array('validate' => 'first', 'atomic' => false)
5450
                );
5451

    
5452
                $result = $Article->validationErrors;
5453
                $expected = array(
5454
                        'Comment' => array(
5455
                                array(
5456
                                        'comment' => array('This field cannot be left blank')
5457
                                )
5458
                        )
5459
                );
5460
                $this->assertEquals($expected, $result);
5461
        }
5462

    
5463
/**
5464
 * testSaveMany method
5465
 *
5466
 * @return void
5467
 */
5468
        public function testSaveMany() {
5469
                $this->loadFixtures('Post');
5470
                $TestModel = new Post();
5471
                $TestModel->deleteAll(true);
5472
                $this->assertEquals(array(), $TestModel->find('all'));
5473

    
5474
                // SQLite seems to reset the PK counter when that happens, so we need this to make the tests pass
5475
                $this->db->truncate($TestModel);
5476

    
5477
                $TestModel->saveMany(array(
5478
                        array(
5479
                                'title' => 'Multi-record post 1',
5480
                                'body' => 'First multi-record post',
5481
                                'author_id' => 2
5482
                        ),
5483
                        array(
5484
                                'title' => 'Multi-record post 2',
5485
                                'body' => 'Second multi-record post',
5486
                                'author_id' => 2
5487
                )));
5488

    
5489
                $result = $TestModel->find('all', array(
5490
                        'recursive' => -1,
5491
                        'order' => 'Post.id ASC'
5492
                ));
5493
                $expected = array(
5494
                        array(
5495
                                'Post' => array(
5496
                                        'id' => '1',
5497
                                        'author_id' => '2',
5498
                                        'title' => 'Multi-record post 1',
5499
                                        'body' => 'First multi-record post',
5500
                                        'published' => 'N'
5501
                                )
5502
                        ),
5503
                        array(
5504
                                'Post' => array(
5505
                                        'id' => '2',
5506
                                        'author_id' => '2',
5507
                                        'title' => 'Multi-record post 2',
5508
                                        'body' => 'Second multi-record post',
5509
                                        'published' => 'N'
5510
                                )
5511
                        )
5512
                );
5513
                $this->assertEquals(static::date(), $result[0]['Post']['updated']);
5514
                $this->assertEquals(static::date(), $result[0]['Post']['created']);
5515
                $this->assertEquals(static::date(), $result[1]['Post']['updated']);
5516
                $this->assertEquals(static::date(), $result[1]['Post']['created']);
5517
                unset($result[0]['Post']['updated'], $result[0]['Post']['created']);
5518
                unset($result[1]['Post']['updated'], $result[1]['Post']['created']);
5519
                $this->assertEquals($expected, $result);
5520
        }
5521

    
5522
/**
5523
 * Test SaveMany with validate=false.
5524
 *
5525
 * @return void
5526
 */
5527
        public function testSaveManyValidateFalse() {
5528
                $this->loadFixtures('Post');
5529
                $TestModel = new Post();
5530
                $TestModel->deleteAll(true);
5531
                $data = array(
5532
                        array('id' => 1, 'author_id' => 1, 'title' => 'hi'),
5533
                        array('id' => 2, 'author_id' => 1, 'title' => 'bye')
5534
                );
5535
                $result = $TestModel->saveAll($data, array('validate' => false));
5536
                $this->assertTrue($result);
5537
        }
5538

    
5539
/**
5540
 * Test SaveAssociated with Habtm relations
5541
 *
5542
 * @return void
5543
 */
5544
        public function testSaveAssociatedHabtm() {
5545
                $this->loadFixtures('Article', 'Tag', 'Comment', 'User', 'ArticlesTag');
5546
                $data = array(
5547
                        'Article' => array(
5548
                                'user_id' => 1,
5549
                                'title' => 'Article Has and belongs to Many Tags'
5550
                        ),
5551
                        'Tag' => array(
5552
                                'Tag' => array(1, 2)
5553
                        ),
5554
                        'Comment' => array(
5555
                                array(
5556
                                        'comment' => 'Article comment',
5557
                                        'user_id' => 1
5558
                )));
5559
                $Article = new Article();
5560
                $result = $Article->saveAssociated($data);
5561
                $this->assertFalse(empty($result));
5562

    
5563
                $result = $Article->read();
5564
                $this->assertEquals(2, count($result['Tag']));
5565
                $this->assertEquals('tag1', $result['Tag'][0]['tag']);
5566
                $this->assertEquals(1, count($result['Comment']));
5567
                $this->assertEquals(1, count($result['Comment'][0]['comment']));
5568
        }
5569

    
5570
/**
5571
 * Test SaveAssociated with Habtm relations and extra join table fields
5572
 *
5573
 * @return void
5574
 */
5575
        public function testSaveAssociatedHabtmWithExtraJoinTableFields() {
5576
                $this->loadFixtures('Something', 'SomethingElse', 'JoinThing');
5577

    
5578
                $data = array(
5579
                        'Something' => array(
5580
                                'id' => 4,
5581
                                'title' => 'Extra Fields',
5582
                                'body' => 'Extra Fields Body',
5583
                                'published' => '1'
5584
                        ),
5585
                        'SomethingElse' => array(
5586
                                array('something_else_id' => 1, 'doomed' => '1'),
5587
                                array('something_else_id' => 2, 'doomed' => '0'),
5588
                                array('something_else_id' => 3, 'doomed' => '1')
5589
                        )
5590
                );
5591

    
5592
                $Something = new Something();
5593
                $result = $Something->saveAssociated($data);
5594
                $this->assertFalse(empty($result));
5595
                $result = $Something->read();
5596

    
5597
                $this->assertEquals(3, count($result['SomethingElse']));
5598
                $this->assertTrue(Set::matches('/Something[id=4]', $result));
5599

    
5600
                $this->assertTrue(Set::matches('/SomethingElse[id=1]', $result));
5601
                $this->assertTrue(Set::matches('/SomethingElse[id=1]/JoinThing[something_else_id=1]', $result));
5602
                $this->assertTrue(Set::matches('/SomethingElse[id=1]/JoinThing[doomed=1]', $result));
5603

    
5604
                $this->assertTrue(Set::matches('/SomethingElse[id=2]', $result));
5605
                $this->assertTrue(Set::matches('/SomethingElse[id=2]/JoinThing[something_else_id=2]', $result));
5606
                $this->assertTrue(Set::matches('/SomethingElse[id=2]/JoinThing[doomed=0]', $result));
5607

    
5608
                $this->assertTrue(Set::matches('/SomethingElse[id=3]', $result));
5609
                $this->assertTrue(Set::matches('/SomethingElse[id=3]/JoinThing[something_else_id=3]', $result));
5610
                $this->assertTrue(Set::matches('/SomethingElse[id=3]/JoinThing[doomed=1]', $result));
5611
        }
5612

    
5613
/**
5614
 * testSaveAssociatedHasOne method
5615
 *
5616
 * @return void
5617
 */
5618
        public function testSaveAssociatedHasOne() {
5619
                $model = new Comment();
5620
                $model->deleteAll(true);
5621
                $this->assertEquals(array(), $model->find('all'));
5622

    
5623
                $model->Attachment->deleteAll(true);
5624
                $this->assertEquals(array(), $model->Attachment->find('all'));
5625

    
5626
                $this->assertTrue($model->saveAssociated(array(
5627
                        'Comment' => array(
5628
                                'comment' => 'Comment with attachment',
5629
                                'article_id' => 1,
5630
                                'user_id' => 1
5631
                        ),
5632
                        'Attachment' => array(
5633
                                'attachment' => 'some_file.zip'
5634
                ))));
5635
                $result = $model->find('all', array('fields' => array(
5636
                        'Comment.id', 'Comment.comment', 'Attachment.id',
5637
                        'Attachment.comment_id', 'Attachment.attachment'
5638
                )));
5639
                $expected = array(array(
5640
                        'Comment' => array(
5641
                                'id' => '1',
5642
                                'comment' => 'Comment with attachment'
5643
                        ),
5644
                        'Attachment' => array(
5645
                                'id' => '1',
5646
                                'comment_id' => '1',
5647
                                'attachment' => 'some_file.zip'
5648
                )));
5649
                $this->assertEquals($expected, $result);
5650

    
5651
                $model->Attachment->bindModel(array('belongsTo' => array('Comment')), false);
5652
                $data = array(
5653
                        'Comment' => array(
5654
                                'comment' => 'Comment with attachment',
5655
                                'article_id' => 1,
5656
                                'user_id' => 1
5657
                        ),
5658
                        'Attachment' => array(
5659
                                'attachment' => 'some_file.zip'
5660
                ));
5661
                $this->assertTrue($model->saveAssociated($data, array('validate' => 'first')));
5662
        }
5663

    
5664
/**
5665
 * testSaveAssociatedBelongsTo method
5666
 *
5667
 * @return void
5668
 */
5669
        public function testSaveAssociatedBelongsTo() {
5670
                $model = new Comment();
5671
                $model->deleteAll(true);
5672
                $this->assertEquals(array(), $model->find('all'));
5673

    
5674
                $model->Article->deleteAll(true);
5675
                $this->assertEquals(array(), $model->Article->find('all'));
5676

    
5677
                $this->assertTrue($model->saveAssociated(array(
5678
                        'Comment' => array(
5679
                                'comment' => 'Article comment',
5680
                                'article_id' => 1,
5681
                                'user_id' => 1
5682
                        ),
5683
                        'Article' => array(
5684
                                'title' => 'Model Associations 101',
5685
                                'user_id' => 1
5686
                ))));
5687
                $result = $model->find('all', array('fields' => array(
5688
                        'Comment.id', 'Comment.comment', 'Comment.article_id', 'Article.id', 'Article.title'
5689
                )));
5690
                $expected = array(array(
5691
                        'Comment' => array(
5692
                                'id' => '1',
5693
                                'article_id' => '1',
5694
                                'comment' => 'Article comment'
5695
                        ),
5696
                        'Article' => array(
5697
                                'id' => '1',
5698
                                'title' => 'Model Associations 101'
5699
                )));
5700
                $this->assertEquals($expected, $result);
5701
        }
5702

    
5703
/**
5704
 * testSaveAssociatedHasOneValidation method
5705
 *
5706
 * @return void
5707
 */
5708
        public function testSaveAssociatedHasOneValidation() {
5709
                $model = new Comment();
5710
                $model->deleteAll(true);
5711
                $this->assertEquals(array(), $model->find('all'));
5712

    
5713
                $model->Attachment->deleteAll(true);
5714
                $this->assertEquals(array(), $model->Attachment->find('all'));
5715

    
5716
                $model->validate = array('comment' => 'notBlank');
5717
                $model->Attachment->validate = array('attachment' => 'notBlank');
5718
                $model->Attachment->bindModel(array('belongsTo' => array('Comment')));
5719

    
5720
                $result = $model->saveAssociated(
5721
                        array(
5722
                                'Comment' => array(
5723
                                        'comment' => '',
5724
                                        'article_id' => 1,
5725
                                        'user_id' => 1
5726
                                ),
5727
                                'Attachment' => array('attachment' => '')
5728
                        )
5729
                );
5730
                $this->assertFalse($result);
5731
                $expected = array(
5732
                        'comment' => array(
5733
                                'This field cannot be left blank'
5734
                        ),
5735
                        'Attachment' => array(
5736
                                'attachment' => array(
5737
                                        'This field cannot be left blank'
5738
                                )
5739
                        )
5740
                );
5741
                $this->assertEquals($expected, $model->validationErrors);
5742
                $this->assertEquals($expected['Attachment'], $model->Attachment->validationErrors);
5743
        }
5744

    
5745
/**
5746
 * testSaveAssociatedAtomic method
5747
 *
5748
 * @return void
5749
 */
5750
        public function testSaveAssociatedAtomic() {
5751
                $this->loadFixtures('Article', 'User');
5752
                $TestModel = new Article();
5753

    
5754
                $result = $TestModel->saveAssociated(array(
5755
                        'Article' => array(
5756
                                'title' => 'Post with Author',
5757
                                'body' => 'This post will be saved with an author',
5758
                                'user_id' => 2
5759
                        ),
5760
                        'Comment' => array(
5761
                                array('comment' => 'First new comment', 'user_id' => 2))
5762
                ), array('atomic' => false));
5763

    
5764
                $this->assertSame($result, array('Article' => true, 'Comment' => array(true)));
5765

    
5766
                $result = $TestModel->saveAssociated(array(
5767
                        'Article' => array('id' => 2),
5768
                        'Comment' => array(
5769
                                array(
5770
                                        'comment' => 'First new comment',
5771
                                        'published' => 'Y',
5772
                                        'user_id' => 1
5773
                                ),
5774
                                array(
5775
                                        'comment' => 'Second new comment',
5776
                                        'published' => 'Y',
5777
                                        'user_id' => 2
5778
                        ))
5779
                ), array('validate' => true, 'atomic' => false));
5780
                $this->assertSame($result, array('Article' => true, 'Comment' => array(true, true)));
5781
        }
5782

    
5783
/**
5784
 * testSaveManyAtomic method
5785
 *
5786
 * @return void
5787
 */
5788
        public function testSaveManyAtomic() {
5789
                $this->loadFixtures('Article', 'User');
5790
                $TestModel = new Article();
5791

    
5792
                $result = $TestModel->saveMany(array(
5793
                        array(
5794
                                'id' => '1',
5795
                                'title' => 'Baleeted First Post',
5796
                                'body' => 'Baleeted!',
5797
                                'published' => 'N'
5798
                        ),
5799
                        array(
5800
                                'id' => '2',
5801
                                'title' => 'Just update the title'
5802
                        ),
5803
                        array(
5804
                                'title' => 'Creating a fourth post',
5805
                                'body' => 'Fourth post body',
5806
                                'user_id' => 2
5807
                        )
5808
                ), array('atomic' => false));
5809
                $this->assertSame($result, array(true, true, true));
5810

    
5811
                $TestModel->validate = array('title' => 'notBlank', 'author_id' => 'numeric');
5812
                $result = $TestModel->saveMany(array(
5813
                        array(
5814
                                'id' => '1',
5815
                                'title' => 'Un-Baleeted First Post',
5816
                                'body' => 'Not Baleeted!',
5817
                                'published' => 'Y'
5818
                        ),
5819
                        array(
5820
                                'id' => '2',
5821
                                'title' => '',
5822
                                'body' => 'Trying to get away with an empty title'
5823
                        )
5824
                ), array('validate' => true, 'atomic' => false));
5825

    
5826
                $this->assertSame(array(true, false), $result);
5827
        }
5828

    
5829
/**
5830
 * testSaveAssociatedHasMany method
5831
 *
5832
 * @return void
5833
 */
5834
        public function testSaveAssociatedHasMany() {
5835
                $this->loadFixtures('Article', 'Comment');
5836
                $TestModel = new Article();
5837
                $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
5838

    
5839
                $result = $TestModel->saveAssociated(array(
5840
                        'Article' => array('id' => 2),
5841
                        'Comment' => array(
5842
                                array('comment' => 'First new comment', 'published' => 'Y', 'user_id' => 1),
5843
                                array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
5844
                        )
5845
                ));
5846
                $this->assertFalse(empty($result));
5847

    
5848
                $result = $TestModel->findById(2);
5849
                $expected = array(
5850
                        'First Comment for Second Article',
5851
                        'Second Comment for Second Article',
5852
                        'First new comment',
5853
                        'Second new comment'
5854
                );
5855
                $this->assertEquals($expected, Hash::extract($result['Comment'], '{n}.comment'));
5856

    
5857
                $result = $TestModel->saveAssociated(
5858
                        array(
5859
                                'Article' => array('id' => 2),
5860
                                'Comment' => array(
5861
                                        array(
5862
                                                'comment' => 'Third new comment',
5863
                                                'published' => 'Y',
5864
                                                'user_id' => 1
5865
                        ))),
5866
                        array('atomic' => false)
5867
                );
5868
                $this->assertFalse(empty($result));
5869

    
5870
                $result = $TestModel->findById(2);
5871
                $expected = array(
5872
                        'First Comment for Second Article',
5873
                        'Second Comment for Second Article',
5874
                        'First new comment',
5875
                        'Second new comment',
5876
                        'Third new comment'
5877
                );
5878
                $this->assertEquals($expected, Hash::extract($result['Comment'], '{n}.comment'));
5879

    
5880
                $TestModel->beforeSaveReturn = false;
5881
                $result = $TestModel->saveAssociated(
5882
                        array(
5883
                                'Article' => array('id' => 2),
5884
                                'Comment' => array(
5885
                                        array(
5886
                                                'comment' => 'Fourth new comment',
5887
                                                'published' => 'Y',
5888
                                                'user_id' => 1
5889
                        ))),
5890
                        array('atomic' => false)
5891
                );
5892
                $this->assertEquals(array('Article' => false), $result);
5893

    
5894
                $result = $TestModel->findById(2);
5895
                $expected = array(
5896
                        'First Comment for Second Article',
5897
                        'Second Comment for Second Article',
5898
                        'First new comment',
5899
                        'Second new comment',
5900
                        'Third new comment'
5901
                );
5902
                $this->assertEquals($expected, Hash::extract($result['Comment'], '{n}.comment'));
5903
        }
5904

    
5905
/**
5906
 * testSaveAssociatedHasManyEmpty method
5907
 *
5908
 * @return void
5909
 */
5910
        public function testSaveAssociatedHasManyEmpty() {
5911
                $this->loadFixtures('Article', 'Comment');
5912
                $TestModel = new Article();
5913
                $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
5914
                $TestModel->validate = $TestModel->Comment->validate = array('user_id' => array('notBlank' => array('rule' => 'notBlank', 'required' => true)));
5915

    
5916
                //empty hasMany data is ignored in save
5917
                $result = $TestModel->saveAssociated(array(
5918
                        'Article' => array('title' => 'title', 'user_id' => 1),
5919
                        'Comment' => array()
5920
                ), array('validate' => true));
5921
                $this->assertTrue($result);
5922

    
5923
                $result = $TestModel->saveAssociated(array(
5924
                        'Article' => array('title' => 'title', 'user_id' => 1),
5925
                        'Comment' => array()
5926
                ), array('validate' => true, 'atomic' => false));
5927
                $this->assertEquals(array('Article' => true), $result);
5928

    
5929
                //empty primary data is not ignored
5930
                $result = $TestModel->saveAssociated(array('Article' => array()), array('validate' => true));
5931
                $this->assertFalse($result);
5932

    
5933
                $result = $TestModel->saveAssociated(array('Article' => array()), array('validate' => true, 'atomic' => false));
5934
                $this->assertEquals(array('Article' => false), $result);
5935
        }
5936

    
5937
/**
5938
 * testSaveAssociatedHasManyValidation method
5939
 *
5940
 * @return void
5941
 */
5942
        public function testSaveAssociatedHasManyValidation() {
5943
                $this->loadFixtures('Article', 'Comment');
5944
                $TestModel = new Article();
5945
                $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
5946
                $TestModel->Comment->validate = array('comment' => 'notBlank');
5947

    
5948
                $result = $TestModel->saveAssociated(array(
5949
                        'Article' => array('id' => 2),
5950
                        'Comment' => array(
5951
                                array('comment' => '', 'published' => 'Y', 'user_id' => 1),
5952
                        )
5953
                ), array('validate' => true));
5954
                $this->assertFalse($result);
5955

    
5956
                $expected = array('Comment' => array(
5957
                        array('comment' => array('This field cannot be left blank'))
5958
                ));
5959
                $this->assertEquals($expected, $TestModel->validationErrors);
5960
                $expected = array(
5961
                        array('comment' => array('This field cannot be left blank'))
5962
                );
5963
                $this->assertEquals($expected, $TestModel->Comment->validationErrors);
5964

    
5965
                $result = $TestModel->saveAssociated(array(
5966
                        'Article' => array('id' => 2),
5967
                        'Comment' => array(
5968
                                array(
5969
                                        'comment' => '',
5970
                                        'published' => 'Y',
5971
                                        'user_id' => 1
5972
                        ))
5973
                ), array('validate' => 'first'));
5974
                $this->assertFalse($result);
5975
        }
5976

    
5977
/**
5978
 * test saveMany with transactions and ensure there is no missing rollback.
5979
 *
5980
 * @return void
5981
 */
5982
        public function testSaveManyTransactionNoRollback() {
5983
                $this->loadFixtures('Post');
5984

    
5985
                $Post = new TestPost();
5986
                $Post->validate = array(
5987
                        'title' => array('rule' => array('notBlank'))
5988
                );
5989

    
5990
                // If validation error occurs, rollback() should be called.
5991
                $db = $this->_getMockDboSource(array('begin', 'commit', 'rollback'));
5992
                $db->expects($this->once())->method('begin')->will($this->returnValue(true));
5993
                $db->expects($this->never())->method('commit');
5994
                $db->expects($this->once())->method('rollback');
5995

    
5996
                $Post->setDataSourceObject($db);
5997

    
5998
                $data = array(
5999
                        array('author_id' => 1, 'title' => 'New Fourth Post'),
6000
                        array('author_id' => 1, 'title' => '')
6001
                );
6002
                $Post->saveMany($data, array('validate' => true));
6003

    
6004
                // If exception thrown, rollback() should be called too.
6005
                $db = $this->_getMockDboSource(array('begin', 'commit', 'rollback'));
6006
                $db->expects($this->once())->method('begin')->will($this->returnValue(true));
6007
                $db->expects($this->never())->method('commit');
6008
                $db->expects($this->once())->method('rollback');
6009

    
6010
                $Post->setDataSourceObject($db);
6011

    
6012
                $data = array(
6013
                        array('author_id' => 1, 'title' => 'New Fourth Post'),
6014
                        array('author_id' => 1, 'title' => 'New Fifth Post', 'body' => $db->expression('PDO_EXCEPTION()'))
6015
                );
6016

    
6017
                try {
6018
                        $Post->saveMany($data, array('validate' => true));
6019
                        $this->fail('No exception thrown');
6020
                } catch (PDOException $e) {
6021
                }
6022

    
6023
                // Otherwise, commit() should be called.
6024
                $db = $this->_getMockDboSource(array('begin', 'commit', 'rollback'));
6025
                $db->expects($this->once())->method('begin')->will($this->returnValue(true));
6026
                $db->expects($this->once())->method('commit');
6027
                $db->expects($this->never())->method('rollback');
6028

    
6029
                $Post->setDataSourceObject($db);
6030

    
6031
                $data = array(
6032
                        array('author_id' => 1, 'title' => 'New Fourth Post'),
6033
                        array('author_id' => 1, 'title' => 'New Fifth Post')
6034
                );
6035
                $Post->saveMany($data, array('validate' => true));
6036
        }
6037

    
6038
/**
6039
 * test saveAssociated with transactions and ensure there is no missing rollback.
6040
 *
6041
 * @return void
6042
 */
6043
        public function testSaveAssociatedTransactionNoRollback() {
6044
                $this->loadFixtures('Post', 'Author');
6045

    
6046
                $Post = new TestPost();
6047
                $Post->Author->validate = array(
6048
                        'user' => array('rule' => array('notBlank'))
6049
                );
6050

    
6051
                // If validation error occurs, rollback() should be called.
6052
                $db = $this->_getMockDboSource(array('begin', 'commit', 'rollback'));
6053
                $db->expects($this->once())->method('begin')->will($this->returnValue(true));
6054
                $db->expects($this->never())->method('commit');
6055
                $db->expects($this->once())->method('rollback');
6056

    
6057
                $Post->setDataSourceObject($db);
6058
                $Post->Author->setDataSourceObject($db);
6059

    
6060
                $data = array(
6061
                        'Post' => array(
6062
                                'title' => 'New post',
6063
                                'body' => 'Content',
6064
                                'published' => 'Y'
6065
                        ),
6066
                        'Author' => array(
6067
                                'user' => '',
6068
                                'password' => "sekret"
6069
                        )
6070
                );
6071
                $Post->saveAssociated($data, array('validate' => true, 'atomic' => true));
6072

    
6073
                // If exception thrown, commit() should be called.
6074
                $db = $this->_getMockDboSource(array('begin', 'commit', 'rollback'));
6075
                $db->expects($this->once())->method('begin')->will($this->returnValue(true));
6076
                $db->expects($this->never())->method('commit');
6077
                $db->expects($this->once())->method('rollback');
6078

    
6079
                $Post->setDataSourceObject($db);
6080
                $Post->Author->setDataSourceObject($db);
6081

    
6082
                $data = array(
6083
                        'Post' => array(
6084
                                'title' => 'New post',
6085
                                'body' => $db->expression('PDO_EXCEPTION()'),
6086
                                'published' => 'Y'
6087
                        ),
6088
                        'Author' => array(
6089
                                'user' => 'New user',
6090
                                'password' => "sekret"
6091
                        )
6092
                );
6093

    
6094
                try {
6095
                        $Post->saveAssociated($data, array('validate' => true, 'atomic' => true));
6096
                        $this->fail('No exception thrown');
6097
                } catch (PDOException $e) {
6098
                }
6099

    
6100
                // Otherwise, commit() should be called.
6101
                $db = $this->_getMockDboSource(array('begin', 'commit', 'rollback'));
6102
                $db->expects($this->once())->method('begin')->will($this->returnValue(true));
6103
                $db->expects($this->once())->method('commit');
6104
                $db->expects($this->never())->method('rollback');
6105

    
6106
                $Post->setDataSourceObject($db);
6107
                $Post->Author->setDataSourceObject($db);
6108

    
6109
                $data = array(
6110
                        'Post' => array(
6111
                                'title' => 'New post',
6112
                                'body' => 'Content',
6113
                                'published' => 'Y'
6114
                        ),
6115
                        'Author' => array(
6116
                                'user' => 'New user',
6117
                                'password' => "sekret"
6118
                        )
6119
                );
6120
                $Post->saveAssociated($data, array('validate' => true, 'atomic' => true));
6121
        }
6122

    
6123
/**
6124
 * test saveMany with nested saveMany call.
6125
 *
6126
 * @return void
6127
 */
6128
        public function testSaveManyNestedSaveMany() {
6129
                $this->loadFixtures('Sample');
6130
                $TransactionManyTestModel = new TransactionManyTestModel();
6131

    
6132
                $data = array(
6133
                        array('apple_id' => 1, 'name' => 'sample5'),
6134
                );
6135

    
6136
                $this->assertTrue($TransactionManyTestModel->saveMany($data, array('atomic' => true)));
6137
        }
6138

    
6139
/**
6140
 * testSaveManyTransaction method
6141
 *
6142
 * @return void
6143
 */
6144
        public function testSaveManyTransaction() {
6145
                $this->loadFixtures('Post', 'Author', 'Comment', 'Attachment');
6146
                $TestModel = new Post();
6147

    
6148
                $TestModel->validate = array('title' => 'notBlank');
6149
                $data = array(
6150
                        array('author_id' => 1, 'title' => 'New Fourth Post'),
6151
                        array('author_id' => 1, 'title' => 'New Fifth Post'),
6152
                        array('author_id' => 1, 'title' => '')
6153
                );
6154
                $this->assertFalse($TestModel->saveMany($data));
6155

    
6156
                $result = $TestModel->find('all', array('recursive' => -1));
6157
                $expected = array(
6158
                        array('Post' => array(
6159
                                'id' => '1',
6160
                                'author_id' => 1,
6161
                                'title' => 'First Post',
6162
                                'body' => 'First Post Body',
6163
                                'published' => 'Y',
6164
                                'created' => '2007-03-18 10:39:23',
6165
                                'updated' => '2007-03-18 10:41:31'
6166
                        )),
6167
                        array('Post' => array(
6168
                                'id' => '2',
6169
                                'author_id' => 3,
6170
                                'title' => 'Second Post',
6171
                                'body' => 'Second Post Body',
6172
                                'published' => 'Y',
6173
                                'created' => '2007-03-18 10:41:23',
6174
                                'updated' => '2007-03-18 10:43:31'
6175
                        )),
6176
                        array('Post' => array(
6177
                                'id' => '3',
6178
                                'author_id' => 1,
6179
                                'title' => 'Third Post',
6180
                                'body' => 'Third Post Body',
6181
                                'published' => 'Y',
6182
                                'created' => '2007-03-18 10:43:23',
6183
                                'updated' => '2007-03-18 10:45:31'
6184
                )));
6185

    
6186
                if (count($result) != 3) {
6187
                        // Database doesn't support transactions
6188
                        $expected[] = array(
6189
                                'Post' => array(
6190
                                        'id' => '4',
6191
                                        'author_id' => 1,
6192
                                        'title' => 'New Fourth Post',
6193
                                        'body' => null,
6194
                                        'published' => 'N'
6195
                        ));
6196

    
6197
                        $expected[] = array(
6198
                                'Post' => array(
6199
                                        'id' => '5',
6200
                                        'author_id' => 1,
6201
                                        'title' => 'New Fifth Post',
6202
                                        'body' => null,
6203
                                        'published' => 'N',
6204
                        ));
6205

    
6206
                        $this->assertEquals(static::date(), $result[3]['Post']['created']);
6207
                        $this->assertEquals(static::date(), $result[3]['Post']['updated']);
6208
                        $this->assertEquals(static::date(), $result[4]['Post']['created']);
6209
                        $this->assertEquals(static::date(), $result[4]['Post']['updated']);
6210
                        unset($result[3]['Post']['created'], $result[3]['Post']['updated']);
6211
                        unset($result[4]['Post']['created'], $result[4]['Post']['updated']);
6212
                        $this->assertEquals($expected, $result);
6213
                        // Skip the rest of the transactional tests
6214
                        return;
6215
                }
6216

    
6217
                $this->assertEquals($expected, $result);
6218

    
6219
                $data = array(
6220
                        array('author_id' => 1, 'title' => 'New Fourth Post'),
6221
                        array('author_id' => 1, 'title' => ''),
6222
                        array('author_id' => 1, 'title' => 'New Sixth Post')
6223
                );
6224
                $this->assertFalse($TestModel->saveMany($data));
6225

    
6226
                $result = $TestModel->find('all', array('recursive' => -1));
6227
                $expected = array(
6228
                        array('Post' => array(
6229
                                'id' => '1',
6230
                                'author_id' => 1,
6231
                                'title' => 'First Post',
6232
                                'body' => 'First Post Body',
6233
                                'published' => 'Y',
6234
                                'created' => '2007-03-18 10:39:23',
6235
                                'updated' => '2007-03-18 10:41:31'
6236
                        )),
6237
                        array('Post' => array(
6238
                                'id' => '2',
6239
                                'author_id' => 3,
6240
                                'title' => 'Second Post',
6241
                                'body' => 'Second Post Body',
6242
                                'published' => 'Y',
6243
                                'created' => '2007-03-18 10:41:23',
6244
                                'updated' => '2007-03-18 10:43:31'
6245
                        )),
6246
                        array('Post' => array(
6247
                                'id' => '3',
6248
                                'author_id' => 1,
6249
                                'title' => 'Third Post',
6250
                                'body' => 'Third Post Body',
6251
                                'published' => 'Y',
6252
                                'created' => '2007-03-18 10:43:23',
6253
                                'updated' => '2007-03-18 10:45:31'
6254
                )));
6255

    
6256
                if (count($result) != 3) {
6257
                        // Database doesn't support transactions
6258
                        $expected[] = array(
6259
                                'Post' => array(
6260
                                        'id' => '4',
6261
                                        'author_id' => 1,
6262
                                        'title' => 'New Fourth Post',
6263
                                        'body' => 'Third Post Body',
6264
                                        'published' => 'N'
6265
                        ));
6266

    
6267
                        $expected[] = array(
6268
                                'Post' => array(
6269
                                        'id' => '5',
6270
                                        'author_id' => 1,
6271
                                        'title' => 'Third Post',
6272
                                        'body' => 'Third Post Body',
6273
                                        'published' => 'N'
6274
                        ));
6275
                        $this->assertEquals(static::date(), $result[3]['Post']['created']);
6276
                        $this->assertEquals(static::date(), $result[3]['Post']['updated']);
6277
                        $this->assertEquals(static::date(), $result[4]['Post']['created']);
6278
                        $this->assertEquals(static::date(), $result[4]['Post']['updated']);
6279
                        unset($result[3]['Post']['created'], $result[3]['Post']['updated']);
6280
                        unset($result[4]['Post']['created'], $result[4]['Post']['updated']);
6281
                }
6282
                $this->assertEquals($expected, $result);
6283

    
6284
                $TestModel->validate = array('title' => 'notBlank');
6285
                $data = array(
6286
                        array('author_id' => 1, 'title' => 'New Fourth Post'),
6287
                        array('author_id' => 1, 'title' => 'New Fifth Post'),
6288
                        array('author_id' => 1, 'title' => 'New Sixth Post')
6289
                );
6290
                $this->assertTrue($TestModel->saveMany($data));
6291

    
6292
                $result = $TestModel->find('all', array(
6293
                        'recursive' => -1,
6294
                        'fields' => array('author_id', 'title', 'body', 'published'),
6295
                        'order' => array('Post.created' => 'ASC')
6296
                ));
6297

    
6298
                $expected = array(
6299
                        array('Post' => array(
6300
                                'author_id' => 1,
6301
                                'title' => 'First Post',
6302
                                'body' => 'First Post Body',
6303
                                'published' => 'Y'
6304
                        )),
6305
                        array('Post' => array(
6306
                                'author_id' => 3,
6307
                                'title' => 'Second Post',
6308
                                'body' => 'Second Post Body',
6309
                                'published' => 'Y'
6310
                        )),
6311
                        array('Post' => array(
6312
                                'author_id' => 1,
6313
                                'title' => 'Third Post',
6314
                                'body' => 'Third Post Body',
6315
                                'published' => 'Y'
6316
                        )),
6317
                        array('Post' => array(
6318
                                'author_id' => 1,
6319
                                'title' => 'New Fourth Post',
6320
                                'body' => '',
6321
                                'published' => 'N'
6322
                        )),
6323
                        array('Post' => array(
6324
                                'author_id' => 1,
6325
                                'title' => 'New Fifth Post',
6326
                                'body' => '',
6327
                                'published' => 'N'
6328
                        )),
6329
                        array('Post' => array(
6330
                                'author_id' => 1,
6331
                                'title' => 'New Sixth Post',
6332
                                'body' => '',
6333
                                'published' => 'N'
6334
                )));
6335
                $this->assertEquals($expected, $result);
6336
        }
6337

    
6338
/**
6339
 * testSaveManyValidation method
6340
 *
6341
 * @return void
6342
 */
6343
        public function testSaveManyValidation() {
6344
                $this->loadFixtures('Post', 'Author', 'Comment', 'Attachment');
6345
                $TestModel = new Post();
6346

    
6347
                $data = array(
6348
                        array(
6349
                                'id' => '1',
6350
                                'title' => 'Baleeted First Post',
6351
                                'body' => 'Baleeted!',
6352
                                'published' => 'N'
6353
                        ),
6354
                        array(
6355
                                'id' => '2',
6356
                                'title' => 'Just update the title'
6357
                        ),
6358
                        array(
6359
                                'title' => 'Creating a fourth post',
6360
                                'body' => 'Fourth post body',
6361
                                'author_id' => 2
6362
                ));
6363

    
6364
                $this->assertTrue($TestModel->saveMany($data));
6365

    
6366
                $result = $TestModel->find('all', array('recursive' => -1, 'order' => 'Post.id ASC'));
6367
                $expected = array(
6368
                        array(
6369
                                'Post' => array(
6370
                                        'id' => '1',
6371
                                        'author_id' => '1',
6372
                                        'title' => 'Baleeted First Post',
6373
                                        'body' => 'Baleeted!',
6374
                                        'published' => 'N',
6375
                                        'created' => '2007-03-18 10:39:23'
6376
                                )
6377
                        ),
6378
                        array(
6379
                                'Post' => array(
6380
                                        'id' => '2',
6381
                                        'author_id' => '3',
6382
                                        'title' => 'Just update the title',
6383
                                        'body' => 'Second Post Body',
6384
                                        'published' => 'Y',
6385
                                        'created' => '2007-03-18 10:41:23'
6386
                                )
6387
                        ),
6388
                        array(
6389
                                'Post' => array(
6390
                                        'id' => '3',
6391
                                        'author_id' => '1',
6392
                                        'title' => 'Third Post',
6393
                                        'body' => 'Third Post Body',
6394
                                        'published' => 'Y',
6395
                                        'created' => '2007-03-18 10:43:23',
6396
                                        'updated' => '2007-03-18 10:45:31'
6397
                        )),
6398
                        array(
6399
                                'Post' => array(
6400
                                        'id' => '4',
6401
                                        'author_id' => '2',
6402
                                        'title' => 'Creating a fourth post',
6403
                                        'body' => 'Fourth post body',
6404
                                        'published' => 'N'
6405
                                )
6406
                        )
6407
                );
6408

    
6409
                $this->assertEquals(static::date(), $result[0]['Post']['updated']);
6410
                $this->assertEquals(static::date(), $result[1]['Post']['updated']);
6411
                $this->assertEquals(static::date(), $result[3]['Post']['created']);
6412
                $this->assertEquals(static::date(), $result[3]['Post']['updated']);
6413
                unset($result[0]['Post']['updated'], $result[1]['Post']['updated']);
6414
                unset($result[3]['Post']['created'], $result[3]['Post']['updated']);
6415
                $this->assertEquals($expected, $result);
6416

    
6417
                $TestModel->validate = array('title' => 'notBlank', 'author_id' => 'numeric');
6418
                $data = array(
6419
                        array(
6420
                                'id' => '1',
6421
                                'title' => 'Un-Baleeted First Post',
6422
                                'body' => 'Not Baleeted!',
6423
                                'published' => 'Y'
6424
                        ),
6425
                        array(
6426
                                'id' => '2',
6427
                                'title' => '',
6428
                                'body' => 'Trying to get away with an empty title'
6429
                ));
6430
                $result = $TestModel->saveMany($data);
6431
                $this->assertFalse($result);
6432

    
6433
                $result = $TestModel->find('all', array('recursive' => -1, 'order' => 'Post.id ASC'));
6434
                $errors = array(1 => array('title' => array('This field cannot be left blank')));
6435
                $transactionWorked = Set::matches('/Post[1][title=Baleeted First Post]', $result);
6436
                if (!$transactionWorked) {
6437
                        $this->assertTrue(Set::matches('/Post[1][title=Un-Baleeted First Post]', $result));
6438
                        $this->assertTrue(Set::matches('/Post[2][title=Just update the title]', $result));
6439
                }
6440

    
6441
                $this->assertEquals($errors, $TestModel->validationErrors);
6442

    
6443
                $TestModel->validate = array('title' => 'notBlank', 'author_id' => 'numeric');
6444
                $data = array(
6445
                        array(
6446
                                'id' => '1',
6447
                                'title' => 'Un-Baleeted First Post',
6448
                                'body' => 'Not Baleeted!',
6449
                                'published' => 'Y'
6450
                        ),
6451
                        array(
6452
                                'id' => '2',
6453
                                'title' => '',
6454
                                'body' => 'Trying to get away with an empty title'
6455
                ));
6456
                $result = $TestModel->saveMany($data, array('validate' => true, 'atomic' => false));
6457
                $this->assertEquals(array(true, false), $result);
6458

    
6459
                $result = $TestModel->find('all', array(
6460
                        'fields' => array('id', 'author_id', 'title', 'body', 'published'),
6461
                        'recursive' => -1,
6462
                        'order' => 'Post.id ASC'
6463
                ));
6464
                $errors = array(1 => array('title' => array('This field cannot be left blank')));
6465
                $expected = array(
6466
                        array(
6467
                                'Post' => array(
6468
                                        'id' => '1',
6469
                                        'author_id' => '1',
6470
                                        'title' => 'Un-Baleeted First Post',
6471
                                        'body' => 'Not Baleeted!',
6472
                                        'published' => 'Y',
6473
                        )),
6474
                        array(
6475
                                'Post' => array(
6476
                                        'id' => '2',
6477
                                        'author_id' => '3',
6478
                                        'title' => 'Just update the title',
6479
                                        'body' => 'Second Post Body',
6480
                                        'published' => 'Y',
6481
                        )),
6482
                        array(
6483
                                'Post' => array(
6484
                                        'id' => '3',
6485
                                        'author_id' => '1',
6486
                                        'title' => 'Third Post',
6487
                                        'body' => 'Third Post Body',
6488
                                        'published' => 'Y',
6489
                        )),
6490
                        array(
6491
                                'Post' => array(
6492
                                        'id' => '4',
6493
                                        'author_id' => '2',
6494
                                        'title' => 'Creating a fourth post',
6495
                                        'body' => 'Fourth post body',
6496
                                        'published' => 'N',
6497
                )));
6498
                $this->assertEquals($expected, $result);
6499
                $this->assertEquals($errors, $TestModel->validationErrors);
6500

    
6501
                $data = array(
6502
                        array(
6503
                                'id' => '1',
6504
                                'title' => 'Re-Baleeted First Post',
6505
                                'body' => 'Baleeted!',
6506
                                'published' => 'N'
6507
                        ),
6508
                        array(
6509
                                'id' => '2',
6510
                                'title' => '',
6511
                                'body' => 'Trying to get away with an empty title'
6512
                ));
6513
                $this->assertFalse($TestModel->saveMany($data, array('validate' => 'first')));
6514

    
6515
                $result = $TestModel->find('all', array(
6516
                        'fields' => array('id', 'author_id', 'title', 'body', 'published'),
6517
                        'recursive' => -1,
6518
                        'order' => 'Post.id ASC'
6519
                ));
6520
                $this->assertEquals($expected, $result);
6521
                $this->assertEquals($errors, $TestModel->validationErrors);
6522
        }
6523

    
6524
/**
6525
 * testValidateMany method
6526
 *
6527
 * @return void
6528
 */
6529
        public function testValidateMany() {
6530
                $TestModel = new Article();
6531
                $TestModel->validate = array('title' => 'notBlank');
6532
                $data = array(
6533
                                0 => array('title' => ''),
6534
                                1 => array('title' => 'title 1'),
6535
                                2 => array('title' => 'title 2'),
6536
                );
6537
                $result = $TestModel->validateMany($data);
6538
                $this->assertFalse($result);
6539
                $expected = array(
6540
                        0 => array('title' => array('This field cannot be left blank')),
6541
                );
6542
                $this->assertEquals($expected, $TestModel->validationErrors);
6543

    
6544
                $data = array(
6545
                                0 => array('title' => 'title 0'),
6546
                                1 => array('title' => ''),
6547
                                2 => array('title' => 'title 2'),
6548
                );
6549
                $result = $TestModel->validateMany($data);
6550
                $this->assertFalse($result);
6551
                $expected = array(
6552
                        1 => array('title' => array('This field cannot be left blank')),
6553
                );
6554
                $this->assertEquals($expected, $TestModel->validationErrors);
6555
        }
6556

    
6557
/**
6558
 * testSaveAssociatedValidateFirst method
6559
 *
6560
 * @return void
6561
 */
6562
        public function testSaveAssociatedValidateFirst() {
6563
                $this->loadFixtures('Article', 'Comment', 'Attachment');
6564
                $model = new Article();
6565
                $model->deleteAll(true);
6566

    
6567
                $model->Comment->validate = array('comment' => 'notBlank');
6568
                $result = $model->saveAssociated(array(
6569
                        'Article' => array(
6570
                                'title' => 'Post with Author',
6571
                                'body' => 'This post will be saved author'
6572
                        ),
6573
                        'Comment' => array(
6574
                                array('comment' => 'First new comment'),
6575
                                array('comment' => '')
6576
                        )
6577
                ), array('validate' => 'first'));
6578

    
6579
                $this->assertFalse($result);
6580

    
6581
                $result = $model->find('all');
6582
                $this->assertSame(array(), $result);
6583
                $expected = array('Comment' => array(
6584
                        1 => array('comment' => array('This field cannot be left blank'))
6585
                ));
6586

    
6587
                $this->assertEquals($expected['Comment'], $model->Comment->validationErrors);
6588

    
6589
                $this->assertSame($model->Comment->find('count'), 0);
6590

    
6591
                $result = $model->saveAssociated(
6592
                        array(
6593
                                'Article' => array(
6594
                                        'title' => 'Post with Author',
6595
                                        'body' => 'This post will be saved with an author',
6596
                                        'user_id' => 2
6597
                                ),
6598
                                'Comment' => array(
6599
                                        array(
6600
                                                'comment' => 'Only new comment',
6601
                                                'user_id' => 2
6602
                        ))),
6603
                        array('validate' => 'first')
6604
                );
6605

    
6606
                $this->assertTrue($result);
6607

    
6608
                $result = $model->Comment->find('all');
6609
                $this->assertSame(count($result), 1);
6610
                $result = Hash::extract($result, '{n}.Comment.article_id');
6611
                $this->assertEquals(4, $result[0]);
6612

    
6613
                $model->deleteAll(true);
6614
                $data = array(
6615
                        'Article' => array(
6616
                                'title' => 'Post with Author saveAlled from comment',
6617
                                'body' => 'This post will be saved with an author',
6618
                                'user_id' => 2
6619
                        ),
6620
                        'Comment' => array(
6621
                                'comment' => 'Only new comment', 'user_id' => 2
6622
                ));
6623

    
6624
                $result = $model->Comment->saveAssociated($data, array('validate' => 'first'));
6625
                $this->assertFalse(empty($result));
6626

    
6627
                $result = $model->find('all');
6628
                $this->assertEquals(
6629
                        'Post with Author saveAlled from comment',
6630
                        $result[0]['Article']['title']
6631
                );
6632
                $this->assertEquals('Only new comment', $result[0]['Comment'][0]['comment']);
6633
        }
6634

    
6635
/**
6636
 * test saveMany()'s return is correct when using atomic = false and validate = first.
6637
 *
6638
 * @return void
6639
 */
6640
        public function testSaveManyValidateFirstAtomicFalse() {
6641
                $Something = new Something();
6642
                $invalidData = array(
6643
                        array(
6644
                                'title' => 'foo',
6645
                                'body' => 'bar',
6646
                                'published' => 'baz',
6647
                        ),
6648
                        array(
6649
                                'body' => 3,
6650
                                'published' => 'sd',
6651
                        ),
6652
                );
6653
                $Something->create();
6654
                $Something->validate = array(
6655
                        'title' => array(
6656
                                'rule' => 'alphaNumeric',
6657
                                'required' => true,
6658
                        ),
6659
                        'body' => array(
6660
                                'rule' => 'alphaNumeric',
6661
                                'required' => true,
6662
                                'allowEmpty' => true,
6663
                        ),
6664
                );
6665
                $result = $Something->saveMany($invalidData, array(
6666
                        'atomic' => false,
6667
                        'validate' => 'first',
6668
                ));
6669
                $expected = array(true, false);
6670
                $this->assertEquals($expected, $result);
6671

    
6672
                $Something = new Something();
6673
                $validData = array(
6674
                        array(
6675
                                'title' => 'title value',
6676
                                'body' => 'body value',
6677
                                'published' => 'baz',
6678
                        ),
6679
                        array(
6680
                                'title' => 'valid',
6681
                                'body' => 'this body',
6682
                                'published' => 'sd',
6683
                        ),
6684
                );
6685
                $Something->create();
6686
                $result = $Something->saveMany($validData, array(
6687
                        'atomic' => false,
6688
                        'validate' => 'first',
6689
                ));
6690
                $expected = array(true, true);
6691
                $this->assertEquals($expected, $result);
6692
        }
6693

    
6694
/**
6695
 * testValidateAssociated method
6696
 *
6697
 * @return void
6698
 */
6699
        public function testValidateAssociated() {
6700
                $this->loadFixtures('Attachment', 'Article', 'Comment');
6701
                $TestModel = new Comment();
6702
                $TestModel->Attachment->validate = array('attachment' => 'notBlank');
6703

    
6704
                $data = array(
6705
                        'Comment' => array(
6706
                                'comment' => 'This is the comment'
6707
                        ),
6708
                        'Attachment' => array(
6709
                                'attachment' => ''
6710
                        )
6711
                );
6712

    
6713
                $result = $TestModel->validateAssociated($data);
6714
                $this->assertFalse($result);
6715

    
6716
                $TestModel = new Article();
6717
                $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
6718
                $TestModel->Comment->validate = array('comment' => 'notBlank');
6719

    
6720
                $data = array(
6721
                        'Article' => array('id' => 2),
6722
                        'Comment' => array(
6723
                                array(
6724
                                        'id' => 1,
6725
                                        'comment' => '',
6726
                                        'published' => 'Y',
6727
                                        'user_id' => 1),
6728
                                array(
6729
                                        'id' => 2,
6730
                                        'comment' =>
6731
                                        'comment',
6732
                                        'published' => 'Y',
6733
                                        'user_id' => 1
6734
                )));
6735
                $result = $TestModel->validateAssociated($data);
6736
                $this->assertFalse($result);
6737

    
6738
                $data = array(
6739
                        'Article' => array('id' => 2),
6740
                        'Comment' => array(
6741
                                array(
6742
                                        'id' => 1,
6743
                                        'comment' => '',
6744
                                        'published' => 'Y',
6745
                                        'user_id' => 1
6746
                                ),
6747
                                array(
6748
                                        'id' => 2,
6749
                                        'comment' => 'comment',
6750
                                        'published' => 'Y',
6751
                                        'user_id' => 1
6752
                                ),
6753
                                array(
6754
                                        'id' => 3,
6755
                                        'comment' => '',
6756
                                        'published' => 'Y',
6757
                                        'user_id' => 1
6758
                )));
6759
                $result = $TestModel->validateAssociated($data, array(
6760
                                'atomic' => false
6761
                ));
6762
                $expected = array(
6763
                        'Article' => true,
6764
                        'Comment' => array(false, true, false)
6765
                );
6766
                $this->assertSame($expected, $result);
6767

    
6768
                $expected = array('Comment' => array(
6769
                        0 => array('comment' => array('This field cannot be left blank')),
6770
                        2 => array('comment' => array('This field cannot be left blank'))
6771
                ));
6772
                $this->assertEquals($expected, $TestModel->validationErrors);
6773

    
6774
                $expected = array(
6775
                        0 => array('comment' => array('This field cannot be left blank')),
6776
                        2 => array('comment' => array('This field cannot be left blank'))
6777
                );
6778
                $this->assertEquals($expected, $TestModel->Comment->validationErrors);
6779
        }
6780

    
6781
/**
6782
 * test that saveMany behaves like plain save() when suplied empty data
6783
 *
6784
 * @link https://cakephp.lighthouseapp.com/projects/42648/tickets/277-test-saveall-with-validation-returns-incorrect-boolean-when-saving-empty-data
6785
 * @return void
6786
 */
6787
        public function testSaveManyEmptyData() {
6788
                $this->skipIf($this->db instanceof Sqlserver, 'This test is not compatible with SQL Server.');
6789

    
6790
                $this->loadFixtures('Article', 'ProductUpdateAll', 'Comment', 'Attachment');
6791
                $model = new Article();
6792
                $result = $model->saveMany(array(), array('validate' => true));
6793
                $this->assertFalse(empty($result));
6794

    
6795
                $model = new ProductUpdateAll();
6796
                $result = $model->saveMany(array());
6797
                $this->assertFalse($result);
6798
        }
6799

    
6800
/**
6801
 * test that saveAssociated behaves like plain save() when supplied empty data
6802
 *
6803
 * @link https://cakephp.lighthouseapp.com/projects/42648/tickets/277-test-saveall-with-validation-returns-incorrect-boolean-when-saving-empty-data
6804
 * @return void
6805
 */
6806
        public function testSaveAssociatedEmptyData() {
6807
                $this->skipIf($this->db instanceof Sqlserver, 'This test is not compatible with SQL Server.');
6808

    
6809
                $this->loadFixtures('Article', 'ProductUpdateAll', 'Comment', 'Attachment');
6810
                $model = new Article();
6811
                $result = $model->saveAssociated(array(), array('validate' => true));
6812
                $this->assertFalse(empty($result));
6813

    
6814
                $model = new ProductUpdateAll();
6815
                $result = $model->saveAssociated(array());
6816
                $this->assertFalse($result);
6817
        }
6818

    
6819
/**
6820
 * Test that saveAssociated will accept expression object values when saving.
6821
 *
6822
 * @return void
6823
 */
6824
        public function testSaveAssociatedExpressionObjects() {
6825
                $this->loadFixtures('Post', 'Author', 'Comment', 'Attachment', 'Article', 'User');
6826
                $TestModel = new Post();
6827
                $db = $TestModel->getDataSource();
6828

    
6829
                $TestModel->saveAssociated(array(
6830
                        'Post' => array(
6831
                                'title' => $db->expression("(SELECT 'Post with Author')"),
6832
                                'body' => 'This post will be saved with an author'
6833
                        ),
6834
                        'Author' => array(
6835
                                'user' => 'bob',
6836
                                'password' => '5f4dcc3b5aa765d61d8327deb882cf90'
6837
                )), array('atomic' => false));
6838

    
6839
                $result = $TestModel->find('first', array(
6840
                        'order' => array('Post.id ' => 'DESC')
6841
                ));
6842
                $this->assertEquals('Post with Author', $result['Post']['title']);
6843
        }
6844

    
6845
/**
6846
 * testUpdateWithCalculation method
6847
 *
6848
 * @return void
6849
 */
6850
        public function testUpdateWithCalculation() {
6851
                $this->loadFixtures('DataTest');
6852
                $model = new DataTest();
6853
                $model->deleteAll(true);
6854
                $result = $model->saveMany(array(
6855
                        array('count' => 5, 'float' => 1.1),
6856
                        array('count' => 3, 'float' => 1.2),
6857
                        array('count' => 4, 'float' => 1.3),
6858
                        array('count' => 1, 'float' => 2.0),
6859
                ));
6860
                $this->assertFalse(empty($result));
6861

    
6862
                $result = Hash::extract($model->find('all', array('fields' => 'count')), '{n}.DataTest.count');
6863
                $this->assertEquals(array(5, 3, 4, 1), $result);
6864

    
6865
                $this->assertTrue($model->updateAll(array('count' => 'count + 2')));
6866
                $result = Hash::extract($model->find('all', array('fields' => 'count')), '{n}.DataTest.count');
6867
                $this->assertEquals(array(7, 5, 6, 3), $result);
6868

    
6869
                $this->assertTrue($model->updateAll(array('DataTest.count' => 'DataTest.count - 1')));
6870
                $result = Hash::extract($model->find('all', array('fields' => 'count')), '{n}.DataTest.count');
6871
                $this->assertEquals(array(6, 4, 5, 2), $result);
6872
        }
6873

    
6874
/**
6875
 * testToggleBoolFields method
6876
 *
6877
 * @return void
6878
 */
6879
        public function testToggleBoolFields() {
6880
                $this->loadFixtures('CounterCacheUser', 'CounterCachePost');
6881
                $Post = new CounterCachePost();
6882
                $Post->unbindModel(array('belongsTo' => array('User')), true);
6883

    
6884
                $true = array('Post' => array('published' => true, 'id' => 2));
6885
                $false = array('Post' => array('published' => false, 'id' => 2));
6886
                $fields = array('Post.published', 'Post.id');
6887
                $updateConditions = array('Post.id' => 2);
6888

    
6889
                // check its true
6890
                $result = $Post->find('first', array('conditions' => $updateConditions, 'fields' => $fields));
6891
                $this->assertEquals($true, $result);
6892

    
6893
                // Testing without the alias
6894
                $this->assertTrue($Post->updateAll(array('published' => 'NOT published'), $updateConditions));
6895
                $result = $Post->find('first', array('conditions' => $updateConditions, 'fields' => $fields));
6896
                $this->assertEquals($false, $result);
6897

    
6898
                $this->assertTrue($Post->updateAll(array('published' => 'NOT published'), $updateConditions));
6899
                $result = $Post->find('first', array('conditions' => $updateConditions, 'fields' => $fields));
6900
                $this->assertEquals($true, $result);
6901

    
6902
                $db = ConnectionManager::getDataSource('test');
6903
                $alias = $db->name('Post.published');
6904

    
6905
                // Testing with the alias
6906
                $this->assertTrue($Post->updateAll(array('Post.published' => "NOT $alias"), $updateConditions));
6907
                $result = $Post->find('first', array('conditions' => $updateConditions, 'fields' => $fields));
6908
                $this->assertEquals($false, $result);
6909

    
6910
                $this->assertTrue($Post->updateAll(array('Post.published' => "NOT $alias"), $updateConditions));
6911
                $result = $Post->find('first', array('conditions' => $updateConditions, 'fields' => $fields));
6912
                $this->assertEquals($true, $result);
6913
        }
6914

    
6915
/**
6916
 * TestFindAllWithoutForeignKey
6917
 *
6918
 * @return void
6919
 */
6920
        public function testFindAllForeignKey() {
6921
                $this->loadFixtures('ProductUpdateAll', 'GroupUpdateAll');
6922
                $ProductUpdateAll = new ProductUpdateAll();
6923

    
6924
                $conditions = array('Group.name' => 'group one');
6925

    
6926
                $ProductUpdateAll->bindModel(array(
6927
                        'belongsTo' => array(
6928
                                'Group' => array('className' => 'GroupUpdateAll')
6929
                        )
6930
                ));
6931

    
6932
                $ProductUpdateAll->belongsTo = array(
6933
                        'Group' => array('className' => 'GroupUpdateAll', 'foreignKey' => 'group_id')
6934
                );
6935

    
6936
                $results = $ProductUpdateAll->find('all', compact('conditions'));
6937
                $this->assertTrue(!empty($results));
6938

    
6939
                $ProductUpdateAll->bindModel(array('belongsTo' => array('Group')));
6940
                $ProductUpdateAll->belongsTo = array(
6941
                        'Group' => array(
6942
                                'className' => 'GroupUpdateAll',
6943
                                'foreignKey' => false,
6944
                                'conditions' => 'ProductUpdateAll.groupcode = Group.code'
6945
                        ));
6946

    
6947
                $resultsFkFalse = $ProductUpdateAll->find('all', compact('conditions'));
6948
                $this->assertTrue(!empty($resultsFkFalse));
6949
                $expected = array(
6950
                        '0' => array(
6951
                                'ProductUpdateAll' => array(
6952
                                        'id' => 1,
6953
                                        'name'        => 'product one',
6954
                                        'groupcode' => 120,
6955
                                        'group_id' => 1),
6956
                                'Group' => array(
6957
                                        'id' => 1,
6958
                                        'name' => 'group one',
6959
                                        'code' => 120)
6960
                                ),
6961
                        '1' => array(
6962
                                'ProductUpdateAll' => array(
6963
                                        'id' => 2,
6964
                                        'name'        => 'product two',
6965
                                        'groupcode'        => 120,
6966
                                        'group_id'        => 1),
6967
                                'Group' => array(
6968
                                        'id' => 1,
6969
                                        'name' => 'group one',
6970
                                        'code' => 120)
6971
                                )
6972

    
6973
                        );
6974
                $this->assertEquals($expected, $results);
6975
                $this->assertEquals($expected, $resultsFkFalse);
6976
        }
6977

    
6978
/**
6979
 * test updateAll with empty values.
6980
 *
6981
 * @return void
6982
 */
6983
        public function testUpdateAllEmptyValues() {
6984
                $this->skipIf($this->db instanceof Sqlserver || $this->db instanceof Postgres, 'This test is not compatible with Postgres or SQL Server.');
6985

    
6986
                $this->loadFixtures('Author', 'Post');
6987
                $model = new Author();
6988
                $result = $model->updateAll(array('user' => '""'));
6989
                $this->assertTrue($result);
6990
        }
6991

    
6992
/**
6993
 * testUpdateAllWithJoins
6994
 *
6995
 * @return void
6996
 */
6997
        public function testUpdateAllWithJoins() {
6998
                $this->skipIf(!$this->db instanceof Mysql, 'Currently, there is no way of doing joins in an update statement in postgresql or sqlite');
6999

    
7000
                $this->loadFixtures('ProductUpdateAll', 'GroupUpdateAll');
7001
                $ProductUpdateAll = new ProductUpdateAll();
7002

    
7003
                $conditions = array('Group.name' => 'group one');
7004

    
7005
                $ProductUpdateAll->bindModel(array('belongsTo' => array(
7006
                        'Group' => array('className' => 'GroupUpdateAll')))
7007
                );
7008

    
7009
                $ProductUpdateAll->updateAll(array('name' => "'new product'"), $conditions);
7010
                $results = $ProductUpdateAll->find('all', array(
7011
                        'conditions' => array('ProductUpdateAll.name' => 'new product')
7012
                ));
7013
                $expected = array(
7014
                        '0' => array(
7015
                                'ProductUpdateAll' => array(
7016
                                        'id' => 1,
7017
                                        'name' => 'new product',
7018
                                        'groupcode'        => 120,
7019
                                        'group_id' => 1),
7020
                                'Group' => array(
7021
                                        'id' => 1,
7022
                                        'name' => 'group one',
7023
                                        'code' => 120)
7024
                                ),
7025
                        '1' => array(
7026
                                'ProductUpdateAll' => array(
7027
                                        'id' => 2,
7028
                                        'name' => 'new product',
7029
                                        'groupcode' => 120,
7030
                                        'group_id' => 1),
7031
                                'Group' => array(
7032
                                        'id' => 1,
7033
                                        'name' => 'group one',
7034
                                        'code' => 120)));
7035

    
7036
                $this->assertEquals($expected, $results);
7037
        }
7038

    
7039
/**
7040
 * testUpdateAllWithoutForeignKey
7041
 *
7042
 * @return void
7043
 */
7044
        public function testUpdateAllWithoutForeignKey() {
7045
                $this->skipIf(!$this->db instanceof Mysql, 'Currently, there is no way of doing joins in an update statement in postgresql');
7046

    
7047
                $this->loadFixtures('ProductUpdateAll', 'GroupUpdateAll');
7048
                $ProductUpdateAll = new ProductUpdateAll();
7049

    
7050
                $conditions = array('Group.name' => 'group one');
7051

    
7052
                $ProductUpdateAll->bindModel(array('belongsTo' => array(
7053
                        'Group' => array('className' => 'GroupUpdateAll')
7054
                )));
7055

    
7056
                $ProductUpdateAll->belongsTo = array(
7057
                        'Group' => array(
7058
                                'className' => 'GroupUpdateAll',
7059
                                'foreignKey' => false,
7060
                                'conditions' => 'ProductUpdateAll.groupcode = Group.code'
7061
                        )
7062
                );
7063

    
7064
                $ProductUpdateAll->updateAll(array('name' => "'new product'"), $conditions);
7065
                $resultsFkFalse = $ProductUpdateAll->find('all', array('conditions' => array('ProductUpdateAll.name' => 'new product')));
7066
                $expected = array(
7067
                        '0' => array(
7068
                                'ProductUpdateAll' => array(
7069
                                        'id' => 1,
7070
                                        'name' => 'new product',
7071
                                        'groupcode'        => 120,
7072
                                        'group_id' => 1),
7073
                                'Group' => array(
7074
                                        'id' => 1,
7075
                                        'name' => 'group one',
7076
                                        'code' => 120)
7077
                                ),
7078
                        '1' => array(
7079
                                'ProductUpdateAll' => array(
7080
                                        'id' => 2,
7081
                                        'name' => 'new product',
7082
                                        'groupcode' => 120,
7083
                                        'group_id' => 1),
7084
                                'Group' => array(
7085
                                        'id' => 1,
7086
                                        'name' => 'group one',
7087
                                        'code' => 120)));
7088
                $this->assertEquals($expected, $resultsFkFalse);
7089
        }
7090

    
7091
/**
7092
 * test writing floats in german locale.
7093
 *
7094
 * @return void
7095
 */
7096
        public function testWriteFloatAsGerman() {
7097
                $restore = setlocale(LC_NUMERIC, 0);
7098

    
7099
                $this->skipIf(setlocale(LC_NUMERIC, 'de_DE') === false, "The German locale isn't available.");
7100

    
7101
                $model = new DataTest();
7102
                $result = $model->save(array(
7103
                        'count' => 1,
7104
                        'float' => 3.14593
7105
                ));
7106
                $this->assertTrue((bool)$result);
7107
                setlocale(LC_NUMERIC, $restore);
7108
        }
7109

    
7110
/**
7111
 * Test returned array contains primary key when save creates a new record
7112
 *
7113
 * @return void
7114
 */
7115
        public function testPkInReturnArrayForCreate() {
7116
                $this->loadFixtures('Article');
7117
                $TestModel = new Article();
7118

    
7119
                $data = array('Article' => array(
7120
                        'user_id' => '1',
7121
                        'title' => 'Fourth Article',
7122
                        'body' => 'Fourth Article Body',
7123
                        'published' => 'Y'
7124
                ));
7125
                $result = $TestModel->save($data);
7126
                $this->assertSame($result['Article']['id'], $TestModel->id);
7127
        }
7128

    
7129
/**
7130
 * testSaveAllFieldListValidateBelongsTo
7131
 *
7132
 * @return void
7133
 */
7134
        public function testSaveAllFieldListValidateBelongsTo() {
7135
                $this->loadFixtures('Post', 'Author', 'Comment', 'Attachment');
7136
                $TestModel = new Post();
7137

    
7138
                $result = $TestModel->find('all');
7139
                $this->assertEquals(3, count($result));
7140
                $this->assertFalse(isset($result[3]));
7141

    
7142
                // test belongsTo
7143
                $fieldList = array(
7144
                        'Post' => array('title'),
7145
                        'Author' => array('user')
7146
                );
7147
                $data = array(
7148
                        'Post' => array(
7149
                                'title' => 'Post without body',
7150
                                'body' => 'This will not be saved',
7151
                        ),
7152
                        'Author' => array(
7153
                                'user' => 'bob',
7154
                                'test' => 'This will not be saved',
7155

    
7156
                ));
7157
                $TestModel->saveAll($data, array('fieldList' => $fieldList));
7158

    
7159
                $result = $TestModel->find('all', array(
7160
                        'order' => 'Post.id ASC',
7161
                ));
7162
                $expected = array(
7163
                        'Post' => array(
7164
                                'id' => '4',
7165
                                'author_id' => '5',
7166
                                'title' => 'Post without body',
7167
                                'body' => null,
7168
                                'published' => 'N',
7169
                                'created' => static::date(),
7170
                                'updated' => static::date(),
7171
                        ),
7172
                        'Author' => array(
7173
                                'id' => '5',
7174
                                'user' => 'bob',
7175
                                'password' => null,
7176
                                'created' => static::date(),
7177
                                'updated' => static::date(),
7178
                                'test' => 'working',
7179
                        ),
7180
                );
7181
                $this->assertEquals($expected, $result[3]);
7182
                $this->assertEquals(4, count($result));
7183
                $this->assertEquals('', $result[3]['Post']['body']);
7184
                $this->assertEquals('working', $result[3]['Author']['test']);
7185

    
7186
                $fieldList = array(
7187
                        'Post' => array('title')
7188
                );
7189
                $data = array(
7190
                        'Post' => array(
7191
                                'title' => 'Post without body 2',
7192
                                'body' => 'This will not be saved'
7193
                        ),
7194
                        'Author' => array(
7195
                                'user' => 'jack'
7196
                        )
7197
                );
7198
                $TestModel->saveAll($data, array('fieldList' => $fieldList));
7199
                $result = $TestModel->find('all', array(
7200
                        'order' => 'Post.id ASC',
7201
                ));
7202
                $this->assertNull($result[4]['Post']['body']);
7203

    
7204
                $fieldList = array(
7205
                        'Author' => array('password')
7206
                );
7207
                $data = array(
7208
                        'Post' => array(
7209
                                'id' => '5',
7210
                                'title' => 'Post title',
7211
                                'body' => 'Post body'
7212
                        ),
7213
                        'Author' => array(
7214
                                'id' => '6',
7215
                                'user' => 'will not change',
7216
                                'password' => 'foobar'
7217
                        )
7218
                );
7219
                $result = $TestModel->saveAll($data, array('fieldList' => $fieldList));
7220
                $this->assertTrue($result);
7221

    
7222
                $result = $TestModel->find('all', array(
7223
                        'order' => 'Post.id ASC',
7224
                ));
7225
                $expected = array(
7226
                        'Post' => array(
7227
                                'id' => '5',
7228
                                'author_id' => '6',
7229
                                'title' => 'Post title',
7230
                                'body' => 'Post body',
7231
                                'published' => 'N',
7232
                                'created' => static::date(),
7233
                                'updated' => static::date()
7234
                        ),
7235
                        'Author' => array(
7236
                                'id' => '6',
7237
                                'user' => 'jack',
7238
                                'password' => 'foobar',
7239
                                'created' => static::date(),
7240
                                'updated' => static::date(),
7241
                                'test' => 'working'
7242
                        ),
7243
                );
7244
                $this->assertEquals($expected, $result[4]);
7245

    
7246
                // test multirecord
7247
                $this->db->truncate($TestModel);
7248

    
7249
                $fieldList = array('title', 'author_id');
7250
                $TestModel->saveAll(array(
7251
                        array(
7252
                                'title' => 'Multi-record post 1',
7253
                                'body' => 'First multi-record post',
7254
                                'author_id' => 2
7255
                        ),
7256
                        array(
7257
                                'title' => 'Multi-record post 2',
7258
                                'body' => 'Second multi-record post',
7259
                                'author_id' => 2
7260
                )), array('fieldList' => $fieldList));
7261

    
7262
                $result = $TestModel->find('all', array(
7263
                        'recursive' => -1,
7264
                        'order' => 'Post.id ASC'
7265
                ));
7266
                $expected = array(
7267
                        array(
7268
                                'Post' => array(
7269
                                        'id' => '1',
7270
                                        'author_id' => '2',
7271
                                        'title' => 'Multi-record post 1',
7272
                                        'body' => '',
7273
                                        'published' => 'N',
7274
                                        'created' => static::date(),
7275
                                        'updated' => static::date()
7276
                                )
7277
                        ),
7278
                        array(
7279
                                'Post' => array(
7280
                                        'id' => '2',
7281
                                        'author_id' => '2',
7282
                                        'title' => 'Multi-record post 2',
7283
                                        'body' => '',
7284
                                        'published' => 'N',
7285
                                        'created' => static::date(),
7286
                                        'updated' => static::date()
7287
                                )
7288
                        )
7289
                );
7290
                $this->assertEquals($expected, $result);
7291
        }
7292

    
7293
/**
7294
 * testSaveAllFieldListHasMany method
7295
 *
7296
 * @return void
7297
 */
7298
        public function testSaveAllFieldListHasMany() {
7299
                $this->loadFixtures('Article', 'Comment');
7300
                $TestModel = new Article();
7301
                $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
7302

    
7303
                $this->db->truncate($TestModel);
7304
                $this->db->truncate(new Comment());
7305

    
7306
                $data = array(
7307
                        'Article' => array('title' => 'I will not save'),
7308
                        'Comment' => array(
7309
                                array('comment' => 'First new comment', 'published' => 'Y', 'user_id' => 1),
7310
                                array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
7311
                        )
7312
                );
7313

    
7314
                $fieldList = array(
7315
                        'Article' => array('id'),
7316
                        'Comment' => array('article_id', 'user_id')
7317
                );
7318
                $TestModel->saveAll($data, array('fieldList' => $fieldList));
7319

    
7320
                $result = $TestModel->find('all');
7321
                $this->assertEquals('', $result[0]['Article']['title']);
7322
                $this->assertEquals('', $result[0]['Comment'][0]['comment']);
7323
                $this->assertEquals('', $result[0]['Comment'][1]['comment']);
7324

    
7325
                $fieldList = array(
7326
                        'Article' => array('id'),
7327
                        'Comment' => array('user_id')
7328
                );
7329
                $TestModel->saveAll($data, array('fieldList' => $fieldList));
7330
                $result = $TestModel->find('all');
7331

    
7332
                $this->assertEquals('', $result[1]['Article']['title']);
7333
                $this->assertEquals(2, count($result[1]['Comment']));
7334

    
7335
                $TestModel->whitelist = array('id');
7336
                $TestModel->Comment->whitelist = array('user_id');
7337
                $TestModel->saveAll($data);
7338
                $result = $TestModel->find('all');
7339

    
7340
                $this->assertEquals('', $result[2]['Article']['title']);
7341
                $this->assertEquals(2, count($result[2]['Comment']));
7342
        }
7343

    
7344
/**
7345
 * testSaveAllFieldListHasOne method
7346
 *
7347
 * @return void
7348
 */
7349
        public function testSaveAllFieldListHasOne() {
7350
                $this->loadFixtures('Attachment', 'Comment', 'Article', 'User');
7351
                $TestModel = new Comment();
7352

    
7353
                $TestModel->validate = array('comment' => 'notBlank');
7354
                $TestModel->Attachment->validate = array('attachment' => 'notBlank');
7355

    
7356
                $record = array(
7357
                        'Comment' => array(
7358
                                'user_id' => 1,
7359
                                'article_id' => 1,
7360
                                'comment' => '',
7361
                        ),
7362
                        'Attachment' => array(
7363
                                'attachment' => ''
7364
                        )
7365
                );
7366
                $result = $TestModel->saveAll($record, array('validate' => 'only'));
7367
                $this->assertFalse($result);
7368

    
7369
                $fieldList = array(
7370
                        'Comment' => array('id', 'article_id', 'user_id'),
7371
                        'Attachment' => array('comment_id')
7372
                );
7373
                $result = $TestModel->saveAll($record, array(
7374
                        'fieldList' => $fieldList, 'validate' => 'only'
7375
                ));
7376
                $this->assertTrue($result);
7377
                $this->assertEmpty($TestModel->validationErrors);
7378
        }
7379

    
7380
/**
7381
 * testSaveAllFieldListHasOneAddFkToWhitelist method
7382
 *
7383
 * @return void
7384
 */
7385
        public function testSaveAllFieldListHasOneAddFkToWhitelist() {
7386
                $this->loadFixtures('ArticleFeatured', 'Featured');
7387
                $Article = new ArticleFeatured();
7388
                $Article->belongsTo = $Article->hasMany = array();
7389
                $Article->Featured->validate = array('end_date' => 'notBlank');
7390

    
7391
                $record = array(
7392
                        'ArticleFeatured' => array(
7393
                                'user_id' => 1,
7394
                                'title' => 'First Article',
7395
                                'body' => '',
7396
                                'published' => 'Y'
7397
                        ),
7398
                        'Featured' => array(
7399
                                'category_id' => 1,
7400
                                'end_date' => ''
7401
                        )
7402
                );
7403
                $result = $Article->saveAll($record, array('validate' => 'only'));
7404
                $this->assertFalse($result);
7405
                $expected = array(
7406
                        'body' => array(
7407
                                'This field cannot be left blank'
7408
                        ),
7409
                        'Featured' => array(
7410
                                'end_date' => array(
7411
                                        'This field cannot be left blank'
7412
                                )
7413
                        )
7414
                );
7415
                $this->assertEquals($expected, $Article->validationErrors);
7416

    
7417
                $fieldList = array(
7418
                        'ArticleFeatured' => array('user_id', 'title'),
7419
                        'Featured' => array('category_id')
7420
                );
7421

    
7422
                $result = $Article->saveAll($record, array(
7423
                        'fieldList' => $fieldList, 'validate' => 'first'
7424
                ));
7425
                $this->assertTrue($result);
7426
                $this->assertEmpty($Article->validationErrors);
7427

    
7428
                $Article->recursive = 0;
7429
                $result = $Article->find('first', array('order' => array('ArticleFeatured.created' => 'DESC')));
7430
                $this->assertSame($result['ArticleFeatured']['id'], $result['Featured']['article_featured_id']);
7431
        }
7432

    
7433
/**
7434
 * testSaveAllDeepFieldListValidateBelongsTo
7435
 *
7436
 * @return void
7437
 */
7438
        public function testSaveAllDeepFieldListValidateBelongsTo() {
7439
                $this->loadFixtures('Post', 'Author', 'Comment', 'Attachment', 'Article', 'User');
7440
                $TestModel = new Post();
7441
                $TestModel->Author->bindModel(array('hasMany' => array('Comment' => array('foreignKey' => 'user_id'))), false);
7442
                $TestModel->recursive = 2;
7443

    
7444
                $result = $TestModel->find('all');
7445
                $this->assertEquals(3, count($result));
7446
                $this->assertFalse(isset($result[3]));
7447

    
7448
                // test belongsTo
7449
                $fieldList = array(
7450
                        'Post' => array('title', 'author_id'),
7451
                        'Author' => array('user'),
7452
                        'Comment' => array('comment')
7453
                );
7454
                $TestModel->saveAll(array(
7455
                        'Post' => array(
7456
                                'title' => 'Post without body',
7457
                                'body' => 'This will not be saved',
7458
                        ),
7459
                        'Author' => array(
7460
                                'user' => 'bob',
7461
                                'test' => 'This will not be saved',
7462
                                'Comment' => array(
7463
                                        array('id' => 5, 'comment' => 'I am still published', 'published' => 'N'))
7464

    
7465
                )), array('fieldList' => $fieldList, 'deep' => true));
7466

    
7467
                $result = $TestModel->Author->Comment->find('first', array(
7468
                        'conditions' => array('Comment.id' => 5),
7469
                        'fields' => array('comment', 'published')
7470
                ));
7471
                $expected = array(
7472
                        'Comment' => array(
7473
                                'comment' => 'I am still published',
7474
                                'published' => 'Y'
7475
                        )
7476
                );
7477
                $this->assertEquals($expected, $result);
7478
        }
7479

    
7480
/**
7481
 * testSaveAllDeepFieldListHasMany method
7482
 *
7483
 * @return void
7484
 */
7485
        public function testSaveAllDeepFieldListHasMany() {
7486
                $this->loadFixtures('Article', 'Comment', 'User');
7487
                $TestModel = new Article();
7488
                $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
7489

    
7490
                $this->db->truncate($TestModel);
7491
                $this->db->truncate(new Comment());
7492

    
7493
                $fieldList = array(
7494
                        'Article' => array('id'),
7495
                        'Comment' => array('article_id', 'user_id'),
7496
                        'User' => array('user')
7497
                );
7498

    
7499
                $result = $TestModel->saveAll(array(
7500
                        'Article' => array('id' => 2, 'title' => 'I will not save'),
7501
                        'Comment' => array(
7502
                                array('comment' => 'First new comment', 'published' => 'Y', 'user_id' => 1),
7503
                                array(
7504
                                        'comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2,
7505
                                        'User' => array('user' => 'nopassword', 'password' => 'not saved')
7506
                                )
7507
                        )
7508
                ), array('fieldList' => $fieldList, 'deep' => true));
7509

    
7510
                $result = $TestModel->Comment->User->find('first', array(
7511
                        'conditions' => array('User.user' => 'nopassword'),
7512
                        'fields' => array('user', 'password')
7513
                ));
7514
                $expected = array(
7515
                        'User' => array(
7516
                                'user' => 'nopassword',
7517
                                'password' => ''
7518
                        )
7519
                );
7520
                $this->assertEquals($expected, $result);
7521
        }
7522

    
7523
/**
7524
 * testSaveAllDeepHasManyBelongsTo method
7525
 *
7526
 * @return void
7527
 */
7528
        public function testSaveAllDeepHasManyBelongsTo() {
7529
                $this->loadFixtures('Article', 'Comment', 'User');
7530
                $TestModel = new Article();
7531
                $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
7532

    
7533
                $this->db->truncate($TestModel);
7534
                $this->db->truncate(new Comment());
7535

    
7536
                $result = $TestModel->saveAll(array(
7537
                        'Article' => array('id' => 2, 'title' => 'The title'),
7538
                        'Comment' => array(
7539
                                array('comment' => 'First new comment', 'published' => 'Y', 'user_id' => 1),
7540
                                array(
7541
                                        'comment' => 'belongsto', 'published' => 'Y',
7542
                                        'User' => array('user' => 'findme', 'password' => 'somepass')
7543
                                )
7544
                        )
7545
                ), array('deep' => true));
7546

    
7547
                $result = $TestModel->Comment->User->find('first', array(
7548
                        'conditions' => array('User.user' => 'findme'),
7549
                        'fields' => array('id', 'user', 'password')
7550
                ));
7551
                $expected = array(
7552
                        'User' => array(
7553
                                'id' => 5,
7554
                                'user' => 'findme',
7555
                                'password' => 'somepass',
7556
                        )
7557
                );
7558
                $this->assertEquals($expected, $result);
7559

    
7560
                $result = $TestModel->Comment->find('first', array(
7561
                        'conditions' => array('Comment.user_id' => 5),
7562
                        'fields' => array('id', 'comment', 'published', 'user_id')
7563
                ));
7564
                $expected = array(
7565
                        'Comment' => array(
7566
                                'id' => 2,
7567
                                'comment' => 'belongsto',
7568
                                'published' => 'Y',
7569
                                'user_id' => 5
7570
                        )
7571
                );
7572
                $this->assertEquals($expected, $result);
7573
        }
7574

    
7575
/**
7576
 * testSaveAllDeepHasManyhasMany method
7577
 *
7578
 * @return void
7579
 */
7580
        public function testSaveAllDeepHasManyHasMany() {
7581
                $this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
7582
                $TestModel = new Article();
7583
                $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = $TestModel->Comment->belongsTo = array();
7584
                $TestModel->Comment->unbindModel(array('hasOne' => array('Attachment')), false);
7585
                $TestModel->Comment->bindModel(array('hasMany' => array('Attachment')), false);
7586

    
7587
                $this->db->truncate($TestModel);
7588
                $this->db->truncate(new Comment());
7589
                $this->db->truncate(new Attachment());
7590

    
7591
                $result = $TestModel->saveAll(array(
7592
                        'Article' => array('id' => 2, 'title' => 'The title'),
7593
                        'Comment' => array(
7594
                                array('comment' => 'First new comment', 'published' => 'Y', 'user_id' => 1),
7595
                                array(
7596
                                        'comment' => 'hasmany', 'published' => 'Y', 'user_id' => 5,
7597
                                        'Attachment' => array(
7598
                                                array('attachment' => 'first deep attachment'),
7599
                                                array('attachment' => 'second deep attachment'),
7600
                                        )
7601
                                )
7602
                        )
7603
                ), array('deep' => true));
7604

    
7605
                $result = $TestModel->Comment->find('first', array(
7606
                        'conditions' => array('Comment.comment' => 'hasmany'),
7607
                        'fields' => array('id', 'comment', 'published', 'user_id'),
7608
                        'recursive' => -1
7609
                ));
7610
                $expected = array(
7611
                        'Comment' => array(
7612
                                'id' => 2,
7613
                                'comment' => 'hasmany',
7614
                                'published' => 'Y',
7615
                                'user_id' => 5
7616
                        )
7617
                );
7618
                $this->assertEquals($expected, $result);
7619

    
7620
                $result = $TestModel->Comment->Attachment->find('all', array(
7621
                        'fields' => array('attachment', 'comment_id'),
7622
                        'order' => array('Attachment.id' => 'ASC')
7623
                ));
7624
                $expected = array(
7625
                        array('Attachment' => array('attachment' => 'first deep attachment', 'comment_id' => 2)),
7626
                        array('Attachment' => array('attachment' => 'second deep attachment', 'comment_id' => 2)),
7627
                );
7628
                $this->assertEquals($expected, $result);
7629
        }
7630

    
7631
/**
7632
 * testSaveAllDeepOrderHasManyHasMany method
7633
 *
7634
 * @return void
7635
 */
7636
        public function testSaveAllDeepOrderHasManyHasMany() {
7637
                $this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
7638
                $TestModel = new Article();
7639
                $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = $TestModel->Comment->belongsTo = array();
7640
                $TestModel->Comment->unbindModel(array('hasOne' => array('Attachment')), false);
7641
                $TestModel->Comment->bindModel(array('hasMany' => array('Attachment')), false);
7642

    
7643
                $this->db->truncate($TestModel);
7644
                $this->db->truncate(new Comment());
7645
                $this->db->truncate(new Attachment());
7646

    
7647
                $result = $TestModel->saveAll(array(
7648
                        'Article' => array('id' => 2, 'title' => 'Comment has its data after Attachment'),
7649
                        'Comment' => array(
7650
                                array(
7651
                                        'Attachment' => array(
7652
                                                array('attachment' => 'attachment should be created with comment_id'),
7653
                                                array('attachment' => 'comment should be created with article_id'),
7654
                                        ),
7655
                                        'comment' => 'after associated data',
7656
                                        'user_id' => 1
7657
                                )
7658
                        )
7659
                ), array('deep' => true));
7660
                $result = $TestModel->Comment->find('first', array(
7661
                        'conditions' => array('Comment.article_id' => 2),
7662
                ));
7663

    
7664
                $this->assertEquals(2, $result['Comment']['article_id']);
7665
                $this->assertEquals(2, count($result['Attachment']));
7666
        }
7667

    
7668
/**
7669
 * testSaveAllDeepEmptyHasManyHasMany method
7670
 *
7671
 * @return void
7672
 */
7673
        public function testSaveAllDeepEmptyHasManyHasMany() {
7674
                $this->skipIf(!$this->db instanceof Mysql, 'This test is only compatible with Mysql.');
7675

    
7676
                $this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
7677
                $TestModel = new Article();
7678
                $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = $TestModel->Comment->belongsTo = array();
7679
                $TestModel->Comment->unbindModel(array('hasOne' => array('Attachment')), false);
7680
                $TestModel->Comment->bindModel(array('hasMany' => array('Attachment')), false);
7681

    
7682
                $this->db->truncate($TestModel);
7683
                $this->db->truncate(new Comment());
7684
                $this->db->truncate(new Attachment());
7685

    
7686
                $result = $TestModel->saveAll(array(
7687
                        'Article' => array('id' => 3, 'user_id' => 1, 'title' => 'Comment has no data'),
7688
                        'Comment' => array(
7689
                                array(
7690
                                        'user_id' => 1,
7691
                                        'Attachment' => array(
7692
                                                array('attachment' => 'attachment should be created with comment_id'),
7693
                                                array('attachment' => 'comment should be created with article_id'),
7694
                                        ),
7695
                                )
7696
                        )
7697
                ), array('deep' => true));
7698
                $result = $TestModel->Comment->find('first', array(
7699
                        'conditions' => array('Comment.article_id' => 3),
7700
                ));
7701

    
7702
                $this->assertEquals(3, $result['Comment']['article_id']);
7703
                $this->assertEquals(2, count($result['Attachment']));
7704
        }
7705

    
7706
/**
7707
 * Test that boolean fields don't cause saveMany to fail
7708
 *
7709
 * @return void
7710
 */
7711
        public function testSaveManyBooleanFields() {
7712
                $this->loadFixtures('Item', 'Syfile', 'Image');
7713
                $data = array(
7714
                        array(
7715
                                'Item' => array(
7716
                                        'name' => 'testing',
7717
                                        'syfile_id' => 1,
7718
                                        'published' => false
7719
                                )
7720
                        ),
7721
                        array(
7722
                                'Item' => array(
7723
                                        'name' => 'testing 2',
7724
                                        'syfile_id' => 1,
7725
                                        'published' => true
7726
                                )
7727
                        ),
7728
                );
7729
                $item = ClassRegistry::init('Item');
7730
                $result = $item->saveMany($data, array('atomic' => false));
7731

    
7732
                $this->assertCount(2, $result, '2 records should have been saved.');
7733
                $this->assertTrue($result[0], 'Both should have succeded');
7734
                $this->assertTrue($result[1], 'Both should have succeded');
7735
        }
7736

    
7737
/**
7738
 * testSaveManyDeepHasManyValidationFailure method
7739
 *
7740
 * @return void
7741
 */
7742
        public function testSaveManyDeepHasManyValidationFailure() {
7743
                $this->loadFixtures('Article', 'Comment');
7744
                $TestModel = new Article();
7745
                $TestModel->Comment->validate = array(
7746
                        'comment' => array(
7747
                                'notBlank' => array(
7748
                                        'rule' => array('notBlank'),
7749
                                )
7750
                        )
7751
                );
7752

    
7753
                $result = $TestModel->saveMany(array(
7754
                        array(
7755
                                'user_id' => 1,
7756
                                'title' => 'New Article',
7757
                                'body' => 'This article contains a invalid comment',
7758
                                'Comment' => array(
7759
                                        array(
7760
                                                'user_id' => 1,
7761
                                                'comment' => ''
7762
                                        )
7763
                                )
7764
                        )
7765
                ), array('deep' => true));
7766
                $this->assertFalse($result);
7767
                $this->assertEquals(array(
7768
                        array(
7769
                                'Comment' => array(
7770
                                        array('comment' => array('notBlank'))
7771
                                )
7772
                        )
7773
                ), $TestModel->validationErrors);
7774
        }
7775

    
7776
/**
7777
 * testSaveAssociatedDeepHasOneHasManyValidateTrueValidationFailure method
7778
 *
7779
 * @return void
7780
 */
7781
        public function testSaveAssociatedDeepHasOneHasManyValidateTrueValidationFailure() {
7782
                $this->loadFixtures('User', 'Article', 'Comment');
7783
                $TestModel = new UserHasOneArticle();
7784
                $TestModel->Article->Comment->validate = array(
7785
                        'comment' => array(
7786
                                'notBlank' => array(
7787
                                        'rule' => array('notBlank'),
7788
                                )
7789
                        )
7790
                );
7791

    
7792
                $result = $TestModel->saveAssociated(array(
7793
                        'User' => array(
7794
                                'user' => 'hiromi',
7795
                                'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
7796
                        ),
7797
                        'Article' => array(
7798
                                'title' => 'Article with User',
7799
                                'body' => 'This article will be saved with an user and contains a invalid comment',
7800
                                'Comment' => array(
7801
                                        array(
7802
                                                'user_id' => 1,
7803
                                                'comment' => ''
7804
                                        )
7805
                                )
7806
                        )
7807
                ), array('deep' => true, 'validate' => true));
7808
                $this->assertFalse($result);
7809
                $this->assertEquals(array(
7810
                        'Article' => array(
7811
                                'Comment' => array(
7812
                                        array('comment' => array('notBlank'))
7813
                                )
7814
                        )
7815
                ), $TestModel->validationErrors);
7816
        }
7817

    
7818
/**
7819
 * testSaveAssociatedDeepBelongsToHasManyValidateTrueValidationFailure method
7820
 *
7821
 * @return void
7822
 */
7823
        public function testSaveAssociatedDeepBelongsToHasManyValidateTrueValidationFailure() {
7824
                $this->loadFixtures('ArticlesTag', 'Article', 'Comment');
7825
                $TestModel = new ArticlesTagBelongsToArticle();
7826
                $TestModel->Article->Comment->validate = array(
7827
                        'comment' => array(
7828
                                'notBlank' => array(
7829
                                        'rule' => array('notBlank'),
7830
                                )
7831
                        )
7832
                );
7833

    
7834
                $result = $TestModel->saveAssociated(array(
7835
                        'ArticlesTagBelongsToArticle' => array(
7836
                                'tag_id' => 1,
7837
                        ),
7838
                        'Article' => array(
7839
                                'title' => 'Article with User',
7840
                                'body' => 'This article will be saved with an user and contains a invalid comment',
7841
                                'Comment' => array(
7842
                                        array(
7843
                                                'user_id' => 1,
7844
                                                'comment' => ''
7845
                                        )
7846
                                )
7847
                        )
7848
                ), array('deep' => true, 'validate' => true));
7849
                $this->assertFalse($result);
7850
                $this->assertEquals(array(
7851
                        'Article' => array(
7852
                                'Comment' => array(
7853
                                        array('comment' => array('notBlank'))
7854
                                )
7855
                        )
7856
                ), $TestModel->validationErrors);
7857
        }
7858

    
7859
/**
7860
 * Test that boolean fields don't cause saveAssociated to fail
7861
 *
7862
 * @return void
7863
 */
7864
        public function testSaveAssociatedHasOneBooleanFields() {
7865
                $this->loadFixtures('Item', 'Syfile', 'Image');
7866
                $data = array(
7867
                        'Syfile' => array(
7868
                                'image_id' => 1,
7869
                                'name' => 'Some file',
7870
                        ),
7871
                        'Item' => array(
7872
                                'name' => 'testing',
7873
                                'published' => false
7874
                        ),
7875
                );
7876
                $syfile = ClassRegistry::init('Syfile');
7877
                $syfile->bindModel(array('hasOne' => array('Item')), false);
7878
                $result = $syfile->saveAssociated($data, array('atomic' => false));
7879

    
7880
                $this->assertCount(2, $result, '2 records should have been saved.');
7881
                $this->assertTrue($result['Syfile'], 'Both should have succeded');
7882
                $this->assertTrue($result['Item'], 'Both should have succeded');
7883
        }
7884

    
7885
/**
7886
 * Test that boolean fields don't cause saveAssociated to fail
7887
 *
7888
 * @return void
7889
 */
7890
        public function testSaveAssociatedBelongsToBooleanFields() {
7891
                $this->loadFixtures('Item', 'Syfile', 'Image');
7892
                $data = array(
7893
                        'Syfile' => array(
7894
                                'image_id' => 1,
7895
                                'name' => 'Some file',
7896
                        ),
7897
                        'Item' => array(
7898
                                'name' => 'testing',
7899
                                'syfile_id' => 2,
7900
                                'published' => false
7901
                        ),
7902
                );
7903
                $item = ClassRegistry::init('Item');
7904
                $item->bindModel(array(
7905
                        'belongsTo' => array(
7906
                                'Item' => array(
7907
                                        'foreignKey' => 'image_id'
7908
                                )
7909
                        )
7910
                ), false);
7911
                $result = $item->saveAssociated($data, array('atomic' => false));
7912

    
7913
                $this->assertCount(2, $result, '2 records should have been saved.');
7914
                $this->assertTrue($result['Syfile'], 'Both should have succeded');
7915
                $this->assertTrue($result['Item'], 'Both should have succeded');
7916
        }
7917

    
7918
/**
7919
 * testUpdateAllBoolean
7920
 *
7921
 * @return void
7922
 */
7923
        public function testUpdateAllBoolean() {
7924
                $this->loadFixtures('Item', 'Syfile', 'Portfolio', 'Image', 'ItemsPortfolio');
7925
                $TestModel = new Item();
7926
                $result = $TestModel->updateAll(array('published' => true));
7927
                $this->assertTrue($result);
7928

    
7929
                $result = $TestModel->find('first', array('fields' => array('id', 'published')));
7930
                $this->assertEquals(true, $result['Item']['published']);
7931
        }
7932

    
7933
/**
7934
 * testUpdateAllBooleanConditions
7935
 *
7936
 * @return void
7937
 */
7938
        public function testUpdateAllBooleanConditions() {
7939
                $this->loadFixtures('Item', 'Syfile', 'Portfolio', 'Image', 'ItemsPortfolio');
7940
                $TestModel = new Item();
7941

    
7942
                $result = $TestModel->updateAll(array('published' => true), array('Item.id' => 1));
7943
                $this->assertTrue($result);
7944
                $result = $TestModel->find('first', array(
7945
                        'fields' => array('id', 'published'),
7946
                        'conditions' => array('Item.id' => 1)));
7947
                $this->assertEquals(true, $result['Item']['published']);
7948
        }
7949

    
7950
/**
7951
 * testUpdateBoolean
7952
 *
7953
 * @return void
7954
 */
7955
        public function testUpdateBoolean() {
7956
                $this->loadFixtures('Item', 'Syfile', 'Portfolio', 'Image', 'ItemsPortfolio');
7957
                $TestModel = new Item();
7958

    
7959
                $result = $TestModel->save(array('published' => true, 'id' => 1));
7960
                $this->assertTrue((bool)$result);
7961
                $result = $TestModel->find('first', array(
7962
                        'fields' => array('id', 'published'),
7963
                        'conditions' => array('Item.id' => 1)));
7964
                $this->assertEquals(true, $result['Item']['published']);
7965
        }
7966

    
7967
/**
7968
 * Test the clear() method.
7969
 *
7970
 * @return void
7971
 */
7972
        public function testClear() {
7973
                $this->loadFixtures('Bid');
7974
                $model = ClassRegistry::init('Bid');
7975
                $model->set(array('name' => 'Testing', 'message_id' => 3));
7976
                $this->assertTrue(isset($model->data['Bid']['name']));
7977
                $this->assertTrue($model->clear());
7978
                $this->assertFalse(isset($model->data['Bid']['name']));
7979
                $this->assertFalse(isset($model->data['Bid']['message_id']));
7980
        }
7981

    
7982
/**
7983
 * Test that Model::save() doesn't generate a query with WHERE 1 = 1 on race condition.
7984
 *
7985
 * @link https://github.com/cakephp/cakephp/issues/3857
7986
 * @return void
7987
 */
7988
        public function testSafeUpdateMode() {
7989
                $this->loadFixtures('User');
7990

    
7991
                $User = ClassRegistry::init('User');
7992
                $this->assertFalse($User->__safeUpdateMode);
7993

    
7994
                $User->getEventManager()->attach(array($this, 'deleteMe'), 'Model.beforeSave');
7995

    
7996
                $User->id = 1;
7997
                $User->set(array('user' => 'nobody'));
7998
                $User->save();
7999

    
8000
                $users = $User->find('list', array('fields' => 'User.user'));
8001

    
8002
                $expected = array(
8003
                        2 => 'nate',
8004
                        3 => 'larry',
8005
                        4 => 'garrett',
8006
                );
8007
                $this->assertEquals($expected, $users);
8008
                $this->assertFalse($User->__safeUpdateMode);
8009

    
8010
                $User->id = 2;
8011
                $User->set(array('user' => $User->getDataSource()->expression('PDO_EXCEPTION()')));
8012
                try {
8013
                        $User->save(null, false);
8014
                        $this->fail('No exception thrown');
8015
                } catch (PDOException $e) {
8016
                        $this->assertFalse($User->__safeUpdateMode);
8017
                }
8018
        }
8019

    
8020
/**
8021
 * Emulates race condition
8022
 *
8023
 * @param CakeEvent $event containing the Model
8024
 * @return void
8025
 */
8026
        public function deleteMe($event) {
8027
                $Model = $event->subject;
8028
                $Model->getDataSource()->delete($Model, array($Model->alias . '.' . $Model->primaryKey => $Model->id));
8029
        }
8030

    
8031
/**
8032
 * Creates a convenient mock DboSource
8033
 *
8034
 * We cannot call several methods via mock DboSource, such as DboSource::value()
8035
 * because mock DboSource has no $_connection.
8036
 * This method helps us to avoid this problem.
8037
 *
8038
 * @param array $methods Configurable method names.
8039
 * @return DboSource
8040
 */
8041
        protected function _getMockDboSource($methods = array()) {
8042
                $testDb = ConnectionManager::getDataSource('test');
8043

    
8044
                $passthrough = array_diff(array('value', 'begin', 'rollback', 'commit', 'describe', 'lastInsertId', 'execute'), $methods);
8045

    
8046
                $methods = array_merge($methods, $passthrough);
8047
                if (!in_array('connect', $methods)) {
8048
                        $methods[] = 'connect'; // This will be called by DboSource::__construct().
8049
                }
8050

    
8051
                $db = $this->getMock('DboSource', $methods);
8052
                $db->columns = $testDb->columns;
8053
                $db->startQuote = $testDb->startQuote;
8054
                $db->endQuote = $testDb->endQuote;
8055

    
8056
                foreach ($passthrough as $method) {
8057
                        $db->expects($this->any())
8058
                                ->method($method)
8059
                                ->will($this->returnCallback(array($testDb, $method)));
8060
                }
8061

    
8062
                return $db;
8063
        }
8064

    
8065
/**
8066
 * Test that transactions behave correctly on nested saveMany calls.
8067
 *
8068
 * @return void
8069
 */
8070
        public function testTransactionOnNestedSaveMany() {
8071
                $this->loadFixtures('Post');
8072
                $Post = new TestPost();
8073
                $Post->getEventManager()->attach(array($this, 'nestedSaveMany'), 'Model.afterSave');
8074

    
8075
                // begin -> [ begin -> commit ] -> commit
8076
                $db = $this->_getMockDboSource(array('begin', 'commit', 'rollback'));
8077
                $db->expects($this->exactly(2))->method('begin')->will($this->returnValue(true));
8078
                $db->expects($this->exactly(2))->method('commit');
8079
                $db->expects($this->never())->method('rollback');
8080
                $Post->setDataSourceObject($db);
8081

    
8082
                $data = array(
8083
                        array('author_id' => 1, 'title' => 'Outer Post'),
8084
                );
8085
                $Post->dataForAfterSave = array(
8086
                        array('author_id' => 1, 'title' => 'Inner Post'),
8087
                );
8088
                $this->assertTrue($Post->saveMany($data));
8089

    
8090
                // begin -> [  begin(false) ] -> commit
8091
                $db = $this->_getMockDboSource(array('begin', 'commit', 'rollback'));
8092
                $db->expects($this->at(0))->method('begin')->will($this->returnValue(true));
8093
                $db->expects($this->at(1))->method('begin')->will($this->returnValue(false));
8094
                $db->expects($this->once())->method('commit');
8095
                $db->expects($this->never())->method('rollback');
8096
                $Post->setDataSourceObject($db);
8097

    
8098
                $data = array(
8099
                        array('author_id' => 1, 'title' => 'Outer Post'),
8100
                );
8101
                $Post->dataForAfterSave = array(
8102
                        array('author_id' => 1, 'title' => 'Inner Post'),
8103
                );
8104
                $this->assertTrue($Post->saveMany($data));
8105

    
8106
                // begin -> [ begin -> rollback ] -> rollback
8107
                $db = $this->_getMockDboSource(array('begin', 'commit', 'rollback'));
8108
                $db->expects($this->exactly(2))->method('begin')->will($this->returnValue(true));
8109
                $db->expects($this->never())->method('commit');
8110
                $db->expects($this->exactly(2))->method('rollback');
8111
                $Post->setDataSourceObject($db);
8112
                $data = array(
8113
                        array('author_id' => 1, 'title' => 'Outer Post'),
8114
                );
8115
                $Post->dataForAfterSave = array(
8116
                        array('author_id' => 1, 'title' => 'Inner Post', 'body' => $db->expression('PDO_EXCEPTION()')),
8117
                );
8118

    
8119
                try {
8120
                        $Post->saveMany($data);
8121
                        $this->fail('No exception thrown');
8122
                } catch(Exception $e) {
8123
                }
8124
        }
8125

    
8126
/**
8127
 * Test that transaction behaves correctly on nested saveAssociated calls.
8128
 *
8129
 * @return void
8130
 */
8131
        public function testTransactionOnNestedSaveAssociated() {
8132
                $this->loadFixtures('Author', 'Post');
8133

    
8134
                $Author = new TestAuthor();
8135
                $Author->getEventManager()->attach(array($this, 'nestedSaveAssociated'), 'Model.afterSave');
8136

    
8137
                // begin -> [ begin -> commit ] -> commit
8138
                $db = $this->_getMockDboSource(array('begin', 'commit', 'rollback'));
8139
                $db->expects($this->exactly(2))->method('begin')->will($this->returnValue(true));
8140
                $db->expects($this->exactly(2))->method('commit');
8141
                $db->expects($this->never())->method('rollback');
8142
                $Author->setDataSourceObject($db);
8143
                $Author->Post->setDataSourceObject($db);
8144

    
8145
                $data = array(
8146
                        'Author' => array('user' => 'outer'),
8147
                        'Post' => array(
8148
                                array('title' => 'Outer Post'),
8149
                        )
8150
                );
8151
                $Author->dataForAfterSave = array(
8152
                        'Author' => array('user' => 'inner'),
8153
                        'Post' => array(
8154
                                array('title' => 'Inner Post'),
8155
                        )
8156
                );
8157
                $this->assertTrue($Author->saveAssociated($data));
8158

    
8159
                // begin -> [  begin(false) ] -> commit
8160
                $db = $this->_getMockDboSource(array('begin', 'commit', 'rollback'));
8161
                $db->expects($this->at(0))->method('begin')->will($this->returnValue(true));
8162
                $db->expects($this->at(1))->method('begin')->will($this->returnValue(false));
8163
                $db->expects($this->once())->method('commit');
8164
                $db->expects($this->never())->method('rollback');
8165
                $Author->setDataSourceObject($db);
8166
                $Author->Post->setDataSourceObject($db);
8167
                $data = array(
8168
                        'Author' => array('user' => 'outer'),
8169
                        'Post' => array(
8170
                                array('title' => 'Outer Post'),
8171
                        )
8172
                );
8173
                $Author->dataForAfterSave = array(
8174
                        'Author' => array('user' => 'inner'),
8175
                        'Post' => array(
8176
                                array('title' => 'Inner Post'),
8177
                        )
8178
                );
8179
                $this->assertTrue($Author->saveAssociated($data));
8180

    
8181
                // begin -> [ begin -> rollback ] -> rollback
8182
                $db = $this->_getMockDboSource(array('begin', 'commit', 'rollback'));
8183
                $db->expects($this->exactly(2))->method('begin')->will($this->returnValue(true));
8184
                $db->expects($this->never())->method('commit');
8185
                $db->expects($this->exactly(2))->method('rollback');
8186
                $Author->setDataSourceObject($db);
8187
                $Author->Post->setDataSourceObject($db);
8188
                $data = array(
8189
                        'Author' => array('user' => 'outer'),
8190
                        'Post' => array(
8191
                                array('title' => 'Outer Post'),
8192
                        )
8193
                );
8194
                $Author->dataForAfterSave = array(
8195
                        'Author' => array('user' => 'inner', 'password' => $db->expression('PDO_EXCEPTION()')),
8196
                        'Post' => array(
8197
                                array('title' => 'Inner Post'),
8198
                        )
8199
                );
8200

    
8201
                try {
8202
                        $Author->saveAssociated($data);
8203
                        $this->fail('No exception thrown');
8204
                } catch(Exception $e) {
8205
                }
8206
        }
8207

    
8208
/**
8209
 * A callback for testing nested saveMany.
8210
 *
8211
 * @param CakeEvent $event containing the Model
8212
 * @return void
8213
 */
8214
        public function nestedSaveMany($event) {
8215
                $Model = $event->subject;
8216
                $Model->saveMany($Model->dataForAfterSave, array('callbacks' => false));
8217
        }
8218

    
8219
/**
8220
 * A callback for testing nested saveAssociated.
8221
 *
8222
 * @param CakeEvent $event containing the Model
8223
 * @return void
8224
 */
8225
        public function nestedSaveAssociated($event) {
8226
                $Model = $event->subject;
8227
                $Model->saveAssociated($Model->dataForAfterSave, array('callbacks' => false));
8228
        }
8229
}