Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
13532 anikendra 1
<?php
2
/**
3
 * ModelValidationTest 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
require_once dirname(__FILE__) . DS . 'ModelTestBase.php';
20
 
21
/**
22
 * ModelValidationTest
23
 *
24
 * @package       Cake.Test.Case.Model
25
 */
26
class ModelValidationTest extends BaseModelTest {
27
 
28
/**
29
 * override locale to the default (eng).
30
 *
31
 * @return void
32
 */
33
	public function setUp() {
34
		parent::setUp();
35
		Configure::write('Config.language', 'eng');
36
	}
37
 
38
/**
39
 * Tests validation parameter order in custom validation methods
40
 *
41
 * @return void
42
 */
43
	public function testValidationParams() {
44
		$TestModel = new ValidationTest1();
45
		$TestModel->validate['title'] = array(
46
			'rule' => 'customValidatorWithParams',
47
			'required' => true
48
		);
49
		$TestModel->create(array('title' => 'foo'));
50
		$TestModel->invalidFields();
51
 
52
		$expected = array(
53
			'data' => array(
54
				'title' => 'foo'
55
			),
56
			'validator' => array(
57
				'rule' => 'customValidatorWithParams',
58
				'on' => null,
59
				'last' => true,
60
				'allowEmpty' => false,
61
				'required' => true,
62
				'message' => null
63
			),
64
			'or' => true,
65
			'ignoreOnSame' => 'id'
66
		);
67
		$this->assertEquals($expected, $TestModel->validatorParams);
68
 
69
		$TestModel->validate['title'] = array(
70
			'rule' => 'customValidatorWithMessage',
71
			'required' => true
72
		);
73
		$expected = array(
74
			'title' => array('This field will *never* validate! Muhahaha!')
75
		);
76
 
77
		$this->assertEquals($expected, $TestModel->invalidFields());
78
 
79
		$TestModel->validate['title'] = array(
80
			'rule' => array('customValidatorWithSixParams', 'one', 'two', null, 'four'),
81
			'required' => true
82
		);
83
		$TestModel->create(array('title' => 'foo'));
84
		$TestModel->invalidFields();
85
		$expected = array(
86
			'data' => array(
87
				'title' => 'foo'
88
			),
89
			'one' => 'one',
90
			'two' => 'two',
91
			'three' => null,
92
			'four' => 'four',
93
			'five' => array(
94
				'rule' => array(1 => 'one', 2 => 'two', 3 => null, 4 => 'four'),
95
				'on' => null,
96
				'last' => true,
97
				'allowEmpty' => false,
98
				'required' => true,
99
				'message' => null
100
			),
101
			'six' => 6
102
		);
103
		$this->assertEquals($expected, $TestModel->validatorParams);
104
 
105
		$TestModel->validate['title'] = array(
106
			'rule' => array('customValidatorWithSixParams', 'one', array('two'), null, 'four', array('five' => 5)),
107
			'required' => true
108
		);
109
		$TestModel->create(array('title' => 'foo'));
110
		$TestModel->invalidFields();
111
		$expected = array(
112
			'data' => array(
113
				'title' => 'foo'
114
			),
115
			'one' => 'one',
116
			'two' => array('two'),
117
			'three' => null,
118
			'four' => 'four',
119
			'five' => array('five' => 5),
120
			'six' => array(
121
				'rule' => array(1 => 'one', 2 => array('two'), 3 => null, 4 => 'four', 5 => array('five' => 5)),
122
				'on' => null,
123
				'last' => true,
124
				'allowEmpty' => false,
125
				'required' => true,
126
				'message' => null
127
			)
128
		);
129
		$this->assertEquals($expected, $TestModel->validatorParams);
130
	}
131
 
132
/**
133
 * Tests validation parameter fieldList in invalidFields
134
 *
135
 * @return void
136
 */
137
	public function testInvalidFieldsWithFieldListParams() {
138
		$TestModel = new ValidationTest1();
139
		$TestModel->validate = $validate = array(
140
			'title' => array(
141
				'rule' => 'alphaNumeric',
142
				'required' => true
143
			),
144
			'name' => array(
145
				'rule' => 'alphaNumeric',
146
				'required' => true
147
		));
148
		$TestModel->set(array('title' => '$$', 'name' => '##'));
149
		$TestModel->invalidFields(array('fieldList' => array('title')));
150
		$expected = array(
151
			'title' => array('This field cannot be left blank')
152
		);
153
		$this->assertEquals($expected, $TestModel->validationErrors);
154
		$TestModel->validationErrors = array();
155
 
156
		$TestModel->invalidFields(array('fieldList' => array('name')));
157
		$expected = array(
158
			'name' => array('This field cannot be left blank')
159
		);
160
		$this->assertEquals($expected, $TestModel->validationErrors);
161
		$TestModel->validationErrors = array();
162
 
163
		$TestModel->invalidFields(array('fieldList' => array('name', 'title')));
164
		$expected = array(
165
			'name' => array('This field cannot be left blank'),
166
			'title' => array('This field cannot be left blank')
167
		);
168
		$this->assertEquals($expected, $TestModel->validationErrors);
169
		$TestModel->validationErrors = array();
170
 
171
		$TestModel->whitelist = array('name');
172
		$TestModel->invalidFields();
173
		$expected = array('name' => array('This field cannot be left blank'));
174
		$this->assertEquals($expected, $TestModel->validationErrors);
175
 
176
		$this->assertEquals($TestModel->validate, $validate);
177
	}
178
 
179
/**
180
 * Test that invalidFields() integrates well with save(). And that fieldList can be an empty type.
181
 *
182
 * @return void
183
 */
184
	public function testInvalidFieldsWhitelist() {
185
		$TestModel = new ValidationTest1();
186
		$TestModel->validate = array(
187
			'title' => array(
188
				'rule' => 'alphaNumeric',
189
				'required' => true
190
			),
191
			'name' => array(
192
				'rule' => 'alphaNumeric',
193
				'required' => true
194
		));
195
 
196
		$TestModel->whitelist = array('name');
197
		$TestModel->save(array('name' => '#$$#', 'title' => '$$$$'));
198
 
199
		$expected = array('name' => array('This field cannot be left blank'));
200
		$this->assertEquals($expected, $TestModel->validationErrors);
201
	}
202
 
203
/**
204
 * testValidates method
205
 *
206
 * @return void
207
 */
208
	public function testValidates() {
209
		$TestModel = new TestValidate();
210
 
211
		$TestModel->validate = array(
212
			'user_id' => 'numeric',
213
			'title' => array('allowEmpty' => false, 'rule' => 'notEmpty'),
214
			'body' => 'notEmpty'
215
		);
216
 
217
		$data = array('TestValidate' => array(
218
			'user_id' => '1',
219
			'title' => '',
220
			'body' => 'body'
221
		));
222
		$result = $TestModel->create($data);
223
		$this->assertEquals($data, $result);
224
		$result = $TestModel->validates();
225
		$this->assertFalse($result);
226
 
227
		$data = array('TestValidate' => array(
228
			'user_id' => '1',
229
			'title' => 'title',
230
			'body' => 'body'
231
		));
232
		$result = $TestModel->create($data) && $TestModel->validates();
233
		$this->assertTrue($result);
234
 
235
		$data = array('TestValidate' => array(
236
			'user_id' => '1',
237
			'title' => '0',
238
			'body' => 'body'
239
		));
240
		$result = $TestModel->create($data);
241
		$this->assertEquals($data, $result);
242
		$result = $TestModel->validates();
243
		$this->assertTrue($result);
244
 
245
		$data = array('TestValidate' => array(
246
			'user_id' => '1',
247
			'title' => 0,
248
			'body' => 'body'
249
		));
250
		$result = $TestModel->create($data);
251
		$this->assertEquals($data, $result);
252
		$result = $TestModel->validates();
253
		$this->assertTrue($result);
254
 
255
		$TestModel->validate['modified'] = array('allowEmpty' => true, 'rule' => 'date');
256
 
257
		$data = array('TestValidate' => array(
258
			'user_id' => '1',
259
			'title' => 0,
260
			'body' => 'body',
261
			'modified' => ''
262
		));
263
		$result = $TestModel->create($data);
264
		$this->assertEquals($data, $result);
265
		$result = $TestModel->validates();
266
		$this->assertTrue($result);
267
 
268
		$data = array('TestValidate' => array(
269
			'user_id' => '1',
270
			'title' => 0,
271
			'body' => 'body',
272
			'modified' => '2007-05-01'
273
		));
274
		$result = $TestModel->create($data);
275
		$this->assertEquals($data, $result);
276
		$result = $TestModel->validates();
277
		$this->assertTrue($result);
278
 
279
		$data = array('TestValidate' => array(
280
			'user_id' => '1',
281
			'title' => 0,
282
			'body' => 'body',
283
			'modified' => 'invalid-date-here'
284
		));
285
		$result = $TestModel->create($data);
286
		$this->assertEquals($data, $result);
287
		$result = $TestModel->validates();
288
		$this->assertFalse($result);
289
 
290
		$data = array('TestValidate' => array(
291
			'user_id' => '1',
292
			'title' => 0,
293
			'body' => 'body',
294
			'modified' => 0
295
		));
296
		$result = $TestModel->create($data);
297
		$this->assertEquals($data, $result);
298
		$result = $TestModel->validates();
299
		$this->assertFalse($result);
300
 
301
		$data = array('TestValidate' => array(
302
			'user_id' => '1',
303
			'title' => 0,
304
			'body' => 'body',
305
			'modified' => '0'
306
		));
307
		$result = $TestModel->create($data);
308
		$this->assertEquals($data, $result);
309
		$result = $TestModel->validates();
310
		$this->assertFalse($result);
311
 
312
		$TestModel->validate['modified'] = array('allowEmpty' => false, 'rule' => 'date');
313
 
314
		$data = array('TestValidate' => array('modified' => null));
315
		$result = $TestModel->create($data);
316
		$this->assertEquals($data, $result);
317
		$result = $TestModel->validates();
318
		$this->assertFalse($result);
319
 
320
		$data = array('TestValidate' => array('modified' => false));
321
		$result = $TestModel->create($data);
322
		$this->assertEquals($data, $result);
323
		$result = $TestModel->validates();
324
		$this->assertFalse($result);
325
 
326
		$data = array('TestValidate' => array('modified' => ''));
327
		$result = $TestModel->create($data);
328
		$this->assertEquals($data, $result);
329
		$result = $TestModel->validates();
330
		$this->assertFalse($result);
331
 
332
		$data = array('TestValidate' => array(
333
			'modified' => '2007-05-01'
334
		));
335
		$result = $TestModel->create($data);
336
		$this->assertEquals($data, $result);
337
		$result = $TestModel->validates();
338
		$this->assertTrue($result);
339
 
340
		$TestModel->validate['slug'] = array('allowEmpty' => false, 'rule' => array('maxLength', 45));
341
 
342
		$data = array('TestValidate' => array(
343
			'user_id' => '1',
344
			'title' => 0,
345
			'body' => 'body',
346
			'slug' => ''
347
		));
348
		$result = $TestModel->create($data);
349
		$this->assertEquals($data, $result);
350
		$result = $TestModel->validates();
351
		$this->assertFalse($result);
352
 
353
		$data = array('TestValidate' => array(
354
			'user_id' => '1',
355
			'title' => 0,
356
			'body' => 'body',
357
			'slug' => 'slug-right-here'
358
		));
359
		$result = $TestModel->create($data);
360
		$this->assertEquals($data, $result);
361
		$result = $TestModel->validates();
362
		$this->assertTrue($result);
363
 
364
		$data = array('TestValidate' => array(
365
			'user_id' => '1',
366
			'title' => 0,
367
			'body' => 'body',
368
			'slug' => 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz'
369
		));
370
		$result = $TestModel->create($data);
371
		$this->assertEquals($data, $result);
372
		$result = $TestModel->validates();
373
		$this->assertFalse($result);
374
 
375
		$TestModel->validate = array(
376
			'number' => array(
377
				'rule' => 'validateNumber',
378
				'min' => 3,
379
				'max' => 5
380
			),
381
			'title' => array(
382
				'allowEmpty' => false,
383
				'rule' => 'notEmpty'
384
		));
385
 
386
		$data = array('TestValidate' => array(
387
			'title' => 'title',
388
			'number' => '0'
389
		));
390
		$result = $TestModel->create($data);
391
		$this->assertEquals($data, $result);
392
		$result = $TestModel->validates();
393
		$this->assertFalse($result);
394
 
395
		$data = array('TestValidate' => array(
396
			'title' => 'title',
397
			'number' => 0
398
		));
399
		$result = $TestModel->create($data);
400
		$this->assertEquals($data, $result);
401
		$result = $TestModel->validates();
402
		$this->assertFalse($result);
403
 
404
		$data = array('TestValidate' => array(
405
			'title' => 'title',
406
			'number' => '3'
407
		));
408
		$result = $TestModel->create($data);
409
		$this->assertEquals($data, $result);
410
		$result = $TestModel->validates();
411
		$this->assertTrue($result);
412
 
413
		$data = array('TestValidate' => array(
414
			'title' => 'title',
415
			'number' => 3
416
		));
417
		$result = $TestModel->create($data);
418
		$this->assertEquals($data, $result);
419
		$result = $TestModel->validates();
420
		$this->assertTrue($result);
421
 
422
		$TestModel->validate = array(
423
			'number' => array(
424
				'rule' => 'validateNumber',
425
				'min' => 5,
426
				'max' => 10
427
			),
428
			'title' => array(
429
				'allowEmpty' => false,
430
				'rule' => 'notEmpty'
431
		));
432
 
433
		$data = array('TestValidate' => array(
434
			'title' => 'title',
435
			'number' => '3'
436
		));
437
		$result = $TestModel->create($data);
438
		$this->assertEquals($data, $result);
439
		$result = $TestModel->validates();
440
		$this->assertFalse($result);
441
 
442
		$data = array('TestValidate' => array(
443
			'title' => 'title',
444
			'number' => 3
445
		));
446
		$result = $TestModel->create($data);
447
		$this->assertEquals($data, $result);
448
		$result = $TestModel->validates();
449
		$this->assertFalse($result);
450
 
451
		$TestModel->validate = array(
452
			'title' => array(
453
				'allowEmpty' => false,
454
				'rule' => 'validateTitle'
455
		));
456
 
457
		$data = array('TestValidate' => array('title' => ''));
458
		$result = $TestModel->create($data);
459
		$this->assertEquals($data, $result);
460
		$result = $TestModel->validates();
461
		$this->assertFalse($result);
462
 
463
		$data = array('TestValidate' => array('title' => 'new title'));
464
		$result = $TestModel->create($data);
465
		$this->assertEquals($data, $result);
466
		$result = $TestModel->validates();
467
		$this->assertFalse($result);
468
 
469
		$data = array('TestValidate' => array('title' => 'title-new'));
470
		$result = $TestModel->create($data);
471
		$this->assertEquals($data, $result);
472
		$result = $TestModel->validates();
473
		$this->assertTrue($result);
474
 
475
		$TestModel->validate = array('title' => array(
476
			'allowEmpty' => true,
477
			'rule' => 'validateTitle'
478
		));
479
		$data = array('TestValidate' => array('title' => ''));
480
		$result = $TestModel->create($data);
481
		$this->assertEquals($data, $result);
482
		$result = $TestModel->validates();
483
		$this->assertTrue($result);
484
 
485
		$TestModel->validate = array(
486
			'title' => array(
487
				'length' => array(
488
					'allowEmpty' => true,
489
					'rule' => array('maxLength', 10)
490
		)));
491
		$data = array('TestValidate' => array('title' => ''));
492
		$result = $TestModel->create($data);
493
		$this->assertEquals($data, $result);
494
		$result = $TestModel->validates();
495
		$this->assertTrue($result);
496
 
497
		$TestModel->validate = array(
498
			'title' => array(
499
				'rule' => array('userDefined', 'Article', 'titleDuplicate')
500
		));
501
		$data = array('TestValidate' => array('title' => 'My Article Title'));
502
		$result = $TestModel->create($data);
503
		$this->assertEquals($data, $result);
504
		$result = $TestModel->validates();
505
		$this->assertFalse($result);
506
 
507
		$data = array('TestValidate' => array(
508
			'title' => 'My Article With a Different Title'
509
		));
510
		$result = $TestModel->create($data);
511
		$this->assertEquals($data, $result);
512
		$result = $TestModel->validates();
513
		$this->assertTrue($result);
514
 
515
		$TestModel->validate = array(
516
			'title' => array(
517
				'tooShort' => array('rule' => array('minLength', 50)),
518
				'onlyLetters' => array('rule' => '/^[a-z]+$/i')
519
			),
520
		);
521
		$data = array('TestValidate' => array(
522
			'title' => 'I am a short string'
523
		));
524
		$TestModel->create($data);
525
		$result = $TestModel->validates();
526
		$this->assertFalse($result);
527
		$result = $TestModel->validationErrors;
528
		$expected = array(
529
			'title' => array('tooShort')
530
		);
531
		$this->assertEquals($expected, $result);
532
 
533
		$TestModel->validate = array(
534
			'title' => array(
535
				'tooShort' => array(
536
					'rule' => array('minLength', 50),
537
					'last' => false
538
				),
539
				'onlyLetters' => array('rule' => '/^[a-z]+$/i')
540
			),
541
		);
542
		$data = array('TestValidate' => array(
543
			'title' => 'I am a short string'
544
		));
545
		$TestModel->create($data);
546
		$result = $TestModel->validates();
547
		$this->assertFalse($result);
548
		$result = $TestModel->validationErrors;
549
		$expected = array(
550
			'title' => array('tooShort', 'onlyLetters')
551
		);
552
		$this->assertEquals($expected, $result);
553
		$result = $TestModel->validationErrors;
554
		$this->assertEquals($expected, $result);
555
	}
556
 
557
/**
558
 * test that validates() checks all the 'with' associations as well for validation
559
 * as this can cause partial/wrong data insertion.
560
 *
561
 * @return void
562
 */
563
	public function testValidatesWithAssociations() {
564
		$this->loadFixtures('Something', 'SomethingElse', 'JoinThing');
565
		$data = array(
566
			'Something' => array(
567
				'id' => 5,
568
				'title' => 'Extra Fields',
569
				'body' => 'Extra Fields Body',
570
				'published' => '1'
571
			),
572
			'SomethingElse' => array(
573
				array('something_else_id' => 1, 'doomed' => '')
574
			)
575
		);
576
 
577
		$Something = new Something();
578
		$JoinThing = $Something->JoinThing;
579
 
580
		$JoinThing->validate = array('doomed' => array('rule' => 'notEmpty'));
581
 
582
		$expectedError = array('doomed' => array('This field cannot be left blank'));
583
 
584
		$Something->create();
585
		$result = $Something->save($data);
586
		$this->assertFalse($result, 'Save occurred even when with models failed. %s');
587
		$this->assertEquals($expectedError, $JoinThing->validationErrors);
588
		$count = $Something->find('count', array('conditions' => array('Something.id' => $data['Something']['id'])));
589
		$this->assertSame(0, $count);
590
 
591
		$data = array(
592
			'Something' => array(
593
				'id' => 5,
594
				'title' => 'Extra Fields',
595
				'body' => 'Extra Fields Body',
596
				'published' => '1'
597
			),
598
			'SomethingElse' => array(
599
				array('something_else_id' => 1, 'doomed' => 1),
600
				array('something_else_id' => 1, 'doomed' => '')
601
			)
602
		);
603
		$Something->create();
604
		$result = $Something->save($data);
605
		$this->assertFalse($result, 'Save occurred even when with models failed. %s');
606
 
607
		$joinRecords = $JoinThing->find('count', array(
608
			'conditions' => array('JoinThing.something_id' => $data['Something']['id'])
609
		));
610
		$this->assertEquals(0, $joinRecords, 'Records were saved on the join table. %s');
611
	}
612
 
613
/**
614
 * test that saveAll and with models with validation interact well
615
 *
616
 * @return void
617
 */
618
	public function testValidatesWithModelsAndSaveAll() {
619
		$this->loadFixtures('Something', 'SomethingElse', 'JoinThing');
620
		$data = array(
621
			'Something' => array(
622
				'id' => 5,
623
				'title' => 'Extra Fields',
624
				'body' => 'Extra Fields Body',
625
				'published' => '1'
626
			),
627
			'SomethingElse' => array(
628
				array('something_else_id' => 1, 'doomed' => '')
629
			)
630
		);
631
		$Something = new Something();
632
		$JoinThing = $Something->JoinThing;
633
 
634
		$JoinThing->validate = array('doomed' => array('rule' => 'notEmpty'));
635
		$expectedError = array('doomed' => array('This field cannot be left blank'));
636
 
637
		$Something->create();
638
		$result = $Something->saveAll($data, array('validate' => 'only'));
639
		$this->assertFalse($result);
640
		$result = $Something->validateAssociated($data);
641
		$this->assertFalse($result);
642
		$this->assertEquals($expectedError, $JoinThing->validationErrors);
643
		$result = $Something->validator()->validateAssociated($data);
644
		$this->assertFalse($result);
645
 
646
		$Something->create();
647
		$result = $Something->saveAll($data, array('validate' => 'first'));
648
		$this->assertFalse($result);
649
		$this->assertEquals($expectedError, $JoinThing->validationErrors);
650
 
651
		$count = $Something->find('count', array('conditions' => array('Something.id' => $data['Something']['id'])));
652
		$this->assertSame(0, $count);
653
 
654
		$joinRecords = $JoinThing->find('count', array(
655
			'conditions' => array('JoinThing.something_id' => $data['Something']['id'])
656
		));
657
		$this->assertEquals(0, $joinRecords, 'Records were saved on the join table. %s');
658
	}
659
 
660
/**
661
 * test that saveAll and with models at initial insert (no id has set yet)
662
 * with validation interact well
663
 *
664
 * @return void
665
 */
666
	public function testValidatesWithModelsAndSaveAllWithoutId() {
667
		$this->loadFixtures('Post', 'Author');
668
 
669
		$data = array(
670
			'Author' => array(
671
				'name' => 'Foo Bar',
672
			),
673
			'Post' => array(
674
				array('title' => 'Hello'),
675
				array('title' => 'World'),
676
			)
677
		);
678
		$Author = new Author();
679
		$Post = $Author->Post;
680
 
681
		$Post->validate = array('author_id' => array('rule' => 'numeric'));
682
 
683
		$Author->create();
684
		$result = $Author->saveAll($data, array('validate' => 'only'));
685
		$this->assertTrue($result);
686
		$result = $Author->validateAssociated($data);
687
		$this->assertTrue($result);
688
		$this->assertTrue($result);
689
 
690
		$Author->create();
691
		$result = $Author->saveAll($data, array('validate' => 'first'));
692
		$this->assertTrue($result);
693
		$this->assertNotNull($Author->id);
694
 
695
		$id = $Author->id;
696
		$count = $Author->find('count', array('conditions' => array('Author.id' => $id)));
697
		$this->assertSame(1, $count);
698
 
699
		$count = $Post->find('count', array(
700
			'conditions' => array('Post.author_id' => $id)
701
		));
702
		$this->assertEquals($count, count($data['Post']));
703
	}
704
 
705
/**
706
 * Test that missing validation methods trigger errors in development mode.
707
 * Helps to make development easier.
708
 *
709
 * @expectedException PHPUnit_Framework_Error
710
 * @return void
711
 */
712
	public function testMissingValidationErrorTriggering() {
713
		Configure::write('debug', 2);
714
 
715
		$TestModel = new ValidationTest1();
716
		$TestModel->create(array('title' => 'foo'));
717
		$TestModel->validate = array(
718
			'title' => array(
719
				'rule' => array('thisOneBringsThePain'),
720
				'required' => true
721
			)
722
		);
723
		$TestModel->invalidFields(array('fieldList' => array('title')));
724
	}
725
 
726
/**
727
 * Test placeholder replacement when validation message is an array
728
 *
729
 * @return void
730
 */
731
	public function testValidationMessageAsArray() {
732
		$TestModel = new ValidationTest1();
733
		$TestModel->validate = array(
734
			'title' => array(
735
				'minLength' => array(
736
					'rule' => array('minLength', 6),
737
					'required' => true,
738
					'message' => 'Minimum length allowed is %d chars',
739
					'last' => false
740
				),
741
				'between' => array(
742
					'rule' => array('between', 5, 15),
743
					'message' => array('You may enter up to %s chars (minimum is %s chars)', 14, 6)
744
				)
745
			)
746
		);
747
 
748
		$TestModel->create();
749
		$expected = array(
750
			'title' => array(
751
				'Minimum length allowed is 6 chars',
752
			)
753
		);
754
		$TestModel->invalidFields();
755
		$this->assertEquals($expected, $TestModel->validationErrors);
756
 
757
		$TestModel->create(array('title' => 'foo'));
758
		$expected = array(
759
			'title' => array(
760
				'Minimum length allowed is 6 chars',
761
				'You may enter up to 14 chars (minimum is 6 chars)'
762
			)
763
		);
764
		$TestModel->invalidFields();
765
		$this->assertEquals($expected, $TestModel->validationErrors);
766
	}
767
 
768
/**
769
 * Test validation message translation
770
 *
771
 * @return void
772
 */
773
	public function testValidationMessageTranslation() {
774
		$lang = Configure::read('Config.language');
775
		Configure::write('Config.language', 'en');
776
		App::build(array(
777
			'Locale' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Locale' . DS),
778
		), App::RESET);
779
 
780
		$TestModel = new ValidationTest1();
781
		$TestModel->validationDomain = 'validation_messages';
782
		$TestModel->validate = array(
783
			'title' => array(
784
				array(
785
					'rule' => array('customValidationMethod', 'arg1'),
786
					'required' => true,
787
					'message' => 'Validation failed: %s'
788
				)
789
			)
790
		);
791
 
792
		$TestModel->create();
793
		$expected = array(
794
			'title' => array(
795
				'Translated validation failed: Translated arg1',
796
			)
797
		);
798
		$TestModel->invalidFields();
799
		$this->assertEquals($expected, $TestModel->validationErrors);
800
 
801
		$TestModel->validationDomain = 'default';
802
		Configure::write('Config.language', $lang);
803
		App::build();
804
	}
805
 
806
/**
807
 * Test for 'on' => [create|update] in validation rules.
808
 *
809
 * @return void
810
 */
811
	public function testStateValidation() {
812
		$this->loadFixtures('Article');
813
		$Article = new Article();
814
 
815
		$data = array(
816
			'Article' => array(
817
				'title' => '',
818
				'body' => 'Extra Fields Body',
819
				'published' => '1'
820
			)
821
		);
822
 
823
		$Article->validate = array(
824
			'title' => array(
825
				'notempty' => array(
826
					'rule' => 'notEmpty',
827
					'on' => 'create'
828
				)
829
			)
830
		);
831
 
832
		$Article->create($data);
833
		$this->assertFalse($Article->validates());
834
 
835
		$Article->save(null, array('validate' => false));
836
		$data['Article']['id'] = $Article->id;
837
		$Article->set($data);
838
		$this->assertTrue($Article->validates());
839
 
840
		unset($data['Article']['id']);
841
		$Article->validate = array(
842
			'title' => array(
843
				'notempty' => array(
844
					'rule' => 'notEmpty',
845
					'on' => 'update'
846
				)
847
			)
848
		);
849
 
850
		$Article->create($data);
851
		$this->assertTrue($Article->validates());
852
 
853
		$Article->save(null, array('validate' => false));
854
		$data['Article']['id'] = $Article->id;
855
		$Article->set($data);
856
		$this->assertFalse($Article->validates());
857
	}
858
 
859
/**
860
 * Test for 'required' => [create|update] in validation rules.
861
 *
862
 * @return void
863
 */
864
	public function testStateRequiredValidation() {
865
		$this->loadFixtures('Article');
866
		$Article = new Article();
867
 
868
		// no title field present
869
		$data = array(
870
			'Article' => array(
871
				'body' => 'Extra Fields Body',
872
				'published' => '1'
873
			)
874
		);
875
 
876
		$Article->validate = array(
877
			'title' => array(
878
				'notempty' => array(
879
					'rule' => 'notEmpty',
880
					'required' => 'create'
881
				)
882
			)
883
		);
884
 
885
		$Article->create($data);
886
		$this->assertFalse($Article->validates());
887
 
888
		$Article->save(null, array('validate' => false));
889
		$data['Article']['id'] = $Article->id;
890
		$Article->set($data);
891
		$this->assertTrue($Article->validates());
892
 
893
		unset($data['Article']['id']);
894
		$Article->validate = array(
895
			'title' => array(
896
				'notempty' => array(
897
					'rule' => 'notEmpty',
898
					'required' => 'update'
899
				)
900
			)
901
		);
902
 
903
		$Article->create($data);
904
		$this->assertTrue($Article->validates());
905
 
906
		$Article->save(null, array('validate' => false));
907
		$data['Article']['id'] = $Article->id;
908
		$Article->set($data);
909
		$this->assertFalse($Article->validates());
910
	}
911
 
912
/**
913
 * Test that 'required' and 'on' are not conflicting
914
 *
915
 * @return void
916
 */
917
	public function testOnRequiredConflictValidation() {
918
		$this->loadFixtures('Article');
919
		$Article = new Article();
920
 
921
		// no title field present
922
		$data = array(
923
			'Article' => array(
924
				'body' => 'Extra Fields Body',
925
				'published' => '1'
926
			)
927
		);
928
 
929
		$Article->validate = array(
930
			'title' => array(
931
				'notempty' => array(
932
					'rule' => 'notEmpty',
933
					'required' => 'create',
934
					'on' => 'create'
935
				)
936
			)
937
		);
938
 
939
		$Article->create($data);
940
		$this->assertFalse($Article->validates());
941
 
942
		$Article->validate = array(
943
			'title' => array(
944
				'notempty' => array(
945
					'rule' => 'notEmpty',
946
					'required' => 'update',
947
					'on' => 'create'
948
				)
949
			)
950
		);
951
 
952
		$Article->create($data);
953
		$this->assertTrue($Article->validates());
954
 
955
		$Article->validate = array(
956
			'title' => array(
957
				'notempty' => array(
958
					'rule' => 'notEmpty',
959
					'required' => 'create',
960
					'on' => 'update'
961
				)
962
			)
963
		);
964
 
965
		$Article->create($data);
966
		$this->assertTrue($Article->validates());
967
 
968
		$Article->validate = array(
969
			'title' => array(
970
				'notempty' => array(
971
					'rule' => 'notEmpty',
972
					'required' => 'update',
973
					'on' => 'update'
974
				)
975
			)
976
		);
977
 
978
		$Article->create($data);
979
		$this->assertTrue($Article->validates());
980
 
981
		$Article->validate = array(
982
			'title' => array(
983
				'notempty' => array(
984
					'rule' => 'notEmpty',
985
					'required' => 'create',
986
					'on' => 'create'
987
				)
988
			)
989
		);
990
 
991
		$Article->save(null, array('validate' => false));
992
		$data['Article']['id'] = $Article->id;
993
		$Article->set($data);
994
		$this->assertTrue($Article->validates());
995
 
996
		$Article->validate = array(
997
			'title' => array(
998
				'notempty' => array(
999
					'rule' => 'notEmpty',
1000
					'required' => 'update',
1001
					'on' => 'create'
1002
				)
1003
			)
1004
		);
1005
 
1006
		$Article->set($data);
1007
		$this->assertTrue($Article->validates());
1008
 
1009
		$Article->validate = array(
1010
			'title' => array(
1011
				'notempty' => array(
1012
					'rule' => 'notEmpty',
1013
					'required' => 'create',
1014
					'on' => 'update'
1015
				)
1016
			)
1017
		);
1018
 
1019
		$Article->set($data);
1020
		$this->assertTrue($Article->validates());
1021
 
1022
		$Article->validate = array(
1023
			'title' => array(
1024
				'notempty' => array(
1025
					'rule' => 'notEmpty',
1026
					'required' => 'update',
1027
					'on' => 'update'
1028
				)
1029
			)
1030
		);
1031
 
1032
		$Article->set($data);
1033
		$this->assertFalse($Article->validates());
1034
	}
1035
 
1036
/**
1037
 * testSaveAllDeepValidateOnly
1038
 * tests the validate methods with deeper recursive data
1039
 *
1040
 * @return void
1041
 */
1042
	public function testSaveAllDeepValidateOnly() {
1043
		$this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
1044
		$TestModel = new Article();
1045
		$TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
1046
		$TestModel->hasAndBelongsToMany = array();
1047
		$TestModel->Comment->Attachment->validate['attachment'] = 'notEmpty';
1048
		$TestModel->Comment->validate['comment'] = 'notEmpty';
1049
 
1050
		$data = array(
1051
			'Article' => array('id' => 2),
1052
			'Comment' => array(
1053
				array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => 'newuser', 'password' => 'newuserpass')),
1054
				array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
1055
			)
1056
		);
