PageRenderTime 69ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 2ms

/lib/Cake/Test/Case/View/Helper/FormHelperTest.php

https://bitbucket.org/Aapje/quoted-for-the-win
PHP | 8151 lines | 6353 code | 645 blank | 1153 comment | 1 complexity | 13a44c5be121a2426464f6e0d7cbf7d6 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * FormHelperTest 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.
  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.
  14. * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
  15. * @package Cake.Test.Case.View.Helper
  16. * @since CakePHP(tm) v 1.2.0.4206
  17. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  18. */
  19. App::uses('ClassRegistry', 'Utility');
  20. App::uses('Controller', 'Controller');
  21. App::uses('View', 'View');
  22. App::uses('Model', 'Model');
  23. App::uses('Security', 'Utility');
  24. App::uses('CakeRequest', 'Network');
  25. App::uses('HtmlHelper', 'View/Helper');
  26. App::uses('FormHelper', 'View/Helper');
  27. App::uses('Router', 'Routing');
  28. /**
  29. * ContactTestController class
  30. *
  31. * @package cake
  32. * @package Cake.Test.Case.View.Helper
  33. */
  34. class ContactTestController extends Controller {
  35. /**
  36. * name property
  37. *
  38. * @var string 'ContactTest'
  39. */
  40. public $name = 'ContactTest';
  41. /**
  42. * uses property
  43. *
  44. * @var mixed null
  45. */
  46. public $uses = null;
  47. }
  48. /**
  49. * Contact class
  50. *
  51. * @package cake
  52. * @package Cake.Test.Case.View.Helper
  53. */
  54. class Contact extends CakeTestModel {
  55. /**
  56. * primaryKey property
  57. *
  58. * @var string 'id'
  59. */
  60. public $primaryKey = 'id';
  61. /**
  62. * useTable property
  63. *
  64. * @var bool false
  65. */
  66. public $useTable = false;
  67. /**
  68. * name property
  69. *
  70. * @var string 'Contact'
  71. */
  72. public $name = 'Contact';
  73. /**
  74. * Default schema
  75. *
  76. * @var array
  77. */
  78. protected $_schema = array(
  79. 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
  80. 'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
  81. 'email' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
  82. 'phone' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
  83. 'password' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
  84. 'published' => array('type' => 'date', 'null' => true, 'default' => null, 'length' => null),
  85. 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
  86. 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null),
  87. 'age' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => null)
  88. );
  89. /**
  90. * validate property
  91. *
  92. * @var array
  93. */
  94. public $validate = array(
  95. 'non_existing' => array(),
  96. 'idontexist' => array(),
  97. 'imrequired' => array('rule' => array('between', 5, 30), 'allowEmpty' => false),
  98. 'imrequiredonupdate' => array('notEmpty' => array('rule' => 'alphaNumeric', 'on' => 'update')),
  99. 'imrequiredoncreate' => array('required' => array('rule' => 'alphaNumeric', 'on' => 'create')),
  100. 'imrequiredonboth' => array(
  101. 'required' => array('rule' => 'alphaNumeric'),
  102. ),
  103. 'string_required' => 'notEmpty',
  104. 'imalsorequired' => array('rule' => 'alphaNumeric', 'allowEmpty' => false),
  105. 'imrequiredtoo' => array('rule' => 'notEmpty'),
  106. 'required_one' => array('required' => array('rule' => array('notEmpty'))),
  107. 'imnotrequired' => array('required' => false, 'rule' => 'alphaNumeric', 'allowEmpty' => true),
  108. 'imalsonotrequired' => array(
  109. 'alpha' => array('rule' => 'alphaNumeric', 'allowEmpty' => true),
  110. 'between' => array('rule' => array('between', 5, 30), 'allowEmpty' => true),
  111. ),
  112. 'imnotrequiredeither' => array('required' => true, 'rule' => array('between', 5, 30), 'allowEmpty' => true),
  113. 'iamrequiredalways' => array(
  114. 'email' => array('rule' => 'email'),
  115. 'rule_on_create' => array('rule' => array('maxLength', 50), 'on' => 'create'),
  116. 'rule_on_update' => array('rule' => array('between', 1, 50), 'on' => 'update'),
  117. ),
  118. );
  119. /**
  120. * schema method
  121. *
  122. * @return void
  123. */
  124. public function setSchema($schema) {
  125. $this->_schema = $schema;
  126. }
  127. /**
  128. * hasAndBelongsToMany property
  129. *
  130. * @var array
  131. */
  132. public $hasAndBelongsToMany = array('ContactTag' => array('with' => 'ContactTagsContact'));
  133. /**
  134. * hasAndBelongsToMany property
  135. *
  136. * @var array
  137. */
  138. public $belongsTo = array('User' => array('className' => 'UserForm'));
  139. }
  140. /**
  141. * ContactTagsContact class
  142. *
  143. * @package cake
  144. * @package Cake.Test.Case.View.Helper
  145. */
  146. class ContactTagsContact extends CakeTestModel {
  147. /**
  148. * useTable property
  149. *
  150. * @var bool false
  151. */
  152. public $useTable = false;
  153. /**
  154. * name property
  155. *
  156. * @var string 'Contact'
  157. */
  158. public $name = 'ContactTagsContact';
  159. /**
  160. * Default schema
  161. *
  162. * @var array
  163. */
  164. protected $_schema = array(
  165. 'contact_id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
  166. 'contact_tag_id' => array(
  167. 'type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'
  168. )
  169. );
  170. /**
  171. * schema method
  172. *
  173. * @return void
  174. */
  175. public function setSchema($schema) {
  176. $this->_schema = $schema;
  177. }
  178. }
  179. /**
  180. * ContactNonStandardPk class
  181. *
  182. * @package cake
  183. * @package Cake.Test.Case.View.Helper
  184. */
  185. class ContactNonStandardPk extends Contact {
  186. /**
  187. * primaryKey property
  188. *
  189. * @var string 'pk'
  190. */
  191. public $primaryKey = 'pk';
  192. /**
  193. * name property
  194. *
  195. * @var string 'ContactNonStandardPk'
  196. */
  197. public $name = 'ContactNonStandardPk';
  198. /**
  199. * schema method
  200. *
  201. * @return void
  202. */
  203. public function schema($field = false) {
  204. $this->_schema = parent::schema();
  205. $this->_schema['pk'] = $this->_schema['id'];
  206. unset($this->_schema['id']);
  207. return $this->_schema;
  208. }
  209. }
  210. /**
  211. * ContactTag class
  212. *
  213. * @package cake
  214. * @package Cake.Test.Case.View.Helper
  215. */
  216. class ContactTag extends Model {
  217. /**
  218. * useTable property
  219. *
  220. * @var bool false
  221. */
  222. public $useTable = false;
  223. /**
  224. * schema definition
  225. *
  226. * @var array
  227. */
  228. protected $_schema = array(
  229. 'id' => array('type' => 'integer', 'null' => false, 'default' => '', 'length' => '8'),
  230. 'name' => array('type' => 'string', 'null' => false, 'default' => '', 'length' => '255'),
  231. 'created' => array('type' => 'date', 'null' => true, 'default' => '', 'length' => ''),
  232. 'modified' => array('type' => 'datetime', 'null' => true, 'default' => '', 'length' => null)
  233. );
  234. }
  235. /**
  236. * UserForm class
  237. *
  238. * @package cake
  239. * @package Cake.Test.Case.View.Helper
  240. */
  241. class UserForm extends CakeTestModel {
  242. /**
  243. * useTable property
  244. *
  245. * @var bool false
  246. */
  247. public $useTable = false;
  248. /**
  249. * primaryKey property
  250. *
  251. * @var string 'id'
  252. */
  253. public $primaryKey = 'id';
  254. /**
  255. * name property
  256. *
  257. * @var string 'UserForm'
  258. */
  259. public $name = 'UserForm';
  260. /**
  261. * hasMany property
  262. *
  263. * @var array
  264. */
  265. public $hasMany = array(
  266. 'OpenidUrl' => array('className' => 'OpenidUrl', 'foreignKey' => 'user_form_id'
  267. ));
  268. /**
  269. * schema definition
  270. *
  271. * @var array
  272. */
  273. protected $_schema = array(
  274. 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
  275. 'published' => array('type' => 'date', 'null' => true, 'default' => null, 'length' => null),
  276. 'other' => array('type' => 'text', 'null' => true, 'default' => null, 'length' => null),
  277. 'stuff' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 10),
  278. 'something' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 255),
  279. 'active' => array('type' => 'boolean', 'null' => false, 'default' => false),
  280. 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
  281. 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
  282. );
  283. }
  284. /**
  285. * OpenidUrl class
  286. *
  287. * @package cake
  288. * @package Cake.Test.Case.View.Helper
  289. */
  290. class OpenidUrl extends CakeTestModel {
  291. /**
  292. * useTable property
  293. *
  294. * @var bool false
  295. */
  296. public $useTable = false;
  297. /**
  298. * primaryKey property
  299. *
  300. * @var string 'id'
  301. */
  302. public $primaryKey = 'id';
  303. /**
  304. * name property
  305. *
  306. * @var string 'OpenidUrl'
  307. */
  308. public $name = 'OpenidUrl';
  309. /**
  310. * belongsTo property
  311. *
  312. * @var array
  313. */
  314. public $belongsTo = array('UserForm' => array(
  315. 'className' => 'UserForm', 'foreignKey' => 'user_form_id'
  316. ));
  317. /**
  318. * validate property
  319. *
  320. * @var array
  321. */
  322. public $validate = array('openid_not_registered' => array());
  323. /**
  324. * schema method
  325. *
  326. * @var array
  327. */
  328. protected $_schema = array(
  329. 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
  330. 'user_form_id' => array(
  331. 'type' => 'user_form_id', 'null' => '', 'default' => '', 'length' => '8'
  332. ),
  333. 'url' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
  334. );
  335. /**
  336. * beforeValidate method
  337. *
  338. * @return void
  339. */
  340. public function beforeValidate($options = array()) {
  341. $this->invalidate('openid_not_registered');
  342. return true;
  343. }
  344. }
  345. /**
  346. * ValidateUser class
  347. *
  348. * @package cake
  349. * @package Cake.Test.Case.View.Helper
  350. */
  351. class ValidateUser extends CakeTestModel {
  352. /**
  353. * primaryKey property
  354. *
  355. * @var string 'id'
  356. */
  357. public $primaryKey = 'id';
  358. /**
  359. * useTable property
  360. *
  361. * @var bool false
  362. */
  363. public $useTable = false;
  364. /**
  365. * name property
  366. *
  367. * @var string 'ValidateUser'
  368. */
  369. public $name = 'ValidateUser';
  370. /**
  371. * hasOne property
  372. *
  373. * @var array
  374. */
  375. public $hasOne = array('ValidateProfile' => array(
  376. 'className' => 'ValidateProfile', 'foreignKey' => 'user_id'
  377. ));
  378. /**
  379. * schema method
  380. *
  381. * @var array
  382. */
  383. protected $_schema = array(
  384. 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
  385. 'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
  386. 'email' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
  387. 'balance' => array('type' => 'float', 'null' => false, 'length' => '5,2'),
  388. 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
  389. 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
  390. );
  391. /**
  392. * beforeValidate method
  393. *
  394. * @return void
  395. */
  396. public function beforeValidate($options = array()) {
  397. $this->invalidate('email');
  398. return false;
  399. }
  400. }
  401. /**
  402. * ValidateProfile class
  403. *
  404. * @package cake
  405. * @package Cake.Test.Case.View.Helper
  406. */
  407. class ValidateProfile extends CakeTestModel {
  408. /**
  409. * primaryKey property
  410. *
  411. * @var string 'id'
  412. */
  413. public $primaryKey = 'id';
  414. /**
  415. * useTable property
  416. *
  417. * @var bool false
  418. */
  419. public $useTable = false;
  420. /**
  421. * schema property
  422. *
  423. * @var array
  424. */
  425. protected $_schema = array(
  426. 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
  427. 'user_id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
  428. 'full_name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
  429. 'city' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
  430. 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
  431. 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
  432. );
  433. /**
  434. * name property
  435. *
  436. * @var string 'ValidateProfile'
  437. */
  438. public $name = 'ValidateProfile';
  439. /**
  440. * hasOne property
  441. *
  442. * @var array
  443. */
  444. public $hasOne = array('ValidateItem' => array(
  445. 'className' => 'ValidateItem', 'foreignKey' => 'profile_id'
  446. ));
  447. /**
  448. * belongsTo property
  449. *
  450. * @var array
  451. */
  452. public $belongsTo = array('ValidateUser' => array(
  453. 'className' => 'ValidateUser', 'foreignKey' => 'user_id'
  454. ));
  455. /**
  456. * beforeValidate method
  457. *
  458. * @return void
  459. */
  460. public function beforeValidate($options = array()) {
  461. $this->invalidate('full_name');
  462. $this->invalidate('city');
  463. return false;
  464. }
  465. }
  466. /**
  467. * ValidateItem class
  468. *
  469. * @package cake
  470. * @package Cake.Test.Case.View.Helper
  471. */
  472. class ValidateItem extends CakeTestModel {
  473. /**
  474. * primaryKey property
  475. *
  476. * @var string 'id'
  477. */
  478. public $primaryKey = 'id';
  479. /**
  480. * useTable property
  481. *
  482. * @var bool false
  483. */
  484. public $useTable = false;
  485. /**
  486. * name property
  487. *
  488. * @var string 'ValidateItem'
  489. */
  490. public $name = 'ValidateItem';
  491. /**
  492. * schema property
  493. *
  494. * @var array
  495. */
  496. protected $_schema = array(
  497. 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
  498. 'profile_id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
  499. 'name' => array('type' => 'text', 'null' => '', 'default' => '', 'length' => '255'),
  500. 'description' => array(
  501. 'type' => 'string', 'null' => '', 'default' => '', 'length' => '255'
  502. ),
  503. 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
  504. 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
  505. );
  506. /**
  507. * belongsTo property
  508. *
  509. * @var array
  510. */
  511. public $belongsTo = array('ValidateProfile' => array('foreignKey' => 'profile_id'));
  512. /**
  513. * beforeValidate method
  514. *
  515. * @return void
  516. */
  517. public function beforeValidate($options = array()) {
  518. $this->invalidate('description');
  519. return false;
  520. }
  521. }
  522. /**
  523. * TestMail class
  524. *
  525. * @package cake
  526. * @package Cake.Test.Case.View.Helper
  527. */
  528. class TestMail extends CakeTestModel {
  529. /**
  530. * primaryKey property
  531. *
  532. * @var string 'id'
  533. */
  534. public $primaryKey = 'id';
  535. /**
  536. * useTable property
  537. *
  538. * @var bool false
  539. */
  540. public $useTable = false;
  541. /**
  542. * name property
  543. *
  544. * @var string 'TestMail'
  545. */
  546. public $name = 'TestMail';
  547. }
  548. /**
  549. * FormHelperTest class
  550. *
  551. * @package cake
  552. * @subpackage Cake.Test.Case.View.Helper
  553. * @property FormHelper $Form
  554. */
  555. class FormHelperTest extends CakeTestCase {
  556. /**
  557. * Fixtures to be used
  558. *
  559. * @var array
  560. */
  561. public $fixtures = array('core.post');
  562. /**
  563. * Do not load the fixtures by default
  564. *
  565. * @var boolean
  566. */
  567. public $autoFixtures = false;
  568. /**
  569. * setUp method
  570. *
  571. * @return void
  572. */
  573. public function setUp() {
  574. parent::setUp();
  575. Configure::write('App.base', '');
  576. $this->Controller = new ContactTestController();
  577. $this->View = new View($this->Controller);
  578. $this->Form = new FormHelper($this->View);
  579. $this->Form->Html = new HtmlHelper($this->View);
  580. $this->Form->request = new CakeRequest('contacts/add', false);
  581. $this->Form->request->here = '/contacts/add';
  582. $this->Form->request['action'] = 'add';
  583. $this->Form->request->webroot = '';
  584. $this->Form->request->base = '';
  585. ClassRegistry::addObject('Contact', new Contact());
  586. ClassRegistry::addObject('ContactNonStandardPk', new ContactNonStandardPk());
  587. ClassRegistry::addObject('OpenidUrl', new OpenidUrl());
  588. ClassRegistry::addObject('User', new UserForm());
  589. ClassRegistry::addObject('ValidateItem', new ValidateItem());
  590. ClassRegistry::addObject('ValidateUser', new ValidateUser());
  591. ClassRegistry::addObject('ValidateProfile', new ValidateProfile());
  592. $this->oldSalt = Configure::read('Security.salt');
  593. $this->dateRegex = array(
  594. 'daysRegex' => 'preg:/(?:<option value="0?([\d]+)">\\1<\/option>[\r\n]*)*/',
  595. 'monthsRegex' => 'preg:/(?:<option value="[\d]+">[\w]+<\/option>[\r\n]*)*/',
  596. 'yearsRegex' => 'preg:/(?:<option value="([\d]+)">\\1<\/option>[\r\n]*)*/',
  597. 'hoursRegex' => 'preg:/(?:<option value="0?([\d]+)">\\1<\/option>[\r\n]*)*/',
  598. 'minutesRegex' => 'preg:/(?:<option value="([\d]+)">0?\\1<\/option>[\r\n]*)*/',
  599. 'meridianRegex' => 'preg:/(?:<option value="(am|pm)">\\1<\/option>[\r\n]*)*/',
  600. );
  601. Configure::write('Security.salt', 'foo!');
  602. }
  603. /**
  604. * tearDown method
  605. *
  606. * @return void
  607. */
  608. public function tearDown() {
  609. parent::tearDown();
  610. unset($this->Form->Html, $this->Form, $this->Controller, $this->View);
  611. Configure::write('Security.salt', $this->oldSalt);
  612. }
  613. /**
  614. * testFormCreateWithSecurity method
  615. *
  616. * Test form->create() with security key.
  617. *
  618. * @return void
  619. */
  620. public function testCreateWithSecurity() {
  621. $this->Form->request['_Token'] = array('key' => 'testKey');
  622. $encoding = strtolower(Configure::read('App.encoding'));
  623. $result = $this->Form->create('Contact', array('url' => '/contacts/add'));
  624. $expected = array(
  625. 'form' => array('method' => 'post', 'action' => '/contacts/add', 'accept-charset' => $encoding, 'id' => 'ContactAddForm'),
  626. 'div' => array('style' => 'display:none;'),
  627. array('input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST')),
  628. array('input' => array(
  629. 'type' => 'hidden', 'name' => 'data[_Token][key]', 'value' => 'testKey', 'id'
  630. )),
  631. '/div'
  632. );
  633. $this->assertTags($result, $expected);
  634. $result = $this->Form->create('Contact', array('url' => '/contacts/add', 'id' => 'MyForm'));
  635. $expected['form']['id'] = 'MyForm';
  636. $this->assertTags($result, $expected);
  637. }
  638. /**
  639. * test that create() clears the fields property so it starts fresh
  640. *
  641. * @return void
  642. */
  643. public function testCreateClearingFields() {
  644. $this->Form->fields = array('model_id');
  645. $this->Form->create('Contact');
  646. $this->assertEquals(array(), $this->Form->fields);
  647. }
  648. /**
  649. * Tests form hash generation with model-less data
  650. *
  651. * @return void
  652. */
  653. public function testValidateHashNoModel() {
  654. $this->Form->request['_Token'] = array('key' => 'foo');
  655. $result = $this->Form->secure(array('anything'));
  656. $this->assertRegExp('/540ac9c60d323c22bafe997b72c0790f39a8bdef/', $result);
  657. }
  658. /**
  659. * Tests that models with identical field names get resolved properly
  660. *
  661. * @return void
  662. */
  663. public function testDuplicateFieldNameResolution() {
  664. $result = $this->Form->create('ValidateUser');
  665. $this->assertEquals(array('ValidateUser'), $this->Form->entity());
  666. $result = $this->Form->input('ValidateItem.name');
  667. $this->assertEquals(array('ValidateItem', 'name'), $this->Form->entity());
  668. $result = $this->Form->input('ValidateUser.name');
  669. $this->assertEquals(array('ValidateUser', 'name'), $this->Form->entity());
  670. $this->assertRegExp('/name="data\[ValidateUser\]\[name\]"/', $result);
  671. $this->assertRegExp('/type="text"/', $result);
  672. $result = $this->Form->input('ValidateItem.name');
  673. $this->assertEquals(array('ValidateItem', 'name'), $this->Form->entity());
  674. $this->assertRegExp('/name="data\[ValidateItem\]\[name\]"/', $result);
  675. $this->assertRegExp('/<textarea/', $result);
  676. $result = $this->Form->input('name');
  677. $this->assertEquals(array('ValidateUser', 'name'), $this->Form->entity());
  678. $this->assertRegExp('/name="data\[ValidateUser\]\[name\]"/', $result);
  679. $this->assertRegExp('/type="text"/', $result);
  680. }
  681. /**
  682. * Tests that hidden fields generated for checkboxes don't get locked
  683. *
  684. * @return void
  685. */
  686. public function testNoCheckboxLocking() {
  687. $this->Form->request['_Token'] = array('key' => 'foo');
  688. $this->assertSame(array(), $this->Form->fields);
  689. $this->Form->checkbox('check', array('value' => '1'));
  690. $this->assertSame($this->Form->fields, array('check'));
  691. }
  692. /**
  693. * testFormSecurityFields method
  694. *
  695. * Test generation of secure form hash generation.
  696. *
  697. * @return void
  698. */
  699. public function testFormSecurityFields() {
  700. $key = 'testKey';
  701. $fields = array('Model.password', 'Model.username', 'Model.valid' => '0');
  702. $this->Form->request['_Token'] = array('key' => $key);
  703. $result = $this->Form->secure($fields);
  704. $expected = Security::hash(serialize($fields) . Configure::read('Security.salt'));
  705. $expected .= ':' . 'Model.valid';
  706. $expected = array(
  707. 'div' => array('style' => 'display:none;'),
  708. array('input' => array(
  709. 'type' => 'hidden', 'name' => 'data[_Token][fields]',
  710. 'value' => urlencode($expected), 'id' => 'preg:/TokenFields\d+/'
  711. )),
  712. array('input' => array(
  713. 'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
  714. 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/'
  715. )),
  716. '/div'
  717. );
  718. $this->assertTags($result, $expected);
  719. }
  720. /**
  721. * Tests correct generation of number fields for double and float fields
  722. *
  723. * @return void
  724. */
  725. public function testTextFieldGenerationForFloats() {
  726. $model = ClassRegistry::getObject('Contact');
  727. $model->setSchema(array('foo' => array(
  728. 'type' => 'float',
  729. 'null' => false,
  730. 'default' => null,
  731. 'length' => null
  732. )));
  733. $this->Form->create('Contact');
  734. $result = $this->Form->input('foo');
  735. $expected = array(
  736. 'div' => array('class' => 'input number'),
  737. 'label' => array('for' => 'ContactFoo'),
  738. 'Foo',
  739. '/label',
  740. array('input' => array(
  741. 'type' => 'number',
  742. 'name' => 'data[Contact][foo]',
  743. 'id' => 'ContactFoo',
  744. 'step' => 'any'
  745. )),
  746. '/div'
  747. );
  748. $this->assertTags($result, $expected);
  749. $result = $this->Form->input('foo', array('step' => 0.5));
  750. $expected = array(
  751. 'div' => array('class' => 'input number'),
  752. 'label' => array('for' => 'ContactFoo'),
  753. 'Foo',
  754. '/label',
  755. array('input' => array(
  756. 'type' => 'number',
  757. 'name' => 'data[Contact][foo]',
  758. 'id' => 'ContactFoo',
  759. 'step' => '0.5'
  760. )),
  761. '/div'
  762. );
  763. $this->assertTags($result, $expected);
  764. }
  765. /**
  766. * Tests correct generation of number fields for integer fields
  767. *
  768. * @access public
  769. * @return void
  770. */
  771. public function testTextFieldTypeNumberGenerationForIntegers() {
  772. $model = ClassRegistry::getObject('Contact');
  773. $model->setSchema(array('foo' => array(
  774. 'type' => 'integer',
  775. 'null' => false,
  776. 'default' => null,
  777. 'length' => null
  778. )));
  779. $this->Form->create('Contact');
  780. $result = $this->Form->input('foo');
  781. $expected = array(
  782. 'div' => array('class' => 'input number'),
  783. 'label' => array('for' => 'ContactFoo'),
  784. 'Foo',
  785. '/label',
  786. array('input' => array(
  787. 'type' => 'number', 'name' => 'data[Contact][foo]',
  788. 'id' => 'ContactFoo'
  789. )),
  790. '/div'
  791. );
  792. $this->assertTags($result, $expected);
  793. }
  794. /**
  795. * testFormSecurityMultipleFields method
  796. *
  797. * Test secure() with multiple row form. Ensure hash is correct.
  798. *
  799. * @return void
  800. */
  801. public function testFormSecurityMultipleFields() {
  802. $key = 'testKey';
  803. $fields = array(
  804. 'Model.0.password', 'Model.0.username', 'Model.0.hidden' => 'value',
  805. 'Model.0.valid' => '0', 'Model.1.password', 'Model.1.username',
  806. 'Model.1.hidden' => 'value', 'Model.1.valid' => '0'
  807. );
  808. $this->Form->request['_Token'] = array('key' => $key);
  809. $result = $this->Form->secure($fields);
  810. $hash = '51e3b55a6edd82020b3f29c9ae200e14bbeb7ee5%3AModel.0.hidden%7CModel.0.valid';
  811. $hash .= '%7CModel.1.hidden%7CModel.1.valid';
  812. $expected = array(
  813. 'div' => array('style' => 'display:none;'),
  814. array('input' => array(
  815. 'type' => 'hidden', 'name' => 'data[_Token][fields]',
  816. 'value' => $hash, 'id' => 'preg:/TokenFields\d+/'
  817. )),
  818. array('input' => array(
  819. 'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
  820. 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/'
  821. )),
  822. '/div'
  823. );
  824. $this->assertTags($result, $expected);
  825. }
  826. /**
  827. * testFormSecurityMultipleSubmitButtons
  828. *
  829. * test form submit generation and ensure that _Token is only created on end()
  830. *
  831. * @return void
  832. */
  833. public function testFormSecurityMultipleSubmitButtons() {
  834. $key = 'testKey';
  835. $this->Form->request['_Token'] = array('key' => $key);
  836. $this->Form->create('Addresses');
  837. $this->Form->input('Address.title');
  838. $this->Form->input('Address.first_name');
  839. $result = $this->Form->submit('Save', array('name' => 'save'));
  840. $expected = array(
  841. 'div' => array('class' => 'submit'),
  842. 'input' => array('type' => 'submit', 'name' => 'save', 'value' => 'Save'),
  843. '/div',
  844. );
  845. $this->assertTags($result, $expected);
  846. $result = $this->Form->submit('Cancel', array('name' => 'cancel'));
  847. $expected = array(
  848. 'div' => array('class' => 'submit'),
  849. 'input' => array('type' => 'submit', 'name' => 'cancel', 'value' => 'Cancel'),
  850. '/div',
  851. );
  852. $this->assertTags($result, $expected);
  853. $result = $this->Form->end(null);
  854. $expected = array(
  855. 'div' => array('style' => 'display:none;'),
  856. array('input' => array(
  857. 'type' => 'hidden', 'name' => 'data[_Token][fields]',
  858. 'value' => 'preg:/.+/', 'id' => 'preg:/TokenFields\d+/'
  859. )),
  860. array('input' => array(
  861. 'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
  862. 'value' => 'cancel%7Csave', 'id' => 'preg:/TokenUnlocked\d+/'
  863. )),
  864. '/div'
  865. );
  866. $this->assertTags($result, $expected);
  867. }
  868. /**
  869. * Test that buttons created with foo[bar] name attributes are unlocked correctly.
  870. *
  871. * @return void
  872. */
  873. public function testSecurityButtonNestedNamed() {
  874. $key = 'testKey';
  875. $this->Form->request['_Token'] = array('key' => $key);
  876. $this->Form->create('Addresses');
  877. $this->Form->button('Test', array('type' => 'submit', 'name' => 'Address[button]'));
  878. $result = $this->Form->unlockField();
  879. $this->assertEquals(array('Address.button'), $result);
  880. }
  881. /**
  882. * Test that submit inputs created with foo[bar] name attributes are unlocked correctly.
  883. *
  884. * @return void
  885. */
  886. public function testSecuritySubmitNestedNamed() {
  887. $key = 'testKey';
  888. $this->Form->request['_Token'] = array('key' => $key);
  889. $this->Form->create('Addresses');
  890. $this->Form->submit('Test', array('type' => 'submit', 'name' => 'Address[button]'));
  891. $result = $this->Form->unlockField();
  892. $this->assertEquals(array('Address.button'), $result);
  893. }
  894. /**
  895. * Test that the correct fields are unlocked for image submits with no names.
  896. *
  897. * @return void
  898. */
  899. public function testSecuritySubmitImageNoName() {
  900. $key = 'testKey';
  901. $this->Form->request['_Token'] = array('key' => $key);
  902. $this->Form->create('User');
  903. $result = $this->Form->submit('save.png');
  904. $expected = array(
  905. 'div' => array('class' => 'submit'),
  906. 'input' => array('type' => 'image', 'src' => 'img/save.png'),
  907. '/div'
  908. );
  909. $this->assertTags($result, $expected);
  910. $this->assertEquals(array('x', 'y'), $this->Form->unlockField());
  911. }
  912. /**
  913. * Test that the correct fields are unlocked for image submits with names.
  914. *
  915. * @return void
  916. */
  917. public function testSecuritySubmitImageName() {
  918. $key = 'testKey';
  919. $this->Form->request['_Token'] = array('key' => $key);
  920. $this->Form->create('User');
  921. $result = $this->Form->submit('save.png', array('name' => 'test'));
  922. $expected = array(
  923. 'div' => array('class' => 'submit'),
  924. 'input' => array('type' => 'image', 'name' => 'test', 'src' => 'img/save.png'),
  925. '/div'
  926. );
  927. $this->assertTags($result, $expected);
  928. $this->assertEquals(array('test', 'test_x', 'test_y'), $this->Form->unlockField());
  929. }
  930. /**
  931. * testFormSecurityMultipleInputFields method
  932. *
  933. * Test secure form creation with multiple row creation. Checks hidden, text, checkbox field types
  934. *
  935. * @return void
  936. */
  937. public function testFormSecurityMultipleInputFields() {
  938. $key = 'testKey';
  939. $this->Form->request['_Token'] = array('key' => $key);
  940. $this->Form->create('Addresses');
  941. $this->Form->hidden('Addresses.0.id', array('value' => '123456'));
  942. $this->Form->input('Addresses.0.title');
  943. $this->Form->input('Addresses.0.first_name');
  944. $this->Form->input('Addresses.0.last_name');
  945. $this->Form->input('Addresses.0.address');
  946. $this->Form->input('Addresses.0.city');
  947. $this->Form->input('Addresses.0.phone');
  948. $this->Form->input('Addresses.0.primary', array('type' => 'checkbox'));
  949. $this->Form->hidden('Addresses.1.id', array('value' => '654321'));
  950. $this->Form->input('Addresses.1.title');
  951. $this->Form->input('Addresses.1.first_name');
  952. $this->Form->input('Addresses.1.last_name');
  953. $this->Form->input('Addresses.1.address');
  954. $this->Form->input('Addresses.1.city');
  955. $this->Form->input('Addresses.1.phone');
  956. $this->Form->input('Addresses.1.primary', array('type' => 'checkbox'));
  957. $result = $this->Form->secure($this->Form->fields);
  958. $hash = 'c9118120e680a7201b543f562e5301006ccfcbe2%3AAddresses.0.id%7CAddresses.1.id';
  959. $expected = array(
  960. 'div' => array('style' => 'display:none;'),
  961. array('input' => array(
  962. 'type' => 'hidden', 'name' => 'data[_Token][fields]',
  963. 'value' => $hash, 'id' => 'preg:/TokenFields\d+/'
  964. )),
  965. array('input' => array(
  966. 'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
  967. 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/'
  968. )),
  969. '/div'
  970. );
  971. $this->assertTags($result, $expected);
  972. }
  973. /**
  974. * Test form security with Model.field.0 style inputs
  975. *
  976. * @return void
  977. */
  978. public function testFormSecurityArrayFields() {
  979. $key = 'testKey';
  980. $this->Form->request->params['_Token']['key'] = $key;
  981. $this->Form->create('Address');
  982. $this->Form->input('Address.primary.1');
  983. $this->assertEquals('Address.primary', $this->Form->fields[0]);
  984. $this->Form->input('Address.secondary.1.0');
  985. $this->assertEquals('Address.secondary', $this->Form->fields[1]);
  986. }
  987. /**
  988. * testFormSecurityMultipleInputDisabledFields method
  989. *
  990. * test secure form generation with multiple records and disabled fields.
  991. *
  992. * @return void
  993. */
  994. public function testFormSecurityMultipleInputDisabledFields() {
  995. $key = 'testKey';
  996. $this->Form->request->params['_Token'] = array(
  997. 'key' => $key,
  998. 'unlockedFields' => array('first_name', 'address')
  999. );
  1000. $this->Form->create();
  1001. $this->Form->hidden('Addresses.0.id', array('value' => '123456'));
  1002. $this->Form->input('Addresses.0.title');
  1003. $this->Form->input('Addresses.0.first_name');
  1004. $this->Form->input('Addresses.0.last_name');
  1005. $this->Form->input('Addresses.0.address');
  1006. $this->Form->input('Addresses.0.city');
  1007. $this->Form->input('Addresses.0.phone');
  1008. $this->Form->hidden('Addresses.1.id', array('value' => '654321'));
  1009. $this->Form->input('Addresses.1.title');
  1010. $this->Form->input('Addresses.1.first_name');
  1011. $this->Form->input('Addresses.1.last_name');
  1012. $this->Form->input('Addresses.1.address');
  1013. $this->Form->input('Addresses.1.city');
  1014. $this->Form->input('Addresses.1.phone');
  1015. $result = $this->Form->secure($this->Form->fields);
  1016. $hash = '629b6536dcece48aa41a117045628ce602ccbbb2%3AAddresses.0.id%7CAddresses.1.id';
  1017. $expected = array(
  1018. 'div' => array('style' => 'display:none;'),
  1019. array('input' => array(
  1020. 'type' => 'hidden', 'name' => 'data[_Token][fields]',
  1021. 'value' => $hash, 'id' => 'preg:/TokenFields\d+/'
  1022. )),
  1023. array('input' => array(
  1024. 'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
  1025. 'value' => 'address%7Cfirst_name', 'id' => 'preg:/TokenUnlocked\d+/'
  1026. )),
  1027. '/div'
  1028. );
  1029. $this->assertTags($result, $expected);
  1030. }
  1031. /**
  1032. * testFormSecurityInputDisabledFields method
  1033. *
  1034. * Test single record form with disabled fields.
  1035. *
  1036. * @return void
  1037. */
  1038. public function testFormSecurityInputUnlockedFields() {
  1039. $key = 'testKey';
  1040. $this->Form->request['_Token'] = array(
  1041. 'key' => $key,
  1042. 'unlockedFields' => array('first_name', 'address')
  1043. );
  1044. $this->Form->create();
  1045. $this->assertEquals($this->Form->request['_Token']['unlockedFields'], $this->Form->unlockField());
  1046. $this->Form->hidden('Addresses.id', array('value' => '123456'));
  1047. $this->Form->input('Addresses.title');
  1048. $this->Form->input('Addresses.first_name');
  1049. $this->Form->input('Addresses.last_name');
  1050. $this->Form->input('Addresses.address');
  1051. $this->Form->input('Addresses.city');
  1052. $this->Form->input('Addresses.phone');
  1053. $result = $this->Form->fields;
  1054. $expected = array(
  1055. 'Addresses.id' => '123456', 'Addresses.title', 'Addresses.last_name',
  1056. 'Addresses.city', 'Addresses.phone'
  1057. );
  1058. $this->assertEquals($expected, $result);
  1059. $result = $this->Form->secure($expected);
  1060. $hash = '2981c38990f3f6ba935e6561dc77277966fabd6d%3AAddresses.id';
  1061. $expected = array(
  1062. 'div' => array('style' => 'display:none;'),
  1063. array('input' => array(
  1064. 'type' => 'hidden', 'name' => 'data[_Token][fields]',
  1065. 'value' => $hash, 'id' => 'preg:/TokenFields\d+/'
  1066. )),
  1067. array('input' => array(
  1068. 'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
  1069. 'value' => 'address%7Cfirst_name', 'id' => 'preg:/TokenUnlocked\d+/'
  1070. )),
  1071. '/div'
  1072. );
  1073. $this->assertTags($result, $expected);
  1074. }
  1075. /**
  1076. * test securing inputs with custom name attributes.
  1077. *
  1078. * @return void
  1079. */
  1080. public function testFormSecureWithCustomNameAttribute() {
  1081. $this->Form->request->params['_Token']['key'] = 'testKey';
  1082. $this->Form->text('UserForm.published', array('name' => 'data[User][custom]'));
  1083. $this->assertEquals('User.custom', $this->Form->fields[0]);
  1084. $this->Form->text('UserForm.published', array('name' => 'data[User][custom][another][value]'));
  1085. $this->assertEquals('User.custom.another.value', $this->Form->fields[1]);
  1086. }
  1087. /**
  1088. * testFormSecuredInput method
  1089. *
  1090. * Test generation of entire secure form, assertions made on input() output.
  1091. *
  1092. * @return void
  1093. */
  1094. public function testFormSecuredInput() {
  1095. $this->Form->request['_Token'] = array('key' => 'testKey');
  1096. $result = $this->Form->create('Contact', array('url' => '/contacts/add'));
  1097. $encoding = strtolower(Configure::read('App.encoding'));
  1098. $expected = array(
  1099. 'form' => array('method' => 'post', 'action' => '/contacts/add', 'accept-charset' => $encoding, 'id' => 'ContactAddForm'),
  1100. 'div' => array('style' => 'display:none;'),
  1101. array('input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST')),
  1102. array('input' => array(
  1103. 'type' => 'hidden', 'name' => 'data[_Token][key]',
  1104. 'value' => 'testKey', 'id' => 'preg:/Token\d+/'
  1105. )),
  1106. '/div'
  1107. );
  1108. $this->assertTags($result, $expected);
  1109. $result = $this->Form->input('UserForm.published', array('type' => 'text'));
  1110. $expected = array(
  1111. 'div' => array('class' => 'input text'),
  1112. 'label' => array('for' => 'UserFormPublished'),
  1113. 'Published',
  1114. '/label',
  1115. array('input' => array(
  1116. 'type' => 'text', 'name' => 'data[UserForm][published]',
  1117. 'id' => 'UserFormPublished'
  1118. )),
  1119. '/div'
  1120. );
  1121. $this->assertTags($result, $expected);
  1122. $result = $this->Form->input('UserForm.other', array('type' => 'text'));
  1123. $expected = array(
  1124. 'div' => array('class' => 'input text'),
  1125. 'label' => array('for' => 'UserFormOther'),
  1126. 'Other',
  1127. '/label',
  1128. array('input' => array(
  1129. 'type' => 'text', 'name' => 'data[UserForm][other]',
  1130. 'id' => 'UserFormOther'
  1131. )),
  1132. '/div'
  1133. );
  1134. $this->assertTags($result, $expected);
  1135. $result = $this->Form->hidden('UserForm.stuff');
  1136. $expected = array('input' => array(
  1137. 'type' => 'hidden', 'name' => 'data[UserForm][stuff]',
  1138. 'id' => 'UserFormStuff'
  1139. ));
  1140. $this->assertTags($result, $expected);
  1141. $result = $this->Form->hidden('UserForm.hidden', array('value' => '0'));
  1142. $expected = array('input' => array(
  1143. 'type' => 'hidden', 'name' => 'data[UserForm][hidden]',
  1144. 'value' => '0', 'id' => 'UserFormHidden'
  1145. ));
  1146. $this->assertTags($result, $expected);
  1147. $result = $this->Form->input('UserForm.something', array('type' => 'checkbox'));
  1148. $expected = array(
  1149. 'div' => array('class' => 'input checkbox'),
  1150. array('input' => array(
  1151. 'type' => 'hidden', 'name' => 'data[UserForm][something]',
  1152. 'value' => '0', 'id' => 'UserFormSomething_'
  1153. )),
  1154. array('input' => array(
  1155. 'type' => 'checkbox', 'name' => 'data[UserForm][something]',
  1156. 'value' => '1', 'id' => 'UserFormSomething'
  1157. )),
  1158. 'label' => array('for' => 'UserFormSomething'),
  1159. 'Something',
  1160. '/label',
  1161. '/div'
  1162. );
  1163. $this->assertTags($result, $expected);
  1164. $result = $this->Form->fields;
  1165. $expected = array(
  1166. 'UserForm.published', 'UserForm.other', 'UserForm.stuff' => '',
  1167. 'UserForm.hidden' => '0', 'UserForm.something'
  1168. );
  1169. $this->assertEquals($expected, $result);
  1170. $hash = 'bd7c4a654e5361f9a433a43f488ff9a1065d0aaf%3AUserForm.hidden%7CUserForm.stuff';
  1171. $result = $this->Form->secure($this->Form->fields);
  1172. $expected = array(
  1173. 'div' => array('style' => 'display:none;'),
  1174. array('input' => array(
  1175. 'type' => 'hidden', 'name' => 'data[_Token][fields]',
  1176. 'value' => $hash, 'id' => 'preg:/TokenFields\d+/'
  1177. )),
  1178. array('input' => array(
  1179. 'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
  1180. 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/'
  1181. )),
  1182. '/div'
  1183. );
  1184. $this->assertTags($result, $expected);
  1185. }
  1186. /**
  1187. * Tests that the correct keys are added to the field hash index
  1188. *
  1189. * @return void
  1190. */
  1191. public function testFormSecuredFileInput() {
  1192. $this->Form->request['_Token'] = array('key' => 'testKey');
  1193. $this->assertEquals(array(), $this->Form->fields);
  1194. $result = $this->Form->file('Attachment.file');
  1195. $expected = array(
  1196. 'Attachment.file.name', 'Attachment.file.type', 'Attachment.file.tmp_name',
  1197. 'Attachment.file.error', 'Attachment.file.size'
  1198. );
  1199. $this->assertEquals($expected, $this->Form->fields);
  1200. }
  1201. /**
  1202. * test that multiple selects keys are added to field hash
  1203. *
  1204. * @return void
  1205. */
  1206. public function testFormSecuredMultipleSelect() {
  1207. $this->Form->request['_Token'] = array('key' => 'testKey');
  1208. $this->assertEquals(array(), $this->Form->fields);
  1209. $options = array('1' => 'one', '2' => 'two');
  1210. $this->Form->select('Model.select', $options);
  1211. $expected = array('Model.select');
  1212. $this->assertEquals($expected, $this->Form->fields);
  1213. $this->Form->fields = array();
  1214. $this->Form->select('Model.select', $options, array('multiple' => true));
  1215. $this->assertEquals($expected, $this->Form->fields);
  1216. }
  1217. /**
  1218. * testFormSecuredRadio method
  1219. *
  1220. * @return void
  1221. */
  1222. public function testFormSecuredRadio() {
  1223. $this->Form->request['_Token'] = array('key' => 'testKey');
  1224. $this->assertEquals(array(), $this->Form->fields);
  1225. $options = array('1' => 'option1', '2' => 'option2');
  1226. $this->Form->radio('Test.test', $options);
  1227. $expected = array('Test.test');
  1228. $this->assertEquals($expected, $this->Form->fields);
  1229. }
  1230. /**
  1231. * test that forms with disabled inputs + secured forms leave off the inputs from the form
  1232. * hashing.
  1233. *
  1234. * @return void
  1235. */
  1236. public function testFormSecuredAndDisabled() {
  1237. $this->Form->request['_Token'] = array('key' => 'testKey');
  1238. $this->Form->checkbox('Model.checkbox', array('disabled' => true));
  1239. $this->Form->text('Model.text', array('disabled' => true));
  1240. $this->Form->password('Model.text', array('disabled' => true));
  1241. $this->Form->textarea('Model.textarea', array('disabled' => true));
  1242. $this->Form->select('Model.select', array(1, 2), array('disabled' => true));
  1243. $this->Form->radio('Model.radio', array(1, 2), array('disabled' => array(1, 2)));
  1244. $this->Form->year('Model.year', null, null, array('disabled' => true));
  1245. $this->Form->month('Model.month', array('disabled' => true));
  1246. $this->Form->day('Model.day', array('disabled' => true));
  1247. $this->Form->hour('Model.hour', false, array('disabled' => true));
  1248. $this->Form->minute('Model.minute', array('disabled' => true));
  1249. $this->Form->meridian('Model.meridian', array('disabled' => true));
  1250. $expected = array(
  1251. 'Model.radio' => ''
  1252. );
  1253. $this->assertEquals($expected, $this->Form->fields);
  1254. }
  1255. /**
  1256. * testDisableSecurityUsingForm method
  1257. *
  1258. * @return void
  1259. */
  1260. public function testDisableSecurityUsingForm() {
  1261. $this->Form->request['_Token'] = array(
  1262. 'key' => 'testKey',
  1263. 'disabledFields' => array()
  1264. );
  1265. $this->Form->create();
  1266. $this->Form->hidden('Addresses.id', array('value' => '123456'));
  1267. $this->Form->input('Addresses.title');
  1268. $this->Form->input('Addresses.first_name', array('secure' => false));
  1269. $this->Form->input('Addresses.city', array('type' => 'textarea', 'secure' => false));
  1270. $this->Form->input('Addresses.zip', array(
  1271. 'type' => 'select', 'options' => array(1,2), 'secure' => false
  1272. ));
  1273. $result = $this->Form->fields;
  1274. $expected = array(
  1275. 'Addresses.id' => '123456', 'Addresses.title',
  1276. );
  1277. $this->assertEquals($expected, $result);
  1278. }
  1279. /**
  1280. * test disableField
  1281. *
  1282. * @return void
  1283. */
  1284. public function testUnlockFieldAddsToList() {
  1285. $this->Form->request['_Token'] = array(
  1286. 'key' => 'testKey',
  1287. 'unlockedFields' => array()
  1288. );
  1289. $this->Form->create('Contact');
  1290. $this->Form->unlockField('Contact.name');
  1291. $this->Form->text('Contact.name');
  1292. $this->assertEquals(array('Contact.name'), $this->Form->unlockField());
  1293. $this->assertEquals(array(), $this->Form->fields);
  1294. }
  1295. /**
  1296. * test unlockField removing from fields array.
  1297. *
  1298. * @return void
  1299. */
  1300. public function testUnlockFieldRemovingFromFields() {
  1301. $this->Form->request['_Token'] = array(
  1302. 'key' => 'testKey',
  1303. 'unlockedFields' => array()
  1304. );
  1305. $this->Form->create('Contact');
  1306. $this->Form->hidden('Contact.id', array('value' => 1));
  1307. $this->Form->text('Contact.name');
  1308. $this->assertEquals(1, $this->Form->fields['Contact.id'], 'Hidden input should be secured.');
  1309. $this->assertTrue(in_array('Contact.name', $this->Form->fields), 'Field should be secured.');
  1310. $this->Form->unlockField('Contact.name');
  1311. $this->Form->unlockField('Contact.id');
  1312. $this->assertEquals(array(), $this->Form->fields);
  1313. }
  1314. /**
  1315. * testTagIsInvalid method
  1316. *
  1317. * @return void
  1318. */
  1319. public function testTagIsInvalid() {
  1320. $Contact = ClassRegistry::getObject('Contact');
  1321. $Contact->validationErrors[0]['email'] = array('Please provide an email');
  1322. $this->Form->setEntity('Contact.0.email');
  1323. $result = $this->Form->tagIsInvalid();
  1324. $expected = array('Please provide an email');
  1325. $this->assertEquals($expected, $result);
  1326. $this->Form->setEntity('Contact.1.email');
  1327. $result = $this->Form->tagIsInvalid();
  1328. $expected = false;
  1329. $this->assertSame($expected, $result);
  1330. $this->Form->setEntity('Contact.0.name');
  1331. $result = $this->Form->tagIsInvalid();
  1332. $expected = false;
  1333. $this->assertSame($expected, $result);
  1334. }
  1335. /**
  1336. * testPasswordValidation method
  1337. *
  1338. * test validation errors on password input.
  1339. *
  1340. * @return void
  1341. */
  1342. public function testPasswordValidation() {
  1343. $Contact = ClassRegistry::getObject('Contact');
  1344. $Contact->validationErrors['password'] = array('Please provide a password');
  1345. $result = $this->Form->input('Contact.password');
  1346. $expected = array(
  1347. 'div' => array('class' => 'input password error'),
  1348. 'label' => array('for' => 'ContactPassword'),
  1349. 'Password',
  1350. '/label',
  1351. 'input' => array(
  1352. 'type' => 'password', 'name' => 'data[Contact][password]',
  1353. 'id' => 'ContactPassword', 'class' => 'form-error'
  1354. ),
  1355. array('div' => array('class' => 'error-message')),
  1356. 'Please provide a password',
  1357. '/div',
  1358. '/div'
  1359. );
  1360. $this->assertTags($result, $expected);
  1361. }
  1362. /**
  1363. * testEmptyErrorValidation method
  1364. *
  1365. * test validation error div when validation message is an empty string
  1366. *
  1367. * @access public
  1368. * @return void
  1369. */
  1370. public function testEmptyErrorValidation() {
  1371. $this->Form->validationErrors['Contact']['password'] = '';
  1372. $result = $this->Form->input('Contact.password');
  1373. $expected = array(
  1374. 'div' => array('class' => 'input password error'),
  1375. 'label' => array('for' => 'ContactPassword'),
  1376. 'Password',
  1377. '/label',
  1378. 'input' => array(
  1379. 'type' => 'password', 'name' => 'data[Contact][password]',
  1380. 'id' => 'ContactPassword', 'class' => 'form-error'
  1381. ),
  1382. array('div' => array('class' => 'error-message')),
  1383. array(),
  1384. '/div',
  1385. '/div'
  1386. );
  1387. $this->assertTags($result, $expected);
  1388. }
  1389. /**
  1390. * testEmptyInputErrorValidation method
  1391. *
  1392. * test validation error div when validation message is overridden by an empty string when calling input()
  1393. *
  1394. * @access public
  1395. * @return void
  1396. */
  1397. public function testEmptyInputErrorValidation() {
  1398. $this->Form->validationErrors['Contact']['password'] = 'Please provide a password';
  1399. $result = $this->Form->input('Contact.password', array('error' => ''));
  1400. $expected = array(
  1401. 'div' => array('class' => 'input password error'),
  1402. 'label' => array('for' => 'ContactPassword'),
  1403. 'Password',
  1404. '/label',
  1405. 'input' => array(
  1406. 'type' => 'password', 'name' => 'data[Contact][password]',
  1407. 'id' => 'ContactPassword', 'class' => 'form-error'
  1408. ),
  1409. array('div' => array('class' => 'error-message')),
  1410. array(),
  1411. '/div',
  1412. '/div'
  1413. );
  1414. $this->assertTags($result, $expected);
  1415. }
  1416. /**
  1417. * testFormValidationAssociated method
  1418. *
  1419. * test display of form errors in conjunction with model::validates.
  1420. *
  1421. * @return void
  1422. */
  1423. public function testFormValidationAssociated() {
  1424. $this->UserForm = ClassRegistry::getObject('UserForm');
  1425. $this->UserForm->OpenidUrl = ClassRegistry::getObject('OpenidUrl');
  1426. $data = array(
  1427. 'UserForm' => array('name' => 'user'),
  1428. 'OpenidUrl' => array('url' => 'http://www.cakephp.org')
  1429. );
  1430. $result = $this->UserForm->OpenidUrl->create($data);
  1431. $this->assertFalse(empty($result));
  1432. $this->assertFalse($this->UserForm->OpenidUrl->validates());
  1433. $result = $this->Form->create('UserForm', array('type' => 'post', 'action' => 'login'));
  1434. $encoding = strtolower(Configure::read('App.encoding'));
  1435. $expected = array(
  1436. 'form' => array(
  1437. 'method' => 'post', 'action' => '/user_forms/login', 'id' => 'UserFormLoginForm',
  1438. 'accept-charset' => $encoding
  1439. ),
  1440. 'div' => array('style' => 'display:none;'),
  1441. 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
  1442. '/div'
  1443. );
  1444. $this->assertTags($result, $expected);
  1445. $result = $this->Form->error(
  1446. 'OpenidUrl.openid_not_registered', 'Error, not registered', array('wrap' => false)
  1447. );
  1448. $this->assertEquals('Error, not registered', $result);
  1449. unset($this->UserForm->OpenidUrl, $this->UserForm);
  1450. }
  1451. /**
  1452. * testFormValidationAssociatedFirstLevel method
  1453. *
  1454. * test form error display with associated model.
  1455. *
  1456. * @return void
  1457. */
  1458. public function testFormValidationAssociatedFirstLevel() {
  1459. $this->ValidateUser = ClassRegistry::getObject('ValidateUser');
  1460. $this->ValidateUser->ValidateProfile = ClassRegistry::getObject('ValidateProfile');
  1461. $data = array(
  1462. 'ValidateUser' => array('name' => 'mariano'),
  1463. 'ValidateProfile' => array('full_name' => 'Mariano Iglesias')
  1464. );
  1465. $result = $this->ValidateUser->create($data);
  1466. $this->assertFalse(empty($result));
  1467. $this->assertFalse($this->ValidateUser->validates());
  1468. $this->assertFalse($this->ValidateUser->ValidateProfile->validates());
  1469. $result = $this->Form->create('ValidateUser', array('type' => 'post', 'action' => 'add'));
  1470. $encoding = strtolower(Configure::read('App.encoding'));
  1471. $expected = array(
  1472. 'form' => array('method' => 'post', 'action' => '/validate_users/add', 'id','accept-charset' => $encoding),
  1473. 'div' => array('style' => 'display:none;'),
  1474. 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
  1475. '/div'
  1476. );
  1477. $this->assertTags($result, $expected);
  1478. $result = $this->Form->error(
  1479. 'ValidateUser.email', 'Invalid email', array('wrap' => false)
  1480. );
  1481. $this->assertEquals('Invalid email', $result);
  1482. $result = $this->Form->error(
  1483. 'ValidateProfile.full_name', 'Invalid name', array('wrap' => false)
  1484. );
  1485. $this->assertEquals('Invalid name', $result);
  1486. $result = $this->Form->error(
  1487. 'ValidateProfile.city', 'Invalid city', array('wrap' => false)
  1488. );
  1489. $this->assertEquals('Invalid city', $result);
  1490. unset($this->ValidateUser->ValidateProfile);
  1491. unset($this->ValidateUser);
  1492. }
  1493. /**
  1494. * testFormValidationAssociatedSecondLevel method
  1495. *
  1496. * test form error display with associated model.
  1497. *
  1498. * @return void
  1499. */
  1500. public function testFormValidationAssociatedSecondLevel() {
  1501. $this->ValidateUser = ClassRegistry::getObject('ValidateUser');
  1502. $this->ValidateUser->ValidateProfile = ClassRegistry::getObject('ValidateProfile');
  1503. $this->ValidateUser->ValidateProfile->ValidateItem = ClassRegistry::getObject('ValidateItem');
  1504. $data = array(
  1505. 'ValidateUser' => array('name' => 'mariano'),
  1506. 'ValidateProfile' => array('full_name' => 'Mariano Iglesias'),
  1507. 'ValidateItem' => array('name' => 'Item')
  1508. );
  1509. $result = $this->ValidateUser->create($data);
  1510. $this->assertFalse(empty($result));
  1511. $this->assertFalse($this->ValidateUser->validates());
  1512. $this->assertFalse($this->ValidateUser->ValidateProfile->validates());
  1513. $this->assertFalse($this->ValidateUser->ValidateProfile->ValidateItem->validates());
  1514. $result = $this->Form->create('ValidateUser', array('type' => 'post', 'action' => 'add'));
  1515. $encoding = strtolower(Configure::read('App.encoding'));
  1516. $expected = array(
  1517. 'form' => array('method' => 'post', 'action' => '/validate_users/add', 'id','accept-charset' => $encoding),
  1518. 'div' => array('style' => 'display:none;'),
  1519. 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
  1520. '/div'
  1521. );
  1522. $this->assertTags($result, $expected);
  1523. $result = $this->Form->error(
  1524. 'ValidateUser.email', 'Invalid email', array('wrap' => false)
  1525. );
  1526. $this->assertEquals('Invalid email', $result);
  1527. $result = $this->Form->error(
  1528. 'ValidateProfile.full_name', 'Invalid name', array('wrap' => false)
  1529. );
  1530. $this->assertEquals('Invalid name', $result);
  1531. $result = $this->Form->error(
  1532. 'ValidateProfile.city', 'Invalid city', array('wrap' => false)
  1533. );
  1534. $result = $this->Form->error(
  1535. 'ValidateItem.description', 'Invalid description', array('wrap' => false)
  1536. );
  1537. $this->assertEquals('Invalid description', $result);
  1538. unset($this->ValidateUser->ValidateProfile->ValidateItem);
  1539. unset($this->ValidateUser->ValidateProfile);
  1540. unset($this->ValidateUser);
  1541. }
  1542. /**
  1543. * testFormValidationMultiRecord method
  1544. *
  1545. * test form error display with multiple records.
  1546. *
  1547. * @return void
  1548. */
  1549. public function testFormValidationMultiRecord() {
  1550. $Contact = ClassRegistry::getObject('Contact');
  1551. $Contact->validationErrors[2] = array(
  1552. 'name' => array('This field cannot be left blank')
  1553. );
  1554. $result = $this->Form->input('Contact.2.name');
  1555. $expected = array(
  1556. 'div' => array('class' => 'input text error'),
  1557. 'label' => array('for' => 'Contact2Name'),
  1558. 'Name',
  1559. '/label',
  1560. 'input' => array(
  1561. 'type' => 'text', 'name' => 'data[Contact][2][name]', 'id' => 'Contact2Name',
  1562. 'class' => 'form-error', 'maxlength' => 255
  1563. ),
  1564. array('div' => array('class' => 'error-message')),
  1565. 'This field cannot be left blank',
  1566. '/div',
  1567. '/div'
  1568. );
  1569. $this->assertTags($result, $expected);
  1570. }
  1571. /**
  1572. * testMultipleInputValidation method
  1573. *
  1574. * test multiple record form validation error display.
  1575. *
  1576. * @return void
  1577. */
  1578. public function testMultipleInputValidation() {
  1579. $Address = ClassRegistry::init(array('class' => 'Address', 'table' => false, 'ds' => 'test'));
  1580. $Address->validationErrors[0] = array(
  1581. 'title' => array('This field cannot be empty'),
  1582. 'first_name' => array('This field cannot be empty')
  1583. );
  1584. $Address->validationErrors[1] = array(
  1585. 'last_name' => array('You must have a last name')
  1586. );
  1587. $this->Form->create();
  1588. $result = $this->Form->input('Address.0.title');
  1589. $expected = array(
  1590. 'div' => array('class'),
  1591. 'label' => array('for'),
  1592. 'preg:/[^<]+/',
  1593. '/label',
  1594. 'input' => array(
  1595. 'type' => 'text', 'name', 'id', 'class' => 'form-error'
  1596. ),
  1597. array(

Large files files are truncated, but you can click here to view the full file