ZF-3869: Document how to test forms which use Zend_Form_Element_Hash

Description

Zend_Forms containing a Zend_Form_Element_Hash are not supported by Zend_Test_PHPUnit. The form will not pass as long as you do not send the token as well generated by Zend_Form_Element_Hash. See discussion at [http://nabble.com/Zend_Test_PHPUnit-and-hashed-for…]

A solution might be to retrieve the name of the hash element as well as the hash from Zend_Session and add it by default as $_POST variables:

``` This example is not working. It's just a thought. I'll see whether I can find a working solution.

Comments

Matthew, what do you think is the best way to handle it?

Sorry for poor formatting, first time commenting. I was able to solve this by creating a new Zend_Form_Element_Hash object in the test.

Example:

$csrf = new Zend_Form_Element_Hash("csrf"); $this->request->setMethod('POST')->setPost( array( ... 'csrf' => $csrf->getHash(), ));

As it turns out, the above didn't actually solve it. I just had another error that masked it.

For reference, the discussion link doesn't work, but http://zend-framework-community.634137.n4.nabble.com/… does.


$csrf = new Zend_Form_Element_Hash("csrf");

$hash = $csrf->getHash();
$csrf->initCsrfToken();
$csrf->initCsrfValidator();

$this->request->setMethod('POST')->setPost(
array(
...
'csrf' => $hash,
));

That would work

This is more of a documentation/awareness issue than an issue with {{Zend_Form_Element_Hash}} itself. I suggest updating the manual entry for that component to outline how forms which use it can be unit tested. Example:


Index: documentation/manual/en/module_specs/Zend_Form-StandardElements.xml
===================================================================
--- documentation/manual/en/module_specs/Zend_Form-StandardElements.xml (revision 24514)
+++ documentation/manual/en/module_specs/Zend_Form-StandardElements.xml (working copy)
@@ -522,6 +522,37 @@
             The 'formHidden' view helper is used to render the element in the
             form.
         
+
+        
+            Testing forms containing Zend_Form_Element_Hash
+            
+                When unit testing a form containing a Zend_Form_Element_Hash 
+                it is necessary to call initCsrfToken and 
+                initCsrfValidator before attempting to
+                validate the form.  The hash value of the Zend_Form_Element_Hash 
+                element must also be injected into the array of values passed as the
+                argument to Zend_Form::isValid
+            
+            
+                Simple example of testing a CSRF-protected form
+                
+public function testCsrfProtectedForm() 
+{
+    $form = new Zend_Form();
+    $form->addElement(new Zend_Form_Element_Hash('csrf'));
+
+    $csrf = $form->getElement('csrf');
+    $csrf->initCsrfToken();
+    $csrf->initCsrfValidator();
+
+    $this->assertTrue($form->isValid(array(
+        'csrf' => $csrf->getHash()
+    )));
+}
+
+            
+        
+        
     
 
     

Thoughts?

Attached patch

Fixed in trunk (1.12.0): r24757 Fixed in release-1.11 (1.11.12): r24758

Not applicable to ZF2