1057
		$result = $TestModel->saveAll($data, array('validate' => 'only', 'deep' => true));
1058
		$this->assertTrue($result);
1059
		$result = $TestModel->validateAssociated($data, array('deep' => true));
1060
		$this->assertTrue($result);
1061
 
1062
		$data = array(
1063
			'Article' => array('id' => 2),
1064
			'Comment' => array(
1065
				array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
1066
				array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
1067
			)
1068
		);
1069
		$result = $TestModel->saveAll($data, array('validate' => 'only', 'deep' => true));
1070
		$this->assertFalse($result);
1071
		$result = $TestModel->validateAssociated($data, array('deep' => true));
1072
		$this->assertFalse($result);
1073
 
1074
		$data = array(
1075
			'Article' => array('id' => 2),
1076
			'Comment' => array(
1077
				array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => 'newuser', 'password' => 'newuserpass')),
1078
				array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
1079
			)
1080
		);
1081
		$expected = array(
1082
			'Article' => true,
1083
			'Comment' => array(
1084
				true,
1085
				true
1086
			)
1087
		);
1088
		$result = $TestModel->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
1089
		$this->assertSame($expected, $result);
1090
		$result = $TestModel->validateAssociated($data, array('atomic' => false, 'deep' => true));
1091
		$this->assertSame($expected, $result);
