Update UploadedFile's tests for SAPI and use of *_uploaded_file functions
This commit is contained in:
parent
257f2b7610
commit
a93b37a548
|
|
@ -19,11 +19,35 @@ class UploadedFile implements UploadedFileInterface
|
|||
private $tmpName;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $type
|
||||
* @param int $size
|
||||
* @param string $tmpName
|
||||
* @param int $error
|
||||
* Create a new Uri. The arguments correspond with keys from arrays
|
||||
* provided by $_FILES. For example, given this structure for $_FILES:
|
||||
*
|
||||
* array(
|
||||
* 'avatar' => arrary(
|
||||
* 'name' => 'my-avatar.png',
|
||||
* 'type' => 'image/png',
|
||||
* 'size' => 90996,
|
||||
* 'tmp_name' => 'phpUxcOty',
|
||||
* 'error' => 0
|
||||
* )
|
||||
* )
|
||||
*
|
||||
* ...use this call:
|
||||
*
|
||||
* new UploadedFile(
|
||||
* $_FILES['avatar']['name'],
|
||||
* $_FILES['avatar']['type'],
|
||||
* $_FILES['avatar']['size'],
|
||||
* $_FILES['avatar']['tmp_name'],
|
||||
* $_FILES['avatar']['error']
|
||||
* );
|
||||
*
|
||||
* @param string $name Name of the file; provided by the client
|
||||
* @param string $type Media type of the file; provided by the client
|
||||
* @param int $size The file size in bytes.
|
||||
* @param string $tmpName Local filesystem name of the file
|
||||
* @param int $error One of PHP's UPLOAD_ERR_XXX constants.
|
||||
* @see http://php.net/manual/en/features.file-upload.errors.php
|
||||
*/
|
||||
public function __construct($name, $type, $size, $tmpName, $error)
|
||||
{
|
||||
|
|
@ -44,31 +68,34 @@ class UploadedFile implements UploadedFileInterface
|
|||
* Retrieve a stream representing the uploaded file.
|
||||
*
|
||||
* This method returns a StreamInterface instance, representing the
|
||||
* uploaded file. The purpose of this method is to allow utilizing native PHP
|
||||
* uploaded file. The purpose of this method is to allow using native PHP
|
||||
* stream functionality to manipulate the file upload, such as
|
||||
* stream_copy_to_stream() (though the result will need to be decorated in a
|
||||
* native PHP stream wrapper to work with such functions).
|
||||
* stream_copy_to_stream() (though the result will need to be decorated in
|
||||
* a native PHP stream wrapper to work with such functions).
|
||||
*
|
||||
* If the moveTo() method has been called previously, this method will raise
|
||||
* an exception.
|
||||
* If the moveTo() method has been called previously, this method will
|
||||
* raise an exception.
|
||||
*
|
||||
* @return StreamInterface Stream representation of the uploaded file.
|
||||
* @throws \RuntimeException in cases when no stream is available or can be
|
||||
* created.
|
||||
* @throws \RuntimeException in cases when no stream is available or can
|
||||
* be created.
|
||||
*/
|
||||
public function getStream()
|
||||
{
|
||||
if ($this->moved) {
|
||||
throw new \RuntimeException("File has already been moved");
|
||||
}
|
||||
if (php_sapi_name() !== "cli" && !is_uploaded_file($this->tmpName)) {
|
||||
throw new \RuntimeException("File is not an uploaded file.");
|
||||
}
|
||||
return $this->stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the uploaded file to a new location.
|
||||
*
|
||||
* Use this method as an alternative to move_uploaded_file(). This method is
|
||||
* guaranteed to work in both SAPI and non-SAPI environments.
|
||||
* Use this method as an alternative to move_uploaded_file(). This method
|
||||
* is guaranteed to work in both SAPI and non-SAPI environments.
|
||||
*
|
||||
* The original file or stream will be removed on completion.
|
||||
*
|
||||
|
|
@ -87,14 +114,10 @@ class UploadedFile implements UploadedFileInterface
|
|||
if ($this->tmpName === null || !file_exists($this->tmpName)) {
|
||||
throw new \RuntimeException("File " . $this->tmpName . " does not exist.");
|
||||
}
|
||||
$sapi = php_sapi_name();
|
||||
$whitelist = ["apache", "apache2filter", "apache2handler", "cgi", "fpm-fcgi", "cgi-fcgi"];
|
||||
if (in_array($sapi, $whitelist)) {
|
||||
// @codeCoverageIgnoreStart
|
||||
move_uploaded_file($this->tmpName, $path);
|
||||
} else {
|
||||
// @codeCoverageIgnoreEnd
|
||||
if (php_sapi_name() === "cli") {
|
||||
rename($this->tmpName, $path);
|
||||
} else {
|
||||
move_uploaded_file($this->tmpName, $path);
|
||||
}
|
||||
$this->moved = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace WellRESTed\Message;
|
||||
|
||||
class UploadedFileState
|
||||
{
|
||||
public static $php_sapi_name;
|
||||
public static $is_uploaded_file;
|
||||
}
|
||||
|
||||
function php_sapi_name()
|
||||
{
|
||||
return UploadedFileState::$php_sapi_name;
|
||||
}
|
||||
|
||||
function move_uploaded_file($source, $target)
|
||||
{
|
||||
return rename($source, $target);
|
||||
}
|
||||
|
||||
function is_uploaded_file($file)
|
||||
{
|
||||
return UploadedFileState::$is_uploaded_file;
|
||||
}
|
||||
|
|
@ -3,8 +3,13 @@
|
|||
namespace WellRESTed\Test\Message;
|
||||
|
||||
use WellRESTed\Message\UploadedFile;
|
||||
use WellRESTed\Message\UploadedFileState;
|
||||
|
||||
// Hides several php core functions for testing.
|
||||
require_once __DIR__ . "/../../../src/UploadedFileState.php";
|
||||
|
||||
/**
|
||||
* @coversDefaultClass WellRESTed\Message\UploadedFile
|
||||
* @uses WellRESTed\Message\UploadedFile
|
||||
* @uses WellRESTed\Message\Stream
|
||||
* @uses WellRESTed\Message\NullStream
|
||||
|
|
@ -17,6 +22,7 @@ class UploadedFileTest extends \PHPUnit_Framework_TestCase
|
|||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
UploadedFileState::$php_sapi_name = "cli";
|
||||
$this->tmpName = tempnam(sys_get_temp_dir(), "tst");
|
||||
$this->movePath = tempnam(sys_get_temp_dir(), "tst");
|
||||
}
|
||||
|
|
@ -36,8 +42,8 @@ class UploadedFileTest extends \PHPUnit_Framework_TestCase
|
|||
// getStream
|
||||
|
||||
/**
|
||||
* @covers WellRESTed\Message\UploadedFile::__construct
|
||||
* @covers WellRESTed\Message\UploadedFile::getStream
|
||||
* @covers ::__construct
|
||||
* @covers ::getStream
|
||||
*/
|
||||
public function testGetStreamReturnsStreamInterface()
|
||||
{
|
||||
|
|
@ -46,22 +52,21 @@ class UploadedFileTest extends \PHPUnit_Framework_TestCase
|
|||
}
|
||||
|
||||
/**
|
||||
* @covers WellRESTed\Message\UploadedFile::__construct
|
||||
* @covers WellRESTed\Message\UploadedFile::getStream
|
||||
* @covers ::__construct
|
||||
* @covers ::getStream
|
||||
*/
|
||||
public function testGetStreamReturnsStreamWrappingUploadedFile()
|
||||
{
|
||||
$content = "Hello, World!";
|
||||
file_put_contents($this->tmpName, $content);
|
||||
|
||||
$file = new UploadedFile("", "", 0, $this->tmpName, "");
|
||||
$stream = $file->getStream();
|
||||
$this->assertEquals($content, (string) $stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers WellRESTed\Message\UploadedFile::__construct
|
||||
* @covers WellRESTed\Message\UploadedFile::getStream
|
||||
* @covers ::__construct
|
||||
* @covers ::getStream
|
||||
*/
|
||||
public function testGetStreamReturnsEmptyStreamForNoFile()
|
||||
{
|
||||
|
|
@ -70,27 +75,56 @@ class UploadedFileTest extends \PHPUnit_Framework_TestCase
|
|||
}
|
||||
|
||||
/**
|
||||
* @covers WellRESTed\Message\UploadedFile::__construct
|
||||
* @covers WellRESTed\Message\UploadedFile::getStream
|
||||
* @covers ::__construct
|
||||
* @covers ::getStream
|
||||
* @expectedException \RuntimeException
|
||||
*/
|
||||
public function testGetStreamThrowsExceptionAfterMoveTo()
|
||||
{
|
||||
$content = "Hello, World!";
|
||||
file_put_contents($this->tmpName, $content);
|
||||
|
||||
$file = new UploadedFile("", "", 0, $this->tmpName, "");
|
||||
$file->moveTo($this->movePath);
|
||||
$file->getStream();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::__construct
|
||||
* @covers ::getStream
|
||||
* @expectedException \RuntimeException
|
||||
*/
|
||||
public function testGetStreamThrowsExceptionForNonUploadedFile()
|
||||
{
|
||||
UploadedFileState::$php_sapi_name = "apache";
|
||||
UploadedFileState::$is_uploaded_file = false;
|
||||
$file = new UploadedFile("", "", 0, "", 0);
|
||||
$file->getStream();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// move
|
||||
// moveTo
|
||||
|
||||
/**
|
||||
* @covers WellRESTed\Message\UploadedFile::moveTo
|
||||
* @covers ::moveTo
|
||||
*/
|
||||
public function testMoveToRelocatesUploadedFileToDestiationIfExists()
|
||||
public function testMoveToSapiRelocatesUploadedFileToDestiationIfExists()
|
||||
{
|
||||
UploadedFileState::$php_sapi_name = "fpm-fcgi";
|
||||
|
||||
$content = "Hello, World!";
|
||||
file_put_contents($this->tmpName, $content);
|
||||
$originalMd5 = md5_file($this->tmpName);
|
||||
|
||||
$file = new UploadedFile("", "", 0, $this->tmpName, "");
|
||||
$file->moveTo($this->movePath);
|
||||
|
||||
$this->assertEquals($originalMd5, md5_file($this->movePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::moveTo
|
||||
*/
|
||||
public function testMoveToNonSapiRelocatesUploadedFileToDestiationIfExists()
|
||||
{
|
||||
$content = "Hello, World!";
|
||||
file_put_contents($this->tmpName, $content);
|
||||
|
|
@ -103,10 +137,10 @@ class UploadedFileTest extends \PHPUnit_Framework_TestCase
|
|||
}
|
||||
|
||||
/**
|
||||
* @covers WellRESTed\Message\UploadedFile::moveTo
|
||||
* @covers ::moveTo
|
||||
* @expectedException \RuntimeException
|
||||
*/
|
||||
public function testThrowsExcpetionOnSubsequentCallToMoveTo()
|
||||
public function testMoveToThrowsExcpetionOnSubsequentCall()
|
||||
{
|
||||
$content = "Hello, World!";
|
||||
file_put_contents($this->tmpName, $content);
|
||||
|
|
|
|||
Loading…
Reference in New Issue