PageRenderTime 61ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 1ms

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

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

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