1092
 
1093
		$data = array(
1094
			'Article' => array('id' => 2),
1095
			'Comment' => array(
1096
				array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
1097
				array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
1098
			)
1099
		);
1100
		$expected = array(
1101
			'Article' => true,
1102
			'Comment' => array(
1103
				false,
1104
				true
1105
			)
1106
		);
1107
		$result = $TestModel->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
1108
		$this->assertSame($expected, $result);
1109
		$result = $TestModel->validateAssociated($data, array('atomic' => false, 'deep' => true));
1110
		$this->assertSame($expected, $result);
1111
 
1112
		$data = array(
1113
			'Article' => array('id' => 2),
1114
			'Comment' => array(
1115
				array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
1116
				array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => 'deepsaved'))
1117
			)
1118
		);
1119
		$result = $TestModel->saveAll($data, array('validate' => 'only', 'deep' => true));
1120
		$this->assertTrue($result);
1121
		$result = $TestModel->validateAssociated($data, array('deep' => true));
1122
		$this->assertTrue($result);
1123
 
1124
		$data = array(
1125
			'Article' => array('id' => 2),
1126
			'Comment' => array(
1127
				array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
1128
				array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
1129
			)
1130
		);
1131
		$result = $TestModel->saveAll($data, array('validate' => 'only', 'deep' => true));
