3 namespace Wikimedia\ParamValidator\Util
;
5 require_once __DIR__
. '/UploadedFileTestBase.php';
7 use Psr\Http\Message\StreamInterface
;
11 * @covers Wikimedia\ParamValidator\Util\UploadedFile
13 class UploadedFileTest
extends UploadedFileTestBase
{
15 public function testGetStream() {
16 $filename = $this->makeTemp( __FUNCTION__
);
18 $file = new UploadedFile( [ 'error' => UPLOAD_ERR_OK
, 'tmp_name' => $filename ], false );
20 // getStream() fails for non-OK uploads
26 UPLOAD_ERR_NO_TMP_DIR
,
27 UPLOAD_ERR_CANT_WRITE
,
31 $file2 = new UploadedFile( [ 'error' => $code, 'tmp_name' => $filename ], false );
34 $this->fail( 'Expected exception not thrown' );
35 } catch ( \PHPUnit\Framework\AssertionFailedError
$ex ) {
37 } catch ( RuntimeException
$ex ) {
42 $stream = $file->getStream();
43 $this->assertInstanceOf( StreamInterface
::class, $stream );
45 $this->assertSame( 'foobar', $stream->getContents() );
47 // Second call also works
48 $this->assertInstanceOf( StreamInterface
::class, $file->getStream() );
50 // getStream() throws after move, and the stream is invalidated too
51 $file->moveTo( $filename . '.xxx' );
55 $this->fail( 'Expected exception not thrown' );
56 } catch ( \PHPUnit\Framework\AssertionFailedError
$ex ) {
58 } catch ( RuntimeException
$ex ) {
59 $this->assertSame( 'File has already been moved', $ex->getMessage() );
63 $stream->getContents();
64 $this->fail( 'Expected exception not thrown' );
65 } catch ( \PHPUnit\Framework\AssertionFailedError
$ex ) {
67 } catch ( RuntimeException
$ex ) {
70 unlink( $filename . '.xxx' ); // Clean up
73 // getStream() fails if the file is missing
74 $file = new UploadedFile( [ 'error' => UPLOAD_ERR_OK
, 'tmp_name' => $filename ], true );
77 $this->fail( 'Expected exception not thrown' );
78 } catch ( \PHPUnit\Framework\AssertionFailedError
$ex ) {
80 } catch ( RuntimeException
$ex ) {
81 $this->assertSame( 'Uploaded file is missing', $ex->getMessage() );
85 public function testMoveTo() {
87 $filename = $this->makeTemp( __FUNCTION__
);
88 $this->assertFileExists( $filename, 'sanity check' );
89 $this->assertFileNotExists( "$filename.xxx", 'sanity check' );
90 $file = new UploadedFile( [ 'error' => UPLOAD_ERR_OK
, 'tmp_name' => $filename ], false );
91 $file->moveTo( $filename . '.xxx' );
92 $this->assertFileNotExists( $filename );
93 $this->assertFileExists( "$filename.xxx" );
95 // Fails on a second move attempt
96 $this->assertFileNotExists( "$filename.yyy", 'sanity check' );
98 $file->moveTo( $filename . '.yyy' );
99 $this->fail( 'Expected exception not thrown' );
100 } catch ( \PHPUnit\Framework\AssertionFailedError
$ex ) {
102 } catch ( RuntimeException
$ex ) {
103 $this->assertSame( 'File has already been moved', $ex->getMessage() );
105 $this->assertFileNotExists( $filename );
106 $this->assertFileExists( "$filename.xxx" );
107 $this->assertFileNotExists( "$filename.yyy" );
109 // Fails if the file is missing
110 $file = new UploadedFile( [ 'error' => UPLOAD_ERR_OK
, 'tmp_name' => "$filename.aaa" ], false );
111 $this->assertFileNotExists( "$filename.aaa", 'sanity check' );
112 $this->assertFileNotExists( "$filename.bbb", 'sanity check' );
114 $file->moveTo( $filename . '.bbb' );
115 $this->fail( 'Expected exception not thrown' );
116 } catch ( \PHPUnit\Framework\AssertionFailedError
$ex ) {
118 } catch ( RuntimeException
$ex ) {
119 $this->assertSame( 'Uploaded file is missing', $ex->getMessage() );
121 $this->assertFileNotExists( "$filename.aaa" );
122 $this->assertFileNotExists( "$filename.bbb" );
124 // Fails for non-upload file (when not flagged to ignore that)
125 $filename = $this->makeTemp( __FUNCTION__
);
126 $this->assertFileExists( $filename, 'sanity check' );
127 $this->assertFileNotExists( "$filename.xxx", 'sanity check' );
128 $file = new UploadedFile( [ 'error' => UPLOAD_ERR_OK
, 'tmp_name' => $filename ] );
130 $file->moveTo( $filename . '.xxx' );
131 $this->fail( 'Expected exception not thrown' );
132 } catch ( \PHPUnit\Framework\AssertionFailedError
$ex ) {
134 } catch ( RuntimeException
$ex ) {
135 $this->assertSame( 'Specified file is not an uploaded file', $ex->getMessage() );
137 $this->assertFileExists( $filename );
138 $this->assertFileNotExists( "$filename.xxx" );
140 // Fails for error uploads
141 $filename = $this->makeTemp( __FUNCTION__
);
142 $this->assertFileExists( $filename, 'sanity check' );
143 $this->assertFileNotExists( "$filename.xxx", 'sanity check' );
146 UPLOAD_ERR_FORM_SIZE
,
149 UPLOAD_ERR_NO_TMP_DIR
,
150 UPLOAD_ERR_CANT_WRITE
,
151 UPLOAD_ERR_EXTENSION
,
154 $file = new UploadedFile( [ 'error' => $code, 'tmp_name' => $filename ], false );
156 $file->moveTo( $filename . '.xxx' );
157 $this->fail( 'Expected exception not thrown' );
158 } catch ( \PHPUnit\Framework\AssertionFailedError
$ex ) {
160 } catch ( RuntimeException
$ex ) {
162 $this->assertFileExists( $filename );
163 $this->assertFileNotExists( "$filename.xxx" );
166 // Move failure triggers exception
167 $filename = $this->makeTemp( __FUNCTION__
, 'file1' );
168 $filename2 = $this->makeTemp( __FUNCTION__
, 'file2' );
169 $this->assertFileExists( $filename, 'sanity check' );
170 $file = new UploadedFile( [ 'error' => UPLOAD_ERR_OK
, 'tmp_name' => $filename ], false );
172 $file->moveTo( $filename2 . DIRECTORY_SEPARATOR
. 'foobar' );
173 $this->fail( 'Expected exception not thrown' );
174 } catch ( \PHPUnit\Framework\AssertionFailedError
$ex ) {
176 } catch ( RuntimeException
$ex ) {
178 $this->assertFileExists( $filename );
181 public function testInfoMethods() {
182 $filename = $this->makeTemp( __FUNCTION__
);
183 $file = new UploadedFile( [
184 'name' => 'C:\\example.txt',
185 'type' => 'text/plain',
187 'error' => UPLOAD_ERR_OK
,
188 'tmp_name' => $filename,
190 $this->assertSame( 1025, $file->getSize() );
191 $this->assertSame( UPLOAD_ERR_OK
, $file->getError() );
192 $this->assertSame( 'C:\\example.txt', $file->getClientFilename() );
193 $this->assertSame( 'text/plain', $file->getClientMediaType() );
195 // None of these are allowed to error
196 $file = new UploadedFile( [], false );
197 $this->assertSame( null, $file->getSize() );
198 $this->assertSame( UPLOAD_ERR_NO_FILE
, $file->getError() );
199 $this->assertSame( null, $file->getClientFilename() );
200 $this->assertSame( null, $file->getClientMediaType() );
202 // "if none was provided" behavior, given that $_FILES often contains
204 $file = new UploadedFile( [
208 'error' => UPLOAD_ERR_NO_FILE
,
209 'tmp_name' => $filename,
211 $this->assertSame( null, $file->getClientFilename() );
212 $this->assertSame( null, $file->getClientMediaType() );