PageRenderTime 57ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 1ms

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

https://bitbucket.org/udeshika/fake_twitter
PHP | 7623 lines | 5950 code | 591 blank | 1082 comment | 1 complexity | f3178e7bffb0c509e1d08f66860afefe 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/view/1196/Testing>
  8. * Copyright 2005-2011, 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-2011, Cake Software Foundation, Inc.
  14. * @link http://book.cakephp.org/view/1196/Testing 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($this->Form->fields, array());
  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($this->Form->entity(), array('ValidateUser'));
  655. $result = $this->Form->input('ValidateItem.name');
  656. $this->assertEquals($this->Form->entity(), array('ValidateItem', 'name'));
  657. $result = $this->Form->input('ValidateUser.name');
  658. $this->assertEquals($this->Form->entity(), array('ValidateUser', 'name'));
  659. $this->assertRegExp('/name="data\[ValidateUser\]\[name\]"/', $result);
  660. $this->assertRegExp('/type="text"/', $result);
  661. $result = $this->Form->input('ValidateItem.name');
  662. $this->assertEquals($this->Form->entity(), array('ValidateItem', 'name'));
  663. $this->assertRegExp('/name="data\[ValidateItem\]\[name\]"/', $result);
  664. $this->assertRegExp('/<textarea/', $result);
  665. $result = $this->Form->input('name');
  666. $this->assertEquals($this->Form->entity(), array('ValidateUser', 'name'));
  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($this->Form->fields, array());
  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. 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. }
  974. /**
  975. * testFormSecurityMultipleInputDisabledFields method
  976. *
  977. * test secure form generation with multiple records and disabled fields.
  978. *
  979. * @return void
  980. */
  981. public function testFormSecurityMultipleInputDisabledFields() {
  982. $key = 'testKey';
  983. $this->Form->request->params['_Token'] = array(
  984. 'key' => $key,
  985. 'unlockedFields' => array('first_name', 'address')
  986. );
  987. $this->Form->create();
  988. $this->Form->hidden('Addresses.0.id', array('value' => '123456'));
  989. $this->Form->input('Addresses.0.title');
  990. $this->Form->input('Addresses.0.first_name');
  991. $this->Form->input('Addresses.0.last_name');
  992. $this->Form->input('Addresses.0.address');
  993. $this->Form->input('Addresses.0.city');
  994. $this->Form->input('Addresses.0.phone');
  995. $this->Form->hidden('Addresses.1.id', array('value' => '654321'));
  996. $this->Form->input('Addresses.1.title');
  997. $this->Form->input('Addresses.1.first_name');
  998. $this->Form->input('Addresses.1.last_name');
  999. $this->Form->input('Addresses.1.address');
  1000. $this->Form->input('Addresses.1.city');
  1001. $this->Form->input('Addresses.1.phone');
  1002. $result = $this->Form->secure($this->Form->fields);
  1003. $hash = '629b6536dcece48aa41a117045628ce602ccbbb2%3AAddresses.0.id%7CAddresses.1.id';
  1004. $expected = array(
  1005. 'div' => array('style' => 'display:none;'),
  1006. array('input' => array(
  1007. 'type' => 'hidden', 'name' => 'data[_Token][fields]',
  1008. 'value' => $hash, 'id' => 'preg:/TokenFields\d+/'
  1009. )),
  1010. array('input' => array(
  1011. 'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
  1012. 'value' => 'address%7Cfirst_name', 'id' => 'preg:/TokenUnlocked\d+/'
  1013. )),
  1014. '/div'
  1015. );
  1016. $this->assertTags($result, $expected);
  1017. }
  1018. /**
  1019. * testFormSecurityInputDisabledFields method
  1020. *
  1021. * Test single record form with disabled fields.
  1022. *
  1023. * @return void
  1024. */
  1025. public function testFormSecurityInputUnlockedFields() {
  1026. $key = 'testKey';
  1027. $this->Form->request['_Token'] = array(
  1028. 'key' => $key,
  1029. 'unlockedFields' => array('first_name', 'address')
  1030. );
  1031. $this->Form->create();
  1032. $this->assertEquals($this->Form->request['_Token']['unlockedFields'], $this->Form->unlockField());
  1033. $this->Form->hidden('Addresses.id', array('value' => '123456'));
  1034. $this->Form->input('Addresses.title');
  1035. $this->Form->input('Addresses.first_name');
  1036. $this->Form->input('Addresses.last_name');
  1037. $this->Form->input('Addresses.address');
  1038. $this->Form->input('Addresses.city');
  1039. $this->Form->input('Addresses.phone');
  1040. $result = $this->Form->fields;
  1041. $expected = array(
  1042. 'Addresses.id' => '123456', 'Addresses.title', 'Addresses.last_name',
  1043. 'Addresses.city', 'Addresses.phone'
  1044. );
  1045. $this->assertEquals($expected, $result);
  1046. $result = $this->Form->secure($expected);
  1047. $hash = '2981c38990f3f6ba935e6561dc77277966fabd6d%3AAddresses.id';
  1048. $expected = array(
  1049. 'div' => array('style' => 'display:none;'),
  1050. array('input' => array(
  1051. 'type' => 'hidden', 'name' => 'data[_Token][fields]',
  1052. 'value' => $hash, 'id' => 'preg:/TokenFields\d+/'
  1053. )),
  1054. array('input' => array(
  1055. 'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
  1056. 'value' => 'address%7Cfirst_name', 'id' => 'preg:/TokenUnlocked\d+/'
  1057. )),
  1058. '/div'
  1059. );
  1060. $this->assertTags($result, $expected);
  1061. }
  1062. /**
  1063. * test securing inputs with custom name attributes.
  1064. *
  1065. * @return void
  1066. */
  1067. public function testFormSecureWithCustomNameAttribute() {
  1068. $this->Form->request->params['_Token']['key'] = 'testKey';
  1069. $this->Form->text('UserForm.published', array('name' => 'data[User][custom]'));
  1070. $this->assertEquals('User.custom', $this->Form->fields[0]);
  1071. $this->Form->text('UserForm.published', array('name' => 'data[User][custom][another][value]'));
  1072. $this->assertEquals('User.custom.another.value', $this->Form->fields[1]);
  1073. }
  1074. /**
  1075. * testFormSecuredInput method
  1076. *
  1077. * Test generation of entire secure form, assertions made on input() output.
  1078. *
  1079. * @return void
  1080. */
  1081. public function testFormSecuredInput() {
  1082. $this->Form->request['_Token'] = array('key' => 'testKey');
  1083. $result = $this->Form->create('Contact', array('url' => '/contacts/add'));
  1084. $encoding = strtolower(Configure::read('App.encoding'));
  1085. $expected = array(
  1086. 'form' => array('method' => 'post', 'action' => '/contacts/add', 'accept-charset' => $encoding, 'id' => 'ContactAddForm'),
  1087. 'div' => array('style' => 'display:none;'),
  1088. array('input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST')),
  1089. array('input' => array(
  1090. 'type' => 'hidden', 'name' => 'data[_Token][key]',
  1091. 'value' => 'testKey', 'id' => 'preg:/Token\d+/'
  1092. )),
  1093. '/div'
  1094. );
  1095. $this->assertTags($result, $expected);
  1096. $result = $this->Form->input('UserForm.published', array('type' => 'text'));
  1097. $expected = array(
  1098. 'div' => array('class' => 'input text'),
  1099. 'label' => array('for' => 'UserFormPublished'),
  1100. 'Published',
  1101. '/label',
  1102. array('input' => array(
  1103. 'type' => 'text', 'name' => 'data[UserForm][published]',
  1104. 'id' => 'UserFormPublished'
  1105. )),
  1106. '/div'
  1107. );
  1108. $this->assertTags($result, $expected);
  1109. $result = $this->Form->input('UserForm.other', array('type' => 'text'));
  1110. $expected = array(
  1111. 'div' => array('class' => 'input text'),
  1112. 'label' => array('for' => 'UserFormOther'),
  1113. 'Other',
  1114. '/label',
  1115. array('input' => array(
  1116. 'type' => 'text', 'name' => 'data[UserForm][other]',
  1117. 'id' => 'UserFormOther'
  1118. )),
  1119. '/div'
  1120. );
  1121. $this->assertTags($result, $expected);
  1122. $result = $this->Form->hidden('UserForm.stuff');
  1123. $expected = array('input' => array(
  1124. 'type' => 'hidden', 'name' => 'data[UserForm][stuff]',
  1125. 'id' => 'UserFormStuff'
  1126. ));
  1127. $this->assertTags($result, $expected);
  1128. $result = $this->Form->hidden('UserForm.hidden', array('value' => '0'));
  1129. $expected = array('input' => array(
  1130. 'type' => 'hidden', 'name' => 'data[UserForm][hidden]',
  1131. 'value' => '0', 'id' => 'UserFormHidden'
  1132. ));
  1133. $this->assertTags($result, $expected);
  1134. $result = $this->Form->input('UserForm.something', array('type' => 'checkbox'));
  1135. $expected = array(
  1136. 'div' => array('class' => 'input checkbox'),
  1137. array('input' => array(
  1138. 'type' => 'hidden', 'name' => 'data[UserForm][something]',
  1139. 'value' => '0', 'id' => 'UserFormSomething_'
  1140. )),
  1141. array('input' => array(
  1142. 'type' => 'checkbox', 'name' => 'data[UserForm][something]',
  1143. 'value' => '1', 'id' => 'UserFormSomething'
  1144. )),
  1145. 'label' => array('for' => 'UserFormSomething'),
  1146. 'Something',
  1147. '/label',
  1148. '/div'
  1149. );
  1150. $this->assertTags($result, $expected);
  1151. $result = $this->Form->fields;
  1152. $expected = array(
  1153. 'UserForm.published', 'UserForm.other', 'UserForm.stuff' => '',
  1154. 'UserForm.hidden' => '0', 'UserForm.something'
  1155. );
  1156. $this->assertEquals($expected, $result);
  1157. $hash = 'bd7c4a654e5361f9a433a43f488ff9a1065d0aaf%3AUserForm.hidden%7CUserForm.stuff';
  1158. $result = $this->Form->secure($this->Form->fields);
  1159. $expected = array(
  1160. 'div' => array('style' => 'display:none;'),
  1161. array('input' => array(
  1162. 'type' => 'hidden', 'name' => 'data[_Token][fields]',
  1163. 'value' => $hash, 'id' => 'preg:/TokenFields\d+/'
  1164. )),
  1165. array('input' => array(
  1166. 'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
  1167. 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/'
  1168. )),
  1169. '/div'
  1170. );
  1171. $this->assertTags($result, $expected);
  1172. }
  1173. /**
  1174. * Tests that the correct keys are added to the field hash index
  1175. *
  1176. * @return void
  1177. */
  1178. public function testFormSecuredFileInput() {
  1179. $this->Form->request['_Token'] = array('key' => 'testKey');
  1180. $this->assertEquals($this->Form->fields, array());
  1181. $result = $this->Form->file('Attachment.file');
  1182. $expected = array(
  1183. 'Attachment.file.name', 'Attachment.file.type', 'Attachment.file.tmp_name',
  1184. 'Attachment.file.error', 'Attachment.file.size'
  1185. );
  1186. $this->assertEquals($this->Form->fields, $expected);
  1187. }
  1188. /**
  1189. * test that multiple selects keys are added to field hash
  1190. *
  1191. * @return void
  1192. */
  1193. public function testFormSecuredMultipleSelect() {
  1194. $this->Form->request['_Token'] = array('key' => 'testKey');
  1195. $this->assertEquals($this->Form->fields, array());
  1196. $options = array('1' => 'one', '2' => 'two');
  1197. $this->Form->select('Model.select', $options);
  1198. $expected = array('Model.select');
  1199. $this->assertEquals($this->Form->fields, $expected);
  1200. $this->Form->fields = array();
  1201. $this->Form->select('Model.select', $options, array('multiple' => true));
  1202. $this->assertEquals($this->Form->fields, $expected);
  1203. }
  1204. /**
  1205. * testFormSecuredRadio method
  1206. *
  1207. * @return void
  1208. */
  1209. public function testFormSecuredRadio() {
  1210. $this->Form->request['_Token'] = array('key' => 'testKey');
  1211. $this->assertEquals($this->Form->fields, array());
  1212. $options = array('1' => 'option1', '2' => 'option2');
  1213. $this->Form->radio('Test.test', $options);
  1214. $expected = array('Test.test');
  1215. $this->assertEquals($this->Form->fields, $expected);
  1216. }
  1217. /**
  1218. * testDisableSecurityUsingForm method
  1219. *
  1220. * @return void
  1221. */
  1222. public function testDisableSecurityUsingForm() {
  1223. $this->Form->request['_Token'] = array(
  1224. 'key' => 'testKey',
  1225. 'disabledFields' => array()
  1226. );
  1227. $this->Form->create();
  1228. $this->Form->hidden('Addresses.id', array('value' => '123456'));
  1229. $this->Form->input('Addresses.title');
  1230. $this->Form->input('Addresses.first_name', array('secure' => false));
  1231. $this->Form->input('Addresses.city', array('type' => 'textarea', 'secure' => false));
  1232. $this->Form->input('Addresses.zip', array(
  1233. 'type' => 'select', 'options' => array(1,2), 'secure' => false
  1234. ));
  1235. $result = $this->Form->fields;
  1236. $expected = array(
  1237. 'Addresses.id' => '123456', 'Addresses.title',
  1238. );
  1239. $this->assertEquals($expected, $result);
  1240. }
  1241. /**
  1242. * test disableField
  1243. *
  1244. * @return void
  1245. */
  1246. public function testUnlockFieldAddsToList() {
  1247. $this->Form->request['_Token'] = array(
  1248. 'key' => 'testKey',
  1249. 'unlockedFields' => array()
  1250. );
  1251. $this->Form->create('Contact');
  1252. $this->Form->unlockField('Contact.name');
  1253. $this->Form->text('Contact.name');
  1254. $this->assertEquals(array('Contact.name'), $this->Form->unlockField());
  1255. $this->assertEquals(array(), $this->Form->fields);
  1256. }
  1257. /**
  1258. * test unlockField removing from fields array.
  1259. *
  1260. * @return void
  1261. */
  1262. public function testUnlockFieldRemovingFromFields() {
  1263. $this->Form->request['_Token'] = array(
  1264. 'key' => 'testKey',
  1265. 'unlockedFields' => array()
  1266. );
  1267. $this->Form->create('Contact');
  1268. $this->Form->hidden('Contact.id', array('value' => 1));
  1269. $this->Form->text('Contact.name');
  1270. $this->assertEquals(1, $this->Form->fields['Contact.id'], 'Hidden input should be secured.');
  1271. $this->assertTrue(in_array('Contact.name', $this->Form->fields), 'Field should be secured.');
  1272. $this->Form->unlockField('Contact.name');
  1273. $this->Form->unlockField('Contact.id');
  1274. $this->assertEquals(array(), $this->Form->fields);
  1275. }
  1276. /**
  1277. * testPasswordValidation method
  1278. *
  1279. * test validation errors on password input.
  1280. *
  1281. * @return void
  1282. */
  1283. public function testPasswordValidation() {
  1284. $Contact = ClassRegistry::getObject('Contact');
  1285. $Contact->validationErrors['password'] = array('Please provide a password');
  1286. $result = $this->Form->input('Contact.password');
  1287. $expected = array(
  1288. 'div' => array('class' => 'input password error'),
  1289. 'label' => array('for' => 'ContactPassword'),
  1290. 'Password',
  1291. '/label',
  1292. 'input' => array(
  1293. 'type' => 'password', 'name' => 'data[Contact][password]',
  1294. 'id' => 'ContactPassword', 'class' => 'form-error'
  1295. ),
  1296. array('div' => array('class' => 'error-message')),
  1297. 'Please provide a password',
  1298. '/div',
  1299. '/div'
  1300. );
  1301. $this->assertTags($result, $expected);
  1302. }
  1303. /**
  1304. * testEmptyErrorValidation method
  1305. *
  1306. * test validation error div when validation message is an empty string
  1307. *
  1308. * @access public
  1309. * @return void
  1310. */
  1311. function testEmptyErrorValidation() {
  1312. $this->Form->validationErrors['Contact']['password'] = '';
  1313. $result = $this->Form->input('Contact.password');
  1314. $expected = array(
  1315. 'div' => array('class' => 'input password error'),
  1316. 'label' => array('for' => 'ContactPassword'),
  1317. 'Password',
  1318. '/label',
  1319. 'input' => array(
  1320. 'type' => 'password', 'name' => 'data[Contact][password]',
  1321. 'id' => 'ContactPassword', 'class' => 'form-error'
  1322. ),
  1323. array('div' => array('class' => 'error-message')),
  1324. array(),
  1325. '/div',
  1326. '/div'
  1327. );
  1328. $this->assertTags($result, $expected);
  1329. }
  1330. /**
  1331. * testEmptyInputErrorValidation method
  1332. *
  1333. * test validation error div when validation message is overriden by an empty string when calling input()
  1334. *
  1335. * @access public
  1336. * @return void
  1337. */
  1338. function testEmptyInputErrorValidation() {
  1339. $this->Form->validationErrors['Contact']['password'] = 'Please provide a password';
  1340. $result = $this->Form->input('Contact.password', array('error' => ''));
  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. array(),
  1352. '/div',
  1353. '/div'
  1354. );
  1355. $this->assertTags($result, $expected);
  1356. }
  1357. /**
  1358. * testFormValidationAssociated method
  1359. *
  1360. * test display of form errors in conjunction with model::validates.
  1361. *
  1362. * @return void
  1363. */
  1364. public function testFormValidationAssociated() {
  1365. $this->UserForm = ClassRegistry::getObject('UserForm');
  1366. $this->UserForm->OpenidUrl = ClassRegistry::getObject('OpenidUrl');
  1367. $data = array(
  1368. 'UserForm' => array('name' => 'user'),
  1369. 'OpenidUrl' => array('url' => 'http://www.cakephp.org')
  1370. );
  1371. $result = $this->UserForm->OpenidUrl->create($data);
  1372. $this->assertFalse(empty($result));
  1373. $this->assertFalse($this->UserForm->OpenidUrl->validates());
  1374. $result = $this->Form->create('UserForm', array('type' => 'post', 'action' => 'login'));
  1375. $encoding = strtolower(Configure::read('App.encoding'));
  1376. $expected = array(
  1377. 'form' => array(
  1378. 'method' => 'post', 'action' => '/user_forms/login', 'id' => 'UserFormLoginForm',
  1379. 'accept-charset' => $encoding
  1380. ),
  1381. 'div' => array('style' => 'display:none;'),
  1382. 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
  1383. '/div'
  1384. );
  1385. $this->assertTags($result, $expected);
  1386. $result = $this->Form->error(
  1387. 'OpenidUrl.openid_not_registered', 'Error, not registered', array('wrap' => false)
  1388. );
  1389. $this->assertEquals($result, 'Error, not registered');
  1390. unset($this->UserForm->OpenidUrl, $this->UserForm);
  1391. }
  1392. /**
  1393. * testFormValidationAssociatedFirstLevel method
  1394. *
  1395. * test form error display with associated model.
  1396. *
  1397. * @return void
  1398. */
  1399. public function testFormValidationAssociatedFirstLevel() {
  1400. $this->ValidateUser = ClassRegistry::getObject('ValidateUser');
  1401. $this->ValidateUser->ValidateProfile = ClassRegistry::getObject('ValidateProfile');
  1402. $data = array(
  1403. 'ValidateUser' => array('name' => 'mariano'),
  1404. 'ValidateProfile' => array('full_name' => 'Mariano Iglesias')
  1405. );
  1406. $result = $this->ValidateUser->create($data);
  1407. $this->assertFalse(empty($result));
  1408. $this->assertFalse($this->ValidateUser->validates());
  1409. $this->assertFalse($this->ValidateUser->ValidateProfile->validates());
  1410. $result = $this->Form->create('ValidateUser', array('type' => 'post', 'action' => 'add'));
  1411. $encoding = strtolower(Configure::read('App.encoding'));
  1412. $expected = array(
  1413. 'form' => array('method' => 'post', 'action' => '/validate_users/add', 'id','accept-charset' => $encoding),
  1414. 'div' => array('style' => 'display:none;'),
  1415. 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
  1416. '/div'
  1417. );
  1418. $this->assertTags($result, $expected);
  1419. $result = $this->Form->error(
  1420. 'ValidateUser.email', 'Invalid email', array('wrap' => false)
  1421. );
  1422. $this->assertEquals($result, 'Invalid email');
  1423. $result = $this->Form->error(
  1424. 'ValidateProfile.full_name', 'Invalid name', array('wrap' => false)
  1425. );
  1426. $this->assertEquals($result, 'Invalid name');
  1427. $result = $this->Form->error(
  1428. 'ValidateProfile.city', 'Invalid city', array('wrap' => false)
  1429. );
  1430. $this->assertEquals($result, 'Invalid city');
  1431. unset($this->ValidateUser->ValidateProfile);
  1432. unset($this->ValidateUser);
  1433. }
  1434. /**
  1435. * testFormValidationAssociatedSecondLevel method
  1436. *
  1437. * test form error display with associated model.
  1438. *
  1439. * @return void
  1440. */
  1441. public function testFormValidationAssociatedSecondLevel() {
  1442. $this->ValidateUser = ClassRegistry::getObject('ValidateUser');
  1443. $this->ValidateUser->ValidateProfile = ClassRegistry::getObject('ValidateProfile');
  1444. $this->ValidateUser->ValidateProfile->ValidateItem = ClassRegistry::getObject('ValidateItem');
  1445. $data = array(
  1446. 'ValidateUser' => array('name' => 'mariano'),
  1447. 'ValidateProfile' => array('full_name' => 'Mariano Iglesias'),
  1448. 'ValidateItem' => array('name' => 'Item')
  1449. );
  1450. $result = $this->ValidateUser->create($data);
  1451. $this->assertFalse(empty($result));
  1452. $this->assertFalse($this->ValidateUser->validates());
  1453. $this->assertFalse($this->ValidateUser->ValidateProfile->validates());
  1454. $this->assertFalse($this->ValidateUser->ValidateProfile->ValidateItem->validates());
  1455. $result = $this->Form->create('ValidateUser', array('type' => 'post', 'action' => 'add'));
  1456. $encoding = strtolower(Configure::read('App.encoding'));
  1457. $expected = array(
  1458. 'form' => array('method' => 'post', 'action' => '/validate_users/add', 'id','accept-charset' => $encoding),
  1459. 'div' => array('style' => 'display:none;'),
  1460. 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
  1461. '/div'
  1462. );
  1463. $this->assertTags($result, $expected);
  1464. $result = $this->Form->error(
  1465. 'ValidateUser.email', 'Invalid email', array('wrap' => false)
  1466. );
  1467. $this->assertEquals($result, 'Invalid email');
  1468. $result = $this->Form->error(
  1469. 'ValidateProfile.full_name', 'Invalid name', array('wrap' => false)
  1470. );
  1471. $this->assertEquals($result, 'Invalid name');
  1472. $result = $this->Form->error(
  1473. 'ValidateProfile.city', 'Invalid city', array('wrap' => false)
  1474. );
  1475. $result = $this->Form->error(
  1476. 'ValidateItem.description', 'Invalid description', array('wrap' => false)
  1477. );
  1478. $this->assertEquals($result, 'Invalid description');
  1479. unset($this->ValidateUser->ValidateProfile->ValidateItem);
  1480. unset($this->ValidateUser->ValidateProfile);
  1481. unset($this->ValidateUser);
  1482. }
  1483. /**
  1484. * testFormValidationMultiRecord method
  1485. *
  1486. * test form error display with multiple records.
  1487. *
  1488. * @return void
  1489. */
  1490. public function testFormValidationMultiRecord() {
  1491. $Contact = ClassRegistry::getObject('Contact');
  1492. $Contact->validationErrors[2] = array(
  1493. 'name' => array('This field cannot be left blank')
  1494. );
  1495. $result = $this->Form->input('Contact.2.name');
  1496. $expected = array(
  1497. 'div' => array('class' => 'input text error'),
  1498. 'label' => array('for' => 'Contact2Name'),
  1499. 'Name',
  1500. '/label',
  1501. 'input' => array(
  1502. 'type' => 'text', 'name' => 'data[Contact][2][name]', 'id' => 'Contact2Name',
  1503. 'class' => 'form-error', 'maxlength' => 255
  1504. ),
  1505. array('div' => array('class' => 'error-message')),
  1506. 'This field cannot be left blank',
  1507. '/div',
  1508. '/div'
  1509. );
  1510. $this->assertTags($result, $expected);
  1511. }
  1512. /**
  1513. * testMultipleInputValidation method
  1514. *
  1515. * test multiple record form validation error display.
  1516. *
  1517. * @return void
  1518. */
  1519. public function testMultipleInputValidation() {
  1520. $Address = ClassRegistry::init(array('class' => 'Address', 'table' => false, 'ds' => 'test'));
  1521. $Address->validationErrors[0] = array(
  1522. 'title' => array('This field cannot be empty'),
  1523. 'first_name' => array('This field cannot be empty')
  1524. );
  1525. $Address->validationErrors[1] = array(
  1526. 'last_name' => array('You must have a last name')
  1527. );
  1528. $this->Form->create();
  1529. $result = $this->Form->input('Address.0.title');
  1530. $expected = array(
  1531. 'div' => array('class'),
  1532. 'label' => array('for'),
  1533. 'preg:/[^<]+/',
  1534. '/label',
  1535. 'input' => array(
  1536. 'type' => 'text', 'name', 'id', 'class' => 'form-error'
  1537. ),
  1538. array('div' => array('class' => 'error-message')),
  1539. 'This field cannot be empty',
  1540. '/div',
  1541. '/div'
  1542. );
  1543. $this->assertTags($result, $expected);
  1544. $result = $this->Form->input('Address.0.first_name');
  1545. $expected = array(
  1546. 'div' => array('class'),
  1547. 'label' => array('for'),
  1548. 'preg:/[^<]+/',
  1549. '/label',
  1550. 'input' => array('type' => 'text', 'name', 'id', 'class' => 'form-error'),
  1551. array('div' => array('class' => 'error-message')),
  1552. 'This field cannot be empty',
  1553. '/div',
  1554. '/div'
  1555. );
  1556. $this->assertTags($result, $expected);
  1557. $result = $this->Form->input('Address.0.last_name');
  1558. $expected = array(
  1559. 'div' => array('class'),
  1560. 'label' => array('for'),
  1561. 'preg:/[^<]+/',
  1562. '/label',
  1563. 'input' => array('type' => 'text', 'name', 'id'),
  1564. '/div'
  1565. );
  1566. $this->assertTags($result, $expected);
  1567. $result = $this->Form->input('Address.1.last_name');
  1568. $expected = array(
  1569. 'div' => array('class'),
  1570. 'label' => array('for'),
  1571. 'preg:/[^<]+/',
  1572. '/label',
  1573. 'input' => array(
  1574. 'type' => 'text', 'name' => 'preg:/[^<]+/',
  1575. 'id' => 'preg:/[^<]+/', 'class' => 'form-error'
  1576. ),
  1577. array('div' => array('class' => 'error-message')),
  1578. 'You must have a last name',
  1579. '/div',
  1580. '/div'
  1581. );
  1582. $this->assertTags($result, $expected);
  1583. }
  1584. /**
  1585. * testInput method
  1586. *
  1587. * Test various incarnations of input().
  1588. *
  1589. * @return void
  1590. */
  1591. public function testInput() {
  1592. $result = $this->Form->input('ValidateUser.balance');
  1593. $expected = array(
  1594. 'div' => array('class'),
  1595. 'label' => array('for'),
  1596. 'Balance',
  1597. '/label',
  1598. 'input' => array('name', 'type' => 'number', 'maxlength' => 8, 'id'),
  1599. '/div',
  1600. );
  1601. $this->assertTags($result, $expected);
  1602. $result = $this->Form->input('Contact.email', array('id' => 'custom'));
  1603. $expected = array(
  1604. 'div' => array('class' => 'input text'),
  1605. 'label' => array('for' => 'custom'),
  1606. 'Email',
  1607. '/label',
  1608. array('input' => array(
  1609. 'type' => 'text', 'name' => 'data[Contact][email]',
  1610. 'id' => 'custom', 'maxlength' => 255
  1611. )),
  1612. '/div'
  1613. );
  1614. $this->assertTags($result, $expected);
  1615. $result = $this->Form->input('Contact.email', array('div' => array('class' => false)));
  1616. $expected = array(
  1617. '<div',
  1618. 'label' => array('for' => 'ContactEmail'),
  1619. 'Email',
  1620. '/label',
  1621. array('input' => array(
  1622. 'type' => 'text', 'name' => 'data[Contact][email]',
  1623. 'id' => 'ContactEmail', 'maxlength' => 255
  1624. )),
  1625. '/div'
  1626. );
  1627. $this->assertTags($result, $expected);
  1628. $result = $this->Form->hidden('Contact.idontexist');
  1629. $expected = array('input' => array(
  1630. 'type' => 'hidden', 'name' => 'data[Contact][idontexist]',
  1631. 'id' => 'Con…

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