1132
		$this->assertFalse($result);
1133
		$result = $TestModel->validateAssociated($data, array('deep' => true));
1134
		$this->assertFalse($result);
1135
 
1136
		$data = array(
1137
			'Article' => array('id' => 2),
1138
			'Comment' => array(
1139
				array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
1140
				array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => 'deepsave'))
1141
			)
1142
		);
1143
		$expected = array(
1144
			'Article' => true,
1145
			'Comment' => array(
1146
				true,
1147
				true
1148
			)
1149
		);
1150
		$result = $TestModel->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
1151
		$this->assertSame($expected, $result);
1152
		$result = $TestModel->validateAssociated($data, array('atomic' => false, 'deep' => true));
1153
		$this->assertSame($expected, $result);
1154
 
1155
		$data = array(
1156
			'Article' => array('id' => 2),
1157
			'Comment' => array(
1158
				array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
1159
				array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
1160
			)
1161
		);
1162
		$expected = array(
1163
			'Article' => true,
1164
			'Comment' => array(
1165
				true,
1166
				false
1167
			)
1168
		);
1169
		$result = $TestModel->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
1170
		$this->assertSame($expected, $result);
1171
		$result = $TestModel->validateAssociated($data, array('atomic' => false, 'deep' => true));
1172
		$this->assertSame($expected, $result);
1173
 
1174
		$expected = array(
1175
			'Comment' => array(
1176
				1 => array(
1177
					'Attachment' => array(
1178
						'attachment' => array('This field cannot be left blank')
1179
					)
1180
				)
1181
			)
1182
		);
1183
		$result = $TestModel->validationErrors;
1184
		$this->assertSame($expected, $result);
1185
 
1186
		$data = array(
1187
			'Attachment' => array(
1188
				'attachment' => 'deepsave insert',
1189
			),
1190
			'Comment' => array(
1191
				'comment' => 'First comment deepsave insert',
1192
				'published' => 'Y',
1193
				'user_id' => 5,
1194
				'Article' => array(
1195
					'title' => 'First Article deepsave insert',
1196
					'body' => 'First Article Body deepsave insert',
1197
					'User' => array(
1198
						'user' => 'deepsave',
1199
						'password' => 'magic'
1200
					),
1201
				),
1202
			)
1203
		);
1204
 
1205
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
1206
		$this->assertTrue($result);
1207
		$result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => true));
1208
		$this->assertTrue($result);
1209
 
1210
		$expected = array(
1211
			'Attachment' => true,
1212
			'Comment' => true
1213
		);
1214
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
1215
		$this->assertSame($expected, $result);
1216
		$result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => true));
1217
		$this->assertSame($expected, $result);
1218
 
1219
		$data = array(
1220
			'Attachment' => array(
1221
				'attachment' => 'deepsave insert',
1222
			),
1223
			'Comment' => array(
1224
				'comment' => 'First comment deepsave insert',
1225
				'published' => 'Y',
1226
				'user_id' => 5,
1227
				'Article' => array(
1228
					'title' => 'First Article deepsave insert',
1229
					'body' => 'First Article Body deepsave insert',
1230
					'User' => array(
1231
						'user' => '',
1232
						'password' => 'magic'
1233
					),
1234
				),
1235
			)
1236
		);
1237
 
1238
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
1239
		$this->assertFalse($result);
1240
		$result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => true));
1241
		$this->assertFalse($result);
1242
 
1243
		$result = $TestModel->Comment->Attachment->validationErrors;
1244
		$expected = array(
1245
			'Comment' => array(
1246
				'Article' => array(
1247
					'User' => array(
1248
						'user' => array('This field cannot be left blank')
1249
					)
1250
				)
1251
			)
1252
		);
1253
		$this->assertSame($expected, $result);
1254
 
1255
		$expected = array(
1256
			'Attachment' => true,
1257
			'Comment' => false
1258
		);
1259
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
1260
		$this->assertEquals($expected, $result);
1261
		$result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => true));
1262
		$this->assertEquals($expected, $result);
