ModelValidationTest.php 63 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181
  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. 'User' => array(
  1148. 'user' => array('This field cannot be left blank')
  1149. )
  1150. )
  1151. )
  1152. );
  1153. $this->assertSame($expected, $result);
  1154. $expected = array(
  1155. 'Attachment' => true,
  1156. 'Comment' => false
  1157. );
  1158. $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
  1159. $this->assertEquals($expected, $result);
  1160. $result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => true));
  1161. $this->assertEquals($expected, $result);
  1162. $data['Comment']['comment'] = '';
  1163. $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
  1164. $this->assertFalse($result);
  1165. $result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => true));
  1166. $this->assertFalse($result);
  1167. $result = $TestModel->Comment->Attachment->validationErrors;
  1168. $expected = array(
  1169. 'Comment' => array(
  1170. 'comment' => array('This field cannot be left blank'),
  1171. 'Article' => array(
  1172. 'body' => array('This field cannot be left blank'),
  1173. 'User' => array(
  1174. 'user' => array('This field cannot be left blank')
  1175. )
  1176. )
  1177. )
  1178. );
  1179. $this->assertSame($expected, $result);
  1180. $expected = array(
  1181. 'Attachment' => true,
  1182. 'Comment' => false
  1183. );
  1184. $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
  1185. $this->assertEquals($expected, $result);
  1186. $result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => true));
  1187. $this->assertEquals($expected, $result);
  1188. $data['Attachment']['attachment'] = '';
  1189. $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
  1190. $this->assertFalse($result);
  1191. $result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => true));
  1192. $this->assertFalse($result);
  1193. $result = $TestModel->Comment->Attachment->validationErrors;
  1194. $expected = array(
  1195. 'attachment' => array('This field cannot be left blank'),
  1196. 'Comment' => array(
  1197. 'comment' => array('This field cannot be left blank'),
  1198. 'Article' => array(
  1199. 'body' => array('This field cannot be left blank'),
  1200. 'User' => array(
  1201. 'user' => array('This field cannot be left blank')
  1202. )
  1203. )
  1204. )
  1205. );
  1206. $this->assertSame($expected, $result);
  1207. $result = $TestModel->Comment->validationErrors;
  1208. $expected = array(
  1209. 'comment' => array('This field cannot be left blank'),
  1210. 'Article' => array(
  1211. 'body' => array('This field cannot be left blank'),
  1212. 'User' => array(
  1213. 'user' => array('This field cannot be left blank')
  1214. )
  1215. )
  1216. );
  1217. $this->assertSame($expected, $result);
  1218. $expected = array(
  1219. 'Attachment' => false,
  1220. 'Comment' => false
  1221. );
  1222. $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
  1223. $this->assertEquals($expected, $result);
  1224. $result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => true));
  1225. $this->assertEquals($expected, $result);
  1226. }
  1227. /**
  1228. * testSaveAllNotDeepValidateOnly
  1229. * tests the validate methods to not validate deeper recursive data
  1230. *
  1231. * @return void
  1232. */
  1233. public function testSaveAllNotDeepValidateOnly() {
  1234. $this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
  1235. $TestModel = new Article();
  1236. $TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
  1237. $TestModel->hasAndBelongsToMany = array();
  1238. $TestModel->Comment->Attachment->validate['attachment'] = 'notEmpty';
  1239. $TestModel->Comment->validate['comment'] = 'notEmpty';
  1240. $data = array(
  1241. 'Article' => array('id' => 2, 'body' => ''),
  1242. 'Comment' => array(
  1243. array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
  1244. array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
  1245. )
  1246. );
  1247. $result = $TestModel->saveAll($data, array('validate' => 'only', 'deep' => false));
  1248. $this->assertFalse($result);
  1249. $result = $TestModel->validateAssociated($data, array('deep' => false));
  1250. $this->assertFalse($result);
  1251. $expected = array('body' => array('This field cannot be left blank'));
  1252. $result = $TestModel->validationErrors;
  1253. $this->assertSame($expected, $result);
  1254. $data = array(
  1255. 'Article' => array('id' => 2, 'body' => 'Ignore invalid user data'),
  1256. 'Comment' => array(
  1257. array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
  1258. array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
  1259. )
  1260. );
  1261. $result = $TestModel->saveAll($data, array('validate' => 'only', 'deep' => false));
  1262. $this->assertTrue($result);
  1263. $result = $TestModel->validateAssociated($data, array('deep' => false));
  1264. $this->assertTrue($result);
  1265. $data = array(
  1266. 'Article' => array('id' => 2, 'body' => 'Ignore invalid user data'),
  1267. 'Comment' => array(
  1268. array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
  1269. array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
  1270. )
  1271. );
  1272. $expected = array(
  1273. 'Article' => true,
  1274. 'Comment' => array(
  1275. true,
  1276. true
  1277. )
  1278. );
  1279. $result = $TestModel->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => false));
  1280. $this->assertSame($expected, $result);
  1281. $result = $TestModel->validateAssociated($data, array('atomic' => false, 'deep' => false));
  1282. $this->assertSame($expected, $result);
  1283. $data = array(
  1284. 'Article' => array('id' => 2, 'body' => 'Ignore invalid attachment data'),
  1285. 'Comment' => array(
  1286. array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
  1287. array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
  1288. )
  1289. );
  1290. $result = $TestModel->saveAll($data, array('validate' => 'only', 'deep' => false));
  1291. $this->assertTrue($result);
  1292. $result = $TestModel->validateAssociated($data, array('deep' => false));
  1293. $this->assertTrue($result);
  1294. $data = array(
  1295. 'Article' => array('id' => 2, 'body' => 'Ignore invalid attachment data'),
  1296. 'Comment' => array(
  1297. array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
  1298. array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
  1299. )
  1300. );
  1301. $expected = array(
  1302. 'Article' => true,
  1303. 'Comment' => array(
  1304. true,
  1305. true
  1306. )
  1307. );
  1308. $result = $TestModel->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => false));
  1309. $this->assertSame($expected, $result);
  1310. $result = $TestModel->validateAssociated($data, array('atomic' => false, 'deep' => false));
  1311. $this->assertSame($expected, $result);
  1312. $expected = array();
  1313. $result = $TestModel->validationErrors;
  1314. $this->assertSame($expected, $result);
  1315. $data = array(
  1316. 'Attachment' => array(
  1317. 'attachment' => 'deepsave insert',
  1318. ),
  1319. 'Comment' => array(
  1320. 'comment' => 'First comment deepsave insert',
  1321. 'published' => 'Y',
  1322. 'user_id' => 5,
  1323. 'Article' => array(
  1324. 'title' => 'First Article deepsave insert ignored',
  1325. 'body' => 'First Article Body deepsave insert',
  1326. 'User' => array(
  1327. 'user' => '',
  1328. 'password' => 'magic'
  1329. ),
  1330. ),
  1331. )
  1332. );
  1333. $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => false));
  1334. $this->assertTrue($result);
  1335. $result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => false));
  1336. $this->assertTrue($result);
  1337. $result = $TestModel->Comment->Attachment->validationErrors;
  1338. $expected = array();
  1339. $this->assertSame($expected, $result);
  1340. $expected = array(
  1341. 'Attachment' => true,
  1342. 'Comment' => true
  1343. );
  1344. $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => false));
  1345. $this->assertEquals($expected, $result);
  1346. $result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => false));
  1347. $this->assertEquals($expected, $result);
  1348. $data['Comment']['Article']['body'] = '';
  1349. $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => false));
  1350. $this->assertTrue($result);
  1351. $result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => false));
  1352. $this->assertTrue($result);
  1353. $result = $TestModel->Comment->Attachment->validationErrors;
  1354. $expected = array();
  1355. $this->assertSame($expected, $result);
  1356. $expected = array(
  1357. 'Attachment' => true,
  1358. 'Comment' => true
  1359. );
  1360. $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => false));
  1361. $this->assertEquals($expected, $result);
  1362. $result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => false));
  1363. $this->assertEquals($expected, $result);
  1364. }
  1365. /**
  1366. * testValidateAssociated method
  1367. *
  1368. * @return void
  1369. */
  1370. public function testValidateAssociated() {
  1371. $this->loadFixtures('Comment', 'Attachment');
  1372. $TestModel = new Comment();
  1373. $TestModel->Attachment->validate = array('attachment' => 'notEmpty');
  1374. $data = array(
  1375. 'Comment' => array(
  1376. 'comment' => 'This is the comment'
  1377. ),
  1378. 'Attachment' => array(
  1379. 'attachment' => ''
  1380. )
  1381. );
  1382. $result = $TestModel->saveAll($data, array('validate' => 'only'));
  1383. $this->assertFalse($result);
  1384. $result = $TestModel->validateAssociated($data);
  1385. $this->assertFalse($result);
  1386. $TestModel->validate = array('comment' => 'notEmpty');
  1387. $record = array(
  1388. 'Comment' => array(
  1389. 'user_id' => 1,
  1390. 'article_id' => 1,
  1391. 'comment' => '',
  1392. ),
  1393. 'Attachment' => array(
  1394. 'attachment' => ''
  1395. )
  1396. );
  1397. $result = $TestModel->saveAll($record, array('validate' => 'only'));
  1398. $this->assertFalse($result);
  1399. $result = $TestModel->validateAssociated($record);
  1400. $this->assertFalse($result);
  1401. $fieldList = array(
  1402. 'Comment' => array('id', 'article_id', 'user_id'),
  1403. 'Attachment' => array('comment_id')
  1404. );
  1405. $result = $TestModel->saveAll($record, array(
  1406. 'fieldList' => $fieldList, 'validate' => 'only'
  1407. ));
  1408. $this->assertTrue($result);
  1409. $this->assertEmpty($TestModel->validationErrors);
  1410. $result = $TestModel->validateAssociated($record, array('fieldList' => $fieldList));
  1411. $this->assertTrue($result);
  1412. $this->assertEmpty($TestModel->validationErrors);
  1413. $TestModel = new Article();
  1414. $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
  1415. $TestModel->Comment->validate = array('comment' => 'notEmpty');
  1416. $data = array(
  1417. 'Article' => array('id' => 2),
  1418. 'Comment' => array(
  1419. array(
  1420. 'id' => 1,
  1421. 'comment' => '',
  1422. 'published' => 'Y',
  1423. 'user_id' => 1,
  1424. ),
  1425. array(
  1426. 'id' => 2,
  1427. 'comment' =>
  1428. 'comment',
  1429. 'published' => 'Y',
  1430. 'user_id' => 1
  1431. ),
  1432. array(
  1433. 'id' => 3,
  1434. 'comment' => '',
  1435. 'published' => 'Y',
  1436. 'user_id' => 1
  1437. )));
  1438. $result = $TestModel->saveAll($data, array('validate' => 'only'));
  1439. $this->assertFalse($result);
  1440. $result = $TestModel->validateAssociated($data);
  1441. $this->assertFalse($result);
  1442. $expected = array(
  1443. 'Article' => true,
  1444. 'Comment' => array(false, true, false)
  1445. );
  1446. $result = $TestModel->saveAll($data, array('atomic' => false, 'validate' => 'only'));
  1447. $this->assertSame($expected, $result);
  1448. $result = $TestModel->validateAssociated($data, array('atomic' => false));
  1449. $this->assertSame($expected, $result);
  1450. $expected = array('Comment' => array(
  1451. 0 => array('comment' => array('This field cannot be left blank')),
  1452. 2 => array('comment' => array('This field cannot be left blank'))
  1453. ));
  1454. $this->assertEquals($expected['Comment'], $TestModel->Comment->validationErrors);
  1455. $model = new Comment();
  1456. $model->deleteAll(true);
  1457. $model->validate = array('comment' => 'notEmpty');
  1458. $model->Attachment->validate = array('attachment' => 'notEmpty');
  1459. $model->Attachment->bindModel(array('belongsTo' => array('Comment')));
  1460. $expected = array(
  1461. 'comment' => array('This field cannot be left blank'),
  1462. 'Attachment' => array(
  1463. 'attachment' => array('This field cannot be left blank')
  1464. )
  1465. );
  1466. $data = array(
  1467. 'Comment' => array('comment' => '', 'article_id' => 1, 'user_id' => 1),
  1468. 'Attachment' => array('attachment' => '')
  1469. );
  1470. $result = $model->saveAll($data, array('validate' => 'only'));
  1471. $this->assertFalse($result);
  1472. $result = $model->validateAssociated($data);
  1473. $this->assertFalse($result);
  1474. $this->assertEquals($expected, $model->validationErrors);
  1475. $this->assertEquals($expected['Attachment'], $model->Attachment->validationErrors);
  1476. }
  1477. /**
  1478. * testValidateMany method
  1479. *
  1480. * @return void
  1481. */
  1482. public function testValidateMany() {
  1483. $TestModel = new Article();
  1484. $TestModel->validate = array('title' => 'notEmpty');
  1485. $data = array(
  1486. 0 => array('title' => ''),
  1487. 1 => array('title' => 'title 1'),
  1488. 2 => array('title' => 'title 2'),
  1489. );
  1490. $expected = array(
  1491. 0 => array('title' => array('This field cannot be left blank')),
  1492. );
  1493. $result = $TestModel->saveAll($data, array('validate' => 'only'));
  1494. $this->assertFalse($result);
  1495. $this->assertEquals($expected, $TestModel->validationErrors);
  1496. $result = $TestModel->validateMany($data);
  1497. $this->assertFalse($result);
  1498. $this->assertEquals($expected, $TestModel->validationErrors);
  1499. $data = array(
  1500. 0 => array('title' => 'title 0'),
  1501. 1 => array('title' => ''),
  1502. 2 => array('title' => 'title 2'),
  1503. );
  1504. $expected = array(
  1505. 1 => array('title' => array('This field cannot be left blank')),
  1506. );
  1507. $result = $TestModel->saveAll($data, array('validate' => 'only'));
  1508. $this->assertFalse($result);
  1509. $this->assertEquals($expected, $TestModel->validationErrors);
  1510. $result = $TestModel->validateMany($data);
  1511. $this->assertFalse($result);
  1512. $this->assertEquals($expected, $TestModel->validationErrors);
  1513. }
  1514. /**
  1515. * testGetMethods method
  1516. *
  1517. * @return void
  1518. */
  1519. public function testGetMethods() {
  1520. $this->loadFixtures('Article', 'Comment');
  1521. $TestModel = new Article();
  1522. $Validator = $TestModel->validator();
  1523. $result = $Validator->getMethods();
  1524. $expected = array_map('strtolower', get_class_methods('Article'));
  1525. $this->assertEquals($expected, array_keys($result));
  1526. }
  1527. /**
  1528. * testSetValidationDomain method
  1529. *
  1530. * @return void
  1531. */
  1532. public function testSetValidationDomain() {
  1533. $this->loadFixtures('Article', 'Comment');
  1534. $TestModel = new Article();
  1535. $Validator = $TestModel->validator();
  1536. $result = $Validator->setValidationDomain('default');
  1537. $this->assertEquals('default', $TestModel->validationDomain);
  1538. $result = $Validator->setValidationDomain('other');
  1539. $this->assertEquals('other', $TestModel->validationDomain);
  1540. }
  1541. /**
  1542. * testGetModel method
  1543. *
  1544. * @return void
  1545. */
  1546. public function testGetModel() {
  1547. $TestModel = new Article();
  1548. $Validator = $TestModel->validator();
  1549. $result = $Validator->getModel();
  1550. $this->assertInstanceOf('Article', $result);
  1551. }
  1552. /**
  1553. * Tests it is possible to get validation sets for a field using an array inteface
  1554. *
  1555. * @return void
  1556. */
  1557. public function testArrayAccessGet() {
  1558. $TestModel = new Article();
  1559. $Validator = $TestModel->validator();
  1560. $titleValidator = $Validator['title'];
  1561. $this->assertEquals('title', $titleValidator->field);
  1562. $this->assertCount(1, $titleValidator->getRules());
  1563. $rule = current($titleValidator->getRules());
  1564. $this->assertEquals('notEmpty', $rule->rule);
  1565. $titleValidator = $Validator['body'];
  1566. $this->assertEquals('body', $titleValidator->field);
  1567. $this->assertCount(1, $titleValidator->getRules());
  1568. $rule = current($titleValidator->getRules());
  1569. $this->assertEquals('notEmpty', $rule->rule);
  1570. $titleValidator = $Validator['user_id'];
  1571. $this->assertEquals('user_id', $titleValidator->field);
  1572. $this->assertCount(1, $titleValidator->getRules());
  1573. $rule = current($titleValidator->getRules());
  1574. $this->assertEquals('numeric', $rule->rule);
  1575. }
  1576. /**
  1577. * Tests it is possible to check for validation sets for a field using an array inteface
  1578. *
  1579. * @return void
  1580. */
  1581. public function testArrayAccessExists() {
  1582. $TestModel = new Article();
  1583. $Validator = $TestModel->validator();
  1584. $this->assertTrue(isset($Validator['title']));
  1585. $this->assertTrue(isset($Validator['body']));
  1586. $this->assertTrue(isset($Validator['user_id']));
  1587. $this->assertFalse(isset($Validator['other']));
  1588. }
  1589. /**
  1590. * Tests it is possible to set validation rules for a field using an array inteface
  1591. *
  1592. * @return void
  1593. */
  1594. public function testArrayAccessSet() {
  1595. $TestModel = new Article();
  1596. $Validator = $TestModel->validator();
  1597. $set = array(
  1598. 'numeric' => array('rule' => 'numeric', 'allowEmpty' => false),
  1599. 'range' => array('rule' => array('between', 1, 5), 'allowEmpty' => false),
  1600. );
  1601. $Validator['other'] = $set;
  1602. $rules = $Validator['other'];
  1603. $this->assertEquals('other', $rules->field);
  1604. $validators = $rules->getRules();
  1605. $this->assertCount(2, $validators);
  1606. $this->assertEquals('numeric', $validators['numeric']->rule);
  1607. $this->assertEquals(array('between', 1, 5), $validators['range']->rule);
  1608. $Validator['new'] = new CakeValidationSet('new', $set, array());
  1609. $rules = $Validator['new'];
  1610. $this->assertEquals('new', $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. }
  1616. /**
  1617. * Tests it is possible to unset validation rules
  1618. *
  1619. * @return void
  1620. */
  1621. public function testArrayAccessUset() {
  1622. $TestModel = new Article();
  1623. $Validator = $TestModel->validator();
  1624. $this->assertTrue(isset($Validator['title']));
  1625. unset($Validator['title']);
  1626. $this->assertFalse(isset($Validator['title']));
  1627. }
  1628. /**
  1629. * Tests it is possible to iterate a validation object
  1630. *
  1631. * @return void
  1632. */
  1633. public function testIterator() {
  1634. $TestModel = new Article();
  1635. $Validator = $TestModel->validator();
  1636. $i = 0;
  1637. foreach ($Validator as $field => $rules) {
  1638. if ($i === 0) {
  1639. $this->assertEquals('user_id', $field);
  1640. }
  1641. if ($i === 1) {
  1642. $this->assertEquals('title', $field);
  1643. }
  1644. if ($i === 2) {
  1645. $this->assertEquals('body', $field);
  1646. }
  1647. $this->assertInstanceOf('CakeValidationSet', $rules);
  1648. $i++;
  1649. }
  1650. $this->assertEquals(3, $i);
  1651. }
  1652. /**
  1653. * Tests countable interface in ModelValidator
  1654. *
  1655. * @return void
  1656. */
  1657. public function testCount() {
  1658. $TestModel = new Article();
  1659. $Validator = $TestModel->validator();
  1660. $this->assertCount(3, $Validator);
  1661. $set = array(
  1662. 'numeric' => array('rule' => 'numeric', 'allowEmpty' => false),
  1663. 'range' => array('rule' => array('between', 1, 5), 'allowEmpty' => false),
  1664. );
  1665. $Validator['other'] = $set;
  1666. $this->assertCount(4, $Validator);
  1667. unset($Validator['title']);
  1668. $this->assertCount(3, $Validator);
  1669. unset($Validator['body']);
  1670. $this->assertCount(2, $Validator);
  1671. }
  1672. /**
  1673. * Tests it is possible to add validation rules
  1674. *
  1675. * @return void
  1676. */
  1677. public function testAddRule() {
  1678. $TestModel = new Article();
  1679. $Validator = $TestModel->validator();
  1680. $Validator->add('other', 'numeric', array('rule' => 'numeric', 'allowEmpty' => false));
  1681. $Validator->add('other', 'range', array('rule' => array('between', 1, 5), 'allowEmpty' => false));
  1682. $rules = $Validator['other'];
  1683. $this->assertEquals('other', $rules->field);
  1684. $validators = $rules->getRules();
  1685. $this->assertCount(2, $validators);
  1686. $this->assertEquals('numeric', $validators['numeric']->rule);
  1687. $this->assertEquals(array('between', 1, 5), $validators['range']->rule);
  1688. }
  1689. /**
  1690. * Tests it is possible to remove validation rules
  1691. *
  1692. * @return void
  1693. */
  1694. public function testRemoveRule() {
  1695. $TestModel = new Article();
  1696. $Validator = $TestModel->validator();
  1697. $this->assertTrue(isset($Validator['title']));
  1698. $Validator->remove('title');
  1699. $this->assertFalse(isset($Validator['title']));
  1700. $Validator->add('other', 'numeric', array('rule' => 'numeric', 'allowEmpty' => false));
  1701. $Validator->add('other', 'range', array('rule' => array('between', 1, 5), 'allowEmpty' => false));
  1702. $this->assertTrue(isset($Validator['other']));
  1703. $Validator->remove('other', 'numeric');
  1704. $this->assertTrue(isset($Validator['other']));
  1705. $this->assertFalse(isset($Validator['other']['numeric']));
  1706. $this->assertTrue(isset($Validator['other']['range']));
  1707. }
  1708. /**
  1709. * Tests validation callbacks are triggered
  1710. *
  1711. * @return void
  1712. */
  1713. public function testValidateCallbacks() {
  1714. $TestModel = $this->getMock('Article', array('beforeValidate', 'afterValidate'));
  1715. $TestModel->expects($this->once())->method('beforeValidate');
  1716. $TestModel->expects($this->once())->method('afterValidate');
  1717. $TestModel->set(array('title' => '', 'body' => 'body'));
  1718. $TestModel->validates();
  1719. }
  1720. /**
  1721. * Tests that altering data in a beforeValidate callback will lead to saving those
  1722. * values in database
  1723. *
  1724. * @return void
  1725. */
  1726. public function testValidateFirstWithBeforeValidate() {
  1727. $this->loadFixtures('Article', 'User');
  1728. $model = new CustomArticle();
  1729. $model->validate = array(
  1730. 'title' => array(
  1731. 'notempty' => array(
  1732. 'rule' => 'notEmpty',
  1733. 'required' => true,
  1734. 'allowEmpty' => false
  1735. )
  1736. )
  1737. );
  1738. $data = array(
  1739. 'CustomArticle' => array(
  1740. 'body' => 'foo0'
  1741. )
  1742. );
  1743. $result = $model->saveAll($data, array('validate' => 'first'));
  1744. $this->assertTrue($result);
  1745. $this->assertFalse($model->findMethods['unPublished'], 'beforeValidate was run twice');
  1746. $model->findMethods['unPublished'] = true;
  1747. $data = array(
  1748. 'CustomArticle' => array(
  1749. 'body' => 'foo1'
  1750. )
  1751. );
  1752. $result = $model->saveAll($data, array('validate' => 'first', 'deep' => true));
  1753. $this->assertTrue($result);
  1754. $title = $model->field('title', array('body' => 'foo1'));
  1755. $this->assertEquals('foo', $title);
  1756. $this->assertFalse($model->findMethods['unPublished'], 'beforeValidate was run twice');
  1757. $data = array(
  1758. array('body' => 'foo2'),
  1759. array('body' => 'foo3'),
  1760. array('body' => 'foo4')
  1761. );
  1762. $result = $model->saveAll($data, array('validate' => 'first', 'deep' => true));
  1763. $this->assertTrue($result);
  1764. $this->assertEquals('foo', $model->field('title', array('body' => 'foo2')));
  1765. $this->assertEquals('foo', $model->field('title', array('body' => 'foo3')));
  1766. $this->assertEquals('foo', $model->field('title', array('body' => 'foo4')));
  1767. }
  1768. /**
  1769. * Tests that altering data in a beforeValidate callback will lead to saving those
  1770. * values in database
  1771. *
  1772. * @return void
  1773. */
  1774. public function testValidateFirstAssociatedWithBeforeValidate() {
  1775. $this->loadFixtures('Article', 'User');
  1776. $model = new CustomArticle();
  1777. $model->validate = array(
  1778. 'title' => array(
  1779. 'notempty' => array(
  1780. 'rule' => 'notEmpty',
  1781. 'required' => true
  1782. )
  1783. )
  1784. );
  1785. $articles = array(
  1786. array('body' => 'foo1'),
  1787. array('body' => 'foo2'),
  1788. array('body' => 'foo3')
  1789. );
  1790. $user = new User();
  1791. $user->bindModel(array('hasMany' => array('CustomArticle')));
  1792. $data = array(
  1793. 'User' => array('user' => 'foo', 'password' => 'bar'),
  1794. 'CustomArticle' => $articles
  1795. );
  1796. $result = $user->saveAll($data, array('validate' => 'first'));
  1797. $this->assertTrue($result);
  1798. $this->assertEquals('foo', $model->field('title', array('body' => 'foo1')));
  1799. $this->assertEquals('foo', $model->field('title', array('body' => 'foo2')));
  1800. $this->assertEquals('foo', $model->field('title', array('body' => 'foo3')));
  1801. }
  1802. /**
  1803. * testValidateFirstWithDefaults method
  1804. *
  1805. * return @void
  1806. */
  1807. public function testFirstWithDefaults() {
  1808. $this->loadFixtures('Article', 'Tag', 'Comment', 'User', 'ArticlesTag');
  1809. $TestModel = new Article();
  1810. $result = $TestModel->find('first', array(
  1811. 'conditions' => array('Article.id' => 1)
  1812. ));
  1813. $expected = array(
  1814. 'Article' => array(
  1815. 'id' => 1,
  1816. 'user_id' => 1,
  1817. 'title' => 'First Article',
  1818. 'body' => 'First Article Body',
  1819. 'published' => 'Y',
  1820. 'created' => '2007-03-18 10:39:23'
  1821. ),
  1822. );
  1823. unset($result['Article']['updated']);
  1824. $this->assertEquals($expected['Article'], $result['Article']);
  1825. $data = array(
  1826. 'Article' => array(
  1827. 'id' => 1,
  1828. 'title' => 'First Article (modified)'
  1829. ),
  1830. 'Comment' => array(
  1831. array('comment' => 'Article comment', 'user_id' => 1)
  1832. )
  1833. );
  1834. $result = $TestModel->saveAll($data, array('validate' => 'first'));
  1835. $this->assertTrue($result);
  1836. $result = $TestModel->find('first', array(
  1837. 'conditions' => array('Article.id' => 1)
  1838. ));
  1839. $expected['Article']['title'] = 'First Article (modified)';
  1840. unset($result['Article']['updated']);
  1841. $this->assertEquals($expected['Article'], $result['Article']);
  1842. }
  1843. public function testAddMultipleRules() {
  1844. $TestModel = new Article();
  1845. $Validator = $TestModel->validator();
  1846. $set = array(
  1847. 'numeric' => array('rule' => 'numeric', 'allowEmpty' => false),
  1848. 'range' => array('rule' => array('between', 1, 5), 'allowEmpty' => false),
  1849. );
  1850. $Validator->add('other', $set);
  1851. $rules = $Validator['other'];
  1852. $this->assertEquals('other', $rules->field);
  1853. $validators = $rules->getRules();
  1854. $this->assertCount(2, $validators);
  1855. $this->assertEquals('numeric', $validators['numeric']->rule);
  1856. $this->assertEquals(array('between', 1, 5), $validators['range']->rule);
  1857. $set = new CakeValidationSet('other', array(
  1858. 'a' => array('rule' => 'numeric', 'allowEmpty' => false),
  1859. 'b' => array('rule' => array('between', 1, 5), 'allowEmpty' => false),
  1860. ));
  1861. $Validator->add('other', $set);
  1862. $this->assertSame($set, $Validator->getField('other'));
  1863. }
  1864. /**
  1865. * Test that rules are parsed correctly when calling getField()
  1866. *
  1867. * @return void
  1868. */
  1869. public function testValidator() {
  1870. $TestModel = new Article();
  1871. $Validator = $TestModel->validator();
  1872. $result = $Validator->getField();
  1873. $expected = array('user_id', 'title', 'body');
  1874. $this->assertEquals($expected, array_keys($result));
  1875. $this->assertTrue($result['user_id'] instanceof CakeValidationSet);
  1876. $result = $TestModel->validator()->getField('title');
  1877. $this->assertTrue($result instanceof CakeValidationSet);
  1878. }
  1879. /**
  1880. * Tests that altering data in a beforeValidate callback will lead to saving those
  1881. * values in database, this time with belongsTo associations
  1882. *
  1883. * @return void
  1884. */
  1885. public function testValidateFirstAssociatedWithBeforeValidate2() {
  1886. $this->loadFixtures('Article', 'User');
  1887. $model = new CustomArticle();
  1888. $model->validate = array(
  1889. 'title' => array(
  1890. 'notempty' => array(
  1891. 'rule' => 'notEmpty',
  1892. 'required' => true
  1893. )
  1894. )
  1895. );
  1896. $data = array(
  1897. 'User' => array('user' => 'foo', 'password' => 'bar'),
  1898. 'CustomArticle' => array(
  1899. 'body' => 'a test'
  1900. )
  1901. );
  1902. $result = $model->saveAll($data, array('validate' => 'first'));
  1903. $this->assertTrue($result);
  1904. $this->assertEquals('foo', $model->field('title', array('body' => 'a test')));
  1905. }
  1906. /**
  1907. * Testing you can dynamically add rules to a field, added this to dispel doubts
  1908. * after a presentation made to show off this new feature
  1909. *
  1910. * @return void
  1911. **/
  1912. public function testDynamicValidationRuleBuilding() {
  1913. $model = new Article;
  1914. $validator = $model->validator();
  1915. $validator->add('body', 'isSpecial', array('rule' => 'special'));
  1916. $rules = $validator['body']->getRules();
  1917. $this->assertCount(2, $rules);
  1918. $this->assertEquals('special', $rules['isSpecial']->rule);
  1919. $validator['body']->setRule('isAwesome', array('rule' => 'awesome'));
  1920. $rules = $validator['body']->getRules();
  1921. $this->assertCount(3, $rules);
  1922. $this->assertEquals('awesome', $rules['isAwesome']->rule);
  1923. }
  1924. /**
  1925. * Test to ensure custom validation methods work with CakeValidationSet
  1926. *
  1927. * @return void
  1928. */
  1929. public function testCustomMethodsWithCakeValidationSet() {
  1930. $TestModel = new TestValidate();
  1931. $Validator = $TestModel->validator();
  1932. $Validator->add('title', 'validateTitle', array(
  1933. 'rule' => 'validateTitle',
  1934. 'message' => 'That aint right',
  1935. ));
  1936. $data = array('title' => 'notatitle');
  1937. $result = $Validator->getField('title')->validate($data);
  1938. $expected = array(0 => 'That aint right');
  1939. $this->assertEquals($expected, $result);
  1940. $data = array('title' => 'title-is-good');
  1941. $result = $Validator->getField('title')->validate($data);
  1942. $expected = array();
  1943. $this->assertEquals($expected, $result);
  1944. }
  1945. }