From d43ac7127691de37038c30a12978f5305cf1dbe6 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sat, 20 Dec 2014 12:21:25 -0500 Subject: [PATCH] Implement a FormHelper context class for Form\Form. This allows FormHelper to work with Form instances. --- src/View/Form/FormContext.php | 136 +++++++++++++ tests/TestCase/View/Form/FormContextTest.php | 204 +++++++++++++++++++ 2 files changed, 340 insertions(+) create mode 100644 src/View/Form/FormContext.php create mode 100644 tests/TestCase/View/Form/FormContextTest.php diff --git a/src/View/Form/FormContext.php b/src/View/Form/FormContext.php new file mode 100644 index 00000000000..46c5e364948 --- /dev/null +++ b/src/View/Form/FormContext.php @@ -0,0 +1,136 @@ +_request = $request; + $context += [ + 'entity' => null, + ]; + $this->_form = $context['entity']; + } + +/** + * {@inheritDoc} + */ + public function primaryKey() { + return []; + } + +/** + * {@inheritDoc} + */ + public function isPrimaryKey($field) { + return false; + } + +/** + * {@inheritDoc} + */ + public function isCreate() { + return true; + } + +/** + * {@inheritDoc} + */ + public function val($field) { + return $this->_request->data($field); + } + +/** + * {@inheritDoc} + */ + public function isRequired($field) { + $validator = $this->_form->validator(); + if (!$validator->hasField($field)) { + return false; + } + if ($this->type($field) !== 'boolean') { + return $validator->isEmptyAllowed($field, true) === false; + } + return false; + } + +/** + * {@inheritDoc} + */ + public function fieldNames() { + $schema = $this->_form->schema(); + return $schema->fields(); + } + +/** + * {@inheritDoc} + */ + public function type($field) { + $schema = $this->_form->schema(); + return $schema->fieldType($field); + } + +/** + * {@inheritDoc} + */ + public function attributes($field) { + $column = (array)$this->_form->schema()->field($field); + $whitelist = ['length' => null, 'precision' => null]; + return array_intersect_key($column, $whitelist); + } + +/** + * {@inheritDoc} + */ + public function hasError($field) { + $errors = $this->error($field); + return count($errors) > 0; + } + +/** + * {@inheritDoc} + */ + public function error($field) { + $errors = $this->_form->errors(); + if (isset($errors[$field])) { + return array_values($errors[$field]); + } + return []; + } + +} diff --git a/tests/TestCase/View/Form/FormContextTest.php b/tests/TestCase/View/Form/FormContextTest.php new file mode 100644 index 00000000000..b2bcafbbc17 --- /dev/null +++ b/tests/TestCase/View/Form/FormContextTest.php @@ -0,0 +1,204 @@ +request = new Request(); + } + +/** + * Test getting the primary key. + * + * @return void + */ + public function testPrimaryKey() { + $context = new FormContext($this->request, ['entity' => new Form()]); + $this->assertEquals([], $context->primaryKey()); + } + +/** + * Test isPrimaryKey. + * + * @return void + */ + public function testIsPrimaryKey() { + $context = new FormContext($this->request, ['entity' => new Form()]); + $this->assertFalse($context->isPrimaryKey('id')); + } + +/** + * Test the isCreate method. + * + * @return void + */ + public function testIsCreate() { + $context = new FormContext($this->request, ['entity' => new Form()]); + $this->assertTrue($context->isCreate()); + } + +/** + * Test reading values from the request & defaults. + */ + public function testValPresent() { + $this->request->data = [ + 'Articles' => [ + 'title' => 'New title', + 'body' => 'My copy', + ] + ]; + $context = new FormContext($this->request, ['entity' => new Form()]); + $this->assertEquals('New title', $context->val('Articles.title')); + $this->assertEquals('My copy', $context->val('Articles.body')); + $this->assertNull($context->val('Articles.nope')); + } + +/** + * Test getting values when the request and defaults are missing. + * + * @return void + */ + public function testValMissing() { + $context = new FormContext($this->request, ['entity' => new Form()]); + $this->assertNull($context->val('Comments.field')); + } + +/** + * Test isRequired + * + * @return void + */ + public function testIsRequired() { + $form = new Form(); + $form->validator() + ->requirePresence('name') + ->add('email', 'format', ['rule' => 'email']); + + $context = new FormContext($this->request, [ + 'entity' => $form + ]); + $this->assertTrue($context->isRequired('name')); + $this->assertTrue($context->isRequired('email')); + $this->assertFalse($context->isRequired('body')); + $this->assertFalse($context->isRequired('Prefix.body')); + } + +/** + * Test the type method. + * + * @return void + */ + public function testType() { + $form = new Form(); + $form->schema() + ->addField('email', 'string') + ->addField('user_id', 'integer'); + + $context = new FormContext($this->request, [ + 'entity' => $form + ]); + $this->assertNull($context->type('undefined')); + $this->assertEquals('integer', $context->type('user_id')); + $this->assertEquals('string', $context->type('email')); + $this->assertNull($context->type('Prefix.email')); + } + +/** + * Test fetching attributes. + * + * @return void + */ + public function testAttributes() { + $form = new Form(); + $form->schema() + ->addField('email', [ + 'type' => 'string', + 'length' => 10, + ]) + ->addField('amount', [ + 'type' => 'decimal', + 'length' => 5, + 'precision' => 2, + ]); + $context = new FormContext($this->request, [ + 'entity' => $form + ]); + $this->assertEquals([], $context->attributes('id')); + $this->assertEquals(['length' => 10, 'precision' => null], $context->attributes('email')); + $this->assertEquals(['precision' => 2, 'length' => 5], $context->attributes('amount')); + } + +/** + * Test fetching errors. + * + * @return void + */ + public function testError() { + $form = new Form(); + $form->validator() + ->add('email', 'format', ['rule' => 'email']) + ->add('name', 'length', ['rule' => ['minLength', 10]]); + $form->validate([ + 'email' => 'derp', + 'name' => 'derp' + ]); + + $context = new FormContext($this->request, ['entity' => $form]); + $this->assertEquals([], $context->error('empty')); + $this->assertEquals(['The provided value is invalid'], $context->error('email')); + $this->assertEquals(['The provided value is invalid'], $context->error('name')); + + $this->assertEquals([], $context->error('Alias.name')); + $this->assertEquals([], $context->error('nope.nope')); + } + +/** + * Test checking errors. + * + * @return void + */ + public function testHasError() { + $form = new Form(); + $form->validator() + ->add('email', 'format', ['rule' => 'email']) + ->add('name', 'length', ['rule' => ['minLength', 10]]); + $form->validate([ + 'email' => 'derp', + 'name' => 'derp' + ]); + + $context = new FormContext($this->request, ['entity' => $form]); + $this->assertTrue($context->hasError('email')); + $this->assertTrue($context->hasError('name')); + $this->assertFalse($context->hasError('nope')); + $this->assertFalse($context->hasError('nope.nope')); + } + +}