[CLEANUP] Ensure variables initalized and fix code smell
[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 }
41
42 /**
43 * @return array
44 */
45 public function invalidStreamsDataProvider()
46 {
47 return [
48 'null' => [null],
49 'true' => [true],
50 'false' => [false],
51 'int' => [1],
52 'float' => [1.1],
53 /* Have not figured out a valid way to test an invalid path yet; null byte injection
54 * appears to get caught by fopen()
55 'invalid-path' => [ ('WIN' === strtoupper(substr(PHP_OS, 0, 3))) ? '[:]' : 'foo' . chr(0) ],
56 */
57 'array' => [['filename']],
58 'object' => [(object) ['filename']],
59 ];
60 }
61
62 /**
63 * @dataProvider invalidStreamsDataProvider
64 * @test
65 */
66 public function constructorRaisesExceptionOnInvalidStreamOrFile($streamOrFile)
67 {
68 $this->expectException(\InvalidArgumentException::class);
69 new UploadedFile($streamOrFile, 0, UPLOAD_ERR_OK);
70 }
71
72 /**
73 * @return array
74 */
75 public function invalidSizesDataProvider()
76 {
77 return [
78 'null' => [null],
79 'true' => [true],
80 'false' => [false],
81 'float' => [1.1],
82 'string' => ['1'],
83 'array' => [[1]],
84 'object' => [(object) [1]],
85 ];
86 }
87
88 /**
89 * @dataProvider invalidSizesDataProvider
90 * @test
91 */
92 public function constructorRaisesExceptionOnInvalidSize($size)
93 {
94 $this->expectException(\InvalidArgumentException::class);
95 $this->expectExceptionCode(1436717302);
96 new UploadedFile(fopen('php://temp', 'wb+'), $size, UPLOAD_ERR_OK);
97 }
98
99 /**
100 * @return array
101 */
102 public function invalidErrorStatusesDataProvider()
103 {
104 return [
105 'null' => [null],
106 'true' => [true],
107 'false' => [false],
108 'float' => [1.1],
109 'string' => ['1'],
110 'array' => [[1]],
111 'object' => [(object) [1]],
112 'negative' => [-1],
113 'too-big' => [9],
114 ];
115 }
116
117 /**
118 * @dataProvider invalidErrorStatusesDataProvider
119 * @test
120 */
121 public function constructorRaisesExceptionOnInvalidErrorStatus($status)
122 {
123 $this->expectException(\InvalidArgumentException::class);
124 $this->expectExceptionCode(1436717303);
125 new UploadedFile(fopen('php://temp', 'wb+'), 0, $status);
126 }
127
128 /**
129 * @return array
130 */
131 public function invalidFilenamesAndMediaTypesDataProvider()
132 {
133 return [
134 'true' => [true],
135 'false' => [false],
136 'int' => [1],
137 'float' => [1.1],
138 'array' => [['string']],
139 'object' => [(object) ['string']],
140 ];
141 }
142
143 /**
144 * @dataProvider invalidFilenamesAndMediaTypesDataProvider
145 * @test
146 */
147 public function constructorRaisesExceptionOnInvalidClientFilename($filename)
148 {
149 $this->expectException(\InvalidArgumentException::class);
150 $this->expectExceptionCode(1436717304);
151 new UploadedFile(fopen('php://temp', 'wb+'), 0, UPLOAD_ERR_OK, $filename);
152 }
153
154 /**
155 * @dataProvider invalidFilenamesAndMediaTypesDataProvider
156 * @test
157 */
158 public function constructorRaisesExceptionOnInvalidClientMediaType($mediaType)
159 {
160 $this->expectException(\InvalidArgumentException::class);
161 $this->expectExceptionCode(1436717305);
162 new UploadedFile(fopen('php://temp', 'wb+'), 0, UPLOAD_ERR_OK, 'foobar.baz', $mediaType);
163 }
164
165 /**
166 * @test
167 */
168 public function getStreamReturnsOriginalStreamObject()
169 {
170 $stream = new Stream('php://temp');
171 $upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
172 $this->assertSame($stream, $upload->getStream());
173 }
174
175 /**
176 * @test
177 */
178 public function getStreamReturnsWrappedPhpStream()
179 {
180 $stream = fopen('php://temp', 'wb+');
181 $upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
182 $uploadStream = $upload->getStream()->detach();
183 $this->assertSame($stream, $uploadStream);
184 }
185
186 /**
187 * @test
188 */
189 public function getStreamReturnsStreamForFile()
190 {
191 $this->tmpFile = $stream = tempnam(sys_get_temp_dir(), 'phly');
192 $upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
193 $uploadStream = $upload->getStream();
194 $r = new \ReflectionProperty($uploadStream, 'stream');
195 $r->setAccessible(true);
196 $this->assertSame($stream, $r->getValue($uploadStream));
197 }
198
199 /**
200 * @test
201 */
202 public function moveToMovesFileToDesignatedPath()
203 {
204 $stream = new Stream('php://temp', 'wb+');
205 $stream->write('Foo bar!');
206 $upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
207
208 $this->tmpFile = $to = GeneralUtility::tempnam('psr7');
209 $upload->moveTo($to);
210 $this->assertTrue(file_exists($to));
211 $contents = file_get_contents($to);
212 $this->assertEquals($stream->__toString(), $contents);
213 }
214
215 /**
216 * @return array
217 */
218 public function invalidMovePathsDataProvider()
219 {
220 return [
221 'null' => [null],
222 'true' => [true],
223 'false' => [false],
224 'int' => [1],
225 'float' => [1.1],
226 'empty' => [''],
227 'array' => [['filename']],
228 'object' => [(object) ['filename']],
229 ];
230 }
231
232 /**
233 * @dataProvider invalidMovePathsDataProvider
234 * @test
235 */
236 public function moveToRaisesExceptionForInvalidPath($path)
237 {
238 $stream = new Stream('php://temp', 'wb+');
239 $stream->write('Foo bar!');
240 $upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
241
242 $this->tmpFile = $path;
243 $this->expectException(\InvalidArgumentException::class);
244 $this->expectExceptionCode(1436717307);
245 $upload->moveTo($path);
246 }
247
248 /**
249 * @test
250 */
251 public function moveToCannotBeCalledMoreThanOnce()
252 {
253 $stream = new Stream('php://temp', 'wb+');
254 $stream->write('Foo bar!');
255 $upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
256
257 $this->tmpFile = $to = GeneralUtility::tempnam('psr7');
258 $upload->moveTo($to);
259 $this->assertTrue(file_exists($to));
260
261 $this->expectException(\RuntimeException::class);
262 $this->expectExceptionCode(1436717308);
263 $upload->moveTo($to);
264 }
265
266 /**
267 * @test
268 */
269 public function getGetStreamRaisesExceptionAfterMove()
270 {
271 $stream = new Stream('php://temp', 'wb+');
272 $stream->write('Foo bar!');
273 $upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
274
275 $this->tmpFile = $to = GeneralUtility::tempnam('psr7');
276 $upload->moveTo($to);
277 $this->assertTrue(file_exists($to));
278
279 $this->expectException(\RuntimeException::class);
280 $this->expectExceptionCode(1436717306);
281 $upload->getStream();
282 }
283 }