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

/Vendor/pear-pear.cakephp.org/CakePHP/Cake/Test/Case/View/Helper/FormHelperTest.php

https://bitbucket.org/daveschwan/ronin-group
PHP | 9627 lines | 7686 code | 752 blank | 1189 comment | 1 complexity | 948e0af78c32a78cea5e576038a4fcea MD5 | raw file
Possible License(s): LGPL-2.1, MPL-2.0-no-copyleft-exception, MIT, BSD-3-Clause, Apache-2.0

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

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

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