You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
210 lines
6.4 KiB
210 lines
6.4 KiB
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace GuzzleHttp\Tests\Psr7;
|
|
|
|
use GuzzleHttp\Psr7\Stream;
|
|
use GuzzleHttp\Psr7\UploadedFile;
|
|
use PHPUnit\Framework\TestCase;
|
|
use ReflectionProperty;
|
|
|
|
/**
|
|
* @covers \GuzzleHttp\Psr7\UploadedFile
|
|
*/
|
|
class UploadedFileTest extends TestCase
|
|
{
|
|
private $cleanup;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->cleanup = [];
|
|
}
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
foreach ($this->cleanup as $file) {
|
|
if (is_scalar($file) && file_exists($file)) {
|
|
unlink($file);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function invalidStreams()
|
|
{
|
|
return [
|
|
'null' => [null],
|
|
'true' => [true],
|
|
'false' => [false],
|
|
'int' => [1],
|
|
'float' => [1.1],
|
|
'array' => [['filename']],
|
|
'object' => [(object) ['filename']],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider invalidStreams
|
|
*/
|
|
public function testRaisesExceptionOnInvalidStreamOrFile($streamOrFile): void
|
|
{
|
|
$this->expectException(\InvalidArgumentException::class);
|
|
|
|
new UploadedFile($streamOrFile, 0, UPLOAD_ERR_OK);
|
|
}
|
|
|
|
public function testGetStreamReturnsOriginalStreamObject(): void
|
|
{
|
|
$stream = new Stream(fopen('php://temp', 'r'));
|
|
$upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
|
|
|
|
self::assertSame($stream, $upload->getStream());
|
|
}
|
|
|
|
public function testGetStreamReturnsWrappedPhpStream(): void
|
|
{
|
|
$stream = fopen('php://temp', 'wb+');
|
|
$upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
|
|
$uploadStream = $upload->getStream()->detach();
|
|
|
|
self::assertSame($stream, $uploadStream);
|
|
}
|
|
|
|
public function testGetStreamReturnsStreamForFile(): void
|
|
{
|
|
$this->cleanup[] = $stream = tempnam(sys_get_temp_dir(), 'stream_file');
|
|
$upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
|
|
$uploadStream = $upload->getStream();
|
|
$r = new ReflectionProperty($uploadStream, 'filename');
|
|
$r->setAccessible(true);
|
|
|
|
self::assertSame($stream, $r->getValue($uploadStream));
|
|
}
|
|
|
|
public function testSuccessful(): void
|
|
{
|
|
$stream = \GuzzleHttp\Psr7\Utils::streamFor('Foo bar!');
|
|
$upload = new UploadedFile($stream, $stream->getSize(), UPLOAD_ERR_OK, 'filename.txt', 'text/plain');
|
|
|
|
self::assertSame($stream->getSize(), $upload->getSize());
|
|
self::assertSame('filename.txt', $upload->getClientFilename());
|
|
self::assertSame('text/plain', $upload->getClientMediaType());
|
|
|
|
$this->cleanup[] = $to = tempnam(sys_get_temp_dir(), 'successful');
|
|
$upload->moveTo($to);
|
|
self::assertFileExists($to);
|
|
self::assertSame($stream->__toString(), file_get_contents($to));
|
|
}
|
|
|
|
public function invalidMovePaths(): iterable
|
|
{
|
|
return [
|
|
'null' => [null],
|
|
'true' => [true],
|
|
'false' => [false],
|
|
'int' => [1],
|
|
'float' => [1.1],
|
|
'empty' => [''],
|
|
'array' => [['filename']],
|
|
'object' => [(object) ['filename']],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider invalidMovePaths
|
|
*/
|
|
public function testMoveRaisesExceptionForInvalidPath($path): void
|
|
{
|
|
$stream = \GuzzleHttp\Psr7\Utils::streamFor('Foo bar!');
|
|
$upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
|
|
|
|
$this->expectException(\InvalidArgumentException::class);
|
|
$this->expectExceptionMessage('path');
|
|
$upload->moveTo($path);
|
|
}
|
|
|
|
public function testMoveCannotBeCalledMoreThanOnce(): void
|
|
{
|
|
$stream = \GuzzleHttp\Psr7\Utils::streamFor('Foo bar!');
|
|
$upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
|
|
|
|
$this->cleanup[] = $to = tempnam(sys_get_temp_dir(), 'diac');
|
|
$upload->moveTo($to);
|
|
self::assertFileExists($to);
|
|
|
|
$this->expectException(\RuntimeException::class);
|
|
$this->expectExceptionMessage('moved');
|
|
$upload->moveTo($to);
|
|
}
|
|
|
|
public function testCannotRetrieveStreamAfterMove(): void
|
|
{
|
|
$stream = \GuzzleHttp\Psr7\Utils::streamFor('Foo bar!');
|
|
$upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK);
|
|
|
|
$this->cleanup[] = $to = tempnam(sys_get_temp_dir(), 'diac');
|
|
$upload->moveTo($to);
|
|
self::assertFileExists($to);
|
|
|
|
$this->expectException(\RuntimeException::class);
|
|
$this->expectExceptionMessage('moved');
|
|
$upload->getStream();
|
|
}
|
|
|
|
public function nonOkErrorStatus(): iterable
|
|
{
|
|
return [
|
|
'UPLOAD_ERR_INI_SIZE' => [UPLOAD_ERR_INI_SIZE],
|
|
'UPLOAD_ERR_FORM_SIZE' => [UPLOAD_ERR_FORM_SIZE],
|
|
'UPLOAD_ERR_PARTIAL' => [UPLOAD_ERR_PARTIAL],
|
|
'UPLOAD_ERR_NO_FILE' => [UPLOAD_ERR_NO_FILE],
|
|
'UPLOAD_ERR_NO_TMP_DIR' => [UPLOAD_ERR_NO_TMP_DIR],
|
|
'UPLOAD_ERR_CANT_WRITE' => [UPLOAD_ERR_CANT_WRITE],
|
|
'UPLOAD_ERR_EXTENSION' => [UPLOAD_ERR_EXTENSION],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider nonOkErrorStatus
|
|
*/
|
|
public function testConstructorDoesNotRaiseExceptionForInvalidStreamWhenErrorStatusPresent($status): void
|
|
{
|
|
$uploadedFile = new UploadedFile('not ok', 0, $status);
|
|
self::assertSame($status, $uploadedFile->getError());
|
|
}
|
|
|
|
/**
|
|
* @dataProvider nonOkErrorStatus
|
|
*/
|
|
public function testMoveToRaisesExceptionWhenErrorStatusPresent($status): void
|
|
{
|
|
$uploadedFile = new UploadedFile('not ok', 0, $status);
|
|
$this->expectException(\RuntimeException::class);
|
|
$this->expectExceptionMessage('upload error');
|
|
$uploadedFile->moveTo(__DIR__.'/'.bin2hex(random_bytes(20)));
|
|
}
|
|
|
|
/**
|
|
* @dataProvider nonOkErrorStatus
|
|
*/
|
|
public function testGetStreamRaisesExceptionWhenErrorStatusPresent($status): void
|
|
{
|
|
$uploadedFile = new UploadedFile('not ok', 0, $status);
|
|
$this->expectException(\RuntimeException::class);
|
|
$this->expectExceptionMessage('upload error');
|
|
$uploadedFile->getStream();
|
|
}
|
|
|
|
public function testMoveToCreatesStreamIfOnlyAFilenameWasProvided(): void
|
|
{
|
|
$this->cleanup[] = $from = tempnam(sys_get_temp_dir(), 'copy_from');
|
|
$this->cleanup[] = $to = tempnam(sys_get_temp_dir(), 'copy_to');
|
|
|
|
copy(__FILE__, $from);
|
|
|
|
$uploadedFile = new UploadedFile($from, 100, UPLOAD_ERR_OK, basename($from), 'text/plain');
|
|
$uploadedFile->moveTo($to);
|
|
|
|
self::assertFileEquals(__FILE__, $to);
|
|
}
|
|
}
|
|
|