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

Functional Testing Collection Form Fields #4124

Closed
gzankevich opened this issue Apr 26, 2012 · 24 comments
Closed

Functional Testing Collection Form Fields #4124

gzankevich opened this issue Apr 26, 2012 · 24 comments

Comments

@gzankevich
Copy link

@gzankevich gzankevich commented Apr 26, 2012

With form collections, we use Javascript to add the new fields and Symfony handles the rest.

In the following example, Office has a many-to-many with Contact.

When attempting the same approach in functional tests, e.g. by doing:

    $form = $buttonCrawlerNode->form(array(
            'company_whateverbundle_officetype[office_contacts][0][contact]' => '1'
    ));

The actual result is:

InvalidArgumentException: The form field "company_whateverbundle_officetype[office_contacts][0][contact]" does not exist.

The expected result is that a new contact is added.

Steps to reproduce:

  1. Create a couple of entities with a many-to-many association between them.
  2. Create a form with a collection field to edit the associations.
  3. Create a functional test and try to create a new association with it.
@gzankevich
Copy link
Author

@gzankevich gzankevich commented Apr 26, 2012

Same deal with collections of "file" entities when calling:

$form['company_whateverbundle_officetype[image_attachment][0][file]']->upload(__DIR__.'/../../Fixtures/SampleImage.png');
@stof
Copy link
Member

@stof stof commented Apr 26, 2012

Are you setting the allow_add option to true for the CollectionType ?

@gzankevich
Copy link
Author

@gzankevich gzankevich commented Apr 26, 2012

Yes, it works fine in dev/prod environments.

@leftdevel
Copy link

@leftdevel leftdevel commented Jul 13, 2012

Hi @gzankevich, did you managed it?

@gzankevich
Copy link
Author

@gzankevich gzankevich commented Jul 16, 2012

Issue still persists. I'll try it out on a clean installation and see what happens.

@r4cker
Copy link

@r4cker r4cker commented Jul 24, 2012

I am facing the same problem.

  • Works fine in dev/prod
  • allow_add set to TRUE

@gzankevich Did you find what happend?

@gzankevich
Copy link
Author

@gzankevich gzankevich commented Jul 28, 2012

I've created a Gist containing all of the code necessary to reproduce the problem: https://gist.github.com/3193910

@carlescliment
Copy link

@carlescliment carlescliment commented Nov 8, 2012

Subscribing.

I'll try submitting the form with a $client->request('POST', $data).

Not optimal, but it should at least let me test the controller.

@sstok
Copy link
Contributor

@sstok sstok commented Feb 7, 2013

I was facing this problem to today, I actually needed to remove a row from the collection 😄

But found I little trick to make this work.

$form = $crawler->selectButton('save')->form();
$form->setValues(array(
    'customer_invoice_form[customer]' => 'C0001',
    'customer_invoice_form[address]'  => "274 Rose avenue US\n212-35 OKMontgomery",

    'customer_invoice_form[items][0][number]'        => 1,
    'customer_invoice_form[items][0][label]'         => 'Domainreg bar-foo.com',
    'customer_invoice_form[items][0][period][start]' => '01-01-2013',
    'customer_invoice_form[items][0][period][end]'   => '01-12-2013',
    'customer_invoice_form[items][0][price]'         => '20,00',
    'customer_invoice_form[items][0][taxPercent]'    => '21,10',
));

// Now do what ever you want with the $values.
$values = $form->getPhpValues();
unset($values['customer_invoice_form']['items'][1]);

$client->request($form->getMethod(), $form->getUri(), $values, $form->getPhpFiles());
//$client->submit($form);
@ste93cry
Copy link
Contributor

@ste93cry ste93cry commented Mar 14, 2013

I have the same problem: I'm using knockout to render a form client-side with javascript instead of rendering it with twig, however I can't submit any form which has inputs that don't exist. The problem is clear: the inputs are rendered client-side, so when I try to use the crawler to get them and change their values obviously it can't find them. There should be a way in the Symfony testing framework to submit data that isn't part of the form

@sstok
Copy link
Contributor

@sstok sstok commented Mar 15, 2013

@ste93cry Try my method ;)

@leftdevel
Copy link

