ModelValidationTest.php 59 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038
  1. <?php
  2. /**
  3. * ModelValidationTest file
  4. *
  5. * PHP 5
  6. *
  7. * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
  8. * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  9. *
  10. * Licensed under The MIT License
  11. * Redistributions of files must retain the above copyright notice
  12. *
  13. * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  14. * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
  15. * @package Cake.Test.Case.Model
  16. * @since CakePHP(tm) v 1.2.0.4206
  17. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  18. */
  19. require_once dirname(__FILE__) . DS . 'ModelTestBase.php';
  20. /**
  21. * ModelValidationTest
  22. *
  23. * @package Cake.Test.Case.Model
  24. */
  25. class ModelValidationTest extends BaseModelTest {
  26. /**
  27. * Tests validation parameter order in custom validation methods
  28. *
  29. * @return void
  30. */
  31. public function testValidationParams() {
  32. $TestModel = new ValidationTest1();
  33. $TestModel->validate['title'] = array(
  34. 'rule' => 'customValidatorWithParams',
  35. 'required' => true
  36. );
  37. $TestModel->create(array('title' => 'foo'));
  38. $TestModel->invalidFields();
  39. $expected = array(
  40. 'data' => array(
  41. 'title' => 'foo'
  42. ),
  43. 'validator' => array(
  44. 'rule' => 'customValidatorWithParams',
  45. 'on' => null,
  46. 'last' => true,
  47. 'allowEmpty' => false,
  48. 'required' => true,
  49. 'message' => null
  50. ),
  51. 'or' => true,
  52. 'ignoreOnSame' => 'id'
  53. );
  54. $this->assertEquals($expected, $TestModel->validatorParams);
  55. $TestModel->validate['title'] = array(
  56. 'rule' => 'customValidatorWithMessage',
  57. 'required' => true
  58. );
  59. $expected = array(
  60. 'title' => array('This field will *never* validate! Muhahaha!')
  61. );
  62. $this->assertEquals($expected, $TestModel->invalidFields());
  63. $TestModel->validate['title'] = array(
  64. 'rule' => array('customValidatorWithSixParams', 'one', 'two', null, 'four'),
  65. 'required' => true
  66. );
  67. $TestModel->create(array('title' => 'foo'));
  68. $TestModel->invalidFields();
  69. $expected = array(
  70. 'data' => array(
  71. 'title' => 'foo'
  72. ),
  73. 'one' => 'one',
  74. 'two' => 'two',
  75. 'three' => null,
  76. 'four' => 'four',
  77. 'five' => array(
  78. 'rule' => array(1 => 'one', 2 => 'two', 3 => null, 4 => 'four'),
  79. 'on' => null,
  80. 'last' => true,
  81. 'allowEmpty' => false,
  82. 'required' => true,
  83. 'message' => null
  84. ),
  85. 'six' => 6
  86. );
  87. $this->assertEquals($expected, $TestModel->validatorParams);
  88. $TestModel->validate['title'] = array(
  89. 'rule' => array('customValidatorWithSixParams', 'one', array('two'), null, 'four', array('five' => 5)),
  90. 'required' => true
  91. );
  92. $TestModel->create(array('title' => 'foo'));
  93. $TestModel->invalidFields();
  94. $expected = array(
  95. 'data' => array(
  96. 'title' => 'foo'
  97. ),
  98. 'one' => 'one',
  99. 'two' => array('two'),
  100. 'three' => null,
  101. 'four' => 'four',
  102. 'five' => array('five' => 5),
  103. 'six' => array(
  104. 'rule' => array(1 => 'one', 2 => array('two'), 3 => null, 4 => 'four', 5 => array('five' => 5)),
  105. 'on' => null,
  106. 'last' => true,
  107. 'allowEmpty' => false,
  108. 'required' => true,
  109. 'message' => null
  110. )
  111. );
  112. $this->assertEquals($expected, $TestModel->validatorParams);
  113. }
  114. /**
  115. * Tests validation parameter fieldList in invalidFields
  116. *
  117. * @return void
  118. */
  119. public function testInvalidFieldsWithFieldListParams() {
  120. $TestModel = new ValidationTest1();
  121. $TestModel->validate = $validate = array(
  122. 'title' => array(
  123. 'rule' => 'alphaNumeric',
  124. 'required' => true
  125. ),
  126. 'name' => array(
  127. 'rule' => 'alphaNumeric',
  128. 'required' => true
  129. ));
  130. $TestModel->set(array('title' => '$$', 'name' => '##'));
  131. $TestModel->invalidFields(array('fieldList' => array('title')));
  132. $expected = array(
  133. 'title' => array('This field cannot be left blank')
  134. );
  135. $this->assertEquals($expected, $TestModel->validationErrors);
  136. $TestModel->validationErrors = array();
  137. $TestModel->invalidFields(array('fieldList' => array('name')));
  138. $expected = array(
  139. 'name' => array('This field cannot be left blank')
  140. );
  141. $this->assertEquals($expected, $TestModel->validationErrors);
  142. $TestModel->validationErrors = array();
  143. $TestModel->invalidFields(array('fieldList' => array('name', 'title')));
  144. $expected = array(
  145. 'name' => array('This field cannot be left blank'),
  146. 'title' => array('This field cannot be left blank')
  147. );
  148. $this->assertEquals($expected, $TestModel->validationErrors);
  149. $TestModel->validationErrors = array();
  150. $TestModel->whitelist = array('name');
  151. $TestModel->invalidFields();
  152. $expected = array('name' => array('This field cannot be left blank'));
  153. $this->assertEquals($expected, $TestModel->validationErrors);
  154. $this->assertEquals($TestModel->validate, $validate);
  155. }
  156. /**
  157. * Test that invalidFields() integrates well with save(). And that fieldList can be an empty type.
  158. *
  159. * @return void
  160. */
  161. public function testInvalidFieldsWhitelist() {
  162. $TestModel = new ValidationTest1();
  163. $TestModel->validate = array(
  164. 'title' => array(
  165. 'rule' => 'alphaNumeric',
  166. 'required' => true
  167. ),
  168. 'name' => array(
  169. 'rule' => 'alphaNumeric',
  170. 'required' => true
  171. ));
  172. $TestModel->whitelist = array('name');
  173. $TestModel->save(array('name' => '#$$#', 'title' => '$$$$'));
  174. $expected = array('name' => array('This field cannot be left blank'));
  175. $this->assertEquals($expected, $TestModel->validationErrors);
  176. }
  177. /**
  178. * testValidates method
  179. *
  180. * @return void
  181. */
  182. public function testValidates() {
  183. $TestModel = new TestValidate();
  184. $TestModel->validate = array(
  185. 'user_id' => 'numeric',
  186. 'title' => array('allowEmpty' => false, 'rule' => 'notEmpty'),
  187. 'body' => 'notEmpty'
  188. );
  189. $data = array('TestValidate' => array(
  190. 'user_id' => '1',
  191. 'title' => '',
  192. 'body' => 'body'
  193. ));
  194. $result = $TestModel->create($data);
  195. $this->assertEquals($data, $result);
  196. $result = $TestModel->validates();
  197. $this->assertFalse($result);
  198. $data = array('TestValidate' => array(
  199. 'user_id' => '1',
  200. 'title' => 'title',
  201. 'body' => 'body'
  202. ));
  203. $result = $TestModel->create($data) && $TestModel->validates();
  204. $this->assertTrue($result);
  205. $data = array('TestValidate' => array(
  206. 'user_id' => '1',
  207. 'title' => '0',
  208. 'body' => 'body'
  209. ));
  210. $result = $TestModel->create($data);
  211. $this->assertEquals($data, $result);
  212. $result = $TestModel->validates();
  213. $this->assertTrue($result);
  214. $data = array('TestValidate' => array(
  215. 'user_id' => '1',
  216. 'title' => 0,
  217. 'body' => 'body'
  218. ));
  219. $result = $TestModel->create($data);
  220. $this->assertEquals($data, $result);
  221. $result = $TestModel->validates();
  222. $this->assertTrue($result);
  223. $TestModel->validate['modified'] = array('allowEmpty' => true, 'rule' => 'date');
  224. $data = array('TestValidate' => array(
  225. 'user_id' => '1',
  226. 'title' => 0,
  227. 'body' => 'body',
  228. 'modified' => ''
  229. ));
  230. $result = $TestModel->create($data);
  231. $this->assertEquals($data, $result);
  232. $result = $TestModel->validates();
  233. $this->assertTrue($result);
  234. $data = array('TestValidate' => array(
  235. 'user_id' => '1',
  236. 'title' => 0,
  237. 'body' => 'body',
  238. 'modified' => '2007-05-01'
  239. ));
  240. $result = $TestModel->create($data);
  241. $this->assertEquals($data, $result);
  242. $result = $TestModel->validates();
  243. $this->assertTrue($result);
  244. $data = array('TestValidate' => array(
  245. 'user_id' => '1',
  246. 'title' => 0,
  247. 'body' => 'body',
  248. 'modified' => 'invalid-date-here'
  249. ));
  250. $result = $TestModel->create($data);
  251. $this->assertEquals($data, $result);
  252. $result = $TestModel->validates();
  253. $this->assertFalse($result);
  254. $data = array('TestValidate' => array(
  255. 'user_id' => '1',
  256. 'title' => 0,
  257. 'body' => 'body',
  258. 'modified' => 0
  259. ));
  260. $result = $TestModel->create($data);
  261. $this->assertEquals($data, $result);
  262. $result = $TestModel->validates();
  263. $this->assertFalse($result);
  264. $data = array('TestValidate' => array(
  265. 'user_id' => '1',
  266. 'title' => 0,
  267. 'body' => 'body',
  268. 'modified' => '0'
  269. ));
  270. $result = $TestModel->create($data);
  271. $this->assertEquals($data, $result);
  272. $result = $TestModel->validates();
  273. $this->assertFalse($result);
  274. $TestModel->validate['modified'] = array('allowEmpty' => false, 'rule' => 'date');
  275. $data = array('TestValidate' => array('modified' => null));
  276. $result = $TestModel->create($data);
  277. $this->assertEquals($data, $result);
  278. $result = $TestModel->validates();
  279. $this->assertFalse($result);
  280. $data = array('TestValidate' => array('modified' => false));
  281. $result = $TestModel->create($data);
  282. $this->assertEquals($data, $result);
  283. $result = $TestModel->validates();
  284. $this->assertFalse($result);
  285. $data = array('TestValidate' => array('modified' => ''));
  286. $result = $TestModel->create($data);
  287. $this->assertEquals($data, $result);
  288. $result = $TestModel->validates();
  289. $this->assertFalse($result);
  290. $data = array('TestValidate' => array(
  291. 'modified' => '2007-05-01'
  292. ));
  293. $result = $TestModel->create($data);
  294. $this->assertEquals($data, $result);
  295. $result = $TestModel->validates();
  296. $this->assertTrue($result);
  297. $TestModel->validate['slug'] = array('allowEmpty' => false, 'rule' => array('maxLength', 45));
  298. $data = array('TestValidate' => array(
  299. 'user_id' => '1',
  300. 'title' => 0,
  301. 'body' => 'body',
  302. 'slug' => ''
  303. ));
  304. $result = $TestModel->create($data);
  305. $this->assertEquals($data, $result);
  306. $result = $TestModel->validates();
  307. $this->assertFalse($result);
  308. $data = array('TestValidate' => array(
  309. 'user_id' => '1',
  310. 'title' => 0,
  311. 'body' => 'body',
  312. 'slug' => 'slug-right-here'
  313. ));
  314. $result = $TestModel->create($data);
  315. $this->assertEquals($data, $result);
  316. $result = $TestModel->validates();
  317. $this->assertTrue($result);
  318. $data = array('TestValidate' => array(
  319. 'user_id' => '1',
  320. 'title' => 0,
  321. 'body' => 'body',
  322. 'slug' => 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz'
  323. ));
  324. $result = $TestModel->create($data);
  325. $this->assertEquals($data, $result);
  326. $result = $TestModel->validates();
  327. $this->assertFalse($result);
  328. $TestModel->validate = array(
  329. 'number' => array(
  330. 'rule' => 'validateNumber',
  331. 'min' => 3,
  332. 'max' => 5
  333. ),
  334. 'title' => array(
  335. 'allowEmpty' => false,
  336. 'rule' => 'notEmpty'
  337. ));
  338. $data = array('TestValidate' => array(
  339. 'title' => 'title',
  340. 'number' => '0'
  341. ));
  342. $result = $TestModel->create($data);
  343. $this->assertEquals($data, $result);
  344. $result = $TestModel->validates();
  345. $this->assertFalse($result);
  346. $data = array('TestValidate' => array(
  347. 'title' => 'title',
  348. 'number' => 0
  349. ));
  350. $result = $TestModel->create($data);
  351. $this->assertEquals($data, $result);
  352. $result = $TestModel->validates();
  353. $this->assertFalse($result);
  354. $data = array('TestValidate' => array(
  355. 'title' => 'title',
  356. 'number' => '3'
  357. ));
  358. $result = $TestModel->create($data);
  359. $this->assertEquals($data, $result);
  360. $result = $TestModel->validates();
  361. $this->assertTrue($result);
  362. $data = array('TestValidate' => array(
  363. 'title' => 'title',
  364. 'number' => 3
  365. ));
  366. $result = $TestModel->create($data);
  367. $this->assertEquals($data, $result);
  368. $result = $TestModel->validates();
  369. $this->assertTrue($result);
  370. $TestModel->validate = array(
  371. 'number' => array(
  372. 'rule' => 'validateNumber',
  373. 'min' => 5,
  374. 'max' => 10
  375. ),
  376. 'title' => array(
  377. 'allowEmpty' => false,
  378. 'rule' => 'notEmpty'
  379. ));
  380. $data = array('TestValidate' => array(
  381. 'title' => 'title',
  382. 'number' => '3'
  383. ));
  384. $result = $TestModel->create($data);
  385. $this->assertEquals($data, $result);
  386. $result = $TestModel->validates();
  387. $this->assertFalse($result);
  388. $data = array('TestValidate' => array(
  389. 'title' => 'title',
  390. 'number' => 3
  391. ));
  392. $result = $TestModel->create($data);
  393. $this->assertEquals($data, $result);
  394. $result = $TestModel->validates();
  395. $this->assertFalse($result);
  396. $TestModel->validate = array(
  397. 'title' => array(
  398. 'allowEmpty' => false,
  399. 'rule' => 'validateTitle'
  400. ));
  401. $data = array('TestValidate' => array('title' => ''));
  402. $result = $TestModel->create($data);
  403. $this->assertEquals($data, $result);
  404. $result = $TestModel->validates();
  405. $this->assertFalse($result);
  406. $data = array('TestValidate' => array('title' => 'new title'));
  407. $result = $TestModel->create($data);
  408. $this->assertEquals($data, $result);
  409. $result = $TestModel->validates();
  410. $this->assertFalse($result);
  411. $data = array('TestValidate' => array('title' => 'title-new'));
  412. $result = $TestModel->create($data);
  413. $this->assertEquals($data, $result);
  414. $result = $TestModel->validates();
  415. $this->assertTrue($result);
  416. $TestModel->validate = array('title' => array(
  417. 'allowEmpty' => true,
  418. 'rule' => 'validateTitle'
  419. ));
  420. $data = array('TestValidate' => array('title' => ''));
  421. $result = $TestModel->create($data);
  422. $this->assertEquals($data, $result);
  423. $result = $TestModel->validates();
  424. $this->assertTrue($result);
  425. $TestModel->validate = array(
  426. 'title' => array(
  427. 'length' => array(
  428. 'allowEmpty' => true,
  429. 'rule' => array('maxLength', 10)
  430. )));
  431. $data = array('TestValidate' => array('title' => ''));
  432. $result = $TestModel->create($data);
  433. $this->assertEquals($data, $result);
  434. $result = $TestModel->validates();
  435. $this->assertTrue($result);
  436. $TestModel->validate = array(
  437. 'title' => array(
  438. 'rule' => array('userDefined', 'Article', 'titleDuplicate')
  439. ));
  440. $data = array('TestValidate' => array('title' => 'My Article Title'));
  441. $result = $TestModel->create($data);
  442. $this->assertEquals($data, $result);
  443. $result = $TestModel->validates();
  444. $this->assertFalse($result);
  445. $data = array('TestValidate' => array(
  446. 'title' => 'My Article With a Different Title'
  447. ));
  448. $result = $TestModel->create($data);
  449. $this->assertEquals($data, $result);
  450. $result = $TestModel->validates();
  451. $this->assertTrue($result);
  452. $TestModel->validate = array(
  453. 'title' => array(
  454. 'tooShort' => array('rule' => array('minLength', 50)),
  455. 'onlyLetters' => array('rule' => '/^[a-z]+$/i')
  456. ),
  457. );
  458. $data = array('TestValidate' => array(
  459. 'title' => 'I am a short string'
  460. ));
  461. $TestModel->create($data);
  462. $result = $TestModel->validates();
  463. $this->assertFalse($result);
  464. $result = $TestModel->validationErrors;
  465. $expected = array(
  466. 'title' => array('tooShort')
  467. );
  468. $this->assertEquals($expected, $result);
  469. $TestModel->validate = array(
  470. 'title' => array(
  471. 'tooShort' => array(
  472. 'rule' => array('minLength', 50),
  473. 'last' => false
  474. ),
  475. 'onlyLetters' => array('rule' => '/^[a-z]+$/i')
  476. ),
  477. );
  478. $data = array('TestValidate' => array(
  479. 'title' => 'I am a short string'
  480. ));
  481. $TestModel->create($data);
  482. $result = $TestModel->validates();
  483. $this->assertFalse($result);
  484. $result = $TestModel->validationErrors;
  485. $expected = array(
  486. 'title' => array('tooShort', 'onlyLetters')
  487. );
  488. $this->assertEquals($expected, $result);
  489. $result = $TestModel->validationErrors;
  490. $this->assertEquals($expected, $result);
  491. }
  492. /**
  493. * test that validates() checks all the 'with' associations as well for validation
  494. * as this can cause partial/wrong data insertion.
  495. *
  496. * @return void
  497. */
  498. public function testValidatesWithAssociations() {
  499. $this->loadFixtures('Something', 'SomethingElse', 'JoinThing');
  500. $data = array(
  501. 'Something' => array(
  502. 'id' => 5,
  503. 'title' => 'Extra Fields',
  504. 'body' => 'Extra Fields Body',
  505. 'published' => '1'
  506. ),
  507. 'SomethingElse' => array(
  508. array('something_else_id' => 1, 'doomed' => '')
  509. )
  510. );
  511. $Something = new Something();
  512. $JoinThing = $Something->JoinThing;
  513. $JoinThing->validate = array('doomed' => array('rule' => 'notEmpty'));
  514. $expectedError = array('doomed' => array('This field cannot be left blank'));
  515. $Something->create();
  516. $result = $Something->save($data);
  517. $this->assertFalse($result, 'Save occurred even when with models failed. %s');
  518. $this->assertEquals($expectedError, $JoinThing->validationErrors);
  519. $count = $Something->find('count', array('conditions' => array('Something.id' => $data['Something']['id'])));
  520. $this->assertSame($count, 0);
  521. $data = array(
  522. 'Something' => array(
  523. 'id' => 5,
  524. 'title' => 'Extra Fields',
  525. 'body' => 'Extra Fields Body',
  526. 'published' => '1'
  527. ),
  528. 'SomethingElse' => array(
  529. array('something_else_id' => 1, 'doomed' => 1),
  530. array('something_else_id' => 1, 'doomed' => '')
  531. )
  532. );
  533. $Something->create();
  534. $result = $Something->save($data);
  535. $this->assertFalse($result, 'Save occurred even when with models failed. %s');
  536. $joinRecords = $JoinThing->find('count', array(
  537. 'conditions' => array('JoinThing.something_id' => $data['Something']['id'])
  538. ));
  539. $this->assertEquals(0, $joinRecords, 'Records were saved on the join table. %s');
  540. }
  541. /**
  542. * test that saveAll and with models with validation interact well
  543. *
  544. * @return void
  545. */
  546. public function testValidatesWithModelsAndSaveAll() {
  547. $this->loadFixtures('Something', 'SomethingElse', 'JoinThing');
  548. $data = array(
  549. 'Something' => array(
  550. 'id' => 5,
  551. 'title' => 'Extra Fields',
  552. 'body' => 'Extra Fields Body',
  553. 'published' => '1'
  554. ),
  555. 'SomethingElse' => array(
  556. array('something_else_id' => 1, 'doomed' => '')
  557. )
  558. );
  559. $Something = new Something();
  560. $JoinThing = $Something->JoinThing;
  561. $JoinThing->validate = array('doomed' => array('rule' => 'notEmpty'));
  562. $expectedError = array('doomed' => array('This field cannot be left blank'));
  563. $Something->create();
  564. $result = $Something->saveAll($data, array('validate' => 'only'));
  565. $this->assertFalse($result);
  566. $result = $Something->validateAssociated($data);
  567. $this->assertFalse($result);
  568. $this->assertEquals($expectedError, $JoinThing->validationErrors);
  569. $result = $Something->validator()->validateAssociated($data);
  570. $this->assertFalse($result);
  571. $Something->create();
  572. $result = $Something->saveAll($data, array('validate' => 'first'));
  573. $this->assertFalse($result);
  574. $this->assertEquals($expectedError, $JoinThing->validationErrors);
  575. $count = $Something->find('count', array('conditions' => array('Something.id' => $data['Something']['id'])));
  576. $this->assertSame($count, 0);
  577. $joinRecords = $JoinThing->find('count', array(
  578. 'conditions' => array('JoinThing.something_id' => $data['Something']['id'])
  579. ));
  580. $this->assertEquals(0, $joinRecords, 'Records were saved on the join table. %s');
  581. }
  582. /**
  583. * test that saveAll and with models at initial insert (no id has set yet)
  584. * with validation interact well
  585. *
  586. * @return void
  587. */
  588. public function testValidatesWithModelsAndSaveAllWithoutId() {
  589. $this->loadFixtures('Post', 'Author');
  590. $data = array(
  591. 'Author' => array(
  592. 'name' => 'Foo Bar',
  593. ),
  594. 'Post' => array(
  595. array('title' => 'Hello'),
  596. array('title' => 'World'),
  597. )
  598. );
  599. $Author = new Author();
  600. $Post = $Author->Post;
  601. $Post->validate = array('author_id' => array('rule' => 'numeric'));
  602. $Author->create();
  603. $result = $Author->saveAll($data, array('validate' => 'only'));
  604. $this->assertTrue($result);
  605. $result = $Author->validateAssociated($data);
  606. $this->assertTrue($result);
  607. $this->assertTrue($result);
  608. $Author->create();
  609. $result = $Author->saveAll($data, array('validate' => 'first'));
  610. $this->assertTrue($result);
  611. $this->assertFalse(is_null($Author->id));
  612. $id = $Author->id;
  613. $count = $Author->find('count', array('conditions' => array('Author.id' => $id)));
  614. $this->assertSame($count, 1);
  615. $count = $Post->find('count', array(
  616. 'conditions' => array('Post.author_id' => $id)
  617. ));
  618. $this->assertEquals($count, count($data['Post']));
  619. }
  620. /**
  621. * Test that missing validation methods trigger errors in development mode.
  622. * Helps to make development easier.
  623. *
  624. * @expectedException PHPUnit_Framework_Error
  625. * @return void
  626. */
  627. public function testMissingValidationErrorTriggering() {
  628. Configure::write('debug', 2);
  629. $TestModel = new ValidationTest1();
  630. $TestModel->create(array('title' => 'foo'));
  631. $TestModel->validate = array(
  632. 'title' => array(
  633. 'rule' => array('thisOneBringsThePain'),
  634. 'required' => true
  635. )
  636. );
  637. $TestModel->invalidFields(array('fieldList' => array('title')));
  638. }
  639. /**
  640. * Test that missing validation methods does not trigger errors in production mode.
  641. *
  642. * @return void
  643. */
  644. public function testMissingValidationErrorNoTriggering() {
  645. Configure::write('debug', 0);
  646. $TestModel = new ValidationTest1();
  647. $TestModel->create(array('title' => 'foo'));
  648. $TestModel->validate = array(
  649. 'title' => array(
  650. 'rule' => array('thisOneBringsThePain'),
  651. 'required' => true
  652. )
  653. );
  654. $TestModel->invalidFields(array('fieldList' => array('title')));
  655. $this->assertEquals(array(), $TestModel->validationErrors);
  656. }
  657. /**
  658. * Test placeholder replacement when validation message is an array
  659. *
  660. * @return void
  661. */
  662. public function testValidationMessageAsArray() {
  663. $TestModel = new ValidationTest1();
  664. $TestModel->validate = array(
  665. 'title' => array(
  666. 'minLength' => array(
  667. 'rule' => array('minLength', 6),
  668. 'required' => true,
  669. 'message' => 'Minimum length allowed is %d chars',
  670. 'last' => false
  671. ),
  672. 'between' => array(
  673. 'rule' => array('between', 5, 15),
  674. 'message' => array('You may enter up to %s chars (minimum is %s chars)', 14, 6)
  675. )
  676. )
  677. );
  678. $TestModel->create();
  679. $expected = array(
  680. 'title' => array(
  681. 'Minimum length allowed is 6 chars',
  682. )
  683. );
  684. $TestModel->invalidFields();
  685. $this->assertEquals($expected, $TestModel->validationErrors);
  686. $TestModel->create(array('title' => 'foo'));
  687. $expected = array(
  688. 'title' => array(
  689. 'Minimum length allowed is 6 chars',
  690. 'You may enter up to 14 chars (minimum is 6 chars)'
  691. )
  692. );
  693. $TestModel->invalidFields();
  694. $this->assertEquals($expected, $TestModel->validationErrors);
  695. }
  696. /**
  697. * Test validation message translation
  698. *
  699. * @return void
  700. */
  701. public function testValidationMessageTranslation() {
  702. $lang = Configure::read('Config.language');
  703. Configure::write('Config.language', 'en');
  704. App::build(array(
  705. 'Locale' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Locale' . DS),
  706. ), App::RESET);
  707. $TestModel = new ValidationTest1();
  708. $TestModel->validationDomain = 'validation_messages';
  709. $TestModel->validate = array(
  710. 'title' => array(
  711. array(
  712. 'rule' => array('customValidationMethod', 'arg1'),
  713. 'required' => true,
  714. 'message' => 'Validation failed: %s'
  715. )
  716. )
  717. );
  718. $TestModel->create();
  719. $expected = array(
  720. 'title' => array(
  721. 'Translated validation failed: Translated arg1',
  722. )
  723. );
  724. $TestModel->invalidFields();
  725. $this->assertEquals($expected, $TestModel->validationErrors);
  726. $TestModel->validationDomain = 'default';
  727. Configure::write('Config.language', $lang);
  728. App::build();
  729. }
  730. /**
  731. * Test for 'on' => [create|update] in validation rules.
  732. *
  733. * @return void
  734. */
  735. public function testStateValidation() {
  736. $this->loadFixtures('Article');
  737. $Article = new Article();
  738. $data = array(
  739. 'Article' => array(
  740. 'title' => '',
  741. 'body' => 'Extra Fields Body',
  742. 'published' => '1'
  743. )
  744. );
  745. $Article->validate = array(
  746. 'title' => array(
  747. 'notempty' => array(
  748. 'rule' => 'notEmpty',
  749. 'on' => 'create'
  750. )
  751. )
  752. );
  753. $Article->create($data);
  754. $this->assertFalse($Article->validates());
  755. $Article->save(null, array('validate' => false));
  756. $data['Article']['id'] = $Article->id;
  757. $Article->set($data);
  758. $this->assertTrue($Article->validates());
  759. unset($data['Article']['id']);
  760. $Article->validate = array(
  761. 'title' => array(
  762. 'notempty' => array(
  763. 'rule' => 'notEmpty',
  764. 'on' => 'update'
  765. )
  766. )
  767. );
  768. $Article->create($data);
  769. $this->assertTrue($Article->validates());
  770. $Article->save(null, array('validate' => false));
  771. $data['Article']['id'] = $Article->id;
  772. $Article->set($data);
  773. $this->assertFalse($Article->validates());
  774. }
  775. /**
  776. * Test for 'required' => [create|update] in validation rules.
  777. *
  778. * @return void
  779. */
  780. public function testStateRequiredValidation() {
  781. $this->loadFixtures('Article');
  782. $Article = new Article();
  783. // no title field present
  784. $data = array(
  785. 'Article' => array(
  786. 'body' => 'Extra Fields Body',
  787. 'published' => '1'
  788. )
  789. );
  790. $Article->validate = array(
  791. 'title' => array(
  792. 'notempty' => array(
  793. 'rule' => 'notEmpty',
  794. 'required' => 'create'
  795. )
  796. )
  797. );
  798. $Article->create($data);
  799. $this->assertFalse($Article->validates());
  800. $Article->save(null, array('validate' => false));
  801. $data['Article']['id'] = $Article->id;
  802. $Article->set($data);
  803. $this->assertTrue($Article->validates());
  804. unset($data['Article']['id']);
  805. $Article->validate = array(
  806. 'title' => array(
  807. 'notempty' => array(
  808. 'rule' => 'notEmpty',
  809. 'required' => 'update'
  810. )
  811. )
  812. );
  813. $Article->create($data);
  814. $this->assertTrue($Article->validates());
  815. $Article->save(null, array('validate' => false));
  816. $data['Article']['id'] = $Article->id;
  817. $Article->set($data);
  818. $this->assertFalse($Article->validates());
  819. }
  820. /**
  821. * Test that 'required' and 'on' are not conflicting
  822. *
  823. * @return void
  824. */
  825. public function testOnRequiredConflictValidation() {
  826. $this->loadFixtures('Article');
  827. $Article = new Article();
  828. // no title field present
  829. $data = array(
  830. 'Article' => array(
  831. 'body' => 'Extra Fields Body',
  832. 'published' => '1'
  833. )
  834. );
  835. $Article->validate = array(
  836. 'title' => array(
  837. 'notempty' => array(
  838. 'rule' => 'notEmpty',
  839. 'required' => 'create',
  840. 'on' => 'create'
  841. )
  842. )
  843. );
  844. $Article->create($data);
  845. $this->assertFalse($Article->validates());
  846. $Article->validate = array(
  847. 'title' => array(
  848. 'notempty' => array(
  849. 'rule' => 'notEmpty',
  850. 'required' => 'update',
  851. 'on' => 'create'
  852. )
  853. )
  854. );
  855. $Article->create($data);
  856. $this->assertTrue($Article->validates());
  857. $Article->validate = array(
  858. 'title' => array(
  859. 'notempty' => array(
  860. 'rule' => 'notEmpty',
  861. 'required' => 'create',
  862. 'on' => 'update'
  863. )
  864. )
  865. );
  866. $Article->create($data);
  867. $this->assertTrue($Article->validates());
  868. $Article->validate = array(
  869. 'title' => array(
  870. 'notempty' => array(
  871. 'rule' => 'notEmpty',
  872. 'required' => 'update',
  873. 'on' => 'update'
  874. )
  875. )
  876. );
  877. $Article->create($data);
  878. $this->assertTrue($Article->validates());
  879. $Article->validate = array(
  880. 'title' => array(
  881. 'notempty' => array(
  882. 'rule' => 'notEmpty',
  883. 'required' => 'create',
  884. 'on' => 'create'
  885. )
  886. )
  887. );
  888. $Article->save(null, array('validate' => false));
  889. $data['Article']['id'] = $Article->id;
  890. $Article->set($data);
  891. $this->assertTrue($Article->validates());
  892. $Article->validate = array(
  893. 'title' => array(
  894. 'notempty' => array(
  895. 'rule' => 'notEmpty',
  896. 'required' => 'update',
  897. 'on' => 'create'
  898. )
  899. )
  900. );
  901. $Article->set($data);
  902. $this->assertTrue($Article->validates());
  903. $Article->validate = array(
  904. 'title' => array(
  905. 'notempty' => array(
  906. 'rule' => 'notEmpty',
  907. 'required' => 'create',
  908. 'on' => 'update'
  909. )
  910. )
  911. );
  912. $Article->set($data);
  913. $this->assertTrue($Article->validates());
  914. $Article->validate = array(
  915. 'title' => array(
  916. 'notempty' => array(
  917. 'rule' => 'notEmpty',
  918. 'required' => 'update',
  919. 'on' => 'update'
  920. )
  921. )
  922. );
  923. $Article->set($data);
  924. $this->assertFalse($Article->validates());
  925. }
  926. /**
  927. * testSaveAllDeepValidateOnly
  928. * tests the validate methods with deeper recursive data
  929. *
  930. * @return void
  931. */
  932. public function testSaveAllDeepValidateOnly() {
  933. $this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
  934. $TestModel = new Article();
  935. $TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
  936. $TestModel->hasAndBelongsToMany = array();
  937. $TestModel->Comment->Attachment->validate['attachment'] = 'notEmpty';
  938. $TestModel->Comment->validate['comment'] = 'notEmpty';
  939. $data = array(
  940. 'Article' => array('id' => 2),
  941. 'Comment' => array(
  942. array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => 'newuser', 'password' => 'newuserpass')),
  943. array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
  944. )
  945. );
  946. $result = $TestModel->saveAll($data, array('validate' => 'only', 'deep' => true));
  947. $this->assertTrue($result);
  948. $result = $TestModel->validateAssociated($data, array('deep' => true));
  949. $this->assertTrue($result);
  950. $data = array(
  951. 'Article' => array('id' => 2),
  952. 'Comment' => array(
  953. array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
  954. array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
  955. )
  956. );
  957. $result = $TestModel->saveAll($data, array('validate' => 'only', 'deep' => true));
  958. $this->assertFalse($result);
  959. $result = $TestModel->validateAssociated($data, array('deep' => true));
  960. $this->assertFalse($result);
  961. $data = array(
  962. 'Article' => array('id' => 2),
  963. 'Comment' => array(
  964. array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => 'newuser', 'password' => 'newuserpass')),
  965. array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
  966. )
  967. );
  968. $expected = array(
  969. 'Article' => true,
  970. 'Comment' => array(
  971. true,
  972. true
  973. )
  974. );
  975. $result = $TestModel->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
  976. $this->assertSame($expected, $result);
  977. $result = $TestModel->validateAssociated($data, array('atomic' => false, 'deep' => true));
  978. $this->assertSame($expected, $result);
  979. $data = array(
  980. 'Article' => array('id' => 2),
  981. 'Comment' => array(
  982. array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
  983. array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
  984. )
  985. );
  986. $expected = array(
  987. 'Article' => true,
  988. 'Comment' => array(
  989. false,
  990. true
  991. )
  992. );
  993. $result = $TestModel->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
  994. $this->assertSame($expected, $result);
  995. $result = $TestModel->validateAssociated($data, array('atomic' => false, 'deep' => true));
  996. $this->assertSame($expected, $result);
  997. $data = array(
  998. 'Article' => array('id' => 2),
  999. 'Comment' => array(
  1000. array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
  1001. array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => 'deepsaved'))
  1002. )
  1003. );
  1004. $result = $TestModel->saveAll($data, array('validate' => 'only', 'deep' => true));
  1005. $this->assertTrue($result);
  1006. $result = $TestModel->validateAssociated($data, array('deep' => true));
  1007. $this->assertTrue($result);
  1008. $data = array(
  1009. 'Article' => array('id' => 2),
  1010. 'Comment' => array(
  1011. array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
  1012. array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
  1013. )
  1014. );
  1015. $result = $TestModel->saveAll($data, array('validate' => 'only', 'deep' => true));
  1016. $this->assertFalse($result);
  1017. $result = $TestModel->validateAssociated($data, array('deep' => true));
  1018. $this->assertFalse($result);
  1019. $data = array(
  1020. 'Article' => array('id' => 2),
  1021. 'Comment' => array(
  1022. array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
  1023. array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => 'deepsave'))
  1024. )
  1025. );
  1026. $expected = array(
  1027. 'Article' => true,
  1028. 'Comment' => array(
  1029. true,
  1030. true
  1031. )
  1032. );
  1033. $result = $TestModel->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
  1034. $this->assertSame($expected, $result);
  1035. $result = $TestModel->validateAssociated($data, array('atomic' => false, 'deep' => true));
  1036. $this->assertSame($expected, $result);
  1037. $data = array(
  1038. 'Article' => array('id' => 2),
  1039. 'Comment' => array(
  1040. array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
  1041. array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
  1042. )
  1043. );
  1044. $expected = array(
  1045. 'Article' => true,
  1046. 'Comment' => array(
  1047. true,
  1048. false
  1049. )
  1050. );
  1051. $result = $TestModel->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
  1052. $this->assertSame($expected, $result);
  1053. $result = $TestModel->validateAssociated($data, array('atomic' => false, 'deep' => true));
  1054. $this->assertSame($expected, $result);
  1055. $expected = array(
  1056. 'Comment' => array(
  1057. 1 => array(
  1058. 'Attachment' => array(
  1059. 'attachment' => array('This field cannot be left blank')
  1060. )
  1061. )
  1062. )
  1063. );
  1064. $result = $TestModel->validationErrors;
  1065. $this->assertSame($expected, $result);
  1066. $data = array(
  1067. 'Attachment' => array(
  1068. 'attachment' => 'deepsave insert',
  1069. ),
  1070. 'Comment' => array(
  1071. 'comment' => 'First comment deepsave insert',
  1072. 'published' => 'Y',
  1073. 'user_id' => 5,
  1074. 'Article' => array(
  1075. 'title' => 'First Article deepsave insert',
  1076. 'body' => 'First Article Body deepsave insert',
  1077. 'User' => array(
  1078. 'user' => 'deepsave',
  1079. 'password' => 'magic'
  1080. ),
  1081. ),
  1082. )
  1083. );
  1084. $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
  1085. $this->assertTrue($result);
  1086. $result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => true));
  1087. $this->assertTrue($result);
  1088. $expected = array(
  1089. 'Attachment' => true,
  1090. 'Comment' => true
  1091. );
  1092. $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
  1093. $this->assertSame($expected, $result);
  1094. $result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => true));
  1095. $this->assertSame($expected, $result);
  1096. $data = array(
  1097. 'Attachment' => array(
  1098. 'attachment' => 'deepsave insert',
  1099. ),
  1100. 'Comment' => array(
  1101. 'comment' => 'First comment deepsave insert',
  1102. 'published' => 'Y',
  1103. 'user_id' => 5,
  1104. 'Article' => array(
  1105. 'title' => 'First Article deepsave insert',
  1106. 'body' => 'First Article Body deepsave insert',
  1107. 'User' => array(
  1108. 'user' => '',
  1109. 'password' => 'magic'
  1110. ),
  1111. ),
  1112. )
  1113. );
  1114. $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
  1115. $this->assertFalse($result);
  1116. $result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => true));
  1117. $this->assertFalse($result);
  1118. $result = $TestModel->Comment->Attachment->validationErrors;
  1119. $expected = array(
  1120. 'Comment' => array(
  1121. 'Article' => array(
  1122. 'User' => array(
  1123. 'user' => array('This field cannot be left blank')
  1124. )
  1125. )
  1126. )
  1127. );
  1128. $this->assertSame($expected, $result);
  1129. $expected = array(
  1130. 'Attachment' => true,
  1131. 'Comment' => false
  1132. );
  1133. $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
  1134. $this->assertEquals($expected, $result);
  1135. $result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => true));
  1136. $this->assertEquals($expected, $result);
  1137. $data['Comment']['Article']['body'] = '';
  1138. $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
  1139. $this->assertFalse($result);
  1140. $result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => true));
  1141. $this->assertFalse($result);
  1142. $result = $TestModel->Comment->Attachment->validationErrors;
  1143. $expected = array(
  1144. 'Comment' => array(
  1145. 'Article' => array(
  1146. 'body' => array('This field cannot be left blank')
  1147. )
  1148. )
  1149. );
  1150. $this->assertSame($expected, $result);
  1151. $expected = array(
  1152. 'Attachment' => true,
  1153. 'Comment' => false
  1154. );
  1155. $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
  1156. $this->assertEquals($expected, $result);
  1157. $result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => true));
  1158. $this->assertEquals($expected, $result);
  1159. $data['Comment']['comment'] = '';
  1160. $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
  1161. $this->assertFalse($result);
  1162. $result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => true));
  1163. $this->assertFalse($result);
  1164. $result = $TestModel->Comment->Attachment->validationErrors;
  1165. $expected = array(
  1166. 'Comment' => array(
  1167. 'comment' => array('This field cannot be left blank')
  1168. )
  1169. );
  1170. $this->assertSame($expected, $result);
  1171. $expected = array(
  1172. 'Attachment' => true,
  1173. 'Comment' => false
  1174. );
  1175. $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
  1176. $this->assertEquals($expected, $result);
  1177. $result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => true));
  1178. $this->assertEquals($expected, $result);
  1179. $data['Attachment']['attachment'] = '';
  1180. $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
  1181. $this->assertFalse($result);
  1182. $result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => true));
  1183. $this->assertFalse($result);
  1184. $result = $TestModel->Comment->Attachment->validationErrors;
  1185. $expected = array('attachment' => array('This field cannot be left blank'));
  1186. $this->assertSame($expected, $result);
  1187. $result = $TestModel->Comment->validationErrors;
  1188. $expected = array('comment' => array('This field cannot be left blank'));
  1189. $this->assertSame($expected, $result);
  1190. $expected = array(
  1191. 'Attachment' => false,
  1192. 'Comment' => false
  1193. );
  1194. $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
  1195. $this->assertEquals($expected, $result);
  1196. $result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => true));
  1197. $this->assertEquals($expected, $result);
  1198. }
  1199. /**
  1200. * testSaveAllNotDeepValidateOnly
  1201. * tests the validate methods to not validate deeper recursive data
  1202. *
  1203. * @return void
  1204. */
  1205. public function testSaveAllNotDeepValidateOnly() {
  1206. $this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
  1207. $TestModel = new Article();
  1208. $TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
  1209. $TestModel->hasAndBelongsToMany = array();
  1210. $TestModel->Comment->Attachment->validate['attachment'] = 'notEmpty';
  1211. $TestModel->Comment->validate['comment'] = 'notEmpty';
  1212. $data = array(
  1213. 'Article' => array('id' => 2, 'body' => ''),
  1214. 'Comment' => array(
  1215. array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
  1216. array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
  1217. )
  1218. );
  1219. $result = $TestModel->saveAll($data, array('validate' => 'only', 'deep' => false));
  1220. $this->assertFalse($result);
  1221. $result = $TestModel->validateAssociated($data, array('deep' => false));
  1222. $this->assertFalse($result);
  1223. $expected = array('body' => array('This field cannot be left blank'));
  1224. $result = $TestModel->validationErrors;
  1225. $this->assertSame($expected, $result);
  1226. $data = array(
  1227. 'Article' => array('id' => 2, 'body' => 'Ignore invalid user data'),
  1228. 'Comment' => array(
  1229. array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
  1230. array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
  1231. )
  1232. );
  1233. $result = $TestModel->saveAll($data, array('validate' => 'only', 'deep' => false));
  1234. $this->assertTrue($result);
  1235. $result = $TestModel->validateAssociated($data, array('deep' => false));
  1236. $this->assertTrue($result);
  1237. $data = array(
  1238. 'Article' => array('id' => 2, 'body' => 'Ignore invalid user data'),
  1239. 'Comment' => array(
  1240. array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
  1241. array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
  1242. )
  1243. );
  1244. $expected = array(
  1245. 'Article' => true,
  1246. 'Comment' => array(
  1247. true,
  1248. true
  1249. )
  1250. );
  1251. $result = $TestModel->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => false));
  1252. $this->assertSame($expected, $result);
  1253. $result = $TestModel->validateAssociated($data, array('atomic' => false, 'deep' => false));
  1254. $this->assertSame($expected, $result);
  1255. $data = array(
  1256. 'Article' => array('id' => 2, 'body' => 'Ignore invalid attachment data'),
  1257. 'Comment' => array(
  1258. array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
  1259. array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
  1260. )
  1261. );
  1262. $result = $TestModel->saveAll($data, array('validate' => 'only', 'deep' => false));
  1263. $this->assertTrue($result);
  1264. $result = $TestModel->validateAssociated($data, array('deep' => false));
  1265. $this->assertTrue($result);
  1266. $data = array(
  1267. 'Article' => array('id' => 2, 'body' => 'Ignore invalid attachment data'),
  1268. 'Comment' => array(
  1269. array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
  1270. array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
  1271. )
  1272. );
  1273. $expected = array(
  1274. 'Article' => true,
  1275. 'Comment' => array(
  1276. true,
  1277. true
  1278. )
  1279. );
  1280. $result = $TestModel->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => false));
  1281. $this->assertSame($expected, $result);
  1282. $result = $TestModel->validateAssociated($data, array('atomic' => false, 'deep' => false));
  1283. $this->assertSame($expected, $result);
  1284. $expected = array();
  1285. $result = $TestModel->validationErrors;
  1286. $this->assertSame($expected, $result);
  1287. $data = array(
  1288. 'Attachment' => array(
  1289. 'attachment' => 'deepsave insert',
  1290. ),
  1291. 'Comment' => array(
  1292. 'comment' => 'First comment deepsave insert',
  1293. 'published' => 'Y',
  1294. 'user_id' => 5,
  1295. 'Article' => array(
  1296. 'title' => 'First Article deepsave insert ignored',
  1297. 'body' => 'First Article Body deepsave insert',
  1298. 'User' => array(
  1299. 'user' => '',
  1300. 'password' => 'magic'
  1301. ),
  1302. ),
  1303. )
  1304. );
  1305. $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => false));
  1306. $this->assertTrue($result);
  1307. $result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => false));
  1308. $this->assertTrue($result);
  1309. $result = $TestModel->Comment->Attachment->validationErrors;
  1310. $expected = array();
  1311. $this->assertSame($expected, $result);
  1312. $expected = array(
  1313. 'Attachment' => true,
  1314. 'Comment' => true
  1315. );
  1316. $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => false));
  1317. $this->assertEquals($expected, $result);
  1318. $result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => false));
  1319. $this->assertEquals($expected, $result);
  1320. $data['Comment']['Article']['body'] = '';
  1321. $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => false));
  1322. $this->assertTrue($result);
  1323. $result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => false));
  1324. $this->assertTrue($result);
  1325. $result = $TestModel->Comment->Attachment->validationErrors;
  1326. $expected = array();
  1327. $this->assertSame($expected, $result);
  1328. $expected = array(
  1329. 'Attachment' => true,
  1330. 'Comment' => true
  1331. );
  1332. $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => false));
  1333. $this->assertEquals($expected, $result);
  1334. $result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => false));
  1335. $this->assertEquals($expected, $result);
  1336. }
  1337. /**
  1338. * testValidateAssociated method
  1339. *
  1340. * @return void
  1341. */
  1342. public function testValidateAssociated() {
  1343. $this->loadFixtures('Comment', 'Attachment');
  1344. $TestModel = new Comment();
  1345. $TestModel->Attachment->validate = array('attachment' => 'notEmpty');
  1346. $data = array(
  1347. 'Comment' => array(
  1348. 'comment' => 'This is the comment'
  1349. ),
  1350. 'Attachment' => array(
  1351. 'attachment' => ''
  1352. )
  1353. );
  1354. $result = $TestModel->saveAll($data, array('validate' => 'only'));
  1355. $this->assertFalse($result);
  1356. $result = $TestModel->validateAssociated($data);
  1357. $this->assertFalse($result);
  1358. $TestModel->validate = array('comment' => 'notEmpty');
  1359. $record = array(
  1360. 'Comment' => array(
  1361. 'user_id' => 1,
  1362. 'article_id' => 1,
  1363. 'comment' => '',
  1364. ),
  1365. 'Attachment' => array(
  1366. 'attachment' => ''
  1367. )
  1368. );
  1369. $result = $TestModel->saveAll($record, array('validate' => 'only'));
  1370. $this->assertFalse($result);
  1371. $result = $TestModel->validateAssociated($record);
  1372. $this->assertFalse($result);
  1373. $fieldList = array(
  1374. 'Comment' => array('id', 'article_id', 'user_id'),
  1375. 'Attachment' => array('comment_id')
  1376. );
  1377. $result = $TestModel->saveAll($record, array(
  1378. 'fieldList' => $fieldList, 'validate' => 'only'
  1379. ));
  1380. $this->assertTrue($result);
  1381. $this->assertEmpty($TestModel->validationErrors);
  1382. $result = $TestModel->validateAssociated($record, array('fieldList' => $fieldList));
  1383. $this->assertTrue($result);
  1384. $this->assertEmpty($TestModel->validationErrors);
  1385. $TestModel = new Article();
  1386. $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
  1387. $TestModel->Comment->validate = array('comment' => 'notEmpty');
  1388. $data = array(
  1389. 'Article' => array('id' => 2),
  1390. 'Comment' => array(
  1391. array(
  1392. 'id' => 1,
  1393. 'comment' => '',
  1394. 'published' => 'Y',
  1395. 'user_id' => 1,
  1396. ),
  1397. array(
  1398. 'id' => 2,
  1399. 'comment' =>
  1400. 'comment',
  1401. 'published' => 'Y',
  1402. 'user_id' => 1
  1403. ),
  1404. array(
  1405. 'id' => 3,
  1406. 'comment' => '',
  1407. 'published' => 'Y',
  1408. 'user_id' => 1
  1409. )));
  1410. $result = $TestModel->saveAll($data, array('validate' => 'only'));
  1411. $this->assertFalse($result);
  1412. $result = $TestModel->validateAssociated($data);
  1413. $this->assertFalse($result);
  1414. $expected = array(
  1415. 'Article' => true,
  1416. 'Comment' => array(false, true, false)
  1417. );
  1418. $result = $TestModel->saveAll($data, array('atomic' => false, 'validate' => 'only'));
  1419. $this->assertSame($expected, $result);
  1420. $result = $TestModel->validateAssociated($data, array('atomic' => false));
  1421. $this->assertSame($expected, $result);
  1422. $expected = array('Comment' => array(
  1423. 0 => array('comment' => array('This field cannot be left blank')),
  1424. 2 => array('comment' => array('This field cannot be left blank'))
  1425. ));
  1426. $this->assertEquals($expected['Comment'], $TestModel->Comment->validationErrors);
  1427. $model = new Comment();
  1428. $model->deleteAll(true);
  1429. $model->validate = array('comment' => 'notEmpty');
  1430. $model->Attachment->validate = array('attachment' => 'notEmpty');
  1431. $model->Attachment->bindModel(array('belongsTo' => array('Comment')));
  1432. $expected = array(
  1433. 'Comment' => array('comment' => array('This field cannot be left blank')),
  1434. 'Attachment' => array('attachment' => array('This field cannot be left blank'))
  1435. );
  1436. $data = array(
  1437. 'Comment' => array('comment' => '', 'article_id' => 1, 'user_id' => 1),
  1438. 'Attachment' => array('attachment' => '')
  1439. );
  1440. $result = $model->saveAll($data, array('validate' => 'only'));
  1441. $this->assertFalse($result);
  1442. $result = $model->validateAssociated($data);
  1443. $this->assertFalse($result);
  1444. $this->assertEquals($expected['Comment'], $model->validationErrors);
  1445. $this->assertEquals($expected['Attachment'], $model->Attachment->validationErrors);
  1446. }
  1447. /**
  1448. * testValidateMany method
  1449. *
  1450. * @return void
  1451. */
  1452. public function testValidateMany() {
  1453. $TestModel = new Article();
  1454. $TestModel->validate = array('title' => 'notEmpty');
  1455. $data = array(
  1456. 0 => array('title' => ''),
  1457. 1 => array('title' => 'title 1'),
  1458. 2 => array('title' => 'title 2'),
  1459. );
  1460. $expected = array(
  1461. 0 => array('title' => array('This field cannot be left blank')),
  1462. );
  1463. $result = $TestModel->saveAll($data, array('validate' => 'only'));
  1464. $this->assertFalse($result);
  1465. $this->assertEquals($expected, $TestModel->validationErrors);
  1466. $result = $TestModel->validateMany($data);
  1467. $this->assertFalse($result);
  1468. $this->assertEquals($expected, $TestModel->validationErrors);
  1469. $data = array(
  1470. 0 => array('title' => 'title 0'),
  1471. 1 => array('title' => ''),
  1472. 2 => array('title' => 'title 2'),
  1473. );
  1474. $expected = array(
  1475. 1 => array('title' => array('This field cannot be left blank')),
  1476. );
  1477. $result = $TestModel->saveAll($data, array('validate' => 'only'));
  1478. $this->assertFalse($result);
  1479. $this->assertEquals($expected, $TestModel->validationErrors);
  1480. $result = $TestModel->validateMany($data);
  1481. $this->assertFalse($result);
  1482. $this->assertEquals($expected, $TestModel->validationErrors);
  1483. }
  1484. /**
  1485. * testGetMethods method
  1486. *
  1487. * @return void
  1488. */
  1489. public function testGetMethods() {
  1490. $this->loadFixtures('Article', 'Comment');
  1491. $TestModel = new Article();
  1492. $Validator = $TestModel->validator();
  1493. $result = $Validator->getMethods();
  1494. $expected = array_map('strtolower', get_class_methods('Article'));
  1495. $this->assertEquals($expected, array_keys($result));
  1496. }
  1497. /**
  1498. * testSetValidationDomain method
  1499. *
  1500. * @return void
  1501. */
  1502. public function testSetValidationDomain() {
  1503. $this->loadFixtures('Article', 'Comment');
  1504. $TestModel = new Article();
  1505. $Validator = $TestModel->validator();
  1506. $result = $Validator->setValidationDomain('default');
  1507. $this->assertEquals('default', $TestModel->validationDomain);
  1508. $result = $Validator->setValidationDomain('other');
  1509. $this->assertEquals('other', $TestModel->validationDomain);
  1510. }
  1511. /**
  1512. * testGetModel method
  1513. *
  1514. * @return void
  1515. */
  1516. public function testGetModel() {
  1517. $TestModel = new Article();
  1518. $Validator = $TestModel->validator();
  1519. $result = $Validator->getModel();
  1520. $this->assertInstanceOf('Article', $result);
  1521. }
  1522. /**
  1523. * Tests it is possible to get validation sets for a field using an array inteface
  1524. *
  1525. * @return void
  1526. */
  1527. public function testArrayAccessGet() {
  1528. $TestModel = new Article();
  1529. $Validator = $TestModel->validator();
  1530. $titleValidator = $Validator['title'];
  1531. $this->assertEquals('title', $titleValidator->field);
  1532. $this->assertCount(1, $titleValidator->getRules());
  1533. $rule = current($titleValidator->getRules());
  1534. $this->assertEquals('notEmpty', $rule->rule);
  1535. $titleValidator = $Validator['body'];
  1536. $this->assertEquals('body', $titleValidator->field);
  1537. $this->assertCount(1, $titleValidator->getRules());
  1538. $rule = current($titleValidator->getRules());
  1539. $this->assertEquals('notEmpty', $rule->rule);
  1540. $titleValidator = $Validator['user_id'];
  1541. $this->assertEquals('user_id', $titleValidator->field);
  1542. $this->assertCount(1, $titleValidator->getRules());
  1543. $rule = current($titleValidator->getRules());
  1544. $this->assertEquals('numeric', $rule->rule);
  1545. }
  1546. /**
  1547. * Tests it is possible to check for validation sets for a field using an array inteface
  1548. *
  1549. * @return void
  1550. */
  1551. public function testArrayAccessExists() {
  1552. $TestModel = new Article();
  1553. $Validator = $TestModel->validator();
  1554. $this->assertTrue(isset($Validator['title']));
  1555. $this->assertTrue(isset($Validator['body']));
  1556. $this->assertTrue(isset($Validator['user_id']));
  1557. $this->assertFalse(isset($Validator['other']));
  1558. }
  1559. /**
  1560. * Tests it is possible to set validation rules for a field using an array inteface
  1561. *
  1562. * @return void
  1563. */
  1564. public function testArrayAccessSet() {
  1565. $TestModel = new Article();
  1566. $Validator = $TestModel->validator();
  1567. $set = array(
  1568. 'numeric' => array('rule' => 'numeric', 'allowEmpty' => false),
  1569. 'range' => array('rule' => array('between', 1, 5), 'allowEmpty' => false),
  1570. );
  1571. $Validator['other'] = $set;
  1572. $rules = $Validator['other'];
  1573. $this->assertEquals('other', $rules->field);
  1574. $validators = $rules->getRules();
  1575. $this->assertCount(2, $validators);
  1576. $this->assertEquals('numeric', $validators['numeric']->rule);
  1577. $this->assertEquals(array('between', 1, 5), $validators['range']->rule);
  1578. $Validator['new'] = new CakeValidationSet('new', $set, array());
  1579. $rules = $Validator['new'];
  1580. $this->assertEquals('new', $rules->field);
  1581. $validators = $rules->getRules();
  1582. $this->assertCount(2, $validators);
  1583. $this->assertEquals('numeric', $validators['numeric']->rule);
  1584. $this->assertEquals(array('between', 1, 5), $validators['range']->rule);
  1585. }
  1586. /**
  1587. * Tests it is possible to unset validation rules
  1588. *
  1589. * @return void
  1590. */
  1591. public function testArrayAccessUset() {
  1592. $TestModel = new Article();
  1593. $Validator = $TestModel->validator();
  1594. $this->assertTrue(isset($Validator['title']));
  1595. unset($Validator['title']);
  1596. $this->assertFalse(isset($Validator['title']));
  1597. }
  1598. /**
  1599. * Tests it is possible to iterate a validation object
  1600. *
  1601. * @return void
  1602. */
  1603. public function testIterator() {
  1604. $TestModel = new Article();
  1605. $Validator = $TestModel->validator();
  1606. $i = 0;
  1607. foreach ($Validator as $field => $rules) {
  1608. if ($i === 0) {
  1609. $this->assertEquals('user_id', $field);
  1610. }
  1611. if ($i === 1) {
  1612. $this->assertEquals('title', $field);
  1613. }
  1614. if ($i === 2) {
  1615. $this->assertEquals('body', $field);
  1616. }
  1617. $this->assertInstanceOf('CakeValidationSet', $rules);
  1618. $i++;
  1619. }
  1620. $this->assertEquals(3, $i);
  1621. }
  1622. /**
  1623. * Tests countable interface in ModelValidator
  1624. *
  1625. * @return void
  1626. */
  1627. public function testCount() {
  1628. $TestModel = new Article();
  1629. $Validator = $TestModel->validator();
  1630. $this->assertCount(3, $Validator);
  1631. $set = array(
  1632. 'numeric' => array('rule' => 'numeric', 'allowEmpty' => false),
  1633. 'range' => array('rule' => array('between', 1, 5), 'allowEmpty' => false),
  1634. );
  1635. $Validator['other'] = $set;
  1636. $this->assertCount(4, $Validator);
  1637. unset($Validator['title']);
  1638. $this->assertCount(3, $Validator);
  1639. unset($Validator['body']);
  1640. $this->assertCount(2, $Validator);
  1641. }
  1642. /**
  1643. * Tests it is possible to add validation rules
  1644. *
  1645. * @return void
  1646. */
  1647. public function testAddRule() {
  1648. $TestModel = new Article();
  1649. $Validator = $TestModel->validator();
  1650. $set = array(
  1651. 'numeric' => array('rule' => 'numeric', 'allowEmpty' => false),
  1652. 'range' => array('rule' => array('between', 1, 5), 'allowEmpty' => false),
  1653. );
  1654. $Validator->add('other', 'numeric', array('rule' => 'numeric', 'allowEmpty' => false));
  1655. $Validator->add('other', 'range', array('rule' => array('between', 1, 5), 'allowEmpty' => false));
  1656. $rules = $Validator['other'];
  1657. $this->assertEquals('other', $rules->field);
  1658. $validators = $rules->getRules();
  1659. $this->assertCount(2, $validators);
  1660. $this->assertEquals('numeric', $validators['numeric']->rule);
  1661. $this->assertEquals(array('between', 1, 5), $validators['range']->rule);
  1662. }
  1663. /**
  1664. * Tests it is possible to remove validation rules
  1665. *
  1666. * @return void
  1667. */
  1668. public function testRemoveRule() {
  1669. $TestModel = new Article();
  1670. $Validator = $TestModel->validator();
  1671. $this->assertTrue(isset($Validator['title']));
  1672. $Validator->remove('title');
  1673. $this->assertFalse(isset($Validator['title']));
  1674. $Validator->add('other', 'numeric', array('rule' => 'numeric', 'allowEmpty' => false));
  1675. $Validator->add('other', 'range', array('rule' => array('between', 1, 5), 'allowEmpty' => false));
  1676. $this->assertTrue(isset($Validator['other']));
  1677. $Validator->remove('other', 'numeric');
  1678. $this->assertTrue(isset($Validator['other']));
  1679. $this->assertFalse(isset($Validator['other']['numeric']));
  1680. $this->assertTrue(isset($Validator['other']['range']));
  1681. }
  1682. /**
  1683. * Tests validation callbacks are triggered
  1684. *
  1685. * @return void
  1686. */
  1687. public function testValidateCallbacks() {
  1688. $TestModel = $this->getMock('Article', array('beforeValidate', 'afterValidate'));
  1689. $TestModel->expects($this->once())->method('beforeValidate');
  1690. $TestModel->expects($this->once())->method('afterValidate');
  1691. $TestModel->set(array('title' => '', 'body' => 'body'));
  1692. $TestModel->validates();
  1693. }
  1694. /**
  1695. * Tests that altering data in a beforeValidate callback will lead to saving those
  1696. * values in database
  1697. *
  1698. * @return void
  1699. */
  1700. public function testValidateFirstWithBeforeValidate() {
  1701. $this->loadFixtures('Article', 'User');
  1702. $model = new CustomArticle();
  1703. $model->validate = array(
  1704. 'title' => array(
  1705. 'notempty' => array(
  1706. 'rule' => 'notEmpty',
  1707. 'required' => true,
  1708. 'allowEmpty' => false
  1709. )
  1710. )
  1711. );
  1712. $data = array(
  1713. 'CustomArticle' => array(
  1714. 'body' => 'foo0'
  1715. )
  1716. );
  1717. $result = $model->saveAll($data, array('validate' => 'first'));
  1718. $this->assertTrue($result);
  1719. $this->assertFalse($model->findMethods['unPublished'], 'beforeValidate was run twice');
  1720. $model->findMethods['unPublished'] = true;
  1721. $data = array(
  1722. 'CustomArticle' => array(
  1723. 'body' => 'foo1'
  1724. )
  1725. );
  1726. $result = $model->saveAll($data, array('validate' => 'first', 'deep' => true));
  1727. $this->assertTrue($result);
  1728. $title = $model->field('title', array('body' => 'foo1'));
  1729. $this->assertEquals('foo', $title);
  1730. $this->assertFalse($model->findMethods['unPublished'], 'beforeValidate was run twice');
  1731. $data = array(
  1732. array('body' => 'foo2'),
  1733. array('body' => 'foo3'),
  1734. array('body' => 'foo4')
  1735. );
  1736. $result = $model->saveAll($data, array('validate' => 'first', 'deep' => true));
  1737. $this->assertTrue($result);
  1738. $this->assertEquals('foo', $model->field('title', array('body' => 'foo2')));
  1739. $this->assertEquals('foo', $model->field('title', array('body' => 'foo3')));
  1740. $this->assertEquals('foo', $model->field('title', array('body' => 'foo4')));
  1741. }
  1742. /**
  1743. * Tests that altering data in a beforeValidate callback will lead to saving those
  1744. * values in database
  1745. *
  1746. * @return void
  1747. */
  1748. public function testValidateFirstAssociatedWithBeforeValidate() {
  1749. $this->loadFixtures('Article', 'User');
  1750. $model = new CustomArticle();
  1751. $model->validate = array(
  1752. 'title' => array(
  1753. 'notempty' => array(
  1754. 'rule' => 'notEmpty',
  1755. 'required' => true
  1756. )
  1757. )
  1758. );
  1759. $articles = array(
  1760. array('body' => 'foo1'),
  1761. array('body' => 'foo2'),
  1762. array('body' => 'foo3')
  1763. );
  1764. $user = new User();
  1765. $user->hasMany['CustomArticle'] = array('foreignKey' => 'user_id');
  1766. $data = array(
  1767. 'User' => array('user' => 'foo', 'password' => 'bar'),
  1768. 'CustomArticle' => $articles
  1769. );
  1770. $result = $user->saveAll($data, array('validate' => 'first'));
  1771. $this->assertTrue($result);
  1772. $this->assertEquals('foo', $model->field('title', array('body' => 'foo1')));
  1773. $this->assertEquals('foo', $model->field('title', array('body' => 'foo2')));
  1774. $this->assertEquals('foo', $model->field('title', array('body' => 'foo3')));
  1775. }
  1776. /**
  1777. * testValidateFirstWithDefaults method
  1778. *
  1779. * return @void
  1780. */
  1781. public function testFirstWithDefaults() {
  1782. $this->loadFixtures('Article', 'Tag', 'Comment', 'User', 'ArticlesTag');
  1783. $TestModel = new Article();
  1784. $result = $TestModel->find('first', array(
  1785. 'conditions' => array('Article.id' => 1)
  1786. ));
  1787. $expected = array(
  1788. 'Article' => array(
  1789. 'id' => 1,
  1790. 'user_id' => 1,
  1791. 'title' => 'First Article',
  1792. 'body' => 'First Article Body',
  1793. 'published' => 'Y',
  1794. 'created' => '2007-03-18 10:39:23'
  1795. ),
  1796. );
  1797. unset($result['Article']['updated']);
  1798. $this->assertEquals($expected['Article'], $result['Article']);
  1799. $data = array(
  1800. 'Article' => array(
  1801. 'id' => 1,
  1802. 'title' => 'First Article (modified)'
  1803. ),
  1804. 'Comment' => array(
  1805. array('comment' => 'Article comment', 'user_id' => 1)
  1806. )
  1807. );
  1808. $result = $TestModel->saveAll($data, array('validate' => 'first'));
  1809. $this->assertTrue($result);
  1810. $result = $TestModel->find('first', array(
  1811. 'conditions' => array('Article.id' => 1)
  1812. ));
  1813. $expected['Article']['title'] = 'First Article (modified)';
  1814. unset($result['Article']['updated']);
  1815. $this->assertEquals($expected['Article'], $result['Article']);
  1816. }
  1817. }