Permalink
Browse files

Add tests for context detectors.

Move code around and add tests for the default context classes.
  • Loading branch information...
1 parent dda3040 commit 11014f9a918751cd826acc9940b4b8134aba784c @markstory markstory committed Feb 10, 2014
Showing with 75 additions and 53 deletions.
  1. +57 −49 src/View/Helper/FormHelper.php
  2. +18 −4 tests/TestCase/View/Helper/FormHelperTest.php
@@ -26,6 +26,7 @@
use Cake\View\Form\NullContext;
use Cake\View\Helper;
use Cake\View\StringTemplate;
+use Cake\View\Helper\StringTemplateTrait;
use Cake\View\View;
use Cake\View\Widget\InputRegistry;
use DateTime;
@@ -41,6 +42,8 @@
*/
class FormHelper extends Helper {
+ use StringTemplateTrait;
+
/**
* Other helpers used by FormHelper
*
@@ -136,13 +139,6 @@ class FormHelper extends Helper {
protected $_registry;
/**
- * Template formatter for the helper.
- *
- * @var Cake\View\StringTemplate
- */
- protected $_templates;
-
-/**
* Context for the current form.
*
* @var Cake\View\Form\Context
@@ -158,42 +154,60 @@ class FormHelper extends Helper {
protected $_contextProviders;
/**
+ * Default templates the FormHelper uses.
+ *
+ * @var array
+ */
+ protected $_defaultTemplates = [
+ 'formstart' => '<form {{attrs}}>',
+ 'formend' => '</form>',
+ ];
+
+/**
* Copies the validationErrors variable from the View object into this instance
*
* @param View $View The View this helper is being attached to.
* @param array $settings Configuration settings for the helper.
*/
public function __construct(View $View, $settings = array()) {
$settings += ['widgets' => [], 'templates' => null, 'registry' => null];
- if (is_array($settings['templates'])) {
- $settings['templates'] = new StringTemplate($settings['templates']);
- }
- $this->_templates = $settings['templates'] ?: new StringTemplate();
+ parent::__construct($View, $settings);
+ $this->initStringTemplates($this->_defaultTemplates);
if (empty($settings['registry'])) {
- $settings['registry'] = new InputRegistry($this->_templates, $settings['widgets']);
+ $settings['registry'] = new InputRegistry($this->_templater, $settings['widgets']);
}
$this->_registry = $settings['registry'];
+ unset($this->settings['registry']);
+ $this->_addDefaultContextProviders();
+ }
+
+/**
+ * Add the default suite of context providers provided by CakePHP.
+ *
+ * @return void
+ */
+ protected function _addDefaultContextProviders() {
$this->addContextProvider('array', function ($request, $data) {
- if (is_array($data) && isset($data['schema'])) {
- return new ArrayContext($request, $data);
+ if (is_array($data['entity']) && isset($data['entity']['schema'])) {
+ return new ArrayContext($request, $data['entity']);
}
});
+
$this->addContextProvider('orm', function ($request, $data) {
if (
- $data instanceof Entity ||
- $data instanceof Traversable ||
- (is_array($data) && !isset($data['schema']))
+ $data['entity'] instanceof Entity ||
+ $data['entity'] instanceof Traversable ||
+ (is_array($data['entity']) && !isset($data['entity']['schema']))
) {
return new EntityContext($request, $data);
}
});
+
$this->addContextProvider('_default', function ($request, $data) {
return new NullContext($request, (array)$data);
});
-
- parent::__construct($View, $settings);
}
/**
@@ -262,34 +276,26 @@ public function tagIsInvalid() {
* @return string An formatted opening FORM tag.
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#options-for-create
*/
- public function create($model = null, $options = array()) {
- $created = $id = $key = false;
+ public function create($model = null, $options = []) {
+ $id = $key = false;
$append = '';
- $this->_context = $this->_buildContext($model);
-
- // TODO implement 'isNew' on context classes.
- if ($model !== false && $key) {
- $recordExists = (
- isset($this->request->data[$model]) &&
- !empty($this->request->data[$model][$key]) &&
- !is_array($this->request->data[$model][$key])
- );
-
- if ($recordExists) {
- $created = true;
- $id = $this->request->data[$model][$key];
- }
+ if (empty($options['context'])) {
+ $options['context'] = [];
}
+ $options['context']['entity'] = $model;
+ $this->_context = $this->_buildContext($options['context']);
+ unset($options['context']);
+
+ $isCreate = $this->_context->isCreate();
- $options = array_merge(array(
- 'type' => ($created && empty($options['action'])) ? 'put' : 'post',
+ $options = array_merge([
+ 'type' => (!$isCreate && empty($options['action'])) ? 'put' : 'post',
'action' => null,
'url' => null,
'default' => true,
'encoding' => strtolower(Configure::read('App.encoding')),
- ),
- $options);
+ ], $options);
if (!isset($options['id'])) {
$domId = isset($options['action']) ? $options['action'] : $this->request['action'];
@@ -299,12 +305,9 @@ public function create($model = null, $options = array()) {
if ($options['action'] === null && $options['url'] === null) {
$options['action'] = $this->request->here(false);
} elseif (empty($options['url']) || is_array($options['url'])) {
+ // TODO restore convention around model->controller name.
if (empty($options['url']['controller'])) {
- if (!empty($model)) {
- $options['url']['controller'] = Inflector::underscore(Inflector::pluralize($model));
- } elseif (!empty($this->request->params['controller'])) {
- $options['url']['controller'] = Inflector::underscore($this->request->params['controller']);
- }
+ $options['url']['controller'] = Inflector::underscore($this->request->params['controller']);
}
if (empty($options['action'])) {
$options['action'] = $this->request->params['action'];
@@ -319,7 +322,9 @@ public function create($model = null, $options = array()) {
'controller' => $this->_View->viewPath,
'action' => $options['action'],
);
- $options['action'] = array_merge($actionDefaults, (array)$options['url']);
+ $options['action'] = (array)$options['url'] + $actionDefaults;
+
+ // TODO add primary key handling
if (empty($options['action'][0]) && !empty($id)) {
$options['action'][0] = $id;
}
@@ -339,15 +344,17 @@ public function create($model = null, $options = array()) {
case 'put':
case 'delete':
$append .= $this->hidden('_method', array(
- 'name' => '_method', 'value' => strtoupper($options['type']), 'id' => null,
+ 'name' => '_method',
+ 'value' => strtoupper($options['type']),
+ 'id' => null,
'secure' => static::SECURE_SKIP
));
default:
$htmlAttributes['method'] = 'post';
}
$this->requestType = strtolower($options['type']);
- $action = $this->url($options['action']);
+ $htmlAttributes['action'] = $this->url($options['action']);
unset($options['type'], $options['action']);
if (!$options['default']) {
@@ -373,8 +380,9 @@ public function create($model = null, $options = array()) {
if (!empty($append)) {
$append = $this->Html->useTag('hiddenblock', $append);
}
-
- return $this->Html->useTag('form', $action, $htmlAttributes) . $append;
+ return $this->_templater->format('formstart', [
+ 'attrs' => $this->_templater->formatAttributes($htmlAttributes)
+ ]) . $append;
}
/**
@@ -21,6 +21,7 @@
use Cake\Core\Configure;
use Cake\Core\Plugin;
use Cake\Network\Request;
+use Cake\ORM\Entity;
use Cake\ORM\Table;
use Cake\ORM\TableRegistry;
use Cake\Routing\Router;
@@ -30,6 +31,13 @@
use Cake\View\Helper\HtmlHelper;
use Cake\View\View;
+
+/**
+ * Test stub.
+ */
+class Article extends Entity {
+}
+
/**
* ContactTestController class
*
@@ -454,7 +462,7 @@ class FormHelperTest extends TestCase {
*
* @var array
*/
- public $fixtures = array('core.post');
+ public $fixtures = array('core.article');
/**
* Do not load the fixtures by default
@@ -562,7 +570,7 @@ public function testContextClassMatching() {
*/
public function contextSelectionProvider() {
$entity = $this->getMock('Cake\ORM\Entity');
- $collection = $this->getMock('Cake\Collection\Collection', [], [[$entity]]);
+ $collection = $this->getMock('Cake\Collection\Collection', ['extract'], [[$entity]]);
$data = [
'schema' => [
'title' => ['type' => 'string']
@@ -585,6 +593,8 @@ public function contextSelectionProvider() {
* @return void
*/
public function testCreateContextSelectionBuiltIn($data, $class) {
+ $this->Form->create($data);
+ $this->assertInstanceOf($class, $this->Form->context());
}
/**
@@ -595,10 +605,14 @@ public function testCreateContextSelectionBuiltIn($data, $class) {
* @return void
*/
public function testCreateWithSecurity() {
- $this->markTestIncomplete('Need to revisit once models work again.');
+ $this->markTestIncomplete();
$this->Form->request->params['_csrfToken'] = 'testKey';
$encoding = strtolower(Configure::read('App.encoding'));
- $result = $this->Form->create('Contact', array('url' => '/contacts/add'));
+ $article = new Article();
+ $result = $this->Form->create($article, [
+ 'url' => '/contacts/add',
+ 'context' => ['table' => 'Articles']
+ ]);
$expected = array(
'form' => array('method' => 'post', 'action' => '/contacts/add', 'accept-charset' => $encoding, 'id' => 'ContactAddForm'),
'div' => array('style' => 'display:none;'),

0 comments on commit 11014f9

Please sign in to comment.