FileFieldTest.php 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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\Tests\Component\Form;
  11. use Symfony\Component\Form\FileField;
  12. use Symfony\Component\HttpFoundation\File\File;
  13. class FileFieldTest extends \PHPUnit_Framework_TestCase
  14. {
  15. public static $tmpFiles = array();
  16. protected static $tmpDir;
  17. protected $field;
  18. public static function setUpBeforeClass()
  19. {
  20. self::$tmpDir = sys_get_temp_dir();
  21. // we need a session ID
  22. @session_start();
  23. }
  24. protected function setUp()
  25. {
  26. $this->field = new FileField('file', array(
  27. 'secret' => '$secret$',
  28. 'tmp_dir' => self::$tmpDir,
  29. ));
  30. }
  31. protected function tearDown()
  32. {
  33. foreach (self::$tmpFiles as $key => $file) {
  34. @unlink($file);
  35. unset(self::$tmpFiles[$key]);
  36. }
  37. }
  38. public function createTmpFile($path)
  39. {
  40. self::$tmpFiles[] = $path;
  41. file_put_contents($path, 'foobar');
  42. }
  43. public function testSubmitUploadsNewFiles()
  44. {
  45. $tmpDir = realpath(self::$tmpDir);
  46. $tmpName = md5(session_id() . '$secret$' . '12345');
  47. $tmpPath = $tmpDir . DIRECTORY_SEPARATOR . $tmpName;
  48. $that = $this;
  49. $file = $this->getMock('Symfony\Component\HttpFoundation\File\UploadedFile', array(), array(), '', false);
  50. $file->expects($this->once())
  51. ->method('move')
  52. ->with($this->equalTo($tmpDir));
  53. $file->expects($this->once())
  54. ->method('rename')
  55. ->with($this->equalTo($tmpName))
  56. ->will($this->returnCallback(function ($directory) use ($that, $tmpPath) {
  57. $that->createTmpFile($tmpPath);
  58. }));
  59. $file->expects($this->any())
  60. ->method('getName')
  61. ->will($this->returnValue('original_name.jpg'));
  62. $this->field->submit(array(
  63. 'file' => $file,
  64. 'token' => '12345',
  65. 'original_name' => '',
  66. ));
  67. $this->assertTrue(file_exists($tmpPath));
  68. $this->assertEquals(array(
  69. 'file' => '',
  70. 'token' => '12345',
  71. 'original_name' => 'original_name.jpg',
  72. ), $this->field->getDisplayedData());
  73. $this->assertEquals($tmpPath, $this->field->getData());
  74. $this->assertFalse($this->field->isIniSizeExceeded());
  75. $this->assertFalse($this->field->isFormSizeExceeded());
  76. $this->assertTrue($this->field->isUploadComplete());
  77. }
  78. public function testSubmitKeepsUploadedFilesOnErrors()
  79. {
  80. $tmpPath = self::$tmpDir . '/' . md5(session_id() . '$secret$' . '12345');
  81. $this->createTmpFile($tmpPath);
  82. $this->field->submit(array(
  83. 'file' => '',
  84. 'token' => '12345',
  85. 'original_name' => 'original_name.jpg',
  86. ));
  87. $this->assertTrue(file_exists($tmpPath));
  88. $this->assertEquals(array(
  89. 'file' => '',
  90. 'token' => '12345',
  91. 'original_name' => 'original_name.jpg',
  92. ), $this->field->getDisplayedData());
  93. $this->assertEquals(realpath($tmpPath), realpath($this->field->getData()));
  94. }
  95. /**
  96. * @expectedException UnexpectedValueException
  97. */
  98. public function testSubmitFailsOnMissingMultipart()
  99. {
  100. $this->field->submit(array(
  101. 'file' => 'foo.jpg',
  102. 'token' => '12345',
  103. 'original_name' => 'original_name.jpg',
  104. ));
  105. }
  106. public function testSubmitKeepsOldFileIfNotOverwritten()
  107. {
  108. $oldPath = tempnam(sys_get_temp_dir(), 'FileFieldTest');
  109. $this->createTmpFile($oldPath);
  110. $this->field->setData($oldPath);
  111. $this->assertEquals($oldPath, $this->field->getData());
  112. $this->field->submit(array(
  113. 'file' => '',
  114. 'token' => '12345',
  115. 'original_name' => '',
  116. ));
  117. $this->assertTrue(file_exists($oldPath));
  118. $this->assertEquals(array(
  119. 'file' => '',
  120. 'token' => '12345',
  121. 'original_name' => '',
  122. ), $this->field->getDisplayedData());
  123. $this->assertEquals($oldPath, $this->field->getData());
  124. }
  125. public function testSubmitHandlesUploadErrIniSize()
  126. {
  127. $file = $this->getMock('Symfony\Component\HttpFoundation\File\UploadedFile', array(), array(), '', false);
  128. $file->expects($this->any())
  129. ->method('getError')
  130. ->will($this->returnValue(UPLOAD_ERR_INI_SIZE));
  131. $this->field->submit(array(
  132. 'file' => $file,
  133. 'token' => '12345',
  134. 'original_name' => ''
  135. ));
  136. $this->assertTrue($this->field->isIniSizeExceeded());
  137. }
  138. public function testSubmitHandlesUploadErrFormSize()
  139. {
  140. $file = $this->getMock('Symfony\Component\HttpFoundation\File\UploadedFile', array(), array(), '', false);
  141. $file->expects($this->any())
  142. ->method('getError')
  143. ->will($this->returnValue(UPLOAD_ERR_FORM_SIZE));
  144. $this->field->submit(array(
  145. 'file' => $file,
  146. 'token' => '12345',
  147. 'original_name' => ''
  148. ));
  149. $this->assertTrue($this->field->isFormSizeExceeded());
  150. }
  151. public function testSubmitHandlesUploadErrPartial()
  152. {
  153. $file = $this->getMock('Symfony\Component\HttpFoundation\File\UploadedFile', array(), array(), '', false);
  154. $file->expects($this->any())
  155. ->method('getError')
  156. ->will($this->returnValue(UPLOAD_ERR_PARTIAL));
  157. $this->field->submit(array(
  158. 'file' => $file,
  159. 'token' => '12345',
  160. 'original_name' => ''
  161. ));
  162. $this->assertFalse($this->field->isUploadComplete());
  163. }
  164. public function testSubmitThrowsExceptionOnUploadErrNoTmpDir()
  165. {
  166. $file = $this->getMock('Symfony\Component\HttpFoundation\File\UploadedFile', array(), array(), '', false);
  167. $file->expects($this->any())
  168. ->method('getError')
  169. ->will($this->returnValue(UPLOAD_ERR_NO_TMP_DIR));
  170. $this->setExpectedException('Symfony\Component\Form\Exception\FormException');
  171. $this->field->submit(array(
  172. 'file' => $file,
  173. 'token' => '12345',
  174. 'original_name' => ''
  175. ));
  176. }
  177. public function testSubmitThrowsExceptionOnUploadErrCantWrite()
  178. {
  179. $file = $this->getMock('Symfony\Component\HttpFoundation\File\UploadedFile', array(), array(), '', false);
  180. $file->expects($this->any())
  181. ->method('getError')
  182. ->will($this->returnValue(UPLOAD_ERR_CANT_WRITE));
  183. $this->setExpectedException('Symfony\Component\Form\Exception\FormException');
  184. $this->field->submit(array(
  185. 'file' => $file,
  186. 'token' => '12345',
  187. 'original_name' => ''
  188. ));
  189. }
  190. public function testSubmitThrowsExceptionOnUploadErrExtension()
  191. {
  192. $file = $this->getMock('Symfony\Component\HttpFoundation\File\UploadedFile', array(), array(), '', false);
  193. $file->expects($this->any())
  194. ->method('getError')
  195. ->will($this->returnValue(UPLOAD_ERR_EXTENSION));
  196. $this->setExpectedException('Symfony\Component\Form\Exception\FormException');
  197. $this->field->submit(array(
  198. 'file' => $file,
  199. 'token' => '12345',
  200. 'original_name' => ''
  201. ));
  202. }
  203. }