added unit and integration tests

pull/601/head
n0nag0n 6 months ago
parent f08b9bcbfb
commit f697e30afa

@ -62,9 +62,10 @@ use flight\net\Route;
* @method void jsonp(mixed $data, string $param = 'jsonp', int $code = 200, bool $encode = true, string $charset = 'utf-8', int $option = 0)
* Sends a JSONP response.
*
* # HTTP caching
* # HTTP methods
* @method void etag(string $id, ('strong'|'weak') $type = 'strong') Handles ETag HTTP caching.
* @method void lastModified(int $time) Handles last modified HTTP caching.
* @method void download(string $filePath) Downloads a file
*
* phpcs:disable PSR2.Methods.MethodDeclaration.Underscore
*/
@ -895,29 +896,43 @@ class Engine
}
}
public function _download(string $file): void {
if (!file_exists($file)) {
throw new Exception("$file cannot be found.");
/**
* Downloads a file
*
* @param string $filePath The path to the file to download
* @throws Exception If the file cannot be found
*
* @return void
*/
public function _download(string $filePath): void {
if (file_exists($filePath) === false) {
throw new Exception("$filePath cannot be found.");
}
$fileSize = filesize($file);
$fileSize = filesize($filePath);
$mimeType = mime_content_type($file);
$mimeType = mime_content_type($filePath);
$mimeType = $mimeType !== false ? $mimeType : 'application/octet-stream';
header('Content-Description: File Transfer');
header('Content-Type: ' . $mimeType);
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . $fileSize);
$response = $this->response();
$response->send();
$response->setRealHeader('Content-Description: File Transfer');
$response->setRealHeader('Content-Type: ' . $mimeType);
$response->setRealHeader('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
$response->setRealHeader('Expires: 0');
$response->setRealHeader('Cache-Control: must-revalidate');
$response->setRealHeader('Pragma: public');
$response->setRealHeader('Content-Length: ' . $fileSize);
// Clear the output buffer
// // Clear the output buffer
ob_clean();
flush();
// Read the file and send it to the output buffer
readfile($file);
// // Read the file and send it to the output buffer
readfile($filePath);
if(empty(getenv('PHPUNIT_TEST'))) {
exit; // @codeCoverageIgnore
}
}
/**

@ -75,9 +75,10 @@ require_once __DIR__ . '/autoload.php';
* @method static void error(Throwable $exception) Sends an HTTP 500 response.
* @method static void notFound() Sends an HTTP 404 response.
*
* # HTTP caching
* # HTTP methods
* @method static void etag(string $id, ('strong'|'weak') $type = 'strong') Performs ETag HTTP caching.
* @method static void lastModified(int $time) Performs last modified HTTP caching.
* @method static void download(string $filePath) Downloads a file
*/
class Flight
{

@ -952,4 +952,38 @@ class EngineTest extends TestCase
$this->assertEquals('Method Not Allowed', $engine->response()->getBody());
}
public function testDownload()
{
$engine = new class extends Engine {
public function getLoader()
{
return $this->loader;
}
};
// doing this so we can overwrite some parts of the response
$engine->getLoader()->register('response', function () {
return new class extends Response {
public function setRealHeader(
string $header_string,
bool $replace = true,
int $response_code = 0
): self {
return $this;
}
};
});
$tmpfile = tmpfile();
fwrite($tmpfile, 'I am a teapot');
$streamPath = stream_get_meta_data($tmpfile)['uri'];
$this->expectOutputString('I am a teapot');
$engine->download($streamPath);
}
public function testDownloadBadPath() {
$engine = new Engine();
$this->expectException(Exception::class);
$this->expectExceptionMessage("/path/to/nowhere cannot be found.");
$engine->download('/path/to/nowhere');
}
}

@ -86,6 +86,7 @@ class LayoutMiddleware
<li><a href="/dice">Dice Container</a></li>
<li><a href="/no-container">No Container Registered</a></li>
<li><a href="/Pascal_Snake_Case">Pascal_Snake_Case</a></li>
<li><a href="/download">Download File</a></li>
</ul>
HTML;
echo '<div id="container">';

@ -175,6 +175,11 @@ Flight::route('/json-halt', function () {
Flight::jsonHalt(['message' => 'JSON rendered and halted successfully with no other body content!']);
});
// Download a file
Flight::route('/download', function () {
Flight::download('test_file.txt');
});
Flight::map('error', function (Throwable $e) {
echo sprintf(
<<<HTML

@ -0,0 +1 @@
This file downloaded successfully!
Loading…
Cancel
Save