FileFieldTest.php 6.9 KB

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