如何使用symfony 2.3在WebTestCase中提交无效的选择选项


How to submit an invalid select option in WebTestCase with symfony 2.3

我正在尝试在symfony 2.3中测试具有选择输入的表单...以及文件上传(Enctype Multipart/form-data)

选择输入如下...

  • 这是必填字段。
  • 有 3 个选项 [1, 2, 3]

使用DomCrawler我选择表单

$form = $crawler->selectButton->('Update')->form()

然后尝试将选择的值设置为

$form['select'] = null$form['select'] = ssjksjkajsdfj

DomCrawler 中有一个内部验证系统,如果我这样做,它会返回以下错误。

InvalidArgumentException: Input "select" cannot take "ssjksjkajsdfj" as a value (possible values: 1, 2, 3).

在symfony 2.4及更高版本中,DomCrawler/Form中有一个叫做disableValidation()的神奇方法,效果很好。不幸的是,由于某些依赖项需要 2.3 我无法升级

我也尝试直接使用$client->Request()方法

$post_data = '------WebKitFormBoundaryi7fAxO2jrDFTmxef
Content-Disposition: form-data; name="select"
ssjksjkajsdfj
------WebKitFormBoundaryi7fAxO2jrDFTmxef--';
        $client->request(
            'POST',
            $form->getUri(),
            array(),
            array(),
            array(
                'CONTENT_TYPE' => 'multipart/form-data; boundary=----WebKitFormBoundaryi7fAxO2jrDFTmxef',
            ),
            $post_data
        );

但是symfony似乎不知道/关心表单,只是返回一个常规表单 没有任何错误消息,表单处理程序出于某种原因不会验证表单。

这是控制器中的更新操作

public function updateAction(Request $request, $id)
{
    $em = $this->getDoctrine()->getManager();
    $entity = $em->getRepository('CoyoteAdBundle:Ad')->find($id);
    if (!$entity) {
        throw $this->createNotFoundException('Unable to find Ad entity.');
    }
    $old_entity = $entity;
    $editForm = $this->createEditForm($entity);
    $editForm->handleRequest($request);
    if ($editForm->isValid()) {
        $this->archiveImage($old_entity);
        $entity->upload();
        $em->flush();
        $this->addSuccessFlash('Ad has been updated successfully!');
        return $this->redirect($this->generateUrl('ad_show', array('id' => $id)));
    }
    return $this->render('CoyoteAdBundle:Ad:edit.html.twig', array(
        'entity'      => $entity,
        'form'   => $editForm->createView(),
    ));
}

在这里我发现了一个确切的问题...使用Symfony DomCrawler在选择输入中选择不可能的值

但答案不是我想要的。我想测试并确保服务器将返回 200 以及一条消息,让用户知道他们正在绑定做什么是不可能的。

PS:我可以在铬中与邮递员达到预期的结果。

我不知道

SF 2.3中有任何方法可以disableValidation。但是,我认为发送虚假请求应该可以解决问题。我也认为您使用请求方法的方式不正确。查看 2.3 SF 版本的文档,您有一个有关如何伪造请求的示例:

// Form submission with a file upload
use Symfony'Component'HttpFoundation'File'UploadedFile;
$photo = new UploadedFile(
    '/path/to/photo.jpg',
    'photo.jpg',
    'image/jpeg',
    123
);// Fake photo upload if you like, if not, just send the select value.
$client->request(
    'POST',
    '/submit',// valid route
    array('select' => 'ssjksjkajsdfj'),// Substitute here the name of your select and the value you want to send
    array('photo' => $photo)
);

它应该发送请求,如果一切正常,控制器应该回答 200 和错误。

希望对您有所帮助。

更新

好的,这里有几件事:CSRF 很重要,请求中参数的格式也很重要。

由于您的表单使用的是 CSRF,因此您应该在请求中发送它,否则它将失败并将您重定向到"空"表单。此外,请求必须以正确的格式发送数据。假设表单生成的代码命名表单中的输入my_form[name]您应该相应地在请求中创建它们:

$csrfToken = $client->getContainer()->get('form.csrf_provider')->generateCsrfToken('my_form');// Generate CSRF for my_form
        $crawler = $client->request(
                'POST', 
                '/ajax/register', // valid route
                array(
            'my_form' => array(// form accepts params in form my_form[name]
                '_token' => $csrfToken,
                'select' => 'asdfasdf',// select I want to send invalid value
                'photo' => $photo, // the uploaded photo
                'whatever' => 'whatever', // rest of required parameters.
            ),
        ));