Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling Polycollections errors #51

Open
3kynox opened this issue Dec 14, 2015 · 5 comments
Open

Handling Polycollections errors #51

3kynox opened this issue Dec 14, 2015 · 5 comments

Comments

@3kynox
Copy link

3kynox commented Dec 14, 2015

Hello !

I'm looking to manage errors with polycollections.
It's easy to manage normal fields or moyensComm validation using validation.yml file

brunoBundle\Entity\Contact:
    properties:
        moyensComm:
            - Count:
                min: 1
                max: 5
                minMessage: "Vous devez spécifier au moins un moyen de communication"
                maxMessage: "Vous ne pouvez ajouter plus de {{ limit }} moyen(s) de communication"
        text:
            - Length:
                min: 5
                max: 20
                minMessage: "Vous devez spécifier au minimum 5 caractères pour le champ 'Text'"
                maxMessage: "Vous êtes limités à {{ limit }} caractères pour le champ 'Text'"

But about Polycollections, not sure how to specify constraints.

Thanks for help.

@jmclean
Copy link
Contributor

jmclean commented Dec 15, 2015

First you need to tell Symfony to apply validation rules to the entities in the moyensComm array:

brunoBundle\Entity\Contact:
    properties:
        moyensComm:
            - Valid: ~

And then you can add validation rules for your derived classes:

brunoBundle\Entity\Email:
    properties:
        email:
            - Email: ~
            - NotBlank: ~

You may also need to turn off error_bubbling on the polycollection to make some errors (like Count in your example) show up in the right place:

        $builder
            ->add('moyensComm', 'infinite_form_polycollection', array(
                'error_bubbling' => false,

@3kynox
Copy link
Author

3kynox commented Dec 15, 2015

Thanks jm, this is working (if no moyensComm is defined, showing error at the right place and it adds regex pattern property to the email input field in my example).

I face another problem about tests (using codeception) and polycollections.
I'm writing a method to test form data validation that's look like that :

// brunoBundle/Tests/unit/Form/ContactTypeTest.php

use brunoBundle\Form\ContactType;
use brunoBundle\Entity\Contact;
use brunoBundle\Entity\Telephone;

use Symfony\Component\Form\Test\TypeTestCase;

class ContactTypeTest extends TypeTestCase
{
    public function testSubmitValidData()
    {
        $formData = array(
            'text' => 'Client n°3',
            'textarea' => 'Encore du texte ...',
            'email' => '[email protected]',
            'entier' => 51,
            'money' => 51,
            'date' => new \DateTime('2016/01/01'),
            'gender' => 2,
            'moyensComm' => array('0' => array('numero' => '00 00 00 00 10')),
        );

        $object = new Contact();
        $object->setText('Client n°3');
        $object->setTextarea('Encore du texte ...');
        $object->setEmail('[email protected]');
        $object->setEntier(51);
        $object->setMoney(51);
        $object->setDate(new \DateTime('2016/01/01'));

        $telephone = new Telephone();
        $telephone->setNumero('00 00 00 00 10');
        $telephone->setContact($object);

        $object->addMoyensComm($telephone);

        $object->getMoyensComm();

        $type = new ContactType($object);
        $form = $this->factory->create($type);

        // submit the data to the form directly
        $form->submit($formData);

        $this->assertTrue($form->isSynchronized());
        $this->assertEquals($object, $form->getData());

        $view = $form->createView();
        $children = $view->children;

        foreach (array_keys($formData) as $key) {
            $this->assertArrayHasKey($key, $children);
        }
    }
}

What I do here is build an array with correct values, then building a Contact object and comparing both.

The problem is it returns error :

Test telephone (TelephoneTest::testTelephone)                                                                                                Ok
Test check telephone bdd (TelephoneTest::testCheckTelephoneBdd)                                                                              Ok
Test change numero (TelephoneTest::testChangeNumero)                                                                                         Ok
ContactTypeTest::testSubmitValidData                                                                                                         Error
--------------------------------------------------------------------------------------------------------------------------------------------------


Time: 8.66 seconds, Memory: 27.75Mb

There was 1 error:

---------
1) ContactTypeTest::testSubmitValidData

  [Symfony\Component\Form\Exception\InvalidArgumentException] Could not load type "infinite_form_polycollection"  

#1  D:\clients\courtier-web\formType\www\vendor\symfony\symfony\src\Symfony\Component\Form\FormFactory.php:82
#2  D:\clients\courtier-web\formType\www\vendor\symfony\symfony\src\Symfony\Component\Form\FormBuilder.php:106
#3  D:\clients\courtier-web\formType\www\vendor\symfony\symfony\src\Symfony\Component\Form\FormBuilder.php:267
#4  D:\clients\courtier-web\formType\www\vendor\symfony\symfony\src\Symfony\Component\Form\FormBuilder.php:215
#5  D:\clients\courtier-web\formType\www\vendor\symfony\symfony\src\Symfony\Component\Form\FormFactory.php:39
#6  D:\clients\courtier-web\formType\www\src\brunoBundle\Tests\unit\Form\ContactTypeTest.php:46
#7  ContactTypeTest->testSubmitValidData

FAILURES!
Tests: 13, Assertions: 34, Errors: 1.

Am I doing this the wrong way ?

@jmclean
Copy link
Contributor

jmclean commented Dec 15, 2015

You're on the right track but see also Symfony's documentation on testing forms with dependencies.

class ContactTypeTest extends TypeTestCase
{
    protected function getExtensions()
    {
        $adresse = new AdresseType();
        $contact = new ContactType();
        $email = new EmailType();
        $mobile = new MobileType();
        $telephone = new TelephoneType();
        $polycollection = new PolyCollectionType();

        return array(
            new PreloadedExtension(
                array(
                    $adresse->getName() => $adresse,
                    $contact->getName() => $contact,
                    $email->getName() => $email,
                    $mobile->getName() => $mobile,
                    $telephone->getName() => $telephone,
                    $polycollection->getName() => $polycollection,
                ),
                array()
            ),
        );
    }

@3kynox
Copy link
Author

3kynox commented Dec 16, 2015

Thanks for answer jm,

I saw this Symfony doc page but I was getting pain to adapt code to polycollection situation.

I did last code you post but I still have error could not load type "infinite_form_polycollection

I try to find how the name is given, it should not be the same currently.

EDIT : Finally got dump that works inside unit test (using ob_flush()) and

var_dump($polycollection->getName()) returns string(21) "brunobundle_moyencomm"

@jmclean
Copy link
Contributor

jmclean commented Dec 17, 2015

What do your use statements look like now? You'll need use Infinite\FormBundle\Form\Type\PolycollectionType; in there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants