[BUGFIX] Unit tests call parent::tearDown()
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Http / UploadedFileTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Unit\Http;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Http\Stream;
18 use TYPO3\CMS\Core\Http\UploadedFile;
19 use TYPO3\CMS\Core\Utility\GeneralUtility;
20
21 /**
22 * Testcase for \TYPO3\CMS\Core\Http\UploadedFile
23 *
24 * Adapted from https://github.com/phly/http/
25 */
26 class UploadedFileTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
27 {
28 protected $tmpFile;
29
30 protected function setUp()
31 {
32 $this->tmpFile = null;
33 }
34
35 protected function tearDown()
36 {
37 if (is_scalar($this->tmpFile) && file_exists($this->tmpFile)) {
38 unlink($this->tmpFile);
39 }
40 parent::tearDown();
41 }
42
43 /**
44 * @return array
45 */
46 public function invalidStreamsDataProvider()
47 {
48 return [
49 'null' => [null],
50 'true' => [true],
51 'false' => [false],
52 'int' => [1],
53 'float' => [1.1],
54 /* Have not figured out a valid way to test an invalid path yet; null byte injection
55 * appears to get caught by fopen()
56 'invalid-path' => [ ('WIN' === strtoupper(substr(PHP_OS, 0, 3))) ? '[:]' : 'foo' . chr(0) ],
57 */
58 'array' => [['filename']],
59 'object' => [(object) ['filename']],
60 ];
61 }
62
63 /**
64 * @dataProvider invalidStreamsDataProvider
65 * @test
66 */
67 public function constructorRaisesExceptionOnInvalidStreamOrFile($streamOrFile)
68 {
69 $this->expectException(\InvalidArgumentException::class);
70 new UploadedFile($streamOrFile, 0, UPLOAD_ERR_OK);
71 }
72
73 /**
74 * @return array
75 */
76 public function invalidSizesDataProvider()
77 {
78 return [
79 'null' => [null],
80 'true' => [true],
81 'false' => [false],
82 'float' => [1.1],
83 'string' => ['1'],
84 'array' => [[1]],
85 'object' => [(object) [1]],
86 ];
87 }
88
89 /**
90 * @dataProvider invalidSizesDataProvider
91 * @test
92 */
93 public function constructorRaisesExceptionOnInvalidSize($size)
94 {
95 $this->expectException(\InvalidArgumentException::class);
96 $this->expectExceptionCode(1436717302);
97 new UploadedFile(fopen('php://temp', 'wb+'), $size, UPLOAD_ERR_OK);
98 }
99
100 /**
101 * @return array
102 */
103 public function invalidErrorStatusesDataProvider()
104 {
105 return [
106 'null' => [null],
107 'true' => [true],
108 'false' => [false],
109 'float' => [1.1],
110 'string' => ['1'],
111 'array' => [[1]],
112 'object' => [(object) [1]],
113 'negative' => [-1],
114 'too-big' => [9],
115 ];
116 }
117
118 /**
119 * @dataProvider invalidErrorStatusesDataProvider
120 * @test
121 */
122 public function constructorRaisesExceptionOnInvalidErrorStatus($status)
123 {
124 $this->expectException(\InvalidArgumentException::class);
125 $this->expectExceptionCode(1436717303);
126 new UploadedFile(fopen('php://temp', 'wb+'), 0, $status);
127 }
128
129 /**
130 * @return array
131 */
132 public function invalidFilenamesAndMediaTypesDataProvider()
133 {
134 return [
135 'true' => [true],
136 'false' => [false],
137 'int' => [1],
138 'float' => [1.1],
139 'array' => [['string']],
140 'object' => [(object) ['string']],
141 ];
142 }
143
144 /**
145 * @dataProvider invalidFilenamesAndMediaTypesDataProvider
146 * @test
147 */
148 public function constructorRaisesExceptionOnInvalidClientFilename($filename)
149 {
150 $this->expectException(\InvalidArgumentException::class);
151 $this->expectExceptionCode(1436717304);
152 new UploadedFile(fopen('php://temp', 'wb+'), 0, UPLOAD_ERR_OK, $filename);
153 }
154
155 /**
156 * @dataProvider invalidFilenamesAndMediaTypesDataProvider
157 * @test
158 */
159 public function constructorRaisesExceptionOnInvalidClientMediaType($mediaType)
160 {
161 $this->expectException(\InvalidArgumentException::class);
162 $this->expectExceptionCode(1436717305);
163 new UploadedFile(fopen('php://temp', 'wb+'), 0, UPLOAD_ERR_OK, 'foobar.baz', $mediaType);
164 }
165
166 /**
167 * @test
168 */
169 public function getStreamReturnsOriginalStreamObject()
170 {
171 $stream = new Stream('php://temp');
172 $upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
173 $this->assertSame($stream, $upload->getStream());
174 }
175
176 /**
177 * @test
178 */
179 public function getStreamReturnsWrappedPhpStream()
180 {
181 $stream = fopen('php://temp', 'wb+');
182 $upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
183 $uploadStream = $upload->getStream()->detach();
184 $this->assertSame($stream, $uploadStream);
185 }
186
187 /**
188 * @test
189 */
190 public function getStreamReturnsStreamForFile()
191 {
192 $this->tmpFile = $stream = tempnam(sys_get_temp_dir(), 'phly');
193 $upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
194 $uploadStream = $upload->getStream();
195 $r = new \ReflectionProperty($uploadStream, 'stream');
196 $r->setAccessible(true);
197 $this->assertSame($stream, $r->getValue($uploadStream));
198 }
199
200 /**
201 * @test
202 */
203 public function moveToMovesFileToDesignatedPath()
204 {
205 $stream = new Stream('php://temp', 'wb+');
206 $stream->write('Foo bar!');
207 $upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
208
209 $this->tmpFile = $to = GeneralUtility::tempnam('psr7');
210 $upload->moveTo($to);
211 $this->assertTrue(file_exists($to));
212 $contents = file_get_contents($to);
213 $this->assertEquals($stream->__toString(), $contents);
214 }
215
216 /**
217 * @return array
218 */
219 public function invalidMovePathsDataProvider()
220 {
221 return [
222 'null' => [null],
223 'true' => [true],
224 'false' => [false],
225 'int' => [1],
226 'float' => [1.1],
227 'empty' => [''],
228 'array' => [['filename']],
229 'object' => [(object) ['filename']],
230 ];
231 }
232
233 /**
234 * @dataProvider invalidMovePathsDataProvider
235 * @test
236 */
237 public function moveToRaisesExceptionForInvalidPath($path)
238 {
239 $stream = new Stream('php://temp', 'wb+');
240 $stream->write('Foo bar!');
241 $upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
242
243 $this->tmpFile = $path;
244 $this->expectException(\InvalidArgumentException::class);
245 $this->expectExceptionCode(1436717307);
246 $upload->moveTo($path);
247 }
248
249 /**
250 * @test
251 */
252 public function moveToCannotBeCalledMoreThanOnce()
253 {
254 $stream = new Stream('php://temp', 'wb+');
255 $stream->write('Foo bar!');
256 $upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
257
258 $this->tmpFile = $to = GeneralUtility::tempnam('psr7');
259 $upload->moveTo($to);
260 $this->assertTrue(file_exists($to));
261
262 $this->expectException(\RuntimeException::class);
263 $this->expectExceptionCode(1436717308);
264 $upload->moveTo($to);
265 }
266
267 /**
268 * @test
269 */
270 public function getGetStreamRaisesExceptionAfterMove()
271 {
272 $stream = new Stream('php://temp', 'wb+');
273 $stream->write('Foo bar!');
274 $upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
275
276 $this->tmpFile = $to = GeneralUtility::tempnam('psr7');
277 $upload->moveTo($to);
278 $this->assertTrue(file_exists($to));
279
280 $this->expectException(\RuntimeException::class);
281 $this->expectExceptionCode(1436717306);
282 $upload->getStream();
283 }
284 }