mardi 7 juillet 2015

The class 'Symfony\\Component\\HttpFoundation\\File\\UploadedFile' was not found in the chain configured namespaces during Rest API Unit Test

I'm writing a REST API client and I am trying to unit test the user creation process which let a user to upload an image.

I am using Symfony 2.7, Doctrine Extension Bundle (Uploadable extension) and FOS Rest Bundle

The unit tests are working well excepted when I try to upload a file, it triggers me the following error when I error_log the 500 HTTP Reponse :

The class 'Symfony\\Component\\HttpFoundation\\File\\UploadedFile' was not found in the chain configured namespaces 

Please find the relevant code :

UsersControllerTest.php

<?php
namespace Acme\Bundle\UserBundle\Tests\Controller;

use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class UsersControllerTest extends WebTestCase
{
    public function testAvatar(){
        $client = static::createClient();

        $shortImage = tempnam(sys_get_temp_dir(), 'upl');
        imagepng(imagecreatetruecolor(10, 10), $shortImage);

        $file = new UploadedFile(
            $shortImage,
            basename($shortImage),
            MimeTypeGuesser::getInstance()->guess($shortImage),
            filesize($shortImage)
        );

        $crawler = $client->request(
            "POST",
            "/api/users",
            array(
                "user_registration" => array(
                    "firstName" => "test",          
                    "lastName" => "test"        
                ),
            ),          
            array(
                'user_registration'=>array('avatar'=>$file)
            ),          
            array(
                'Content-Type' => 'multipart/formdata'
            )           
        );      
        error_log($client->getResponse()); //Here I see the Uploadable class namespace error
        $this->assertEquals(200, $client->getResponse()->getStatusCode());      
    }   
}

UserRegistrationType.php

<?php
namespace Acme\Bundle\UserBundle\Form\Type;

use Acme\Bundle\UserBundle\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormBuilderInterface;

class UserRegistrationType extends AbstractType{

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Acme\Bundle\UserBundle\Entity\User',
            'cascade_validation' => true,
            'csrf_protection' => false
        ));
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('firstName', 'text');
        $builder->add('lastName', 'text');
        $builder->add('avatar', 'file', array(
            'required' => false
        ));
    }

    public function getParent()
    {
        return 'form';
    }

    public function getName()
    {
        return 'user_registration';
    }

}

UsersController.php

<?php
namespace Acme\Bundle\UserBundle\Controller;

use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Controller\Annotations\View;
use Acme\Bundle\UserBundle\Entity\User;
use Acme\Bundle\UserBundle\Entity\Avatar;
use Acme\Bundle\UserBundle\Form\Type\UserRegistrationType;
use Symfony\Component\HttpFoundation\Request;
use FOS\RestBundle\Controller\Annotations\RouteResource;
use JMS\SecurityExtraBundle\Annotation as JMSSecurity;

class UsersController extends FOSRestController
{

    /**
     * @View(serializerGroups={"Registration"})
    */
    public function postUsersAction(Request $request){
        $user = new User();

        $form = $this->createForm(new UserRegistrationType(), $user);
        $form->submit($request);


        if ($form->isValid()) {                     
            $em = $this->getDoctrine()->getManager();
            $em->persist($user);
            if(null !== $user->getAvatar()){
                $uploadableManager = $this->get('stof_doctrine_extensions.uploadable.manager');
                $uploadableManager->markEntityToUpload($user, $user->getAvatar());                  
            }       
            $em->flush();           
            return $user;
        }

        else {
            $validator = $this->get('validator');
            $errors = $validator->validate($user, array('Default','Registration'));
            $view = $this->view($errors, 400);
            return $this->handleView($view);
        }
    }
}

Avatar.php

<?php

namespace Acme\Bundle\UserBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;

/**
 * Avatar
 *
 * @ORM\Table("avatar")
 * @ORM\Entity
 * @Gedmo\Uploadable(pathMethod="getPath", callback="postUploadAction", filenameGenerator="SHA1", allowOverwrite=true, appendNumber=true) 
 */
class Avatar
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(name="path", type="string")
     * @Gedmo\UploadableFilePath
     */
    private $path;

    /**
     * @ORM\Column(name="name", type="string")
     * @Gedmo\UploadableFileName
     */
    private $name;

    /**
     * @ORM\Column(name="mime_type", type="string")
     * @Gedmo\UploadableFileMimeType
     */
    private $mimeType;

    /**
     * @ORM\Column(name="size", type="decimal")
     * @Gedmo\UploadableFileSize
     */
    private $size;


    public function postUploadAction(array $info)
    {
        // Do some stuff with the file..
    }


    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    public function getPath(){
        return __DIR__.'../../web/avatars/';
    }

    /**
     * Set path
     *
     * @param string $path
     * @return Image
     */
    public function setPath($path)
    {
        $this->path = $path;

        return $this;
    }

    /**
     * Set mimeType
     *
     * @param string $mimeType
     * @return Image
     */
    public function setMimeType($mimeType)
    {
        $this->mimeType = $mimeType;

        return $this;
    }

    /**
     * Get mimeType
     *
     * @return string
     */
    public function getMimeType()
    {
        return $this->mimeType;
    }

    /**
     * Set size
     *
     * @param string $size
     * @return Image
     */
    public function setSize($size)
    {
        $this->size = $size;

        return $this;
    }

    /**
     * Get size
     *
     * @return string
     */
    public function getSize()
    {
        return $this->size;
    }
}

User.php

class User{

    ...

    /**
    * Avatar
    * 
    * @ORM\OneToOne(targetEntity="Acme\Bundle\UserBundle\Entity\Avatar", cascade={"all"})
    * @ORM\JoinColumn(nullable=true)
    * @Assert\Valid
    */
    private $avatar;


    public function getAvatar(){
        return $this->avatar;
    }

    public function setAvatar($avatar = null){
        $this->avatar = $avatar;
        return $this;
    }
}

I really don't know the origin of the error, On my config.yml the doctrine mapping is set to auto

Thank you in advance for any help

Aucun commentaire:

Enregistrer un commentaire