@leftdevel leftdevel commented Mar 15, 2013

+1 @sstok. That is the way to go in phpunit.

@fnagel
Copy link
Contributor

@fnagel fnagel commented Feb 20, 2014

@sstok Is your workaround supposed to work in Symfony 2.3.x?

@fnagel
Copy link
Contributor

@fnagel fnagel commented Feb 20, 2014

Ok, here's another workaround:

$form = $crawler->filter('form .submit-button .btn-primary')->form();
$formData = array(
    'step2Type[positions][0][property1]' => '1',
    'step2Type[positions][0][property2]' => 'xyz',
);

$this->client->request($form->getMethod(), $form->getUri(), $form->getPhpValues(), $form->getPhpFiles(), array(), http_build_query($formData))
@gagarine
Copy link

@gagarine gagarine commented Jul 20, 2014

I have field than as formed with the name like
properties[0].value
properties[1].value

And no workarounds works.
I can't change the field name has it's on a service I don't control...

@wouterj
Copy link
Member

@wouterj wouterj commented Aug 11, 2014

This seems more like a mailinglist item than a bug/feature report afaics.

@jakzal
Copy link
Contributor

@jakzal jakzal commented May 12, 2015

re #3824

@placid2000
Copy link

@placid2000 placid2000 commented Jul 23, 2015

I've faced the same a few times now and ignored it ill now.. Still no solution there? The workarounds don't seem to work for me neither

@sstok
Copy link
Contributor

@sstok sstok commented Jul 23, 2015

properties[0].value
properties[1].value

Are property-paths, a property-path cannot be used for the DOMCrawler.

fnagel's solution works as it doesn't actually use the DOMCrawler but creates the request directly instead.

@alexislefebvre
Copy link
Contributor

@alexislefebvre alexislefebvre commented Mar 8, 2016

(moved to #3824 (comment))

@webmozart webmozart removed the Form label Mar 9, 2016
@webmozart webmozart changed the title [Form] Functional Testing Collection Form Fields Functional Testing Collection Form Fields Mar 9, 2016
@fabpot
Copy link
Member

@fabpot fabpot commented Sep 21, 2018

Closing as the pull request was closed in favor of some documentation in symfony/symfony-docs#6427

@fabpot fabpot closed this Sep 21, 2018
@lordelph
Copy link

@lordelph lordelph commented Oct 14, 2018

I've got an alternative approach which perhaps better mirrors what really happens - before obtaining the Symfony\Component\DomCrawler\Form modify the retrieved DOM to insert dynamically created form fields. Here's a helper function which illustrates the approach

    protected function addFormField(Crawler $crawler, $formName, $inputName, $inputType='text')
    {
        //create input element in same document
        $doc = $crawler->getNode(0)->ownerDocument;
        $input=$doc->createElement('input');
        $input->setAttribute('type', $inputType);
        $input->setAttribute('name', $inputName);

        //add input to form
        $formNode=$crawler->filter('form[name="'.$formName.'"]')->getNode(0);
        $formNode->appendChild($input);
    }

Then a functional test just needs to add any dynamic form elements it needs before calling form()

//add a dynamic collection field for a file upload
$this->addFormField($crawler, 'my_entity', 'my_entity[images][0][newImage]', 'file');

//get the form as normal
$form = $crawler->selectButton('Update')->form();

//this will now work!
$form['product_type[images][0][newImage]']->upload($filename);
@alexislefebvre
Copy link
Contributor

@alexislefebvre alexislefebvre commented Oct 20, 2018

@lordelph This is interesting, you could add it in the documentation as an alternative way to do the same thing as in symfony/symfony-docs#6427

lordelph added a commit to lordelph/symfony-docs that referenced this issue Oct 20, 2018
In response to suggestion in symfony/symfony#4124 (comment) this PR adds an alternative approach for testing forms which have dynamic collections. The suggestion is to manipulate the DOM before retrieving the Form object in a functional test.
lordelph added a commit to lordelph/symfony-docs that referenced this issue Oct 20, 2018
@lordelph
Copy link

@lordelph lordelph commented Oct 20, 2018

Added a PR here symfony/symfony-docs#10527

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

Successfully merging a pull request may close this issue.

None yet