1263
 
1264
		$data['Comment']['Article']['body'] = '';
1265
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
1266
		$this->assertFalse($result);
1267
		$result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => true));
1268
		$this->assertFalse($result);
1269
 
1270
		$result = $TestModel->Comment->Attachment->validationErrors;
1271
		$expected = array(
1272
			'Comment' => array(
1273
				'Article' => array(
1274
					'body' => array('This field cannot be left blank'),
1275
					'User' => array(
1276
						'user' => array('This field cannot be left blank')
1277
					)
1278
				)
1279
			)
1280
		);
1281
		$this->assertSame($expected, $result);
1282
 
1283
		$expected = array(
1284
			'Attachment' => true,
1285
			'Comment' => false
1286
		);
1287
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
1288
		$this->assertEquals($expected, $result);
1289
		$result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => true));
1290
		$this->assertEquals($expected, $result);
1291
 
1292
		$data['Comment']['comment'] = '';
1293
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
1294
		$this->assertFalse($result);
1295
		$result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => true));
1296
		$this->assertFalse($result);
1297
 
1298
		$result = $TestModel->Comment->Attachment->validationErrors;
1299
		$expected = array(
1300
			'Comment' => array(
1301
				'comment' => array('This field cannot be left blank'),
1302
				'Article' => array(
1303
					'body' => array('This field cannot be left blank'),
1304
					'User' => array(
1305
						'user' => array('This field cannot be left blank')
1306
					)
1307
				)
1308
			)
1309
		);
1310
		$this->assertSame($expected, $result);
1311
 
1312
		$expected = array(
1313
			'Attachment' => true,
1314
			'Comment' => false
1315
		);
1316
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
1317
		$this->assertEquals($expected, $result);
1318
		$result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => true));
1319
		$this->assertEquals($expected, $result);
1320
 
1321
		$data['Attachment']['attachment'] = '';
1322
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
1323
		$this->assertFalse($result);
1324
		$result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => true));
1325
		$this->assertFalse($result);
1326
 
1327
		$result = $TestModel->Comment->Attachment->validationErrors;
1328
		$expected = array(
1329
			'attachment' => array('This field cannot be left blank'),
1330
			'Comment' => array(
1331
				'comment' => array('This field cannot be left blank'),
1332
				'Article' => array(
1333
					'body' => array('This field cannot be left blank'),
1334
					'User' => array(
1335
						'user' => array('This field cannot be left blank')
1336
					)
1337
				)
1338
			)
1339
		);
1340
		$this->assertSame($expected, $result);
1341
 
1342
		$result = $TestModel->Comment->validationErrors;
1343
		$expected = array(
1344
			'comment' => array('This field cannot be left blank'),
1345
			'Article' => array(
1346
					'body' => array('This field cannot be left blank'),
1347
					'User' => array(
1348
						'user' => array('This field cannot be left blank')
1349
					)
1350
				)
1351
		);
1352
		$this->assertSame($expected, $result);
1353
 
1354
		$expected = array(
1355
			'Attachment' => false,
1356
			'Comment' => false
1357
		);
1358
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
1359
		$this->assertEquals($expected, $result);
1360
		$result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => true));
1361
		$this->assertEquals($expected, $result);
1362
	}
1363
 
1364
/**
1365
 * testSaveAllNotDeepValidateOnly
1366
 * tests the validate methods to not validate deeper recursive data
1367
 *
1368
 * @return void
1369
 */
1370
	public function testSaveAllNotDeepValidateOnly() {
1371
		$this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
1372
		$TestModel = new Article();
1373
		$TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
1374
		$TestModel->hasAndBelongsToMany = array();
1375
		$TestModel->Comment->Attachment->validate['attachment'] = 'notEmpty';
1376
		$TestModel->Comment->validate['comment'] = 'notEmpty';
1377
 
1378
		$data = array(
1379
			'Article' => array('id' => 2, 'body' => ''),
1380
			'Comment' => array(
1381
				array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
1382
				array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
1383
			)
1384
		);
1385
		$result = $TestModel->saveAll($data, array('validate' => 'only', 'deep' => false));
1386
		$this->assertFalse($result);
1387
		$result = $TestModel->validateAssociated($data, array('deep' => false));
1388
		$this->assertFalse($result);
1389
 
1390
		$expected = array('body' => array('This field cannot be left blank'));
1391
		$result = $TestModel->validationErrors;
1392
		$this->assertSame($expected, $result);
1393
 
1394
		$data = array(
1395
			'Article' => array('id' => 2, 'body' => 'Ignore invalid user data'),
1396
			'Comment' => array(
1397
				array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
1398
				array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
1399
			)
1400
		);
1401
		$result = $TestModel->saveAll($data, array('validate' => 'only', 'deep' => false));
1402
		$this->assertTrue($result);
1403
		$result = $TestModel->validateAssociated($data, array('deep' => false));
1404
		$this->assertTrue($result);
1405
 
1406
		$data = array(
1407
			'Article' => array('id' => 2, 'body' => 'Ignore invalid user data'),
1408
			'Comment' => array(
1409
				array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
1410
				array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
1411
			)
1412
		);
1413
		$expected = array(
1414
			'Article' => true,
1415
			'Comment' => array(
1416
				true,
1417
				true
1418
			)
1419
		);
1420
		$result = $TestModel->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => false));
1421
		$this->assertSame($expected, $result);
1422
		$result = $TestModel->validateAssociated($data, array('atomic' => false, 'deep' => false));
1423
		$this->assertSame($expected, $result);
1424
 
1425
		$data = array(
1426
			'Article' => array('id' => 2, 'body' => 'Ignore invalid attachment data'),
1427
			'Comment' => array(
1428
				array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
1429
				array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
1430
			)
1431
		);
1432
		$result = $TestModel->saveAll($data, array('validate' => 'only', 'deep' => false));
1433
		$this->assertTrue($result);
1434
		$result = $TestModel->validateAssociated($data, array('deep' => false));
1435
		$this->assertTrue($result);
1436
 
1437
		$data = array(
1438
			'Article' => array('id' => 2, 'body' => 'Ignore invalid attachment data'),
1439
			'Comment' => array(
1440
				array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
1441
				array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
1442
			)
1443
		);
1444
		$expected = array(
1445
			'Article' => true,
1446
			'Comment' => array(
1447
				true,
1448
				true
1449
			)
1450
		);
1451
		$result = $TestModel->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => false));
1452
		$this->assertSame($expected, $result);
1453
		$result = $TestModel->validateAssociated($data, array('atomic' => false, 'deep' => false));
1454
		$this->assertSame($expected, $result);
1455
 
1456
		$expected = array();
1457
		$result = $TestModel->validationErrors;
1458
		$this->assertSame($expected, $result);
1459
 
1460
		$data = array(
1461
			'Attachment' => array(
1462
				'attachment' => 'deepsave insert',
1463
			),
1464
			'Comment' => array(
1465
				'comment' => 'First comment deepsave insert',
1466
				'published' => 'Y',
1467
				'user_id' => 5,
1468
				'Article' => array(
1469
					'title' => 'First Article deepsave insert ignored',
1470
					'body' => 'First Article Body deepsave insert',
1471
					'User' => array(
1472
						'user' => '',
1473
						'password' => 'magic'
1474
					),
1475
				),
1476
			)
1477
		);
1478
 
1479
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => false));
1480
		$this->assertTrue($result);
1481
		$result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => false));
1482
		$this->assertTrue($result);
1483
 
1484
		$result = $TestModel->Comment->Attachment->validationErrors;
1485
		$expected = array();
1486
		$this->assertSame($expected, $result);
1487
 
1488
		$expected = array(
1489
			'Attachment' => true,
1490
			'Comment' => true
1491
		);
1492
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => false));
1493
		$this->assertEquals($expected, $result);
1494
		$result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => false));
1495
		$this->assertEquals($expected, $result);
1496
 
1497
		$data['Comment']['Article']['body'] = '';
1498
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => false));
1499
		$this->assertTrue($result);
1500
		$result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => false));
1501
		$this->assertTrue($result);
1502
 
1503
		$result = $TestModel->Comment->Attachment->validationErrors;
1504
		$expected = array();
1505
		$this->assertSame($expected, $result);
1506
 
1507
		$expected = array(
1508
			'Attachment' => true,
1509
			'Comment' => true
1510
		);
1511
		$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => false));
1512
		$this->assertEquals($expected, $result);
1513
		$result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => false));
1514
		$this->assertEquals($expected, $result);
1515
	}
1516
 
1517
/**
1518
 * testValidateAssociated method
1519
 *
1520
 * @return void
1521
 */
1522
	public function testValidateAssociated() {
1523
		$this->loadFixtures('Comment', 'Attachment', 'Article', 'User');
1524
		$TestModel = new Comment();
1525
		$TestModel->Attachment->validate = array('attachment' => 'notEmpty');
1526
 
1527
		$data = array(
1528
			'Comment' => array(
1529
				'comment' => 'This is the comment'
1530
			),
1531
			'Attachment' => array(
1532
				'attachment' => ''
1533
			)
1534
		);
1535
		$result = $TestModel->saveAll($data, array('validate' => 'only'));
1536
		$this->assertFalse($result);
1537
		$result = $TestModel->validateAssociated($data);
1538
		$this->assertFalse($result);
1539
 
1540
		$fieldList = array(
1541
			'Attachment' => array('comment_id')
1542
		);
1543
		$result = $TestModel->saveAll($data, array(
1544
			'fieldList' => $fieldList, 'validate' => 'only'
1545
		));
1546
		$this->assertTrue($result);
1547
		$this->assertEmpty($TestModel->validationErrors);
1548
		$result = $TestModel->validateAssociated($data, array('fieldList' => $fieldList));
1549
		$this->assertTrue($result);
1550
		$this->assertEmpty($TestModel->validationErrors);
1551
 
1552
		$TestModel->validate = array('comment' => 'notEmpty');
1553
		$record = array(
1554
			'Comment' => array(
1555
				'user_id' => 1,
1556
				'article_id' => 1,
1557
				'comment' => '',
1558
			),
1559
			'Attachment' => array(
1560
				'attachment' => ''
1561
			)
1562
		);
1563
		$result = $TestModel->saveAll($record, array('validate' => 'only'));
1564
		$this->assertFalse($result);
1565
		$result = $TestModel->validateAssociated($record);
1566
		$this->assertFalse($result);
1567
 
1568
		$fieldList = array(
1569
			'Comment' => array('id', 'article_id', 'user_id'),
1570
			'Attachment' => array('comment_id')
1571
		);
1572
		$result = $TestModel->saveAll($record, array(
1573
			'fieldList' => $fieldList, 'validate' => 'only'
1574
		));
1575
		$this->assertTrue($result);
1576
		$this->assertEmpty($TestModel->validationErrors);
1577
		$result = $TestModel->validateAssociated($record, array('fieldList' => $fieldList));
1578
		$this->assertTrue($result);
1579
		$this->assertEmpty($TestModel->validationErrors);
1580
 
1581
		$TestModel = new Article();
1582
		$TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
1583
		$TestModel->Comment->validate = array('comment' => 'notEmpty');
1584
		$data = array(
1585
			'Article' => array('id' => 2),
1586
			'Comment' => array(
1587
				array(
1588
					'id' => 1,
1589
					'comment' => '',
1590
					'published' => 'Y',
1591
					'user_id' => 1,
1592
				),
1593
				array(
1594
					'id' => 2,
1595
					'comment' =>
1596
					'comment',
1597
					'published' => 'Y',
1598
					'user_id' => 1
1599
				),
1600
				array(
1601
					'id' => 3,
1602
					'comment' => '',
1603
					'published' => 'Y',
1604
					'user_id' => 1
1605
		)));
1606
		$result = $TestModel->saveAll($data, array('validate' => 'only'));
1607
		$this->assertFalse($result);
1608
		$result = $TestModel->validateAssociated($data);
1609
		$this->assertFalse($result);
1610
 
1611
		$expected = array(
1612
			'Article' => true,
1613
			'Comment' => array(false, true, false)
1614
		);
1615
		$result = $TestModel->saveAll($data, array('atomic' => false, 'validate' => 'only'));
1616
		$this->assertSame($expected, $result);
1617
		$result = $TestModel->validateAssociated($data, array('atomic' => false));
1618
		$this->assertSame($expected, $result);
1619
 
1620
		$expected = array('Comment' => array(
1621
 
1622
			2 => array('comment' => array('This field cannot be left blank'))
1623
		));
1624
		$this->assertEquals($expected['Comment'], $TestModel->Comment->validationErrors);
1625
 
1626
		$model = new Comment();
1627
		$model->deleteAll(true);
1628
		$model->validate = array('comment' => 'notEmpty');
1629
		$model->Attachment->validate = array('attachment' => 'notEmpty');
1630
		$model->Attachment->bindModel(array('belongsTo' => array('Comment')));
1631
		$expected = array(
1632
			'comment' => array('This field cannot be left blank'),
1633
			'Attachment' => array(
1634
				'attachment' => array('This field cannot be left blank')
1635
			)
1636
		);
1637
 
1638
		$data = array(
1639
			'Comment' => array('comment' => '', 'article_id' => 1, 'user_id' => 1),
1640
			'Attachment' => array('attachment' => '')
1641
		);
1642
		$result = $model->saveAll($data, array('validate' => 'only'));
1643
		$this->assertFalse($result);
1644
		$result = $model->validateAssociated($data);
1645
		$this->assertFalse($result);
1646
		$this->assertEquals($expected, $model->validationErrors);
1647
		$this->assertEquals($expected['Attachment'], $model->Attachment->validationErrors);
1648
	}
1649
 
1650
/**
1651
 * testValidateMany method
1652
 *
1653
 * @return void
1654
 */
1655
	public function testValidateMany() {
1656
		$TestModel = new Article();
1657
		$TestModel->validate = array('title' => 'notEmpty');
1658
		$data = array(
1659
 
1660
			1 => array('title' => 'title 1'),
1661
			2 => array('title' => 'title 2'),
1662
		);
1663
		$expected = array(
1664
 
1665
		);
1666
 
1667
		$result = $TestModel->saveAll($data, array('validate' => 'only'));
1668
		$this->assertFalse($result);
1669
		$this->assertEquals($expected, $TestModel->validationErrors);
1670
		$result = $TestModel->validateMany($data);
1671
		$this->assertFalse($result);
1672
		$this->assertEquals($expected, $TestModel->validationErrors);
1673
 
1674
		$data = array(
1675
 
1676
			1 => array('title' => ''),
1677
			2 => array('title' => 'title 2'),
1678
		);
1679
		$expected = array(
1680
			1 => array('title' => array('This field cannot be left blank')),
1681
		);
1682
		$result = $TestModel->saveAll($data, array('validate' => 'only'));
1683
		$this->assertFalse($result);
1684
		$this->assertEquals($expected, $TestModel->validationErrors);
1685
		$result = $TestModel->validateMany($data);
1686
		$this->assertFalse($result);
1687
		$this->assertEquals($expected, $TestModel->validationErrors);
1688
	}
1689
 
1690
/**
1691
 * testGetMethods method
1692
 *
1693
 * @return void
1694
 */
1695
	public function testGetMethods() {
1696
		$this->loadFixtures('Article', 'Comment');
1697
		$TestModel = new Article();
1698
		$Validator = $TestModel->validator();
1699
 
1700
		$result = $Validator->getMethods();
1701
 
1702
		$expected = array_map('strtolower', get_class_methods('Article'));
1703
		$this->assertEquals($expected, array_keys($result));
1704
	}
1705
 
1706
/**
1707
 *  Tests that methods are refreshed when the list of behaviors change
1708
 *
1709
 * @return void
1710
 */
1711
	public function testGetMethodsRefresh() {
1712
		$this->loadFixtures('Article', 'Comment');
1713
		$TestModel = new Article();
1714
		$Validator = $TestModel->validator();
1715
 
1716
		$result = $Validator->getMethods();
1717
 
1718
		$expected = array_map('strtolower', get_class_methods('Article'));
1719
		$this->assertEquals($expected, array_keys($result));
1720
 
1721
		$TestModel->Behaviors->load('Containable');
1722
		$newList = array(
1723
			'contain',
1724
			'resetbindings',
1725
			'containments',
1726
			'fielddependencies',
1727
			'containmentsmap'
1728
		);
1729
		$this->assertEquals(array_merge($expected, $newList), array_keys($Validator->getMethods()));
1730
 
1731
		$TestModel->Behaviors->unload('Containable');
1732
		$this->assertEquals($expected, array_keys($Validator->getMethods()));
1733
	}
1734
 
1735
/**
1736
 * testSetValidationDomain method
1737
 *
1738
 * @return void
1739
 */
1740
	public function testSetValidationDomain() {
1741
		$this->loadFixtures('Article', 'Comment');
1742
		$TestModel = new Article();
1743
		$Validator = $TestModel->validator();
1744
 
1745
		$result = $Validator->setValidationDomain('default');
1746
		$this->assertEquals('default', $TestModel->validationDomain);
1747
 
1748
		$result = $Validator->setValidationDomain('other');
1749
		$this->assertEquals('other', $TestModel->validationDomain);
1750
	}
1751
 
1752
/**
1753
 * testGetModel method
1754
 *
1755
 * @return void
1756
 */
1757
	public function testGetModel() {
1758
		$TestModel = new Article();
1759
		$Validator = $TestModel->validator();
1760
 
1761
		$result = $Validator->getModel();
1762
		$this->assertInstanceOf('Article', $result);
1763
	}
1764
 
1765
/**
1766
 * Tests it is possible to get validation sets for a field using an array inteface
1767
 *
1768
 * @return void
1769
 */
1770
	public function testArrayAccessGet() {
1771
		$TestModel = new Article();
1772
		$Validator = $TestModel->validator();
1773
 
1774
		$titleValidator = $Validator['title'];
1775
		$this->assertEquals('title', $titleValidator->field);
1776
		$this->assertCount(1, $titleValidator->getRules());
1777
		$rule = current($titleValidator->getRules());
1778
		$this->assertEquals('notEmpty', $rule->rule);
1779
 
1780
		$titleValidator = $Validator['body'];
1781
		$this->assertEquals('body', $titleValidator->field);
1782
		$this->assertCount(1, $titleValidator->getRules());
1783
		$rule = current($titleValidator->getRules());
1784
		$this->assertEquals('notEmpty', $rule->rule);
1785
 
1786
		$titleValidator = $Validator['user_id'];
1787
		$this->assertEquals('user_id', $titleValidator->field);
1788
		$this->assertCount(1, $titleValidator->getRules());
1789
		$rule = current($titleValidator->getRules());
1790
		$this->assertEquals('numeric', $rule->rule);
1791
	}
1792
 
1793
/**
1794
 * Tests it is possible to check for validation sets for a field using an array inteface
1795
 *
1796
 * @return void
1797
 */
1798
	public function testArrayAccessExists() {
1799
		$TestModel = new Article();
1800
		$Validator = $TestModel->validator();
1801
 
1802
		$this->assertTrue(isset($Validator['title']));
1803
		$this->assertTrue(isset($Validator['body']));
1804
		$this->assertTrue(isset($Validator['user_id']));
1805
		$this->assertFalse(isset($Validator['other']));
1806
	}
1807
 
1808
/**
1809
 * Tests it is possible to set validation rules for a field using an array inteface
1810
 *
1811
 * @return void
1812
 */
