Download PHPUnit binary data

How can I populate php://inputbinary data to check downloads? (Or, otherwise, test downloads). I am using plupload as my interface and I want to disconnect my server.

This is the part of the code I want to check:

public function recieve($file = 'file')
{
    // Get parameters
    $chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0;
    $chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 0;
    $fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : '';
    $targetDir = $this->_uploadDir;

    // Clean the fileName for security reasons
    $fileName = preg_replace('/[^\w\._]+/', '_', $fileName);

    // Make sure the fileName is unique but only if chunking is disabled
    if ($chunks < 2 && file_exists($targetDir . DIRECTORY_SEPARATOR . $fileName)) {
        $ext = strrpos($fileName, '.');
        $fileName_a = substr($fileName, 0, $ext);
        $fileName_b = substr($fileName, $ext);

        $count = 1;
        while (file_exists(
                $targetDir . DIRECTORY_SEPARATOR . $fileName_a . '_' . $count . $fileName_b)) {
            $count++;
        }

        $fileName = $fileName_a . '_' . $count . $fileName_b;
    }

    $filePath = $targetDir . DIRECTORY_SEPARATOR . $fileName;

    // Create target dir
    if (!file_exists($targetDir)) {
        if (!is_writable(dirname($targetDir))) {
            $this->_messages[] = 'Cannot write to ' . dirname($targetDir) . ' for mkdir';
            return false;
        }
        mkdir($targetDir, 0777, true);
    }

    // Check permissions
    if (!is_writable($targetDir)) {
        $this->_messages[] = 'Unable to write to temp directory.';
        return false;
    }

    // Look for the content type header
    $contentType = null;
    if (isset($_SERVER["HTTP_CONTENT_TYPE"]))
        $contentType = $_SERVER["HTTP_CONTENT_TYPE"];

    if (isset($_SERVER["CONTENT_TYPE"]))
        $contentType = $_SERVER["CONTENT_TYPE"];

    // Handle non multipart uploads older WebKit versions didn't support multipart in HTML5
    if (strpos($contentType, "multipart") !== false) {
        if (isset($_FILES[$file]['tmp_name']) && is_uploaded_file($_FILES[$file]['tmp_name'])) {
            // Open temp file
            $out = fopen("{$filePath}.part", $chunk == 0 ? "wb" : "ab");
            if ($out) {
                // Read binary input stream and append it to temp file
                $in = fopen($_FILES[$file]['tmp_name'], "rb");

                if ($in) {
                    while ($buff = fread($in, 4096)) {
                        fwrite($out, $buff);
                    }
                } else {
                    $this->_messages[] = 'Failed to open input stream.';
                    return false;
                }
                fclose($in);
                fclose($out);
                unlink($_FILES[$file]['tmp_name']);
            } else {
                $this->_messages[] = 'Failed to open output stream.';
                return false;
            }
        } else {
            $this->_messages[] = 'Failed to move uploaded file.';
            return false;
        }
    } else {
        // Open temp file
        $out = fopen("{$filePath}.part", $chunk == 0 ? "wb" : "ab");
        if ($out) {
            // Read binary input stream and append it to temp file
            $in = fopen("php://input", "rb");
            if ($in) {
                while ($buff = fread($in, 4096)) {
                    fwrite($out, $buff);
                }
            } else {
                $this->_messages[] = 'Failed to open input stream.';
                return false;
            }
            fclose($in);
            fclose($out);
        } else {
            $this->_messages[] = 'Failed to open output stream.';
            return false;
        }
    }

    // Check if file upload is complete
    if (!$chunks || $chunk == $chunks - 1) {
        // Strip the temp .part suffix off
        rename("{$filePath}.part", $filePath);
        return $filePath;
    }
}

* Edit

Added more code to show that I want unit test

+5
source share
2 answers

This seems impossible to do with regular PHPUnit tests, but I found a way to integrate .phpt tests with PHPUnit at: http://qafoo.com/blog/013_testing_file_uploads_with_php.html

For reference, uploadTest.phpt:

--TEST--
Example test emulating a file upload
--POST_RAW--
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryfywL8UCjFtqUBTQn

------WebKitFormBoundaryfywL8UCjFtqUBTQn
Content-Disposition: form-data; name="file"; filename="example.txt"
Content-Type: text/plain

Contents of text file here

------WebKitFormBoundaryfywL8UCjFtqUBTQn
Content-Disposition: form-data; name="submit"

Upload
------WebKitFormBoundaryfywL8UCjFtqUBTQn--
--FILE--
<?php
require __DIR__ . '/Upload.php';

$upload = new Upload();
$file = $upload->recieve('file');

var_dump(file_exists($file));
?>
--EXPECT--
bool(true)

And the corresponding PHPUnit testing integration:

<?php
require_once 'PHPUnit/Extensions/PhptTestCase.php';
class UploadExampleTest extends PHPUnit_Extensions_PhptTestCase
{
    public function __construct()
    {
        parent::__construct(__DIR__ . '/uploadTest.phpt');
    }
}
+6

-, unit test, 200- ! , . getFileName(), getContentType(), isChunked() getChunkDetails(), transferChunk() .. , . , getContentType():

public function getContentType() {
    if (isset($_SERVER["CONTENT_TYPE"]))
        return $_SERVER["CONTENT_TYPE"];

    if (isset($_SERVER["HTTP_CONTENT_TYPE"]))
        return $_SERVER["HTTP_CONTENT_TYPE"];

    throw new FileTransferException('Unknown content type');
}

.

/**
 * @expectedException FileTransferException
 */
public function testUnknownContentType() {
    $fixture = new FileTransfer();
    unset($_SERVER["CONTENT_TYPE"]);
    unset($_SERVER["HTTP_CONTENT_TYPE"]);
    $fixture->getContentType();
}

public function testRegularContentType() {
    $fixture = new FileTransfer();
    $_SERVER["CONTENT_TYPE"] = 'regular';
    unset($_SERVER["HTTP_CONTENT_TYPE"]);
    self::assertEquals('regular', $fixture->getContentType());
}

public function testHttpContentType() {
    $fixture = new FileTransfer();
    unset($_SERVER["CONTENT_TYPE"]);
    $_SERVER["HTTP_CONTENT_TYPE"] = 'http';
    self::assertEquals('http', $fixture->getContentType());
}

public function testRegularContentTypeTakesPrecedence() {
    $fixture = new FileTransfer();
    $_SERVER["HTTP_CONTENT_TYPE"] = 'http';
    $_SERVER["CONTENT_TYPE"] = 'regular';
    self::assertEquals('regular', $fixture->getContentType());
}

, - . , -, php://input . "" " ": , , .

/ is_uploaded_file() , . isUploadedFile() openInputStream(). , . , is_uploaded_file() unit test. PHP, , , , (end-to-end).

- . , vfsStream.

+2

All Articles