Completed
Push — master ( ac4cc7...3c4d8e )
by Tobias
03:01
created

UploadedFileTest::testGetStream()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Tests\Nyholm\Psr7;
4
5
use Nyholm\Psr7\Stream;
6
use Nyholm\Psr7\UploadedFile;
7
use PHPUnit\Framework\TestCase;
8
use Psr\Http\Message\StreamInterface;
9
10
/**
11
 * @covers \Nyholm\Psr7\UploadedFile
12
 */
13
class UploadedFileTest extends TestCase
14
{
15
    protected $cleanup;
16
17
    public function setUp()
18
    {
19
        $this->cleanup = [];
20
    }
21
22
    public function tearDown()
23
    {
24
        foreach ($this->cleanup as $file) {
25
            if (is_scalar($file) && file_exists($file)) {
26
                unlink($file);
27
            }
28
        }
29
    }
30
31 View Code Duplication
    public function invalidStreams()
32
    {
33
        return [
34
            'null' => [null],
35
            'true' => [true],
36
            'false' => [false],
37
            'int' => [1],
38
            'float' => [1.1],
39
            'array' => [['filename']],
40
            'object' => [(object) ['filename']],
41
        ];
42
    }
43
44
    /**
45
     * @dataProvider invalidStreams
46
     */
47
    public function testRaisesExceptionOnInvalidStreamOrFile($streamOrFile)
48
    {
49
        $this->expectException(\InvalidArgumentException::class);
50
        $this->expectExceptionMessage('Invalid stream or file provided for UploadedFile');
51
52
        new UploadedFile($streamOrFile, 0, UPLOAD_ERR_OK);
53
    }
54
55
    public function invalidErrorStatuses()
56
    {
57
        return [
58
            'null' => [null],
59
            'true' => [true],
60
            'false' => [false],
61
            'float' => [1.1],
62
            'string' => ['1'],
63
            'array' => [[1]],
64
            'object' => [(object) [1]],
65
            'negative' => [-1],
66
            'too-big' => [9],
67
        ];
68
    }
69
70
    /**
71
     * @dataProvider invalidErrorStatuses
72
     */
73
    public function testRaisesExceptionOnInvalidErrorStatus($status)
74
    {
75
        $this->expectException(\InvalidArgumentException::class);
76
        $this->expectExceptionMessage('status');
77
78
        new UploadedFile(fopen('php://temp', 'wb+'), 0, $status);
79
    }
80
81 View Code Duplication
    public function invalidFilenamesAndMediaTypes()
82
    {
83
        return [
84
            'true' => [true],
85
            'false' => [false],
86
            'int' => [1],
87
            'float' => [1.1],
88
            'array' => [['string']],
89
            'object' => [(object) ['string']],
90
        ];
91
    }
92
93
    /**
94
     * @dataProvider invalidFilenamesAndMediaTypes
95
     */
96 View Code Duplication
    public function testRaisesExceptionOnInvalidClientFilename($filename)
97
    {
98
        $this->expectException(\InvalidArgumentException::class);
99
        $this->expectExceptionMessage('filename');
100
101
        new UploadedFile(fopen('php://temp', 'wb+'), 0, UPLOAD_ERR_OK, $filename);
102
    }
103
104
    /**
105
     * @dataProvider invalidFilenamesAndMediaTypes
106
     */
107 View Code Duplication
    public function testRaisesExceptionOnInvalidClientMediaType($mediaType)
108
    {
109
        $this->expectException(\InvalidArgumentException::class);
110
        $this->expectExceptionMessage('media type');
111
112
        new UploadedFile(fopen('php://temp', 'wb+'), 0, UPLOAD_ERR_OK, 'foobar.baz', $mediaType);
113
    }
114
115
    public function testGetStreamReturnsOriginalStreamObject()
116
    {
117
        $stream = Stream::create('');
118
        $upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
119
120
        $this->assertSame($stream, $upload->getStream());
121
    }
122
123
    public function testGetStreamReturnsWrappedPhpStream()
124
    {
125
        $stream = fopen('php://temp', 'wb+');
126
        $upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
127
        $uploadStream = $upload->getStream()->detach();
128
129
        $this->assertSame($stream, $uploadStream);
130
    }
131
132
    public function testGetStream()
133
    {
134
        $upload = new UploadedFile(__DIR__.'/Resources/foo.txt', 0, UPLOAD_ERR_OK);
135
        $stream = $upload->getStream();
136
        $this->assertInstanceOf(StreamInterface::class, $stream);
137
        $this->assertEquals("Foobar\n", $stream->__toString());
138
    }
139
140
    public function testSuccessful()
141
    {
142
        $stream = Stream::create('Foo bar!');
143
        $upload = new UploadedFile($stream, $stream->getSize(), UPLOAD_ERR_OK, 'filename.txt', 'text/plain');
144
145
        $this->assertEquals($stream->getSize(), $upload->getSize());
146
        $this->assertEquals('filename.txt', $upload->getClientFilename());
147
        $this->assertEquals('text/plain', $upload->getClientMediaType());
148
149
        $this->cleanup[] = $to = tempnam(sys_get_temp_dir(), 'successful');
150
        $upload->moveTo($to);
151
        $this->assertFileExists($to);
152
        $this->assertEquals($stream->__toString(), file_get_contents($to));
153
    }
154
155 View Code Duplication
    public function invalidMovePaths()
156
    {
157
        return [
158
            'null' => [null],
159
            'true' => [true],
160
            'false' => [false],
161
            'int' => [1],
162
            'float' => [1.1],
163
            'empty' => [''],
164
            'array' => [['filename']],
165
            'object' => [(object) ['filename']],
166
        ];
167
    }
168
169
    /**
170
     * @dataProvider invalidMovePaths
171
     */
172
    public function testMoveRaisesExceptionForInvalidPath($path)
173
    {
174
        $stream = (new \Nyholm\Psr7\Factory\Psr17Factory())->createStream('Foo bar!');
175
        $upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
176
177
        $this->cleanup[] = $path;
178
179
        $this->expectException(\InvalidArgumentException::class);
180
        $this->expectExceptionMessage('path');
181
        $upload->moveTo($path);
182
    }
183
184 View Code Duplication
    public function testMoveCannotBeCalledMoreThanOnce()
185
    {
186
        $stream = (new \Nyholm\Psr7\Factory\Psr17Factory())->createStream('Foo bar!');
187
        $upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
188
189
        $this->cleanup[] = $to = tempnam(sys_get_temp_dir(), 'diac');
190
        $upload->moveTo($to);
191
        $this->assertTrue(file_exists($to));
192
193
        $this->expectException(\RuntimeException::class);
194
        $this->expectExceptionMessage('moved');
195
        $upload->moveTo($to);
196
    }
197
198 View Code Duplication
    public function testCannotRetrieveStreamAfterMove()
199
    {
200
        $stream = (new \Nyholm\Psr7\Factory\Psr17Factory())->createStream('Foo bar!');
201
        $upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
202
203
        $this->cleanup[] = $to = tempnam(sys_get_temp_dir(), 'diac');
204
        $upload->moveTo($to);
205
        $this->assertFileExists($to);
206
207
        $this->expectException(\RuntimeException::class);
208
        $this->expectExceptionMessage('moved');
209
        $upload->getStream();
210
    }
211
212
    public function nonOkErrorStatus()
213
    {
214
        return [
215
            'UPLOAD_ERR_INI_SIZE' => [UPLOAD_ERR_INI_SIZE],
216
            'UPLOAD_ERR_FORM_SIZE' => [UPLOAD_ERR_FORM_SIZE],
217
            'UPLOAD_ERR_PARTIAL' => [UPLOAD_ERR_PARTIAL],
218
            'UPLOAD_ERR_NO_FILE' => [UPLOAD_ERR_NO_FILE],
219
            'UPLOAD_ERR_NO_TMP_DIR' => [UPLOAD_ERR_NO_TMP_DIR],
220
            'UPLOAD_ERR_CANT_WRITE' => [UPLOAD_ERR_CANT_WRITE],
221
            'UPLOAD_ERR_EXTENSION' => [UPLOAD_ERR_EXTENSION],
222
        ];
223
    }
224
225
    /**
226
     * @dataProvider nonOkErrorStatus
227
     */
228
    public function testConstructorDoesNotRaiseExceptionForInvalidStreamWhenErrorStatusPresent($status)
229
    {
230
        $uploadedFile = new UploadedFile('not ok', 0, $status);
231
        $this->assertSame($status, $uploadedFile->getError());
232
    }
233
234
    /**
235
     * @dataProvider nonOkErrorStatus
236
     */
237
    public function testMoveToRaisesExceptionWhenErrorStatusPresent($status)
238
    {
239
        $uploadedFile = new UploadedFile('not ok', 0, $status);
240
        $this->expectException(\RuntimeException::class);
241
        $this->expectExceptionMessage('upload error');
242
        $uploadedFile->moveTo(__DIR__.'/'.uniqid());
243
    }
244
245
    /**
246
     * @dataProvider nonOkErrorStatus
247
     */
248
    public function testGetStreamRaisesExceptionWhenErrorStatusPresent($status)
249
    {
250
        $uploadedFile = new UploadedFile('not ok', 0, $status);
251
        $this->expectException(\RuntimeException::class);
252
        $this->expectExceptionMessage('upload error');
253
        $uploadedFile->getStream();
254
    }
255
256
    public function testMoveToCreatesStreamIfOnlyAFilenameWasProvided()
257
    {
258
        $this->cleanup[] = $from = tempnam(sys_get_temp_dir(), 'copy_from');
259
        $this->cleanup[] = $to = tempnam(sys_get_temp_dir(), 'copy_to');
260
261
        copy(__FILE__, $from);
262
263
        $uploadedFile = new UploadedFile($from, 100, UPLOAD_ERR_OK, basename($from), 'text/plain');
264
        $uploadedFile->moveTo($to);
265
266
        $this->assertFileEquals(__FILE__, $to);
267
    }
268
}
269