PageRenderTime 60ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

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

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

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