Тесты формы: как отправить коллекцию в существующую форму?

Я использую два способа проверки своих форм:

Используя $form = …->form();

Затем задаем значения массива $form (точнее это объект \Symfony\Component\DomCrawler\Form):

Полный пример из документации:

$form = $crawler->selectButton('submit')->form();

// set some values
$form['name'] = 'Lucas';
$form['form_name[subject]'] = 'Hey there!';

// submit the form
$crawler = $client->submit($form);

Отправив данные POST напрямую:

Предыдущий код не работает с формами, управляющими коллекциями (полагающимися для полей, созданных Javascript), потому что он выдает ошибку, если поле не существует. Вот почему я также использую другой способ.

Полный пример из документации:

// Directly submit a form (but using the Crawler is easier!)
$client->request('POST', '/submit', array('name' => 'Fabien'));

Это решение — единственный известный мне способ тестирования форм, которые управляют коллекциями с полями, добавленными Javascript (см. ссылку на документацию выше). Но это второе решение сложнее использовать, потому что:

  • он не проверяет, какие поля существуют, это непрактично, когда мне нужно отправить форму с существующими полями and коллекция, которая опирается на поля, созданные динамически с помощью Javascript
  • требуется добавить форму _token вручную

Мой вопрос

Можно ли использовать синтаксис первого способа для определения существующих полей, а затем добавить новые динамически созданные поля со вторым синтаксисом?

Другими словами, я хотел бы иметь что-то вроде этого:

$form = $crawler->selectButton('submit')->form();

// set some values for the existing fields
$form['name'] = 'Lucas';
$form['form_name[subject]'] = 'Hey there!';

// submit the form with additional data
$crawler = $client->submit($form, array('name' => 'Fabien'));

Но я получаю эту ошибку:

Недоступное поле "имя"

И $form->get('name')->setData('Fabien'); вызывает ту же ошибку.

Этот пример не идеален, потому что в форме нет коллекции, но этого достаточно, чтобы показать вам мою проблему.

Я ищу способ избежать этой проверки, когда добавляю некоторые поля в существующую форму.


person A.L    schedule 23.09.2015    source источник
comment
Я думаю, это поможет вам в решении этой проблемы... дает недоступное поле"> stackoverflow.com/questions/15454760/   -  person Nandakumar    schedule 24.09.2015
comment
@NandaKumar спасибо, но это тот же синтаксис, что и в моем вопросе (раздел Путем отправки данных POST напрямую:).   -  person A.L    schedule 24.09.2015
comment
Не могли бы вы опубликовать html-форму, которую вы отображаете?   -  person Nandakumar    schedule 25.09.2015
comment
@NandaKumar: я хочу отправить значения для несуществующих полей, вы уверены, что это поможет вам увидеть форму?   -  person A.L    schedule 25.09.2015
comment
вам нужно добавить динамические элементы к узлам, прежде чем вы настроите их в коде... Пожалуйста, проверьте эту ссылку для справки api.symfony.com/2.4/Symfony/Component/DomCrawler/Crawler.html   -  person Nandakumar    schedule 29.09.2015
comment
@NandaKumar: спасибо, значит, мне следует использовать ->addNode(…), чтобы добавить узел в форму?   -  person A.L    schedule 29.09.2015
comment
Пожалуйста, проверьте эту тему Добавление содержимого symfony.com/doc/current /компоненты/   -  person Nandakumar    schedule 29.09.2015
comment
На GitHub продолжается обсуждение: github.com/symfony/symfony/issues/3824< /а>   -  person A.L    schedule 09.03.2016


Ответы (1)


Это можно сделать, вызвав слегка измененный код из submit():

// Get the form.
$form = $crawler->filter('button')->form();

// Merge existing values with new values.
$values = array_merge_recursive(
    $form->getPhpValues(),
    array(
        // New values.
        'FORM_NAME' => array(
            'COLLECTION_NAME' => array(
                array(
                    'FIELD_NAME_1' => 'a',
                    'FIELD_NAME_2' => '1',
                )
            )
        )
    )
);

// Submit the form with the existing and new values.
$crawler = $this->client->request($form->getMethod(), $form->getUri(), $values,
    $form->getPhpFiles());

Массив значений новостей в этом примере соответствует форме, где у вас есть поля с этими names:

<input type="…" name="FORM_NAME[COLLECTION_NAME][A_NUMBER][FIELD_NAME_1]" />
<input type="…" name="FORM_NAME[COLLECTION_NAME][A_NUMBER][FIELD_NAME_2]" />

Количество (индекс) полей не имеет значения, PHP объединит массивы и отправит данные, Symfony преобразует эти данные в соответствующие поля.

person A.L    schedule 18.03.2016