p2 project
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.

211 lines
6.4 KiB

2 months ago
<?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);
}
}