TLDR:
How to write an integration test for a FilePostRedirectGet form submission request?
In my application I have a multi-page form with a file element in it. Originally the controller code was (psuedo code - all multi-page stuff removed):
$form = new MyForm(); if($this->getRequest()->isPost()) { if($form->isValid($this->getRequest()->getPost()) { //move file to new home and save post to database. return $this->redirect()->toRoute('admin/cms/edit'); } } return new ViewModel(['form' => $form]);
Very basically, if the form was valid it would save the form details and perform a redirect (typically the edit version of the page). If the form was not valid, it would just show the form again with the appropriate error messages.
The problem with this approach, is if one of the form elements fails validation, the file input will lose its value and the user will need to re-upload their file. To get around this, I changed to the FPRG approach:
$form = new MyForm(); /* @var $prg FilePostRedirectGet */ $prg = $this->filePostRedirectGet($form, $this->url()->fromRoute($this->routeMatch, ['action' => $this->action, 'id' => $id], ['query' => ['page' => $page]]), true); if ($prg instanceof Response) { return $prg; // Return PRG redirect response } elseif ($prg !== false) { //move file to new home and save post to database. return $this->redirect()->toRoute('admin/cms/edit'); } return new ViewModel(['form' => $form]);
The FilePostRedirectGet
plugin saves the post data in a session, redirects to the same page, validates the form and, if valid, redirects to the success/edit page - otherwise just show the form with errors. The benefits of this approach is that the file input retains its value regardless of any other failed elements.
The problem is, how to write an integration test for this request?
Originally, there was only one redirect (on success) so I could test for that (model mocking stuff removed for brevity):
/** * Redirect to next page after form submission. */ public function testAddActionRedirectsAfterValidPost() { $postData = $this->_postData(); $this->dispatch('http://localhost/admin/cms/add', 'POST', $postData); $this->assertResponseStatusCode(302); $this->assertRedirectTo('http://localhost/admin/cms/edit/13'); return $postData; }
However, due to the multiple redirects, I cannot use this method of testing if the request was successful or not.
How to write an integration test for this request?
0 comments:
Post a Comment