1813
	public function testArrayAccessSet() {
1814
		$TestModel = new Article();
1815
		$Validator = $TestModel->validator();
1816
 
1817
		$set = array(
1818
			'numeric' => array('rule' => 'numeric', 'allowEmpty' => false),
1819
			'range' => array('rule' => array('between', 1, 5), 'allowEmpty' => false),
1820
		);
1821
		$Validator['other'] = $set;
1822
		$rules = $Validator['other'];
1823
		$this->assertEquals('other', $rules->field);
1824
 
1825
		$validators = $rules->getRules();
1826
		$this->assertCount(2, $validators);
1827
		$this->assertEquals('numeric', $validators['numeric']->rule);
1828
		$this->assertEquals(array('between', 1, 5), $validators['range']->rule);
1829
 
1830
		$Validator['new'] = new CakeValidationSet('new', $set, array());
1831
		$rules = $Validator['new'];
1832
		$this->assertEquals('new', $rules->field);
1833
 
1834
		$validators = $rules->getRules();
1835
		$this->assertCount(2, $validators);
1836
		$this->assertEquals('numeric', $validators['numeric']->rule);
1837
		$this->assertEquals(array('between', 1, 5), $validators['range']->rule);
1838
	}
1839
 
1840
/**
1841
 * Tests it is possible to unset validation rules
1842
 *
1843
 * @return void
1844
 */
1845
	public function testArrayAccessUset() {
1846
		$TestModel = new Article();
1847
		$Validator = $TestModel->validator();
1848
 
1849
		$this->assertTrue(isset($Validator['title']));
1850
		unset($Validator['title']);
1851
		$this->assertFalse(isset($Validator['title']));
1852
	}
1853
 
1854
/**
1855
 * Tests it is possible to iterate a validation object
1856
 *
1857
 * @return void
1858
 */
1859
	public function testIterator() {
1860
		$TestModel = new Article();
1861
		$Validator = $TestModel->validator();
1862
 
1863
		$i = 0;
1864
		foreach ($Validator as $field => $rules) {
1865
			if ($i === 0) {
1866
				$this->assertEquals('user_id', $field);
1867
			}
1868
			if ($i === 1) {
1869
				$this->assertEquals('title', $field);
1870
			}
1871
			if ($i === 2) {
1872
				$this->assertEquals('body', $field);
1873
			}
1874
			$this->assertInstanceOf('CakeValidationSet', $rules);
1875
			$i++;
1876
		}
1877
		$this->assertEquals(3, $i);
1878
	}
1879
 
1880
/**
1881
 * Tests countable interface in ModelValidator
1882
 *
1883
 * @return void
1884
 */
1885
	public function testCount() {
1886
		$TestModel = new Article();
1887
		$Validator = $TestModel->validator();
1888
		$this->assertCount(3, $Validator);
1889
 
1890
		$set = array(
1891
			'numeric' => array('rule' => 'numeric', 'allowEmpty' => false),
1892
			'range' => array('rule' => array('between', 1, 5), 'allowEmpty' => false),
1893
		);
1894
		$Validator['other'] = $set;
1895
		$this->assertCount(4, $Validator);
1896
 
1897
		unset($Validator['title']);
1898
		$this->assertCount(3, $Validator);
1899
		unset($Validator['body']);
1900
		$this->assertCount(2, $Validator);
1901
	}
1902
 
1903
/**
1904
 * Tests it is possible to add validation rules
1905
 *
1906
 * @return void
1907
 */
1908
	public function testAddRule() {
1909
		$TestModel = new Article();
1910
		$Validator = $TestModel->validator();
1911
 
1912
		$Validator->add('other', 'numeric', array('rule' => 'numeric', 'allowEmpty' => false));
1913
		$Validator->add('other', 'range', array('rule' => array('between', 1, 5), 'allowEmpty' => false));
1914
		$rules = $Validator['other'];
1915
		$this->assertEquals('other', $rules->field);
1916
 
1917
		$validators = $rules->getRules();
1918
		$this->assertCount(2, $validators);
1919
		$this->assertEquals('numeric', $validators['numeric']->rule);
1920
		$this->assertEquals(array('between', 1, 5), $validators['range']->rule);
1921
	}
1922
 
1923
/**
1924
 * Tests it is possible to remove validation rules
1925
 *
1926
 * @return void
1927
 */
1928
	public function testRemoveRule() {
1929
		$TestModel = new Article();
1930
		$Validator = $TestModel->validator();
1931
 
1932
		$this->assertTrue(isset($Validator['title']));
1933
		$Validator->remove('title');
1934
		$this->assertFalse(isset($Validator['title']));
1935
 
1936
		$Validator->add('other', 'numeric', array('rule' => 'numeric', 'allowEmpty' => false));
1937
		$Validator->add('other', 'range', array('rule' => array('between', 1, 5), 'allowEmpty' => false));
1938
		$this->assertTrue(isset($Validator['other']));
1939
 
1940
		$Validator->remove('other', 'numeric');
1941
		$this->assertTrue(isset($Validator['other']));
1942
		$this->assertFalse(isset($Validator['other']['numeric']));
1943
		$this->assertTrue(isset($Validator['other']['range']));
1944
	}
1945
 
1946
/**
1947
 * Tests validation callbacks are triggered
1948
 *
1949
 * @return void
1950
 */
1951
	public function testValidateCallbacks() {
1952
		$TestModel = $this->getMock('Article', array('beforeValidate', 'afterValidate'));
1953
		$TestModel->expects($this->once())->method('beforeValidate');
1954
		$TestModel->expects($this->once())->method('afterValidate');
1955
 
1956
		$TestModel->set(array('title' => '', 'body' => 'body'));
1957
		$TestModel->validates();
1958
	}
1959
 
1960
/**
1961
 * Tests that altering data in a beforeValidate callback will lead to saving those
1962
 * values in database
1963
 *
1964
 * @return void
1965
 */
1966
	public function testValidateFirstWithBeforeValidate() {
1967
		$this->loadFixtures('Article', 'User');
1968
		$model = new CustomArticle();
1969
		$model->validate = array(
1970
			'title' => array(
1971
				'notempty' => array(
1972
					'rule' => 'notEmpty',
1973
					'required' => true,
1974
					'allowEmpty' => false
1975
				)
1976
			)
1977
		);
1978
		$data = array(
1979
			'CustomArticle' => array(
1980
				'body' => 'foo0'
1981
			)
1982
		);
1983
		$result = $model->saveAll($data, array('validate' => 'first'));
1984
		$this->assertTrue($result);
1985
 
1986
		$this->assertFalse($model->findMethods['unPublished'], 'beforeValidate was run twice');
1987
 
1988
		$model->findMethods['unPublished'] = true;
1989
		$data = array(
1990
			'CustomArticle' => array(
1991
				'body' => 'foo1'
1992
			)
1993
		);
1994
		$result = $model->saveAll($data, array('validate' => 'first', 'deep' => true));
1995
		$this->assertTrue($result);
1996
		$title = $model->field('title', array('body' => 'foo1'));
1997
		$this->assertEquals('foo', $title);
1998
		$this->assertFalse($model->findMethods['unPublished'], 'beforeValidate was run twice');
1999
 
2000
		$data = array(
2001
			array('body' => 'foo2'),
2002
			array('body' => 'foo3'),
2003
			array('body' => 'foo4')
2004
		);
2005
 
2006
		$result = $model->saveAll($data, array('validate' => 'first', 'deep' => true));
2007
		$this->assertTrue($result);
2008
 
2009
		$this->assertEquals('foo', $model->field('title', array('body' => 'foo2')));
2010
		$this->assertEquals('foo', $model->field('title', array('body' => 'foo3')));
2011
		$this->assertEquals('foo', $model->field('title', array('body' => 'foo4')));
2012
	}
2013
 
2014
/**
2015
 * Tests that altering data in a beforeValidate callback will lead to saving those
2016
 * values in database
2017
 *
2018
 * @return void
2019
 */
2020
	public function testValidateFirstAssociatedWithBeforeValidate() {
2021
		$this->loadFixtures('Article', 'User');
2022
		$model = new CustomArticle();
2023
		$model->validate = array(
2024
			'title' => array(
2025
				'notempty' => array(
2026
					'rule' => 'notEmpty',
2027
					'required' => true
2028
				)
2029
			)
2030
		);
2031
		$articles = array(
2032
			array('body' => 'foo1'),
2033
			array('body' => 'foo2'),
2034
			array('body' => 'foo3')
2035
		);
2036
		$user = new User();
2037
		$user->bindModel(array('hasMany' => array('CustomArticle')));
2038
		$data = array(
2039
			'User' => array('user' => 'foo', 'password' => 'bar'),
2040
			'CustomArticle' => $articles
2041
		);
2042
		$result = $user->saveAll($data, array('validate' => 'first'));
2043
		$this->assertTrue($result);
2044
 
2045
		$this->assertEquals('foo', $model->field('title', array('body' => 'foo1')));
2046
		$this->assertEquals('foo', $model->field('title', array('body' => 'foo2')));
2047
		$this->assertEquals('foo', $model->field('title', array('body' => 'foo3')));
2048
	}
2049
 
2050
/**
2051
 * testValidateFirstWithDefaults method
2052
 *
2053
 * return @void
2054
 */
2055
	public function testFirstWithDefaults() {
2056
		$this->loadFixtures('Article', 'Tag', 'Comment', 'User', 'ArticlesTag');
2057
		$TestModel = new Article();
2058
 
2059
		$result = $TestModel->find('first', array(
2060
			'conditions' => array('Article.id' => 1)
2061
		));
2062
		$expected = array(
2063
			'Article' => array(
2064
				'id' => 1,
2065
				'user_id' => 1,
2066
				'title' => 'First Article',
2067
				'body' => 'First Article Body',
2068
				'published' => 'Y',
2069
				'created' => '2007-03-18 10:39:23'
2070
			),
2071
		);
2072
		unset($result['Article']['updated']);
2073
		$this->assertEquals($expected['Article'], $result['Article']);
2074
 
2075
		$data = array(
2076
			'Article' => array(
2077
				'id' => 1,
2078
				'title' => 'First Article (modified)'
2079
			),
2080
			'Comment' => array(
2081
				array('comment' => 'Article comment', 'user_id' => 1)
2082
			)
2083
		);
2084
		$result = $TestModel->saveAll($data, array('validate' => 'first'));
2085
		$this->assertTrue($result);
2086
 
2087
		$result = $TestModel->find('first', array(
2088
			'conditions' => array('Article.id' => 1)
2089
		));
2090
		$expected['Article']['title'] = 'First Article (modified)';
2091
		unset($result['Article']['updated']);
2092
		$this->assertEquals($expected['Article'], $result['Article']);
2093
	}
