2009-10-12 11 views
0

D'abord mon code:Comment tester la fonction de téléchargement de fichiers avec la logique placée dans le filtre renommer (Zend_Form_Element_File)?

class ProfileController extends Zend_Controller_Action { 

private function getUploadAvatarForm() 
{ 
    $form = new Zend_Form; 
    $form->setAttrib('enctype', 'multipart/form-data'); 
    $form->setAction($this->view->baseUrl('/profile/upload-avatar')) 
     ->setName('uploadAvatarForm') 
     ->setMethod('POST'); 

    $element = new Zend_Form_Element_File('avatar'); 
    $element->setLabel('Upload an image:') 
      ->addFilter('Rename', 
       array('target' => '/path/toimages/directory/' . $this->userId . '.png', 
         'overwrite' => true) 
      ); 

    $element->addValidator('Count', false, 1); 
    $element->addValidator('Size', false, 102400); 
    $element->addValidator('Extension', false, 'png'); 
    $form->addElement($element, 'avatar') 
     ->addElement('submit', 'submit_upload', array('label' => 'upload')); 
    return $form; 
} 

public function uploadAvatarAction() 
{ 
    $form = $this->getUploadAvatarForm(); 
    $this->view->form = $form; 
    if (!$this->getRequest()->isPost() || !$form->isValid($_POST)) { 
     return; 
    }     
    if (!$form->avatar->receive()) { 
     ... error... 
    } 
    ... ok ... 
} 

} 

La question est: une partie de la logique de buissiness est placé dans le filtre Renommer. Dans ma vision ça vaut le coup, mais peut-être que je me trompe.

Je suis en train de le tester:

public function testUploadFile() 
{ 
    $this->_doLogin('user', 'password'); 
    $this->getRequest() 
     ->setMethod('POST')); 
    $this->mockFileUpload(); 

    $this->dispatch('profile/upload-avatar'); 
    var_dump($this->getResponse()->getBody()); 
} 

private function mockFileUpload() 
{ 
    $_FILES = array(
     'avatar' => array(
      'name' => 'test.png', 
      'type' => 'image/png', 
      'tmp_name' => '/tmp/test.png', 
      'error' => 0, 
      'size' => 10127)); 
} 

mais a obtenu:

Le fichier 'avatar' a été uploadé illégale, attaque possible

Pourriez-vous s'il vous plaît me suggérer comment tester cette situation? (Avec tout système de fichiers sera ok - je vais utiliser vfsStream pour cela, de sorte que le problème ne doit imiter le téléchargement post)

Répondre

0

Dans votre classe de test, définissez votre formulaire à utiliser une classe étendue de Zend_File_Transfer_Adapter_Http et override la méthode isValid(). Vous devrez évidemment changer la portée de votre fonction de formulaire en public dans votre ProfileController. Ceci doit être utilisé avec PHPUnit. Je ne sais pas encore comment l'intégrer avec Zend_Test_PHPUnit_ControllerTestCase, mais je devrai le comprendre à un moment donné et je le mettrai à jour.

$class = new ProfileController(); 
$form = $class->getUploadAvatarForm(); 
$form->getElement('avatar')->setTransferAdapter(new MockAdapter()); 

MockAdapter.php

class MockAdapter extends Zend_File_Transfer_Adapter_Http 
{ 
    public function isValid($files = null) 
    { 
     return true; 
    } 
} 
0

J'ai eu un problème similaire. Après un peu de lecture de code et d'expérimentation, j'ai découvert que mon problème était dû à l'appel de la fonction isValid de mon formulaire deux fois (à cause d'un petit problème de code). Je ne sais pas exactement comment, mais le double isValid a provoqué la suppression de mon fichier tmp (le fichier téléchargé) avant que la seconde fonction isValid ne soit exécutée, ce qui fait que la ligne 183 de Zend_Validate_File_Upload pense que ce n'était pas un téléchargement de fichier correct (parce que la deuxième fois qu'il l'a cherché, il a déjà été supprimé):

Si vous voulez vérifier si votre fichier temporaire n'est pas là pour une raison de modifier la ligne 183 de Zend_Validate_File_Upload:

case 0: 
    var_dump(file_exists($content['tmp_name'])); 
    if (!is_uploaded_file($content['tmp_name'])) { 
     $this->_throw($file, self::ATTACK); 
    } 
    break; 

peut-être votre changement de nom le filtre est en train de déplacer ou de renommer le fichier?