Testing Upload Files In Zend Framework 2

I ran into a problem trying to write controller tests for one views which do file uploads. Unfortunately validation seems to fail every time for mocked requests with the unhelpful message “File was illegally uploaded. This could be a possible attack.”

Best I could find on the Internet:

if (IN_UNIT_TESTS) {
  $form->getInputFilte()->remove('name-of-upload-field');
}

Unfortunately this appears to break collections.

The problem is that ZF2 is unconditionally using is_uploaded_file in the UploadFile validator. (This is really a non-unit dependency so it should be mocked by default but it isn’t.) The FileInput input filter prepends that validator to the form without any option to override it. The File form element itself asks for the FileInput input filter by using its filter specification.

A solution is tricky because Zend Form’s heavily abstracted design design means that the call to “is_uploaded_file” is buried so many levels into Zend code. I think this kind of design is really only acceptable when you own the code and can get rid of these flaws fairly quickly. With Zend Form it means you effectively end up with your own form library on top of Zend’s which rather
defeats the object after a while.

The best workaround I found (once I worked out what was going on) was to replace the upload field entirely:

namespace FixedForms;

class FixedUploadFilter extends \Zend\InputFilter\FileInput {
  public function __construct() {
    $unhack 
      = defined('FIXEDFORMS_ENABLE_TEST_HACKS') 
      && FIXEDFORMS_ENABLE_TEST_HACKS;
    $this->setAutoPrependUploadValidator(! $unhack);
  }
}

class FixedUploadField extends \Zend\Form\Element\File {
  public function getInputSpecification() {
    return array(
      'type' => 'FixedForms\FixedUploadFilter',
      'name' => $this->getName(),
      'required' => false,
    );
  }
}

There may be a way to set the “auto prepend” property from the filter specification meaning you don’t need the extra InputFiler class but I lost patience before finding it.

This is an extra intrusive layer but hopefully it will save you a few hours trying hack around this problem.

Advertisements
Testing Upload Files In Zend Framework 2

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s