2094
 
2095
	public function testAddMultipleRules() {
2096
		$TestModel = new Article();
2097
		$Validator = $TestModel->validator();
2098
 
2099
		$set = array(
2100
			'numeric' => array('rule' => 'numeric', 'allowEmpty' => false),
2101
			'range' => array('rule' => array('between', 1, 5), 'allowEmpty' => false),
2102
		);
2103
 
2104
		$Validator->add('other', $set);
2105
		$rules = $Validator['other'];
2106
		$this->assertEquals('other', $rules->field);
2107
 
2108
		$validators = $rules->getRules();
2109
		$this->assertCount(2, $validators);
2110
		$this->assertEquals('numeric', $validators['numeric']->rule);
2111
		$this->assertEquals(array('between', 1, 5), $validators['range']->rule);
2112
 
2113
		$set = new CakeValidationSet('other', array(
2114
			'a' => array('rule' => 'numeric', 'allowEmpty' => false),
2115
			'b' => array('rule' => array('between', 1, 5), 'allowEmpty' => false),
2116
		));
2117
 
2118
		$Validator->add('other', $set);
2119
		$this->assertSame($set, $Validator->getField('other'));
2120
	}
2121
 
2122
/**
2123
 * Test that rules are parsed correctly when calling getField()
2124
 *
2125
 * @return void
2126
 */
2127
	public function testValidator() {
2128
		$TestModel = new Article();
2129
		$Validator = $TestModel->validator();
2130
 
2131
		$result = $Validator->getField();
2132
		$expected = array('user_id', 'title', 'body');
2133
		$this->assertEquals($expected, array_keys($result));
2134
		$this->assertTrue($result['user_id'] instanceof CakeValidationSet);
2135
 
2136
		$result = $TestModel->validator()->getField('title');
2137
		$this->assertTrue($result instanceof CakeValidationSet);
2138
	}
2139
 
2140
/**
2141
 * Test that validator override works as expected
2142
 *
2143
 * @return void
2144
 */
2145
	public function testValidatorOverride() {
2146
		$TestModel = new Article();
2147
		$ValidatorA = new ModelValidator($TestModel);
2148
		$ValidatorB = new ModelValidator($TestModel);
2149
 
2150
		$TestModel->validator($ValidatorA);
2151
		$TestModel->validator($ValidatorB);
2152
 
2153
		$this->assertSame($ValidatorB, $TestModel->validator());
2154
		$this->assertNotSame($ValidatorA, $TestModel->validator());
2155
	}
2156
 
2157
/**
2158
 * Test that type hint exception is thrown
2159
 *
2160
 * @expectedException PHPUnit_Framework_Error
2161
 * @return void
2162
 */
2163
	public function testValidatorTypehintException() {
2164
		new ModelValidator('asdasds');
2165
	}
2166
 
2167
/**
2168
 * Tests that altering data in a beforeValidate callback will lead to saving those
2169
 * values in database, this time with belongsTo associations
2170
 *
2171
 * @return void
2172
 */
2173
	public function testValidateFirstAssociatedWithBeforeValidate2() {
2174
		$this->loadFixtures('Article', 'User');
2175
		$model = new CustomArticle();
2176
		$model->validate = array(
2177
			'title' => array(
2178
				'notempty' => array(
2179
					'rule' => 'notEmpty',
2180
					'required' => true
2181
				)
2182
			)
2183
		);
2184
 
2185
		$data = array(
2186
			'User' => array('user' => 'foo', 'password' => 'bar'),
2187
			'CustomArticle' => array(
2188
				'body' => 'a test'
2189
			)
2190
		);
2191
		$result = $model->saveAll($data, array('validate' => 'first'));
2192
		$this->assertTrue($result);
2193
 
2194
		$this->assertEquals('foo', $model->field('title', array('body' => 'a test')));
2195
	}
2196
 
2197
/**
2198
 * Testing you can dynamically add rules to a field, added this to dispel doubts
2199
 * after a presentation made to show off this new feature
2200
 *
2201
 * @return void
2202
 */
2203
	public function testDynamicValidationRuleBuilding() {
2204
		$model = new Article;
2205
		$validator = $model->validator();
2206
		$validator->add('body', 'isSpecial', array('rule' => 'special'));
2207
		$rules = $validator['body']->getRules();
2208
		$this->assertCount(2, $rules);
2209
		$this->assertEquals('special', $rules['isSpecial']->rule);
2210
		$validator['body']->setRule('isAwesome', array('rule' => 'awesome'));
2211
		$rules = $validator['body']->getRules();
2212
		$this->assertCount(3, $rules);
2213
		$this->assertEquals('awesome', $rules['isAwesome']->rule);
2214
	}
2215
 
2216
/**
2217
 * Test to ensure custom validation methods work with CakeValidationSet
2218
 *
2219
 * @return void
2220
 */
2221
	public function testCustomMethodsWithCakeValidationSet() {
2222
		$TestModel = new TestValidate();
2223
		$Validator = $TestModel->validator();
2224
 
2225
		$Validator->add('title', 'validateTitle', array(
2226
			'rule' => 'validateTitle',
2227
			'message' => 'That aint right',
2228
		));
2229
		$data = array('title' => 'notatitle');
2230
		$result = $Validator->getField('title')->validate($data);
2231
		$expected = array(0 => 'That aint right');
2232
		$this->assertEquals($expected, $result);
2233
 
2234
		$data = array('title' => 'title-is-good');
2235
		$result = $Validator->getField('title')->validate($data);
2236
		$expected = array();
2237
		$this->assertEquals($expected, $result);
2238
	}
2239
 
2240
	public function testCustomMethodWithEmptyValue() {
2241
		$this->loadFixtures('Article');
2242
 
2243
		$model = $this->getMock('Article', array('isLegit'));
2244
		$model->validate = array(
2245
			'title' => array(
2246
				'custom' => array(
2247
					'rule' => array('isLegit'),
2248
					'message' => 'is no good'
2249
				)
2250
			)
2251
		);
2252
		$model->expects($this->once())
2253
			->method('isLegit')
2254
			->will($this->returnValue(false));
2255
 
2256
		$model->set(array('title' => ''));
2257
		$this->assertFalse($model->validates());
2258
	}
2259
 
2260
/**
2261
 * Test validateAssociated with atomic=false & deep=true
2262
 *
2263
 * @return void
2264
 */
2265
	public function testValidateAssociatedAtomicFalseDeepTrueWithErrors() {
2266
		$this->loadFixtures('Comment', 'Article', 'User', 'Attachment');
2267
		$Attachment = ClassRegistry::init('Attachment');
2268
		$Attachment->Comment->validator()->add('comment', array(
2269
			array('rule' => 'notEmpty')
2270
		));
2271
		$Attachment->Comment->User->bindModel(array(
2272
			'hasMany' => array(
2273
				'Article',
2274
				'Comment'
2275
			)),
2276
			false
2277
		);
2278
 
2279
		$data = array(
2280
			'Attachment' => array(
2281
				'attachment' => 'text',
2282
				'Comment' => array(
2283
					'comment' => '',
2284
					'published' => 'N',
2285
					'User' => array(
2286
						'user' => 'Foo',
2287
						'password' => 'mypassword',
2288
						'Comment' => array(
2289
							array(
2290
								'comment' => ''
2291
							)
2292
						)
2293
					)
2294
				)
2295
			)
2296
		);
2297
		$result = $Attachment->validateAssociated($data, array('atomic' => false, 'deep' => true));
2298
 
2299
		$result = $Attachment->validationErrors;
2300
		$expected = array(
2301
			'Comment' => array(
2302
				'comment' => array(
2303
 
2304
				),
2305
				'User' => array(
2306
					'Comment' => array(
2307
 
2308
							'comment' => array(
2309
 
2310
							),
2311
						),
2312
					),
2313
				),
2314
			),
2315
		);
2316
		$this->assertEquals($expected, $result);
2317
	}
2318
 
2319
/**
2320
 * Test validateMany with atomic=false & deep=true
2321
 *
2322
 * @return void
2323
 */
2324
	public function testValidateManyAtomicFalseDeepTrueWithErrors() {
2325
		$this->loadFixtures('Comment', 'Article', 'User');
2326
		$Article = ClassRegistry::init('Article');
2327
		$Article->Comment->validator()->add('comment', array(
2328
			array('rule' => 'notEmpty')
2329
		));
2330
 
2331
		$data = array(
2332
			array(
2333
				'Article' => array(
2334
					'user_id' => 1,
2335
					'title' => 'Foo',
2336
					'body' => 'text',
2337
					'published' => 'N'
2338
				),
2339
				'Comment' => array(
2340
					array(
2341
						'user_id' => 1,
2342
						'comment' => 'Baz',
2343
						'published' => 'N',
2344
					)
2345
				),
2346
			),
2347
			array(
2348
				'Article' => array(
2349
					'user_id' => 1,
2350
					'title' => 'Bar',
2351
					'body' => 'text',
2352
					'published' => 'N'
2353
				),
2354
				'Comment' => array(
2355
					array(
2356
						'user_id' => 1,
2357
						'comment' => '',
2358
						'published' => 'N',
2359
					)
2360
				),
2361
			),
2362
		);
2363
		$Article->validateMany($data, array('atomic' => false, 'deep' => true));
2364
 
2365
		$result = $Article->validationErrors;
2366
		$expected = array(
2367
			1 => array(
2368
				'Comment' => array(
2369
 
2370
						'comment' => array(
2371
 
2372
						),
2373
					),
2374
				),
2375
			),
2376
		);
2377
		$this->assertEquals($expected, $result);
2378
	}
2379
 
2380
}