ModelValidationTest.php 67 KB

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