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


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 […]

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.


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.


$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… does.

$csrf = new Zend_Form_Element_Hash("csrf");

$hash = $csrf->getHash();

'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
+            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()
+    )));


Attached patch

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

Not applicable to ZF2