FileFieldTest.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien.potencier@symfony-project.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('getOriginalName')
  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. public function testSubmitKeepsOldFileIfNotOverwritten()
  96. {
  97. $oldPath = tempnam(sys_get_temp_dir(), 'FileFieldTest');
  98. $this->createTmpFile($oldPath);
  99. $this->field->setData($oldPath);
  100. $this->assertEquals($oldPath, $this->field->getData());
  101. $this->field->submit(array(
  102. 'file' => '',
  103. 'token' => '12345',
  104. 'original_name' => '',
  105. ));
  106. $this->assertTrue(file_exists($oldPath));
  107. $this->assertEquals(array(
  108. 'file' => '',
  109. 'token' => '12345',
  110. 'original_name' => '',
  111. ), $this->field->getDisplayedData());
  112. $this->assertEquals($oldPath, $this->field->getData());
  113. }
  114. public function testSubmitHandlesUploadErrIniSize()
  115. {
  116. $file = $this->getMock('Symfony\Component\HttpFoundation\File\UploadedFile', array(), array(), '', false);
  117. $file->expects($this->any())
  118. ->method('getError')
  119. ->will($this->returnValue(UPLOAD_ERR_INI_SIZE));
  120. $this->field->submit(array(
  121. 'file' => $file,
  122. 'token' => '12345',
  123. 'original_name' => ''
  124. ));
  125. $this->assertTrue($this->field->isIniSizeExceeded());
  126. }
  127. public function testSubmitHandlesUploadErrFormSize()
  128. {
  129. $file = $this->getMock('Symfony\Component\HttpFoundation\File\UploadedFile', array(), array(), '', false);
  130. $file->expects($this->any())
  131. ->method('getError')
  132. ->will($this->returnValue(UPLOAD_ERR_FORM_SIZE));
  133. $this->field->submit(array(
  134. 'file' => $file,
  135. 'token' => '12345',
  136. 'original_name' => ''
  137. ));
  138. $this->assertTrue($this->field->isFormSizeExceeded());
  139. }
  140. public function testSubmitHandlesUploadErrPartial()
  141. {
  142. $file = $this->getMock('Symfony\Component\HttpFoundation\File\UploadedFile', array(), array(), '', false);
  143. $file->expects($this->any())
  144. ->method('getError')
  145. ->will($this->returnValue(UPLOAD_ERR_PARTIAL));
  146. $this->field->submit(array(
  147. 'file' => $file,
  148. 'token' => '12345',
  149. 'original_name' => ''
  150. ));
  151. $this->assertFalse($this->field->isUploadComplete());
  152. }
  153. public function testSubmitThrowsExceptionOnUploadErrNoTmpDir()
  154. {
  155. $file = $this->getMock('Symfony\Component\HttpFoundation\File\UploadedFile', array(), array(), '', false);
  156. $file->expects($this->any())
  157. ->method('getError')
  158. ->will($this->returnValue(UPLOAD_ERR_NO_TMP_DIR));
  159. $this->setExpectedException('Symfony\Component\Form\Exception\FormException');
  160. $this->field->submit(array(
  161. 'file' => $file,
  162. 'token' => '12345',
  163. 'original_name' => ''
  164. ));
  165. }
  166. public function testSubmitThrowsExceptionOnUploadErrCantWrite()
  167. {
  168. $file = $this->getMock('Symfony\Component\HttpFoundation\File\UploadedFile', array(), array(), '', false);
  169. $file->expects($this->any())
  170. ->method('getError')
  171. ->will($this->returnValue(UPLOAD_ERR_CANT_WRITE));
  172. $this->setExpectedException('Symfony\Component\Form\Exception\FormException');
  173. $this->field->submit(array(
  174. 'file' => $file,
  175. 'token' => '12345',
  176. 'original_name' => ''
  177. ));
  178. }
  179. public function testSubmitThrowsExceptionOnUploadErrExtension()
  180. {
  181. $file = $this->getMock('Symfony\Component\HttpFoundation\File\UploadedFile', array(), array(), '', false);
  182. $file->expects($this->any())
  183. ->method('getError')
  184. ->will($this->returnValue(UPLOAD_ERR_EXTENSION));
  185. $this->setExpectedException('Symfony\Component\Form\Exception\FormException');
  186. $this->field->submit(array(
  187. 'file' => $file,
  188. 'token' => '12345',
  189. 'original_name' => ''
  190. ));
  191. }
  192. }