FormHelperTest   F
last analyzed

Complexity

Total Complexity 175

Size/Duplication

Total Lines 9381
Duplicated Lines 1.41 %

Coupling/Cohesion

Components 1
Dependencies 20

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 132
loc 9381
rs 0.6314
wmc 175
lcom 1
cbo 20

174 Methods

Rating   Name   Duplication   Size   Complexity  
B setUp() 0 38 1
A tearDown() 0 5 1
A testCreateWithSecurity() 0 19 1
A testCreateEndGetNoSecurity() 0 9 1
A testCreateClearingFields() 0 5 1
A testValidateHashNoModel() 0 5 1
A testDuplicateFieldNameResolution() 0 22 1
A testNoCheckboxLocking() 7 7 1
B testFormSecurityFields() 0 42 1
B testTextFieldGenerationForFloats() 0 42 1
B testTextFieldTypeNumberGenerationForIntegers() 0 24 1
B testFormSecurityMultipleFields() 0 28 1
B testFormSecurityMultipleSubmitButtons() 0 39 1
A testSecurityButtonNestedNamed() 9 9 1
A testSecuritySubmitNestedNamed() 9 9 1
A testSecuritySubmitImageNoName() 0 14 1
A testSecuritySubmitImageName() 0 14 1
B testFormSecurityMultipleInputFields() 0 42 1
A testFormSecurityArrayFields() 0 11 1
B testFormSecurityMultipleInputDisabledFields() 0 40 1
B testFormSecurityInputUnlockedFields() 0 41 1
A testFormSecureWithCustomNameAttribute() 0 9 1
B testFormSecuredInput() 0 102 1
A testSecuredInputCustomName() 0 18 1
A testFormSecuredFileInput() 0 11 1
A testFormSecuredMultipleSelect() 0 13 1
A testFormSecuredRadio() 9 9 1
A testFormSecuredAndDisabledNotAssoc() 0 15 1
A testFormSecuredAndDisabled() 0 21 1
A testDisableSecurityUsingForm() 0 21 1
A testUnlockFieldAddsToList() 0 12 1
A testUnlockFieldRemovingFromFields() 0 16 1
A testTagIsInvalid() 0 16 1
A testTagIsInvalidSaveMany() 0 14 1
B testPasswordValidation() 0 35 1
B testEmptyErrorValidation() 0 34 1
B testEmptyInputErrorValidation() 0 34 1
B testFormValidationAssociated() 0 33 1
B testFormValidationAssociatedFirstLevel() 0 42 1
A testFormValidationAssociatedSecondLevel() 0 50 1
A testFormValidationMultiRecord() 0 22 1
A testMultipleInputValidation() 0 69 1
B testInput() 0 296 1
A testInputZero() 0 11 1
A testInputCheckbox() 0 50 1
A testInputTime() 0 55 1
A testTimeSelectedWithInterval() 0 49 1
B testTimeSelectedWithIntervalTwelve() 0 31 1
A testInputTimeWithIntervalAnd12HourFormat() 0 51 1
B testInputDatetime() 0 82 1
A testInputCheckboxesInLoop() 0 15 2
B testInputCheckboxWithDisabledElements() 0 93 1
A testInputWithLeadingInteger() 0 7 1
B testInputSelectType() 0 166 1
A testInputWithNonStandardPrimaryKeyMakesHidden() 0 17 1
B testInputOverridingMagicSelectType() 0 25 1
A testInputMagicTypeDoesNotOverride() 22 22 1
B testInputMagicSelectForTypeNumber() 0 24 1
A testInputMagicSelectChangeToRadio() 0 5 1
A testInputWithMatchingFieldAndModelName() 0 21 1
B testFormInputs() 0 234 1
A testInputsPluginModel() 0 19 1
B testSelectAsCheckbox() 0 37 1
B testLabel() 0 27 1
B testTextbox() 0 27 1
A testDefaultValue() 0 9 1
A testCheckboxDefaultValue() 0 17 1
B testError() 0 97 1
A testInputErrorEscape() 0 10 1
A testPassword() 0 10 1
B testRadio() 0 179 1
B testRadioDifferentModel() 0 26 1
B testRadioBetween() 0 146 1
A testRadioOptionWithBooleanishValues() 0 74 1
B testRadioDisabled() 0 139 1
B testRadioHiddenInputDisabling() 0 26 1
A testRadioAddEmptyOption() 0 59 1
A testRadioLabelArray() 0 14 1
A testRadioWithCreate() 0 15 1
A testDomIdSuffix() 0 13 1
A testDomIdSuffixCollisionResolvement() 0 19 1
B testSelect() 0 161 1
B testSelectOptionGroupEscaping() 0 35 1
A testSelectWithNullAttributes() 0 14 1
A testNestedSelect() 0 54 1
B testSelectMultiple() 0 173 1
B testSelectMultipleWithDisabledElements() 0 89 1
B testSelectWithDisabledElements() 0 82 1
B testHabtmSelectBox() 0 84 1
B testSelectMultipleCheckboxes() 0 208 1
A testSelectMultipleCheckboxDiv() 0 74 1
A testSelectMultipleCheckboxSecurity() 0 14 1
A testSelectMultipleSecureWithNoOptions() 11 11 1
A testSelectNoSecureWithNoOptions() 0 17 1
B testInputMultipleCheckboxes() 0 99 1
A testSelectHiddenFieldOmission() 0 47 1
A testSelectCheckboxMultipleOverrideName() 0 22 1
B testSelectCheckboxMultipleId() 0 41 1
B testCheckbox() 0 82 1
A testCheckboxCustomNameAttribute() 0 8 1
B testCheckboxCheckedOption() 0 37 1
A testCheckboxDisabling() 0 15 1
B testCheckboxHiddenField() 0 40 1
A testCheckboxZeroValue() 23 23 1
B testDateTime() 0 353 1
A testDateTimeRounding() 0 21 1
A testDateTimeNoErrorsOnEmptyData() 0 14 1
A testDatetimeWithDefault() 0 13 1
A testDateTimeWithBogusData() 0 4 1
A testDateTimeAllZeros() 0 13 1
B testDateTimeEmptyAsArray() 0 33 1
B testFormDateTimeMulti() 0 81 1
A testDateTimeLabelIdMatchesFirstInput() 0 10 1
B testMonth() 0 97 1
B testDay() 0 121 1
B testMinute() 0 105 1
B testHour() 0 109 1
B testYear() 0 192 1
B testYearAutoExpandRange() 0 25 1
A testInputDate() 0 54 1
A testInputDateMaxYear() 0 15 1
B testTextArea() 0 43 1
A testTextAreaWithStupidCharacters() 0 17 1
A testHiddenField() 0 9 1
A testFileUploadField() 0 20 1
A testFileUploadOnOtherModel() 0 8 1
A testButton() 0 19 1
A testButtonUnlockedByDefault() 8 8 1
A testPostButton() 0 16 1
A testPostButtonNestedData() 13 13 1
A testSecurePostButton() 0 23 1
B testPostLink() 0 86 1
B testPostLinkSecurityHash() 0 28 1
A testPostLinkNestedData() 13 13 1
A testPostLinkAfterGetForm() 0 23 1
A testSecurePostLink() 0 22 1
B testSubmitButton() 0 91 1
A testSubmitImage() 0 73 1
A testSubmitUnlockedByDefault() 8 8 1
A testSubmitImageTimestamp() 0 11 1
B testCreate() 0 169 1
B testCreateOnSubmit() 0 38 1
B testCreateAutoUrl() 0 31 1
A testCreateCustomRoute() 0 16 1
B testCreateWithInputDefaults() 0 46 1
A testCreateWithAcceptCharset() 0 16 1
B testCreateQuerystringrequest() 0 45 1
A testCreateWithMultipleIdInData() 0 18 1
B testCreatePassedArgs() 0 24 1
A testCreateNoErrorsWithMockModel() 0 14 1
B testGetFormCreate() 0 24 1
A testGetFormWithFalseModel() 0 17 1
A testDateTimeWithGetForms() 0 12 1
B testEditFormWithData() 0 28 1
B testFormInputRequiredDetection() 0 224 1
A testFormInputRequiredDetectionModelValidator() 0 20 1
B testFormMagicInput() 0 165 1
A testForMagicInputNonExistingNorValidated() 0 55 1
B testFormMagicInputLabel() 0 116 1
B testFormEnd() 0 77 1
A testMultipleFormWithIdFields() 0 20 1
B testDbLessModel() 0 33 1
B testBrokenness() 0 80 1
B testMultiRecordForm() 0 77 1
A testMultiRecordFormValidationErrors() 0 14 1
A testSaveManyRecordFormValidationErrors() 0 12 1
B testInputTemplate() 0 92 1
B testHtml5Inputs() 0 31 1
A testHtml5InputException() 0 3 1
A testIntrospectModelFromRequest() 0 16 1
A testCustomValidationErrors() 0 5 1
B testRequiredOnCreate() 0 82 1
A testRequiredOnUpdate() 0 62 1
A testInputDefaults() 0 55 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like FormHelperTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use FormHelperTest, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * FormHelperTest file
4
 *
5
 * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
6
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
7
 *
8
 * Licensed under The MIT License
9
 * For full copyright and license information, please see the LICENSE.txt
10
 * Redistributions of files must retain the above copyright notice
11
 *
12
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
13
 * @link          http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
14
 * @package       Cake.Test.Case.View.Helper
15
 * @since         CakePHP(tm) v 1.2.0.4206
16
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
 */
18
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
/**
30
 * ContactTestController class
31
 *
32
 * @package       Cake.Test.Case.View.Helper
33
 */
34
class ContactTestController extends Controller {
35
36
/**
37
 * uses property
38
 *
39
 * @var mixed null
40
 */
41
	public $uses = null;
42
}
43
44
/**
45
 * Contact class
46
 *
47
 * @package       Cake.Test.Case.View.Helper
48
 */
49
class Contact extends CakeTestModel {
50
51
/**
52
 * useTable property
53
 *
54
 * @var boolean
55
 */
56
	public $useTable = false;
57
58
/**
59
 * Default schema
60
 *
61
 * @var array
62
 */
63
	protected $_schema = array(
64
		'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
65
		'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
66
		'email' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
67
		'phone' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
68
		'password' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
69
		'published' => array('type' => 'date', 'null' => true, 'default' => null, 'length' => null),
70
		'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
71
		'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null),
72
		'age' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => null)
73
	);
74
75
/**
76
 * validate property
77
 *
78
 * @var array
79
 */
80
	public $validate = array(
81
		'non_existing' => array(),
82
		'idontexist' => array(),
83
		'imrequired' => array('rule' => array('between', 5, 30), 'allowEmpty' => false),
84
		'imrequiredonupdate' => array('notEmpty' => array('rule' => 'alphaNumeric', 'on' => 'update')),
85
		'imrequiredoncreate' => array('required' => array('rule' => 'alphaNumeric', 'on' => 'create')),
86
		'imrequiredonboth' => array(
87
			'required' => array('rule' => 'alphaNumeric'),
88
		),
89
		'string_required' => 'notEmpty',
90
		'imalsorequired' => array('rule' => 'alphaNumeric', 'allowEmpty' => false),
91
		'imrequiredtoo' => array('rule' => 'notEmpty'),
92
		'required_one' => array('required' => array('rule' => array('notEmpty'))),
93
		'imnotrequired' => array('required' => false, 'rule' => 'alphaNumeric', 'allowEmpty' => true),
94
		'imalsonotrequired' => array(
95
			'alpha' => array('rule' => 'alphaNumeric', 'allowEmpty' => true),
96
			'between' => array('rule' => array('between', 5, 30)),
97
		),
98
		'imalsonotrequired2' => array(
99
			'alpha' => array('rule' => 'alphaNumeric', 'allowEmpty' => true),
100
			'between' => array('rule' => array('between', 5, 30), 'allowEmpty' => true),
101
		),
102
		'imnotrequiredeither' => array('required' => true, 'rule' => array('between', 5, 30), 'allowEmpty' => true),
103
		'iamrequiredalways' => array(
104
			'email' => array('rule' => 'email'),
105
			'rule_on_create' => array('rule' => array('maxLength', 50), 'on' => 'create'),
106
			'rule_on_update' => array('rule' => array('between', 1, 50), 'on' => 'update'),
107
		),
108
		'boolean_field' => array('rule' => 'boolean')
109
	);
110
111
/**
112
 * schema method
113
 *
114
 * @return void
115
 */
116
	public function setSchema($schema) {
117
		$this->_schema = $schema;
118
	}
119
120
/**
121
 * hasAndBelongsToMany property
122
 *
123
 * @var array
124
 */
125
	public $hasAndBelongsToMany = array('ContactTag' => array('with' => 'ContactTagsContact'));
126
127
/**
128
 * hasAndBelongsToMany property
129
 *
130
 * @var array
131
 */
132
	public $belongsTo = array('User' => array('className' => 'UserForm'));
133
}
134
135
/**
136
 * ContactTagsContact class
137
 *
138
 * @package       Cake.Test.Case.View.Helper
139
 */
140
class ContactTagsContact extends CakeTestModel {
141
142
/**
143
 * useTable property
144
 *
145
 * @var boolean
146
 */
147
	public $useTable = false;
148
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
/**
162
 * schema method
163
 *
164
 * @return void
165
 */
166
	public function setSchema($schema) {
167
		$this->_schema = $schema;
168
	}
169
170
}
171
172
/**
173
 * ContactNonStandardPk class
174
 *
175
 * @package       Cake.Test.Case.View.Helper
176
 */
177
class ContactNonStandardPk extends Contact {
178
179
/**
180
 * primaryKey property
181
 *
182
 * @var string
183
 */
184
	public $primaryKey = 'pk';
185
186
/**
187
 * schema method
188
 *
189
 * @return void
190
 */
191
	public function schema($field = false) {
192
		$this->_schema = parent::schema();
193
		$this->_schema['pk'] = $this->_schema['id'];
194
		unset($this->_schema['id']);
195
		return $this->_schema;
196
	}
197
198
}
199
200
/**
201
 * ContactTag class
202
 *
203
 * @package       Cake.Test.Case.View.Helper
204
 */
205
class ContactTag extends Model {
206
207
/**
208
 * useTable property
209
 *
210
 * @var boolean
211
 */
212
	public $useTable = false;
213
214
/**
215
 * schema definition
216
 *
217
 * @var array
218
 */
219
	protected $_schema = array(
220
		'id' => array('type' => 'integer', 'null' => false, 'default' => '', 'length' => '8'),
221
		'name' => array('type' => 'string', 'null' => false, 'default' => '', 'length' => '255'),
222
		'created' => array('type' => 'date', 'null' => true, 'default' => '', 'length' => ''),
223
		'modified' => array('type' => 'datetime', 'null' => true, 'default' => '', 'length' => null)
224
	);
225
}
226
227
/**
228
 * UserForm class
229
 *
230
 * @package       Cake.Test.Case.View.Helper
231
 */
232
class UserForm extends CakeTestModel {
233
234
/**
235
 * useTable property
236
 *
237
 * @var boolean
238
 */
239
	public $useTable = false;
240
241
/**
242
 * hasMany property
243
 *
244
 * @var array
245
 */
246
	public $hasMany = array(
247
		'OpenidUrl' => array('className' => 'OpenidUrl', 'foreignKey' => 'user_form_id'
248
	));
249
250
/**
251
 * schema definition
252
 *
253
 * @var array
254
 */
255
	protected $_schema = array(
256
		'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
257
		'published' => array('type' => 'date', 'null' => true, 'default' => null, 'length' => null),
258
		'other' => array('type' => 'text', 'null' => true, 'default' => null, 'length' => null),
259
		'stuff' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 10),
260
		'something' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 255),
261
		'active' => array('type' => 'boolean', 'null' => false, 'default' => false),
262
		'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
263
		'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
264
	);
265
}
266
267
/**
268
 * OpenidUrl class
269
 *
270
 * @package       Cake.Test.Case.View.Helper
271
 */
272
class OpenidUrl extends CakeTestModel {
273
274
/**
275
 * useTable property
276
 *
277
 * @var boolean
278
 */
279
	public $useTable = false;
280
281
/**
282
 * belongsTo property
283
 *
284
 * @var array
285
 */
286
	public $belongsTo = array('UserForm' => array(
287
		'className' => 'UserForm', 'foreignKey' => 'user_form_id'
288
	));
289
290
/**
291
 * validate property
292
 *
293
 * @var array
294
 */
295
	public $validate = array('openid_not_registered' => array());
296
297
/**
298
 * schema method
299
 *
300
 * @var array
301
 */
302
	protected $_schema = array(
303
		'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
304
		'user_form_id' => array(
305
			'type' => 'user_form_id', 'null' => '', 'default' => '', 'length' => '8'
306
		),
307
		'url' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
308
	);
309
310
/**
311
 * beforeValidate method
312
 *
313
 * @return void
314
 */
315
	public function beforeValidate($options = array()) {
316
		$this->invalidate('openid_not_registered');
317
		return true;
318
	}
319
320
}
321
322
/**
323
 * ValidateUser class
324
 *
325
 * @package       Cake.Test.Case.View.Helper
326
 */
327 View Code Duplication
class ValidateUser extends CakeTestModel {
0 ignored issues
show
Duplication introduced by
This class seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
328
329
/**
330
 * useTable property
331
 *
332
 * @var boolean
333
 */
334
	public $useTable = false;
335
336
/**
337
 * hasOne property
338
 *
339
 * @var array
340
 */
341
	public $hasOne = array('ValidateProfile' => array(
342
		'className' => 'ValidateProfile', 'foreignKey' => 'user_id'
343
	));
344
345
/**
346
 * schema method
347
 *
348
 * @var array
349
 */
350
	protected $_schema = array(
351
		'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
352
		'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
353
		'email' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
354
		'balance' => array('type' => 'float', 'null' => false, 'length' => '5,2'),
355
		'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
356
		'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
357
	);
358
359
/**
360
 * beforeValidate method
361
 *
362
 * @return void
363
 */
364
	public function beforeValidate($options = array()) {
365
		$this->invalidate('email');
366
		return false;
367
	}
368
369
}
370
371
/**
372
 * ValidateProfile class
373
 *
374
 * @package       Cake.Test.Case.View.Helper
375
 */
376
class ValidateProfile extends CakeTestModel {
377
378
/**
379
 * useTable property
380
 *
381
 * @var boolean
382
 */
383
	public $useTable = false;
384
385
/**
386
 * schema property
387
 *
388
 * @var array
389
 */
390
	protected $_schema = array(
391
		'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
392
		'user_id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
393
		'full_name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
394
		'city' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
395
		'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
396
		'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
397
	);
398
399
/**
400
 * hasOne property
401
 *
402
 * @var array
403
 */
404
	public $hasOne = array('ValidateItem' => array(
405
		'className' => 'ValidateItem', 'foreignKey' => 'profile_id'
406
	));
407
408
/**
409
 * belongsTo property
410
 *
411
 * @var array
412
 */
413
	public $belongsTo = array('ValidateUser' => array(
414
		'className' => 'ValidateUser', 'foreignKey' => 'user_id'
415
	));
416
417
/**
418
 * beforeValidate method
419
 *
420
 * @return void
421
 */
422
	public function beforeValidate($options = array()) {
423
		$this->invalidate('full_name');
424
		$this->invalidate('city');
425
		return false;
426
	}
427
428
}
429
430
/**
431
 * ValidateItem class
432
 *
433
 * @package       Cake.Test.Case.View.Helper
434
 */
435 View Code Duplication
class ValidateItem extends CakeTestModel {
0 ignored issues
show
Duplication introduced by
This class seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
436
437
/**
438
 * useTable property
439
 *
440
 * @var boolean
441
 */
442
	public $useTable = false;
443
444
/**
445
 * schema property
446
 *
447
 * @var array
448
 */
449
	protected $_schema = array(
450
		'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
451
		'profile_id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
452
		'name' => array('type' => 'text', 'null' => '', 'default' => '', 'length' => '255'),
453
		'description' => array(
454
			'type' => 'string', 'null' => '', 'default' => '', 'length' => '255'
455
		),
456
		'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
457
		'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
458
	);
459
460
/**
461
 * belongsTo property
462
 *
463
 * @var array
464
 */
465
	public $belongsTo = array('ValidateProfile' => array('foreignKey' => 'profile_id'));
466
467
/**
468
 * beforeValidate method
469
 *
470
 * @return void
471
 */
472
	public function beforeValidate($options = array()) {
473
		$this->invalidate('description');
474
		return false;
475
	}
476
477
}
478
479
/**
480
 * TestMail class
481
 *
482
 * @package       Cake.Test.Case.View.Helper
483
 */
484
class TestMail extends CakeTestModel {
485
486
/**
487
 * useTable property
488
 *
489
 * @var boolean
490
 */
491
	public $useTable = false;
492
493
}
494
495
/**
496
 * FormHelperTest class
497
 *
498
 * @package       Cake.Test.Case.View.Helper
499
 * @property FormHelper $Form
500
 */
501
class FormHelperTest extends CakeTestCase {
502
503
/**
504
 * Fixtures to be used
505
 *
506
 * @var array
507
 */
508
	public $fixtures = array('core.post');
509
510
/**
511
 * Do not load the fixtures by default
512
 *
513
 * @var boolean
514
 */
515
	public $autoFixtures = false;
516
517
/**
518
 * setUp method
519
 *
520
 * @return void
521
 */
522
	public function setUp() {
523
		parent::setUp();
524
525
		Configure::write('Config.language', 'eng');
526
		Configure::write('App.base', '');
527
		Configure::delete('Asset');
528
		$this->Controller = new ContactTestController();
529
		$this->View = new View($this->Controller);
530
531
		$this->Form = new FormHelper($this->View);
532
		$this->Form->Html = new HtmlHelper($this->View);
533
		$this->Form->request = new CakeRequest('contacts/add', false);
534
		$this->Form->request->here = '/contacts/add';
535
		$this->Form->request['action'] = 'add';
536
		$this->Form->request->webroot = '';
537
		$this->Form->request->base = '';
538
539
		ClassRegistry::addObject('Contact', new Contact());
540
		ClassRegistry::addObject('ContactNonStandardPk', new ContactNonStandardPk());
541
		ClassRegistry::addObject('OpenidUrl', new OpenidUrl());
542
		ClassRegistry::addObject('User', new UserForm());
543
		ClassRegistry::addObject('ValidateItem', new ValidateItem());
544
		ClassRegistry::addObject('ValidateUser', new ValidateUser());
545
		ClassRegistry::addObject('ValidateProfile', new ValidateProfile());
546
547
		$this->oldSalt = Configure::read('Security.salt');
548
549
		$this->dateRegex = array(
550
			'daysRegex' => 'preg:/(?:<option value="0?([\d]+)">\\1<\/option>[\r\n]*)*/',
551
			'monthsRegex' => 'preg:/(?:<option value="[\d]+">[\w]+<\/option>[\r\n]*)*/',
552
			'yearsRegex' => 'preg:/(?:<option value="([\d]+)">\\1<\/option>[\r\n]*)*/',
553
			'hoursRegex' => 'preg:/(?:<option value="0?([\d]+)">\\1<\/option>[\r\n]*)*/',
554
			'minutesRegex' => 'preg:/(?:<option value="([\d]+)">0?\\1<\/option>[\r\n]*)*/',
555
			'meridianRegex' => 'preg:/(?:<option value="(am|pm)">\\1<\/option>[\r\n]*)*/',
556
		);
557
558
		Configure::write('Security.salt', 'foo!');
559
	}
560
561
/**
562
 * tearDown method
563
 *
564
 * @return void
565
 */
566
	public function tearDown() {
567
		parent::tearDown();
568
		unset($this->Form->Html, $this->Form, $this->Controller, $this->View);
569
		Configure::write('Security.salt', $this->oldSalt);
570
	}
571
572
/**
573
 * testFormCreateWithSecurity method
574
 *
575
 * Test form->create() with security key.
576
 *
577
 * @return void
578
 */
579
	public function testCreateWithSecurity() {
580
		$this->Form->request['_Token'] = array('key' => 'testKey');
581
		$encoding = strtolower(Configure::read('App.encoding'));
582
		$result = $this->Form->create('Contact', array('url' => '/contacts/add'));
583
		$expected = array(
584
			'form' => array('method' => 'post', 'action' => '/contacts/add', 'accept-charset' => $encoding, 'id' => 'ContactAddForm'),
585
			'div' => array('style' => 'display:none;'),
586
			array('input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST')),
587
			array('input' => array(
588
				'type' => 'hidden', 'name' => 'data[_Token][key]', 'value' => 'testKey', 'id'
589
			)),
590
			'/div'
591
		);
592
		$this->assertTags($result, $expected);
593
594
		$result = $this->Form->create('Contact', array('url' => '/contacts/add', 'id' => 'MyForm'));
595
		$expected['form']['id'] = 'MyForm';
596
		$this->assertTags($result, $expected);
597
	}
598
599
/**
600
 * testFormCreateGetNoSecurity method
601
 *
602
 * Test form->create() with no security key as its a get form
603
 *
604
 * @return void
605
 */
606
	public function testCreateEndGetNoSecurity() {
607
		$this->Form->request['_Token'] = array('key' => 'testKey');
608
		$encoding = strtolower(Configure::read('App.encoding'));
609
		$result = $this->Form->create('Contact', array('type' => 'get', 'url' => '/contacts/add'));
610
		$this->assertNotContains('Token', $result);
611
612
		$result = $this->Form->end('Save');
613
		$this->assertNotContains('Token', $result);
614
	}
615
616
/**
617
 * test that create() clears the fields property so it starts fresh
618
 *
619
 * @return void
620
 */
621
	public function testCreateClearingFields() {
622
		$this->Form->fields = array('model_id');
623
		$this->Form->create('Contact');
624
		$this->assertEquals(array(), $this->Form->fields);
625
	}
626
627
/**
628
 * Tests form hash generation with model-less data
629
 *
630
 * @return void
631
 */
632
	public function testValidateHashNoModel() {
633
		$this->Form->request['_Token'] = array('key' => 'foo');
634
		$result = $this->Form->secure(array('anything'));
635
		$this->assertRegExp('/540ac9c60d323c22bafe997b72c0790f39a8bdef/', $result);
636
	}
637
638
/**
639
 * Tests that models with identical field names get resolved properly
640
 *
641
 * @return void
642
 */
643
	public function testDuplicateFieldNameResolution() {
644
		$result = $this->Form->create('ValidateUser');
645
		$this->assertEquals(array('ValidateUser'), $this->Form->entity());
646
647
		$result = $this->Form->input('ValidateItem.name');
648
		$this->assertEquals(array('ValidateItem', 'name'), $this->Form->entity());
649
650
		$result = $this->Form->input('ValidateUser.name');
651
		$this->assertEquals(array('ValidateUser', 'name'), $this->Form->entity());
652
		$this->assertRegExp('/name="data\[ValidateUser\]\[name\]"/', $result);
653
		$this->assertRegExp('/type="text"/', $result);
654
655
		$result = $this->Form->input('ValidateItem.name');
656
		$this->assertEquals(array('ValidateItem', 'name'), $this->Form->entity());
657
		$this->assertRegExp('/name="data\[ValidateItem\]\[name\]"/', $result);
658
		$this->assertRegExp('/<textarea/', $result);
659
660
		$result = $this->Form->input('name');
661
		$this->assertEquals(array('ValidateUser', 'name'), $this->Form->entity());
662
		$this->assertRegExp('/name="data\[ValidateUser\]\[name\]"/', $result);
663
		$this->assertRegExp('/type="text"/', $result);
664
	}
665
666
/**
667
 * Tests that hidden fields generated for checkboxes don't get locked
668
 *
669
 * @return void
670
 */
671 View Code Duplication
	public function testNoCheckboxLocking() {
672
		$this->Form->request['_Token'] = array('key' => 'foo');
673
		$this->assertSame(array(), $this->Form->fields);
674
675
		$this->Form->checkbox('check', array('value' => '1'));
676
		$this->assertSame($this->Form->fields, array('check'));
677
	}
678
679
/**
680
 * testFormSecurityFields method
681
 *
682
 * Test generation of secure form hash generation.
683
 *
684
 * @return void
685
 */
686
	public function testFormSecurityFields() {
687
		$key = 'testKey';
688
		$fields = array('Model.password', 'Model.username', 'Model.valid' => '0');
689
690
		$this->Form->request['_Token'] = array('key' => $key);
691
		$result = $this->Form->secure($fields);
692
693
		$hash = Security::hash(serialize($fields) . Configure::read('Security.salt'));
694
		$hash .= ':' . 'Model.valid';
695
		$hash = urlencode($hash);
696
697
		$expected = array(
698
			'div' => array('style' => 'display:none;'),
699
			array('input' => array(
700
				'type' => 'hidden', 'name' => 'data[_Token][fields]',
701
				'value' => $hash, 'id' => 'preg:/TokenFields\d+/'
702
			)),
703
			array('input' => array(
704
				'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
705
				'value' => '', 'id' => 'preg:/TokenUnlocked\d+/'
706
			)),
707
			'/div'
708
		);
709
		$this->assertTags($result, $expected);
710
711
		$path = CAKE . 'Test' . DS . 'test_app' . DS . 'Config' . DS;
712
		$this->Form->Html->loadConfig('htmlhelper_tags', $path);
713
		$result = $this->Form->secure($fields);
714
		$expected = array(
715
			'div' => array('class' => 'hidden'),
716
			array('input' => array(
717
				'type' => 'hidden', 'name' => 'data[_Token][fields]',
718
				'value' => $hash, 'id' => 'preg:/TokenFields\d+/'
719
			)),
720
			array('input' => array(
721
				'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
722
				'value' => '', 'id' => 'preg:/TokenUnlocked\d+/'
723
			)),
724
			'/div'
725
		);
726
		$this->assertTags($result, $expected);
727
	}
728
729
/**
730
 * Tests correct generation of number fields for double and float fields
731
 *
732
 * @return void
733
 */
734
	public function testTextFieldGenerationForFloats() {
735
		$model = ClassRegistry::getObject('Contact');
736
		$model->setSchema(array('foo' => array(
737
			'type' => 'float',
738
			'null' => false,
739
			'default' => null,
740
			'length' => 10
741
		)));
742
743
		$this->Form->create('Contact');
744
		$result = $this->Form->input('foo');
745
		$expected = array(
746
			'div' => array('class' => 'input number'),
747
			'label' => array('for' => 'ContactFoo'),
748
			'Foo',
749
			'/label',
750
			array('input' => array(
751
				'type' => 'number',
752
				'name' => 'data[Contact][foo]',
753
				'id' => 'ContactFoo',
754
				'step' => 'any'
755
			)),
756
			'/div'
757
		);
758
		$this->assertTags($result, $expected);
759
760
		$result = $this->Form->input('foo', array('step' => 0.5));
761
		$expected = array(
762
			'div' => array('class' => 'input number'),
763
			'label' => array('for' => 'ContactFoo'),
764
			'Foo',
765
			'/label',
766
			array('input' => array(
767
				'type' => 'number',
768
				'name' => 'data[Contact][foo]',
769
				'id' => 'ContactFoo',
770
				'step' => '0.5'
771
			)),
772
			'/div'
773
		);
774
		$this->assertTags($result, $expected);
775
	}
776
777
/**
778
 * Tests correct generation of number fields for integer fields
779
 *
780
 * @return void
781
 */
782
	public function testTextFieldTypeNumberGenerationForIntegers() {
783
		$model = ClassRegistry::getObject('Contact');
784
		$model->setSchema(array('foo' => array(
785
			'type' => 'integer',
786
			'null' => false,
787
			'default' => null,
788
			'length' => null
789
		)));
790
791
		$this->Form->create('Contact');
792
		$result = $this->Form->input('foo');
793
		$expected = array(
794
			'div' => array('class' => 'input number'),
795
			'label' => array('for' => 'ContactFoo'),
796
			'Foo',
797
			'/label',
798
			array('input' => array(
799
				'type' => 'number', 'name' => 'data[Contact][foo]',
800
				'id' => 'ContactFoo'
801
			)),
802
			'/div'
803
		);
804
		$this->assertTags($result, $expected);
805
	}
806
807
/**
808
 * testFormSecurityMultipleFields method
809
 *
810
 * Test secure() with multiple row form. Ensure hash is correct.
811
 *
812
 * @return void
813
 */
814
	public function testFormSecurityMultipleFields() {
815
		$key = 'testKey';
816
817
		$fields = array(
818
			'Model.0.password', 'Model.0.username', 'Model.0.hidden' => 'value',
819
			'Model.0.valid' => '0', 'Model.1.password', 'Model.1.username',
820
			'Model.1.hidden' => 'value', 'Model.1.valid' => '0'
821
		);
822
		$this->Form->request['_Token'] = array('key' => $key);
823
		$result = $this->Form->secure($fields);
824
825
		$hash = '51e3b55a6edd82020b3f29c9ae200e14bbeb7ee5%3AModel.0.hidden%7CModel.0.valid';
826
		$hash .= '%7CModel.1.hidden%7CModel.1.valid';
827
828
		$expected = array(
829
			'div' => array('style' => 'display:none;'),
830
			array('input' => array(
831
				'type' => 'hidden', 'name' => 'data[_Token][fields]',
832
				'value' => $hash, 'id' => 'preg:/TokenFields\d+/'
833
			)),
834
			array('input' => array(
835
				'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
836
				'value' => '', 'id' => 'preg:/TokenUnlocked\d+/'
837
			)),
838
			'/div'
839
		);
840
		$this->assertTags($result, $expected);
841
	}
842
843
/**
844
 * testFormSecurityMultipleSubmitButtons
845
 *
846
 * test form submit generation and ensure that _Token is only created on end()
847
 *
848
 * @return void
849
 */
850
	public function testFormSecurityMultipleSubmitButtons() {
851
		$key = 'testKey';
852
		$this->Form->request['_Token'] = array('key' => $key);
853
854
		$this->Form->create('Addresses');
855
		$this->Form->input('Address.title');
856
		$this->Form->input('Address.first_name');
857
858
		$result = $this->Form->submit('Save', array('name' => 'save'));
859
		$expected = array(
860
			'div' => array('class' => 'submit'),
861
			'input' => array('type' => 'submit', 'name' => 'save', 'value' => 'Save'),
862
			'/div',
863
		);
864
		$this->assertTags($result, $expected);
865
866
		$result = $this->Form->submit('Cancel', array('name' => 'cancel'));
867
		$expected = array(
868
			'div' => array('class' => 'submit'),
869
			'input' => array('type' => 'submit', 'name' => 'cancel', 'value' => 'Cancel'),
870
			'/div',
871
		);
872
		$this->assertTags($result, $expected);
873
		$result = $this->Form->end(null);
874
875
		$expected = array(
876
			'div' => array('style' => 'display:none;'),
877
			array('input' => array(
878
				'type' => 'hidden', 'name' => 'data[_Token][fields]',
879
				'value' => 'preg:/.+/', 'id' => 'preg:/TokenFields\d+/'
880
			)),
881
			array('input' => array(
882
				'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
883
				'value' => 'cancel%7Csave', 'id' => 'preg:/TokenUnlocked\d+/'
884
			)),
885
			'/div'
886
		);
887
		$this->assertTags($result, $expected);
888
	}
889
890
/**
891
 * Test that buttons created with foo[bar] name attributes are unlocked correctly.
892
 *
893
 * @return void
894
 */
895 View Code Duplication
	public function testSecurityButtonNestedNamed() {
896
		$key = 'testKey';
897
		$this->Form->request['_Token'] = array('key' => $key);
898
899
		$this->Form->create('Addresses');
900
		$this->Form->button('Test', array('type' => 'submit', 'name' => 'Address[button]'));
901
		$result = $this->Form->unlockField();
902
		$this->assertEquals(array('Address.button'), $result);
903
	}
904
905
/**
906
 * Test that submit inputs created with foo[bar] name attributes are unlocked correctly.
907
 *
908
 * @return void
909
 */
910 View Code Duplication
	public function testSecuritySubmitNestedNamed() {
911
		$key = 'testKey';
912
		$this->Form->request['_Token'] = array('key' => $key);
913
914
		$this->Form->create('Addresses');
915
		$this->Form->submit('Test', array('type' => 'submit', 'name' => 'Address[button]'));
916
		$result = $this->Form->unlockField();
917
		$this->assertEquals(array('Address.button'), $result);
918
	}
919
920
/**
921
 * Test that the correct fields are unlocked for image submits with no names.
922
 *
923
 * @return void
924
 */
925
	public function testSecuritySubmitImageNoName() {
926
		$key = 'testKey';
927
		$this->Form->request['_Token'] = array('key' => $key);
928
929
		$this->Form->create('User');
930
		$result = $this->Form->submit('save.png');
931
		$expected = array(
932
			'div' => array('class' => 'submit'),
933
			'input' => array('type' => 'image', 'src' => 'img/save.png'),
934
			'/div'
935
		);
936
		$this->assertTags($result, $expected);
937
		$this->assertEquals(array('x', 'y'), $this->Form->unlockField());
938
	}
939
940
/**
941
 * Test that the correct fields are unlocked for image submits with names.
942
 *
943
 * @return void
944
 */
945
	public function testSecuritySubmitImageName() {
946
		$key = 'testKey';
947
		$this->Form->request['_Token'] = array('key' => $key);
948
949
		$this->Form->create('User');
950
		$result = $this->Form->submit('save.png', array('name' => 'test'));
951
		$expected = array(
952
			'div' => array('class' => 'submit'),
953
			'input' => array('type' => 'image', 'name' => 'test', 'src' => 'img/save.png'),
954
			'/div'
955
		);
956
		$this->assertTags($result, $expected);
957
		$this->assertEquals(array('test', 'test_x', 'test_y'), $this->Form->unlockField());
958
	}
959
960
/**
961
 * testFormSecurityMultipleInputFields method
962
 *
963
 * Test secure form creation with multiple row creation. Checks hidden, text, checkbox field types
964
 *
965
 * @return void
966
 */
967
	public function testFormSecurityMultipleInputFields() {
968
		$key = 'testKey';
969
970
		$this->Form->request['_Token'] = array('key' => $key);
971
		$this->Form->create('Addresses');
972
973
		$this->Form->hidden('Addresses.0.id', array('value' => '123456'));
974
		$this->Form->input('Addresses.0.title');
975
		$this->Form->input('Addresses.0.first_name');
976
		$this->Form->input('Addresses.0.last_name');
977
		$this->Form->input('Addresses.0.address');
978
		$this->Form->input('Addresses.0.city');
979
		$this->Form->input('Addresses.0.phone');
980
		$this->Form->input('Addresses.0.primary', array('type' => 'checkbox'));
981
982
		$this->Form->hidden('Addresses.1.id', array('value' => '654321'));
983
		$this->Form->input('Addresses.1.title');
984
		$this->Form->input('Addresses.1.first_name');
985
		$this->Form->input('Addresses.1.last_name');
986
		$this->Form->input('Addresses.1.address');
987
		$this->Form->input('Addresses.1.city');
988
		$this->Form->input('Addresses.1.phone');
989
		$this->Form->input('Addresses.1.primary', array('type' => 'checkbox'));
990
991
		$result = $this->Form->secure($this->Form->fields);
992
993
		$hash = 'a3b9b2ba1cb688838f92818a5970e17dd7943a78%3AAddresses.0.id%7CAddresses.1.id';
994
995
		$expected = array(
996
			'div' => array('style' => 'display:none;'),
997
			array('input' => array(
998
				'type' => 'hidden', 'name' => 'data[_Token][fields]',
999
				'value' => $hash, 'id' => 'preg:/TokenFields\d+/'
1000
			)),
1001
			array('input' => array(
1002
				'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
1003
				'value' => '', 'id' => 'preg:/TokenUnlocked\d+/'
1004
			)),
1005
			'/div'
1006
		);
1007
		$this->assertTags($result, $expected);
1008
	}
1009
1010
/**
1011
 * Test form security with Model.field.0 style inputs
1012
 *
1013
 * @return void
1014
 */
1015
	public function testFormSecurityArrayFields() {
1016
		$key = 'testKey';
1017
1018
		$this->Form->request->params['_Token']['key'] = $key;
1019
		$this->Form->create('Address');
1020
		$this->Form->input('Address.primary.1');
1021
		$this->assertEquals('Address.primary', $this->Form->fields[0]);
1022
1023
		$this->Form->input('Address.secondary.1.0');
1024
		$this->assertEquals('Address.secondary', $this->Form->fields[1]);
1025
	}
1026
1027
/**
1028
 * testFormSecurityMultipleInputDisabledFields method
1029
 *
1030
 * test secure form generation with multiple records and disabled fields.
1031
 *
1032
 * @return void
1033
 */
1034
	public function testFormSecurityMultipleInputDisabledFields() {
1035
		$key = 'testKey';
1036
		$this->Form->request->params['_Token'] = array(
1037
			'key' => $key,
1038
			'unlockedFields' => array('first_name', 'address')
1039
		);
1040
		$this->Form->create();
1041
1042
		$this->Form->hidden('Addresses.0.id', array('value' => '123456'));
1043
		$this->Form->input('Addresses.0.title');
1044
		$this->Form->input('Addresses.0.first_name');
1045
		$this->Form->input('Addresses.0.last_name');
1046
		$this->Form->input('Addresses.0.address');
1047
		$this->Form->input('Addresses.0.city');
1048
		$this->Form->input('Addresses.0.phone');
1049
		$this->Form->hidden('Addresses.1.id', array('value' => '654321'));
1050
		$this->Form->input('Addresses.1.title');
1051
		$this->Form->input('Addresses.1.first_name');
1052
		$this->Form->input('Addresses.1.last_name');
1053
		$this->Form->input('Addresses.1.address');
1054
		$this->Form->input('Addresses.1.city');
1055
		$this->Form->input('Addresses.1.phone');
1056
1057
		$result = $this->Form->secure($this->Form->fields);
1058
		$hash = '5c9cadf9da008cc444d3960b481391a425a5d979%3AAddresses.0.id%7CAddresses.1.id';
1059
1060
		$expected = array(
1061
			'div' => array('style' => 'display:none;'),
1062
			array('input' => array(
1063
				'type' => 'hidden', 'name' => 'data[_Token][fields]',
1064
				'value' => $hash, 'id' => 'preg:/TokenFields\d+/'
1065
			)),
1066
			array('input' => array(
1067
				'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
1068
				'value' => 'address%7Cfirst_name', 'id' => 'preg:/TokenUnlocked\d+/'
1069
			)),
1070
			'/div'
1071
		);
1072
		$this->assertTags($result, $expected);
1073
	}
1074
1075
/**
1076
 * testFormSecurityInputDisabledFields method
1077
 *
1078
 * Test single record form with disabled fields.
1079
 *
1080
 * @return void
1081
 */
1082
	public function testFormSecurityInputUnlockedFields() {
1083
		$key = 'testKey';
1084
		$this->Form->request['_Token'] = array(
1085
			'key' => $key,
1086
			'unlockedFields' => array('first_name', 'address')
1087
		);
1088
		$this->Form->create();
1089
		$this->assertEquals($this->Form->request['_Token']['unlockedFields'], $this->Form->unlockField());
1090
1091
		$this->Form->hidden('Addresses.id', array('value' => '123456'));
1092
		$this->Form->input('Addresses.title');
1093
		$this->Form->input('Addresses.first_name');
1094
		$this->Form->input('Addresses.last_name');
1095
		$this->Form->input('Addresses.address');
1096
		$this->Form->input('Addresses.city');
1097
		$this->Form->input('Addresses.phone');
1098
1099
		$result = $this->Form->fields;
1100
		$expected = array(
1101
			'Addresses.id' => '123456', 'Addresses.title', 'Addresses.last_name',
1102
			'Addresses.city', 'Addresses.phone'
1103
		);
1104
		$this->assertEquals($expected, $result);
1105
1106
		$result = $this->Form->secure($expected);
1107
1108
		$hash = '40289bd07811587887ff56585a8526ff9da59d7a%3AAddresses.id';
1109
		$expected = array(
1110
			'div' => array('style' => 'display:none;'),
1111
			array('input' => array(
1112
				'type' => 'hidden', 'name' => 'data[_Token][fields]',
1113
				'value' => $hash, 'id' => 'preg:/TokenFields\d+/'
1114
			)),
1115
			array('input' => array(
1116
				'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
1117
				'value' => 'address%7Cfirst_name', 'id' => 'preg:/TokenUnlocked\d+/'
1118
			)),
1119
			'/div'
1120
		);
1121
		$this->assertTags($result, $expected);
1122
	}
1123
1124
/**
1125
 * test securing inputs with custom name attributes.
1126
 *
1127
 * @return void
1128
 */
1129
	public function testFormSecureWithCustomNameAttribute() {
1130
		$this->Form->request->params['_Token']['key'] = 'testKey';
1131
1132
		$this->Form->text('UserForm.published', array('name' => 'data[User][custom]'));
0 ignored issues
show
Documentation Bug introduced by
The method text does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1133
		$this->assertEquals('User.custom', $this->Form->fields[0]);
1134
1135
		$this->Form->text('UserForm.published', array('name' => 'data[User][custom][another][value]'));
0 ignored issues
show
Documentation Bug introduced by
The method text does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1136
		$this->assertEquals('User.custom.another.value', $this->Form->fields[1]);
1137
	}
1138
1139
/**
1140
 * testFormSecuredInput method
1141
 *
1142
 * Test generation of entire secure form, assertions made on input() output.
1143
 *
1144
 * @return void
1145
 */
1146
	public function testFormSecuredInput() {
1147
		$this->Form->request['_Token'] = array('key' => 'testKey');
1148
1149
		$result = $this->Form->create('Contact', array('url' => '/contacts/add'));
1150
		$encoding = strtolower(Configure::read('App.encoding'));
1151
		$expected = array(
1152
			'form' => array('method' => 'post', 'action' => '/contacts/add', 'accept-charset' => $encoding, 'id' => 'ContactAddForm'),
1153
			'div' => array('style' => 'display:none;'),
1154
			array('input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST')),
1155
			array('input' => array(
1156
				'type' => 'hidden', 'name' => 'data[_Token][key]',
1157
				'value' => 'testKey', 'id' => 'preg:/Token\d+/'
1158
			)),
1159
			'/div'
1160
		);
1161
		$this->assertTags($result, $expected);
1162
1163
		$result = $this->Form->input('UserForm.published', array('type' => 'text'));
1164
		$expected = array(
1165
			'div' => array('class' => 'input text'),
1166
			'label' => array('for' => 'UserFormPublished'),
1167
			'Published',
1168
			'/label',
1169
			array('input' => array(
1170
				'type' => 'text', 'name' => 'data[UserForm][published]',
1171
				'id' => 'UserFormPublished'
1172
			)),
1173
			'/div'
1174
		);
1175
		$this->assertTags($result, $expected);
1176
1177
		$result = $this->Form->input('UserForm.other', array('type' => 'text'));
1178
		$expected = array(
1179
			'div' => array('class' => 'input text'),
1180
			'label' => array('for' => 'UserFormOther'),
1181
			'Other',
1182
			'/label',
1183
			array('input' => array(
1184
				'type' => 'text', 'name' => 'data[UserForm][other]',
1185
				'id' => 'UserFormOther'
1186
			)),
1187
			'/div'
1188
		);
1189
		$this->assertTags($result, $expected);
1190
1191
		$result = $this->Form->hidden('UserForm.stuff');
1192
		$expected = array(
1193
			'input' => array(
1194
				'type' => 'hidden', 'name' => 'data[UserForm][stuff]',
1195
				'id' => 'UserFormStuff'
1196
		));
1197
		$this->assertTags($result, $expected);
1198
1199
		$result = $this->Form->hidden('UserForm.hidden', array('value' => '0'));
1200
		$expected = array('input' => array(
1201
			'type' => 'hidden', 'name' => 'data[UserForm][hidden]',
1202
			'value' => '0', 'id' => 'UserFormHidden'
1203
		));
1204
		$this->assertTags($result, $expected);
1205
1206
		$result = $this->Form->input('UserForm.something', array('type' => 'checkbox'));
1207
		$expected = array(
1208
			'div' => array('class' => 'input checkbox'),
1209
			array('input' => array(
1210
				'type' => 'hidden', 'name' => 'data[UserForm][something]',
1211
				'value' => '0', 'id' => 'UserFormSomething_'
1212
			)),
1213
			array('input' => array(
1214
				'type' => 'checkbox', 'name' => 'data[UserForm][something]',
1215
				'value' => '1', 'id' => 'UserFormSomething'
1216
			)),
1217
			'label' => array('for' => 'UserFormSomething'),
1218
			'Something',
1219
			'/label',
1220
			'/div'
1221
		);
1222
		$this->assertTags($result, $expected);
1223
1224
		$result = $this->Form->fields;
1225
		$expected = array(
1226
			'UserForm.published', 'UserForm.other', 'UserForm.stuff' => '',
1227
			'UserForm.hidden' => '0', 'UserForm.something'
1228
		);
1229
		$this->assertEquals($expected, $result);
1230
1231
		$hash = '6014b4e1c4f39eb62389712111dbe6435bec66cb%3AUserForm.hidden%7CUserForm.stuff';
1232
1233
		$result = $this->Form->secure($this->Form->fields);
1234
		$expected = array(
1235
			'div' => array('style' => 'display:none;'),
1236
			array('input' => array(
1237
				'type' => 'hidden', 'name' => 'data[_Token][fields]',
1238
				'value' => $hash, 'id' => 'preg:/TokenFields\d+/'
1239
			)),
1240
			array('input' => array(
1241
				'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
1242
				'value' => '', 'id' => 'preg:/TokenUnlocked\d+/'
1243
			)),
1244
			'/div'
1245
		);
1246
		$this->assertTags($result, $expected);
1247
	}
1248
1249
/**
1250
 * Test secured inputs with custom names.
1251
 *
1252
 * @return void
1253
 */
1254
	public function testSecuredInputCustomName() {
1255
		$this->Form->request['_Token'] = array('key' => 'testKey');
1256
		$this->assertEquals(array(), $this->Form->fields);
1257
1258
		$this->Form->input('text_input', array(
1259
			'name' => 'data[Option][General.default_role]',
1260
		));
1261
		$expected = array('Option.General.default_role');
1262
		$this->assertEquals($expected, $this->Form->fields);
1263
1264
		$this->Form->input('select_box', array(
1265
			'name' => 'data[Option][General.select_role]',
1266
			'type' => 'select',
1267
			'options' => array(1, 2),
1268
		));
1269
		$expected = array('Option.General.default_role', 'Option.General.select_role');
1270
		$this->assertEquals($expected, $this->Form->fields);
1271
	}
1272
1273
/**
1274
 * Tests that the correct keys are added to the field hash index
1275
 *
1276
 * @return void
1277
 */
1278
	public function testFormSecuredFileInput() {
1279
		$this->Form->request['_Token'] = array('key' => 'testKey');
1280
		$this->assertEquals(array(), $this->Form->fields);
1281
1282
		$this->Form->file('Attachment.file');
1283
		$expected = array(
1284
			'Attachment.file.name', 'Attachment.file.type', 'Attachment.file.tmp_name',
1285
			'Attachment.file.error', 'Attachment.file.size'
1286
		);
1287
		$this->assertEquals($expected, $this->Form->fields);
1288
	}
1289
1290
/**
1291
 * test that multiple selects keys are added to field hash
1292
 *
1293
 * @return void
1294
 */
1295
	public function testFormSecuredMultipleSelect() {
1296
		$this->Form->request['_Token'] = array('key' => 'testKey');
1297
		$this->assertEquals(array(), $this->Form->fields);
1298
		$options = array('1' => 'one', '2' => 'two');
1299
1300
		$this->Form->select('Model.select', $options);
1301
		$expected = array('Model.select');
1302
		$this->assertEquals($expected, $this->Form->fields);
1303
1304
		$this->Form->fields = array();
1305
		$this->Form->select('Model.select', $options, array('multiple' => true));
1306
		$this->assertEquals($expected, $this->Form->fields);
1307
	}
1308
1309
/**
1310
 * testFormSecuredRadio method
1311
 *
1312
 * @return void
1313
 */
1314 View Code Duplication
	public function testFormSecuredRadio() {
1315
		$this->Form->request['_Token'] = array('key' => 'testKey');
1316
		$this->assertEquals(array(), $this->Form->fields);
1317
		$options = array('1' => 'option1', '2' => 'option2');
1318
1319
		$this->Form->radio('Test.test', $options);
1320
		$expected = array('Test.test');
1321
		$this->assertEquals($expected, $this->Form->fields);
1322
	}
1323
1324
/**
1325
 * Test that when disabled is in a list based attribute array it works.
1326
 *
1327
 * @return void
1328
 */
1329
	public function testFormSecuredAndDisabledNotAssoc() {
1330
		$this->Form->request['_Token'] = array('key' => 'testKey');
1331
1332
		$this->Form->select('Model.select', array(1, 2), array('disabled'));
1333
		$this->Form->checkbox('Model.checkbox', array('disabled'));
1334
		$this->Form->text('Model.text', array('disabled'));
0 ignored issues
show
Documentation Bug introduced by
The method text does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1335
		$this->Form->textarea('Model.textarea', array('disabled'));
1336
		$this->Form->password('Model.password', array('disabled'));
0 ignored issues
show
Documentation Bug introduced by
The method password does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1337
		$this->Form->radio('Model.radio', array(1, 2), array('disabled'));
1338
1339
		$expected = array(
1340
			'Model.radio' => ''
1341
		);
1342
		$this->assertEquals($expected, $this->Form->fields);
1343
	}
1344
1345
/**
1346
 * test that forms with disabled inputs + secured forms leave off the inputs from the form
1347
 * hashing.
1348
 *
1349
 * @return void
1350
 */
1351
	public function testFormSecuredAndDisabled() {
1352
		$this->Form->request['_Token'] = array('key' => 'testKey');
1353
1354
		$this->Form->checkbox('Model.checkbox', array('disabled' => true));
1355
		$this->Form->text('Model.text', array('disabled' => true));
0 ignored issues
show
Documentation Bug introduced by
The method text does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1356
		$this->Form->password('Model.text', array('disabled' => true));
0 ignored issues
show
Documentation Bug introduced by
The method password does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1357
		$this->Form->textarea('Model.textarea', array('disabled' => true));
1358
		$this->Form->select('Model.select', array(1, 2), array('disabled' => true));
1359
		$this->Form->radio('Model.radio', array(1, 2), array('disabled' => array(1, 2)));
1360
		$this->Form->year('Model.year', null, null, array('disabled' => true));
1361
		$this->Form->month('Model.month', array('disabled' => true));
1362
		$this->Form->day('Model.day', array('disabled' => true));
1363
		$this->Form->hour('Model.hour', false, array('disabled' => true));
1364
		$this->Form->minute('Model.minute', array('disabled' => true));
1365
		$this->Form->meridian('Model.meridian', array('disabled' => true));
1366
1367
		$expected = array(
1368
			'Model.radio' => ''
1369
		);
1370
		$this->assertEquals($expected, $this->Form->fields);
1371
	}
1372
1373
/**
1374
 * testDisableSecurityUsingForm method
1375
 *
1376
 * @return void
1377
 */
1378
	public function testDisableSecurityUsingForm() {
1379
		$this->Form->request['_Token'] = array(
1380
			'key' => 'testKey',
1381
			'disabledFields' => array()
1382
		);
1383
		$this->Form->create();
1384
1385
		$this->Form->hidden('Addresses.id', array('value' => '123456'));
1386
		$this->Form->input('Addresses.title');
1387
		$this->Form->input('Addresses.first_name', array('secure' => false));
1388
		$this->Form->input('Addresses.city', array('type' => 'textarea', 'secure' => false));
1389
		$this->Form->input('Addresses.zip', array(
1390
			'type' => 'select', 'options' => array(1, 2), 'secure' => false
1391
		));
1392
1393
		$result = $this->Form->fields;
1394
		$expected = array(
1395
			'Addresses.id' => '123456', 'Addresses.title',
1396
		);
1397
		$this->assertEquals($expected, $result);
1398
	}
1399
1400
/**
1401
 * test disableField
1402
 *
1403
 * @return void
1404
 */
1405
	public function testUnlockFieldAddsToList() {
1406
		$this->Form->request['_Token'] = array(
1407
			'key' => 'testKey',
1408
			'unlockedFields' => array()
1409
		);
1410
		$this->Form->create('Contact');
1411
		$this->Form->unlockField('Contact.name');
1412
		$this->Form->text('Contact.name');
0 ignored issues
show
Documentation Bug introduced by
The method text does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1413
1414
		$this->assertEquals(array('Contact.name'), $this->Form->unlockField());
1415
		$this->assertEquals(array(), $this->Form->fields);
1416
	}
1417
1418
/**
1419
 * test unlockField removing from fields array.
1420
 *
1421
 * @return void
1422
 */
1423
	public function testUnlockFieldRemovingFromFields() {
1424
		$this->Form->request['_Token'] = array(
1425
			'key' => 'testKey',
1426
			'unlockedFields' => array()
1427
		);
1428
		$this->Form->create('Contact');
1429
		$this->Form->hidden('Contact.id', array('value' => 1));
1430
		$this->Form->text('Contact.name');
0 ignored issues
show
Documentation Bug introduced by
The method text does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1431
1432
		$this->assertEquals(1, $this->Form->fields['Contact.id'], 'Hidden input should be secured.');
1433
		$this->assertTrue(in_array('Contact.name', $this->Form->fields), 'Field should be secured.');
1434
1435
		$this->Form->unlockField('Contact.name');
1436
		$this->Form->unlockField('Contact.id');
1437
		$this->assertEquals(array(), $this->Form->fields);
1438
	}
1439
1440
/**
1441
 * testTagIsInvalid method
1442
 *
1443
 * @return void
1444
 */
1445
	public function testTagIsInvalid() {
1446
		$Contact = ClassRegistry::getObject('Contact');
1447
		$Contact->validationErrors[0]['email'] = $expected = array('Please provide an email');
1448
1449
		$this->Form->setEntity('Contact.0.email');
1450
		$result = $this->Form->tagIsInvalid();
1451
		$this->assertEquals($expected, $result);
1452
1453
		$this->Form->setEntity('Contact.1.email');
1454
		$result = $this->Form->tagIsInvalid();
1455
		$this->assertFalse($result);
1456
1457
		$this->Form->setEntity('Contact.0.name');
1458
		$result = $this->Form->tagIsInvalid();
1459
		$this->assertFalse($result);
1460
	}
1461
1462
/**
1463
 * Test tagIsInvalid with validation errors from a saveMany
1464
 *
1465
 * @return void
1466
 */
1467
	public function testTagIsInvalidSaveMany() {
1468
		$Contact = ClassRegistry::getObject('Contact');
1469
		$Contact->validationErrors[0]['email'] = $expected = array('Please provide an email');
1470
1471
		$this->Form->create('Contact');
1472
1473
		$this->Form->setEntity('0.email');
1474
		$result = $this->Form->tagIsInvalid();
1475
		$this->assertEquals($expected, $result);
1476
1477
		$this->Form->setEntity('0.Contact.email');
1478
		$result = $this->Form->tagIsInvalid();
1479
		$this->assertEquals($expected, $result);
1480
	}
1481
1482
/**
1483
 * Test validation errors.
1484
 *
1485
 * @return void
1486
 */
1487
	public function testPasswordValidation() {
1488
		$Contact = ClassRegistry::getObject('Contact');
1489
		$Contact->validationErrors['password'] = array('Please provide a password');
1490
1491
		$result = $this->Form->input('Contact.password');
1492
		$expected = array(
1493
			'div' => array('class' => 'input password error'),
1494
			'label' => array('for' => 'ContactPassword'),
1495
			'Password',
1496
			'/label',
1497
			'input' => array(
1498
				'type' => 'password', 'name' => 'data[Contact][password]',
1499
				'id' => 'ContactPassword', 'class' => 'form-error'
1500
			),
1501
			array('div' => array('class' => 'error-message')),
1502
			'Please provide a password',
1503
			'/div',
1504
			'/div'
1505
		);
1506
		$this->assertTags($result, $expected);
1507
1508
		$result = $this->Form->input('Contact.password', array('errorMessage' => false));
1509
		$expected = array(
1510
			'div' => array('class' => 'input password error'),
1511
			'label' => array('for' => 'ContactPassword'),
1512
			'Password',
1513
			'/label',
1514
			'input' => array(
1515
				'type' => 'password', 'name' => 'data[Contact][password]',
1516
				'id' => 'ContactPassword', 'class' => 'form-error'
1517
			),
1518
			'/div'
1519
		);
1520
		$this->assertTags($result, $expected);
1521
	}
1522
1523
/**
1524
 * Test validation errors, when validation message is an empty string.
1525
 *
1526
 * @return void
1527
 */
1528
	public function testEmptyErrorValidation() {
1529
		$this->Form->validationErrors['Contact']['password'] = '';
1530
1531
		$result = $this->Form->input('Contact.password');
1532
		$expected = array(
1533
			'div' => array('class' => 'input password error'),
1534
			'label' => array('for' => 'ContactPassword'),
1535
			'Password',
1536
			'/label',
1537
			'input' => array(
1538
				'type' => 'password', 'name' => 'data[Contact][password]',
1539
				'id' => 'ContactPassword', 'class' => 'form-error'
1540
			),
1541
			array('div' => array('class' => 'error-message')),
1542
			array(),
1543
			'/div',
1544
			'/div'
1545
		);
1546
		$this->assertTags($result, $expected);
1547
1548
		$result = $this->Form->input('Contact.password', array('errorMessage' => false));
1549
		$expected = array(
1550
			'div' => array('class' => 'input password error'),
1551
			'label' => array('for' => 'ContactPassword'),
1552
			'Password',
1553
			'/label',
1554
			'input' => array(
1555
				'type' => 'password', 'name' => 'data[Contact][password]',
1556
				'id' => 'ContactPassword', 'class' => 'form-error'
1557
			),
1558
			'/div'
1559
		);
1560
		$this->assertTags($result, $expected);
1561
	}
1562
1563
/**
1564
 * Test validation errors, when calling input() overriding validation message by an empty string.
1565
 *
1566
 * @return void
1567
 */
1568
	public function testEmptyInputErrorValidation() {
1569
		$this->Form->validationErrors['Contact']['password'] = 'Please provide a password';
1570
1571
		$result = $this->Form->input('Contact.password', array('error' => ''));
1572
		$expected = array(
1573
			'div' => array('class' => 'input password error'),
1574
			'label' => array('for' => 'ContactPassword'),
1575
			'Password',
1576
			'/label',
1577
			'input' => array(
1578
				'type' => 'password', 'name' => 'data[Contact][password]',
1579
				'id' => 'ContactPassword', 'class' => 'form-error'
1580
			),
1581
			array('div' => array('class' => 'error-message')),
1582
			array(),
1583
			'/div',
1584
			'/div'
1585
		);
1586
		$this->assertTags($result, $expected);
1587
1588
		$result = $this->Form->input('Contact.password', array('error' => '', 'errorMessage' => false));
1589
		$expected = array(
1590
			'div' => array('class' => 'input password error'),
1591
			'label' => array('for' => 'ContactPassword'),
1592
			'Password',
1593
			'/label',
1594
			'input' => array(
1595
				'type' => 'password', 'name' => 'data[Contact][password]',
1596
				'id' => 'ContactPassword', 'class' => 'form-error'
1597
			),
1598
			'/div'
1599
		);
1600
		$this->assertTags($result, $expected);
1601
	}
1602
1603
/**
1604
 * testFormValidationAssociated method
1605
 *
1606
 * test display of form errors in conjunction with model::validates.
1607
 *
1608
 * @return void
1609
 */
1610
	public function testFormValidationAssociated() {
1611
		$this->UserForm = ClassRegistry::getObject('UserForm');
1612
		$this->UserForm->OpenidUrl = ClassRegistry::getObject('OpenidUrl');
1613
1614
		$data = array(
1615
			'UserForm' => array('name' => 'user'),
1616
			'OpenidUrl' => array('url' => 'http://www.cakephp.org')
1617
		);
1618
1619
		$result = $this->UserForm->OpenidUrl->create($data);
1620
		$this->assertFalse(empty($result));
1621
		$this->assertFalse($this->UserForm->OpenidUrl->validates());
1622
1623
		$result = $this->Form->create('UserForm', array('type' => 'post', 'action' => 'login'));
1624
		$encoding = strtolower(Configure::read('App.encoding'));
1625
		$expected = array(
1626
			'form' => array(
1627
				'method' => 'post', 'action' => '/user_forms/login', 'id' => 'UserFormLoginForm',
1628
				'accept-charset' => $encoding
1629
			),
1630
			'div' => array('style' => 'display:none;'),
1631
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
1632
			'/div'
1633
		);
1634
		$this->assertTags($result, $expected);
1635
1636
		$result = $this->Form->error(
1637
			'OpenidUrl.openid_not_registered', 'Error, not registered', array('wrap' => false)
1638
		);
1639
		$this->assertEquals('Error, not registered', $result);
1640
1641
		unset($this->UserForm->OpenidUrl, $this->UserForm);
1642
	}
1643
1644
/**
1645
 * testFormValidationAssociatedFirstLevel method
1646
 *
1647
 * test form error display with associated model.
1648
 *
1649
 * @return void
1650
 */
1651
	public function testFormValidationAssociatedFirstLevel() {
1652
		$this->ValidateUser = ClassRegistry::getObject('ValidateUser');
1653
		$this->ValidateUser->ValidateProfile = ClassRegistry::getObject('ValidateProfile');
1654
1655
		$data = array(
1656
			'ValidateUser' => array('name' => 'mariano'),
1657
			'ValidateProfile' => array('full_name' => 'Mariano Iglesias')
1658
		);
1659
1660
		$result = $this->ValidateUser->create($data);
1661
		$this->assertFalse(empty($result));
1662
		$this->assertFalse($this->ValidateUser->validates());
1663
		$this->assertFalse($this->ValidateUser->ValidateProfile->validates());
1664
1665
		$result = $this->Form->create('ValidateUser', array('type' => 'post', 'action' => 'add'));
1666
		$encoding = strtolower(Configure::read('App.encoding'));
1667
		$expected = array(
1668
			'form' => array('method' => 'post', 'action' => '/validate_users/add', 'id', 'accept-charset' => $encoding),
1669
			'div' => array('style' => 'display:none;'),
1670
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
1671
			'/div'
1672
		);
1673
		$this->assertTags($result, $expected);
1674
1675
		$result = $this->Form->error(
1676
			'ValidateUser.email', 'Invalid email', array('wrap' => false)
1677
		);
1678
		$this->assertEquals('Invalid email', $result);
1679
1680
		$result = $this->Form->error(
1681
			'ValidateProfile.full_name', 'Invalid name', array('wrap' => false)
1682
		);
1683
		$this->assertEquals('Invalid name', $result);
1684
1685
		$result = $this->Form->error(
1686
			'ValidateProfile.city', 'Invalid city', array('wrap' => false)
1687
		);
1688
		$this->assertEquals('Invalid city', $result);
1689
1690
		unset($this->ValidateUser->ValidateProfile);
1691
		unset($this->ValidateUser);
1692
	}
1693
1694
/**
1695
 * testFormValidationAssociatedSecondLevel method
1696
 *
1697
 * test form error display with associated model.
1698
 *
1699
 * @return void
1700
 */
1701
	public function testFormValidationAssociatedSecondLevel() {
1702
		$this->ValidateUser = ClassRegistry::getObject('ValidateUser');
1703
		$this->ValidateUser->ValidateProfile = ClassRegistry::getObject('ValidateProfile');
1704
		$this->ValidateUser->ValidateProfile->ValidateItem = ClassRegistry::getObject('ValidateItem');
1705
1706
		$data = array(
1707
			'ValidateUser' => array('name' => 'mariano'),
1708
			'ValidateProfile' => array('full_name' => 'Mariano Iglesias'),
1709
			'ValidateItem' => array('name' => 'Item')
1710
		);
1711
1712
		$result = $this->ValidateUser->create($data);
1713
		$this->assertFalse(empty($result));
1714
		$this->assertFalse($this->ValidateUser->validates());
1715
		$this->assertFalse($this->ValidateUser->ValidateProfile->validates());
1716
		$this->assertFalse($this->ValidateUser->ValidateProfile->ValidateItem->validates());
1717
1718
		$result = $this->Form->create('ValidateUser', array('type' => 'post', 'action' => 'add'));
1719
		$encoding = strtolower(Configure::read('App.encoding'));
1720
		$expected = array(
1721
			'form' => array('method' => 'post', 'action' => '/validate_users/add', 'id', 'accept-charset' => $encoding),
1722
			'div' => array('style' => 'display:none;'),
1723
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
1724
			'/div'
1725
		);
1726
		$this->assertTags($result, $expected);
1727
1728
		$result = $this->Form->error(
1729
			'ValidateUser.email', 'Invalid email', array('wrap' => false)
1730
		);
1731
		$this->assertEquals('Invalid email', $result);
1732
1733
		$result = $this->Form->error(
1734
			'ValidateProfile.full_name', 'Invalid name', array('wrap' => false)
1735
		);
1736
		$this->assertEquals('Invalid name', $result);
1737
1738
		$result = $this->Form->error(
1739
			'ValidateProfile.city', 'Invalid city', array('wrap' => false)
1740
		);
1741
1742
		$result = $this->Form->error(
1743
			'ValidateItem.description', 'Invalid description', array('wrap' => false)
1744
		);
1745
		$this->assertEquals('Invalid description', $result);
1746
1747
		unset($this->ValidateUser->ValidateProfile->ValidateItem);
1748
		unset($this->ValidateUser->ValidateProfile);
1749
		unset($this->ValidateUser);
1750
	}
1751
1752
/**
1753
 * testFormValidationMultiRecord method
1754
 *
1755
 * test form error display with multiple records.
1756
 *
1757
 * @return void
1758
 */
1759
	public function testFormValidationMultiRecord() {
1760
		$Contact = ClassRegistry::getObject('Contact');
1761
		$Contact->validationErrors[2] = array(
1762
			'name' => array('This field cannot be left blank')
1763
		);
1764
		$result = $this->Form->input('Contact.2.name');
1765
		$expected = array(
1766
			'div' => array('class' => 'input text error'),
1767
			'label' => array('for' => 'Contact2Name'),
1768
			'Name',
1769
			'/label',
1770
			'input' => array(
1771
				'type' => 'text', 'name' => 'data[Contact][2][name]', 'id' => 'Contact2Name',
1772
				'class' => 'form-error', 'maxlength' => 255
1773
			),
1774
			array('div' => array('class' => 'error-message')),
1775
			'This field cannot be left blank',
1776
			'/div',
1777
			'/div'
1778
		);
1779
		$this->assertTags($result, $expected);
1780
	}
1781
1782
/**
1783
 * testMultipleInputValidation method
1784
 *
1785
 * test multiple record form validation error display.
1786
 *
1787
 * @return void
1788
 */
1789
	public function testMultipleInputValidation() {
1790
		$Address = ClassRegistry::init(array('class' => 'Address', 'table' => false, 'ds' => 'test'));
1791
		$Address->validationErrors[0] = array(
1792
			'title' => array('This field cannot be empty'),
1793
			'first_name' => array('This field cannot be empty')
1794
		);
1795
		$Address->validationErrors[1] = array(
1796
			'last_name' => array('You must have a last name')
1797
		);
1798
		$this->Form->create();
1799
1800
		$result = $this->Form->input('Address.0.title');
1801
		$expected = array(
1802
			'div' => array('class'),
1803
			'label' => array('for'),
1804
			'preg:/[^<]+/',
1805
			'/label',
1806
			'input' => array(
1807
				'type' => 'text', 'name', 'id', 'class' => 'form-error'
1808
			),
1809
			array('div' => array('class' => 'error-message')),
1810
			'This field cannot be empty',
1811
			'/div',
1812
			'/div'
1813
		);
1814
		$this->assertTags($result, $expected);
1815
1816
		$result = $this->Form->input('Address.0.first_name');
1817
		$expected = array(
1818
			'div' => array('class'),
1819
			'label' => array('for'),
1820
			'preg:/[^<]+/',
1821
			'/label',
1822
			'input' => array('type' => 'text', 'name', 'id', 'class' => 'form-error'),
1823
			array('div' => array('class' => 'error-message')),
1824
			'This field cannot be empty',
1825
			'/div',
1826
			'/div'
1827
		);
1828
		$this->assertTags($result, $expected);
1829
1830
		$result = $this->Form->input('Address.0.last_name');
1831
		$expected = array(
1832
			'div' => array('class'),
1833
			'label' => array('for'),
1834
			'preg:/[^<]+/',
1835
			'/label',
1836
			'input' => array('type' => 'text', 'name', 'id'),
1837
			'/div'
1838
		);
1839
		$this->assertTags($result, $expected);
1840
1841
		$result = $this->Form->input('Address.1.last_name');
1842
		$expected = array(
1843
			'div' => array('class'),
1844
			'label' => array('for'),
1845
			'preg:/[^<]+/',
1846
			'/label',
1847
			'input' => array(
1848
				'type' => 'text', 'name', 'id',
1849
				'class' => 'form-error'
1850
			),
1851
			array('div' => array('class' => 'error-message')),
1852
			'You must have a last name',
1853
			'/div',
1854
			'/div'
1855
		);
1856
		$this->assertTags($result, $expected);
1857
	}
1858
1859
/**
1860
 * testInput method
1861
 *
1862
 * Test various incarnations of input().
1863
 *
1864
 * @return void
1865
 */
1866
	public function testInput() {
1867
		$result = $this->Form->input('ValidateUser.balance');
1868
		$expected = array(
1869
			'div' => array('class'),
1870
			'label' => array('for'),
1871
			'Balance',
1872
			'/label',
1873
			'input' => array('name', 'type' => 'number', 'id', 'step'),
1874
			'/div',
1875
		);
1876
		$this->assertTags($result, $expected);
1877
1878
		$result = $this->Form->input('Contact.email', array('id' => 'custom'));
1879
		$expected = array(
1880
			'div' => array('class' => 'input email'),
1881
			'label' => array('for' => 'custom'),
1882
			'Email',
1883
			'/label',
1884
			array('input' => array(
1885
				'type' => 'email', 'name' => 'data[Contact][email]',
1886
				'id' => 'custom', 'maxlength' => 255
1887
			)),
1888
			'/div'
1889
		);
1890
		$this->assertTags($result, $expected);
1891
1892
		$result = $this->Form->input('Contact.email', array('div' => array('class' => false)));
1893
		$expected = array(
1894
			'<div',
1895
			'label' => array('for' => 'ContactEmail'),
1896
			'Email',
1897
			'/label',
1898
			array('input' => array(
1899
				'type' => 'email', 'name' => 'data[Contact][email]',
1900
				'id' => 'ContactEmail', 'maxlength' => 255
1901
			)),
1902
			'/div'
1903
		);
1904
		$this->assertTags($result, $expected);
1905
1906
		$result = $this->Form->hidden('Contact.idontexist');
1907
		$expected = array('input' => array(
1908
				'type' => 'hidden', 'name' => 'data[Contact][idontexist]',
1909
				'id' => 'ContactIdontexist'
1910
		));
1911
		$this->assertTags($result, $expected);
1912
1913
		$result = $this->Form->input('Contact.email', array('type' => 'text'));
1914
		$expected = array(
1915
			'div' => array('class' => 'input text'),
1916
			'label' => array('for' => 'ContactEmail'),
1917
			'Email',
1918
			'/label',
1919
			array('input' => array(
1920
				'type' => 'text', 'name' => 'data[Contact][email]',
1921
				'id' => 'ContactEmail'
1922
			)),
1923
			'/div'
1924
		);
1925
		$this->assertTags($result, $expected);
1926
1927
		$result = $this->Form->input('Contact.5.email', array('type' => 'text'));
1928
		$expected = array(
1929
			'div' => array('class' => 'input text'),
1930
			'label' => array('for' => 'Contact5Email'),
1931
			'Email',
1932
			'/label',
1933
			array('input' => array(
1934
				'type' => 'text', 'name' => 'data[Contact][5][email]',
1935
				'id' => 'Contact5Email'
1936
			)),
1937
			'/div'
1938
		);
1939
		$this->assertTags($result, $expected);
1940
1941
		$result = $this->Form->input('Contact.password');
1942
		$expected = array(
1943
			'div' => array('class' => 'input password'),
1944
			'label' => array('for' => 'ContactPassword'),
1945
			'Password',
1946
			'/label',
1947
			array('input' => array(
1948
				'type' => 'password', 'name' => 'data[Contact][password]',
1949
				'id' => 'ContactPassword'
1950
			)),
1951
			'/div'
1952
		);
1953
		$this->assertTags($result, $expected);
1954
1955
		$result = $this->Form->input('Contact.email', array(
1956
			'type' => 'file', 'class' => 'textbox'
1957
		));
1958
		$expected = array(
1959
			'div' => array('class' => 'input file'),
1960
			'label' => array('for' => 'ContactEmail'),
1961
			'Email',
1962
			'/label',
1963
			array('input' => array(
1964
				'type' => 'file', 'name' => 'data[Contact][email]', 'class' => 'textbox',
1965
				'id' => 'ContactEmail'
1966
			)),
1967
			'/div'
1968
		);
1969
		$this->assertTags($result, $expected);
1970
1971
		$this->Form->request->data = array('Contact' => array('phone' => 'Hello & World > weird chars'));
1972
		$result = $this->Form->input('Contact.phone');
1973
		$expected = array(
1974
			'div' => array('class' => 'input tel'),
1975
			'label' => array('for' => 'ContactPhone'),
1976
			'Phone',
1977
			'/label',
1978
			array('input' => array(
1979
				'type' => 'tel', 'name' => 'data[Contact][phone]',
1980
				'value' => 'Hello &amp; World &gt; weird chars',
1981
				'id' => 'ContactPhone', 'maxlength' => 255
1982
			)),
1983
			'/div'
1984
		);
1985
		$this->assertTags($result, $expected);
1986
1987
		$this->Form->request->data['Model']['0']['OtherModel']['field'] = 'My value';
1988
		$result = $this->Form->input('Model.0.OtherModel.field', array('id' => 'myId'));
1989
		$expected = array(
1990
			'div' => array('class' => 'input text'),
1991
			'label' => array('for' => 'myId'),
1992
			'Field',
1993
			'/label',
1994
			'input' => array(
1995
				'type' => 'text', 'name' => 'data[Model][0][OtherModel][field]',
1996
				'value' => 'My value', 'id' => 'myId'
1997
			),
1998
			'/div'
1999
		);
2000
		$this->assertTags($result, $expected);
2001
2002
		unset($this->Form->request->data);
2003
2004
		$Contact = ClassRegistry::getObject('Contact');
2005
		$Contact->validationErrors['field'] = array('Badness!');
2006
		$result = $this->Form->input('Contact.field');
2007
		$expected = array(
2008
			'div' => array('class' => 'input text error'),
2009
			'label' => array('for' => 'ContactField'),
2010
			'Field',
2011
			'/label',
2012
			'input' => array(
2013
				'type' => 'text', 'name' => 'data[Contact][field]',
2014
				'id' => 'ContactField', 'class' => 'form-error'
2015
			),
2016
			array('div' => array('class' => 'error-message')),
2017
			'Badness!',
2018
			'/div',
2019
			'/div'
2020
		);
2021
		$this->assertTags($result, $expected);
2022
2023
		$result = $this->Form->input('Contact.field', array(
2024
			'div' => false, 'error' => array('attributes' => array('wrap' => 'span'))
2025
		));
2026
		$expected = array(
2027
			'label' => array('for' => 'ContactField'),
2028
			'Field',
2029
			'/label',
2030
			'input' => array(
2031
				'type' => 'text', 'name' => 'data[Contact][field]',
2032
				'id' => 'ContactField', 'class' => 'form-error'
2033
			),
2034
			array('span' => array('class' => 'error-message')),
2035
			'Badness!',
2036
			'/span'
2037
		);
2038
		$this->assertTags($result, $expected);
2039
2040
		$result = $this->Form->input('Contact.field', array(
2041
			'type' => 'text', 'error' => array('attributes' => array('class' => 'error'))
2042
		));
2043
		$expected = array(
2044
			'div' => array('class' => 'input text error'),
2045
			'label' => array('for' => 'ContactField'),
2046
			'Field',
2047
			'/label',
2048
			'input' => array(
2049
				'type' => 'text', 'name' => 'data[Contact][field]',
2050
				'id' => 'ContactField', 'class' => 'form-error'
2051
			),
2052
			array('div' => array('class' => 'error')),
2053
			'Badness!',
2054
			'/div'
2055
		);
2056
		$this->assertTags($result, $expected);
2057
2058
		$result = $this->Form->input('Contact.field', array(
2059
			'div' => array('tag' => 'span'), 'error' => array('attributes' => array('wrap' => false))
2060
		));
2061
		$expected = array(
2062
			'span' => array('class' => 'input text error'),
2063
			'label' => array('for' => 'ContactField'),
2064
			'Field',
2065
			'/label',
2066
			'input' => array(
2067
				'type' => 'text', 'name' => 'data[Contact][field]',
2068
				'id' => 'ContactField', 'class' => 'form-error'
2069
			),
2070
			'Badness!',
2071
			'/span'
2072
		);
2073
		$this->assertTags($result, $expected);
2074
2075
		$result = $this->Form->input('Contact.field', array('after' => 'A message to you, Rudy'));
2076
		$expected = array(
2077
			'div' => array('class' => 'input text error'),
2078
			'label' => array('for' => 'ContactField'),
2079
			'Field',
2080
			'/label',
2081
			'input' => array(
2082
				'type' => 'text', 'name' => 'data[Contact][field]',
2083
				'id' => 'ContactField', 'class' => 'form-error'
2084
			),
2085
			'A message to you, Rudy',
2086
			array('div' => array('class' => 'error-message')),
2087
			'Badness!',
2088
			'/div',
2089
			'/div'
2090
		);
2091
		$this->assertTags($result, $expected);
2092
2093
		$this->Form->setEntity(null);
2094
		$this->Form->setEntity('Contact.field');
2095
		$result = $this->Form->input('Contact.field', array(
2096
			'after' => 'A message to you, Rudy', 'error' => false
2097
		));
2098
		$expected = array(
2099
			'div' => array('class' => 'input text'),
2100
			'label' => array('for' => 'ContactField'),
2101
			'Field',
2102
			'/label',
2103
			'input' => array('type' => 'text', 'name' => 'data[Contact][field]', 'id' => 'ContactField', 'class' => 'form-error'),
2104
			'A message to you, Rudy',
2105
			'/div'
2106
		);
2107
		$this->assertTags($result, $expected);
2108
2109
		$result = $this->Form->input('Object.field', array('after' => 'A message to you, Rudy'));
2110
		$expected = array(
2111
			'div' => array('class' => 'input text'),
2112
			'label' => array('for' => 'ObjectField'),
2113
			'Field',
2114
			'/label',
2115
			'input' => array('type' => 'text', 'name' => 'data[Object][field]', 'id' => 'ObjectField'),
2116
			'A message to you, Rudy',
2117
			'/div'
2118
		);
2119
		$this->assertTags($result, $expected);
2120
2121
		$Contact->validationErrors['field'] = array('minLength');
2122
		$result = $this->Form->input('Contact.field', array(
2123
			'error' => array(
2124
				'minLength' => 'Le login doit contenir au moins 2 caractères',
2125
				'maxLength' => 'login too large'
2126
			)
2127
		));
2128
		$expected = array(
2129
			'div' => array('class' => 'input text error'),
2130
			'label' => array('for' => 'ContactField'),
2131
			'Field',
2132
			'/label',
2133
			'input' => array('type' => 'text', 'name' => 'data[Contact][field]', 'id' => 'ContactField', 'class' => 'form-error'),
2134
			array('div' => array('class' => 'error-message')),
2135
			'Le login doit contenir au moins 2 caractères',
2136
			'/div',
2137
			'/div'
2138
		);
2139
		$this->assertTags($result, $expected);
2140
2141
		$Contact->validationErrors['field'] = array('maxLength');
2142
		$result = $this->Form->input('Contact.field', array(
2143
			'error' => array(
2144
				'attributes' => array('wrap' => 'span', 'rel' => 'fake'),
2145
				'minLength' => 'Le login doit contenir au moins 2 caractères',
2146
				'maxLength' => 'login too large',
2147
			)
2148
		));
2149
		$expected = array(
2150
			'div' => array('class' => 'input text error'),
2151
			'label' => array('for' => 'ContactField'),
2152
			'Field',
2153
			'/label',
2154
			'input' => array('type' => 'text', 'name' => 'data[Contact][field]', 'id' => 'ContactField', 'class' => 'form-error'),
2155
			array('span' => array('class' => 'error-message', 'rel' => 'fake')),
2156
			'login too large',
2157
			'/span',
2158
			'/div'
2159
		);
2160
		$this->assertTags($result, $expected);
2161
	}
2162
2163
/**
2164
 * Test that inputs with 0 can be created.
2165
 *
2166
 * @return void
2167
 */
2168
	public function testInputZero() {
2169
		$this->Form->create('User');
2170
		$result = $this->Form->input('0');
2171
		$expected = array(
2172
			'div' => array('class' => 'input text'),
2173
			'label' => array('for' => 'User0'), '/label',
2174
			'input' => array('type' => 'text', 'name' => 'data[User][0]', 'id' => 'User0'),
2175
			'/div'
2176
		);
2177
		$this->assertTags($result, $expected);
2178
	}
2179
2180
/**
2181
 * test input() with checkbox creation
2182
 *
2183
 * @return void
2184
 */
2185
	public function testInputCheckbox() {
2186
		$result = $this->Form->input('User.active', array('label' => false, 'checked' => true));
2187
		$expected = array(
2188
			'div' => array('class' => 'input checkbox'),
2189
			'input' => array('type' => 'hidden', 'name' => 'data[User][active]', 'value' => '0', 'id' => 'UserActive_'),
2190
			array('input' => array('type' => 'checkbox', 'name' => 'data[User][active]', 'value' => '1', 'id' => 'UserActive', 'checked' => 'checked')),
2191
			'/div'
2192
		);
2193
		$this->assertTags($result, $expected);
2194
2195
		$result = $this->Form->input('User.active', array('label' => false, 'checked' => 1));
2196
		$expected = array(
2197
			'div' => array('class' => 'input checkbox'),
2198
			'input' => array('type' => 'hidden', 'name' => 'data[User][active]', 'value' => '0', 'id' => 'UserActive_'),
2199
			array('input' => array('type' => 'checkbox', 'name' => 'data[User][active]', 'value' => '1', 'id' => 'UserActive', 'checked' => 'checked')),
2200
			'/div'
2201
		);
2202
		$this->assertTags($result, $expected);
2203
2204
		$result = $this->Form->input('User.active', array('label' => false, 'checked' => '1'));
2205
		$expected = array(
2206
			'div' => array('class' => 'input checkbox'),
2207
			'input' => array('type' => 'hidden', 'name' => 'data[User][active]', 'value' => '0', 'id' => 'UserActive_'),
2208
			array('input' => array('type' => 'checkbox', 'name' => 'data[User][active]', 'value' => '1', 'id' => 'UserActive', 'checked' => 'checked')),
2209
			'/div'
2210
		);
2211
		$this->assertTags($result, $expected);
2212
2213
		$result = $this->Form->input('User.disabled', array(
2214
			'label' => 'Disabled',
2215
			'type' => 'checkbox',
2216
			'data-foo' => 'disabled'
2217
		));
2218
		$expected = array(
2219
			'div' => array('class' => 'input checkbox'),
2220
			'input' => array('type' => 'hidden', 'name' => 'data[User][disabled]', 'value' => '0', 'id' => 'UserDisabled_'),
2221
			array('input' => array(
2222
				'type' => 'checkbox',
2223
				'name' => 'data[User][disabled]',
2224
				'value' => '1',
2225
				'id' => 'UserDisabled',
2226
				'data-foo' => 'disabled'
2227
			)),
2228
			'label' => array('for' => 'UserDisabled'),
2229
			'Disabled',
2230
			'/label',
2231
			'/div'
2232
		);
2233
		$this->assertTags($result, $expected);
2234
	}
2235
2236
/**
2237
 * test form->input() with time types.
2238
 *
2239
 * @return void
2240
 */
2241
	public function testInputTime() {
2242
		extract($this->dateRegex);
2243
		$result = $this->Form->input('Contact.created', array('type' => 'time', 'timeFormat' => 24));
2244
		$result = explode(':', $result);
2245
		$this->assertRegExp('/option value="23"/', $result[0]);
2246
		$this->assertNotRegExp('/option value="24"/', $result[0]);
2247
2248
		$result = $this->Form->input('Contact.created', array('type' => 'time', 'timeFormat' => 24));
2249
		$result = explode(':', $result);
2250
		$this->assertRegExp('/option value="23"/', $result[0]);
2251
		$this->assertNotRegExp('/option value="24"/', $result[0]);
2252
2253
		$result = $this->Form->input('Model.field', array(
2254
			'type' => 'time', 'timeFormat' => 24, 'interval' => 15
2255
		));
2256
		$result = explode(':', $result);
2257
		$this->assertNotRegExp('#<option value="12"[^>]*>12</option>#', $result[1]);
2258
		$this->assertNotRegExp('#<option value="50"[^>]*>50</option>#', $result[1]);
2259
		$this->assertRegExp('#<option value="15"[^>]*>15</option>#', $result[1]);
2260
2261
		$result = $this->Form->input('Model.field', array(
2262
			'type' => 'time', 'timeFormat' => 12, 'interval' => 15
2263
		));
2264
		$result = explode(':', $result);
2265
		$this->assertNotRegExp('#<option value="12"[^>]*>12</option>#', $result[1]);
2266
		$this->assertNotRegExp('#<option value="50"[^>]*>50</option>#', $result[1]);
2267
		$this->assertRegExp('#<option value="15"[^>]*>15</option>#', $result[1]);
2268
2269
		$result = $this->Form->input('prueba', array(
2270
			'type' => 'time', 'timeFormat' => 24, 'dateFormat' => 'DMY', 'minYear' => 2008,
2271
			'maxYear' => date('Y') + 1, 'interval' => 15
2272
		));
2273
		$result = explode(':', $result);
2274
		$this->assertNotRegExp('#<option value="12"[^>]*>12</option>#', $result[1]);
2275
		$this->assertNotRegExp('#<option value="50"[^>]*>50</option>#', $result[1]);
2276
		$this->assertRegExp('#<option value="15"[^>]*>15</option>#', $result[1]);
2277
		$this->assertRegExp('#<option value="30"[^>]*>30</option>#', $result[1]);
2278
2279
		$result = $this->Form->input('Random.start_time', array(
2280
			'type' => 'time',
2281
			'selected' => '18:15'
2282
		));
2283
		$this->assertContains('<option value="06" selected="selected">6</option>', $result);
2284
		$this->assertContains('<option value="15" selected="selected">15</option>', $result);
2285
		$this->assertContains('<option value="pm" selected="selected">pm</option>', $result);
2286
2287
		$result = $this->Form->input('published', array('type' => 'time'));
2288
		$now = strtotime('now');
2289
		$this->assertContains('<option value="' . date('h', $now) . '" selected="selected">' . date('g', $now) . '</option>', $result);
2290
2291
		$now = strtotime('2013-03-09 00:42:21');
2292
		$result = $this->Form->input('published', array('type' => 'time', 'selected' => $now));
2293
		$this->assertContains('<option value="12" selected="selected">12</option>', $result);
2294
		$this->assertContains('<option value="42" selected="selected">42</option>', $result);
2295
	}
2296
2297
/**
2298
 * Test interval + selected near the hour roll over.
2299
 *
2300
 * @return void
2301
 */
2302
	public function testTimeSelectedWithInterval() {
2303
		$result = $this->Form->input('Model.start_time', array(
2304
			'type' => 'time',
2305
			'interval' => 15,
2306
			'selected' => array('hour' => '3', 'min' => '57', 'meridian' => 'pm')
2307
		));
2308
		$this->assertContains('<option value="04" selected="selected">4</option>', $result);
2309
		$this->assertContains('<option value="00" selected="selected">00</option>', $result);
2310
		$this->assertContains('<option value="pm" selected="selected">pm</option>', $result);
2311
2312
		$result = $this->Form->input('Model.start_time', array(
2313
			'type' => 'time',
2314
			'interval' => 15,
2315
			'selected' => '2012-10-23 15:57:00'
2316
		));
2317
		$this->assertContains('<option value="04" selected="selected">4</option>', $result);
2318
		$this->assertContains('<option value="00" selected="selected">00</option>', $result);
2319
		$this->assertContains('<option value="pm" selected="selected">pm</option>', $result);
2320
2321
		$result = $this->Form->input('Model.start_time', array(
2322
			'timeFormat' => 24,
2323
			'type' => 'time',
2324
			'interval' => 15,
2325
			'selected' => '15:57'
2326
		));
2327
		$this->assertContains('<option value="16" selected="selected">16</option>', $result);
2328
		$this->assertContains('<option value="00" selected="selected">00</option>', $result);
2329
2330
		$result = $this->Form->input('Model.start_time', array(
2331
			'timeFormat' => 24,
2332
			'type' => 'time',
2333
			'interval' => 15,
2334
			'selected' => '23:57'
2335
		));
2336
		$this->assertContains('<option value="00" selected="selected">0</option>', $result);
2337
		$this->assertContains('<option value="00" selected="selected">00</option>', $result);
2338
2339
		$result = $this->Form->input('Model.created', array(
2340
			'timeFormat' => 24,
2341
			'type' => 'datetime',
2342
			'interval' => 15,
2343
			'selected' => '2012-09-30 23:56'
2344
		));
2345
		$this->assertContains('<option value="2012" selected="selected">2012</option>', $result);
2346
		$this->assertContains('<option value="10" selected="selected">October</option>', $result);
2347
		$this->assertContains('<option value="01" selected="selected">1</option>', $result);
2348
		$this->assertContains('<option value="00" selected="selected">0</option>', $result);
2349
		$this->assertContains('<option value="00" selected="selected">00</option>', $result);
2350
	}
2351
2352
/**
2353
 * Test time with selected values around 12:xx:xx
2354
 *
2355
 * @return void
2356
 */
2357
	public function testTimeSelectedWithIntervalTwelve() {
2358
		$result = $this->Form->input('Model.start_time', array(
2359
			'type' => 'time',
2360
			'timeFormat' => 12,
2361
			'interval' => 15,
2362
			'selected' => '00:00:00'
2363
		));
2364
		$this->assertContains('<option value="12" selected="selected">12</option>', $result);
2365
		$this->assertContains('<option value="00" selected="selected">00</option>', $result);
2366
		$this->assertContains('<option value="am" selected="selected">am</option>', $result);
2367
2368
		$result = $this->Form->input('Model.start_time', array(
2369
			'type' => 'time',
2370
			'timeFormat' => 12,
2371
			'interval' => 15,
2372
			'selected' => '12:00:00'
2373
		));
2374
		$this->assertContains('<option value="12" selected="selected">12</option>', $result);
2375
		$this->assertContains('<option value="00" selected="selected">00</option>', $result);
2376
		$this->assertContains('<option value="pm" selected="selected">pm</option>', $result);
2377
2378
		$result = $this->Form->input('Model.start_time', array(
2379
			'type' => 'time',
2380
			'timeFormat' => 12,
2381
			'interval' => 15,
2382
			'selected' => '12:15:00'
2383
		));
2384
		$this->assertContains('<option value="12" selected="selected">12</option>', $result);
2385
		$this->assertContains('<option value="15" selected="selected">15</option>', $result);
2386
		$this->assertContains('<option value="pm" selected="selected">pm</option>', $result);
2387
	}
2388
2389
/**
2390
 * Test interval & timeFormat = 12
2391
 *
2392
 * @return void
2393
 */
2394
	public function testInputTimeWithIntervalAnd12HourFormat() {
2395
		$result = $this->Form->input('Model.start_time', array(
2396
			'type' => 'time',
2397
			'timeFormat' => 12,
2398
			'interval' => 5,
2399
			'selected' => array('hour' => '4', 'min' => '30', 'meridian' => 'pm')
2400
		));
2401
		$this->assertContains('<option value="04" selected="selected">4</option>', $result);
2402
		$this->assertContains('<option value="30" selected="selected">30</option>', $result);
2403
		$this->assertContains('<option value="pm" selected="selected">pm</option>', $result);
2404
2405
		$result = $this->Form->input('Model.start_time', array(
2406
			'type' => 'time',
2407
			'timeFormat' => '12',
2408
			'interval' => 5,
2409
			'selected' => '2013-04-19 16:30:00'
2410
		));
2411
		$this->assertContains('<option value="04" selected="selected">4</option>', $result);
2412
		$this->assertContains('<option value="30" selected="selected">30</option>', $result);
2413
		$this->assertContains('<option value="pm" selected="selected">pm</option>', $result);
2414
2415
		$result = $this->Form->input('Model.start_time', array(
2416
			'type' => 'time',
2417
			'timeFormat' => '12',
2418
			'interval' => 10,
2419
			'selected' => '2013-05-19 00:33:00'
2420
		));
2421
		$this->assertContains('<option value="12" selected="selected">12</option>', $result);
2422
		$this->assertContains('<option value="30" selected="selected">30</option>', $result);
2423
		$this->assertContains('<option value="am" selected="selected">am</option>', $result);
2424
2425
		$result = $this->Form->input('Model.start_time', array(
2426
			'type' => 'time',
2427
			'timeFormat' => '12',
2428
			'interval' => 10,
2429
			'selected' => '2013-05-19 13:33:00'
2430
		));
2431
		$this->assertContains('<option value="01" selected="selected">1</option>', $result);
2432
		$this->assertContains('<option value="30" selected="selected">30</option>', $result);
2433
		$this->assertContains('<option value="pm" selected="selected">pm</option>', $result);
2434
2435
		$result = $this->Form->input('Model.start_time', array(
2436
			'type' => 'time',
2437
			'timeFormat' => '12',
2438
			'interval' => 10,
2439
			'selected' => '2013-05-19 01:33:00'
2440
		));
2441
		$this->assertContains('<option value="01" selected="selected">1</option>', $result);
2442
		$this->assertContains('<option value="30" selected="selected">30</option>', $result);
2443
		$this->assertContains('<option value="am" selected="selected">am</option>', $result);
2444
	}
2445
2446
/**
2447
 * test form->input() with datetime, date and time types
2448
 *
2449
 * @return void
2450
 */
2451
	public function testInputDatetime() {
2452
		extract($this->dateRegex);
2453
		$result = $this->Form->input('prueba', array(
2454
			'type' => 'datetime', 'timeFormat' => 24, 'dateFormat' => 'DMY', 'minYear' => 2008,
2455
			'maxYear' => date('Y') + 1, 'interval' => 15
2456
		));
2457
		$result = explode(':', $result);
2458
		$this->assertNotRegExp('#<option value="12"[^>]*>12</option>#', $result[1]);
2459
		$this->assertNotRegExp('#<option value="50"[^>]*>50</option>#', $result[1]);
2460
		$this->assertRegExp('#<option value="15"[^>]*>15</option>#', $result[1]);
2461
		$this->assertRegExp('#<option value="30"[^>]*>30</option>#', $result[1]);
2462
2463
		//related to ticket #5013
2464
		$result = $this->Form->input('Contact.date', array(
2465
			'type' => 'date', 'class' => 'customClass', 'onChange' => 'function(){}'
2466
		));
2467
		$this->assertRegExp('/class="customClass"/', $result);
2468
		$this->assertRegExp('/onChange="function\(\)\{\}"/', $result);
2469
2470
		$result = $this->Form->input('Contact.date', array(
2471
			'type' => 'date', 'id' => 'customId', 'onChange' => 'function(){}'
2472
		));
2473
		$this->assertRegExp('/id="customIdDay"/', $result);
2474
		$this->assertRegExp('/id="customIdMonth"/', $result);
2475
		$this->assertRegExp('/onChange="function\(\)\{\}"/', $result);
2476
2477
		$result = $this->Form->input('Model.field', array(
2478
			'type' => 'datetime', 'timeFormat' => 24, 'id' => 'customID'
2479
		));
2480
		$this->assertRegExp('/id="customIDDay"/', $result);
2481
		$this->assertRegExp('/id="customIDHour"/', $result);
2482
		$result = explode('</select><select', $result);
2483
		$result = explode(':', $result[1]);
2484
		$this->assertRegExp('/option value="23"/', $result[0]);
2485
		$this->assertNotRegExp('/option value="24"/', $result[0]);
2486
2487
		$result = $this->Form->input('Model.field', array(
2488
			'type' => 'datetime', 'timeFormat' => 12
2489
		));
2490
		$result = explode('</select><select', $result);
2491
		$result = explode(':', $result[1]);
2492
		$this->assertRegExp('/option value="12"/', $result[0]);
2493
		$this->assertNotRegExp('/option value="13"/', $result[0]);
2494
2495
		$this->Form->request->data = array('Contact' => array('created' => null));
2496
		$result = $this->Form->input('Contact.created', array('empty' => 'Date Unknown'));
2497
		$expected = array(
2498
			'div' => array('class' => 'input date'),
2499
			'label' => array('for' => 'ContactCreatedMonth'),
2500
			'Created',
2501
			'/label',
2502
			array('select' => array('name' => 'data[Contact][created][month]', 'id' => 'ContactCreatedMonth')),
2503
			array('option' => array('value' => '')), 'Date Unknown', '/option',
2504
			$monthsRegex,
2505
			'/select', '-',
2506
			array('select' => array('name' => 'data[Contact][created][day]', 'id' => 'ContactCreatedDay')),
2507
			array('option' => array('value' => '')), 'Date Unknown', '/option',
2508
			$daysRegex,
2509
			'/select', '-',
2510
			array('select' => array('name' => 'data[Contact][created][year]', 'id' => 'ContactCreatedYear')),
2511
			array('option' => array('value' => '')), 'Date Unknown', '/option',
2512
			$yearsRegex,
2513
			'/select',
2514
			'/div'
2515
		);
2516
		$this->assertTags($result, $expected);
2517
2518
		$this->Form->request->data = array('Contact' => array('created' => null));
2519
		$result = $this->Form->input('Contact.created', array('type' => 'datetime', 'dateFormat' => 'NONE'));
2520
		$this->assertRegExp('/for\="ContactCreatedHour"/', $result);
2521
2522
		$this->Form->request->data = array('Contact' => array('created' => null));
2523
		$result = $this->Form->input('Contact.created', array('type' => 'datetime', 'timeFormat' => 'NONE'));
2524
		$this->assertRegExp('/for\="ContactCreatedMonth"/', $result);
2525
2526
		$result = $this->Form->input('Contact.created', array(
2527
			'type' => 'date',
2528
			'id' => array('day' => 'created-day', 'month' => 'created-month', 'year' => 'created-year'),
2529
			'timeFormat' => 'NONE'
2530
		));
2531
		$this->assertRegExp('/for\="created-month"/', $result);
2532
	}
2533
2534
/**
2535
 * Test generating checkboxes in a loop.
2536
 *
2537
 * @return void
2538
 */
2539
	public function testInputCheckboxesInLoop() {
2540
		for ($i = 1; $i < 5; $i++) {
2541
			$result = $this->Form->input("Contact.{$i}.email", array('type' => 'checkbox', 'value' => $i));
2542
			$expected = array(
2543
				'div' => array('class' => 'input checkbox'),
2544
				'input' => array('type' => 'hidden', 'name' => "data[Contact][{$i}][email]", 'value' => '0', 'id' => "Contact{$i}Email_"),
2545
				array('input' => array('type' => 'checkbox', 'name' => "data[Contact][{$i}][email]", 'value' => $i, 'id' => "Contact{$i}Email")),
2546
				'label' => array('for' => "Contact{$i}Email"),
2547
				'Email',
2548
				'/label',
2549
				'/div'
2550
			);
2551
			$this->assertTags($result, $expected);
2552
		}
2553
	}
2554
2555
/**
2556
 * Test generating checkboxes with disabled elements.
2557
 *
2558
 * @return void
2559
 */
2560
	public function testInputCheckboxWithDisabledElements() {
2561
		$options = array(1 => 'One', 2 => 'Two', '3' => 'Three');
2562
		$result = $this->Form->input('Contact.multiple', array('multiple' => 'checkbox', 'disabled' => 'disabled', 'options' => $options));
2563
2564
		$expected = array(
2565
			array('div' => array('class' => 'input select')),
2566
			array('label' => array('for' => "ContactMultiple")),
2567
			'Multiple',
2568
			'/label',
2569
			array('input' => array('type' => 'hidden', 'name' => "data[Contact][multiple]", 'value' => '', 'id' => "ContactMultiple")),
2570
			array('div' => array('class' => 'checkbox')),
2571
			array('input' => array('type' => 'checkbox', 'name' => "data[Contact][multiple][]", 'value' => 1, 'disabled' => 'disabled', 'id' => "ContactMultiple1")),
2572
			array('label' => array('for' => "ContactMultiple1")),
2573
			'One',
2574
			'/label',
2575
			'/div',
2576
			array('div' => array('class' => 'checkbox')),
2577
			array('input' => array('type' => 'checkbox', 'name' => "data[Contact][multiple][]", 'value' => 2, 'disabled' => 'disabled', 'id' => "ContactMultiple2")),
2578
			array('label' => array('for' => "ContactMultiple2")),
2579
			'Two',
2580
			'/label',
2581
			'/div',
2582
			array('div' => array('class' => 'checkbox')),
2583
			array('input' => array('type' => 'checkbox', 'name' => "data[Contact][multiple][]", 'value' => 3, 'disabled' => 'disabled', 'id' => "ContactMultiple3")),
2584
			array('label' => array('for' => "ContactMultiple3")),
2585
			'Three',
2586
			'/label',
2587
			'/div',
2588
			'/div'
2589
		);
2590
		$this->assertTags($result, $expected);
2591
2592
		$result = $this->Form->input('Contact.multiple', array('multiple' => 'checkbox', 'disabled' => true, 'options' => $options));
2593
		$this->assertTags($result, $expected);
2594
2595
		$disabled = array('2', 3);
2596
2597
		$expected = array(
2598
			array('div' => array('class' => 'input select')),
2599
			array('label' => array('for' => "ContactMultiple")),
2600
			'Multiple',
2601
			'/label',
2602
			array('input' => array('type' => 'hidden', 'name' => "data[Contact][multiple]", 'value' => '', 'id' => "ContactMultiple")),
2603
			array('div' => array('class' => 'checkbox')),
2604
			array('input' => array('type' => 'checkbox', 'name' => "data[Contact][multiple][]", 'value' => 1, 'id' => "ContactMultiple1")),
2605
			array('label' => array('for' => "ContactMultiple1")),
2606
			'One',
2607
			'/label',
2608
			'/div',
2609
			array('div' => array('class' => 'checkbox')),
2610
			array('input' => array('type' => 'checkbox', 'name' => "data[Contact][multiple][]", 'value' => 2, 'disabled' => 'disabled', 'id' => "ContactMultiple2")),
2611
			array('label' => array('for' => "ContactMultiple2")),
2612
			'Two',
2613
			'/label',
2614
			'/div',
2615
			array('div' => array('class' => 'checkbox')),
2616
			array('input' => array('type' => 'checkbox', 'name' => "data[Contact][multiple][]", 'value' => 3, 'disabled' => 'disabled', 'id' => "ContactMultiple3")),
2617
			array('label' => array('for' => "ContactMultiple3")),
2618
			'Three',
2619
			'/label',
2620
			'/div',
2621
			'/div'
2622
		);
2623
		$result = $this->Form->input('Contact.multiple', array('multiple' => 'checkbox', 'disabled' => $disabled, 'options' => $options));
2624
		$this->assertTags($result, $expected);
2625
2626
		// make sure 50 does only disable 50, and not 50f5c0cf
2627
		$options = array('50' => 'Fifty', '50f5c0cf' => 'Stringy');
2628
		$disabled = array(50);
2629
2630
		$expected = array(
2631
			array('div' => array('class' => 'input select')),
2632
			array('label' => array('for' => "ContactMultiple")),
2633
			'Multiple',
2634
			'/label',
2635
			array('input' => array('type' => 'hidden', 'name' => "data[Contact][multiple]", 'value' => '', 'id' => "ContactMultiple")),
2636
			array('div' => array('class' => 'checkbox')),
2637
			array('input' => array('type' => 'checkbox', 'name' => "data[Contact][multiple][]", 'value' => 50, 'disabled' => 'disabled', 'id' => "ContactMultiple50")),
2638
			array('label' => array('for' => "ContactMultiple50")),
2639
			'Fifty',
2640
			'/label',
2641
			'/div',
2642
			array('div' => array('class' => 'checkbox')),
2643
			array('input' => array('type' => 'checkbox', 'name' => "data[Contact][multiple][]", 'value' => '50f5c0cf', 'id' => "ContactMultiple50f5c0cf")),
2644
			array('label' => array('for' => "ContactMultiple50f5c0cf")),
2645
			'Stringy',
2646
			'/label',
2647
			'/div',
2648
			'/div'
2649
		);
2650
		$result = $this->Form->input('Contact.multiple', array('multiple' => 'checkbox', 'disabled' => $disabled, 'options' => $options));
2651
		$this->assertTags($result, $expected);
2652
	}
2653
2654
/**
2655
 * test input name with leading integer, ensure attributes are generated correctly.
2656
 *
2657
 * @return void
2658
 */
2659
	public function testInputWithLeadingInteger() {
2660
		$result = $this->Form->text('0.Node.title');
0 ignored issues
show
Documentation Bug introduced by
The method text does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
2661
		$expected = array(
2662
			'input' => array('name' => 'data[0][Node][title]', 'id' => '0NodeTitle', 'type' => 'text')
2663
		);
2664
		$this->assertTags($result, $expected);
2665
	}
2666
2667
/**
2668
 * test form->input() with select type inputs.
2669
 *
2670
 * @return void
2671
 */
2672
	public function testInputSelectType() {
2673
		$result = $this->Form->input('email', array(
2674
			'options' => array('è' => 'Firést', 'é' => 'Secoènd'), 'empty' => true)
2675
		);
2676
		$expected = array(
2677
			'div' => array('class' => 'input select'),
2678
			'label' => array('for' => 'email'),
2679
			'Email',
2680
			'/label',
2681
			array('select' => array('name' => 'data[email]', 'id' => 'email')),
2682
			array('option' => array('value' => '')),
2683
			'/option',
2684
			array('option' => array('value' => 'è')),
2685
			'Firést',
2686
			'/option',
2687
			array('option' => array('value' => 'é')),
2688
			'Secoènd',
2689
			'/option',
2690
			'/select',
2691
			'/div'
2692
		);
2693
		$this->assertTags($result, $expected);
2694
2695
		$result = $this->Form->input('email', array(
2696
			'options' => array('First', 'Second'), 'empty' => true)
2697
		);
2698
		$expected = array(
2699
			'div' => array('class' => 'input select'),
2700
			'label' => array('for' => 'email'),
2701
			'Email',
2702
			'/label',
2703
			array('select' => array('name' => 'data[email]', 'id' => 'email')),
2704
			array('option' => array('value' => '')),
2705
			'/option',
2706
			array('option' => array('value' => '0')),
2707
			'First',
2708
			'/option',
2709
			array('option' => array('value' => '1')),
2710
			'Second',
2711
			'/option',
2712
			'/select',
2713
			'/div'
2714
		);
2715
		$this->assertTags($result, $expected);
2716
2717
		$this->View->viewVars['users'] = array('value' => 'good', 'other' => 'bad');
2718
		$this->Form->request->data = array('Model' => array('user_id' => 'value'));
2719
2720
		$result = $this->Form->input('Model.user_id', array('empty' => true));
2721
		$expected = array(
2722
			'div' => array('class' => 'input select'),
2723
			'label' => array('for' => 'ModelUserId'),
2724
			'User',
2725
			'/label',
2726
			'select' => array('name' => 'data[Model][user_id]', 'id' => 'ModelUserId'),
2727
			array('option' => array('value' => '')),
2728
			'/option',
2729
			array('option' => array('value' => 'value', 'selected' => 'selected')),
2730
			'good',
2731
			'/option',
2732
			array('option' => array('value' => 'other')),
2733
			'bad',
2734
			'/option',
2735
			'/select',
2736
			'/div'
2737
		);
2738
		$this->assertTags($result, $expected);
2739
2740
		$this->View->viewVars['users'] = array('value' => 'good', 'other' => 'bad');
2741
		$this->Form->request->data = array('Thing' => array('user_id' => null));
2742
		$result = $this->Form->input('Thing.user_id', array('empty' => 'Some Empty'));
2743
		$expected = array(
2744
			'div' => array('class' => 'input select'),
2745
			'label' => array('for' => 'ThingUserId'),
2746
			'User',
2747
			'/label',
2748
			'select' => array('name' => 'data[Thing][user_id]', 'id' => 'ThingUserId'),
2749
			array('option' => array('value' => '')),
2750
			'Some Empty',
2751
			'/option',
2752
			array('option' => array('value' => 'value')),
2753
			'good',
2754
			'/option',
2755
			array('option' => array('value' => 'other')),
2756
			'bad',
2757
			'/option',
2758
			'/select',
2759
			'/div'
2760
		);
2761
		$this->assertTags($result, $expected);
2762
2763
		$this->View->viewVars['users'] = array('value' => 'good', 'other' => 'bad');
2764
		$this->Form->request->data = array('Thing' => array('user_id' => 'value'));
2765
		$result = $this->Form->input('Thing.user_id', array('empty' => 'Some Empty'));
2766
		$expected = array(
2767
			'div' => array('class' => 'input select'),
2768
			'label' => array('for' => 'ThingUserId'),
2769
			'User',
2770
			'/label',
2771
			'select' => array('name' => 'data[Thing][user_id]', 'id' => 'ThingUserId'),
2772
			array('option' => array('value' => '')),
2773
			'Some Empty',
2774
			'/option',
2775
			array('option' => array('value' => 'value', 'selected' => 'selected')),
2776
			'good',
2777
			'/option',
2778
			array('option' => array('value' => 'other')),
2779
			'bad',
2780
			'/option',
2781
			'/select',
2782
			'/div'
2783
		);
2784
		$this->assertTags($result, $expected);
2785
2786
		$this->View->viewVars['users'] = array('value' => 'good', 'other' => 'bad');
2787
		$this->Form->request->data = array('User' => array('User' => array('value')));
2788
		$result = $this->Form->input('User.User', array('empty' => true));
2789
		$expected = array(
2790
			'div' => array('class' => 'input select'),
2791
			'label' => array('for' => 'UserUser'),
2792
			'User',
2793
			'/label',
2794
			'input' => array('type' => 'hidden', 'name' => 'data[User][User]', 'value' => '', 'id' => 'UserUser_'),
2795
			'select' => array('name' => 'data[User][User][]', 'id' => 'UserUser', 'multiple' => 'multiple'),
2796
			array('option' => array('value' => '')),
2797
			'/option',
2798
			array('option' => array('value' => 'value', 'selected' => 'selected')),
2799
			'good',
2800
			'/option',
2801
			array('option' => array('value' => 'other')),
2802
			'bad',
2803
			'/option',
2804
			'/select',
2805
			'/div'
2806
		);
2807
		$this->assertTags($result, $expected);
2808
2809
		$this->Form->data = array();
0 ignored issues
show
Documentation introduced by
The property data does not exist on object<FormHelper>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
2810
		$result = $this->Form->input('Publisher.id', array(
2811
				'label'		=> 'Publisher',
2812
				'type'		=> 'select',
2813
				'multiple'	=> 'checkbox',
2814
				'options'	=> array('Value 1' => 'Label 1', 'Value 2' => 'Label 2')
2815
		));
2816
		$expected = array(
2817
			array('div' => array('class' => 'input select')),
2818
				array('label' => array('for' => 'PublisherId')),
2819
				'Publisher',
2820
				'/label',
2821
				'input' => array('type' => 'hidden', 'name' => 'data[Publisher][id]', 'value' => '', 'id' => 'PublisherId'),
2822
				array('div' => array('class' => 'checkbox')),
2823
				array('input' => array('type' => 'checkbox', 'name' => 'data[Publisher][id][]', 'value' => 'Value 1', 'id' => 'PublisherIdValue1')),
2824
				array('label' => array('for' => 'PublisherIdValue1')),
2825
				'Label 1',
2826
				'/label',
2827
				'/div',
2828
				array('div' => array('class' => 'checkbox')),
2829
				array('input' => array('type' => 'checkbox', 'name' => 'data[Publisher][id][]', 'value' => 'Value 2', 'id' => 'PublisherIdValue2')),
2830
				array('label' => array('for' => 'PublisherIdValue2')),
2831
				'Label 2',
2832
				'/label',
2833
				'/div',
2834
			'/div'
2835
		);
2836
		$this->assertTags($result, $expected);
2837
	}
2838
2839
/**
2840
 * test that input() and a non standard primary key makes a hidden input by default.
2841
 *
2842
 * @return void
2843
 */
2844
	public function testInputWithNonStandardPrimaryKeyMakesHidden() {
2845
		$this->Form->create('User');
2846
		$this->Form->fieldset = array(
2847
			'User' => array(
2848
				'fields' => array(
2849
					'model_id' => array('type' => 'integer')
2850
				),
2851
				'validates' => array(),
2852
				'key' => 'model_id'
2853
			)
2854
		);
2855
		$result = $this->Form->input('model_id');
2856
		$expected = array(
2857
			'input' => array('type' => 'hidden', 'name' => 'data[User][model_id]', 'id' => 'UserModelId'),
2858
		);
2859
		$this->assertTags($result, $expected);
2860
	}
2861
2862
/**
2863
 * test that overriding the magic select type widget is possible
2864
 *
2865
 * @return void
2866
 */
2867
	public function testInputOverridingMagicSelectType() {
2868
		$this->View->viewVars['users'] = array('value' => 'good', 'other' => 'bad');
2869
		$result = $this->Form->input('Model.user_id', array('type' => 'text'));
2870
		$expected = array(
2871
			'div' => array('class' => 'input text'),
2872
			'label' => array('for' => 'ModelUserId'), 'User', '/label',
2873
			'input' => array('name' => 'data[Model][user_id]', 'type' => 'text', 'id' => 'ModelUserId'),
2874
			'/div'
2875
		);
2876
		$this->assertTags($result, $expected);
2877
2878
		//Check that magic types still work for plural/singular vars
2879
		$this->View->viewVars['types'] = array('value' => 'good', 'other' => 'bad');
2880
		$result = $this->Form->input('Model.type');
2881
		$expected = array(
2882
			'div' => array('class' => 'input select'),
2883
			'label' => array('for' => 'ModelType'), 'Type', '/label',
2884
			'select' => array('name' => 'data[Model][type]', 'id' => 'ModelType'),
2885
			array('option' => array('value' => 'value')), 'good', '/option',
2886
			array('option' => array('value' => 'other')), 'bad', '/option',
2887
			'/select',
2888
			'/div'
2889
		);
2890
		$this->assertTags($result, $expected);
2891
	}
2892
2893
/**
2894
 * Test that inferred types do not override developer input
2895
 *
2896
 * @return void
2897
 */
2898 View Code Duplication
	public function testInputMagicTypeDoesNotOverride() {
2899
		$this->View->viewVars['users'] = array('value' => 'good', 'other' => 'bad');
2900
		$result = $this->Form->input('Model.user', array('type' => 'checkbox'));
2901
		$expected = array(
2902
			'div' => array('class' => 'input checkbox'),
2903
			array('input' => array(
2904
				'type' => 'hidden',
2905
				'name' => 'data[Model][user]',
2906
				'id' => 'ModelUser_',
2907
				'value' => 0,
2908
			)),
2909
			array('input' => array(
2910
				'name' => 'data[Model][user]',
2911
				'type' => 'checkbox',
2912
				'id' => 'ModelUser',
2913
				'value' => 1
2914
			)),
2915
			'label' => array('for' => 'ModelUser'), 'User', '/label',
2916
			'/div'
2917
		);
2918
		$this->assertTags($result, $expected);
2919
	}
2920
2921
/**
2922
 * Test that magic input() selects are created for type=number
2923
 *
2924
 * @return void
2925
 */
2926
	public function testInputMagicSelectForTypeNumber() {
2927
		$this->View->viewVars['balances'] = array(0 => 'nothing', 1 => 'some', 100 => 'a lot');
2928
		$this->Form->request->data = array('ValidateUser' => array('balance' => 1));
2929
		$result = $this->Form->input('ValidateUser.balance');
2930
		$expected = array(
2931
			'div' => array('class' => 'input select'),
2932
			'label' => array('for' => 'ValidateUserBalance'),
2933
			'Balance',
2934
			'/label',
2935
			'select' => array('name' => 'data[ValidateUser][balance]', 'id' => 'ValidateUserBalance'),
2936
			array('option' => array('value' => '0')),
2937
			'nothing',
2938
			'/option',
2939
			array('option' => array('value' => '1', 'selected' => 'selected')),
2940
			'some',
2941
			'/option',
2942
			array('option' => array('value' => '100')),
2943
			'a lot',
2944
			'/option',
2945
			'/select',
2946
			'/div'
2947
		);
2948
		$this->assertTags($result, $expected);
2949
	}
2950
2951
/**
2952
 * Test that magic input() selects can easily be converted into radio types without error.
2953
 *
2954
 * @return void
2955
 */
2956
	public function testInputMagicSelectChangeToRadio() {
2957
		$this->View->viewVars['users'] = array('value' => 'good', 'other' => 'bad');
2958
		$result = $this->Form->input('Model.user_id', array('type' => 'radio'));
2959
		$this->assertRegExp('/input type="radio"/', $result);
2960
	}
2961
2962
/**
2963
 * fields with the same name as the model should work.
2964
 *
2965
 * @return void
2966
 */
2967
	public function testInputWithMatchingFieldAndModelName() {
2968
		$this->Form->create('User');
2969
		$this->Form->fieldset = array(
2970
			'User' => array(
2971
				'fields' => array(
2972
					'User' => array('type' => 'text')
2973
				),
2974
				'validates' => array(),
2975
				'key' => 'id'
2976
			)
2977
		);
2978
		$this->Form->request->data['User']['User'] = 'ABC, Inc.';
2979
		$result = $this->Form->input('User', array('type' => 'text'));
2980
		$expected = array(
2981
			'div' => array('class' => 'input text'),
2982
			'label' => array('for' => 'UserUser'), 'User', '/label',
2983
			'input' => array('name' => 'data[User][User]', 'type' => 'text', 'id' => 'UserUser', 'value' => 'ABC, Inc.'),
2984
			'/div'
2985
		);
2986
		$this->assertTags($result, $expected);
2987
	}
2988
2989
/**
2990
 * testFormInputs method
2991
 *
2992
 * test correct results from form::inputs().
2993
 *
2994
 * @return void
2995
 */
2996
	public function testFormInputs() {
2997
		$this->Form->create('Contact');
2998
		$result = $this->Form->inputs('The Legend');
2999
		$expected = array(
3000
			'<fieldset',
3001
			'<legend',
3002
			'The Legend',
3003
			'/legend',
3004
			'*/fieldset',
3005
		);
3006
		$this->assertTags($result, $expected);
3007
3008
		$result = $this->Form->inputs(array('legend' => 'Field of Dreams', 'fieldset' => 'classy-stuff'));
3009
		$expected = array(
3010
			'fieldset' => array('class' => 'classy-stuff'),
3011
			'<legend',
3012
			'Field of Dreams',
3013
			'/legend',
3014
			'*/fieldset'
3015
		);
3016
		$this->assertTags($result, $expected);
3017
3018
		$result = $this->Form->inputs(null, null, array('legend' => 'Field of Dreams', 'fieldset' => 'classy-stuff'));
3019
		$this->assertTags($result, $expected);
3020
3021
		$result = $this->Form->inputs('Field of Dreams', null, array('fieldset' => 'classy-stuff'));
3022
		$this->assertTags($result, $expected);
3023
3024
		$this->Form->create('Contact');
3025
		$this->Form->request['prefix'] = 'admin';
3026
		$this->Form->request['action'] = 'admin_edit';
3027
		$result = $this->Form->inputs();
3028
		$expected = array(
3029
			'<fieldset',
3030
			'<legend',
3031
			'Edit Contact',
3032
			'/legend',
3033
			'*/fieldset',
3034
		);
3035
		$this->assertTags($result, $expected);
3036
3037
		$this->Form->create('Contact');
3038
		$result = $this->Form->inputs(false);
3039
		$expected = array(
3040
			'input' => array('type' => 'hidden', 'name' => 'data[Contact][id]', 'id' => 'ContactId'),
3041
			array('div' => array('class' => 'input text')),
3042
			'*/div',
3043
			array('div' => array('class' => 'input email')),
3044
			'*/div',
3045
			array('div' => array('class' => 'input tel')),
3046
			'*/div',
3047
			array('div' => array('class' => 'input password')),
3048
			'*/div',
3049
			array('div' => array('class' => 'input date')),
3050
			'*/div',
3051
			array('div' => array('class' => 'input date')),
3052
			'*/div',
3053
			array('div' => array('class' => 'input datetime')),
3054
			'*/div',
3055
			array('div' => array('class' => 'input number')),
3056
			'*/div',
3057
			array('div' => array('class' => 'input select')),
3058
			'*/div',
3059
		);
3060
		$this->assertTags($result, $expected);
3061
3062
		$this->Form->create('Contact');
3063
		$result = $this->Form->inputs(array('fieldset' => false, 'legend' => false));
3064
		$expected = array(
3065
			'input' => array('type' => 'hidden', 'name' => 'data[Contact][id]', 'id' => 'ContactId'),
3066
			array('div' => array('class' => 'input text')),
3067
			'*/div',
3068
			array('div' => array('class' => 'input email')),
3069
			'*/div',
3070
			array('div' => array('class' => 'input tel')),
3071
			'*/div',
3072
			array('div' => array('class' => 'input password')),
3073
			'*/div',
3074
			array('div' => array('class' => 'input date')),
3075
			'*/div',
3076
			array('div' => array('class' => 'input date')),
3077
			'*/div',
3078
			array('div' => array('class' => 'input datetime')),
3079
			'*/div',
3080
			array('div' => array('class' => 'input number')),
3081
			'*/div',
3082
			array('div' => array('class' => 'input select')),
3083
			'*/div',
3084
		);
3085
		$this->assertTags($result, $expected);
3086
3087
		$this->Form->create('Contact');
3088
		$result = $this->Form->inputs(null, null, array('fieldset' => false));
3089
		$this->assertTags($result, $expected);
3090
3091
		$this->Form->create('Contact');
3092
		$result = $this->Form->inputs(array('fieldset' => true, 'legend' => false));
3093
		$expected = array(
3094
			'fieldset' => array(),
3095
			'input' => array('type' => 'hidden', 'name' => 'data[Contact][id]', 'id' => 'ContactId'),
3096
			array('div' => array('class' => 'input text')),
3097
			'*/div',
3098
			array('div' => array('class' => 'input email')),
3099
			'*/div',
3100
			array('div' => array('class' => 'input tel')),
3101
			'*/div',
3102
			array('div' => array('class' => 'input password')),
3103
			'*/div',
3104
			array('div' => array('class' => 'input date')),
3105
			'*/div',
3106
			array('div' => array('class' => 'input date')),
3107
			'*/div',
3108
			array('div' => array('class' => 'input datetime')),
3109
			'*/div',
3110
			array('div' => array('class' => 'input number')),
3111
			'*/div',
3112
			array('div' => array('class' => 'input select')),
3113
			'*/div',
3114
			'/fieldset'
3115
		);
3116
		$this->assertTags($result, $expected);
3117
3118
		$this->Form->create('Contact');
3119
		$result = $this->Form->inputs(array('fieldset' => false, 'legend' => 'Hello'));
3120
		$expected = array(
3121
			'input' => array('type' => 'hidden', 'name' => 'data[Contact][id]', 'id' => 'ContactId'),
3122
			array('div' => array('class' => 'input text')),
3123
			'*/div',
3124
			array('div' => array('class' => 'input email')),
3125
			'*/div',
3126
			array('div' => array('class' => 'input tel')),
3127
			'*/div',
3128
			array('div' => array('class' => 'input password')),
3129
			'*/div',
3130
			array('div' => array('class' => 'input date')),
3131
			'*/div',
3132
			array('div' => array('class' => 'input date')),
3133
			'*/div',
3134
			array('div' => array('class' => 'input datetime')),
3135
			'*/div',
3136
			array('div' => array('class' => 'input number')),
3137
			'*/div',
3138
			array('div' => array('class' => 'input select')),
3139
			'*/div',
3140
		);
3141
		$this->assertTags($result, $expected);
3142
3143
		$this->Form->create('Contact');
3144
		$result = $this->Form->inputs(null, null, array('fieldset' => false, 'legend' => 'Hello'));
3145
		$this->assertTags($result, $expected);
3146
3147
		$this->Form->create('Contact');
3148
		$result = $this->Form->inputs('Hello');
3149
		$expected = array(
3150
			'fieldset' => array(),
3151
			'legend' => array(),
3152
			'Hello',
3153
			'/legend',
3154
			'input' => array('type' => 'hidden', 'name' => 'data[Contact][id]', 'id' => 'ContactId'),
3155
			array('div' => array('class' => 'input text')),
3156
			'*/div',
3157
			array('div' => array('class' => 'input email')),
3158
			'*/div',
3159
			array('div' => array('class' => 'input tel')),
3160
			'*/div',
3161
			array('div' => array('class' => 'input password')),
3162
			'*/div',
3163
			array('div' => array('class' => 'input date')),
3164
			'*/div',
3165
			array('div' => array('class' => 'input date')),
3166
			'*/div',
3167
			array('div' => array('class' => 'input datetime')),
3168
			'*/div',
3169
			array('div' => array('class' => 'input number')),
3170
			'*/div',
3171
			array('div' => array('class' => 'input select')),
3172
			'*/div',
3173
			'/fieldset'
3174
		);
3175
		$this->assertTags($result, $expected);
3176
3177
		$this->Form->create('Contact');
3178
		$result = $this->Form->inputs(array('legend' => 'Hello'));
3179
		$expected = array(
3180
			'fieldset' => array(),
3181
			'legend' => array(),
3182
			'Hello',
3183
			'/legend',
3184
			'input' => array('type' => 'hidden', 'name' => 'data[Contact][id]', 'id' => 'ContactId'),
3185
			array('div' => array('class' => 'input text')),
3186
			'*/div',
3187
			array('div' => array('class' => 'input email')),
3188
			'*/div',
3189
			array('div' => array('class' => 'input tel')),
3190
			'*/div',
3191
			array('div' => array('class' => 'input password')),
3192
			'*/div',
3193
			array('div' => array('class' => 'input date')),
3194
			'*/div',
3195
			array('div' => array('class' => 'input date')),
3196
			'*/div',
3197
			array('div' => array('class' => 'input datetime')),
3198
			'*/div',
3199
			array('div' => array('class' => 'input number')),
3200
			'*/div',
3201
			array('div' => array('class' => 'input select')),
3202
			'*/div',
3203
			'/fieldset'
3204
		);
3205
		$this->assertTags($result, $expected);
3206
3207
		$this->Form->create('Contact');
3208
		$result = $this->Form->inputs(null, null, array('legend' => 'Hello'));
3209
		$this->assertTags($result, $expected);
3210
		$this->Form->end();
3211
3212
		$this->Form->create(false);
3213
		$expected = array(
3214
			'fieldset' => array(),
3215
			array('div' => array('class' => 'input text')),
3216
			'label' => array('for' => 'foo'),
3217
			'Foo',
3218
			'/label',
3219
			'input' => array('type' => 'text', 'name' => 'data[foo]', 'id' => 'foo'),
3220
			'*/div',
3221
			'/fieldset'
3222
		);
3223
		$result = $this->Form->inputs(
3224
			array('foo' => array('type' => 'text')),
3225
			array(),
3226
			array('legend' => false)
3227
		);
3228
		$this->assertTags($result, $expected);
3229
	}
3230
3231
/**
3232
 * Tests inputs() works with plugin models
3233
 *
3234
 * @return void
3235
 */
3236
	public function testInputsPluginModel() {
3237
		$this->loadFixtures('Post');
3238
		App::build(array(
3239
			'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
3240
		));
3241
		CakePlugin::load('TestPlugin');
3242
		$this->Form->request['models'] = array(
3243
			'TestPluginPost' => array('plugin' => 'TestPlugin', 'className' => 'TestPluginPost')
3244
		);
3245
		$this->Form->create('TestPlugin.TestPluginPost');
3246
		$result = $this->Form->inputs();
3247
3248
		$this->assertContains('data[TestPluginPost][id]', $result);
3249
		$this->assertContains('data[TestPluginPost][author_id]', $result);
3250
		$this->assertContains('data[TestPluginPost][title]', $result);
3251
		$this->assertTrue(ClassRegistry::isKeySet('TestPluginPost'));
3252
		$this->assertFalse(ClassRegistry::isKeySet('TestPlugin'));
3253
		$this->assertEquals('TestPluginPost', $this->Form->model());
3254
	}
3255
3256
/**
3257
 * testSelectAsCheckbox method
3258
 *
3259
 * test multi-select widget with checkbox formatting.
3260
 *
3261
 * @return void
3262
 */
3263
	public function testSelectAsCheckbox() {
3264
		$result = $this->Form->select('Model.multi_field', array('first', 'second', 'third'), array('multiple' => 'checkbox', 'value' => array(0, 1)));
3265
		$expected = array(
3266
			'input' => array('type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField'),
3267
			array('div' => array('class' => 'checkbox')),
3268
			array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'checked' => 'checked', 'value' => '0', 'id' => 'ModelMultiField0')),
3269
			array('label' => array('for' => 'ModelMultiField0', 'class' => 'selected')),
3270
			'first',
3271
			'/label',
3272
			'/div',
3273
			array('div' => array('class' => 'checkbox')),
3274
			array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'checked' => 'checked', 'value' => '1', 'id' => 'ModelMultiField1')),
3275
			array('label' => array('for' => 'ModelMultiField1', 'class' => 'selected')),
3276
			'second',
3277
			'/label',
3278
			'/div',
3279
			array('div' => array('class' => 'checkbox')),
3280
			array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '2', 'id' => 'ModelMultiField2')),
3281
			array('label' => array('for' => 'ModelMultiField2')),
3282
			'third',
3283
			'/label',
3284
			'/div',
3285
		);
3286
		$this->assertTags($result, $expected);
3287
3288
		$result = $this->Form->select('Model.multi_field', array('1/2' => 'half'), array('multiple' => 'checkbox'));
3289
		$expected = array(
3290
			'input' => array('type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField'),
3291
			array('div' => array('class' => 'checkbox')),
3292
			array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '1/2', 'id' => 'ModelMultiField12')),
3293
			array('label' => array('for' => 'ModelMultiField12')),
3294
			'half',
3295
			'/label',
3296
			'/div',
3297
		);
3298
		$this->assertTags($result, $expected);
3299
	}
3300
3301
/**
3302
 * testLabel method
3303
 *
3304
 * test label generation.
3305
 *
3306
 * @return void
3307
 */
3308
	public function testLabel() {
3309
		$this->Form->text('Person.name');
0 ignored issues
show
Documentation Bug introduced by
The method text does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
3310
		$result = $this->Form->label();
3311
		$this->assertTags($result, array('label' => array('for' => 'PersonName'), 'Name', '/label'));
3312
3313
		$this->Form->text('Person.name');
0 ignored issues
show
Documentation Bug introduced by
The method text does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
3314
		$result = $this->Form->label();
3315
		$this->assertTags($result, array('label' => array('for' => 'PersonName'), 'Name', '/label'));
3316
3317
		$result = $this->Form->label('Person.first_name');
3318
		$this->assertTags($result, array('label' => array('for' => 'PersonFirstName'), 'First Name', '/label'));
3319
3320
		$result = $this->Form->label('Person.first_name', 'Your first name');
3321
		$this->assertTags($result, array('label' => array('for' => 'PersonFirstName'), 'Your first name', '/label'));
3322
3323
		$result = $this->Form->label('Person.first_name', 'Your first name', array('class' => 'my-class'));
3324
		$this->assertTags($result, array('label' => array('for' => 'PersonFirstName', 'class' => 'my-class'), 'Your first name', '/label'));
3325
3326
		$result = $this->Form->label('Person.first_name', 'Your first name', array('class' => 'my-class', 'id' => 'LabelID'));
3327
		$this->assertTags($result, array('label' => array('for' => 'PersonFirstName', 'class' => 'my-class', 'id' => 'LabelID'), 'Your first name', '/label'));
3328
3329
		$result = $this->Form->label('Person.first_name', '');
3330
		$this->assertTags($result, array('label' => array('for' => 'PersonFirstName'), '/label'));
3331
3332
		$result = $this->Form->label('Person.2.name', '');
3333
		$this->assertTags($result, array('label' => array('for' => 'Person2Name'), '/label'));
3334
	}
3335
3336
/**
3337
 * testTextbox method
3338
 *
3339
 * test textbox element generation
3340
 *
3341
 * @return void
3342
 */
3343
	public function testTextbox() {
3344
		$result = $this->Form->text('Model.field');
0 ignored issues
show
Documentation Bug introduced by
The method text does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
3345
		$this->assertTags($result, array('input' => array('type' => 'text', 'name' => 'data[Model][field]', 'id' => 'ModelField')));
3346
3347
		$result = $this->Form->text('Model.field', array('type' => 'password'));
0 ignored issues
show
Documentation Bug introduced by
The method text does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
3348
		$this->assertTags($result, array('input' => array('type' => 'password', 'name' => 'data[Model][field]', 'id' => 'ModelField')));
3349
3350
		$result = $this->Form->text('Model.field', array('id' => 'theID'));
0 ignored issues
show
Documentation Bug introduced by
The method text does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
3351
		$this->assertTags($result, array('input' => array('type' => 'text', 'name' => 'data[Model][field]', 'id' => 'theID')));
3352
3353
		$this->Form->request->data['Model']['text'] = 'test <strong>HTML</strong> values';
3354
		$result = $this->Form->text('Model.text');
0 ignored issues
show
Documentation Bug introduced by
The method text does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
3355
		$this->assertTags($result, array('input' => array('type' => 'text', 'name' => 'data[Model][text]', 'value' => 'test &lt;strong&gt;HTML&lt;/strong&gt; values', 'id' => 'ModelText')));
3356
3357
		$Contact = ClassRegistry::getObject('Contact');
3358
		$Contact->validationErrors['text'] = array(true);
3359
		$this->Form->request->data['Contact']['text'] = 'test';
3360
		$result = $this->Form->text('Contact.text', array('id' => 'theID'));
0 ignored issues
show
Documentation Bug introduced by
The method text does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
3361
		$this->assertTags($result, array('input' => array('type' => 'text', 'name' => 'data[Contact][text]', 'value' => 'test', 'id' => 'theID', 'class' => 'form-error')));
3362
3363
		$this->Form->request->data['Model']['0']['OtherModel']['field'] = 'My value';
3364
		$result = $this->Form->text('Model.0.OtherModel.field', array('id' => 'myId'));
0 ignored issues
show
Documentation Bug introduced by
The method text does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
3365
		$expected = array(
3366
			'input' => array('type' => 'text', 'name' => 'data[Model][0][OtherModel][field]', 'value' => 'My value', 'id' => 'myId')
3367
		);
3368
		$this->assertTags($result, $expected);
3369
	}
3370
3371
/**
3372
 * testDefaultValue method
3373
 *
3374
 * Test default value setting
3375
 *
3376
 * @return void
3377
 */
3378
	public function testDefaultValue() {
3379
		$this->Form->request->data['Model']['field'] = 'test';
3380
		$result = $this->Form->text('Model.field', array('default' => 'default value'));
0 ignored issues
show
Documentation Bug introduced by
The method text does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
3381
		$this->assertTags($result, array('input' => array('type' => 'text', 'name' => 'data[Model][field]', 'value' => 'test', 'id' => 'ModelField')));
3382
3383
		unset($this->Form->request->data['Model']['field']);
3384
		$result = $this->Form->text('Model.field', array('default' => 'default value'));
0 ignored issues
show
Documentation Bug introduced by
The method text does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
3385
		$this->assertTags($result, array('input' => array('type' => 'text', 'name' => 'data[Model][field]', 'value' => 'default value', 'id' => 'ModelField')));
3386
	}
3387
3388
/**
3389
 * testCheckboxDefaultValue method
3390
 *
3391
 * Test default value setting on checkbox() method
3392
 *
3393
 * @return void
3394
 */
3395
	public function testCheckboxDefaultValue() {
3396
		$this->Form->request->data['Model']['field'] = false;
3397
		$result = $this->Form->checkbox('Model.field', array('default' => true, 'hiddenField' => false));
3398
		$this->assertTags($result, array('input' => array('type' => 'checkbox', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField')));
3399
3400
		unset($this->Form->request->data['Model']['field']);
3401
		$result = $this->Form->checkbox('Model.field', array('default' => true, 'hiddenField' => false));
3402
		$this->assertTags($result, array('input' => array('type' => 'checkbox', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField', 'checked' => 'checked')));
3403
3404
		$this->Form->request->data['Model']['field'] = true;
3405
		$result = $this->Form->checkbox('Model.field', array('default' => false, 'hiddenField' => false));
3406
		$this->assertTags($result, array('input' => array('type' => 'checkbox', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField', 'checked' => 'checked')));
3407
3408
		unset($this->Form->request->data['Model']['field']);
3409
		$result = $this->Form->checkbox('Model.field', array('default' => false, 'hiddenField' => false));
3410
		$this->assertTags($result, array('input' => array('type' => 'checkbox', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField')));
3411
	}
3412
3413
/**
3414
 * testError method
3415
 *
3416
 * Test field error generation
3417
 *
3418
 * @return void
3419
 */
3420
	public function testError() {
3421
		$Contact = ClassRegistry::getObject('Contact');
3422
		$Contact->validationErrors['field'] = array(1);
3423
		$result = $this->Form->error('Contact.field');
3424
		$this->assertTags($result, array('div' => array('class' => 'error-message'), 'Error in field Field', '/div'));
3425
3426
		$result = $this->Form->error('Contact.field', null, array('wrap' => false));
3427
		$this->assertEquals('Error in field Field', $result);
3428
3429
		$Contact->validationErrors['field'] = array("This field contains invalid input");
3430
		$result = $this->Form->error('Contact.field', null, array('wrap' => false));
3431
		$this->assertEquals('This field contains invalid input', $result);
3432
3433
		$Contact->validationErrors['field'] = array("This field contains invalid input");
3434
		$result = $this->Form->error('Contact.field', null, array('wrap' => 'span'));
3435
		$this->assertTags($result, array('span' => array('class' => 'error-message'), 'This field contains invalid input', '/span'));
3436
3437
		$result = $this->Form->error('Contact.field', 'There is an error fool!', array('wrap' => 'span'));
3438
		$this->assertTags($result, array('span' => array('class' => 'error-message'), 'There is an error fool!', '/span'));
3439
3440
		$result = $this->Form->error('Contact.field', "<strong>Badness!</strong>", array('wrap' => false));
3441
		$this->assertEquals('&lt;strong&gt;Badness!&lt;/strong&gt;', $result);
3442
3443
		$result = $this->Form->error('Contact.field', "<strong>Badness!</strong>", array('wrap' => false, 'escape' => true));
3444
		$this->assertEquals('&lt;strong&gt;Badness!&lt;/strong&gt;', $result);
3445
3446
		$result = $this->Form->error('Contact.field', "<strong>Badness!</strong>", array('wrap' => false, 'escape' => false));
3447
		$this->assertEquals('<strong>Badness!</strong>', $result);
3448
3449
		$Contact->validationErrors['field'] = array("email");
3450
		$result = $this->Form->error('Contact.field', array('attributes' => array('class' => 'field-error'), 'email' => 'No good!'));
3451
		$expected = array(
3452
			'div' => array('class' => 'field-error'),
3453
			'No good!',
3454
			'/div'
3455
		);
3456
		$this->assertTags($result, $expected);
3457
3458
		$Contact->validationErrors['field'] = array('notEmpty', 'email', 'Something else');
3459
		$result = $this->Form->error('Contact.field', array(
3460
			'notEmpty' => 'Cannot be empty',
3461
			'email' => 'No good!'
3462
		));
3463
		$expected = array(
3464
			'div' => array('class' => 'error-message'),
3465
				'ul' => array(),
3466
					'<li', 'Cannot be empty', '/li',
3467
					'<li', 'No good!', '/li',
3468
					'<li', 'Something else', '/li',
3469
				'/ul',
3470
			'/div'
3471
		);
3472
		$this->assertTags($result, $expected);
3473
3474
		// Testing error messages list options
3475
		$Contact->validationErrors['field'] = array('notEmpty', 'email');
3476
3477
		$result = $this->Form->error('Contact.field', null, array('listOptions' => 'ol'));
3478
		$expected = array(
3479
			'div' => array('class' => 'error-message'),
3480
				'ol' => array(),
3481
					'<li', 'notEmpty', '/li',
3482
					'<li', 'email', '/li',
3483
				'/ol',
3484
			'/div'
3485
		);
3486
		$this->assertTags($result, $expected);
3487
3488
		$result = $this->Form->error('Contact.field', null, array('listOptions' => array('tag' => 'ol')));
3489
		$expected = array(
3490
			'div' => array('class' => 'error-message'),
3491
				'ol' => array(),
3492
					'<li', 'notEmpty', '/li',
3493
					'<li', 'email', '/li',
3494
				'/ol',
3495
			'/div'
3496
		);
3497
		$this->assertTags($result, $expected);
3498
3499
		$result = $this->Form->error('Contact.field', null, array(
3500
			'listOptions' => array(
3501
				'class' => 'ul-class',
3502
				'itemOptions' => array(
3503
					'class' => 'li-class'
3504
				)
3505
			)
3506
		));
3507
		$expected = array(
3508
			'div' => array('class' => 'error-message'),
3509
				'ul' => array('class' => 'ul-class'),
3510
					array('li' => array('class' => 'li-class')), 'notEmpty', '/li',
3511
					array('li' => array('class' => 'li-class')), 'email', '/li',
3512
				'/ul',
3513
			'/div'
3514
		);
3515
		$this->assertTags($result, $expected);
3516
	}
3517
3518
/**
3519
 * test error options when using form->input();
3520
 *
3521
 * @return void
3522
 */
3523
	public function testInputErrorEscape() {
3524
		$this->Form->create('ValidateProfile');
3525
		$ValidateProfile = ClassRegistry::getObject('ValidateProfile');
3526
		$ValidateProfile->validationErrors['city'] = array('required<br>');
3527
		$result = $this->Form->input('city', array('error' => array('attributes' => array('escape' => true))));
3528
		$this->assertRegExp('/required&lt;br&gt;/', $result);
3529
3530
		$result = $this->Form->input('city', array('error' => array('attributes' => array('escape' => false))));
3531
		$this->assertRegExp('/required<br>/', $result);
3532
	}
3533
3534
/**
3535
 * testPassword method
3536
 *
3537
 * Test password element generation
3538
 *
3539
 * @return void
3540
 */
3541
	public function testPassword() {
3542
		$Contact = ClassRegistry::getObject('Contact');
3543
		$result = $this->Form->password('Contact.field');
0 ignored issues
show
Documentation Bug introduced by
The method password does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
3544
		$this->assertTags($result, array('input' => array('type' => 'password', 'name' => 'data[Contact][field]', 'id' => 'ContactField')));
3545
3546
		$Contact->validationErrors['passwd'] = 1;
3547
		$this->Form->request->data['Contact']['passwd'] = 'test';
3548
		$result = $this->Form->password('Contact.passwd', array('id' => 'theID'));
0 ignored issues
show
Documentation Bug introduced by
The method password does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
3549
		$this->assertTags($result, array('input' => array('type' => 'password', 'name' => 'data[Contact][passwd]', 'value' => 'test', 'id' => 'theID', 'class' => 'form-error')));
3550
	}
3551
3552
/**
3553
 * testRadio method
3554
 *
3555
 * Test radio element set generation
3556
 *
3557
 * @return void
3558
 */
3559
	public function testRadio() {
3560
		$result = $this->Form->radio('Model.field', array('option A'));
3561
		$expected = array(
3562
			'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '', 'id' => 'ModelField_'),
3563
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField0')),
3564
			'label' => array('for' => 'ModelField0'),
3565
			'option A',
3566
			'/label'
3567
		);
3568
		$this->assertTags($result, $expected);
3569
3570
		$result = $this->Form->radio('Model.field', array('1/2' => 'half'));
3571
		$expected = array(
3572
			'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '', 'id' => 'ModelField_'),
3573
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '1/2', 'id' => 'ModelField12')),
3574
			'label' => array('for' => 'ModelField12'),
3575
			'half',
3576
			'/label'
3577
		);
3578
		$this->assertTags($result, $expected);
3579
3580
		$result = $this->Form->radio('Model.field', array('option A', 'option B'));
3581
		$expected = array(
3582
			'fieldset' => array(),
3583
			'legend' => array(),
3584
			'Field',
3585
			'/legend',
3586
			'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '', 'id' => 'ModelField_'),
3587
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField0')),
3588
			array('label' => array('for' => 'ModelField0')),
3589
			'option A',
3590
			'/label',
3591
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField1')),
3592
			array('label' => array('for' => 'ModelField1')),
3593
			'option B',
3594
			'/label',
3595
			'/fieldset'
3596
		);
3597
		$this->assertTags($result, $expected);
3598
3599
		$result = $this->Form->radio('Model.field', array('option A', 'option B'), array('separator' => '<br/>'));
3600
		$expected = array(
3601
			'fieldset' => array(),
3602
			'legend' => array(),
3603
			'Field',
3604
			'/legend',
3605
			'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '', 'id' => 'ModelField_'),
3606
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField0')),
3607
			array('label' => array('for' => 'ModelField0')),
3608
			'option A',
3609
			'/label',
3610
			'br' => array(),
3611
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField1')),
3612
			array('label' => array('for' => 'ModelField1')),
3613
			'option B',
3614
			'/label',
3615
			'/fieldset'
3616
		);
3617
		$this->assertTags($result, $expected);
3618
3619
		$result = $this->Form->radio(
3620
			'Employee.gender',
3621
			array('male' => 'Male', 'female' => 'Female'),
3622
			array('form' => 'my-form')
3623
		);
3624
		$expected = array(
3625
			'fieldset' => array(),
3626
			'legend' => array(),
3627
			'Gender',
3628
			'/legend',
3629
			'input' => array('type' => 'hidden', 'name' => 'data[Employee][gender]', 'value' => '', 'id' => 'EmployeeGender_', 'form' => 'my-form'),
3630
			array('input' => array('type' => 'radio', 'name' => 'data[Employee][gender]', 'value' => 'male', 'id' => 'EmployeeGenderMale', 'form' => 'my-form')),
3631
			array('label' => array('for' => 'EmployeeGenderMale')),
3632
			'Male',
3633
			'/label',
3634
			array('input' => array('type' => 'radio', 'name' => 'data[Employee][gender]', 'value' => 'female', 'id' => 'EmployeeGenderFemale', 'form' => 'my-form')),
3635
			array('label' => array('for' => 'EmployeeGenderFemale')),
3636
			'Female',
3637
			'/label',
3638
			'/fieldset',
3639
		);
3640
		$this->assertTags($result, $expected);
3641
3642
		$result = $this->Form->radio('Officer.gender', array('male' => 'Male', 'female' => 'Female'));
3643
		$expected = array(
3644
			'fieldset' => array(),
3645
			'legend' => array(),
3646
			'Gender',
3647
			'/legend',
3648
			'input' => array('type' => 'hidden', 'name' => 'data[Officer][gender]', 'value' => '', 'id' => 'OfficerGender_'),
3649
			array('input' => array('type' => 'radio', 'name' => 'data[Officer][gender]', 'value' => 'male', 'id' => 'OfficerGenderMale')),
3650
			array('label' => array('for' => 'OfficerGenderMale')),
3651
			'Male',
3652
			'/label',
3653
			array('input' => array('type' => 'radio', 'name' => 'data[Officer][gender]', 'value' => 'female', 'id' => 'OfficerGenderFemale')),
3654
			array('label' => array('for' => 'OfficerGenderFemale')),
3655
			'Female',
3656
			'/label',
3657
			'/fieldset',
3658
		);
3659
		$this->assertTags($result, $expected);
3660
3661
		$result = $this->Form->radio('Contact.1.imrequired', array('option A'));
3662
		$expected = array(
3663
			'input' => array('type' => 'hidden', 'name' => 'data[Contact][1][imrequired]', 'value' => '', 'id' => 'Contact1Imrequired_'),
3664
			array('input' => array(
3665
				'type' => 'radio',
3666
				'name' => 'data[Contact][1][imrequired]',
3667
				'value' => '0',
3668
				'id' => 'Contact1Imrequired0',
3669
				'required' => 'required'
3670
			)),
3671
			'label' => array('for' => 'Contact1Imrequired0'),
3672
			'option A',
3673
			'/label'
3674
		);
3675
		$this->assertTags($result, $expected);
3676
3677
		$result = $this->Form->radio('Model.1.field', array('option A'));
3678
		$expected = array(
3679
			'input' => array('type' => 'hidden', 'name' => 'data[Model][1][field]', 'value' => '', 'id' => 'Model1Field_'),
3680
			array('input' => array('type' => 'radio', 'name' => 'data[Model][1][field]', 'value' => '0', 'id' => 'Model1Field0')),
3681
			'label' => array('for' => 'Model1Field0'),
3682
			'option A',
3683
			'/label'
3684
		);
3685
		$this->assertTags($result, $expected);
3686
3687
		$result = $this->Form->radio('Model.field', array('option A', 'option B'), array('name' => 'data[Model][custom]'));
3688
		$expected = array(
3689
			'fieldset' => array(),
3690
			'legend' => array(),
3691
			'Field',
3692
			'/legend',
3693
			'input' => array('type' => 'hidden', 'name' => 'data[Model][custom]', 'value' => '', 'id' => 'ModelField_'),
3694
			array('input' => array('type' => 'radio', 'name' => 'data[Model][custom]', 'value' => '0', 'id' => 'ModelField0')),
3695
			array('label' => array('for' => 'ModelField0')),
3696
			'option A',
3697
			'/label',
3698
			array('input' => array('type' => 'radio', 'name' => 'data[Model][custom]', 'value' => '1', 'id' => 'ModelField1')),
3699
			array('label' => array('for' => 'ModelField1')),
3700
			'option B',
3701
			'/label',
3702
			'/fieldset'
3703
		);
3704
		$this->assertTags($result, $expected);
3705
3706
		$result = $this->Form->radio(
3707
			'Model.field',
3708
			array('a>b' => 'first', 'a<b' => 'second', 'a"b' => 'third')
3709
		);
3710
		$expected = array(
3711
			'fieldset' => array(),
3712
			'legend' => array(),
3713
			'Field',
3714
			'/legend',
3715
			'input' => array(
3716
				'type' => 'hidden', 'name' => 'data[Model][field]',
3717
				'id' => 'ModelField_', 'value' => '',
3718
			),
3719
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]',
3720
				'id' => 'ModelFieldAB', 'value' => 'a&gt;b')),
3721
			array('label' => array('for' => 'ModelFieldAB')),
3722
			'first',
3723
			'/label',
3724
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]',
3725
				'id' => 'ModelFieldAB1', 'value' => 'a&lt;b')),
3726
			array('label' => array('for' => 'ModelFieldAB1')),
3727
			'second',
3728
			'/label',
3729
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]',
3730
				'id' => 'ModelFieldAB2', 'value' => 'a&quot;b')),
3731
			array('label' => array('for' => 'ModelFieldAB2')),
3732
			'third',
3733
			'/label',
3734
			'/fieldset'
3735
		);
3736
		$this->assertTags($result, $expected);
3737
	}
3738
3739
/**
3740
 * testRadioDifferentModel
3741
 * Refs #2911
3742
 *
3743
 * @return void
3744
 */
3745
	public function testRadioDifferentModel() {
3746
		$this->Form->create('User');
3747
3748
		$result = $this->Form->radio(
3749
			'Model.field',
3750
			array('v1' => 'option A', 'v2' => 'option B'),
3751
			array('label' => true, 'legend' => false, 'value' => false)
3752
		);
3753
		$expected = array(
3754
			array('input' => array(
3755
				'type' => 'radio', 'name' => 'data[Model][field]',
3756
				'value' => 'v1', 'id' => 'ModelFieldV1'
3757
			)),
3758
			array('label' => array('for' => 'ModelFieldV1')),
3759
			'option A',
3760
			'/label',
3761
			array('input' => array(
3762
				'type' => 'radio', 'name' => 'data[Model][field]',
3763
				'value' => 'v2', 'id' => 'ModelFieldV2'
3764
			)),
3765
			array('label' => array('for' => 'ModelFieldV2')),
3766
			'option B',
3767
			'/label'
3768
		);
3769
		$this->assertTags($result, $expected);
3770
	}
3771
3772
/**
3773
 * Test radio inputs with between as string or array. Also ensure
3774
 * that an array with less between elements works.
3775
 *
3776
 * @return void
3777
 */
3778
	public function testRadioBetween() {
3779
		$result = $this->Form->radio(
3780
			'Model.field',
3781
			array('option A', 'option B'),
3782
			array('between' => 'I am between')
3783
		);
3784
		$expected = array(
3785
			'fieldset' => array(),
3786
			'legend' => array(),
3787
			'Field',
3788
			'/legend',
3789
			'I am between',
3790
			'input' => array(
3791
				'type' => 'hidden', 'name' => 'data[Model][field]',
3792
				'value' => '', 'id' => 'ModelField_'
3793
			),
3794
			array('input' => array(
3795
				'type' => 'radio', 'name' => 'data[Model][field]',
3796
				'value' => '0', 'id' => 'ModelField0'
3797
			)),
3798
			array('label' => array('for' => 'ModelField0')),
3799
			'option A',
3800
			'/label',
3801
			array('input' => array(
3802
				'type' => 'radio', 'name' => 'data[Model][field]',
3803
				'value' => '1', 'id' => 'ModelField1'
3804
			)),
3805
			array('label' => array('for' => 'ModelField1')),
3806
			'option B',
3807
			'/label',
3808
			'/fieldset'
3809
		);
3810
		$this->assertTags($result, $expected);
3811
3812
		$result = $this->Form->radio(
3813
			'Model.field',
3814
			array('option A', 'option B', 'option C'),
3815
			array('separator' => '--separator--', 'between' => array('between A', 'between B', 'between C'))
3816
		);
3817
3818
		$expected = array(
3819
			'fieldset' => array(),
3820
			'legend' => array(),
3821
			'Field',
3822
			'/legend',
3823
			'input' => array(
3824
				'type' => 'hidden', 'name' => 'data[Model][field]',
3825
				'value' => '', 'id' => 'ModelField_'
3826
			),
3827
			array('input' => array(
3828
				'type' => 'radio', 'name' => 'data[Model][field]',
3829
				'value' => '0', 'id' => 'ModelField0'
3830
			)),
3831
			array('label' => array('for' => 'ModelField0')),
3832
			'option A',
3833
			'/label',
3834
			'between A',
3835
			'--separator--',
3836
			array('input' => array(
3837
				'type' => 'radio', 'name' => 'data[Model][field]',
3838
				'value' => '1', 'id' => 'ModelField1'
3839
			)),
3840
			array('label' => array('for' => 'ModelField1')),
3841
			'option B',
3842
			'/label',
3843
			'between B',
3844
			'--separator--',
3845
			array('input' => array(
3846
				'type' => 'radio', 'name' => 'data[Model][field]',
3847
				'value' => '2', 'id' => 'ModelField2'
3848
			)),
3849
			array('label' => array('for' => 'ModelField2')),
3850
			'option C',
3851
			'/label',
3852
			'between C',
3853
			'/fieldset'
3854
		);
3855
		$this->assertTags($result, $expected);
3856
3857
		$result = $this->Form->input('Model.field', array(
3858
			'options' => array('1' => 'first', '2' => 'second'),
3859
			'type' => 'radio',
3860
			'before' => '--before--',
3861
			'after' => '--after--',
3862
			'separator' => '--separator--',
3863
			'between' => array('--between first--', '--between second--')
3864
		));
3865
3866
		$expected = array(
3867
			'div' => array('class' => 'input radio'),
3868
			'--before--',
3869
			'fieldset' => array(),
3870
			'legend' => array(),
3871
			'Field',
3872
			'/legend',
3873
			array('input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'id' => 'ModelField_', 'value' => '')),
3874
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField1')),
3875
			array('label' => array('for' => 'ModelField1')),
3876
			'first',
3877
			'/label',
3878
			'--between first--',
3879
			'--separator--',
3880
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '2', 'id' => 'ModelField2')),
3881
			array('label' => array('for' => 'ModelField2')),
3882
			'second',
3883
			'/label',
3884
			'--between second--',
3885
			'/fieldset',
3886
			'--after--',
3887
			'/div'
3888
		);
3889
		$this->assertTags($result, $expected);
3890
3891
		$result = $this->Form->input('Model.field', array(
3892
			'options' => array('1' => 'first', '2' => 'second'),
3893
			'type' => 'radio',
3894
			'before' => '--before--',
3895
			'after' => '--after--',
3896
			'separator' => '--separator--',
3897
			'between' => array('--between first--')
3898
		));
3899
3900
		$expected = array(
3901
			'div' => array('class' => 'input radio'),
3902
			'--before--',
3903
			'fieldset' => array(),
3904
			'legend' => array(),
3905
			'Field',
3906
			'/legend',
3907
			array('input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'id' => 'ModelField_', 'value' => '')),
3908
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField1')),
3909
			array('label' => array('for' => 'ModelField1')),
3910
			'first',
3911
			'/label',
3912
			'--between first--',
3913
			'--separator--',
3914
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '2', 'id' => 'ModelField2')),
3915
			array('label' => array('for' => 'ModelField2')),
3916
			'second',
3917
			'/label',
3918
			'/fieldset',
3919
			'--after--',
3920
			'/div'
3921
		);
3922
		$this->assertTags($result, $expected);
3923
	}
3924
3925
/**
3926
 * Test that radios with a 0 value are selected under the correct conditions.
3927
 * Also ensure that values that are booleanish are handled correctly.
3928
 *
3929
 * @return void
3930
 */
3931
	public function testRadioOptionWithBooleanishValues() {
3932
		$expected = array(
3933
			'fieldset' => array(),
3934
			'legend' => array(),
3935
			'Field',
3936
			'/legend',
3937
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField1')),
3938
			array('label' => array('for' => 'ModelField1')),
3939
			'Yes',
3940
			'/label',
3941
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField0', 'checked' => 'checked')),
3942
			array('label' => array('for' => 'ModelField0')),
3943
			'No',
3944
			'/label',
3945
			'/fieldset'
3946
		);
3947
		$result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'), array('value' => '0'));
3948
		$this->assertTags($result, $expected);
3949
3950
		$result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'), array('value' => 0));
3951
		$this->assertTags($result, $expected);
3952
3953
		$result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'), array('value' => false));
3954
		$this->assertTags($result, $expected);
3955
3956
		$expected = array(
3957
			'fieldset' => array(),
3958
			'legend' => array(),
3959
			'Field',
3960
			'/legend',
3961
			'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '', 'id' => 'ModelField_'),
3962
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField1')),
3963
			array('label' => array('for' => 'ModelField1')),
3964
			'Yes',
3965
			'/label',
3966
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField0')),
3967
			array('label' => array('for' => 'ModelField0')),
3968
			'No',
3969
			'/label',
3970
			'/fieldset'
3971
		);
3972
		$result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'), array('value' => null));
3973
		$this->assertTags($result, $expected);
3974
3975
		$result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'), array('value' => ''));
3976
		$this->assertTags($result, $expected);
3977
3978
		$result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'));
3979
		$this->assertTags($result, $expected);
3980
3981
		$expected = array(
3982
			'fieldset' => array(),
3983
			'legend' => array(),
3984
			'Field',
3985
			'/legend',
3986
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'checked' => 'checked', 'value' => '1', 'id' => 'ModelField1')),
3987
			array('label' => array('for' => 'ModelField1')),
3988
			'Yes',
3989
			'/label',
3990
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField0')),
3991
			array('label' => array('for' => 'ModelField0')),
3992
			'No',
3993
			'/label',
3994
			'/fieldset'
3995
		);
3996
		$result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'), array('value' => 1));
3997
		$this->assertTags($result, $expected);
3998
3999
		$result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'), array('value' => '1'));
4000
		$this->assertTags($result, $expected);
4001
4002
		$result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'), array('value' => true));
4003
		$this->assertTags($result, $expected);
4004
	}
4005
4006
/**
4007
 * test disabled radio options
4008
 *
4009
 * @return void
4010
 */
4011
	public function testRadioDisabled() {
4012
		$result = $this->Form->radio(
4013
			'Model.field',
4014
			array('option A', 'option B'),
4015
			array('disabled' => array(0), 'value' => '0')
4016
		);
4017
		$expected = array(
4018
			'fieldset' => array(),
4019
			'legend' => array(),
4020
			'Field',
4021
			'/legend',
4022
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField0', 'disabled' => 'disabled', 'checked' => 'checked')),
4023
			array('label' => array('for' => 'ModelField0')),
4024
			'option A',
4025
			'/label',
4026
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField1')),
4027
			array('label' => array('for' => 'ModelField1')),
4028
			'option B',
4029
			'/label',
4030
			'/fieldset'
4031
		);
4032
		$this->assertTags($result, $expected);
4033
4034
		$result = $this->Form->radio(
4035
			'Model.field',
4036
			array('option A', 'option B'),
4037
			array('disabled' => true, 'value' => '0')
4038
		);
4039
		$expected = array(
4040
			'fieldset' => array(),
4041
			'legend' => array(),
4042
			'Field',
4043
			'/legend',
4044
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField0', 'disabled' => 'disabled', 'checked' => 'checked')),
4045
			array('label' => array('for' => 'ModelField0')),
4046
			'option A',
4047
			'/label',
4048
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField1', 'disabled' => 'disabled')),
4049
			array('label' => array('for' => 'ModelField1')),
4050
			'option B',
4051
			'/label',
4052
			'/fieldset'
4053
		);
4054
		$this->assertTags($result, $expected);
4055
4056
		$result = $this->Form->radio(
4057
			'Model.field',
4058
			array('option A', 'option B'),
4059
			array('disabled' => 'disabled', 'value' => '0')
4060
		);
4061
		$expected = array(
4062
			'fieldset' => array(),
4063
			'legend' => array(),
4064
			'Field',
4065
			'/legend',
4066
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField0', 'disabled' => 'disabled', 'checked' => 'checked')),
4067
			array('label' => array('for' => 'ModelField0')),
4068
			'option A',
4069
			'/label',
4070
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField1', 'disabled' => 'disabled')),
4071
			array('label' => array('for' => 'ModelField1')),
4072
			'option B',
4073
			'/label',
4074
			'/fieldset'
4075
		);
4076
		$this->assertTags($result, $expected);
4077
4078
		$result = $this->Form->input('Model.field', array(
4079
			'options' => array(1 => 'first', 2 => 'second', '2x' => '2x', '3' => 'third', '3x' => '3x'),
4080
			'type' => 'radio',
4081
			'disabled' => array(2, '3x'),
4082
		));
4083
4084
		$expected = array(
4085
			'div' => array('class' => 'input radio'),
4086
			'fieldset' => array(),
4087
			'legend' => array(),
4088
			'Field',
4089
			'/legend',
4090
			array('input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'id' => 'ModelField_', 'value' => '')),
4091
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField1')),
4092
			array('label' => array('for' => 'ModelField1')),
4093
			'first',
4094
			'/label',
4095
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'disabled' => 'disabled', 'value' => '2', 'id' => 'ModelField2')),
4096
			array('label' => array('for' => 'ModelField2')),
4097
			'second',
4098
			'/label',
4099
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '2x', 'id' => 'ModelField2x')),
4100
			array('label' => array('for' => 'ModelField2x')),
4101
			'2x',
4102
			'/label',
4103
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '3', 'id' => 'ModelField3')),
4104
			array('label' => array('for' => 'ModelField3')),
4105
			'third',
4106
			'/label',
4107
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'disabled' => 'disabled', 'value' => '3x', 'id' => 'ModelField3x')),
4108
			array('label' => array('for' => 'ModelField3x')),
4109
			'3x',
4110
			'/label',
4111
			'/fieldset',
4112
			'/div'
4113
		);
4114
		$this->assertTags($result, $expected);
4115
4116
		$result = $this->Form->input('Model.field', array(
4117
			'type' => 'radio',
4118
			'options' => array(
4119
				1 => 'A',
4120
				2 => 'B',
4121
				3 => 'C'
4122
			),
4123
			'disabled' => array(1)
4124
		));
4125
4126
		$expected = array(
4127
			'div' => array('class' => 'input radio'),
4128
			'fieldset' => array(),
4129
			'legend' => array(),
4130
			'Field',
4131
			'/legend',
4132
			array('input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'id' => 'ModelField_', 'value' => '')),
4133
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'id' => 'ModelField1', 'disabled' => 'disabled', 'value' => '1')),
4134
			array('label' => array('for' => 'ModelField1')),
4135
			'A',
4136
			'/label',
4137
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'id' => 'ModelField2', 'value' => '2')),
4138
			array('label' => array('for' => 'ModelField2')),
4139
			'B',
4140
			'/label',
4141
			array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'id' => 'ModelField3', 'value' => '3')),
4142
			array('label' => array('for' => 'ModelField3')),
4143
			'C',
4144
			'/label',
4145
			'/fieldset',
4146
			'/div'
4147
		);
4148
		$this->assertTags($result, $expected);
4149
	}
4150
4151
/**
4152
 * test disabling the hidden input for radio buttons
4153
 *
4154
 * @return void
4155
 */
4156
	public function testRadioHiddenInputDisabling() {
4157
		$result = $this->Form->input('Model.1.field', array(
4158
				'type' => 'radio',
4159
				'options' => array('option A'),
4160
				'hiddenField' => false
4161
			)
4162
		);
4163
		$expected = array(
4164
			'div' => array('class' => 'input radio'),
4165
			'input' => array('type' => 'radio', 'name' => 'data[Model][1][field]', 'value' => '0', 'id' => 'Model1Field0'),
4166
			'label' => array('for' => 'Model1Field0'),
4167
			'option A',
4168
			'/label',
4169
			'/div'
4170
		);
4171
		$this->assertTags($result, $expected);
4172
4173
		$result = $this->Form->radio('Model.1.field', array('option A'), array('hiddenField' => false));
4174
		$expected = array(
4175
			'input' => array('type' => 'radio', 'name' => 'data[Model][1][field]', 'value' => '0', 'id' => 'Model1Field0'),
4176
			'label' => array('for' => 'Model1Field0'),
4177
			'option A',
4178
			'/label'
4179
		);
4180
		$this->assertTags($result, $expected);
4181
	}
4182
4183
/**
4184
 * test adding an empty option for radio buttons
4185
 *
4186
 * @return void
4187
 */
4188
	public function testRadioAddEmptyOption() {
4189
		$result = $this->Form->input('Model.1.field', array(
4190
			'type' => 'radio',
4191
			'options' => array('option A'),
4192
			'empty' => true,
4193
			'hiddenField' => false
4194
		));
4195
		$expected = array(
4196
			'div' => array('class' => 'input radio'),
4197
				'fieldset' => array(),
4198
					'legend' => array(),
4199
						'Field',
4200
					'/legend',
4201
					array('input' => array('type' => 'radio', 'name' => 'data[Model][1][field]', 'value' => '', 'id' => 'Model1Field')),
4202
					array('label' => array('for' => 'Model1Field')),
4203
						__('empty'),
4204
					'/label',
4205
					array('input' => array('type' => 'radio', 'name' => 'data[Model][1][field]', 'value' => '0', 'id' => 'Model1Field0')),
4206
					array('label' => array('for' => 'Model1Field0')),
4207
						'option A',
4208
					'/label',
4209
				'/fieldset',
4210
			'/div'
4211
		);
4212
		$this->assertTags($result, $expected);
4213
4214
		$result = $this->Form->input('Model.1.field', array(
4215
			'type' => 'radio',
4216
			'options' => array('option A'),
4217
			'empty' => 'CustomEmptyLabel',
4218
			'hiddenField' => false
4219
		));
4220
		$expected = array(
4221
			'div' => array('class' => 'input radio'),
4222
				'fieldset' => array(),
4223
					'legend' => array(),
4224
						'Field',
4225
					'/legend',
4226
					array('input' => array('type' => 'radio', 'name' => 'data[Model][1][field]', 'value' => '', 'id' => 'Model1Field')),
4227
					array('label' => array('for' => 'Model1Field')),
4228
						'CustomEmptyLabel',
4229
					'/label',
4230
					array('input' => array('type' => 'radio', 'name' => 'data[Model][1][field]', 'value' => '0', 'id' => 'Model1Field0')),
4231
					array('label' => array('for' => 'Model1Field0')),
4232
						'option A',
4233
					'/label',
4234
				'/fieldset',
4235
			'/div'
4236
		);
4237
		$this->assertTags($result, $expected);
4238
4239
		$result = $this->Form->input('Model.1.field', array(
4240
			'type' => 'radio',
4241
			'options' => array('option A'),
4242
			'empty' => false,
4243
			'hiddenField' => false
4244
		));
4245
		$this->assertTextNotContains('"Model1Field"', $result);
4246
	}
4247
4248
/**
4249
 * Test that radio() accepts an array for label
4250
 *
4251
 * @return void
4252
 */
4253
	public function testRadioLabelArray() {
4254
		$result = $this->Form->input('Model.field', array(
4255
			'type' => 'radio',
4256
			'legend' => false,
4257
			'label' => array(
4258
				'class' => 'checkbox float-left',
4259
			),
4260
			'options' => array('1' => 'Option A', '2' => 'Option B.')
4261
		));
4262
		$this->assertTextContains(
4263
			'<label for="ModelField1" class="checkbox float-left">Option A</label>',
4264
			$result
4265
		);
4266
	}
4267
4268
/**
4269
 * Test that label id's match the input element id's when radio is called after create().
4270
 *
4271
 * @return void
4272
 */
4273
	public function testRadioWithCreate() {
4274
		$this->Form->create('Model');
4275
		$result = $this->Form->radio('recipient',
4276
			array('1' => '1', '2' => '2', '3' => '3'),
4277
			array('legend' => false, 'value' => '1')
4278
		);
4279
		$this->assertTextNotContains(
4280
			'<label for="ModelModelRecipient1">1</label>',
4281
			$result
4282
		);
4283
		$this->assertTextContains(
4284
			'<label for="ModelRecipient1">1</label>',
4285
			$result
4286
		);
4287
	}
4288
4289
/**
4290
 * testDomIdSuffix method
4291
 *
4292
 * @return void
4293
 */
4294
	public function testDomIdSuffix() {
4295
		$result = $this->Form->domIdSuffix('1 string with 1$-dollar signs');
4296
		$this->assertEquals('1StringWith1DollarSigns', $result);
4297
4298
		$result = $this->Form->domIdSuffix('<abc x="foo" y=\'bar\'>');
4299
		$this->assertEquals('AbcXFooYBar', $result);
4300
4301
		$result = $this->Form->domIdSuffix('1 string with 1$-dollar signs', 'html5');
4302
		$this->assertEquals('1StringWith1$-dollarSigns', $result);
4303
4304
		$result = $this->Form->domIdSuffix('<abc x="foo" y=\'bar\'>', 'html5');
4305
		$this->assertEquals('AbcX=FooY=Bar', $result);
4306
	}
4307
4308
/**
4309
 * testDomIdSuffixCollisionResolvement()
4310
 *
4311
 * @return void
4312
 */
4313
	public function testDomIdSuffixCollisionResolvement() {
4314
		$result = $this->Form->domIdSuffix('a>b');
4315
		$this->assertEquals('AB', $result);
4316
4317
		$result = $this->Form->domIdSuffix('a<b');
4318
		$this->assertEquals('AB1', $result);
4319
4320
		$result = $this->Form->domIdSuffix('a\'b');
4321
		$this->assertEquals('AB2', $result);
4322
4323
		$result = $this->Form->domIdSuffix('1 string with 1$-dollar');
4324
		$this->assertEquals('1StringWith1Dollar', $result);
4325
4326
		$result = $this->Form->domIdSuffix('1 string with 1$-dollar');
4327
		$this->assertEquals('1StringWith1Dollar1', $result);
4328
4329
		$result = $this->Form->domIdSuffix('1 string with 1$-dollar');
4330
		$this->assertEquals('1StringWith1Dollar2', $result);
4331
	}
4332
4333
/**
4334
 * testSelect method
4335
 *
4336
 * Test select element generation.
4337
 *
4338
 * @return void
4339
 */
4340
	public function testSelect() {
4341
		$result = $this->Form->select('Model.field', array());
4342
		$expected = array(
4343
			'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
4344
			array('option' => array('value' => '')),
4345
			'/option',
4346
			'/select'
4347
		);
4348
		$this->assertTags($result, $expected);
4349
4350
		$this->Form->request->data = array('Model' => array('field' => 'value'));
4351
		$result = $this->Form->select('Model.field', array('value' => 'good', 'other' => 'bad'));
4352
		$expected = array(
4353
			'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
4354
			array('option' => array('value' => '')),
4355
			'/option',
4356
			array('option' => array('value' => 'value', 'selected' => 'selected')),
4357
			'good',
4358
			'/option',
4359
			array('option' => array('value' => 'other')),
4360
			'bad',
4361
			'/option',
4362
			'/select'
4363
		);
4364
		$this->assertTags($result, $expected);
4365
4366
		$this->Form->request->data = array();
4367
		$result = $this->Form->select('Model.field', array('value' => 'good', 'other' => 'bad'));
4368
		$expected = array(
4369
			'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
4370
			array('option' => array('value' => '')),
4371
			'/option',
4372
			array('option' => array('value' => 'value')),
4373
			'good',
4374
			'/option',
4375
			array('option' => array('value' => 'other')),
4376
			'bad',
4377
			'/option',
4378
			'/select'
4379
		);
4380
		$this->assertTags($result, $expected);
4381
4382
		$result = $this->Form->select(
4383
			'Model.field', array('first' => 'first "html" <chars>', 'second' => 'value'),
4384
			array('empty' => false)
4385
		);
4386
		$expected = array(
4387
			'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
4388
			array('option' => array('value' => 'first')),
4389
			'first &quot;html&quot; &lt;chars&gt;',
4390
			'/option',
4391
			array('option' => array('value' => 'second')),
4392
			'value',
4393
			'/option',
4394
			'/select'
4395
		);
4396
		$this->assertTags($result, $expected);
4397
4398
		$result = $this->Form->select(
4399
			'Model.field',
4400
			array('first' => 'first "html" <chars>', 'second' => 'value'),
4401
			array('escape' => false, 'empty' => false)
4402
		);
4403
		$expected = array(
4404
			'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
4405
			array('option' => array('value' => 'first')),
4406
			'first "html" <chars>',
4407
			'/option',
4408
			array('option' => array('value' => 'second')),
4409
			'value',
4410
			'/option',
4411
			'/select'
4412
		);
4413
		$this->assertTags($result, $expected);
4414
4415
		$options = array(
4416
			array('value' => 'first', 'name' => 'First'),
4417
			array('value' => 'first', 'name' => 'Another First'),
4418
		);
4419
		$result = $this->Form->select(
4420
			'Model.field',
4421
			$options,
4422
			array('escape' => false, 'empty' => false)
4423
		);
4424
		$expected = array(
4425
			'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
4426
			array('option' => array('value' => 'first')),
4427
			'First',
4428
			'/option',
4429
			array('option' => array('value' => 'first')),
4430
			'Another First',
4431
			'/option',
4432
			'/select'
4433
		);
4434
		$this->assertTags($result, $expected);
4435
4436
		$this->Form->request->data = array('Model' => array('contact_id' => 228));
4437
		$result = $this->Form->select(
4438
			'Model.contact_id',
4439
			array('228' => '228 value', '228-1' => '228-1 value', '228-2' => '228-2 value'),
4440
			array('escape' => false, 'empty' => 'pick something')
4441
		);
4442
4443
		$expected = array(
4444
			'select' => array('name' => 'data[Model][contact_id]', 'id' => 'ModelContactId'),
4445
			array('option' => array('value' => '')), 'pick something', '/option',
4446
			array('option' => array('value' => '228', 'selected' => 'selected')), '228 value', '/option',
4447
			array('option' => array('value' => '228-1')), '228-1 value', '/option',
4448
			array('option' => array('value' => '228-2')), '228-2 value', '/option',
4449
			'/select'
4450
		);
4451
		$this->assertTags($result, $expected);
4452
4453
		$this->Form->request->data['Model']['field'] = 0;
4454
		$result = $this->Form->select('Model.field', array('0' => 'No', '1' => 'Yes'));
4455
		$expected = array(
4456
			'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
4457
			array('option' => array('value' => '')), '/option',
4458
			array('option' => array('value' => '0', 'selected' => 'selected')), 'No', '/option',
4459
			array('option' => array('value' => '1')), 'Yes', '/option',
4460
			'/select'
4461
		);
4462
		$this->assertTags($result, $expected);
4463
4464
		$this->Form->request->data['Model']['field'] = 50;
4465
		$result = $this->Form->select('Model.field', array('50f5c0cf' => 'Stringy', '50' => 'fifty'));
4466
		$expected = array(
4467
			'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
4468
			array('option' => array('value' => '')), '/option',
4469
			array('option' => array('value' => '50f5c0cf')), 'Stringy', '/option',
4470
			array('option' => array('value' => '50', 'selected' => 'selected')), 'fifty', '/option',
4471
			'/select'
4472
		);
4473
		$this->assertTags($result, $expected);
4474
4475
		$result = $this->Form->select('Contact.required_one', array('option A'));
4476
		$expected = array(
4477
			'select' => array(
4478
				'name' => 'data[Contact][required_one]',
4479
				'id' => 'ContactRequiredOne',
4480
				'required' => 'required'
4481
			),
4482
			array('option' => array('value' => '')), '/option',
4483
			array('option' => array('value' => '0')), 'option A', '/option',
4484
			'/select'
4485
		);
4486
		$this->assertTags($result, $expected);
4487
4488
		$result = $this->Form->select('Contact.required_one', array('option A'), array('disabled' => true));
4489
		$expected = array(
4490
			'select' => array(
4491
				'name' => 'data[Contact][required_one]',
4492
				'id' => 'ContactRequiredOne',
4493
				'disabled' => 'disabled'
4494
			),
4495
			array('option' => array('value' => '')), '/option',
4496
			array('option' => array('value' => '0')), 'option A', '/option',
4497
			'/select'
4498
		);
4499
		$this->assertTags($result, $expected);
4500
	}
4501
4502
/**
4503
 * test that select() with optiongroups listens to the escape param.
4504
 *
4505
 * @return void
4506
 */
4507
	public function testSelectOptionGroupEscaping() {
4508
		$options = array(
4509
			'>< Key' => array(
4510
				1 => 'One',
4511
				2 => 'Two'
4512
			)
4513
		);
4514
		$result = $this->Form->select('Model.field', $options, array('empty' => false));
4515
		$expected = array(
4516
			'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
4517
			'optgroup' => array('label' => '&gt;&lt; Key'),
4518
			array('option' => array('value' => '1')), 'One', '/option',
4519
			array('option' => array('value' => '2')), 'Two', '/option',
4520
			'/optgroup',
4521
			'/select'
4522
		);
4523
		$this->assertTags($result, $expected);
4524
4525
		$options = array(
4526
			'>< Key' => array(
4527
				1 => 'One',
4528
				2 => 'Two'
4529
			)
4530
		);
4531
		$result = $this->Form->select('Model.field', $options, array('empty' => false, 'escape' => false));
4532
		$expected = array(
4533
			'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
4534
			'optgroup' => array('label' => '>< Key'),
4535
			array('option' => array('value' => '1')), 'One', '/option',
4536
			array('option' => array('value' => '2')), 'Two', '/option',
4537
			'/optgroup',
4538
			'/select'
4539
		);
4540
		$this->assertTags($result, $expected);
4541
	}
4542
4543
/**
4544
 * Tests that FormHelper::select() allows null to be passed in the $attributes parameter
4545
 *
4546
 * @return void
4547
 */
4548
	public function testSelectWithNullAttributes() {
4549
		$result = $this->Form->select('Model.field', array('first', 'second'), array('empty' => false));
4550
		$expected = array(
4551
			'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
4552
			array('option' => array('value' => '0')),
4553
			'first',
4554
			'/option',
4555
			array('option' => array('value' => '1')),
4556
			'second',
4557
			'/option',
4558
			'/select'
4559
		);
4560
		$this->assertTags($result, $expected);
4561
	}
4562
4563
/**
4564
 * testNestedSelect method
4565
 *
4566
 * test select element generation with optgroups
4567
 *
4568
 * @return void
4569
 */
4570
	public function testNestedSelect() {
4571
		$result = $this->Form->select(
4572
			'Model.field',
4573
			array(1 => 'One', 2 => 'Two', 'Three' => array(
4574
				3 => 'Three', 4 => 'Four', 5 => 'Five'
4575
			)), array('empty' => false)
4576
		);
4577
		$expected = array(
4578
			'select' => array('name' => 'data[Model][field]',
4579
					'id' => 'ModelField'),
4580
					array('option' => array('value' => 1)),
4581
					'One',
4582
					'/option',
4583
					array('option' => array('value' => 2)),
4584
					'Two',
4585
					'/option',
4586
					array('optgroup' => array('label' => 'Three')),
4587
						array('option' => array('value' => 4)),
4588
						'Four',
4589
						'/option',
4590
						array('option' => array('value' => 5)),
4591
						'Five',
4592
						'/option',
4593
					'/optgroup',
4594
					'/select'
4595
					);
4596
		$this->assertTags($result, $expected);
4597
4598
		$result = $this->Form->select(
4599
			'Model.field',
4600
			array(1 => 'One', 2 => 'Two', 'Three' => array(3 => 'Three', 4 => 'Four')),
4601
			array('showParents' => true, 'empty' => false)
4602
		);
4603
4604
		$expected = array(
4605
			'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
4606
				array('option' => array('value' => 1)),
4607
				'One',
4608
				'/option',
4609
				array('option' => array('value' => 2)),
4610
				'Two',
4611
				'/option',
4612
				array('optgroup' => array('label' => 'Three')),
4613
					array('option' => array('value' => 3)),
4614
					'Three',
4615
					'/option',
4616
					array('option' => array('value' => 4)),
4617
					'Four',
4618
					'/option',
4619
				'/optgroup',
4620
			'/select'
4621
		);
4622
		$this->assertTags($result, $expected);
4623
	}
4624
4625
/**
4626
 * testSelectMultiple method
4627
 *
4628
 * test generation of multiple select elements
4629
 *
4630
 * @return void
4631
 */
4632
	public function testSelectMultiple() {
4633
		$options = array('first', 'second', 'third');
4634
		$result = $this->Form->select(
4635
			'Model.multi_field', $options, array('multiple' => true)
4636
		);
4637
		$expected = array(
4638
			'input' => array(
4639
				'type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField_'
4640
			),
4641
			'select' => array(
4642
				'name' => 'data[Model][multi_field][]',
4643
				'id' => 'ModelMultiField', 'multiple' => 'multiple'
4644
			),
4645
			array('option' => array('value' => '0')),
4646
			'first',
4647
			'/option',
4648
			array('option' => array('value' => '1')),
4649
			'second',
4650
			'/option',
4651
			array('option' => array('value' => '2')),
4652
			'third',
4653
			'/option',
4654
			'/select'
4655
		);
4656
		$this->assertTags($result, $expected);
4657
4658
		$result = $this->Form->select(
4659
			'Model.multi_field', $options, array('form' => 'my-form', 'multiple' => 'multiple')
4660
		);
4661
		$expected = array(
4662
			'input' => array(
4663
				'type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField_',
4664
				'form' => 'my-form',
4665
			),
4666
			'select' => array(
4667
				'name' => 'data[Model][multi_field][]',
4668
				'id' => 'ModelMultiField',
4669
				'multiple' => 'multiple',
4670
				'form' => 'my-form',
4671
			),
4672
			array('option' => array('value' => '0')),
4673
			'first',
4674
			'/option',
4675
			array('option' => array('value' => '1')),
4676
			'second',
4677
			'/option',
4678
			array('option' => array('value' => '2')),
4679
			'third',
4680
			'/option',
4681
			'/select'
4682
		);
4683
		$this->assertTags($result, $expected);
4684
4685
		$result = $this->Form->select(
4686
			'Model.multi_field', $options, array('multiple' => true, 'value' => array(0, 1))
4687
		);
4688
		$expected = array(
4689
			'input' => array(
4690
				'type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField_'
4691
			),
4692
			'select' => array(
4693
				'name' => 'data[Model][multi_field][]', 'id' => 'ModelMultiField',
4694
				'multiple' => 'multiple'
4695
			),
4696
			array('option' => array('value' => '0', 'selected' => 'selected')),
4697
			'first',
4698
			'/option',
4699
			array('option' => array('value' => '1', 'selected' => 'selected')),
4700
			'second',
4701
			'/option',
4702
			array('option' => array('value' => '2')),
4703
			'third',
4704
			'/option',
4705
			'/select'
4706
		);
4707
		$this->assertTags($result, $expected);
4708
4709
		$result = $this->Form->select(
4710
			'Model.multi_field', $options, array('multiple' => false, 'value' => array(0, 1))
4711
		);
4712
		$expected = array(
4713
			'select' => array(
4714
				'name' => 'data[Model][multi_field]', 'id' => 'ModelMultiField'
4715
			),
4716
			array('option' => array('value' => '0', 'selected' => 'selected')),
4717
			'first',
4718
			'/option',
4719
			array('option' => array('value' => '1', 'selected' => 'selected')),
4720
			'second',
4721
			'/option',
4722
			array('option' => array('value' => '2')),
4723
			'third',
4724
			'/option',
4725
			'/select'
4726
		);
4727
		$this->assertTags($result, $expected);
4728
4729
		$options = array(1 => 'One', 2 => 'Two', '3' => 'Three', '3x' => 'Stringy');
4730
		$selected = array('2', '3x');
4731
		$result = $this->Form->select(
4732
			'Model.multi_field', $options, array('multiple' => true, 'value' => $selected)
4733
		);
4734
		$expected = array(
4735
			'input' => array(
4736
				'type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField_'
4737
			),
4738
			'select' => array(
4739
				'name' => 'data[Model][multi_field][]', 'multiple' => 'multiple', 'id' => 'ModelMultiField'
4740
			),
4741
			array('option' => array('value' => '1')),
4742
			'One',
4743
			'/option',
4744
			array('option' => array('value' => '2', 'selected' => 'selected')),
4745
			'Two',
4746
			'/option',
4747
			array('option' => array('value' => '3')),
4748
			'Three',
4749
			'/option',
4750
			array('option' => array('value' => '3x', 'selected' => 'selected')),
4751
			'Stringy',
4752
			'/option',
4753
			'/select'
4754
		);
4755
		$this->assertTags($result, $expected);
4756
4757
		$result = $this->Form->select('Contact.required_one', array(
4758
			'1' => 'option A',
4759
			'2' => 'option B'
4760
		), array('multiple' => true));
4761
		$expected = array(
4762
			'input' => array(
4763
				'type' => 'hidden', 'name' => 'data[Contact][required_one]', 'value' => '', 'id' => 'ContactRequiredOne_'
4764
			),
4765
			'select' => array(
4766
				'name' => 'data[Contact][required_one][]',
4767
				'id' => 'ContactRequiredOne',
4768
				'required' => 'required',
4769
				'multiple' => 'multiple'
4770
			),
4771
			array('option' => array('value' => '1')), 'option A', '/option',
4772
			array('option' => array('value' => '2')), 'option B', '/option',
4773
			'/select'
4774
		);
4775
		$this->assertTags($result, $expected);
4776
4777
		$result = $this->Form->select(
4778
			'Model.multi_field',
4779
			array('a>b' => 'first', 'a<b' => 'second', 'a"b' => 'third'),
4780
			array('multiple' => true)
4781
		);
4782
		$expected = array(
4783
			'input' => array(
4784
				'type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '',
4785
				'id' => 'ModelMultiField_'
4786
			),
4787
			array('select' => array('name' => 'data[Model][multi_field][]',
4788
				'multiple' => 'multiple', 'id' => 'ModelMultiField'
4789
			)),
4790
			array('option' => array('value' => 'a&gt;b')),
4791
			'first',
4792
			'/option',
4793
			array('option' => array('value' => 'a&lt;b')),
4794
			'second',
4795
			'/option',
4796
			array('option' => array(
4797
				'value' => 'a&quot;b'
4798
			)),
4799
			'third',
4800
			'/option',
4801
			'/select'
4802
		);
4803
		$this->assertTags($result, $expected);
4804
	}
4805
4806
/**
4807
 * Test generating multiple select with disabled elements.
4808
 *
4809
 * @return void
4810
 */
4811
	public function testSelectMultipleWithDisabledElements() {
4812
		$options = array(1 => 'One', 2 => 'Two', '3' => 'Three', '3x' => 'Stringy');
4813
		$disabled = array(2, 3);
4814
		$result = $this->Form->select('Contact.multiple', $options, array('multiple' => 'multiple', 'disabled' => $disabled));
4815
		$expected = array(
4816
			'input' => array(
4817
				'type' => 'hidden', 'name' => 'data[Contact][multiple]', 'value' => '', 'id' => 'ContactMultiple_'
4818
			),
4819
			'select' => array(
4820
				'name' => 'data[Contact][multiple][]', 'multiple' => 'multiple', 'id' => 'ContactMultiple'
4821
			),
4822
			array('option' => array('value' => '1')),
4823
			'One',
4824
			'/option',
4825
			array('option' => array('value' => '2', 'disabled' => 'disabled')),
4826
			'Two',
4827
			'/option',
4828
			array('option' => array('value' => '3', 'disabled' => 'disabled')),
4829
			'Three',
4830
			'/option',
4831
			array('option' => array('value' => '3x')),
4832
			'Stringy',
4833
			'/option',
4834
			'/select'
4835
		);
4836
		$this->assertTags($result, $expected);
4837
4838
		$options = array(1 => 'One', 2 => 'Two', '3' => 'Three', '3x' => 'Stringy');
4839
		$disabled = array('2', '3x');
4840
		$result = $this->Form->input('Contact.multiple', array('multiple' => 'multiple', 'disabled' => $disabled, 'options' => $options));
4841
		$expected = array(
4842
			array('div' => array('class' => 'input select')),
4843
			array('label' => array('for' => 'ContactMultiple')),
4844
			'Multiple',
4845
			'/label',
4846
			'input' => array(
4847
				'type' => 'hidden', 'name' => 'data[Contact][multiple]', 'value' => '', 'id' => 'ContactMultiple_'
4848
			),
4849
			'select' => array(
4850
				'name' => 'data[Contact][multiple][]', 'multiple' => 'multiple', 'id' => 'ContactMultiple'
4851
			),
4852
			array('option' => array('value' => '1')),
4853
			'One',
4854
			'/option',
4855
			array('option' => array('value' => '2', 'disabled' => 'disabled')),
4856
			'Two',
4857
			'/option',
4858
			array('option' => array('value' => '3')),
4859
			'Three',
4860
			'/option',
4861
			array('option' => array('value' => '3x', 'disabled' => 'disabled')),
4862
			'Stringy',
4863
			'/option',
4864
			'/select',
4865
			'/div'
4866
		);
4867
		$this->assertTags($result, $expected);
4868
4869
		$options = array(1 => 'One', 2 => 'Two', '3' => 'Three', '3x' => 'Stringy');
4870
		$disabled = true;
4871
		$result = $this->Form->input('Contact.multiple', array('multiple' => 'multiple', 'disabled' => $disabled, 'options' => $options));
4872
		$expected = array(
4873
			array('div' => array('class' => 'input select')),
4874
			array('label' => array('for' => 'ContactMultiple')),
4875
			'Multiple',
4876
			'/label',
4877
			'input' => array(
4878
				'type' => 'hidden', 'name' => 'data[Contact][multiple]', 'value' => '', 'id' => 'ContactMultiple_'
4879
			),
4880
			'select' => array(
4881
				'name' => 'data[Contact][multiple][]', 'disabled' => 'disabled', 'multiple' => 'multiple', 'id' => 'ContactMultiple'
4882
			),
4883
			array('option' => array('value' => '1')),
4884
			'One',
4885
			'/option',
4886
			array('option' => array('value' => '2')),
4887
			'Two',
4888
			'/option',
4889
			array('option' => array('value' => '3')),
4890
			'Three',
4891
			'/option',
4892
			array('option' => array('value' => '3x')),
4893
			'Stringy',
4894
			'/option',
4895
			'/select',
4896
			'/div'
4897
		);
4898
		$this->assertTags($result, $expected);
4899
	}
4900
4901
/**
4902
 * Test generating select with disabled elements.
4903
 *
4904
 * @return void
4905
 */
4906
	public function testSelectWithDisabledElements() {
4907
		$options = array(1 => 'One', 2 => 'Two', '3' => 'Three', '3x' => 'Stringy');
4908
		$disabled = array(2, 3);
4909
		$result = $this->Form->select('Model.field', $options, array('disabled' => $disabled));
4910
		$expected = array(
4911
			'select' => array(
4912
				'name' => 'data[Model][field]', 'id' => 'ModelField'
4913
			),
4914
			array('option' => array('value' => '')),
4915
			'/option',
4916
			array('option' => array('value' => '1')),
4917
			'One',
4918
			'/option',
4919
			array('option' => array('value' => '2', 'disabled' => 'disabled')),
4920
			'Two',
4921
			'/option',
4922
			array('option' => array('value' => '3', 'disabled' => 'disabled')),
4923
			'Three',
4924
			'/option',
4925
			array('option' => array('value' => '3x')),
4926
			'Stringy',
4927
			'/option',
4928
			'/select'
4929
		);
4930
		$this->assertTags($result, $expected);
4931
4932
		$options = array(1 => 'One', 2 => 'Two', '3' => 'Three', '3x' => 'Stringy');
4933
		$disabled = array('2', '3x');
4934
		$result = $this->Form->input('Model.field', array('disabled' => $disabled, 'options' => $options));
4935
		$expected = array(
4936
			array('div' => array('class' => 'input select')),
4937
			array('label' => array('for' => 'ModelField')),
4938
			'Field',
4939
			'/label',
4940
			'select' => array(
4941
				'name' => 'data[Model][field]', 'id' => 'ModelField'
4942
			),
4943
			array('option' => array('value' => '1')),
4944
			'One',
4945
			'/option',
4946
			array('option' => array('value' => '2', 'disabled' => 'disabled')),
4947
			'Two',
4948
			'/option',
4949
			array('option' => array('value' => '3')),
4950
			'Three',
4951
			'/option',
4952
			array('option' => array('value' => '3x', 'disabled' => 'disabled')),
4953
			'Stringy',
4954
			'/option',
4955
			'/select',
4956
			'/div'
4957
		);
4958
		$this->assertTags($result, $expected);
4959
4960
		$options = array(1 => 'One', 2 => 'Two', '3' => 'Three', '3x' => 'Stringy');
4961
		$disabled = true;
4962
		$result = $this->Form->input('Model.field', array('disabled' => $disabled, 'options' => $options));
4963
		$expected = array(
4964
			array('div' => array('class' => 'input select')),
4965
			array('label' => array('for' => 'ModelField')),
4966
			'Field',
4967
			'/label',
4968
			'select' => array(
4969
				'name' => 'data[Model][field]', 'id' => 'ModelField', 'disabled' => 'disabled'
4970
			),
4971
			array('option' => array('value' => '1')),
4972
			'One',
4973
			'/option',
4974
			array('option' => array('value' => '2')),
4975
			'Two',
4976
			'/option',
4977
			array('option' => array('value' => '3')),
4978
			'Three',
4979
			'/option',
4980
			array('option' => array('value' => '3x')),
4981
			'Stringy',
4982
			'/option',
4983
			'/select',
4984
			'/div'
4985
		);
4986
		$this->assertTags($result, $expected);
4987
	}
4988
4989
/**
4990
 * test generation of habtm select boxes.
4991
 *
4992
 * @return void
4993
 */
4994
	public function testHabtmSelectBox() {
4995
		$this->View->viewVars['contactTags'] = array(
4996
			1 => 'blue',
4997
			2 => 'red',
4998
			3 => 'green'
4999
		);
5000
		$this->Form->request->data = array(
5001
			'Contact' => array(),
5002
			'ContactTag' => array(
5003
				array(
5004
					'id' => '1',
5005
					'name' => 'blue'
5006
				),
5007
				array(
5008
					'id' => 3,
5009
					'name' => 'green'
5010
				)
5011
			)
5012
		);
5013
		$this->Form->create('Contact');
5014
		$result = $this->Form->input('ContactTag', array('div' => false, 'label' => false));
5015
		$expected = array(
5016
			'input' => array(
5017
				'type' => 'hidden', 'name' => 'data[ContactTag][ContactTag]', 'value' => '', 'id' => 'ContactTagContactTag_'
5018
			),
5019
			'select' => array(
5020
				'name' => 'data[ContactTag][ContactTag][]', 'id' => 'ContactTagContactTag',
5021
				'multiple' => 'multiple'
5022
			),
5023
			array('option' => array('value' => '1', 'selected' => 'selected')),
5024
			'blue',
5025
			'/option',
5026
			array('option' => array('value' => '2')),
5027
			'red',
5028
			'/option',
5029
			array('option' => array('value' => '3', 'selected' => 'selected')),
5030
			'green',
5031
			'/option',
5032
			'/select'
5033
		);
5034
		$this->assertTags($result, $expected);
5035
5036
		// make sure only 50 is selected, and not 50f5c0cf
5037
		$this->View->viewVars['contactTags'] = array(
5038
			'1' => 'blue',
5039
			'50f5c0cf' => 'red',
5040
			'50' => 'green'
5041
		);
5042
		$this->Form->request->data = array(
5043
			'Contact' => array(),
5044
			'ContactTag' => array(
5045
				array(
5046
					'id' => 1,
5047
					'name' => 'blue'
5048
				),
5049
				array(
5050
					'id' => 50,
5051
					'name' => 'green'
5052
				)
5053
			)
5054
		);
5055
		$this->Form->create('Contact');
5056
		$result = $this->Form->input('ContactTag', array('div' => false, 'label' => false));
5057
		$expected = array(
5058
			'input' => array(
5059
				'type' => 'hidden', 'name' => 'data[ContactTag][ContactTag]', 'value' => '', 'id' => 'ContactTagContactTag_'
5060
			),
5061
			'select' => array(
5062
				'name' => 'data[ContactTag][ContactTag][]', 'id' => 'ContactTagContactTag',
5063
				'multiple' => 'multiple'
5064
			),
5065
			array('option' => array('value' => '1', 'selected' => 'selected')),
5066
			'blue',
5067
			'/option',
5068
			array('option' => array('value' => '50f5c0cf')),
5069
			'red',
5070
			'/option',
5071
			array('option' => array('value' => '50', 'selected' => 'selected')),
5072
			'green',
5073
			'/option',
5074
			'/select'
5075
		);
5076
		$this->assertTags($result, $expected);
5077
	}
5078
5079
/**
5080
 * test generation of multi select elements in checkbox format
5081
 *
5082
 * @return void
5083
 */
5084
	public function testSelectMultipleCheckboxes() {
5085
		$result = $this->Form->select(
5086
			'Model.multi_field',
5087
			array('first', 'second', 'third'),
5088
			array('multiple' => 'checkbox')
5089
		);
5090
5091
		$expected = array(
5092
			'input' => array(
5093
				'type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField'
5094
			),
5095
			array('div' => array('class' => 'checkbox')),
5096
			array('input' => array(
5097
				'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
5098
				'value' => '0', 'id' => 'ModelMultiField0'
5099
			)),
5100
			array('label' => array('for' => 'ModelMultiField0')),
5101
			'first',
5102
			'/label',
5103
			'/div',
5104
			array('div' => array('class' => 'checkbox')),
5105
			array('input' => array(
5106
				'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
5107
				'value' => '1', 'id' => 'ModelMultiField1'
5108
			)),
5109
			array('label' => array('for' => 'ModelMultiField1')),
5110
			'second',
5111
			'/label',
5112
			'/div',
5113
			array('div' => array('class' => 'checkbox')),
5114
			array('input' => array(
5115
				'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
5116
				'value' => '2', 'id' => 'ModelMultiField2'
5117
			)),
5118
			array('label' => array('for' => 'ModelMultiField2')),
5119
			'third',
5120
			'/label',
5121
			'/div'
5122
		);
5123
		$this->assertTags($result, $expected);
5124
5125
		$result = $this->Form->select(
5126
			'Model.multi_field',
5127
			array('a' => 'first', 'b' => 'second', 'c' => 'third'),
5128
			array('multiple' => 'checkbox')
5129
		);
5130
		$expected = array(
5131
			'input' => array(
5132
				'type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField'
5133
			),
5134
			array('div' => array('class' => 'checkbox')),
5135
			array('input' => array(
5136
				'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
5137
				'value' => 'a', 'id' => 'ModelMultiFieldA'
5138
			)),
5139
			array('label' => array('for' => 'ModelMultiFieldA')),
5140
			'first',
5141
			'/label',
5142
			'/div',
5143
			array('div' => array('class' => 'checkbox')),
5144
			array('input' => array(
5145
				'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
5146
				'value' => 'b', 'id' => 'ModelMultiFieldB'
5147
			)),
5148
			array('label' => array('for' => 'ModelMultiFieldB')),
5149
			'second',
5150
			'/label',
5151
			'/div',
5152
			array('div' => array('class' => 'checkbox')),
5153
			array('input' => array(
5154
				'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
5155
				'value' => 'c', 'id' => 'ModelMultiFieldC'
5156
			)),
5157
			array('label' => array('for' => 'ModelMultiFieldC')),
5158
			'third',
5159
			'/label',
5160
			'/div'
5161
		);
5162
		$this->assertTags($result, $expected);
5163
5164
		$result = $this->Form->select(
5165
			'Model.multi_field', array('1' => 'first'), array('multiple' => 'checkbox')
5166
		);
5167
		$expected = array(
5168
			'input' => array(
5169
				'type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField'
5170
			),
5171
			array('div' => array('class' => 'checkbox')),
5172
			array('input' => array(
5173
				'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
5174
				'value' => '1', 'id' => 'ModelMultiField1'
5175
			)),
5176
			array('label' => array('for' => 'ModelMultiField1')),
5177
			'first',
5178
			'/label',
5179
			'/div'
5180
		);
5181
		$this->assertTags($result, $expected);
5182
5183
		$this->Form->request->data = array('Model' => array('tags' => array(1)));
5184
		$result = $this->Form->select(
5185
			'Model.tags', array('1' => 'first', 'Array' => 'Array'), array('multiple' => 'checkbox')
5186
		);
5187
		$expected = array(
5188
			'input' => array(
5189
				'type' => 'hidden', 'name' => 'data[Model][tags]', 'value' => '', 'id' => 'ModelTags'
5190
			),
5191
			array('div' => array('class' => 'checkbox')),
5192
			array('input' => array(
5193
				'type' => 'checkbox', 'name' => 'data[Model][tags][]',
5194
				'value' => '1', 'id' => 'ModelTags1', 'checked' => 'checked'
5195
			)),
5196
			array('label' => array('for' => 'ModelTags1', 'class' => 'selected')),
5197
			'first',
5198
			'/label',
5199
			'/div',
5200
5201
			array('div' => array('class' => 'checkbox')),
5202
			array('input' => array(
5203
				'type' => 'checkbox', 'name' => 'data[Model][tags][]',
5204
				'value' => 'Array', 'id' => 'ModelTagsArray'
5205
			)),
5206
			array('label' => array('for' => 'ModelTagsArray')),
5207
			'Array',
5208
			'/label',
5209
			'/div'
5210
		);
5211
		$this->assertTags($result, $expected);
5212
5213
		$result = $this->Form->select(
5214
			'Model.multi_field',
5215
			array('a+' => 'first', 'a++' => 'second', 'a+++' => 'third'),
5216
			array('multiple' => 'checkbox')
5217
		);
5218
		$expected = array(
5219
			'input' => array(
5220
				'type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField'
5221
			),
5222
			array('div' => array('class' => 'checkbox')),
5223
			array('input' => array(
5224
				'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
5225
				'value' => 'a+', 'id' => 'ModelMultiFieldA2'
5226
			)),
5227
			array('label' => array('for' => 'ModelMultiFieldA2')),
5228
			'first',
5229
			'/label',
5230
			'/div',
5231
			array('div' => array('class' => 'checkbox')),
5232
			array('input' => array(
5233
				'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
5234
				'value' => 'a++', 'id' => 'ModelMultiFieldA1'
5235
			)),
5236
			array('label' => array('for' => 'ModelMultiFieldA1')),
5237
			'second',
5238
			'/label',
5239
			'/div',
5240
			array('div' => array('class' => 'checkbox')),
5241
			array('input' => array(
5242
				'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
5243
				'value' => 'a+++', 'id' => 'ModelMultiFieldA'
5244
			)),
5245
			array('label' => array('for' => 'ModelMultiFieldA')),
5246
			'third',
5247
			'/label',
5248
			'/div'
5249
		);
5250
5251
		$this->assertTags($result, $expected);
5252
5253
		$result = $this->Form->select(
5254
			'Model.multi_field',
5255
			array('a>b' => 'first', 'a<b' => 'second', 'a"b' => 'third'),
5256
			array('multiple' => 'checkbox')
5257
		);
5258
		$expected = array(
5259
			'input' => array(
5260
				'type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField'
5261
			),
5262
			array('div' => array('class' => 'checkbox')),
5263
			array('input' => array(
5264
				'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
5265
				'value' => 'a&gt;b', 'id' => 'ModelMultiFieldAB2'
5266
			)),
5267
			array('label' => array('for' => 'ModelMultiFieldAB2')),
5268
			'first',
5269
			'/label',
5270
			'/div',
5271
			array('div' => array('class' => 'checkbox')),
5272
			array('input' => array(
5273
				'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
5274
				'value' => 'a&lt;b', 'id' => 'ModelMultiFieldAB1'
5275
			)),
5276
			array('label' => array('for' => 'ModelMultiFieldAB1')),
5277
			'second',
5278
			'/label',
5279
			'/div',
5280
			array('div' => array('class' => 'checkbox')),
5281
			array('input' => array(
5282
				'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
5283
				'value' => 'a&quot;b', 'id' => 'ModelMultiFieldAB'
5284
			)),
5285
			array('label' => array('for' => 'ModelMultiFieldAB')),
5286
			'third',
5287
			'/label',
5288
			'/div'
5289
		);
5290
		$this->assertTags($result, $expected);
5291
	}
5292
5293
/**
5294
 * test multiple checkboxes with div styles.
5295
 *
5296
 * @return void
5297
 */
5298
	public function testSelectMultipleCheckboxDiv() {
5299
		$result = $this->Form->select(
5300
			'Model.tags',
5301
			array('first', 'second'),
5302
			array('multiple' => 'checkbox', 'class' => 'my-class')
5303
		);
5304
		$expected = array(
5305
			'input' => array(
5306
				'type' => 'hidden', 'name' => 'data[Model][tags]', 'value' => '', 'id' => 'ModelTags'
5307
			),
5308
			array('div' => array('class' => 'my-class')),
5309
			array('input' => array(
5310
				'type' => 'checkbox', 'name' => 'data[Model][tags][]',
5311
				'value' => '0', 'id' => 'ModelTags0'
5312
			)),
5313
			array('label' => array('for' => 'ModelTags0')), 'first', '/label',
5314
			'/div',
5315
5316
			array('div' => array('class' => 'my-class')),
5317
			array('input' => array(
5318
				'type' => 'checkbox', 'name' => 'data[Model][tags][]',
5319
				'value' => '1', 'id' => 'ModelTags1'
5320
			)),
5321
			array('label' => array('for' => 'ModelTags1')), 'second', '/label',
5322
			'/div'
5323
		);
5324
		$this->assertTags($result, $expected);
5325
5326
		$result = $this->Form->input('Model.tags', array(
5327
			'options' => array('first', 'second'),
5328
			'multiple' => 'checkbox',
5329
			'class' => 'my-class',
5330
			'div' => false,
5331
			'label' => false
5332
		));
5333
		$this->assertTags($result, $expected);
5334
5335
		$Contact = ClassRegistry::getObject('Contact');
5336
		$Contact->validationErrors['tags'] = 'Select atleast one option';
5337
		$result = $this->Form->input('Contact.tags', array(
5338
			'options' => array('one'),
5339
			'multiple' => 'checkbox',
5340
			'label' => false,
5341
			'div' => false
5342
		));
5343
		$expected = array(
5344
			'input' => array('type' => 'hidden', 'class' => 'form-error', 'name' => 'data[Contact][tags]', 'value' => '', 'id' => 'ContactTags'),
5345
			array('div' => array('class' => 'checkbox form-error')),
5346
			array('input' => array('type' => 'checkbox', 'name' => 'data[Contact][tags][]', 'value' => '0', 'id' => 'ContactTags0')),
5347
			array('label' => array('for' => 'ContactTags0')),
5348
			'one',
5349
			'/label',
5350
			'/div'
5351
		);
5352
		$this->assertTags($result, $expected);
5353
5354
		$result = $this->Form->input('Contact.tags', array(
5355
			'options' => array('one'),
5356
			'multiple' => 'checkbox',
5357
			'class' => 'mycheckbox',
5358
			'label' => false,
5359
			'div' => false
5360
		));
5361
		$expected = array(
5362
			'input' => array('type' => 'hidden', 'class' => 'form-error', 'name' => 'data[Contact][tags]', 'value' => '', 'id' => 'ContactTags'),
5363
			array('div' => array('class' => 'mycheckbox form-error')),
5364
			array('input' => array('type' => 'checkbox', 'name' => 'data[Contact][tags][]', 'value' => '0', 'id' => 'ContactTags0')),
5365
			array('label' => array('for' => 'ContactTags0')),
5366
			'one',
5367
			'/label',
5368
			'/div'
5369
		);
5370
		$this->assertTags($result, $expected);
5371
	}
5372
5373
/**
5374
 * Checks the security hash array generated for multiple-input checkbox elements
5375
 *
5376
 * @return void
5377
 */
5378
	public function testSelectMultipleCheckboxSecurity() {
5379
		$this->Form->request['_Token'] = array('key' => 'testKey');
5380
		$this->assertEquals(array(), $this->Form->fields);
5381
5382
		$result = $this->Form->select(
5383
			'Model.multi_field', array('1' => 'first', '2' => 'second', '3' => 'third'),
5384
			array('multiple' => 'checkbox')
5385
		);
5386
		$this->assertEquals(array('Model.multi_field'), $this->Form->fields);
5387
5388
		$result = $this->Form->secure($this->Form->fields);
5389
		$key = 'f7d573650a295b94e0938d32b323fde775e5f32b%3A';
5390
		$this->assertRegExp('/"' . $key . '"/', $result);
5391
	}
5392
5393
/**
5394
 * Multiple select elements should always be secured as they always participate
5395
 * in the POST data.
5396
 *
5397
 * @return void
5398
 */
5399 View Code Duplication
	public function testSelectMultipleSecureWithNoOptions() {
5400
		$this->Form->request['_Token'] = array('key' => 'testkey');
5401
		$this->assertEquals(array(), $this->Form->fields);
5402
5403
		$this->Form->select(
5404
			'Model.select',
5405
			array(),
5406
			array('multiple' => true)
5407
		);
5408
		$this->assertEquals(array('Model.select'), $this->Form->fields);
5409
	}
5410
/**
5411
 * When a select box has no options it should not be added to the fields list
5412
 * as it always fail post validation.
5413
 *
5414
 * @return void
5415
 */
5416
	public function testSelectNoSecureWithNoOptions() {
5417
		$this->Form->request['_Token'] = array('key' => 'testkey');
5418
		$this->assertEquals(array(), $this->Form->fields);
5419
5420
		$this->Form->select(
5421
			'Model.select',
5422
			array()
5423
		);
5424
		$this->assertEquals(array(), $this->Form->fields);
5425
5426
		$this->Form->select(
5427
			'Model.select',
5428
			array(),
5429
			array('empty' => true)
5430
		);
5431
		$this->assertEquals(array('Model.select'), $this->Form->fields);
5432
	}
5433
5434
/**
5435
 * testInputMultipleCheckboxes method
5436
 *
5437
 * test input() resulting in multi select elements being generated.
5438
 *
5439
 * @return void
5440
 */
5441
	public function testInputMultipleCheckboxes() {
5442
		$result = $this->Form->input('Model.multi_field', array(
5443
			'options' => array('first', 'second', 'third'),
5444
			'multiple' => 'checkbox'
5445
		));
5446
		$expected = array(
5447
			array('div' => array('class' => 'input select')),
5448
			array('label' => array('for' => 'ModelMultiField')),
5449
			'Multi Field',
5450
			'/label',
5451
			'input' => array('type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField'),
5452
			array('div' => array('class' => 'checkbox')),
5453
			array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '0', 'id' => 'ModelMultiField0')),
5454
			array('label' => array('for' => 'ModelMultiField0')),
5455
			'first',
5456
			'/label',
5457
			'/div',
5458
			array('div' => array('class' => 'checkbox')),
5459
			array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '1', 'id' => 'ModelMultiField1')),
5460
			array('label' => array('for' => 'ModelMultiField1')),
5461
			'second',
5462
			'/label',
5463
			'/div',
5464
			array('div' => array('class' => 'checkbox')),
5465
			array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '2', 'id' => 'ModelMultiField2')),
5466
			array('label' => array('for' => 'ModelMultiField2')),
5467
			'third',
5468
			'/label',
5469
			'/div',
5470
			'/div'
5471
		);
5472
		$this->assertTags($result, $expected);
5473
5474
		$result = $this->Form->input('Model.multi_field', array(
5475
			'options' => array('a' => 'first', 'b' => 'second', 'c' => 'third'),
5476
			'multiple' => 'checkbox'
5477
		));
5478
		$expected = array(
5479
			array('div' => array('class' => 'input select')),
5480
			array('label' => array('for' => 'ModelMultiField')),
5481
			'Multi Field',
5482
			'/label',
5483
			'input' => array('type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField'),
5484
			array('div' => array('class' => 'checkbox')),
5485
			array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => 'a', 'id' => 'ModelMultiFieldA')),
5486
			array('label' => array('for' => 'ModelMultiFieldA')),
5487
			'first',
5488
			'/label',
5489
			'/div',
5490
			array('div' => array('class' => 'checkbox')),
5491
			array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => 'b', 'id' => 'ModelMultiFieldB')),
5492
			array('label' => array('for' => 'ModelMultiFieldB')),
5493
			'second',
5494
			'/label',
5495
			'/div',
5496
			array('div' => array('class' => 'checkbox')),
5497
			array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => 'c', 'id' => 'ModelMultiFieldC')),
5498
			array('label' => array('for' => 'ModelMultiFieldC')),
5499
			'third',
5500
			'/label',
5501
			'/div',
5502
			'/div'
5503
		);
5504
		$this->assertTags($result, $expected);
5505
5506
		$result = $this->Form->input('Model.multi_field', array(
5507
			'options' => array('1' => 'first'),
5508
			'multiple' => 'checkbox',
5509
			'label' => false,
5510
			'div' => false
5511
		));
5512
		$expected = array(
5513
			'input' => array('type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField'),
5514
			array('div' => array('class' => 'checkbox')),
5515
			array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '1', 'id' => 'ModelMultiField1')),
5516
			array('label' => array('for' => 'ModelMultiField1')),
5517
			'first',
5518
			'/label',
5519
			'/div'
5520
		);
5521
		$this->assertTags($result, $expected);
5522
5523
		$result = $this->Form->input('Model.multi_field', array(
5524
			'options' => array('2' => 'second'),
5525
			'multiple' => 'checkbox',
5526
			'label' => false,
5527
			'div' => false
5528
		));
5529
		$expected = array(
5530
			'input' => array('type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField'),
5531
			array('div' => array('class' => 'checkbox')),
5532
			array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '2', 'id' => 'ModelMultiField2')),
5533
			array('label' => array('for' => 'ModelMultiField2')),
5534
			'second',
5535
			'/label',
5536
			'/div'
5537
		);
5538
		$this->assertTags($result, $expected);
5539
	}
5540
5541
/**
5542
 * testSelectHiddenFieldOmission method
5543
 *
5544
 * test that select() with 'hiddenField' => false omits the hidden field
5545
 *
5546
 * @return void
5547
 */
5548
	public function testSelectHiddenFieldOmission() {
5549
		$result = $this->Form->select('Model.multi_field',
5550
			array('first', 'second'),
5551
			array('multiple' => 'checkbox', 'hiddenField' => false, 'value' => null)
5552
		);
5553
		$expected = array(
5554
			array('div' => array('class' => 'checkbox')),
5555
			array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '0', 'id' => 'ModelMultiField0')),
5556
			array('label' => array('for' => 'ModelMultiField0')),
5557
			'first',
5558
			'/label',
5559
			'/div',
5560
			array('div' => array('class' => 'checkbox')),
5561
			array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '1', 'id' => 'ModelMultiField1')),
5562
			array('label' => array('for' => 'ModelMultiField1')),
5563
			'second',
5564
			'/label',
5565
			'/div'
5566
		);
5567
		$this->assertTags($result, $expected);
5568
5569
		$result = $this->Form->input('Model.multi_field', array(
5570
			'options' => array('first', 'second'),
5571
			'multiple' => 'checkbox',
5572
			'hiddenField' => false
5573
		));
5574
		$expected = array(
5575
			array('div' => array('class' => 'input select')),
5576
			array('label' => array('for' => 'ModelMultiField')),
5577
			'Multi Field',
5578
			'/label',
5579
			array('div' => array('class' => 'checkbox')),
5580
			array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '0', 'id' => 'ModelMultiField0')),
5581
			array('label' => array('for' => 'ModelMultiField0')),
5582
			'first',
5583
			'/label',
5584
			'/div',
5585
			array('div' => array('class' => 'checkbox')),
5586
			array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '1', 'id' => 'ModelMultiField1')),
5587
			array('label' => array('for' => 'ModelMultiField1')),
5588
			'second',
5589
			'/label',
5590
			'/div',
5591
			'/div'
5592
		);
5593
		$this->assertTags($result, $expected);
5594
	}
5595
5596
/**
5597
 * test that select() with multiple = checkbox works with overriding name attribute.
5598
 *
5599
 * @return void
5600
 */
5601
	public function testSelectCheckboxMultipleOverrideName() {
5602
		$result = $this->Form->input('category', array(
5603
			'type' => 'select',
5604
			'multiple' => 'checkbox',
5605
			'name' => 'data[fish]',
5606
			'options' => array('1', '2'),
5607
			'div' => false,
5608
			'label' => false,
5609
		));
5610
		$expected = array(
5611
			'input' => array('type' => 'hidden', 'name' => 'data[fish]', 'value' => '', 'id' => 'category'),
5612
			array('div' => array('class' => 'checkbox')),
5613
				array('input' => array('type' => 'checkbox', 'name' => 'data[fish][]', 'value' => '0', 'id' => 'Category0')),
5614
				array('label' => array('for' => 'Category0')), '1', '/label',
5615
			'/div',
5616
			array('div' => array('class' => 'checkbox')),
5617
				array('input' => array('type' => 'checkbox', 'name' => 'data[fish][]', 'value' => '1', 'id' => 'Category1')),
5618
				array('label' => array('for' => 'Category1')), '2', '/label',
5619
			'/div'
5620
		);
5621
		$this->assertTags($result, $expected);
5622
	}
5623
5624
/**
5625
 * Test that 'id' overrides all the checkbox id's as well.
5626
 *
5627
 * @return void
5628
 */
5629
	public function testSelectCheckboxMultipleId() {
5630
		$result = $this->Form->select(
5631
			'Model.multi_field',
5632
			array('first', 'second', 'third'),
5633
			array('multiple' => 'checkbox', 'id' => 'CustomId')
5634
		);
5635
5636
		$expected = array(
5637
			'input' => array(
5638
				'type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'CustomId'
5639
			),
5640
			array('div' => array('class' => 'checkbox')),
5641
			array('input' => array(
5642
				'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
5643
				'value' => '0', 'id' => 'CustomId0'
5644
			)),
5645
			array('label' => array('for' => 'CustomId0')),
5646
			'first',
5647
			'/label',
5648
			'/div',
5649
			array('div' => array('class' => 'checkbox')),
5650
			array('input' => array(
5651
				'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
5652
				'value' => '1', 'id' => 'CustomId1'
5653
			)),
5654
			array('label' => array('for' => 'CustomId1')),
5655
			'second',
5656
			'/label',
5657
			'/div',
5658
			array('div' => array('class' => 'checkbox')),
5659
			array('input' => array(
5660
				'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
5661
				'value' => '2', 'id' => 'CustomId2'
5662
			)),
5663
			array('label' => array('for' => 'CustomId2')),
5664
			'third',
5665
			'/label',
5666
			'/div'
5667
		);
5668
		$this->assertTags($result, $expected);
5669
	}
5670
5671
/**
5672
 * testCheckbox method
5673
 *
5674
 * Test generation of checkboxes
5675
 *
5676
 * @return void
5677
 */
5678
	public function testCheckbox() {
5679
		$result = $this->Form->checkbox('Model.field');
5680
		$expected = array(
5681
			'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField_'),
5682
			array('input' => array('type' => 'checkbox', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField'))
5683
		);
5684
		$this->assertTags($result, $expected);
5685
5686
		$result = $this->Form->checkbox('Model.field', array(
5687
			'id' => 'theID',
5688
			'value' => 'myvalue',
5689
			'form' => 'my-form',
5690
		));
5691
		$expected = array(
5692
			'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'theID_', 'form' => 'my-form'),
5693
			array('input' => array('type' => 'checkbox', 'name' => 'data[Model][field]', 'value' => 'myvalue', 'id' => 'theID', 'form' => 'my-form'))
5694
		);
5695
		$this->assertTags($result, $expected);
5696
5697
		$Contact = ClassRegistry::getObject('Contact');
5698
		$Contact->validationErrors['field'] = 1;
5699
		$this->Form->request->data['Contact']['field'] = 'myvalue';
5700
		$result = $this->Form->checkbox('Contact.field', array('id' => 'theID', 'value' => 'myvalue'));
5701
		$expected = array(
5702
			'input' => array('type' => 'hidden', 'class' => 'form-error', 'name' => 'data[Contact][field]', 'value' => '0', 'id' => 'theID_'),
5703
			array('input' => array('type', 'name', 'value' => 'myvalue', 'id' => 'theID', 'checked' => 'checked', 'class' => 'form-error'))
5704
		);
5705
		$this->assertTags($result, $expected);
5706
5707
		$result = $this->Form->checkbox('Contact.field', array('value' => 'myvalue'));
5708
		$expected = array(
5709
			'input' => array('type' => 'hidden', 'class' => 'form-error', 'name' => 'data[Contact][field]', 'value' => '0', 'id' => 'ContactField_'),
5710
			array('input' => array('type', 'name', 'value' => 'myvalue', 'id' => 'ContactField', 'checked' => 'checked', 'class' => 'form-error'))
5711
		);
5712
		$this->assertTags($result, $expected);
5713
5714
		$this->Form->request->data['Contact']['field'] = '';
5715
		$result = $this->Form->checkbox('Contact.field', array('id' => 'theID'));
5716
		$expected = array(
5717
			'input' => array('type' => 'hidden', 'class' => 'form-error', 'name' => 'data[Contact][field]', 'value' => '0', 'id' => 'theID_'),
5718
			array('input' => array('type' => 'checkbox', 'name' => 'data[Contact][field]', 'value' => '1', 'id' => 'theID', 'class' => 'form-error'))
5719
		);
5720
		$this->assertTags($result, $expected);
5721
5722
		$Contact->validationErrors = array();
5723
		$result = $this->Form->checkbox('Contact.field', array('value' => 'myvalue'));
5724
		$expected = array(
5725
			'input' => array('type' => 'hidden', 'name' => 'data[Contact][field]', 'value' => '0', 'id' => 'ContactField_'),
5726
			array('input' => array('type' => 'checkbox', 'name' => 'data[Contact][field]', 'value' => 'myvalue', 'id' => 'ContactField'))
5727
		);
5728
		$this->assertTags($result, $expected);
5729
5730
		$this->Form->request->data['Contact']['published'] = 1;
5731
		$result = $this->Form->checkbox('Contact.published', array('id' => 'theID'));
5732
		$expected = array(
5733
			'input' => array('type' => 'hidden', 'name' => 'data[Contact][published]', 'value' => '0', 'id' => 'theID_'),
5734
			array('input' => array('type' => 'checkbox', 'name' => 'data[Contact][published]', 'value' => '1', 'id' => 'theID', 'checked' => 'checked'))
5735
		);
5736
		$this->assertTags($result, $expected);
5737
5738
		$this->Form->request->data['Contact']['published'] = 0;
5739
		$result = $this->Form->checkbox('Contact.published', array('id' => 'theID'));
5740
		$expected = array(
5741
			'input' => array('type' => 'hidden', 'name' => 'data[Contact][published]', 'value' => '0', 'id' => 'theID_'),
5742
			array('input' => array('type' => 'checkbox', 'name' => 'data[Contact][published]', 'value' => '1', 'id' => 'theID'))
5743
		);
5744
		$this->assertTags($result, $expected);
5745
5746
		$result = $this->Form->checkbox('Model.CustomField.1.value');
5747
		$expected = array(
5748
			'input' => array('type' => 'hidden', 'name' => 'data[Model][CustomField][1][value]', 'value' => '0', 'id' => 'ModelCustomField1Value_'),
5749
			array('input' => array('type' => 'checkbox', 'name' => 'data[Model][CustomField][1][value]', 'value' => '1', 'id' => 'ModelCustomField1Value'))
5750
		);
5751
		$this->assertTags($result, $expected);
5752
5753
		$result = $this->Form->checkbox('CustomField.1.value');
5754
		$expected = array(
5755
			'input' => array('type' => 'hidden', 'name' => 'data[CustomField][1][value]', 'value' => '0', 'id' => 'CustomField1Value_'),
5756
			array('input' => array('type' => 'checkbox', 'name' => 'data[CustomField][1][value]', 'value' => '1', 'id' => 'CustomField1Value'))
5757
		);
5758
		$this->assertTags($result, $expected);
5759
	}
5760
5761
/**
5762
 * test checkbox() with a custom name attribute
5763
 *
5764
 * @return void
5765
 */
5766
	public function testCheckboxCustomNameAttribute() {
5767
		$result = $this->Form->checkbox('Test.test', array('name' => 'myField'));
5768
		$expected = array(
5769
				'input' => array('type' => 'hidden', 'name' => 'myField', 'value' => '0', 'id' => 'TestTest_'),
5770
				array('input' => array('type' => 'checkbox', 'name' => 'myField', 'value' => '1', 'id' => 'TestTest'))
5771
			);
5772
		$this->assertTags($result, $expected);
5773
	}
5774
5775
/**
5776
 * test the checked option for checkboxes.
5777
 *
5778
 * @return void
5779
 */
5780
	public function testCheckboxCheckedOption() {
5781
		$result = $this->Form->checkbox('Model.field', array('checked' => 'checked'));
5782
		$expected = array(
5783
			'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField_'),
5784
			array('input' => array('type' => 'checkbox', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField', 'checked' => 'checked'))
5785
		);
5786
		$this->assertTags($result, $expected);
5787
5788
		$result = $this->Form->checkbox('Model.field', array('checked' => 1));
5789
		$expected = array(
5790
			'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField_'),
5791
			array('input' => array('type' => 'checkbox', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField', 'checked' => 'checked'))
5792
		);
5793
		$this->assertTags($result, $expected);
5794
5795
		$result = $this->Form->checkbox('Model.field', array('checked' => true));
5796
		$expected = array(
5797
			'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField_'),
5798
			array('input' => array('type' => 'checkbox', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField', 'checked' => 'checked'))
5799
		);
5800
		$this->assertTags($result, $expected);
5801
5802
		$result = $this->Form->checkbox('Model.field', array('checked' => false));
5803
		$expected = array(
5804
			'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField_'),
5805
			array('input' => array('type' => 'checkbox', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField'))
5806
		);
5807
		$this->assertTags($result, $expected);
5808
5809
		$this->Form->request->data['Model']['field'] = 1;
5810
		$result = $this->Form->checkbox('Model.field', array('checked' => false));
5811
		$expected = array(
5812
			'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField_'),
5813
			array('input' => array('type' => 'checkbox', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField'))
5814
		);
5815
		$this->assertTags($result, $expected);
5816
	}
5817
5818
/**
5819
 * Test that disabled attribute works on both the checkbox and hidden input.
5820
 *
5821
 * @return void
5822
 */
5823
	public function testCheckboxDisabling() {
5824
		$result = $this->Form->checkbox('Account.show_name', array('disabled' => 'disabled'));
5825
		$expected = array(
5826
			array('input' => array('type' => 'hidden', 'name' => 'data[Account][show_name]', 'value' => '0', 'id' => 'AccountShowName_', 'disabled' => 'disabled')),
5827
			array('input' => array('type' => 'checkbox', 'name' => 'data[Account][show_name]', 'value' => '1', 'id' => 'AccountShowName', 'disabled' => 'disabled'))
5828
		);
5829
		$this->assertTags($result, $expected);
5830
5831
		$result = $this->Form->checkbox('Account.show_name', array('disabled' => false));
5832
		$expected = array(
5833
			array('input' => array('type' => 'hidden', 'name' => 'data[Account][show_name]', 'value' => '0', 'id' => 'AccountShowName_')),
5834
			array('input' => array('type' => 'checkbox', 'name' => 'data[Account][show_name]', 'value' => '1', 'id' => 'AccountShowName'))
5835
		);
5836
		$this->assertTags($result, $expected);
5837
	}
5838
5839
/**
5840
 * Test that the hidden input for checkboxes can be omitted or set to a
5841
 * specific value.
5842
 *
5843
 * @return void
5844
 */
5845
	public function testCheckboxHiddenField() {
5846
		$result = $this->Form->input('UserForm.something', array(
5847
			'type' => 'checkbox',
5848
			'hiddenField' => false
5849
		));
5850
		$expected = array(
5851
			'div' => array('class' => 'input checkbox'),
5852
			array('input' => array(
5853
				'type' => 'checkbox', 'name' => 'data[UserForm][something]',
5854
				'value' => '1', 'id' => 'UserFormSomething'
5855
			)),
5856
			'label' => array('for' => 'UserFormSomething'),
5857
			'Something',
5858
			'/label',
5859
			'/div'
5860
		);
5861
		$this->assertTags($result, $expected);
5862
5863
		$result = $this->Form->input('UserForm.something', array(
5864
			'type' => 'checkbox',
5865
			'value' => 'Y',
5866
			'hiddenField' => 'N',
5867
		));
5868
		$expected = array(
5869
			'div' => array('class' => 'input checkbox'),
5870
			array('input' => array(
5871
				'type' => 'hidden', 'name' => 'data[UserForm][something]',
5872
				'value' => 'N', 'id' => 'UserFormSomething_'
5873
			)),
5874
			array('input' => array(
5875
				'type' => 'checkbox', 'name' => 'data[UserForm][something]',
5876
				'value' => 'Y', 'id' => 'UserFormSomething'
5877
			)),
5878
			'label' => array('for' => 'UserFormSomething'),
5879
			'Something',
5880
			'/label',
5881
			'/div'
5882
		);
5883
		$this->assertTags($result, $expected);
5884
	}
5885
5886
/**
5887
 * Test that a checkbox can have 0 for the value and 1 for the hidden input.
5888
 *
5889
 * @return void
5890
 */
5891 View Code Duplication
	public function testCheckboxZeroValue() {
5892
		$result = $this->Form->input('User.get_spam', array(
5893
			'type' => 'checkbox',
5894
			'value' => '0',
5895
			'hiddenField' => '1',
5896
		));
5897
		$expected = array(
5898
			'div' => array('class' => 'input checkbox'),
5899
			array('input' => array(
5900
				'type' => 'hidden', 'name' => 'data[User][get_spam]',
5901
				'value' => '1', 'id' => 'UserGetSpam_'
5902
			)),
5903
			array('input' => array(
5904
				'type' => 'checkbox', 'name' => 'data[User][get_spam]',
5905
				'value' => '0', 'id' => 'UserGetSpam'
5906
			)),
5907
			'label' => array('for' => 'UserGetSpam'),
5908
			'Get Spam',
5909
			'/label',
5910
			'/div'
5911
		);
5912
		$this->assertTags($result, $expected);
5913
	}
5914
5915
/**
5916
 * testDateTime method
5917
 *
5918
 * Test generation of date/time select elements
5919
 *
5920
 * @return void
5921
 */
5922
	public function testDateTime() {
5923
		extract($this->dateRegex);
5924
5925
		$result = $this->Form->dateTime('Contact.date', 'DMY', '12', array('empty' => false));
5926
		$now = strtotime('now');
5927
		$expected = array(
5928
			array('select' => array('name' => 'data[Contact][date][day]', 'id' => 'ContactDateDay')),
5929
			$daysRegex,
5930
			array('option' => array('value' => date('d', $now), 'selected' => 'selected')),
5931
			date('j', $now),
5932
			'/option',
5933
			'*/select',
5934
			'-',
5935
			array('select' => array('name' => 'data[Contact][date][month]', 'id' => 'ContactDateMonth')),
5936
			$monthsRegex,
5937
			array('option' => array('value' => date('m', $now), 'selected' => 'selected')),
5938
			date('F', $now),
5939
			'/option',
5940
			'*/select',
5941
			'-',
5942
			array('select' => array('name' => 'data[Contact][date][year]', 'id' => 'ContactDateYear')),
5943
			$yearsRegex,
5944
			array('option' => array('value' => date('Y', $now), 'selected' => 'selected')),
5945
			date('Y', $now),
5946
			'/option',
5947
			'*/select',
5948
			array('select' => array('name' => 'data[Contact][date][hour]', 'id' => 'ContactDateHour')),
5949
			$hoursRegex,
5950
			array('option' => array('value' => date('h', $now), 'selected' => 'selected')),
5951
			date('g', $now),
5952
			'/option',
5953
			'*/select',
5954
			':',
5955
			array('select' => array('name' => 'data[Contact][date][min]', 'id' => 'ContactDateMin')),
5956
			$minutesRegex,
5957
			array('option' => array('value' => date('i', $now), 'selected' => 'selected')),
5958
			date('i', $now),
5959
			'/option',
5960
			'*/select',
5961
			' ',
5962
			array('select' => array('name' => 'data[Contact][date][meridian]', 'id' => 'ContactDateMeridian')),
5963
			$meridianRegex,
5964
			array('option' => array('value' => date('a', $now), 'selected' => 'selected')),
5965
			date('a', $now),
5966
			'/option',
5967
			'*/select'
5968
		);
5969
		$this->assertTags($result, $expected);
5970
5971
		$result = $this->Form->dateTime('Contact.date', 'DMY', '12');
5972
		$expected = array(
5973
			array('select' => array('name' => 'data[Contact][date][day]', 'id' => 'ContactDateDay')),
5974
			$daysRegex,
5975
			array('option' => array('value' => '')),
5976
			'/option',
5977
			'*/select',
5978
			'-',
5979
			array('select' => array('name' => 'data[Contact][date][month]', 'id' => 'ContactDateMonth')),
5980
			$monthsRegex,
5981
			array('option' => array('value' => '')),
5982
			'/option',
5983
			'*/select',
5984
			'-',
5985
			array('select' => array('name' => 'data[Contact][date][year]', 'id' => 'ContactDateYear')),
5986
			$yearsRegex,
5987
			array('option' => array('value' => '')),
5988
			'/option',
5989
			'*/select',
5990
			array('select' => array('name' => 'data[Contact][date][hour]', 'id' => 'ContactDateHour')),
5991
			$hoursRegex,
5992
			array('option' => array('value' => '')),
5993
			'/option',
5994
			'*/select',
5995
			':',
5996
			array('select' => array('name' => 'data[Contact][date][min]', 'id' => 'ContactDateMin')),
5997
			$minutesRegex,
5998
			array('option' => array('value' => '')),
5999
			'/option',
6000
			'*/select',
6001
			' ',
6002
			array('select' => array('name' => 'data[Contact][date][meridian]', 'id' => 'ContactDateMeridian')),
6003
			$meridianRegex,
6004
			array('option' => array('value' => '')),
6005
			'/option',
6006
			'*/select'
6007
		);
6008
		$this->assertTags($result, $expected);
6009
		$this->assertNotRegExp('/<option[^<>]+value=""[^<>]+selected="selected"[^>]*>/', $result);
6010
6011
		$result = $this->Form->dateTime('Contact.date', 'DMY', '12', array('value' => false));
6012
		$this->assertTags($result, $expected);
6013
		$this->assertNotRegExp('/<option[^<>]+value=""[^<>]+selected="selected"[^>]*>/', $result);
6014
6015
		$result = $this->Form->dateTime('Contact.date', 'DMY', '12', array('value' => ''));
6016
		$this->assertTags($result, $expected);
6017
		$this->assertNotRegExp('/<option[^<>]+value=""[^<>]+selected="selected"[^>]*>/', $result);
6018
6019
		$result = $this->Form->dateTime('Contact.date', 'DMY', '12', array('interval' => 5, 'value' => ''));
6020
		$expected = array(
6021
			array('select' => array('name' => 'data[Contact][date][day]', 'id' => 'ContactDateDay')),
6022
			$daysRegex,
6023
			array('option' => array('value' => '')),
6024
			'/option',
6025
			'*/select',
6026
			'-',
6027
			array('select' => array('name' => 'data[Contact][date][month]', 'id' => 'ContactDateMonth')),
6028
			$monthsRegex,
6029
			array('option' => array('value' => '')),
6030
			'/option',
6031
			'*/select',
6032
			'-',
6033
			array('select' => array('name' => 'data[Contact][date][year]', 'id' => 'ContactDateYear')),
6034
			$yearsRegex,
6035
			array('option' => array('value' => '')),
6036
			'/option',
6037
			'*/select',
6038
			array('select' => array('name' => 'data[Contact][date][hour]', 'id' => 'ContactDateHour')),
6039
			$hoursRegex,
6040
			array('option' => array('value' => '')),
6041
			'/option',
6042
			'*/select',
6043
			':',
6044
			array('select' => array('name' => 'data[Contact][date][min]', 'id' => 'ContactDateMin')),
6045
			$minutesRegex,
6046
			array('option' => array('value' => '')),
6047
			'/option',
6048
			array('option' => array('value' => '00')),
6049
			'00',
6050
			'/option',
6051
			array('option' => array('value' => '05')),
6052
			'05',
6053
			'/option',
6054
			array('option' => array('value' => '10')),
6055
			'10',
6056
			'/option',
6057
			'*/select',
6058
			' ',
6059
			array('select' => array('name' => 'data[Contact][date][meridian]', 'id' => 'ContactDateMeridian')),
6060
			$meridianRegex,
6061
			array('option' => array('value' => '')),
6062
			'/option',
6063
			'*/select'
6064
		);
6065
		$this->assertTags($result, $expected);
6066
		$this->assertNotRegExp('/<option[^<>]+value=""[^<>]+selected="selected"[^>]*>/', $result);
6067
6068
		$result = $this->Form->dateTime('Contact.date', 'DMY', '12', array('minuteInterval' => 5, 'value' => ''));
6069
		$result = $this->Form->dateTime('Contact.date', 'DMY', '12', array('minuteInterval' => 5, 'value' => ''));
6070
6071
		$this->Form->request->data['Contact']['data'] = null;
6072
		$result = $this->Form->dateTime('Contact.date', 'DMY', '12');
6073
		$expected = array(
6074
			array('select' => array('name' => 'data[Contact][date][day]', 'id' => 'ContactDateDay')),
6075
			$daysRegex,
6076
			array('option' => array('value' => '')),
6077
			'/option',
6078
			'*/select',
6079
			'-',
6080
			array('select' => array('name' => 'data[Contact][date][month]', 'id' => 'ContactDateMonth')),
6081
			$monthsRegex,
6082
			array('option' => array('value' => '')),
6083
			'/option',
6084
			'*/select',
6085
			'-',
6086
			array('select' => array('name' => 'data[Contact][date][year]', 'id' => 'ContactDateYear')),
6087
			$yearsRegex,
6088
			array('option' => array('value' => '')),
6089
			'/option',
6090
			'*/select',
6091
			array('select' => array('name' => 'data[Contact][date][hour]', 'id' => 'ContactDateHour')),
6092
			$hoursRegex,
6093
			array('option' => array('value' => '')),
6094
			'/option',
6095
			'*/select',
6096
			':',
6097
			array('select' => array('name' => 'data[Contact][date][min]', 'id' => 'ContactDateMin')),
6098
			$minutesRegex,
6099
			array('option' => array('value' => '')),
6100
			'/option',
6101
			'*/select',
6102
			' ',
6103
			array('select' => array('name' => 'data[Contact][date][meridian]', 'id' => 'ContactDateMeridian')),
6104
			$meridianRegex,
6105
			array('option' => array('value' => '')),
6106
			'/option',
6107
			'*/select'
6108
		);
6109
		$this->assertTags($result, $expected);
6110
		$this->assertNotRegExp('/<option[^<>]+value=""[^<>]+selected="selected"[^>]*>/', $result);
6111
6112
		$this->Form->request->data['Model']['field'] = date('Y') . '-01-01 00:00:00';
6113
		$now = strtotime($this->Form->data['Model']['field']);
6114
		$result = $this->Form->dateTime('Model.field', 'DMY', '12', array('empty' => false));
6115
		$expected = array(
6116
			array('select' => array('name' => 'data[Model][field][day]', 'id' => 'ModelFieldDay')),
6117
			$daysRegex,
6118
			array('option' => array('value' => date('d', $now), 'selected' => 'selected')),
6119
			date('j', $now),
6120
			'/option',
6121
			'*/select',
6122
			'-',
6123
			array('select' => array('name' => 'data[Model][field][month]', 'id' => 'ModelFieldMonth')),
6124
			$monthsRegex,
6125
			array('option' => array('value' => date('m', $now), 'selected' => 'selected')),
6126
			date('F', $now),
6127
			'/option',
6128
			'*/select',
6129
			'-',
6130
			array('select' => array('name' => 'data[Model][field][year]', 'id' => 'ModelFieldYear')),
6131
			$yearsRegex,
6132
			array('option' => array('value' => date('Y', $now), 'selected' => 'selected')),
6133
			date('Y', $now),
6134
			'/option',
6135
			'*/select',
6136
			array('select' => array('name' => 'data[Model][field][hour]', 'id' => 'ModelFieldHour')),
6137
			$hoursRegex,
6138
			array('option' => array('value' => date('h', $now), 'selected' => 'selected')),
6139
			date('g', $now),
6140
			'/option',
6141
			'*/select',
6142
			':',
6143
			array('select' => array('name' => 'data[Model][field][min]', 'id' => 'ModelFieldMin')),
6144
			$minutesRegex,
6145
			array('option' => array('value' => date('i', $now), 'selected' => 'selected')),
6146
			date('i', $now),
6147
			'/option',
6148
			'*/select',
6149
			' ',
6150
			array('select' => array('name' => 'data[Model][field][meridian]', 'id' => 'ModelFieldMeridian')),
6151
			$meridianRegex,
6152
			array('option' => array('value' => date('a', $now), 'selected' => 'selected')),
6153
			date('a', $now),
6154
			'/option',
6155
			'*/select'
6156
		);
6157
		$this->assertTags($result, $expected);
6158
6159
		$selected = strtotime('2008-10-26 12:33:00');
6160
		$result = $this->Form->dateTime('Model.field', 'DMY', '12', array('value' => $selected));
6161
		$this->assertRegExp('/<option[^<>]+value="2008"[^<>]+selected="selected"[^>]*>2008<\/option>/', $result);
6162
		$this->assertRegExp('/<option[^<>]+value="10"[^<>]+selected="selected"[^>]*>October<\/option>/', $result);
6163
		$this->assertRegExp('/<option[^<>]+value="26"[^<>]+selected="selected"[^>]*>26<\/option>/', $result);
6164
		$this->assertRegExp('/<option[^<>]+value="12"[^<>]+selected="selected"[^>]*>12<\/option>/', $result);
6165
		$this->assertRegExp('/<option[^<>]+value="33"[^<>]+selected="selected"[^>]*>33<\/option>/', $result);
6166
		$this->assertRegExp('/<option[^<>]+value="pm"[^<>]+selected="selected"[^>]*>pm<\/option>/', $result);
6167
6168
		$this->Form->create('Contact');
6169
		$result = $this->Form->input('published');
6170
		$now = strtotime('now');
6171
		$expected = array(
6172
			'div' => array('class' => 'input date'),
6173
			'label' => array('for' => 'ContactPublishedMonth'),
6174
			'Published',
6175
			'/label',
6176
			array('select' => array('name' => 'data[Contact][published][month]', 'id' => 'ContactPublishedMonth')),
6177
			$monthsRegex,
6178
			array('option' => array('value' => date('m', $now), 'selected' => 'selected')),
6179
			date('F', $now),
6180
			'/option',
6181
			'*/select',
6182
			'-',
6183
			array('select' => array('name' => 'data[Contact][published][day]', 'id' => 'ContactPublishedDay')),
6184
			$daysRegex,
6185
			array('option' => array('value' => date('d', $now), 'selected' => 'selected')),
6186
			date('j', $now),
6187
			'/option',
6188
			'*/select',
6189
			'-',
6190
			array('select' => array('name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear')),
6191
			$yearsRegex,
6192
			array('option' => array('value' => date('Y', $now), 'selected' => 'selected')),
6193
			date('Y', $now),
6194
			'/option',
6195
			'*/select',
6196
			'/div'
6197
		);
6198
		$this->assertTags($result, $expected);
6199
6200
		$result = $this->Form->input('published2', array('type' => 'date'));
6201
		$now = strtotime('now');
6202
		$expected = array(
6203
			'div' => array('class' => 'input date'),
6204
			'label' => array('for' => 'ContactPublished2Month'),
6205
			'Published2',
6206
			'/label',
6207
			array('select' => array('name' => 'data[Contact][published2][month]', 'id' => 'ContactPublished2Month')),
6208
			$monthsRegex,
6209
			array('option' => array('value' => date('m', $now), 'selected' => 'selected')),
6210
			date('F', $now),
6211
			'/option',
6212
			'*/select',
6213
			'-',
6214
			array('select' => array('name' => 'data[Contact][published2][day]', 'id' => 'ContactPublished2Day')),
6215
			$daysRegex,
6216
			array('option' => array('value' => date('d', $now), 'selected' => 'selected')),
6217
			date('j', $now),
6218
			'/option',
6219
			'*/select',
6220
			'-',
6221
			array('select' => array('name' => 'data[Contact][published2][year]', 'id' => 'ContactPublished2Year')),
6222
			$yearsRegex,
6223
			array('option' => array('value' => date('Y', $now), 'selected' => 'selected')),
6224
			date('Y', $now),
6225
			'/option',
6226
			'*/select',
6227
			'/div'
6228
		);
6229
		$this->assertTags($result, $expected);
6230
6231
		$this->Form->create('Contact');
6232
		$result = $this->Form->input('published', array('monthNames' => false));
6233
		$now = strtotime('now');
6234
		$expected = array(
6235
			'div' => array('class' => 'input date'),
6236
			'label' => array('for' => 'ContactPublishedMonth'),
6237
			'Published',
6238
			'/label',
6239
			array('select' => array('name' => 'data[Contact][published][month]', 'id' => 'ContactPublishedMonth')),
6240
			'preg:/(?:<option value="([\d])+">[\d]+<\/option>[\r\n]*)*/',
6241
			array('option' => array('value' => date('m', $now), 'selected' => 'selected')),
6242
			date('m', $now),
6243
			'/option',
6244
			'*/select',
6245
			'-',
6246
			array('select' => array('name' => 'data[Contact][published][day]', 'id' => 'ContactPublishedDay')),
6247
			$daysRegex,
6248
			array('option' => array('value' => date('d', $now), 'selected' => 'selected')),
6249
			date('j', $now),
6250
			'/option',
6251
			'*/select',
6252
			'-',
6253
			array('select' => array('name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear')),
6254
			$yearsRegex,
6255
			array('option' => array('value' => date('Y', $now), 'selected' => 'selected')),
6256
			date('Y', $now),
6257
			'/option',
6258
			'*/select',
6259
			'/div'
6260
		);
6261
		$this->assertTags($result, $expected);
6262
6263
		$result = $this->Form->input('published', array(
6264
			'timeFormat' => 24,
6265
			'interval' => 5,
6266
			'selected' => strtotime('2009-09-03 13:37:00'),
6267
			'type' => 'datetime'
6268
		));
6269
		$this->assertRegExp('/<option[^<>]+value="2009"[^<>]+selected="selected"[^>]*>2009<\/option>/', $result);
6270
		$this->assertRegExp('/<option[^<>]+value="09"[^<>]+selected="selected"[^>]*>September<\/option>/', $result);
6271
		$this->assertRegExp('/<option[^<>]+value="03"[^<>]+selected="selected"[^>]*>3<\/option>/', $result);
6272
		$this->assertRegExp('/<option[^<>]+value="13"[^<>]+selected="selected"[^>]*>13<\/option>/', $result);
6273
		$this->assertRegExp('/<option[^<>]+value="35"[^<>]+selected="selected"[^>]*>35<\/option>/', $result);
6274
	}
6275
6276
/**
6277
 * Test dateTime with rounding
6278
 *
6279
 * @return void
6280
 */
6281
	public function testDateTimeRounding() {
6282
		$this->Form->request->data['Contact'] = array(
6283
			'date' => array(
6284
				'day' => '13',
6285
				'month' => '12',
6286
				'year' => '2010',
6287
				'hour' => '04',
6288
				'min' => '19',
6289
				'meridian' => 'AM'
6290
			)
6291
		);
6292
6293
		$result = $this->Form->dateTime('Contact.date', 'DMY', '12', array('interval' => 15));
6294
		$this->assertTextContains('<option value="15" selected="selected">15</option>', $result);
6295
6296
		$result = $this->Form->dateTime('Contact.date', 'DMY', '12', array('interval' => 15, 'round' => 'up'));
6297
		$this->assertTextContains('<option value="30" selected="selected">30</option>', $result);
6298
6299
		$result = $this->Form->dateTime('Contact.date', 'DMY', '12', array('interval' => 5, 'round' => 'down'));
6300
		$this->assertTextContains('<option value="15" selected="selected">15</option>', $result);
6301
	}
6302
6303
/**
6304
 * Test that empty values don't trigger errors.
6305
 *
6306
 * @return void
6307
 */
6308
	public function testDateTimeNoErrorsOnEmptyData() {
6309
		$this->Form->request->data['Contact'] = array(
6310
			'date' => array(
6311
				'day' => '',
6312
				'month' => '',
6313
				'year' => '',
6314
				'hour' => '',
6315
				'min' => '',
6316
				'meridian' => ''
6317
			)
6318
		);
6319
		$result = $this->Form->dateTime('Contact.date', 'DMY', '12', array('empty' => false));
6320
		$this->assertNotEmpty($result);
6321
	}
6322
6323
/**
6324
 * test that datetime() and default values work.
6325
 *
6326
 * @return void
6327
 */
6328
	public function testDatetimeWithDefault() {
6329
		$result = $this->Form->dateTime('Contact.updated', 'DMY', '12', array('value' => '2009-06-01 11:15:30'));
6330
		$this->assertRegExp('/<option[^<>]+value="2009"[^<>]+selected="selected"[^>]*>2009<\/option>/', $result);
6331
		$this->assertRegExp('/<option[^<>]+value="01"[^<>]+selected="selected"[^>]*>1<\/option>/', $result);
6332
		$this->assertRegExp('/<option[^<>]+value="06"[^<>]+selected="selected"[^>]*>June<\/option>/', $result);
6333
6334
		$result = $this->Form->dateTime('Contact.updated', 'DMY', '12', array(
6335
			'default' => '2009-06-01 11:15:30'
6336
		));
6337
		$this->assertRegExp('/<option[^<>]+value="2009"[^<>]+selected="selected"[^>]*>2009<\/option>/', $result);
6338
		$this->assertRegExp('/<option[^<>]+value="01"[^<>]+selected="selected"[^>]*>1<\/option>/', $result);
6339
		$this->assertRegExp('/<option[^<>]+value="06"[^<>]+selected="selected"[^>]*>June<\/option>/', $result);
6340
	}
6341
6342
/**
6343
 * test that bogus non-date time data doesn't cause errors.
6344
 *
6345
 * @return void
6346
 */
6347
	public function testDateTimeWithBogusData() {
6348
		$result = $this->Form->dateTime('Contact.updated', 'DMY', '12', array('value' => 'CURRENT_TIMESTAMP'));
6349
		$this->assertNotRegExp('/selected="selected">\d/', $result);
6350
	}
6351
6352
/**
6353
 * testDateTime all zeros
6354
 *
6355
 * @return void
6356
 */
6357
	public function testDateTimeAllZeros() {
6358
		$result = $this->Form->dateTime('Contact.date',
6359
			'DMY',
6360
			false,
6361
			array(
6362
				'empty' => array('day' => '-', 'month' => '-', 'year' => '-'),
6363
				'value' => '0000-00-00'
6364
			)
6365
		);
6366
6367
		$this->assertRegExp('/<option value="">-<\/option>/', $result);
6368
		$this->assertNotRegExp('/<option value="0" selected="selected">0<\/option>/', $result);
6369
	}
6370
6371
/**
6372
 * testDateTimeEmptyAsArray
6373
 *
6374
 * @return void
6375
 */
6376
	public function testDateTimeEmptyAsArray() {
6377
		$result = $this->Form->dateTime('Contact.date',
6378
			'DMY',
6379
			'12',
6380
			array(
6381
				'empty' => array('day' => 'DAY', 'month' => 'MONTH', 'year' => 'YEAR',
6382
					'hour' => 'HOUR', 'minute' => 'MINUTE', 'meridian' => false
6383
				)
6384
			)
6385
		);
6386
6387
		$this->assertRegExp('/<option value="">DAY<\/option>/', $result);
6388
		$this->assertRegExp('/<option value="">MONTH<\/option>/', $result);
6389
		$this->assertRegExp('/<option value="">YEAR<\/option>/', $result);
6390
		$this->assertRegExp('/<option value="">HOUR<\/option>/', $result);
6391
		$this->assertRegExp('/<option value="">MINUTE<\/option>/', $result);
6392
		$this->assertNotRegExp('/<option value=""><\/option>/', $result);
6393
6394
		$result = $this->Form->dateTime('Contact.date',
6395
			'DMY',
6396
			'12',
6397
			array(
6398
				'empty' => array('day' => 'DAY', 'month' => 'MONTH', 'year' => 'YEAR')
6399
			)
6400
		);
6401
6402
		$this->assertRegExp('/<option value="">DAY<\/option>/', $result);
6403
		$this->assertRegExp('/<option value="">MONTH<\/option>/', $result);
6404
		$this->assertRegExp('/<option value="">YEAR<\/option>/', $result);
6405
		$this->assertRegExp('/<select[^<>]+id="ContactDateHour">\s<option value=""><\/option>/', $result);
6406
		$this->assertRegExp('/<select[^<>]+id="ContactDateMin">\s<option value=""><\/option>/', $result);
6407
		$this->assertRegExp('/<select[^<>]+id="ContactDateMeridian">\s<option value=""><\/option>/', $result);
6408
	}
6409
6410
/**
6411
 * testFormDateTimeMulti method
6412
 *
6413
 * test multiple datetime element generation
6414
 *
6415
 * @return void
6416
 */
6417
	public function testFormDateTimeMulti() {
6418
		extract($this->dateRegex);
6419
6420
		$result = $this->Form->dateTime('Contact.1.updated');
6421
		$expected = array(
6422
			array('select' => array('name' => 'data[Contact][1][updated][day]', 'id' => 'Contact1UpdatedDay')),
6423
			$daysRegex,
6424
			array('option' => array('value' => '')),
6425
			'/option',
6426
			'*/select',
6427
			'-',
6428
			array('select' => array('name' => 'data[Contact][1][updated][month]', 'id' => 'Contact1UpdatedMonth')),
6429
			$monthsRegex,
6430
			array('option' => array('value' => '')),
6431
			'/option',
6432
			'*/select',
6433
			'-',
6434
			array('select' => array('name' => 'data[Contact][1][updated][year]', 'id' => 'Contact1UpdatedYear')),
6435
			$yearsRegex,
6436
			array('option' => array('value' => '')),
6437
			'/option',
6438
			'*/select',
6439
			array('select' => array('name' => 'data[Contact][1][updated][hour]', 'id' => 'Contact1UpdatedHour')),
6440
			$hoursRegex,
6441
			array('option' => array('value' => '')),
6442
			'/option',
6443
			'*/select',
6444
			':',
6445
			array('select' => array('name' => 'data[Contact][1][updated][min]', 'id' => 'Contact1UpdatedMin')),
6446
			$minutesRegex,
6447
			array('option' => array('value' => '')),
6448
			'/option',
6449
			'*/select',
6450
			' ',
6451
			array('select' => array('name' => 'data[Contact][1][updated][meridian]', 'id' => 'Contact1UpdatedMeridian')),
6452
			$meridianRegex,
6453
			array('option' => array('value' => '')),
6454
			'/option',
6455
			'*/select'
6456
		);
6457
		$this->assertTags($result, $expected);
6458
6459
		$result = $this->Form->dateTime('Contact.2.updated');
6460
		$expected = array(
6461
			array('select' => array('name' => 'data[Contact][2][updated][day]', 'id' => 'Contact2UpdatedDay')),
6462
			$daysRegex,
6463
			array('option' => array('value' => '')),
6464
			'/option',
6465
			'*/select',
6466
			'-',
6467
			array('select' => array('name' => 'data[Contact][2][updated][month]', 'id' => 'Contact2UpdatedMonth')),
6468
			$monthsRegex,
6469
			array('option' => array('value' => '')),
6470
			'/option',
6471
			'*/select',
6472
			'-',
6473
			array('select' => array('name' => 'data[Contact][2][updated][year]', 'id' => 'Contact2UpdatedYear')),
6474
			$yearsRegex,
6475
			array('option' => array('value' => '')),
6476
			'/option',
6477
			'*/select',
6478
			array('select' => array('name' => 'data[Contact][2][updated][hour]', 'id' => 'Contact2UpdatedHour')),
6479
			$hoursRegex,
6480
			array('option' => array('value' => '')),
6481
			'/option',
6482
			'*/select',
6483
			':',
6484
			array('select' => array('name' => 'data[Contact][2][updated][min]', 'id' => 'Contact2UpdatedMin')),
6485
			$minutesRegex,
6486
			array('option' => array('value' => '')),
6487
			'/option',
6488
			'*/select',
6489
			' ',
6490
			array('select' => array('name' => 'data[Contact][2][updated][meridian]', 'id' => 'Contact2UpdatedMeridian')),
6491
			$meridianRegex,
6492
			array('option' => array('value' => '')),
6493
			'/option',
6494
			'*/select'
6495
		);
6496
		$this->assertTags($result, $expected);
6497
	}
6498
6499
/**
6500
 * When changing the date format, the label should always focus the first select box when
6501
 * clicked.
6502
 *
6503
 * @return void
6504
 */
6505
	public function testDateTimeLabelIdMatchesFirstInput() {
6506
		$result = $this->Form->input('Model.date', array('type' => 'date'));
6507
		$this->assertContains('label for="ModelDateMonth"', $result);
6508
6509
		$result = $this->Form->input('Model.date', array('type' => 'date', 'dateFormat' => 'DMY'));
6510
		$this->assertContains('label for="ModelDateDay"', $result);
6511
6512
		$result = $this->Form->input('Model.date', array('type' => 'date', 'dateFormat' => 'YMD'));
6513
		$this->assertContains('label for="ModelDateYear"', $result);
6514
	}
6515
6516
/**
6517
 * testMonth method
6518
 *
6519
 * @return void
6520
 */
6521
	public function testMonth() {
6522
		$result = $this->Form->month('Model.field');
6523
		$expected = array(
6524
			array('select' => array('name' => 'data[Model][field][month]', 'id' => 'ModelFieldMonth')),
6525
			array('option' => array('value' => '')),
6526
			'/option',
6527
			array('option' => array('value' => '01')),
6528
			date('F', strtotime('2008-01-01 00:00:00')),
6529
			'/option',
6530
			array('option' => array('value' => '02')),
6531
			date('F', strtotime('2008-02-01 00:00:00')),
6532
			'/option',
6533
			'*/select',
6534
		);
6535
		$this->assertTags($result, $expected);
6536
6537
		$result = $this->Form->month('Model.field', array('empty' => true));
6538
		$expected = array(
6539
			array('select' => array('name' => 'data[Model][field][month]', 'id' => 'ModelFieldMonth')),
6540
			array('option' => array('value' => '')),
6541
			'/option',
6542
			array('option' => array('value' => '01')),
6543
			date('F', strtotime('2008-01-01 00:00:00')),
6544
			'/option',
6545
			array('option' => array('value' => '02')),
6546
			date('F', strtotime('2008-02-01 00:00:00')),
6547
			'/option',
6548
			'*/select',
6549
		);
6550
		$this->assertTags($result, $expected);
6551
6552
		$result = $this->Form->month('Model.field', array('monthNames' => false));
6553
		$expected = array(
6554
			array('select' => array('name' => 'data[Model][field][month]', 'id' => 'ModelFieldMonth')),
6555
			array('option' => array('value' => '')),
6556
			'/option',
6557
			array('option' => array('value' => '01')),
6558
			'01',
6559
			'/option',
6560
			array('option' => array('value' => '02')),
6561
			'02',
6562
			'/option',
6563
			'*/select',
6564
		);
6565
		$this->assertTags($result, $expected);
6566
6567
		$monthNames = array(
6568
			'01' => 'Jan', '02' => 'Feb', '03' => 'Mar', '04' => 'Apr', '05' => 'May', '06' => 'Jun',
6569
			'07' => 'Jul', '08' => 'Aug', '09' => 'Sep', '10' => 'Oct', '11' => 'Nov', '12' => 'Dec');
6570
		$result = $this->Form->month('Model.field', array('monthNames' => $monthNames));
6571
		$expected = array(
6572
			array('select' => array('name' => 'data[Model][field][month]', 'id' => 'ModelFieldMonth')),
6573
			array('option' => array('value' => '')),
6574
			'/option',
6575
			array('option' => array('value' => '01')),
6576
			'Jan',
6577
			'/option',
6578
			array('option' => array('value' => '02')),
6579
			'Feb',
6580
			'/option',
6581
			'*/select',
6582
		);
6583
		$this->assertTags($result, $expected);
6584
6585
		$this->Form->request->data['Project']['release'] = '2050-02-10';
6586
		$result = $this->Form->month('Project.release');
6587
6588
		$expected = array(
6589
			array('select' => array('name' => 'data[Project][release][month]', 'id' => 'ProjectReleaseMonth')),
6590
			array('option' => array('value' => '')),
6591
			'/option',
6592
			array('option' => array('value' => '01')),
6593
			'January',
6594
			'/option',
6595
			array('option' => array('value' => '02', 'selected' => 'selected')),
6596
			'February',
6597
			'/option',
6598
			'*/select',
6599
		);
6600
		$this->assertTags($result, $expected);
6601
6602
		$this->Form->request->data['Model']['field'] = '12a';
6603
		$result = $this->Form->month('Model.field');
6604
		$expected = array(
6605
			array('select' => array('name' => 'data[Model][field][month]', 'id' => 'ModelFieldMonth')),
6606
			array('option' => array('value' => '')),
6607
			'/option',
6608
			array('option' => array('value' => '01')),
6609
			date('F', strtotime('2008-01-01 00:00:00')),
6610
			'/option',
6611
			array('option' => array('value' => '02')),
6612
			date('F', strtotime('2008-02-01 00:00:00')),
6613
			'/option',
6614
			'*/select',
6615
		);
6616
		$this->assertTags($result, $expected);
6617
	}
6618
6619
/**
6620
 * testDay method
6621
 *
6622
 * @return void
6623
 */
6624
	public function testDay() {
6625
		extract($this->dateRegex);
6626
6627
		$result = $this->Form->day('Model.field', array('value' => false));
6628
		$expected = array(
6629
			array('select' => array('name' => 'data[Model][field][day]', 'id' => 'ModelFieldDay')),
6630
			array('option' => array('value' => '')),
6631
			'/option',
6632
			array('option' => array('value' => '01')),
6633
			'1',
6634
			'/option',
6635
			array('option' => array('value' => '02')),
6636
			'2',
6637
			'/option',
6638
			$daysRegex,
6639
			'/select',
6640
		);
6641
		$this->assertTags($result, $expected);
6642
6643
		$this->Form->request->data['Model']['field'] = '2006-10-10 23:12:32';
6644
		$result = $this->Form->day('Model.field');
6645
		$expected = array(
6646
			array('select' => array('name' => 'data[Model][field][day]', 'id' => 'ModelFieldDay')),
6647
			array('option' => array('value' => '')),
6648
			'/option',
6649
			array('option' => array('value' => '01')),
6650
			'1',
6651
			'/option',
6652
			array('option' => array('value' => '02')),
6653
			'2',
6654
			'/option',
6655
			$daysRegex,
6656
			array('option' => array('value' => '10', 'selected' => 'selected')),
6657
			'10',
6658
			'/option',
6659
			$daysRegex,
6660
			'/select',
6661
		);
6662
		$this->assertTags($result, $expected);
6663
6664
		$this->Form->request->data['Model']['field'] = '';
6665
		$result = $this->Form->day('Model.field', array('value' => '10'));
6666
		$expected = array(
6667
			array('select' => array('name' => 'data[Model][field][day]', 'id' => 'ModelFieldDay')),
6668
			array('option' => array('value' => '')),
6669
			'/option',
6670
			array('option' => array('value' => '01')),
6671
			'1',
6672
			'/option',
6673
			array('option' => array('value' => '02')),
6674
			'2',
6675
			'/option',
6676
			$daysRegex,
6677
			array('option' => array('value' => '10', 'selected' => 'selected')),
6678
			'10',
6679
			'/option',
6680
			$daysRegex,
6681
			'/select',
6682
		);
6683
		$this->assertTags($result, $expected);
6684
6685
		$this->Form->request->data['Model']['field'] = '2006-10-10 23:12:32';
6686
		$result = $this->Form->day('Model.field', array('value' => true));
6687
		$expected = array(
6688
			array('select' => array('name' => 'data[Model][field][day]', 'id' => 'ModelFieldDay')),
6689
			array('option' => array('value' => '')),
6690
			'/option',
6691
			array('option' => array('value' => '01')),
6692
			'1',
6693
			'/option',
6694
			array('option' => array('value' => '02')),
6695
			'2',
6696
			'/option',
6697
			$daysRegex,
6698
			array('option' => array('value' => '10', 'selected' => 'selected')),
6699
			'10',
6700
			'/option',
6701
			$daysRegex,
6702
			'/select',
6703
		);
6704
		$this->assertTags($result, $expected);
6705
6706
		$this->Form->request->data['Project']['release'] = '2050-10-10';
6707
		$result = $this->Form->day('Project.release');
6708
6709
		$expected = array(
6710
			array('select' => array('name' => 'data[Project][release][day]', 'id' => 'ProjectReleaseDay')),
6711
			array('option' => array('value' => '')),
6712
			'/option',
6713
			array('option' => array('value' => '01')),
6714
			'1',
6715
			'/option',
6716
			array('option' => array('value' => '02')),
6717
			'2',
6718
			'/option',
6719
			$daysRegex,
6720
			array('option' => array('value' => '10', 'selected' => 'selected')),
6721
			'10',
6722
			'/option',
6723
			$daysRegex,
6724
			'/select',
6725
		);
6726
		$this->assertTags($result, $expected);
6727
6728
		$this->Form->request->data['Model']['field'] = '12e';
6729
		$result = $this->Form->day('Model.field');
6730
		$expected = array(
6731
			array('select' => array('name' => 'data[Model][field][day]', 'id' => 'ModelFieldDay')),
6732
			array('option' => array('value' => '')),
6733
			'/option',
6734
			array('option' => array('value' => '01')),
6735
			'1',
6736
			'/option',
6737
			array('option' => array('value' => '02')),
6738
			'2',
6739
			'/option',
6740
			$daysRegex,
6741
			'/select',
6742
		);
6743
		$this->assertTags($result, $expected);
6744
	}
6745
6746
/**
6747
 * testMinute method
6748
 *
6749
 * @return void
6750
 */
6751
	public function testMinute() {
6752
		extract($this->dateRegex);
6753
6754
		$result = $this->Form->minute('Model.field');
6755
		$expected = array(
6756
			array('select' => array('name' => 'data[Model][field][min]', 'id' => 'ModelFieldMin')),
6757
			array('option' => array('value' => '')),
6758
			'/option',
6759
			array('option' => array('value' => '00')),
6760
			'00',
6761
			'/option',
6762
			array('option' => array('value' => '01')),
6763
			'01',
6764
			'/option',
6765
			array('option' => array('value' => '02')),
6766
			'02',
6767
			'/option',
6768
			$minutesRegex,
6769
			'/select',
6770
		);
6771
		$this->assertTags($result, $expected);
6772
6773
		$this->Form->request->data['Model']['field'] = '2006-10-10 00:12:32';
6774
		$result = $this->Form->minute('Model.field');
6775
		$expected = array(
6776
			array('select' => array('name' => 'data[Model][field][min]', 'id' => 'ModelFieldMin')),
6777
			array('option' => array('value' => '')),
6778
			'/option',
6779
			array('option' => array('value' => '00')),
6780
			'00',
6781
			'/option',
6782
			array('option' => array('value' => '01')),
6783
			'01',
6784
			'/option',
6785
			array('option' => array('value' => '02')),
6786
			'02',
6787
			'/option',
6788
			$minutesRegex,
6789
			array('option' => array('value' => '12', 'selected' => 'selected')),
6790
			'12',
6791
			'/option',
6792
			$minutesRegex,
6793
			'/select',
6794
		);
6795
		$this->assertTags($result, $expected);
6796
6797
		$this->Form->request->data['Model']['field'] = '';
6798
		$result = $this->Form->minute('Model.field', array('interval' => 5));
6799
		$expected = array(
6800
			array('select' => array('name' => 'data[Model][field][min]', 'id' => 'ModelFieldMin')),
6801
			array('option' => array('value' => '')),
6802
			'/option',
6803
			array('option' => array('value' => '00')),
6804
			'00',
6805
			'/option',
6806
			array('option' => array('value' => '05')),
6807
			'05',
6808
			'/option',
6809
			array('option' => array('value' => '10')),
6810
			'10',
6811
			'/option',
6812
			$minutesRegex,
6813
			'/select',
6814
		);
6815
		$this->assertTags($result, $expected);
6816
6817
		$this->Form->request->data['Model']['field'] = '2006-10-10 00:10:32';
6818
		$result = $this->Form->minute('Model.field', array('interval' => 5));
6819
		$expected = array(
6820
			array('select' => array('name' => 'data[Model][field][min]', 'id' => 'ModelFieldMin')),
6821
			array('option' => array('value' => '')),
6822
			'/option',
6823
			array('option' => array('value' => '00')),
6824
			'00',
6825
			'/option',
6826
			array('option' => array('value' => '05')),
6827
			'05',
6828
			'/option',
6829
			array('option' => array('value' => '10', 'selected' => 'selected')),
6830
			'10',
6831
			'/option',
6832
			$minutesRegex,
6833
			'/select',
6834
		);
6835
		$this->assertTags($result, $expected);
6836
6837
		$result = $this->Form->minute('Model.field', array('value' => '#invalid#'));
6838
		$expected = array(
6839
			array('select' => array('name' => 'data[Model][field][min]', 'id' => 'ModelFieldMin')),
6840
			array('option' => array('value' => '')),
6841
			'/option',
6842
			array('option' => array('value' => '00')),
6843
			'00',
6844
			'/option',
6845
			array('option' => array('value' => '01')),
6846
			'01',
6847
			'/option',
6848
			array('option' => array('value' => '02')),
6849
			'02',
6850
			'/option',
6851
			$minutesRegex,
6852
			'/select',
6853
		);
6854
		$this->assertTags($result, $expected);
6855
	}
6856
6857
/**
6858
 * testHour method
6859
 *
6860
 * @return void
6861
 */
6862
	public function testHour() {
6863
		extract($this->dateRegex);
6864
6865
		$result = $this->Form->hour('Model.field', false);
6866
		$expected = array(
6867
			array('select' => array('name' => 'data[Model][field][hour]', 'id' => 'ModelFieldHour')),
6868
			array('option' => array('value' => '')),
6869
			'/option',
6870
			array('option' => array('value' => '01')),
6871
			'1',
6872
			'/option',
6873
			array('option' => array('value' => '02')),
6874
			'2',
6875
			'/option',
6876
			$hoursRegex,
6877
			'/select',
6878
		);
6879
		$this->assertTags($result, $expected);
6880
6881
		$this->Form->request->data['Model']['field'] = '2006-10-10 00:12:32';
6882
		$result = $this->Form->hour('Model.field', false);
6883
		$expected = array(
6884
			array('select' => array('name' => 'data[Model][field][hour]', 'id' => 'ModelFieldHour')),
6885
			array('option' => array('value' => '')),
6886
			'/option',
6887
			array('option' => array('value' => '01')),
6888
			'1',
6889
			'/option',
6890
			array('option' => array('value' => '02')),
6891
			'2',
6892
			'/option',
6893
			$hoursRegex,
6894
			array('option' => array('value' => '12', 'selected' => 'selected')),
6895
			'12',
6896
			'/option',
6897
			'/select',
6898
		);
6899
		$this->assertTags($result, $expected);
6900
6901
		$this->Form->request->data['Model']['field'] = '';
6902
		$result = $this->Form->hour('Model.field', true, array('value' => '23'));
6903
		$this->assertContains('<option value="23" selected="selected">23</option>', $result);
6904
6905
		$result = $this->Form->hour('Model.field', false, array('value' => '23'));
6906
		$this->assertContains('<option value="11" selected="selected">11</option>', $result);
6907
6908
		$this->Form->request->data['Model']['field'] = '2006-10-10 00:12:32';
6909
		$result = $this->Form->hour('Model.field', true);
6910
		$expected = array(
6911
			array('select' => array('name' => 'data[Model][field][hour]', 'id' => 'ModelFieldHour')),
6912
			array('option' => array('value' => '')),
6913
			'/option',
6914
			array('option' => array('value' => '00', 'selected' => 'selected')),
6915
			'0',
6916
			'/option',
6917
			array('option' => array('value' => '01')),
6918
			'1',
6919
			'/option',
6920
			array('option' => array('value' => '02')),
6921
			'2',
6922
			'/option',
6923
			$hoursRegex,
6924
			'/select',
6925
		);
6926
		$this->assertTags($result, $expected);
6927
6928
		unset($this->Form->request->data['Model']['field']);
6929
		$result = $this->Form->hour('Model.field', true, array('value' => 'now'));
6930
		$thisHour = date('H');
6931
		$optValue = date('G');
6932
		$this->assertRegExp('/<option value="' . $thisHour . '" selected="selected">' . $optValue . '<\/option>/', $result);
6933
6934
		$this->Form->request->data['Model']['field'] = '2050-10-10 01:12:32';
6935
		$result = $this->Form->hour('Model.field', true);
6936
		$expected = array(
6937
			array('select' => array('name' => 'data[Model][field][hour]', 'id' => 'ModelFieldHour')),
6938
			array('option' => array('value' => '')),
6939
			'/option',
6940
			array('option' => array('value' => '00')),
6941
			'0',
6942
			'/option',
6943
			array('option' => array('value' => '01', 'selected' => 'selected')),
6944
			'1',
6945
			'/option',
6946
			array('option' => array('value' => '02')),
6947
			'2',
6948
			'/option',
6949
			$hoursRegex,
6950
			'/select',
6951
		);
6952
		$this->assertTags($result, $expected);
6953
6954
		$this->Form->request->data['Model']['field'] = '18a';
6955
		$result = $this->Form->hour('Model.field', false);
6956
		$expected = array(
6957
			array('select' => array('name' => 'data[Model][field][hour]', 'id' => 'ModelFieldHour')),
6958
			array('option' => array('value' => '')),
6959
			'/option',
6960
			array('option' => array('value' => '01')),
6961
			'1',
6962
			'/option',
6963
			array('option' => array('value' => '02')),
6964
			'2',
6965
			'/option',
6966
			$hoursRegex,
6967
			'/select',
6968
		);
6969
		$this->assertTags($result, $expected);
6970
	}
6971
6972
/**
6973
 * testYear method
6974
 *
6975
 * @return void
6976
 */
6977
	public function testYear() {
6978
		$result = $this->Form->year('Model.field', 2006, 2007);
6979
		$expected = array(
6980
			array('select' => array('name' => 'data[Model][field][year]', 'id' => 'ModelFieldYear')),
6981
			array('option' => array('value' => '')),
6982
			'/option',
6983
			array('option' => array('value' => '2007')),
6984
			'2007',
6985
			'/option',
6986
			array('option' => array('value' => '2006')),
6987
			'2006',
6988
			'/option',
6989
			'/select',
6990
		);
6991
		$this->assertTags($result, $expected);
6992
6993
		$result = $this->Form->year('Model.field', 2006, 2007, array('orderYear' => 'asc'));
6994
		$expected = array(
6995
			array('select' => array('name' => 'data[Model][field][year]', 'id' => 'ModelFieldYear')),
6996
			array('option' => array('value' => '')),
6997
			'/option',
6998
			array('option' => array('value' => '2006')),
6999
			'2006',
7000
			'/option',
7001
			array('option' => array('value' => '2007')),
7002
			'2007',
7003
			'/option',
7004
			'/select',
7005
		);
7006
		$this->assertTags($result, $expected);
7007
7008
		$this->request->data['Contact']['published'] = '';
7009
		$result = $this->Form->year('Contact.published', 2006, 2007, array('class' => 'year'));
7010
		$expected = array(
7011
			array('select' => array('name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear', 'class' => 'year')),
7012
			array('option' => array('value' => '')),
7013
			'/option',
7014
			array('option' => array('value' => '2007')),
7015
			'2007',
7016
			'/option',
7017
			array('option' => array('value' => '2006')),
7018
			'2006',
7019
			'/option',
7020
			'/select',
7021
		);
7022
		$this->assertTags($result, $expected);
7023
7024
		$this->Form->request->data['Contact']['published'] = '2006-10-10';
7025
		$result = $this->Form->year('Contact.published', 2006, 2007, array('empty' => false));
7026
		$expected = array(
7027
			array('select' => array('name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear')),
7028
			array('option' => array('value' => '2007')),
7029
			'2007',
7030
			'/option',
7031
			array('option' => array('value' => '2006', 'selected' => 'selected')),
7032
			'2006',
7033
			'/option',
7034
			'/select',
7035
		);
7036
		$this->assertTags($result, $expected);
7037
7038
		$this->Form->request->data['Contact']['published'] = '';
7039
		$result = $this->Form->year('Contact.published', 2006, 2007, array('value' => false));
7040
		$expected = array(
7041
			array('select' => array('name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear')),
7042
			array('option' => array('value' => '')),
7043
			'/option',
7044
			array('option' => array('value' => '2007')),
7045
			'2007',
7046
			'/option',
7047
			array('option' => array('value' => '2006')),
7048
			'2006',
7049
			'/option',
7050
			'/select',
7051
		);
7052
		$this->assertTags($result, $expected);
7053
7054
		$this->Form->request->data['Contact']['published'] = '2006-10-10';
7055
		$result = $this->Form->year('Contact.published', 2006, 2007, array('empty' => false, 'value' => false));
7056
		$expected = array(
7057
			array('select' => array('name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear')),
7058
			array('option' => array('value' => '2007')),
7059
			'2007',
7060
			'/option',
7061
			array('option' => array('value' => '2006', 'selected' => 'selected')),
7062
			'2006',
7063
			'/option',
7064
			'/select',
7065
		);
7066
		$this->assertTags($result, $expected);
7067
7068
		$this->Form->request->data['Contact']['published'] = '';
7069
		$result = $this->Form->year('Contact.published', 2006, 2007, array('value' => 2007));
7070
		$expected = array(
7071
			array('select' => array('name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear')),
7072
			array('option' => array('value' => '')),
7073
			'/option',
7074
			array('option' => array('value' => '2007', 'selected' => 'selected')),
7075
			'2007',
7076
			'/option',
7077
			array('option' => array('value' => '2006')),
7078
			'2006',
7079
			'/option',
7080
			'/select',
7081
		);
7082
		$this->assertTags($result, $expected);
7083
7084
		$this->Form->request->data['Contact']['published'] = '2006-10-10';
7085
		$result = $this->Form->year('Contact.published', 2006, 2007, array('empty' => false, 'value' => 2007));
7086
		$expected = array(
7087
			array('select' => array('name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear')),
7088
			array('option' => array('value' => '2007', 'selected' => 'selected')),
7089
			'2007',
7090
			'/option',
7091
			array('option' => array('value' => '2006')),
7092
			'2006',
7093
			'/option',
7094
			'/select',
7095
		);
7096
		$this->assertTags($result, $expected);
7097
7098
		$this->Form->request->data['Contact']['published'] = '';
7099
		$result = $this->Form->year('Contact.published', 2006, 2008, array('empty' => false, 'value' => 2007));
7100
		$expected = array(
7101
			array('select' => array('name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear')),
7102
			array('option' => array('value' => '2008')),
7103
			'2008',
7104
			'/option',
7105
			array('option' => array('value' => '2007', 'selected' => 'selected')),
7106
			'2007',
7107
			'/option',
7108
			array('option' => array('value' => '2006')),
7109
			'2006',
7110
			'/option',
7111
			'/select',
7112
		);
7113
		$this->assertTags($result, $expected);
7114
7115
		$this->Form->request->data['Contact']['published'] = '2006-10-10';
7116
		$result = $this->Form->year('Contact.published', 2006, 2008, array('empty' => false));
7117
		$expected = array(
7118
			array('select' => array('name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear')),
7119
			array('option' => array('value' => '2008')),
7120
			'2008',
7121
			'/option',
7122
			array('option' => array('value' => '2007')),
7123
			'2007',
7124
			'/option',
7125
			array('option' => array('value' => '2006', 'selected' => 'selected')),
7126
			'2006',
7127
			'/option',
7128
			'/select',
7129
		);
7130
		$this->assertTags($result, $expected);
7131
7132
		$this->Form->request->data = array();
7133
		$this->Form->create('Contact');
7134
		$result = $this->Form->year('published', 2006, 2008, array('empty' => false));
7135
		$expected = array(
7136
			array('select' => array('name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear')),
7137
			array('option' => array('value' => '2008')),
7138
			'2008',
7139
			'/option',
7140
			array('option' => array('value' => '2007')),
7141
			'2007',
7142
			'/option',
7143
			array('option' => array('value' => '2006')),
7144
			'2006',
7145
			'/option',
7146
			'/select',
7147
		);
7148
		$this->assertTags($result, $expected);
7149
7150
		$result = $this->Form->year('published', array(), array(), array('empty' => false));
7151
		$this->assertContains('data[Contact][published][year]', $result);
7152
7153
		$this->Form->request->data['Contact']['published'] = '2014ee';
7154
		$result = $this->Form->year('Contact.published', 2010, 2011);
7155
		$expected = array(
7156
			array('select' => array('name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear')),
7157
			array('option' => array('value' => '')),
7158
			'/option',
7159
			array('option' => array('value' => '2011')),
7160
			'2011',
7161
			'/option',
7162
			array('option' => array('value' => '2010')),
7163
			'2010',
7164
			'/option',
7165
			'/select',
7166
		);
7167
		$this->assertTags($result, $expected);
7168
	}
7169
7170
/**
7171
 * testYearAutoExpandRange method
7172
 *
7173
 * @return void
7174
 */
7175
	public function testYearAutoExpandRange() {
7176
		$this->Form->request->data['User']['birthday'] = '1930-10-10';
7177
		$result = $this->Form->year('User.birthday');
7178
		preg_match_all('/<option value="([\d]+)"/', $result, $matches);
7179
7180
		$result = $matches[1];
7181
		$expected = range(date('Y') + 20, 1930);
7182
		$this->assertEquals($expected, $result);
7183
7184
		$this->Form->request->data['Project']['release'] = '2050-10-10';
7185
		$result = $this->Form->year('Project.release');
7186
		preg_match_all('/<option value="([\d]+)"/', $result, $matches);
7187
7188
		$result = $matches[1];
7189
		$expected = range(2050, date('Y') - 20);
7190
		$this->assertEquals($expected, $result);
7191
7192
		$this->Form->request->data['Project']['release'] = '1881-10-10';
7193
		$result = $this->Form->year('Project.release', 1890, 1900);
7194
		preg_match_all('/<option value="([\d]+)"/', $result, $matches);
7195
7196
		$result = $matches[1];
7197
		$expected = range(1900, 1881);
7198
		$this->assertEquals($expected, $result);
7199
	}
7200
7201
/**
7202
 * testInputDate method
7203
 *
7204
 * Test various inputs with type date and different dateFormat values.
7205
 * Failing to provide a dateFormat key should not error.
7206
 * It should simply not pre-select any value then.
7207
 *
7208
 * @return void
7209
 */
7210
	public function testInputDate() {
7211
		$this->Form->request->data = array(
7212
			'User' => array(
7213
				'month_year' => array('month' => date('m')),
7214
				'just_year' => array('month' => date('m')),
7215
				'just_month' => array('year' => date('Y')),
7216
				'just_day' => array('month' => date('m')),
7217
			)
7218
		);
7219
		$this->Form->create('User');
7220
		$result = $this->Form->input('month_year',
7221
				array(
7222
					'label' => false,
7223
					'div' => false,
7224
					'type' => 'date',
7225
					'dateFormat' => 'MY',
7226
					'minYear' => 2006,
7227
					'maxYear' => 2008
7228
				)
7229
		);
7230
		$this->assertContains('value="' . date('m') . '" selected="selected"', $result);
7231
		$this->assertNotContains('value="2008" selected="selected"', $result);
7232
7233
		$result = $this->Form->input('just_year',
7234
			array(
7235
				'type' => 'date',
7236
				'label' => false,
7237
				'dateFormat' => 'Y',
7238
				'minYear' => date('Y'),
7239
				'maxYear' => date('Y', strtotime('+20 years'))
7240
			)
7241
		);
7242
		$this->assertNotContains('value="' . date('Y') . '" selected="selected"', $result);
7243
7244
		$result = $this->Form->input('just_month',
7245
			array(
7246
				'type' => 'date',
7247
				'label' => false,
7248
				'dateFormat' => 'M',
7249
				'empty' => false,
7250
			)
7251
		);
7252
		$this->assertNotContains('value="' . date('m') . '" selected="selected"', $result);
7253
7254
		$result = $this->Form->input('just_day',
7255
			array(
7256
				'type' => 'date',
7257
				'label' => false,
7258
				'dateFormat' => 'D',
7259
				'empty' => false,
7260
			)
7261
		);
7262
		$this->assertNotContains('value="' . date('d') . '" selected="selected"', $result);
7263
	}
7264
7265
/**
7266
 * testInputDateMaxYear method
7267
 *
7268
 * Let's say we want to only allow users born from 2006 to 2008 to register
7269
 * This being the first singup page, we still don't have any data
7270
 *
7271
 * @return void
7272
 */
7273
	public function testInputDateMaxYear() {
7274
		$this->Form->request->data = array();
7275
		$this->Form->create('User');
7276
		$result = $this->Form->input('birthday',
7277
				array(
7278
					'label' => false,
7279
					'div' => false,
7280
					'type' => 'date',
7281
					'dateFormat' => 'DMY',
7282
					'minYear' => 2006,
7283
					'maxYear' => 2008
7284
				)
7285
		);
7286
		$this->assertContains('value="2008" selected="selected"', $result);
7287
	}
7288
7289
/**
7290
 * testTextArea method
7291
 *
7292
 * @return void
7293
 */
7294
	public function testTextArea() {
7295
		$this->Form->request->data = array('Model' => array('field' => 'some test data'));
7296
		$result = $this->Form->textarea('Model.field');
7297
		$expected = array(
7298
			'textarea' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
7299
			'some test data',
7300
			'/textarea',
7301
		);
7302
		$this->assertTags($result, $expected);
7303
7304
		$result = $this->Form->textarea('Model.tmp');
7305
		$expected = array(
7306
			'textarea' => array('name' => 'data[Model][tmp]', 'id' => 'ModelTmp'),
7307
			'/textarea',
7308
		);
7309
		$this->assertTags($result, $expected);
7310
7311
		$this->Form->request->data = array('Model' => array('field' => 'some <strong>test</strong> data with <a href="#">HTML</a> chars'));
7312
		$result = $this->Form->textarea('Model.field');
7313
		$expected = array(
7314
			'textarea' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
7315
			htmlentities('some <strong>test</strong> data with <a href="#">HTML</a> chars'),
7316
			'/textarea',
7317
		);
7318
		$this->assertTags($result, $expected);
7319
7320
		$this->Form->request->data = array('Model' => array('field' => 'some <strong>test</strong> data with <a href="#">HTML</a> chars'));
7321
		$result = $this->Form->textarea('Model.field', array('escape' => false));
7322
		$expected = array(
7323
			'textarea' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
7324
			'some <strong>test</strong> data with <a href="#">HTML</a> chars',
7325
			'/textarea',
7326
		);
7327
		$this->assertTags($result, $expected);
7328
7329
		$this->Form->request->data['Model']['0']['OtherModel']['field'] = null;
7330
		$result = $this->Form->textarea('Model.0.OtherModel.field');
7331
		$expected = array(
7332
			'textarea' => array('name' => 'data[Model][0][OtherModel][field]', 'id' => 'Model0OtherModelField'),
7333
			'/textarea'
7334
		);
7335
		$this->assertTags($result, $expected);
7336
	}
7337
7338
/**
7339
 * testTextAreaWithStupidCharacters method
7340
 *
7341
 * test text area with non-ascii characters
7342
 *
7343
 * @return void
7344
 */
7345
	public function testTextAreaWithStupidCharacters() {
7346
		$this->loadFixtures('Post');
7347
		$result = $this->Form->input('Post.content', array(
7348
			'label' => 'Current Text', 'value' => "GREAT®", 'rows' => '15', 'cols' => '75'
7349
		));
7350
		$expected = array(
7351
			'div' => array('class' => 'input textarea'),
7352
				'label' => array('for' => 'PostContent'),
7353
					'Current Text',
7354
				'/label',
7355
				'textarea' => array('name' => 'data[Post][content]', 'id' => 'PostContent', 'rows' => '15', 'cols' => '75'),
7356
				'GREAT®',
7357
				'/textarea',
7358
			'/div'
7359
		);
7360
		$this->assertTags($result, $expected);
7361
	}
7362
7363
/**
7364
 * testHiddenField method
7365
 *
7366
 * @return void
7367
 */
7368
	public function testHiddenField() {
7369
		$Contact = ClassRegistry::getObject('Contact');
7370
		$Contact->validationErrors['field'] = 1;
7371
		$this->Form->request->data['Contact']['field'] = 'test';
7372
		$result = $this->Form->hidden('Contact.field', array('id' => 'theID'));
7373
		$this->assertTags($result, array(
7374
			'input' => array('type' => 'hidden', 'class' => 'form-error', 'name' => 'data[Contact][field]', 'id' => 'theID', 'value' => 'test'))
7375
		);
7376
	}
7377
7378
/**
7379
 * testFileUploadField method
7380
 *
7381
 * @return void
7382
 */
7383
	public function testFileUploadField() {
7384
		$result = $this->Form->file('Model.upload');
7385
		$this->assertTags($result, array('input' => array('type' => 'file', 'name' => 'data[Model][upload]', 'id' => 'ModelUpload')));
7386
7387
		$this->Form->request->data['Model.upload'] = array("name" => "", "type" => "", "tmp_name" => "", "error" => 4, "size" => 0);
7388
		$result = $this->Form->input('Model.upload', array('type' => 'file'));
7389
		$expected = array(
7390
			'div' => array('class' => 'input file'),
7391
			'label' => array('for' => 'ModelUpload'),
7392
			'Upload',
7393
			'/label',
7394
			'input' => array('type' => 'file', 'name' => 'data[Model][upload]', 'id' => 'ModelUpload'),
7395
			'/div'
7396
		);
7397
		$this->assertTags($result, $expected);
7398
7399
		$this->Form->request->data['Model']['upload'] = 'no data should be set in value';
7400
		$result = $this->Form->file('Model.upload');
7401
		$this->assertTags($result, array('input' => array('type' => 'file', 'name' => 'data[Model][upload]', 'id' => 'ModelUpload')));
7402
	}
7403
7404
/**
7405
 * test File upload input on a model not used in create();
7406
 *
7407
 * @return void
7408
 */
7409
	public function testFileUploadOnOtherModel() {
7410
		$this->Form->create('ValidateUser', array('type' => 'file'));
7411
		$result = $this->Form->file('ValidateProfile.city');
7412
		$expected = array(
7413
			'input' => array('type' => 'file', 'name' => 'data[ValidateProfile][city]', 'id' => 'ValidateProfileCity')
7414
		);
7415
		$this->assertTags($result, $expected);
7416
	}
7417
7418
/**
7419
 * testButton method
7420
 *
7421
 * @return void
7422
 */
7423
	public function testButton() {
7424
		$result = $this->Form->button('Hi');
7425
		$this->assertTags($result, array('button' => array('type' => 'submit'), 'Hi', '/button'));
7426
7427
		$result = $this->Form->button('Clear Form >', array('type' => 'reset'));
7428
		$this->assertTags($result, array('button' => array('type' => 'reset'), 'Clear Form >', '/button'));
7429
7430
		$result = $this->Form->button('Clear Form >', array('type' => 'reset', 'id' => 'clearForm'));
7431
		$this->assertTags($result, array('button' => array('type' => 'reset', 'id' => 'clearForm'), 'Clear Form >', '/button'));
7432
7433
		$result = $this->Form->button('<Clear Form>', array('type' => 'reset', 'escape' => true));
7434
		$this->assertTags($result, array('button' => array('type' => 'reset'), '&lt;Clear Form&gt;', '/button'));
7435
7436
		$result = $this->Form->button('No type', array('type' => false));
7437
		$this->assertTags($result, array('button' => array(), 'No type', '/button'));
7438
7439
		$result = $this->Form->button('Upload Text', array('onClick' => "$('#postAddForm').ajaxSubmit({target: '#postTextUpload', url: '/posts/text'});return false;'", 'escape' => false));
7440
		$this->assertNotRegExp('/\&039/', $result);
7441
	}
7442
7443
/**
7444
 * Test that button() makes unlocked fields by default.
7445
 *
7446
 * @return void
7447
 */
7448 View Code Duplication
	public function testButtonUnlockedByDefault() {
7449
		$this->Form->request->params['_Token']['key'] = 'secured';
7450
		$this->Form->button('Save', array('name' => 'save'));
7451
		$this->Form->button('Clear');
7452
7453
		$result = $this->Form->unlockField();
7454
		$this->assertEquals(array('save'), $result);
7455
	}
7456
7457
/**
7458
 * testPostButton method
7459
 *
7460
 * @return void
7461
 */
7462
	public function testPostButton() {
7463
		$result = $this->Form->postButton('Hi', '/controller/action');
7464
		$this->assertTags($result, array(
7465
			'form' => array('method' => 'post', 'action' => '/controller/action', 'accept-charset' => 'utf-8'),
7466
			'div' => array('style' => 'display:none;'),
7467
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
7468
			'/div',
7469
			'button' => array('type' => 'submit'),
7470
			'Hi',
7471
			'/button',
7472
			'/form'
7473
		));
7474
7475
		$result = $this->Form->postButton('Send', '/', array('data' => array('extra' => 'value')));
7476
		$this->assertTrue(strpos($result, '<input type="hidden" name="data[extra]" value="value"/>') !== false);
7477
	}
7478
7479
/**
7480
 * Test using postButton with N dimensional data.
7481
 *
7482
 * @return void
7483
 */
7484 View Code Duplication
	public function testPostButtonNestedData() {
7485
		$data = array(
7486
			'one' => array(
7487
				'two' => array(
7488
					3, 4, 5
7489
				)
7490
			)
7491
		);
7492
		$result = $this->Form->postButton('Send', '/', array('data' => $data));
7493
		$this->assertContains('<input type="hidden" name="data[one][two][0]" value="3"', $result);
7494
		$this->assertContains('<input type="hidden" name="data[one][two][1]" value="4"', $result);
7495
		$this->assertContains('<input type="hidden" name="data[one][two][2]" value="5"', $result);
7496
	}
7497
7498
/**
7499
 * Test that postButton adds _Token fields.
7500
 *
7501
 * @return void
7502
 */
7503
	public function testSecurePostButton() {
7504
		$this->Form->request->params['_Token'] = array('key' => 'testkey');
7505
7506
		$result = $this->Form->postButton('Delete', '/posts/delete/1');
7507
		$expected = array(
7508
			'form' => array(
7509
				'method' => 'post', 'action' => '/posts/delete/1', 'accept-charset' => 'utf-8',
7510
			),
7511
			array('div' => array('style' => 'display:none;')),
7512
			array('input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST')),
7513
			array('input' => array('type' => 'hidden', 'name' => 'data[_Token][key]', 'value' => 'testkey', 'id' => 'preg:/Token\d+/')),
7514
			'/div',
7515
			'button' => array('type' => 'submit'),
7516
			'Delete',
7517
			'/button',
7518
			array('div' => array('style' => 'display:none;')),
7519
			array('input' => array('type' => 'hidden', 'name' => 'data[_Token][fields]', 'value' => 'preg:/[\w\d%]+/', 'id' => 'preg:/TokenFields\d+/')),
7520
			array('input' => array('type' => 'hidden', 'name' => 'data[_Token][unlocked]', 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/')),
7521
			'/div',
7522
			'/form',
7523
		);
7524
		$this->assertTags($result, $expected);
7525
	}
7526
7527
/**
7528
 * testPostLink method
7529
 *
7530
 * @return void
7531
 */
7532
	public function testPostLink() {
7533
		$result = $this->Form->postLink('Delete', '/posts/delete/1');
7534
		$this->assertTags($result, array(
7535
			'form' => array(
7536
				'method' => 'post', 'action' => '/posts/delete/1',
7537
				'name' => 'preg:/post_\w+/', 'id' => 'preg:/post_\w+/', 'style' => 'display:none;'
7538
			),
7539
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
7540
			'/form',
7541
			'a' => array('href' => '#', 'onclick' => 'preg:/document\.post_\w+\.submit\(\); event\.returnValue = false; return false;/'),
7542
			'Delete',
7543
			'/a'
7544
		));
7545
7546
		$result = $this->Form->postLink('Delete', '/posts/delete/1', array('method' => 'delete'));
7547
		$this->assertTags($result, array(
7548
			'form' => array(
7549
				'method' => 'post', 'action' => '/posts/delete/1',
7550
				'name' => 'preg:/post_\w+/', 'id' => 'preg:/post_\w+/', 'style' => 'display:none;'
7551
			),
7552
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'DELETE'),
7553
			'/form',
7554
			'a' => array('href' => '#', 'onclick' => 'preg:/document\.post_\w+\.submit\(\); event\.returnValue = false; return false;/'),
7555
			'Delete',
7556
			'/a'
7557
		));
7558
7559
		$result = $this->Form->postLink('Delete', '/posts/delete/1', array(), 'Confirm?');
7560
		$this->assertTags($result, array(
7561
			'form' => array(
7562
				'method' => 'post', 'action' => '/posts/delete/1',
7563
				'name' => 'preg:/post_\w+/', 'id' => 'preg:/post_\w+/', 'style' => 'display:none;'
7564
			),
7565
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
7566
			'/form',
7567
			'a' => array('href' => '#', 'onclick' => 'preg:/if \(confirm\(&quot;Confirm\?&quot;\)\) \{ document\.post_\w+\.submit\(\); \} event\.returnValue = false; return false;/'),
7568
			'Delete',
7569
			'/a'
7570
		));
7571
7572
		$result = $this->Form->postLink('Delete', '/posts/delete/1', array('escape' => false), '\'Confirm\' this "deletion"?');
7573
		$this->assertTags($result, array(
7574
			'form' => array(
7575
				'method' => 'post', 'action' => '/posts/delete/1',
7576
				'name' => 'preg:/post_\w+/', 'id' => 'preg:/post_\w+/', 'style' => 'display:none;'
7577
			),
7578
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
7579
			'/form',
7580
			'a' => array('href' => '#', 'onclick' => 'preg:/if \(confirm\(&quot;&#039;Confirm&#039; this \\\\&quot;deletion\\\\&quot;\?&quot;\)\) \{ document\.post_\w+\.submit\(\); \} event\.returnValue = false; return false;/'),
7581
			'Delete',
7582
			'/a'
7583
		));
7584
7585
		$result = $this->Form->postLink('Delete', '/posts/delete', array('data' => array('id' => 1)));
7586
		$this->assertContains('<input type="hidden" name="data[id]" value="1"/>', $result);
7587
7588
		$result = $this->Form->postLink('Delete', '/posts/delete/1', array('target' => '_blank'));
7589
		$this->assertTags($result, array(
7590
			'form' => array(
7591
				'method' => 'post', 'target' => '_blank', 'action' => '/posts/delete/1',
7592
				'name' => 'preg:/post_\w+/', 'id' => 'preg:/post_\w+/', 'style' => 'display:none;'
7593
			),
7594
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
7595
			'/form',
7596
			'a' => array('href' => '#', 'onclick' => 'preg:/document\.post_\w+\.submit\(\); event\.returnValue = false; return false;/'),
7597
			'Delete',
7598
			'/a'
7599
		));
7600
7601
		$result = $this->Form->postLink(
7602
			'',
7603
			array('controller' => 'items', 'action' => 'delete', 10),
7604
			array('class' => 'btn btn-danger', 'escape' => false),
7605
			'Confirm thing'
7606
		);
7607
		$this->assertTags($result, array(
7608
			'form' => array(
7609
				'method' => 'post', 'action' => '/items/delete/10',
7610
				'name' => 'preg:/post_\w+/', 'id' => 'preg:/post_\w+/', 'style' => 'display:none;'
7611
			),
7612
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
7613
			'/form',
7614
			'a' => array('class' => 'btn btn-danger', 'href' => '#', 'onclick' => 'preg:/if \(confirm\(\&quot\;Confirm thing\&quot\;\)\) \{ document\.post_\w+\.submit\(\); \} event\.returnValue = false; return false;/'),
7615
			'/a'
7616
		));
7617
	}
7618
7619
/**
7620
 * Test that security hashes for postLink include the url.
7621
 *
7622
 * @return void
7623
 */
7624
	public function testPostLinkSecurityHash() {
7625
		$hash = Security::hash(
7626
			'/posts/delete/1' .
7627
			serialize(array()) .
7628
			'' .
7629
			Configure::read('Security.salt')
7630
		);
7631
		$hash .= '%3A';
7632
		$this->Form->request->params['_Token']['key'] = 'test';
7633
7634
		$result = $this->Form->postLink('Delete', '/posts/delete/1');
7635
		$this->assertTags($result, array(
7636
			'form' => array(
7637
				'method' => 'post', 'action' => '/posts/delete/1',
7638
				'name', 'id', 'style' => 'display:none;'
7639
			),
7640
			array('input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST')),
7641
			array('input' => array('type' => 'hidden', 'name' => 'data[_Token][key]', 'value' => 'test', 'id')),
7642
			'div' => array('style' => 'display:none;'),
7643
			array('input' => array('type' => 'hidden', 'name' => 'data[_Token][fields]', 'value' => $hash, 'id')),
7644
			array('input' => array('type' => 'hidden', 'name' => 'data[_Token][unlocked]', 'value' => '', 'id')),
7645
			'/div',
7646
			'/form',
7647
			'a' => array('href' => '#', 'onclick' => 'preg:/document\.post_\w+\.submit\(\); event\.returnValue = false; return false;/'),
7648
			'Delete',
7649
			'/a'
7650
		));
7651
	}
7652
7653
/**
7654
 * Test using postLink with N dimensional data.
7655
 *
7656
 * @return void
7657
 */
7658 View Code Duplication
	public function testPostLinkNestedData() {
7659
		$data = array(
7660
			'one' => array(
7661
				'two' => array(
7662
					3, 4, 5
7663
				)
7664
			)
7665
		);
7666
		$result = $this->Form->postLink('Send', '/', array('data' => $data));
7667
		$this->assertContains('<input type="hidden" name="data[one][two][0]" value="3"', $result);
7668
		$this->assertContains('<input type="hidden" name="data[one][two][1]" value="4"', $result);
7669
		$this->assertContains('<input type="hidden" name="data[one][two][2]" value="5"', $result);
7670
	}
7671
7672
/**
7673
 * test creating postLinks after a GET form.
7674
 *
7675
 * @return void
7676
 */
7677
	public function testPostLinkAfterGetForm() {
7678
		$this->Form->request->params['_Token']['key'] = 'testkey';
7679
		$this->Form->create('User', array('type' => 'get'));
7680
		$this->Form->end();
7681
7682
		$result = $this->Form->postLink('Delete', '/posts/delete/1');
7683
		$this->assertTags($result, array(
7684
			'form' => array(
7685
				'method' => 'post', 'action' => '/posts/delete/1',
7686
				'name' => 'preg:/post_\w+/', 'id' => 'preg:/post_\w+/', 'style' => 'display:none;'
7687
			),
7688
			array('input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST')),
7689
			array('input' => array('type' => 'hidden', 'name' => 'data[_Token][key]', 'value' => 'testkey', 'id' => 'preg:/Token\d+/')),
7690
			'div' => array('style' => 'display:none;'),
7691
			array('input' => array('type' => 'hidden', 'name' => 'data[_Token][fields]', 'value' => 'preg:/[\w\d%]+/', 'id' => 'preg:/TokenFields\d+/')),
7692
			array('input' => array('type' => 'hidden', 'name' => 'data[_Token][unlocked]', 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/')),
7693
			'/div',
7694
			'/form',
7695
			'a' => array('href' => '#', 'onclick' => 'preg:/document\.post_\w+\.submit\(\); event\.returnValue = false; return false;/'),
7696
			'Delete',
7697
			'/a'
7698
		));
7699
	}
7700
7701
/**
7702
 * Test that postLink adds _Token fields.
7703
 *
7704
 * @return void
7705
 */
7706
	public function testSecurePostLink() {
7707
		$this->Form->request->params['_Token'] = array('key' => 'testkey');
7708
7709
		$result = $this->Form->postLink('Delete', '/posts/delete/1');
7710
		$expected = array(
7711
			'form' => array(
7712
				'method' => 'post', 'action' => '/posts/delete/1',
7713
				'name' => 'preg:/post_\w+/', 'id' => 'preg:/post_\w+/', 'style' => 'display:none;'
7714
			),
7715
			array('input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST')),
7716
			array('input' => array('type' => 'hidden', 'name' => 'data[_Token][key]', 'value' => 'testkey', 'id' => 'preg:/Token\d+/')),
7717
			'div' => array('style' => 'display:none;'),
7718
			array('input' => array('type' => 'hidden', 'name' => 'data[_Token][fields]', 'value' => 'preg:/[\w\d%]+/', 'id' => 'preg:/TokenFields\d+/')),
7719
			array('input' => array('type' => 'hidden', 'name' => 'data[_Token][unlocked]', 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/')),
7720
			'/div',
7721
			'/form',
7722
			'a' => array('href' => '#', 'onclick' => 'preg:/document\.post_\w+\.submit\(\); event\.returnValue = false; return false;/'),
7723
			'Delete',
7724
			'/a'
7725
		);
7726
		$this->assertTags($result, $expected);
7727
	}
7728
7729
/**
7730
 * testSubmitButton method
7731
 *
7732
 * @return void
7733
 */
7734
	public function testSubmitButton() {
7735
		$result = $this->Form->submit('');
7736
		$expected = array(
7737
			'div' => array('class' => 'submit'),
7738
			'input' => array('type' => 'submit', 'value' => ''),
7739
			'/div'
7740
		);
7741
		$this->assertTags($result, $expected);
7742
7743
		$result = $this->Form->submit('Test Submit');
7744
		$expected = array(
7745
			'div' => array('class' => 'submit'),
7746
			'input' => array('type' => 'submit', 'value' => 'Test Submit'),
7747
			'/div'
7748
		);
7749
		$this->assertTags($result, $expected);
7750
7751
		$result = $this->Form->submit('Test Submit', array('div' => array('tag' => 'span')));
7752
		$expected = array(
7753
			'span' => array('class' => 'submit'),
7754
			'input' => array('type' => 'submit', 'value' => 'Test Submit'),
7755
			'/span'
7756
		);
7757
		$this->assertTags($result, $expected);
7758
7759
		$result = $this->Form->submit('Test Submit', array('class' => 'save', 'div' => false));
7760
		$expected = array('input' => array('type' => 'submit', 'value' => 'Test Submit', 'class' => 'save'));
7761
		$this->assertTags($result, $expected);
7762
7763
		$result = $this->Form->submit('Test Submit', array('div' => array('id' => 'SaveButton')));
7764
		$expected = array(
7765
			'div' => array('class' => 'submit', 'id' => 'SaveButton'),
7766
			'input' => array('type' => 'submit', 'value' => 'Test Submit'),
7767
			'/div'
7768
		);
7769
		$this->assertTags($result, $expected);
7770
7771
		$result = $this->Form->submit('Next >');
7772
		$expected = array(
7773
			'div' => array('class' => 'submit'),
7774
			'input' => array('type' => 'submit', 'value' => 'Next &gt;'),
7775
			'/div'
7776
		);
7777
		$this->assertTags($result, $expected);
7778
7779
		$result = $this->Form->submit('Next >', array('escape' => false));
7780
		$expected = array(
7781
			'div' => array('class' => 'submit'),
7782
			'input' => array('type' => 'submit', 'value' => 'Next >'),
7783
			'/div'
7784
		);
7785
		$this->assertTags($result, $expected);
7786
7787
		$result = $this->Form->submit('Reset!', array('type' => 'reset'));
7788
		$expected = array(
7789
			'div' => array('class' => 'submit'),
7790
			'input' => array('type' => 'reset', 'value' => 'Reset!'),
7791
			'/div'
7792
		);
7793
		$this->assertTags($result, $expected);
7794
7795
		$before = '--before--';
7796
		$after = '--after--';
7797
		$result = $this->Form->submit('Test', array('before' => $before));
7798
		$expected = array(
7799
			'div' => array('class' => 'submit'),
7800
			'--before--',
7801
			'input' => array('type' => 'submit', 'value' => 'Test'),
7802
			'/div'
7803
		);
7804
		$this->assertTags($result, $expected);
7805
7806
		$result = $this->Form->submit('Test', array('after' => $after));
7807
		$expected = array(
7808
			'div' => array('class' => 'submit'),
7809
			'input' => array('type' => 'submit', 'value' => 'Test'),
7810
			'--after--',
7811
			'/div'
7812
		);
7813
		$this->assertTags($result, $expected);
7814
7815
		$result = $this->Form->submit('Test', array('before' => $before, 'after' => $after));
7816
		$expected = array(
7817
			'div' => array('class' => 'submit'),
7818
			'--before--',
7819
			'input' => array('type' => 'submit', 'value' => 'Test'),
7820
			'--after--',
7821
			'/div'
7822
		);
7823
		$this->assertTags($result, $expected);
7824
	}
7825
7826
/**
7827
 * test image submit types.
7828
 *
7829
 * @return void
7830
 */
7831
	public function testSubmitImage() {
7832
		$result = $this->Form->submit('http://example.com/cake.power.gif');
7833
		$expected = array(
7834
			'div' => array('class' => 'submit'),
7835
			'input' => array('type' => 'image', 'src' => 'http://example.com/cake.power.gif'),
7836
			'/div'
7837
		);
7838
		$this->assertTags($result, $expected);
7839
7840
		$result = $this->Form->submit('/relative/cake.power.gif');
7841
		$expected = array(
7842
			'div' => array('class' => 'submit'),
7843
			'input' => array('type' => 'image', 'src' => 'relative/cake.power.gif'),
7844
			'/div'
7845
		);
7846
		$this->assertTags($result, $expected);
7847
7848
		$result = $this->Form->submit('cake.power.gif');
7849
		$expected = array(
7850
			'div' => array('class' => 'submit'),
7851
			'input' => array('type' => 'image', 'src' => 'img/cake.power.gif'),
7852
			'/div'
7853
		);
7854
		$this->assertTags($result, $expected);
7855
7856
		$result = $this->Form->submit('Not.an.image');
7857
		$expected = array(
7858
			'div' => array('class' => 'submit'),
7859
			'input' => array('type' => 'submit', 'value' => 'Not.an.image'),
7860
			'/div'
7861
		);
7862
		$this->assertTags($result, $expected);
7863
7864
		$after = '--after--';
7865
		$before = '--before--';
7866
		$result = $this->Form->submit('cake.power.gif', array('after' => $after));
7867
		$expected = array(
7868
			'div' => array('class' => 'submit'),
7869
			'input' => array('type' => 'image', 'src' => 'img/cake.power.gif'),
7870
			'--after--',
7871
			'/div'
7872
		);
7873
		$this->assertTags($result, $expected);
7874
7875
		$result = $this->Form->submit('cake.power.gif', array('before' => $before));
7876
		$expected = array(
7877
			'div' => array('class' => 'submit'),
7878
			'--before--',
7879
			'input' => array('type' => 'image', 'src' => 'img/cake.power.gif'),
7880
			'/div'
7881
		);
7882
		$this->assertTags($result, $expected);
7883
7884
		$result = $this->Form->submit('cake.power.gif', array('before' => $before, 'after' => $after));
7885
		$expected = array(
7886
			'div' => array('class' => 'submit'),
7887
			'--before--',
7888
			'input' => array('type' => 'image', 'src' => 'img/cake.power.gif'),
7889
			'--after--',
7890
			'/div'
7891
		);
7892
		$this->assertTags($result, $expected);
7893
7894
		$result = $this->Form->submit('Not.an.image', array('before' => $before, 'after' => $after));
7895
		$expected = array(
7896
			'div' => array('class' => 'submit'),
7897
			'--before--',
7898
			'input' => array('type' => 'submit', 'value' => 'Not.an.image'),
7899
			'--after--',
7900
			'/div'
7901
		);
7902
		$this->assertTags($result, $expected);
7903
	}
7904
7905
/**
7906
 * Submit buttons should be unlocked by default as there could be multiples, and only one will
7907
 * be submitted at a time.
7908
 *
7909
 * @return void
7910
 */
7911 View Code Duplication
	public function testSubmitUnlockedByDefault() {
7912
		$this->Form->request->params['_Token']['key'] = 'secured';
7913
		$this->Form->submit('Go go');
7914
		$this->Form->submit('Save', array('name' => 'save'));
7915
7916
		$result = $this->Form->unlockField();
7917
		$this->assertEquals(array('save'), $result, 'Only submits with name attributes should be unlocked.');
7918
	}
7919
7920
/**
7921
 * Test submit image with timestamps.
7922
 *
7923
 * @return void
7924
 */
7925
	public function testSubmitImageTimestamp() {
7926
		Configure::write('Asset.timestamp', 'force');
7927
7928
		$result = $this->Form->submit('cake.power.gif');
7929
		$expected = array(
7930
			'div' => array('class' => 'submit'),
7931
			'input' => array('type' => 'image', 'src' => 'preg:/img\/cake\.power\.gif\?\d*/'),
7932
			'/div'
7933
		);
7934
		$this->assertTags($result, $expected);
7935
	}
7936
7937
/**
7938
 * test the create() method
7939
 *
7940
 * @return void
7941
 */
7942
	public function testCreate() {
7943
		$result = $this->Form->create('Contact');
7944
		$encoding = strtolower(Configure::read('App.encoding'));
7945
		$expected = array(
7946
			'form' => array(
7947
				'id' => 'ContactAddForm', 'method' => 'post', 'action' => '/contacts/add',
7948
				'accept-charset' => $encoding
7949
			),
7950
			'div' => array('style' => 'preg:/display\s*\:\s*none;\s*/'),
7951
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
7952
			'/div'
7953
		);
7954
		$this->assertTags($result, $expected);
7955
7956
		$result = $this->Form->create('Contact', array('type' => 'GET'));
7957
		$expected = array('form' => array(
7958
			'id' => 'ContactAddForm', 'method' => 'get', 'action' => '/contacts/add',
7959
			'accept-charset' => $encoding
7960
		));
7961
		$this->assertTags($result, $expected);
7962
7963
		$result = $this->Form->create('Contact', array('type' => 'get'));
7964
		$expected = array('form' => array(
7965
			'id' => 'ContactAddForm', 'method' => 'get', 'action' => '/contacts/add',
7966
			'accept-charset' => $encoding
7967
		));
7968
		$this->assertTags($result, $expected);
7969
7970
		$result = $this->Form->create('Contact', array('type' => 'put'));
7971
		$expected = array(
7972
			'form' => array(
7973
				'id' => 'ContactAddForm', 'method' => 'post', 'action' => '/contacts/add',
7974
				'accept-charset' => $encoding
7975
			),
7976
			'div' => array('style' => 'display:none;'),
7977
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'PUT'),
7978
			'/div'
7979
		);
7980
		$this->assertTags($result, $expected);
7981
7982
		$result = $this->Form->create('Contact', array('type' => 'file'));
7983
		$expected = array(
7984
			'form' => array(
7985
				'id' => 'ContactAddForm', 'method' => 'post', 'action' => '/contacts/add',
7986
				'accept-charset' => $encoding, 'enctype' => 'multipart/form-data'
7987
			),
7988
			'div' => array('style' => 'display:none;'),
7989
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
7990
			'/div'
7991
		);
7992
		$this->assertTags($result, $expected);
7993
7994
		$this->Form->request->data['Contact']['id'] = 1;
7995
		$this->Form->request->here = '/contacts/edit/1';
7996
		$this->Form->request['action'] = 'edit';
7997
		$result = $this->Form->create('Contact');
7998
		$expected = array(
7999
			'form' => array(
8000
				'id' => 'ContactEditForm', 'method' => 'post', 'action' => '/contacts/edit/1',
8001
				'accept-charset' => $encoding
8002
			),
8003
			'div' => array('style' => 'display:none;'),
8004
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'PUT'),
8005
			'/div'
8006
		);
8007
		$this->assertTags($result, $expected);
8008
8009
		$this->Form->request->data['Contact']['id'] = 1;
8010
		$this->Form->request->here = '/contacts/edit/1';
8011
		$this->Form->request['action'] = 'edit';
8012
		$result = $this->Form->create('Contact', array('type' => 'file'));
8013
		$expected = array(
8014
			'form' => array(
8015
				'id' => 'ContactEditForm', 'method' => 'post', 'action' => '/contacts/edit/1',
8016
				'accept-charset' => $encoding, 'enctype' => 'multipart/form-data'
8017
			),
8018
			'div' => array('style' => 'display:none;'),
8019
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'PUT'),
8020
			'/div'
8021
		);
8022
		$this->assertTags($result, $expected);
8023
8024
		$this->Form->request->data['ContactNonStandardPk']['pk'] = 1;
8025
		$result = $this->Form->create('ContactNonStandardPk', array('url' => array('action' => 'edit')));
8026
		$expected = array(
8027
			'form' => array(
8028
				'id' => 'ContactNonStandardPkEditForm', 'method' => 'post',
8029
				'action' => '/contact_non_standard_pks/edit/1', 'accept-charset' => $encoding
8030
			),
8031
			'div' => array('style' => 'display:none;'),
8032
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'PUT'),
8033
			'/div'
8034
		);
8035
		$this->assertTags($result, $expected);
8036
8037
		$result = $this->Form->create('Contact', array('id' => 'TestId'));
8038
		$expected = array(
8039
			'form' => array(
8040
				'id' => 'TestId', 'method' => 'post', 'action' => '/contacts/edit/1',
8041
				'accept-charset' => $encoding
8042
			),
8043
			'div' => array('style' => 'display:none;'),
8044
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'PUT'),
8045
			'/div'
8046
		);
8047
		$this->assertTags($result, $expected);
8048
8049
		$this->Form->request['action'] = 'add';
8050
		$result = $this->Form->create('User', array('url' => array('action' => 'login')));
8051
		$expected = array(
8052
			'form' => array(
8053
				'id' => 'UserAddForm', 'method' => 'post', 'action' => '/users/login',
8054
				'accept-charset' => $encoding
8055
			),
8056
			'div' => array('style' => 'display:none;'),
8057
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
8058
			'/div'
8059
		);
8060
		$this->assertTags($result, $expected);
8061
8062
		$result = $this->Form->create('User', array('action' => 'login'));
8063
		$expected = array(
8064
			'form' => array(
8065
				'id' => 'UserLoginForm', 'method' => 'post', 'action' => '/users/login',
8066
				'accept-charset' => $encoding
8067
			),
8068
			'div' => array('style' => 'display:none;'),
8069
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
8070
			'/div'
8071
		);
8072
		$this->assertTags($result, $expected);
8073
8074
		$result = $this->Form->create('User', array('url' => '/users/login'));
8075
		$expected = array(
8076
			'form' => array('method' => 'post', 'action' => '/users/login', 'accept-charset' => $encoding, 'id' => 'UserAddForm'),
8077
			'div' => array('style' => 'display:none;'),
8078
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
8079
			'/div'
8080
		);
8081
		$this->assertTags($result, $expected);
8082
8083
		$this->Form->request['controller'] = 'pages';
8084
		$result = $this->Form->create('User', array('action' => 'signup'));
8085
		$expected = array(
8086
			'form' => array(
8087
				'id' => 'UserSignupForm', 'method' => 'post', 'action' => '/users/signup',
8088
				'accept-charset' => $encoding
8089
			),
8090
			'div' => array('style' => 'display:none;'),
8091
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
8092
			'/div'
8093
		);
8094
		$this->assertTags($result, $expected);
8095
8096
		$this->Form->request->data = array();
8097
		$this->Form->request['controller'] = 'contacts';
8098
		$this->Form->request['models'] = array('Contact' => array('plugin' => null, 'className' => 'Contact'));
8099
		$result = $this->Form->create(array('url' => array('action' => 'index', 'param')));
8100
		$expected = array(
8101
			'form' => array(
8102
				'id' => 'ContactAddForm', 'method' => 'post', 'action' => '/contacts/index/param',
8103
				'accept-charset' => 'utf-8'
8104
			),
8105
			'div' => array('style' => 'display:none;'),
8106
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
8107
			'/div'
8108
		);
8109
		$this->assertTags($result, $expected);
8110
	}
8111
8112
/**
8113
 * Test the onsubmit option for create()
8114
 *
8115
 * @return void
8116
 */
8117
	public function testCreateOnSubmit() {
8118
		$this->Form->request->data = array();
8119
		$this->Form->request['controller'] = 'contacts';
8120
		$this->Form->request['models'] = array('Contact' => array('plugin' => null, 'className' => 'Contact'));
8121
		$result = $this->Form->create(array('url' => array('action' => 'index', 'param'), 'default' => false));
8122
		$expected = array(
8123
			'form' => array(
8124
				'id' => 'ContactAddForm', 'method' => 'post', 'onsubmit' => 'event.returnValue = false; return false;', 'action' => '/contacts/index/param',
8125
				'accept-charset' => 'utf-8'
8126
			),
8127
			'div' => array('style' => 'display:none;'),
8128
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
8129
			'/div'
8130
		);
8131
		$this->assertTags($result, $expected);
8132
8133
		$this->Form->request->data = array();
8134
		$this->Form->request['controller'] = 'contacts';
8135
		$this->Form->request['models'] = array('Contact' => array('plugin' => null, 'className' => 'Contact'));
8136
		$result = $this->Form->create(array(
8137
			'url' => array('action' => 'index', 'param'),
8138
			'default' => false,
8139
			'onsubmit' => 'someFunction();'
8140
		));
8141
8142
		$expected = array(
8143
			'form' => array(
8144
				'id' => 'ContactAddForm', 'method' => 'post',
8145
				'onsubmit' => 'someFunction();event.returnValue = false; return false;',
8146
				'action' => '/contacts/index/param',
8147
				'accept-charset' => 'utf-8'
8148
			),
8149
			'div' => array('style' => 'display:none;'),
8150
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
8151
			'/div'
8152
		);
8153
		$this->assertTags($result, $expected);
8154
	}
8155
8156
/**
8157
 * test create() with automatic url generation
8158
 *
8159
 * @return void
8160
 */
8161
	public function testCreateAutoUrl() {
8162
		Router::setRequestInfo(array(array(), array('base' => '/base_url')));
8163
		$this->Form->request->here = '/base_url/contacts/add/Contact:1';
8164
		$this->Form->request->base = '/base_url';
8165
		$result = $this->Form->create('Contact');
8166
		$expected = array(
8167
			'form' => array(
8168
				'id' => 'ContactAddForm', 'method' => 'post', 'action' => '/base_url/contacts/add/Contact:1',
8169
				'accept-charset' => 'utf-8'
8170
			),
8171
			'div' => array('style' => 'display:none;'),
8172
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
8173
			'/div'
8174
		);
8175
		$this->assertTags($result, $expected);
8176
8177
		$this->Form->request['action'] = 'delete';
8178
		$this->Form->request->here = '/base_url/contacts/delete/10/User:42';
8179
		$this->Form->request->base = '/base_url';
8180
		$result = $this->Form->create('Contact');
8181
		$expected = array(
8182
			'form' => array(
8183
				'id' => 'ContactDeleteForm', 'method' => 'post', 'action' => '/base_url/contacts/delete/10/User:42',
8184
				'accept-charset' => 'utf-8'
8185
			),
8186
			'div' => array('style' => 'display:none;'),
8187
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
8188
			'/div'
8189
		);
8190
		$this->assertTags($result, $expected);
8191
	}
8192
8193
/**
8194
 * test create() with a custom route
8195
 *
8196
 * @return void
8197
 */
8198
	public function testCreateCustomRoute() {
8199
		Router::connect('/login', array('controller' => 'users', 'action' => 'login'));
8200
		$encoding = strtolower(Configure::read('App.encoding'));
8201
8202
		$result = $this->Form->create('User', array('action' => 'login'));
8203
		$expected = array(
8204
			'form' => array(
8205
				'id' => 'UserLoginForm', 'method' => 'post', 'action' => '/login',
8206
				'accept-charset' => $encoding
8207
			),
8208
			'div' => array('style' => 'display:none;'),
8209
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
8210
			'/div'
8211
		);
8212
		$this->assertTags($result, $expected);
8213
	}
8214
8215
/**
8216
 * test that inputDefaults are stored and used.
8217
 *
8218
 * @return void
8219
 */
8220
	public function testCreateWithInputDefaults() {
8221
		$this->Form->create('User', array(
8222
			'inputDefaults' => array(
8223
				'div' => false,
8224
				'label' => false,
8225
				'error' => array('attributes' => array('wrap' => 'small', 'class' => 'error')),
8226
				'format' => array('before', 'label', 'between', 'input', 'after', 'error')
8227
			)
8228
		));
8229
		$result = $this->Form->input('username');
8230
		$expected = array(
8231
			'input' => array('type' => 'text', 'name' => 'data[User][username]', 'id' => 'UserUsername')
8232
		);
8233
		$this->assertTags($result, $expected);
8234
8235
		$result = $this->Form->input('username', array('div' => true, 'label' => 'username'));
8236
		$expected = array(
8237
			'div' => array('class' => 'input text'),
8238
			'label' => array('for' => 'UserUsername'), 'username', '/label',
8239
			'input' => array('type' => 'text', 'name' => 'data[User][username]', 'id' => 'UserUsername'),
8240
			'/div'
8241
		);
8242
		$this->assertTags($result, $expected);
8243
8244
		$result = $this->Form->input('username', array('label' => 'Username', 'format' => array('input', 'label')));
8245
		$expected = array(
8246
			'input' => array('type' => 'text', 'name' => 'data[User][username]', 'id' => 'UserUsername'),
8247
			'label' => array('for' => 'UserUsername'), 'Username', '/label',
8248
		);
8249
		$this->assertTags($result, $expected);
8250
8251
		$this->Form->create('User', array(
8252
			'inputDefaults' => array(
8253
				'div' => false,
8254
				'label' => array('class' => 'nice', 'for' => 'changed'),
8255
			)
8256
		));
8257
		$result = $this->Form->input('username', array('div' => true));
8258
		$expected = array(
8259
			'div' => array('class' => 'input text'),
8260
			'label' => array('for' => 'changed', 'class' => 'nice'), 'Username', '/label',
8261
			'input' => array('type' => 'text', 'name' => 'data[User][username]', 'id' => 'UserUsername'),
8262
			'/div'
8263
		);
8264
		$this->assertTags($result, $expected);
8265
	}
8266
8267
/**
8268
 * test automatic accept-charset overriding
8269
 *
8270
 * @return void
8271
 */
8272
	public function testCreateWithAcceptCharset() {
8273
		$result = $this->Form->create('UserForm', array(
8274
				'type' => 'post', 'action' => 'login', 'encoding' => 'iso-8859-1'
8275
			)
8276
		);
8277
		$expected = array(
8278
			'form' => array(
8279
				'method' => 'post', 'action' => '/user_forms/login', 'id' => 'UserFormLoginForm',
8280
				'accept-charset' => 'iso-8859-1'
8281
			),
8282
			'div' => array('style' => 'display:none;'),
8283
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
8284
			'/div'
8285
		);
8286
		$this->assertTags($result, $expected);
8287
	}
8288
8289
/**
8290
 * Test base form URL when url param is passed with multiple parameters (&)
8291
 *
8292
 * @return void
8293
 */
8294
	public function testCreateQuerystringrequest() {
8295
		$encoding = strtolower(Configure::read('App.encoding'));
8296
		$result = $this->Form->create('Contact', array(
8297
			'type' => 'post',
8298
			'escape' => false,
8299
			'url' => array(
8300
				'controller' => 'controller',
8301
				'action' => 'action',
8302
				'?' => array('param1' => 'value1', 'param2' => 'value2')
8303
			)
8304
		));
8305
		$expected = array(
8306
			'form' => array(
8307
				'id' => 'ContactAddForm',
8308
				'method' => 'post',
8309
				'action' => '/controller/action?param1=value1&amp;param2=value2',
8310
				'accept-charset' => $encoding
8311
			),
8312
			'div' => array('style' => 'display:none;'),
8313
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
8314
			'/div'
8315
		);
8316
		$this->assertTags($result, $expected);
8317
8318
		$result = $this->Form->create('Contact', array(
8319
			'type' => 'post',
8320
			'url' => array(
8321
				'controller' => 'controller',
8322
				'action' => 'action',
8323
				'?' => array('param1' => 'value1', 'param2' => 'value2')
8324
			)
8325
		));
8326
		$expected = array(
8327
			'form' => array(
8328
				'id' => 'ContactAddForm',
8329
				'method' => 'post',
8330
				'action' => '/controller/action?param1=value1&amp;param2=value2',
8331
				'accept-charset' => $encoding
8332
			),
8333
			'div' => array('style' => 'display:none;'),
8334
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
8335
			'/div'
8336
		);
8337
		$this->assertTags($result, $expected);
8338
	}
8339
8340
/**
8341
 * test that create() doesn't cause errors by multiple id's being in the primary key
8342
 * as could happen with multiple select or checkboxes.
8343
 *
8344
 * @return void
8345
 */
8346
	public function testCreateWithMultipleIdInData() {
8347
		$encoding = strtolower(Configure::read('App.encoding'));
8348
8349
		$this->Form->request->data['Contact']['id'] = array(1, 2);
8350
		$result = $this->Form->create('Contact');
8351
		$expected = array(
8352
			'form' => array(
8353
				'id' => 'ContactAddForm',
8354
				'method' => 'post',
8355
				'action' => '/contacts/add',
8356
				'accept-charset' => $encoding
8357
			),
8358
			'div' => array('style' => 'display:none;'),
8359
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
8360
			'/div'
8361
		);
8362
		$this->assertTags($result, $expected);
8363
	}
8364
8365
/**
8366
 * test that create() doesn't add in extra passed params.
8367
 *
8368
 * @return void
8369
 */
8370
	public function testCreatePassedArgs() {
8371
		$encoding = strtolower(Configure::read('App.encoding'));
8372
		$this->Form->request->data['Contact']['id'] = 1;
8373
		$result = $this->Form->create('Contact', array(
8374
			'type' => 'post',
8375
			'escape' => false,
8376
			'url' => array(
8377
				'action' => 'edit',
8378
				'myparam'
8379
			)
8380
		));
8381
		$expected = array(
8382
			'form' => array(
8383
				'id' => 'ContactAddForm',
8384
				'method' => 'post',
8385
				'action' => '/contacts/edit/myparam',
8386
				'accept-charset' => $encoding
8387
			),
8388
			'div' => array('style' => 'display:none;'),
8389
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
8390
			'/div'
8391
		);
8392
		$this->assertTags($result, $expected);
8393
	}
8394
8395
/**
8396
 * test that create() works without raising errors with a Mock Model
8397
 *
8398
 * @return void
8399
 */
8400
	public function testCreateNoErrorsWithMockModel() {
8401
		$encoding = strtolower(Configure::read('App.encoding'));
8402
		$ContactMock = $this->getMockBuilder('Contact')
8403
				->disableOriginalConstructor()
8404
				->getMock();
8405
		ClassRegistry::removeObject('Contact');
8406
		ClassRegistry::addObject('Contact', $ContactMock);
8407
		$result = $this->Form->create('Contact', array('type' => 'GET'));
8408
		$expected = array('form' => array(
8409
			'id' => 'ContactAddForm', 'method' => 'get', 'action' => '/contacts/add',
8410
			'accept-charset' => $encoding
8411
		));
8412
		$this->assertTags($result, $expected);
8413
	}
8414
8415
/**
8416
 * test creating a get form, and get form inputs.
8417
 *
8418
 * @return void
8419
 */
8420
	public function testGetFormCreate() {
8421
		$encoding = strtolower(Configure::read('App.encoding'));
8422
		$result = $this->Form->create('Contact', array('type' => 'get'));
8423
		$this->assertTags($result, array('form' => array(
8424
			'id' => 'ContactAddForm', 'method' => 'get', 'action' => '/contacts/add',
8425
			'accept-charset' => $encoding
8426
		)));
8427
8428
		$result = $this->Form->text('Contact.name');
0 ignored issues
show
Documentation Bug introduced by
The method text does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
8429
		$this->assertTags($result, array('input' => array(
8430
			'name' => 'name', 'type' => 'text', 'id' => 'ContactName',
8431
		)));
8432
8433
		$result = $this->Form->password('password');
0 ignored issues
show
Documentation Bug introduced by
The method password does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
8434
		$this->assertTags($result, array('input' => array(
8435
			'name' => 'password', 'type' => 'password', 'id' => 'ContactPassword'
8436
		)));
8437
		$this->assertNotRegExp('/<input[^<>]+[^id|name|type|value]=[^<>]*>$/', $result);
8438
8439
		$result = $this->Form->text('user_form');
0 ignored issues
show
Documentation Bug introduced by
The method text does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
8440
		$this->assertTags($result, array('input' => array(
8441
			'name' => 'user_form', 'type' => 'text', 'id' => 'ContactUserForm'
8442
		)));
8443
	}
8444
8445
/**
8446
 * test get form, and inputs when the model param is false
8447
 *
8448
 * @return void
8449
 */
8450
	public function testGetFormWithFalseModel() {
8451
		$encoding = strtolower(Configure::read('App.encoding'));
8452
		$this->Form->request['controller'] = 'contact_test';
8453
		$result = $this->Form->create(false, array('type' => 'get', 'url' => array('controller' => 'contact_test')));
8454
8455
		$expected = array('form' => array(
8456
			'id' => 'addForm', 'method' => 'get', 'action' => '/contact_test/add',
8457
			'accept-charset' => $encoding
8458
		));
8459
		$this->assertTags($result, $expected);
8460
8461
		$result = $this->Form->text('reason');
0 ignored issues
show
Documentation Bug introduced by
The method text does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
8462
		$expected = array(
8463
			'input' => array('type' => 'text', 'name' => 'reason', 'id' => 'reason')
8464
		);
8465
		$this->assertTags($result, $expected);
8466
	}
8467
8468
/**
8469
 * test that datetime() works with GET style forms.
8470
 *
8471
 * @return void
8472
 */
8473
	public function testDateTimeWithGetForms() {
8474
		extract($this->dateRegex);
8475
		$this->Form->create('Contact', array('type' => 'get'));
8476
		$result = $this->Form->datetime('created');
8477
8478
		$this->assertRegExp('/name="created\[year\]"/', $result, 'year name attribute is wrong.');
8479
		$this->assertRegExp('/name="created\[month\]"/', $result, 'month name attribute is wrong.');
8480
		$this->assertRegExp('/name="created\[day\]"/', $result, 'day name attribute is wrong.');
8481
		$this->assertRegExp('/name="created\[hour\]"/', $result, 'hour name attribute is wrong.');
8482
		$this->assertRegExp('/name="created\[min\]"/', $result, 'min name attribute is wrong.');
8483
		$this->assertRegExp('/name="created\[meridian\]"/', $result, 'meridian name attribute is wrong.');
8484
	}
8485
8486
/**
8487
 * testEditFormWithData method
8488
 *
8489
 * test auto populating form elements from submitted data.
8490
 *
8491
 * @return void
8492
 */
8493
	public function testEditFormWithData() {
8494
		$this->Form->request->data = array('Person' => array(
8495
			'id' => 1,
8496
			'first_name' => 'Nate',
8497
			'last_name' => 'Abele',
8498
			'email' => '[email protected]'
8499
		));
8500
		$this->Form->request->addParams(array(
8501
			'models' => array('Person'),
8502
			'controller' => 'people',
8503
			'action' => 'add'
8504
		));
8505
		$options = array(1 => 'Nate', 2 => 'Garrett', 3 => 'Larry');
8506
8507
		$this->Form->create();
8508
		$result = $this->Form->select('People.People', $options, array('multiple' => true));
8509
		$expected = array(
8510
			'input' => array('type' => 'hidden', 'name' => 'data[People][People]', 'value' => '', 'id' => 'PeoplePeople_'),
8511
			'select' => array(
8512
				'name' => 'data[People][People][]', 'multiple' => 'multiple', 'id' => 'PeoplePeople'
8513
			),
8514
			array('option' => array('value' => 1)), 'Nate', '/option',
8515
			array('option' => array('value' => 2)), 'Garrett', '/option',
8516
			array('option' => array('value' => 3)), 'Larry', '/option',
8517
			'/select'
8518
		);
8519
		$this->assertTags($result, $expected);
8520
	}
8521
8522
/**
8523
 * Test that required fields are created for various types of validation.
8524
 *
8525
 * @return void
8526
 */
8527
	public function testFormInputRequiredDetection() {
8528
		$this->Form->create('Contact');
8529
8530
		$result = $this->Form->input('Contact.non_existing');
8531
		$expected = array(
8532
			'div' => array('class' => 'input text'),
8533
			'label' => array('for' => 'ContactNonExisting'),
8534
			'Non Existing',
8535
			'/label',
8536
			'input' => array(
8537
				'type' => 'text', 'name' => 'data[Contact][non_existing]',
8538
				'id' => 'ContactNonExisting'
8539
			),
8540
			'/div'
8541
		);
8542
		$this->assertTags($result, $expected);
8543
8544
		$result = $this->Form->input('Contact.imrequired');
8545
		$expected = array(
8546
			'div' => array('class' => 'input text required'),
8547
			'label' => array('for' => 'ContactImrequired'),
8548
			'Imrequired',
8549
			'/label',
8550
			'input' => array(
8551
				'type' => 'text', 'name' => 'data[Contact][imrequired]',
8552
				'id' => 'ContactImrequired',
8553
				'required' => 'required'
8554
			),
8555
			'/div'
8556
		);
8557
		$this->assertTags($result, $expected);
8558
8559
		$result = $this->Form->input('Contact.imalsorequired');
8560
		$expected = array(
8561
			'div' => array('class' => 'input text required'),
8562
			'label' => array('for' => 'ContactImalsorequired'),
8563
			'Imalsorequired',
8564
			'/label',
8565
			'input' => array(
8566
				'type' => 'text', 'name' => 'data[Contact][imalsorequired]',
8567
				'id' => 'ContactImalsorequired',
8568
				'required' => 'required'
8569
			),
8570
			'/div'
8571
		);
8572
		$this->assertTags($result, $expected);
8573
8574
		$result = $this->Form->input('Contact.imrequiredtoo');
8575
		$expected = array(
8576
			'div' => array('class' => 'input text required'),
8577
			'label' => array('for' => 'ContactImrequiredtoo'),
8578
			'Imrequiredtoo',
8579
			'/label',
8580
			'input' => array(
8581
				'type' => 'text', 'name' => 'data[Contact][imrequiredtoo]',
8582
				'id' => 'ContactImrequiredtoo',
8583
				'required' => 'required'
8584
			),
8585
			'/div'
8586
		);
8587
		$this->assertTags($result, $expected);
8588
8589
		$result = $this->Form->input('Contact.required_one');
8590
		$expected = array(
8591
			'div' => array('class' => 'input text required'),
8592
			'label' => array('for' => 'ContactRequiredOne'),
8593
			'Required One',
8594
			'/label',
8595
			'input' => array(
8596
				'type' => 'text', 'name' => 'data[Contact][required_one]',
8597
				'id' => 'ContactRequiredOne',
8598
				'required' => 'required'
8599
			),
8600
			'/div'
8601
		);
8602
		$this->assertTags($result, $expected);
8603
8604
		$result = $this->Form->input('Contact.string_required');
8605
		$expected = array(
8606
			'div' => array('class' => 'input text required'),
8607
			'label' => array('for' => 'ContactStringRequired'),
8608
			'String Required',
8609
			'/label',
8610
			'input' => array(
8611
				'type' => 'text', 'name' => 'data[Contact][string_required]',
8612
				'id' => 'ContactStringRequired',
8613
				'required' => 'required'
8614
			),
8615
			'/div'
8616
		);
8617
		$this->assertTags($result, $expected);
8618
8619
		$result = $this->Form->input('Contact.imnotrequired');
8620
		$expected = array(
8621
			'div' => array('class' => 'input text'),
8622
			'label' => array('for' => 'ContactImnotrequired'),
8623
			'Imnotrequired',
8624
			'/label',
8625
			'input' => array(
8626
				'type' => 'text', 'name' => 'data[Contact][imnotrequired]',
8627
				'id' => 'ContactImnotrequired'
8628
			),
8629
			'/div'
8630
		);
8631
		$this->assertTags($result, $expected);
8632
8633
		$result = $this->Form->input('Contact.imalsonotrequired');
8634
		$expected = array(
8635
			'div' => array('class' => 'input text'),
8636
			'label' => array('for' => 'ContactImalsonotrequired'),
8637
			'Imalsonotrequired',
8638
			'/label',
8639
			'input' => array(
8640
				'type' => 'text', 'name' => 'data[Contact][imalsonotrequired]',
8641
				'id' => 'ContactImalsonotrequired'
8642
			),
8643
			'/div'
8644
		);
8645
		$this->assertTags($result, $expected);
8646
8647
		$result = $this->Form->input('Contact.imalsonotrequired2');
8648
		$expected = array(
8649
			'div' => array('class' => 'input text'),
8650
			'label' => array('for' => 'ContactImalsonotrequired2'),
8651
			'Imalsonotrequired2',
8652
			'/label',
8653
			'input' => array(
8654
				'type' => 'text', 'name' => 'data[Contact][imalsonotrequired2]',
8655
				'id' => 'ContactImalsonotrequired2'
8656
			),
8657
			'/div'
8658
		);
8659
		$this->assertTags($result, $expected);
8660
8661
		$result = $this->Form->input('Contact.imnotrequiredeither');
8662
		$expected = array(
8663
			'div' => array('class' => 'input text'),
8664
			'label' => array('for' => 'ContactImnotrequiredeither'),
8665
			'Imnotrequiredeither',
8666
			'/label',
8667
			'input' => array(
8668
				'type' => 'text', 'name' => 'data[Contact][imnotrequiredeither]',
8669
				'id' => 'ContactImnotrequiredeither'
8670
			),
8671
			'/div'
8672
		);
8673
		$this->assertTags($result, $expected);
8674
8675
		$result = $this->Form->input('Contact.iamrequiredalways');
8676
		$expected = array(
8677
			'div' => array('class' => 'input text required'),
8678
			'label' => array('for' => 'ContactIamrequiredalways'),
8679
			'Iamrequiredalways',
8680
			'/label',
8681
			'input' => array(
8682
				'type' => 'text', 'name' => 'data[Contact][iamrequiredalways]',
8683
				'id' => 'ContactIamrequiredalways',
8684
				'required' => 'required'
8685
			),
8686
			'/div'
8687
		);
8688
		$this->assertTags($result, $expected);
8689
8690
		$result = $this->Form->input('Contact.boolean_field', array('type' => 'checkbox'));
8691
		$expected = array(
8692
			'div' => array('class' => 'input checkbox required'),
8693
			array('input' => array(
8694
				'type' => 'hidden',
8695
				'name' => 'data[Contact][boolean_field]',
8696
				'id' => 'ContactBooleanField_',
8697
				'value' => '0'
8698
			)),
8699
			array('input' => array(
8700
				'type' => 'checkbox',
8701
				'name' => 'data[Contact][boolean_field]',
8702
				'value' => '1',
8703
				'id' => 'ContactBooleanField'
8704
			)),
8705
			'label' => array('for' => 'ContactBooleanField'),
8706
			'Boolean Field',
8707
			'/label',
8708
			'/div'
8709
		);
8710
		$this->assertTags($result, $expected);
8711
8712
		$result = $this->Form->input('Contact.boolean_field', array('type' => 'checkbox', 'required' => true));
8713
		$expected = array(
8714
			'div' => array('class' => 'input checkbox required'),
8715
			array('input' => array(
8716
				'type' => 'hidden',
8717
				'name' => 'data[Contact][boolean_field]',
8718
				'id' => 'ContactBooleanField_',
8719
				'value' => '0'
8720
			)),
8721
			array('input' => array(
8722
				'type' => 'checkbox',
8723
				'name' => 'data[Contact][boolean_field]',
8724
				'value' => '1',
8725
				'id' => 'ContactBooleanField',
8726
				'required' => 'required'
8727
			)),
8728
			'label' => array('for' => 'ContactBooleanField'),
8729
			'Boolean Field',
8730
			'/label',
8731
			'/div'
8732
		);
8733
		$this->assertTags($result, $expected);
8734
8735
		$result = $this->Form->input('Contact.iamrequiredalways', array('type' => 'file'));
8736
		$expected = array(
8737
			'div' => array('class' => 'input file required'),
8738
			'label' => array('for' => 'ContactIamrequiredalways'),
8739
			'Iamrequiredalways',
8740
			'/label',
8741
			'input' => array(
8742
				'type' => 'file',
8743
				'name' => 'data[Contact][iamrequiredalways]',
8744
				'id' => 'ContactIamrequiredalways',
8745
				'required' => 'required'
8746
			),
8747
			'/div'
8748
		);
8749
		$this->assertTags($result, $expected);
8750
	}
8751
8752
/**
8753
 * Test that required fields are created when only using ModelValidator::add().
8754
 *
8755
 * @return void
8756
 */
8757
	public function testFormInputRequiredDetectionModelValidator() {
8758
		ClassRegistry::getObject('ContactTag')->validator()->add('iwillberequired', 'required', array('rule' => 'notEmpty'));
8759
8760
		$this->Form->create('ContactTag');
8761
		$result = $this->Form->input('ContactTag.iwillberequired');
8762
		$expected = array(
8763
			'div' => array('class' => 'input text required'),
8764
			'label' => array('for' => 'ContactTagIwillberequired'),
8765
			'Iwillberequired',
8766
			'/label',
8767
			'input' => array(
8768
				'name' => 'data[ContactTag][iwillberequired]',
8769
				'type' => 'text',
8770
				'id' => 'ContactTagIwillberequired',
8771
				'required' => 'required'
8772
			),
8773
			'/div'
8774
		);
8775
		$this->assertTags($result, $expected);
8776
	}
8777
8778
/**
8779
 * testFormMagicInput method
8780
 *
8781
 * @return void
8782
 */
8783
	public function testFormMagicInput() {
8784
		$encoding = strtolower(Configure::read('App.encoding'));
8785
		$result = $this->Form->create('Contact');
8786
		$expected = array(
8787
			'form' => array(
8788
				'id' => 'ContactAddForm', 'method' => 'post', 'action' => '/contacts/add',
8789
				'accept-charset' => $encoding
8790
			),
8791
			'div' => array('style' => 'display:none;'),
8792
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
8793
			'/div'
8794
		);
8795
		$this->assertTags($result, $expected);
8796
8797
		$result = $this->Form->input('name');
8798
		$expected = array(
8799
			'div' => array('class' => 'input text'),
8800
			'label' => array('for' => 'ContactName'),
8801
			'Name',
8802
			'/label',
8803
			'input' => array(
8804
				'type' => 'text', 'name' => 'data[Contact][name]',
8805
				'id' => 'ContactName', 'maxlength' => '255'
8806
			),
8807
			'/div'
8808
		);
8809
		$this->assertTags($result, $expected);
8810
8811
		$result = $this->Form->input('non_existing_field_in_contact_model');
8812
		$expected = array(
8813
			'div' => array('class' => 'input text'),
8814
			'label' => array('for' => 'ContactNonExistingFieldInContactModel'),
8815
			'Non Existing Field In Contact Model',
8816
			'/label',
8817
			'input' => array(
8818
				'type' => 'text', 'name' => 'data[Contact][non_existing_field_in_contact_model]',
8819
				'id' => 'ContactNonExistingFieldInContactModel'
8820
			),
8821
			'/div'
8822
		);
8823
		$this->assertTags($result, $expected);
8824
8825
		$result = $this->Form->input('Address.street');
8826
		$expected = array(
8827
			'div' => array('class' => 'input text'),
8828
			'label' => array('for' => 'AddressStreet'),
8829
			'Street',
8830
			'/label',
8831
			'input' => array(
8832
				'type' => 'text', 'name' => 'data[Address][street]',
8833
				'id' => 'AddressStreet'
8834
			),
8835
			'/div'
8836
		);
8837
		$this->assertTags($result, $expected);
8838
8839
		$result = $this->Form->input('Address.non_existing_field_in_model');
8840
		$expected = array(
8841
			'div' => array('class' => 'input text'),
8842
			'label' => array('for' => 'AddressNonExistingFieldInModel'),
8843
			'Non Existing Field In Model',
8844
			'/label',
8845
			'input' => array(
8846
				'type' => 'text', 'name' => 'data[Address][non_existing_field_in_model]',
8847
				'id' => 'AddressNonExistingFieldInModel'
8848
			),
8849
			'/div'
8850
		);
8851
		$this->assertTags($result, $expected);
8852
8853
		$result = $this->Form->input('name', array('div' => false));
8854
		$expected = array(
8855
			'label' => array('for' => 'ContactName'),
8856
			'Name',
8857
			'/label',
8858
			'input' => array(
8859
				'type' => 'text', 'name' => 'data[Contact][name]',
8860
				'id' => 'ContactName', 'maxlength' => '255'
8861
			)
8862
		);
8863
		$this->assertTags($result, $expected);
8864
8865
		extract($this->dateRegex);
8866
		$now = strtotime('now');
8867
8868
		$result = $this->Form->input('Contact.published', array('div' => false));
8869
		$expected = array(
8870
			'label' => array('for' => 'ContactPublishedMonth'),
8871
			'Published',
8872
			'/label',
8873
			array('select' => array(
8874
				'name' => 'data[Contact][published][month]', 'id' => 'ContactPublishedMonth'
8875
			)),
8876
			$monthsRegex,
8877
			array('option' => array('value' => date('m', $now), 'selected' => 'selected')),
8878
			date('F', $now),
8879
			'/option',
8880
			'*/select',
8881
			'-',
8882
			array('select' => array(
8883
				'name' => 'data[Contact][published][day]', 'id' => 'ContactPublishedDay'
8884
			)),
8885
			$daysRegex,
8886
			array('option' => array('value' => date('d', $now), 'selected' => 'selected')),
8887
			date('j', $now),
8888
			'/option',
8889
			'*/select',
8890
			'-',
8891
			array('select' => array(
8892
				'name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear'
8893
			)),
8894
			$yearsRegex,
8895
			array('option' => array('value' => date('Y', $now), 'selected' => 'selected')),
8896
			date('Y', $now),
8897
			'*/select'
8898
		);
8899
		$this->assertTags($result, $expected);
8900
8901
		$result = $this->Form->input('Contact.updated', array('div' => false));
8902
		$expected = array(
8903
			'label' => array('for' => 'ContactUpdatedMonth'),
8904
			'Updated',
8905
			'/label',
8906
			array('select' => array(
8907
				'name' => 'data[Contact][updated][month]', 'id' => 'ContactUpdatedMonth'
8908
			)),
8909
			$monthsRegex,
8910
			array('option' => array('value' => date('m', $now), 'selected' => 'selected')),
8911
			date('F', $now),
8912
			'/option',
8913
			'*/select',
8914
			'-',
8915
			array('select' => array(
8916
				'name' => 'data[Contact][updated][day]', 'id' => 'ContactUpdatedDay'
8917
			)),
8918
			$daysRegex,
8919
			array('option' => array('value' => date('d', $now), 'selected' => 'selected')),
8920
			date('j', $now),
8921
			'/option',
8922
			'*/select',
8923
			'-',
8924
			array('select' => array(
8925
				'name' => 'data[Contact][updated][year]', 'id' => 'ContactUpdatedYear'
8926
			)),
8927
			$yearsRegex,
8928
			array('option' => array('value' => date('Y', $now), 'selected' => 'selected')),
8929
			date('Y', $now),
8930
			'*/select'
8931
		);
8932
		$this->assertTags($result, $expected);
8933
8934
		$result = $this->Form->input('UserForm.stuff');
8935
		$expected = array(
8936
			'div' => array('class' => 'input text'),
8937
			'label' => array('for' => 'UserFormStuff'),
8938
			'Stuff',
8939
			'/label',
8940
			'input' => array(
8941
				'type' => 'text', 'name' => 'data[UserForm][stuff]',
8942
				'id' => 'UserFormStuff', 'maxlength' => 10
8943
			),
8944
			'/div'
8945
		);
8946
		$this->assertTags($result, $expected);
8947
	}
8948
8949
/**
8950
 * testForMagicInputNonExistingNorValidated method
8951
 *
8952
 * @return void
8953
 */
8954
	public function testForMagicInputNonExistingNorValidated() {
8955
		$encoding = strtolower(Configure::read('App.encoding'));
8956
		$result = $this->Form->create('Contact');
8957
		$expected = array(
8958
			'form' => array(
8959
				'id' => 'ContactAddForm', 'method' => 'post', 'action' => '/contacts/add',
8960
				'accept-charset' => $encoding
8961
			),
8962
			'div' => array('style' => 'display:none;'),
8963
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
8964
			'/div'
8965
		);
8966
		$this->assertTags($result, $expected);
8967
8968
		$result = $this->Form->input('Contact.non_existing_nor_validated', array('div' => false));
8969
		$expected = array(
8970
			'label' => array('for' => 'ContactNonExistingNorValidated'),
8971
			'Non Existing Nor Validated',
8972
			'/label',
8973
			'input' => array(
8974
				'type' => 'text', 'name' => 'data[Contact][non_existing_nor_validated]',
8975
				'id' => 'ContactNonExistingNorValidated'
8976
			)
8977
		);
8978
		$this->assertTags($result, $expected);
8979
8980
		$result = $this->Form->input('Contact.non_existing_nor_validated', array(
8981
			'div' => false, 'value' => 'my value'
8982
		));
8983
		$expected = array(
8984
			'label' => array('for' => 'ContactNonExistingNorValidated'),
8985
			'Non Existing Nor Validated',
8986
			'/label',
8987
			'input' => array(
8988
				'type' => 'text', 'name' => 'data[Contact][non_existing_nor_validated]',
8989
				'value' => 'my value', 'id' => 'ContactNonExistingNorValidated'
8990
			)
8991
		);
8992
		$this->assertTags($result, $expected);
8993
8994
		$this->Form->request->data = array(
8995
			'Contact' => array('non_existing_nor_validated' => 'CakePHP magic'
8996
		));
8997
		$result = $this->Form->input('Contact.non_existing_nor_validated', array('div' => false));
8998
		$expected = array(
8999
			'label' => array('for' => 'ContactNonExistingNorValidated'),
9000
			'Non Existing Nor Validated',
9001
			'/label',
9002
			'input' => array(
9003
				'type' => 'text', 'name' => 'data[Contact][non_existing_nor_validated]',
9004
				'value' => 'CakePHP magic', 'id' => 'ContactNonExistingNorValidated'
9005
			)
9006
		);
9007
		$this->assertTags($result, $expected);
9008
	}
9009
9010
/**
9011
 * testFormMagicInputLabel method
9012
 *
9013
 * @return void
9014
 */
9015
	public function testFormMagicInputLabel() {
9016
		$encoding = strtolower(Configure::read('App.encoding'));
9017
		$result = $this->Form->create('Contact');
9018
		$expected = array(
9019
			'form' => array(
9020
				'id' => 'ContactAddForm', 'method' => 'post', 'action' => '/contacts/add',
9021
				'accept-charset' => $encoding
9022
			),
9023
			'div' => array('style' => 'display:none;'),
9024
			'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
9025
			'/div'
9026
		);
9027
		$this->assertTags($result, $expected);
9028
9029
		$result = $this->Form->input('Contact.name', array('div' => false, 'label' => false));
9030
		$this->assertTags($result, array('input' => array(
9031
			'name' => 'data[Contact][name]', 'type' => 'text',
9032
			'id' => 'ContactName', 'maxlength' => '255')
9033
		));
9034
9035
		$result = $this->Form->input('Contact.name', array('div' => false, 'label' => 'My label'));
9036
		$expected = array(
9037
			'label' => array('for' => 'ContactName'),
9038
			'My label',
9039
			'/label',
9040
			'input' => array(
9041
				'type' => 'text', 'name' => 'data[Contact][name]',
9042
				'id' => 'ContactName', 'maxlength' => '255'
9043
			)
9044
		);
9045
		$this->assertTags($result, $expected);
9046
9047
		$result = $this->Form->input('Contact.name', array(
9048
			'div' => false, 'label' => array('class' => 'mandatory')
9049
		));
9050
		$expected = array(
9051
			'label' => array('for' => 'ContactName', 'class' => 'mandatory'),
9052
			'Name',
9053
			'/label',
9054
			'input' => array(
9055
				'type' => 'text', 'name' => 'data[Contact][name]',
9056
				'id' => 'ContactName', 'maxlength' => '255'
9057
			)
9058
		);
9059
		$this->assertTags($result, $expected);
9060
9061
		$result = $this->Form->input('Contact.name', array(
9062
			'div' => false, 'label' => array('class' => 'mandatory', 'text' => 'My label')
9063
		));
9064
		$expected = array(
9065
			'label' => array('for' => 'ContactName', 'class' => 'mandatory'),
9066
			'My label',
9067
			'/label',
9068
			'input' => array(
9069
				'type' => 'text', 'name' => 'data[Contact][name]',
9070
				'id' => 'ContactName', 'maxlength' => '255'
9071
			)
9072
		);
9073
		$this->assertTags($result, $expected);
9074
9075
		$result = $this->Form->input('Contact.name', array(
9076
			'div' => false, 'id' => 'my_id', 'label' => array('for' => 'my_id')
9077
		));
9078
		$expected = array(
9079
			'label' => array('for' => 'my_id'),
9080
			'Name',
9081
			'/label',
9082
			'input' => array(
9083
				'type' => 'text', 'name' => 'data[Contact][name]',
9084
				'id' => 'my_id', 'maxlength' => '255'
9085
			)
9086
		);
9087
		$this->assertTags($result, $expected);
9088
9089
		$result = $this->Form->input('1.id');
9090
		$this->assertTags($result, array('input' => array(
9091
			'type' => 'hidden', 'name' => 'data[Contact][1][id]',
9092
			'id' => 'Contact1Id'
9093
		)));
9094
9095
		$result = $this->Form->input("1.name");
9096
		$expected = array(
9097
			'div' => array('class' => 'input text'),
9098
			'label' => array('for' => 'Contact1Name'),
9099
			'Name',
9100
			'/label',
9101
			'input' => array(
9102
				'type' => 'text', 'name' => 'data[Contact][1][name]',
9103
				'id' => 'Contact1Name', 'maxlength' => '255'
9104
			),
9105
			'/div'
9106
		);
9107
		$this->assertTags($result, $expected);
9108
9109
		$result = $this->Form->input('Contact.1.id');
9110
		$this->assertTags($result, array(
9111
			'input' => array(
9112
				'type' => 'hidden', 'name' => 'data[Contact][1][id]',
9113
				'id' => 'Contact1Id'
9114
			)
9115
		));
9116
9117
		$result = $this->Form->input("Model.1.name");
9118
		$expected = array(
9119
			'div' => array('class' => 'input text'),
9120
			'label' => array('for' => 'Model1Name'),
9121
			'Name',
9122
			'/label',
9123
			'input' => array(
9124
				'type' => 'text', 'name' => 'data[Model][1][name]',
9125
				'id' => 'Model1Name'
9126
			),
9127
			'/div'
9128
		);
9129
		$this->assertTags($result, $expected);
9130
	}
9131
9132
/**
9133
 * testFormEnd method
9134
 *
9135
 * @return void
9136
 */
9137
	public function testFormEnd() {
9138
		$this->assertEquals('</form>', $this->Form->end());
9139
9140
		$result = $this->Form->end('');
9141
		$expected = array(
9142
			'div' => array('class' => 'submit'),
9143
			'input' => array('type' => 'submit', 'value' => ''),
9144
			'/div',
9145
			'/form'
9146
		);
9147
		$this->assertTags($result, $expected);
9148
9149
		$result = $this->Form->end(array('label' => ''));
9150
		$expected = array(
9151
			'div' => array('class' => 'submit'),
9152
			'input' => array('type' => 'submit', 'value' => ''),
9153
			'/div',
9154
			'/form'
9155
		);
9156
		$this->assertTags($result, $expected);
9157
9158
		$result = $this->Form->end('save');
9159
		$expected = array(
9160
			'div' => array('class' => 'submit'),
9161
			'input' => array('type' => 'submit', 'value' => 'save'),
9162
			'/div',
9163
			'/form'
9164
		);
9165
		$this->assertTags($result, $expected);
9166
9167
		$result = $this->Form->end(array('label' => 'save'));
9168
		$expected = array(
9169
			'div' => array('class' => 'submit'),
9170
			'input' => array('type' => 'submit', 'value' => 'save'),
9171
			'/div',
9172
			'/form'
9173
		);
9174
		$this->assertTags($result, $expected);
9175
9176
		$result = $this->Form->end(array('label' => 'save', 'name' => 'Whatever'));
9177
		$expected = array(
9178
			'div' => array('class' => 'submit'),
9179
			'input' => array('type' => 'submit', 'value' => 'save', 'name' => 'Whatever'),
9180
			'/div',
9181
			'/form'
9182
		);
9183
		$this->assertTags($result, $expected);
9184
9185
		$result = $this->Form->end(array('name' => 'Whatever'));
9186
		$expected = array(
9187
			'div' => array('class' => 'submit'),
9188
			'input' => array('type' => 'submit', 'value' => 'Submit', 'name' => 'Whatever'),
9189
			'/div',
9190
			'/form'
9191
		);
9192
		$this->assertTags($result, $expected);
9193
9194
		$result = $this->Form->end(array('label' => 'save', 'name' => 'Whatever', 'div' => 'good'));
9195
		$expected = array(
9196
			'div' => array('class' => 'good'),
9197
			'input' => array('type' => 'submit', 'value' => 'save', 'name' => 'Whatever'),
9198
			'/div',
9199
			'/form'
9200
		);
9201
		$this->assertTags($result, $expected);
9202
9203
		$result = $this->Form->end(array(
9204
			'label' => 'save', 'name' => 'Whatever', 'div' => array('class' => 'good')
9205
		));
9206
		$expected = array(
9207
			'div' => array('class' => 'good'),
9208
			'input' => array('type' => 'submit', 'value' => 'save', 'name' => 'Whatever'),
9209
			'/div',
9210
			'/form'
9211
		);
9212
		$this->assertTags($result, $expected);
9213
	}
9214
9215
/**
9216
 * testMultipleFormWithIdFields method
9217
 *
9218
 * @return void
9219
 */
9220
	public function testMultipleFormWithIdFields() {
9221
		$this->Form->create('UserForm');
9222
9223
		$result = $this->Form->input('id');
9224
		$this->assertTags($result, array('input' => array(
9225
			'type' => 'hidden', 'name' => 'data[UserForm][id]', 'id' => 'UserFormId'
9226
		)));
9227
9228
		$result = $this->Form->input('ValidateItem.id');
9229
		$this->assertTags($result, array('input' => array(
9230
			'type' => 'hidden', 'name' => 'data[ValidateItem][id]',
9231
			'id' => 'ValidateItemId'
9232
		)));
9233
9234
		$result = $this->Form->input('ValidateUser.id');
9235
		$this->assertTags($result, array('input' => array(
9236
			'type' => 'hidden', 'name' => 'data[ValidateUser][id]',
9237
			'id' => 'ValidateUserId'
9238
		)));
9239
	}
9240
9241
/**
9242
 * testDbLessModel method
9243
 *
9244
 * @return void
9245
 */
9246
	public function testDbLessModel() {
9247
		$this->Form->create('TestMail');
9248
9249
		$result = $this->Form->input('name');
9250
		$expected = array(
9251
			'div' => array('class' => 'input text'),
9252
			'label' => array('for' => 'TestMailName'),
9253
			'Name',
9254
			'/label',
9255
			'input' => array(
9256
				'name' => 'data[TestMail][name]', 'type' => 'text',
9257
				'id' => 'TestMailName'
9258
			),
9259
			'/div'
9260
		);
9261
		$this->assertTags($result, $expected);
9262
9263
		ClassRegistry::init('TestMail');
9264
		$this->Form->create('TestMail');
9265
		$result = $this->Form->input('name');
9266
		$expected = array(
9267
			'div' => array('class' => 'input text'),
9268
			'label' => array('for' => 'TestMailName'),
9269
			'Name',
9270
			'/label',
9271
			'input' => array(
9272
				'name' => 'data[TestMail][name]', 'type' => 'text',
9273
				'id' => 'TestMailName'
9274
			),
9275
			'/div'
9276
		);
9277
		$this->assertTags($result, $expected);
9278
	}
9279
9280
/**
9281
 * testBrokenness method
9282
 *
9283
 * @return void
9284
 */
9285
	public function testBrokenness() {
9286
		/*
9287
		 * #4 This test has two parents and four children. By default (as of r7117) both
9288
		 * parents are show but the first parent is missing a child. This is the inconsistency
9289
		 * in the default behaviour - one parent has all children, the other does not - dependent
9290
		 * on the data values.
9291
		 */
9292
		$result = $this->Form->select('Model.field', array(
9293
			'Fred' => array(
9294
				'freds_son_1' => 'Fred',
9295
				'freds_son_2' => 'Freddie'
9296
			),
9297
			'Bert' => array(
9298
				'berts_son_1' => 'Albert',
9299
				'berts_son_2' => 'Bertie')
9300
			),
9301
			array('showParents' => true, 'empty' => false)
9302
		);
9303
9304
		$expected = array(
9305
			'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
9306
				array('optgroup' => array('label' => 'Fred')),
9307
					array('option' => array('value' => 'freds_son_1')),
9308
						'Fred',
9309
					'/option',
9310
					array('option' => array('value' => 'freds_son_2')),
9311
						'Freddie',
9312
					'/option',
9313
				'/optgroup',
9314
				array('optgroup' => array('label' => 'Bert')),
9315
					array('option' => array('value' => 'berts_son_1')),
9316
						'Albert',
9317
					'/option',
9318
					array('option' => array('value' => 'berts_son_2')),
9319
						'Bertie',
9320
					'/option',
9321
				'/optgroup',
9322
			'/select'
9323
		);
9324
		$this->assertTags($result, $expected);
9325
9326
		/*
9327
		 * #2 This is structurally identical to the test above (#1) - only the parent name has
9328
		 * changed, so we should expect the same select list data, just with a different name
9329
		 * for the parent. As of #7117, this test fails because option 3 => 'Three' disappears.
9330
		 * This is where data corruption can occur, because when a select value is missing from
9331
		 * a list a form will substitute the first value in the list - without the user knowing.
9332
		 * If the optgroup name 'Parent' (above) is updated to 'Three' (below), this should not
9333
		 * affect the availability of 3 => 'Three' as a valid option.
9334
		 */
9335
		$options = array(1 => 'One', 2 => 'Two', 'Three' => array(
9336
			3 => 'Three', 4 => 'Four', 5 => 'Five'
9337
		));
9338
		$result = $this->Form->select(
9339
			'Model.field', $options, array('showParents' => true, 'empty' => false)
9340
		);
9341
9342
		$expected = array(
9343
			'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
9344
				array('option' => array('value' => 1)),
9345
					'One',
9346
				'/option',
9347
				array('option' => array('value' => 2)),
9348
					'Two',
9349
				'/option',
9350
				array('optgroup' => array('label' => 'Three')),
9351
					array('option' => array('value' => 3)),
9352
						'Three',
9353
					'/option',
9354
					array('option' => array('value' => 4)),
9355
						'Four',
9356
					'/option',
9357
					array('option' => array('value' => 5)),
9358
						'Five',
9359
					'/option',
9360
				'/optgroup',
9361
			'/select'
9362
		);
9363
		$this->assertTags($result, $expected);
9364
	}
9365
9366
/**
9367
 * Test the generation of fields for a multi record form.
9368
 *
9369
 * @return void
9370
 */
9371
	public function testMultiRecordForm() {
9372
		$this->Form->create('ValidateProfile');
9373
		$this->Form->request->data['ValidateProfile'][1]['ValidateItem'][2]['name'] = 'Value';
9374
		$result = $this->Form->input('ValidateProfile.1.ValidateItem.2.name');
9375
		$expected = array(
9376
			'div' => array('class' => 'input textarea'),
9377
				'label' => array('for' => 'ValidateProfile1ValidateItem2Name'),
9378
					'Name',
9379
				'/label',
9380
				'textarea' => array(
9381
					'id' => 'ValidateProfile1ValidateItem2Name',
9382
					'name' => 'data[ValidateProfile][1][ValidateItem][2][name]',
9383
					'cols' => 30,
9384
					'rows' => 6
9385
				),
9386
				'Value',
9387
				'/textarea',
9388
			'/div'
9389
		);
9390
		$this->assertTags($result, $expected);
9391
9392
		$result = $this->Form->input('ValidateProfile.1.ValidateItem.2.created', array('empty' => true));
9393
		$expected = array(
9394
			'div' => array('class' => 'input date'),
9395
			'label' => array('for' => 'ValidateProfile1ValidateItem2CreatedMonth'),
9396
			'Created',
9397
			'/label',
9398
			array('select' => array(
9399
				'name' => 'data[ValidateProfile][1][ValidateItem][2][created][month]',
9400
				'id' => 'ValidateProfile1ValidateItem2CreatedMonth'
9401
				)
9402
			),
9403
			array('option' => array('value' => '')), '/option',
9404
			$this->dateRegex['monthsRegex'],
9405
			'/select', '-',
9406
			array('select' => array(
9407
				'name' => 'data[ValidateProfile][1][ValidateItem][2][created][day]',
9408
				'id' => 'ValidateProfile1ValidateItem2CreatedDay'
9409
				)
9410
			),
9411
			array('option' => array('value' => '')), '/option',
9412
			$this->dateRegex['daysRegex'],
9413
			'/select', '-',
9414
			array('select' => array(
9415
				'name' => 'data[ValidateProfile][1][ValidateItem][2][created][year]',
9416
				'id' => 'ValidateProfile1ValidateItem2CreatedYear'
9417
				)
9418
			),
9419
			array('option' => array('value' => '')), '/option',
9420
			$this->dateRegex['yearsRegex'],
9421
			'/select',
9422
			'/div'
9423
		);
9424
		$this->assertTags($result, $expected);
9425
9426
		$ValidateProfile = ClassRegistry::getObject('ValidateProfile');
9427
		$ValidateProfile->validationErrors[1]['ValidateItem'][2]['profile_id'] = 'Error';
9428
		$this->Form->request->data['ValidateProfile'][1]['ValidateItem'][2]['profile_id'] = '1';
9429
		$result = $this->Form->input('ValidateProfile.1.ValidateItem.2.profile_id');
9430
		$expected = array(
9431
			'div' => array('class' => 'input select error'),
9432
			'label' => array('for' => 'ValidateProfile1ValidateItem2ProfileId'),
9433
			'Profile',
9434
			'/label',
9435
			'select' => array(
9436
				'name' => 'data[ValidateProfile][1][ValidateItem][2][profile_id]',
9437
				'id' => 'ValidateProfile1ValidateItem2ProfileId',
9438
				'class' => 'form-error'
9439
			),
9440
			'/select',
9441
			array('div' => array('class' => 'error-message')),
9442
			'Error',
9443
			'/div',
9444
			'/div'
9445
		);
9446
		$this->assertTags($result, $expected);
9447
	}
9448
9449
/**
9450
 * test the correct display of multi-record form validation errors.
9451
 *
9452
 * @return void
9453
 */
9454
	public function testMultiRecordFormValidationErrors() {
9455
		$this->Form->create('ValidateProfile');
9456
		$ValidateProfile = ClassRegistry::getObject('ValidateProfile');
9457
		$ValidateProfile->validationErrors[2]['ValidateItem'][1]['name'] = array('Error in field name');
9458
		$result = $this->Form->error('ValidateProfile.2.ValidateItem.1.name');
9459
		$this->assertTags($result, array('div' => array('class' => 'error-message'), 'Error in field name', '/div'));
9460
9461
		$ValidateProfile->validationErrors[2]['city'] = array('Error in field city');
9462
		$result = $this->Form->error('ValidateProfile.2.city');
9463
		$this->assertTags($result, array('div' => array('class' => 'error-message'), 'Error in field city', '/div'));
9464
9465
		$result = $this->Form->error('2.city');
9466
		$this->assertTags($result, array('div' => array('class' => 'error-message'), 'Error in field city', '/div'));
9467
	}
9468
9469
/**
9470
 * test the correct display of multi-record form validation errors.
9471
 *
9472
 * @return void
9473
 */
9474
	public function testSaveManyRecordFormValidationErrors() {
9475
		$this->Form->create('ValidateUser');
9476
		$ValidateUser = ClassRegistry::getObject('ValidateUser');
9477
		$ValidateUser->validationErrors[0]['ValidateItem']['name'] = array('Error in field name');
9478
9479
		$result = $this->Form->error('0.ValidateUser.ValidateItem.name');
9480
		$this->assertTags($result, array('div' => array('class' => 'error-message'), 'Error in field name', '/div'));
9481
9482
		$ValidateUser->validationErrors[0]['city'] = array('Error in field city');
9483
		$result = $this->Form->error('ValidateUser.0.city');
9484
		$this->assertTags($result, array('div' => array('class' => 'error-message'), 'Error in field city', '/div'));
9485
	}
9486
9487
/**
9488
 * tests the ability to change the order of the form input placeholder "input", "label", "before", "between", "after", "error"
9489
 *
9490
 * @return void
9491
 */
9492
	public function testInputTemplate() {
9493
		$result = $this->Form->input('Contact.email', array(
9494
			'type' => 'text', 'format' => array('input')
9495
		));
9496
		$expected = array(
9497
			'div' => array('class' => 'input text'),
9498
			'input' => array(
9499
				'type' => 'text', 'name' => 'data[Contact][email]',
9500
				'id' => 'ContactEmail'
9501
			),
9502
			'/div'
9503
		);
9504
		$this->assertTags($result, $expected);
9505
9506
		$result = $this->Form->input('Contact.email', array(
9507
			'type' => 'text', 'format' => array('input', 'label'),
9508
			'label' => '<em>Email (required)</em>'
9509
		));
9510
		$expected = array(
9511
			'div' => array('class' => 'input text'),
9512
			array('input' => array(
9513
				'type' => 'text', 'name' => 'data[Contact][email]',
9514
				'id' => 'ContactEmail'
9515
			)),
9516
			'label' => array('for' => 'ContactEmail'),
9517
			'em' => array(),
9518
			'Email (required)',
9519
			'/em',
9520
			'/label',
9521
			'/div'
9522
		);
9523
		$this->assertTags($result, $expected);
9524
9525
		$result = $this->Form->input('Contact.email', array(
9526
			'type' => 'text', 'format' => array('input', 'between', 'label', 'after'),
9527
			'between' => '<div>Something in the middle</div>',
9528
			'after' => '<span>Some text at the end</span>'
9529
		));
9530
		$expected = array(
9531
			'div' => array('class' => 'input text'),
9532
			array('input' => array(
9533
				'type' => 'text', 'name' => 'data[Contact][email]',
9534
				'id' => 'ContactEmail'
9535
			)),
9536
			array('div' => array()),
9537
			'Something in the middle',
9538
			'/div',
9539
			'label' => array('for' => 'ContactEmail'),
9540
			'Email',
9541
			'/label',
9542
			'span' => array(),
9543
			'Some text at the end',
9544
			'/span',
9545
			'/div'
9546
		);
9547
		$this->assertTags($result, $expected);
9548
9549
		$result = $this->Form->input('Contact.method', array(
9550
			'type' => 'radio',
9551
			'options' => array('email' => 'Email', 'pigeon' => 'Pigeon'),
9552
			'between' => 'I am between',
9553
		));
9554
		$expected = array(
9555
			'div' => array('class' => 'input radio'),
9556
			'fieldset' => array(),
9557
			'legend' => array(),
9558
			'Method',
9559
			'/legend',
9560
			'I am between',
9561
			'input' => array(
9562
				'type' => 'hidden', 'name' => 'data[Contact][method]',
9563
				'value' => '', 'id' => 'ContactMethod_'
9564
			),
9565
			array('input' => array(
9566
				'type' => 'radio', 'name' => 'data[Contact][method]',
9567
				'value' => 'email', 'id' => 'ContactMethodEmail'
9568
			)),
9569
			array('label' => array('for' => 'ContactMethodEmail')),
9570
			'Email',
9571
			'/label',
9572
			array('input' => array(
9573
				'type' => 'radio', 'name' => 'data[Contact][method]',
9574
				'value' => 'pigeon', 'id' => 'ContactMethodPigeon'
9575
			)),
9576
			array('label' => array('for' => 'ContactMethodPigeon')),
9577
			'Pigeon',
9578
			'/label',
9579
			'/fieldset',
9580
			'/div',
9581
		);
9582
		$this->assertTags($result, $expected);
9583
	}
9584
9585
/**
9586
 * test that some html5 inputs + FormHelper::__call() work
9587
 *
9588
 * @return void
9589
 */
9590
	public function testHtml5Inputs() {
9591
		$result = $this->Form->email('User.email');
0 ignored issues
show
Documentation Bug introduced by
The method email does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
9592
		$expected = array(
9593
			'input' => array('type' => 'email', 'name' => 'data[User][email]', 'id' => 'UserEmail')
9594
		);
9595
		$this->assertTags($result, $expected);
9596
9597
		$result = $this->Form->search('User.query');
0 ignored issues
show
Documentation Bug introduced by
The method search does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
9598
		$expected = array(
9599
			'input' => array('type' => 'search', 'name' => 'data[User][query]', 'id' => 'UserQuery')
9600
		);
9601
		$this->assertTags($result, $expected);
9602
9603
		$result = $this->Form->search('User.query', array('value' => 'test'));
0 ignored issues
show
Documentation Bug introduced by
The method search does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
9604
		$expected = array(
9605
			'input' => array('type' => 'search', 'name' => 'data[User][query]', 'id' => 'UserQuery', 'value' => 'test')
9606
		);
9607
		$this->assertTags($result, $expected);
9608
9609
		$result = $this->Form->search('User.query', array('type' => 'text', 'value' => 'test'));
0 ignored issues
show
Documentation Bug introduced by
The method search does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
9610
		$expected = array(
9611
			'input' => array('type' => 'text', 'name' => 'data[User][query]', 'id' => 'UserQuery', 'value' => 'test')
9612
		);
9613
		$this->assertTags($result, $expected);
9614
9615
		$result = $this->Form->input('User.website', array('type' => 'url', 'value' => 'http://domain.tld', 'div' => false, 'label' => false));
9616
		$expected = array(
9617
			'input' => array('type' => 'url', 'name' => 'data[User][website]', 'id' => 'UserWebsite', 'value' => 'http://domain.tld')
9618
		);
9619
		$this->assertTags($result, $expected);
9620
	}
9621
9622
/**
9623
 *
9624
 * @expectedException CakeException
9625
 * @return void
9626
 */
9627
	public function testHtml5InputException() {
9628
		$this->Form->email();
0 ignored issues
show
Documentation Bug introduced by
The method email does not exist on object<FormHelper>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
9629
	}
9630
9631
/**
9632
 * Tests that a model can be loaded from the model names passed in the request object
9633
 *
9634
 * @return void
9635
 */
9636
	public function testIntrospectModelFromRequest() {
9637
		$this->loadFixtures('Post');
9638
		App::build(array(
9639
			'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
9640
		));
9641
		CakePlugin::load('TestPlugin');
9642
		$this->Form->request['models'] = array('TestPluginPost' => array('plugin' => 'TestPlugin', 'className' => 'TestPluginPost'));
9643
9644
		$this->assertFalse(ClassRegistry::isKeySet('TestPluginPost'));
9645
		$this->Form->create('TestPluginPost');
9646
		$this->assertTrue(ClassRegistry::isKeySet('TestPluginPost'));
9647
		$this->assertInstanceOf('TestPluginPost', ClassRegistry::getObject('TestPluginPost'));
9648
9649
		CakePlugin::unload();
9650
		App::build();
9651
	}
9652
9653
/**
9654
 * Tests that it is possible to set the validation errors directly in the helper for a field
9655
 *
9656
 * @return void
9657
 */
9658
	public function testCustomValidationErrors() {
9659
		$this->Form->validationErrors['Thing']['field'] = 'Badness!';
9660
		$result = $this->Form->error('Thing.field', null, array('wrap' => false));
9661
		$this->assertEquals('Badness!', $result);
9662
	}
9663
9664
/**
9665
 * Tests that the 'on' key validates as expected on create
9666
 *
9667
 * @return void
9668
 */
9669
	public function testRequiredOnCreate() {
9670
		$this->Form->create('Contact');
9671
9672
		$result = $this->Form->input('Contact.imrequiredonupdate');
9673
		$expected = array(
9674
			'div' => array('class' => 'input text'),
9675
			'label' => array('for' => 'ContactImrequiredonupdate'),
9676
			'Imrequiredonupdate',
9677
			'/label',
9678
			'input' => array(
9679
				'type' => 'text', 'name' => 'data[Contact][imrequiredonupdate]',
9680
				'id' => 'ContactImrequiredonupdate'
9681
			),
9682
			'/div'
9683
		);
9684
		$this->assertTags($result, $expected);
9685
9686
		$result = $this->Form->input('Contact.imrequiredoncreate');
9687
		$expected = array(
9688
			'div' => array('class' => 'input text required'),
9689
			'label' => array('for' => 'ContactImrequiredoncreate'),
9690
			'Imrequiredoncreate',
9691
			'/label',
9692
			'input' => array(
9693
				'type' => 'text', 'name' => 'data[Contact][imrequiredoncreate]',
9694
				'id' => 'ContactImrequiredoncreate',
9695
				'required' => 'required'
9696
			),
9697
			'/div'
9698
		);
9699
		$this->assertTags($result, $expected);
9700
9701
		$result = $this->Form->input('Contact.imrequiredonboth');
9702
		$expected = array(
9703
			'div' => array('class' => 'input text required'),
9704
			'label' => array('for' => 'ContactImrequiredonboth'),
9705
			'Imrequiredonboth',
9706
			'/label',
9707
			'input' => array(
9708
				'type' => 'text', 'name' => 'data[Contact][imrequiredonboth]',
9709
				'id' => 'ContactImrequiredonboth',
9710
				'required' => 'required'
9711
			),
9712
			'/div'
9713
		);
9714
		$this->assertTags($result, $expected);
9715
9716
		$this->Form->inputDefaults(array('required' => false));
9717
		$result = $this->Form->input('Contact.imrequired');
9718
		$expected = array(
9719
			'div' => array('class' => 'input text'),
9720
			'label' => array('for' => 'ContactImrequired'),
9721
			'Imrequired',
9722
			'/label',
9723
			'input' => array(
9724
				'type' => 'text', 'name' => 'data[Contact][imrequired]',
9725
				'id' => 'ContactImrequired'
9726
			),
9727
			'/div'
9728
		);
9729
		$this->assertTags($result, $expected);
9730
9731
		$result = $this->Form->input('Contact.imrequired', array('required' => false));
9732
		$this->assertTags($result, $expected);
9733
9734
		$result = $this->Form->input('Contact.imrequired', array('required' => true));
9735
		$expected = array(
9736
			'div' => array('class' => 'input text required'),
9737
			'label' => array('for' => 'ContactImrequired'),
9738
			'Imrequired',
9739
			'/label',
9740
			'input' => array(
9741
				'required' => 'required', 'type' => 'text', 'name' => 'data[Contact][imrequired]',
9742
				'id' => 'ContactImrequired'
9743
			),
9744
			'/div'
9745
		);
9746
		$this->assertTags($result, $expected);
9747
9748
		$result = $this->Form->input('Contact.imrequired', array('required' => null));
9749
		$this->assertTags($result, $expected);
9750
	}
9751
9752
/**
9753
 * Tests that the 'on' key validates as expected on update
9754
 *
9755
 * @return void
9756
 */
9757
	public function testRequiredOnUpdate() {
9758
		$this->Form->request->data['Contact']['id'] = 1;
9759
		$this->Form->create('Contact');
9760
9761
		$result = $this->Form->input('Contact.imrequiredonupdate');
9762
		$expected = array(
9763
			'div' => array('class' => 'input text required'),
9764
			'label' => array('for' => 'ContactImrequiredonupdate'),
9765
			'Imrequiredonupdate',
9766
			'/label',
9767
			'input' => array(
9768
				'type' => 'text', 'name' => 'data[Contact][imrequiredonupdate]',
9769
				'id' => 'ContactImrequiredonupdate',
9770
				'required' => 'required'
9771
			),
9772
			'/div'
9773
		);
9774
		$this->assertTags($result, $expected);
9775
		$result = $this->Form->input('Contact.imrequiredoncreate');
9776
		$expected = array(
9777
			'div' => array('class' => 'input text'),
9778
			'label' => array('for' => 'ContactImrequiredoncreate'),
9779
			'Imrequiredoncreate',
9780
			'/label',
9781
			'input' => array(
9782
				'type' => 'text', 'name' => 'data[Contact][imrequiredoncreate]',
9783
				'id' => 'ContactImrequiredoncreate'
9784
			),
9785
			'/div'
9786
		);
9787
		$this->assertTags($result, $expected);
9788
9789
		$result = $this->Form->input('Contact.imrequiredonboth');
9790
		$expected = array(
9791
			'div' => array('class' => 'input text required'),
9792
			'label' => array('for' => 'ContactImrequiredonboth'),
9793
			'Imrequiredonboth',
9794
			'/label',
9795
			'input' => array(
9796
				'type' => 'text', 'name' => 'data[Contact][imrequiredonboth]',
9797
				'id' => 'ContactImrequiredonboth',
9798
				'required' => 'required'
9799
			),
9800
			'/div'
9801
		);
9802
		$this->assertTags($result, $expected);
9803
9804
		$result = $this->Form->input('Contact.imrequired');
9805
		$expected = array(
9806
			'div' => array('class' => 'input text required'),
9807
			'label' => array('for' => 'ContactImrequired'),
9808
			'Imrequired',
9809
			'/label',
9810
			'input' => array(
9811
				'type' => 'text', 'name' => 'data[Contact][imrequired]',
9812
				'id' => 'ContactImrequired',
9813
				'required' => 'required'
9814
			),
9815
			'/div'
9816
		);
9817
		$this->assertTags($result, $expected);
9818
	}
9819
9820
/**
9821
 * Test inputDefaults setter and getter
9822
 *
9823
 * @return void
9824
 */
9825
	public function testInputDefaults() {
9826
		$this->Form->create('Contact');
9827
9828
		$this->Form->inputDefaults(array(
9829
			'label' => false,
9830
			'div' => array(
9831
				'style' => 'color: #000;'
9832
			)
9833
		));
9834
		$result = $this->Form->input('Contact.field1');
9835
		$expected = array(
9836
			'div' => array('class' => 'input text', 'style' => 'color: #000;'),
9837
			'input' => array(
9838
				'type' => 'text', 'name' => 'data[Contact][field1]',
9839
				'id' => 'ContactField1'
9840
			),
9841
			'/div'
9842
		);
9843
		$this->assertTags($result, $expected);
9844
9845
		$this->Form->inputDefaults(array(
9846
			'div' => false,
9847
			'label' => 'Label',
9848
		));
9849
		$result = $this->Form->input('Contact.field1');
9850
		$expected = array(
9851
			'label' => array('for' => 'ContactField1'),
9852
			'Label',
9853
			'/label',
9854
			'input' => array(
9855
				'type' => 'text', 'name' => 'data[Contact][field1]',
9856
				'id' => 'ContactField1'
9857
			),
9858
		);
9859
		$this->assertTags($result, $expected);
9860
9861
		$this->Form->inputDefaults(array(
9862
			'label' => false,
9863
		), true);
9864
		$result = $this->Form->input('Contact.field1');
9865
		$expected = array(
9866
			'input' => array(
9867
				'type' => 'text', 'name' => 'data[Contact][field1]',
9868
				'id' => 'ContactField1'
9869
			),
9870
		);
9871
		$this->assertTags($result, $expected);
9872
9873
		$result = $this->Form->inputDefaults();
9874
		$expected = array(
9875
			'div' => false,
9876
			'label' => false,
9877
		);
9878
		$this->assertEquals($expected, $result);
9879
	}
9880
9881
}
9882