AbstractRequestHandlerTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Form\Tests;
  11. use PHPUnit\Framework\TestCase;
  12. use Symfony\Component\Form\FormError;
  13. use Symfony\Component\Form\FormFactory;
  14. use Symfony\Component\Form\Forms;
  15. use Symfony\Component\Form\RequestHandlerInterface;
  16. /**
  17. * @author Bernhard Schussek <bschussek@gmail.com>
  18. */
  19. abstract class AbstractRequestHandlerTest extends TestCase
  20. {
  21. /**
  22. * @var RequestHandlerInterface
  23. */
  24. protected $requestHandler;
  25. /**
  26. * @var FormFactory
  27. */
  28. protected $factory;
  29. protected $request;
  30. protected $serverParams;
  31. protected function setUp()
  32. {
  33. $this->serverParams = $this->getMockBuilder('Symfony\Component\Form\Util\ServerParams')->setMethods(array('getNormalizedIniPostMaxSize', 'getContentLength'))->getMock();
  34. $this->requestHandler = $this->getRequestHandler();
  35. $this->factory = Forms::createFormFactoryBuilder()->getFormFactory();
  36. $this->request = null;
  37. }
  38. public function methodExceptGetProvider()
  39. {
  40. return array(
  41. array('POST'),
  42. array('PUT'),
  43. array('DELETE'),
  44. array('PATCH'),
  45. );
  46. }
  47. public function methodProvider()
  48. {
  49. return array_merge(array(
  50. array('GET'),
  51. ), $this->methodExceptGetProvider());
  52. }
  53. /**
  54. * @dataProvider methodProvider
  55. */
  56. public function testSubmitIfNameInRequest($method)
  57. {
  58. $form = $this->getMockForm('param1', $method);
  59. $this->setRequestData($method, array(
  60. 'param1' => 'DATA',
  61. ));
  62. $form->expects($this->once())
  63. ->method('submit')
  64. ->with('DATA', 'PATCH' !== $method);
  65. $this->requestHandler->handleRequest($form, $this->request);
  66. }
  67. /**
  68. * @dataProvider methodProvider
  69. */
  70. public function testDoNotSubmitIfWrongRequestMethod($method)
  71. {
  72. $form = $this->getMockForm('param1', $method);
  73. $otherMethod = 'POST' === $method ? 'PUT' : 'POST';
  74. $this->setRequestData($otherMethod, array(
  75. 'param1' => 'DATA',
  76. ));
  77. $form->expects($this->never())
  78. ->method('submit');
  79. $this->requestHandler->handleRequest($form, $this->request);
  80. }
  81. /**
  82. * @dataProvider methodExceptGetProvider
  83. */
  84. public function testDoNoSubmitSimpleFormIfNameNotInRequestAndNotGetRequest($method)
  85. {
  86. $form = $this->getMockForm('param1', $method, false);
  87. $this->setRequestData($method, array(
  88. 'paramx' => array(),
  89. ));
  90. $form->expects($this->never())
  91. ->method('submit');
  92. $this->requestHandler->handleRequest($form, $this->request);
  93. }
  94. /**
  95. * @dataProvider methodExceptGetProvider
  96. */
  97. public function testDoNotSubmitCompoundFormIfNameNotInRequestAndNotGetRequest($method)
  98. {
  99. $form = $this->getMockForm('param1', $method, true);
  100. $this->setRequestData($method, array(
  101. 'paramx' => array(),
  102. ));
  103. $form->expects($this->never())
  104. ->method('submit');
  105. $this->requestHandler->handleRequest($form, $this->request);
  106. }
  107. public function testDoNotSubmitIfNameNotInRequestAndGetRequest()
  108. {
  109. $form = $this->getMockForm('param1', 'GET');
  110. $this->setRequestData('GET', array(
  111. 'paramx' => array(),
  112. ));
  113. $form->expects($this->never())
  114. ->method('submit');
  115. $this->requestHandler->handleRequest($form, $this->request);
  116. }
  117. /**
  118. * @dataProvider methodProvider
  119. */
  120. public function testSubmitFormWithEmptyNameIfAtLeastOneFieldInRequest($method)
  121. {
  122. $form = $this->getMockForm('', $method);
  123. $form->expects($this->any())
  124. ->method('all')
  125. ->will($this->returnValue(array(
  126. 'param1' => $this->getMockForm('param1'),
  127. 'param2' => $this->getMockForm('param2'),
  128. )));
  129. $this->setRequestData($method, $requestData = array(
  130. 'param1' => 'submitted value',
  131. 'paramx' => 'submitted value',
  132. ));
  133. $form->expects($this->once())
  134. ->method('submit')
  135. ->with($requestData, 'PATCH' !== $method);
  136. $this->requestHandler->handleRequest($form, $this->request);
  137. }
  138. /**
  139. * @dataProvider methodProvider
  140. */
  141. public function testDoNotSubmitFormWithEmptyNameIfNoFieldInRequest($method)
  142. {
  143. $form = $this->getMockForm('', $method);
  144. $form->expects($this->any())
  145. ->method('all')
  146. ->will($this->returnValue(array(
  147. 'param1' => $this->getMockForm('param1'),
  148. 'param2' => $this->getMockForm('param2'),
  149. )));
  150. $this->setRequestData($method, array(
  151. 'paramx' => 'submitted value',
  152. ));
  153. $form->expects($this->never())
  154. ->method('submit');
  155. $this->requestHandler->handleRequest($form, $this->request);
  156. }
  157. /**
  158. * @dataProvider methodExceptGetProvider
  159. */
  160. public function testMergeParamsAndFiles($method)
  161. {
  162. $form = $this->getMockForm('param1', $method);
  163. $file = $this->getMockFile();
  164. $this->setRequestData($method, array(
  165. 'param1' => array(
  166. 'field1' => 'DATA',
  167. ),
  168. ), array(
  169. 'param1' => array(
  170. 'field2' => $file,
  171. ),
  172. ));
  173. $form->expects($this->once())
  174. ->method('submit')
  175. ->with(array(
  176. 'field1' => 'DATA',
  177. 'field2' => $file,
  178. ), 'PATCH' !== $method);
  179. $this->requestHandler->handleRequest($form, $this->request);
  180. }
  181. /**
  182. * @dataProvider methodExceptGetProvider
  183. */
  184. public function testParamTakesPrecedenceOverFile($method)
  185. {
  186. $form = $this->getMockForm('param1', $method);
  187. $file = $this->getMockFile();
  188. $this->setRequestData($method, array(
  189. 'param1' => 'DATA',
  190. ), array(
  191. 'param1' => $file,
  192. ));
  193. $form->expects($this->once())
  194. ->method('submit')
  195. ->with('DATA', 'PATCH' !== $method);
  196. $this->requestHandler->handleRequest($form, $this->request);
  197. }
  198. /**
  199. * @dataProvider methodExceptGetProvider
  200. */
  201. public function testSubmitFileIfNoParam($method)
  202. {
  203. $form = $this->getMockForm('param1', $method);
  204. $file = $this->getMockFile();
  205. $this->setRequestData($method, array(
  206. 'param1' => null,
  207. ), array(
  208. 'param1' => $file,
  209. ));
  210. $form->expects($this->once())
  211. ->method('submit')
  212. ->with($file, 'PATCH' !== $method);
  213. $this->requestHandler->handleRequest($form, $this->request);
  214. }
  215. /**
  216. * @dataProvider methodExceptGetProvider
  217. */
  218. public function testSubmitMultipleFiles($method)
  219. {
  220. $form = $this->getMockForm('param1', $method);
  221. $file = $this->getMockFile();
  222. $this->setRequestData($method, array(
  223. 'param1' => null,
  224. ), array(
  225. 'param2' => $this->getMockFile('2'),
  226. 'param1' => $file,
  227. 'param3' => $this->getMockFile('3'),
  228. ));
  229. $form->expects($this->once())
  230. ->method('submit')
  231. ->with($file, 'PATCH' !== $method);
  232. $this->requestHandler->handleRequest($form, $this->request);
  233. }
  234. /**
  235. * @dataProvider methodExceptGetProvider
  236. */
  237. public function testSubmitFileWithNamelessForm($method)
  238. {
  239. $form = $this->getMockForm(null, $method);
  240. $file = $this->getMockFile();
  241. $this->setRequestData($method, array(
  242. '' => null,
  243. ), array(
  244. '' => $file,
  245. ));
  246. $form->expects($this->once())
  247. ->method('submit')
  248. ->with($file, 'PATCH' !== $method);
  249. $this->requestHandler->handleRequest($form, $this->request);
  250. }
  251. /**
  252. * @dataProvider getPostMaxSizeFixtures
  253. */
  254. public function testAddFormErrorIfPostMaxSizeExceeded($contentLength, $iniMax, $shouldFail, array $errorParams = array())
  255. {
  256. $this->serverParams->expects($this->once())
  257. ->method('getContentLength')
  258. ->will($this->returnValue($contentLength));
  259. $this->serverParams->expects($this->any())
  260. ->method('getNormalizedIniPostMaxSize')
  261. ->will($this->returnValue($iniMax));
  262. $options = array('post_max_size_message' => 'Max {{ max }}!');
  263. $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType', null, $options);
  264. $this->setRequestData('POST', array(), array());
  265. $this->requestHandler->handleRequest($form, $this->request);
  266. if ($shouldFail) {
  267. $error = new FormError($options['post_max_size_message'], null, $errorParams);
  268. $error->setOrigin($form);
  269. $this->assertEquals(array($error), iterator_to_array($form->getErrors()));
  270. $this->assertTrue($form->isSubmitted());
  271. } else {
  272. $this->assertCount(0, $form->getErrors());
  273. $this->assertFalse($form->isSubmitted());
  274. }
  275. }
  276. public function getPostMaxSizeFixtures()
  277. {
  278. return array(
  279. array(pow(1024, 3) + 1, '1G', true, array('{{ max }}' => '1G')),
  280. array(pow(1024, 3), '1G', false),
  281. array(pow(1024, 2) + 1, '1M', true, array('{{ max }}' => '1M')),
  282. array(pow(1024, 2), '1M', false),
  283. array(1024 + 1, '1K', true, array('{{ max }}' => '1K')),
  284. array(1024, '1K', false),
  285. array(null, '1K', false),
  286. array(1024, '', false),
  287. array(1024, 0, false),
  288. );
  289. }
  290. public function testUploadedFilesAreAccepted()
  291. {
  292. $this->assertTrue($this->requestHandler->isFileUpload($this->getMockFile()));
  293. }
  294. public function testInvalidFilesAreRejected()
  295. {
  296. $this->assertFalse($this->requestHandler->isFileUpload($this->getInvalidFile()));
  297. }
  298. abstract protected function setRequestData($method, $data, $files = array());
  299. abstract protected function getRequestHandler();
  300. abstract protected function getMockFile($suffix = '');
  301. abstract protected function getInvalidFile();
  302. protected function getMockForm($name, $method = null, $compound = true)
  303. {
  304. $config = $this->getMockBuilder('Symfony\Component\Form\FormConfigInterface')->getMock();
  305. $config->expects($this->any())
  306. ->method('getMethod')
  307. ->will($this->returnValue($method));
  308. $config->expects($this->any())
  309. ->method('getCompound')
  310. ->will($this->returnValue($compound));
  311. $form = $this->getMockBuilder('Symfony\Component\Form\Test\FormInterface')->getMock();
  312. $form->expects($this->any())
  313. ->method('getName')
  314. ->will($this->returnValue($name));
  315. $form->expects($this->any())
  316. ->method('getConfig')
  317. ->will($this->returnValue($config));
  318. return $form;
  319. }
  320. }