
5 changed files with 167 additions and 3 deletions
-
3composer.json
-
4public_html/static.php
-
24tests/Public/InstallerTest.php
-
90tests/Public/StaticTest.php
-
49tests/ServerTestCase.php
@ -0,0 +1,24 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Roundcube\Tests\Public; |
||||
|
|
||||
|
use Roundcube\Tests\ServerTestCase; |
||||
|
|
||||
|
/** |
||||
|
* Test class to test installer.php |
||||
|
*/ |
||||
|
class InstallerTest extends ServerTestCase |
||||
|
{ |
||||
|
/** |
||||
|
* Test installer.php |
||||
|
*/ |
||||
|
public function testInstaller(): void |
||||
|
{ |
||||
|
$response = $this->request('GET', 'installer.php/'); |
||||
|
|
||||
|
$body = (string) $response->getBody(); |
||||
|
|
||||
|
$this->assertSame(200, $response->getStatusCode()); |
||||
|
$this->assertTrue(str_starts_with($body, '<!DOCTYPE html>')); |
||||
|
} |
||||
|
} |
@ -0,0 +1,90 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Roundcube\Tests\Public; |
||||
|
|
||||
|
use PHPUnit\Framework\Attributes\DataProvider; |
||||
|
use Roundcube\Tests\ServerTestCase; |
||||
|
|
||||
|
/** |
||||
|
* Test class to test static resources server |
||||
|
*/ |
||||
|
class StaticTest extends ServerTestCase |
||||
|
{ |
||||
|
/** |
||||
|
* Dataset for testExistingResources() |
||||
|
*/ |
||||
|
public static function provideExistingResources(): iterable |
||||
|
{ |
||||
|
return [ |
||||
|
['program/resources/blank.gif', 'image/gif'], |
||||
|
['skins/elastic/images/logo.svg?s=1234567', 'image/svg+xml'], |
||||
|
['plugins/acl/acl.js', 'text/javascript'], |
||||
|
]; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Test valid resources |
||||
|
*/ |
||||
|
#[DataProvider('provideExistingResources')]
|
||||
|
public function testExistingResources($path, $ctype): void |
||||
|
{ |
||||
|
$response = $this->request('GET', 'static.php/' . $path); |
||||
|
|
||||
|
$file = file_get_contents(INSTALL_PATH . preg_replace('/\?.*$/', '', $path)); |
||||
|
|
||||
|
$this->assertSame(200, $response->getStatusCode()); |
||||
|
$this->assertSame($file, (string) $response->getBody()); |
||||
|
$this->assertSame(['public, max-age=604800'], $response->getHeader('Cache-Control')); |
||||
|
$this->assertSame(['bytes'], $response->getHeader('Accept-Ranges')); |
||||
|
$this->assertSame([(string) strlen($file)], $response->getHeader('Content-Length')); |
||||
|
$this->assertStringContainsString($ctype, $response->getHeader('Content-Type')[0]); |
||||
|
// TODO: Expires header
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Dataset for testForbiddenResources() |
||||
|
*/ |
||||
|
public static function provideForbiddenResources(): iterable |
||||
|
{ |
||||
|
return [ |
||||
|
[''], |
||||
|
['CHANGELOG.md'], |
||||
|
['LICENSE'], |
||||
|
['skins/../passwd'], |
||||
|
['skins/elastic/templates/about.html'], |
||||
|
['plugins/acl/composer.json'], |
||||
|
['program/include/iniset.php'], |
||||
|
['program/localization/index.inc'], |
||||
|
['public_html/.htaccess'], |
||||
|
['vendor/friendsofphp/php-cs-fixer/logo.png'], |
||||
|
]; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Test forbidden resources |
||||
|
*/ |
||||
|
#[DataProvider('provideForbiddenResources')]
|
||||
|
public function testForbiddenResources($path): void |
||||
|
{ |
||||
|
$response = $this->request('GET', 'static.php/' . $path); |
||||
|
|
||||
|
$this->assertSame(404, $response->getStatusCode()); |
||||
|
$this->assertSame('', (string) $response->getBody()); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Test handling of Modified-Since header |
||||
|
*/ |
||||
|
public function testModifiedSinceHeader(): void |
||||
|
{ |
||||
|
$this->markTestIncomplete(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Test handling of Range header |
||||
|
*/ |
||||
|
public function testRangeHeader(): void |
||||
|
{ |
||||
|
$this->markTestIncomplete(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,49 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Roundcube\Tests; |
||||
|
|
||||
|
use PHPUnit\Framework\TestCase; |
||||
|
use Symfony\Component\Process\Process; |
||||
|
|
||||
|
/** |
||||
|
* Test class to test HTTP requests to Roundcube |
||||
|
*/ |
||||
|
class ServerTestCase extends TestCase |
||||
|
{ |
||||
|
protected static $phpProcess; |
||||
|
|
||||
|
#[\Override]
|
||||
|
public static function setUpBeforeClass(): void |
||||
|
{ |
||||
|
$path = realpath(__DIR__ . '/../public_html'); |
||||
|
$cmd = ['php', '-S', 'localhost:8000', '-t', $path]; |
||||
|
$env = []; |
||||
|
|
||||
|
static::$phpProcess = new Process($cmd, null, $env); |
||||
|
static::$phpProcess->setWorkingDirectory($path); |
||||
|
static::$phpProcess->start(); |
||||
|
usleep(50 * 1000); // give the server some time before we start testing
|
||||
|
} |
||||
|
|
||||
|
#[\Override]
|
||||
|
public static function tearDownAfterClass(): void |
||||
|
{ |
||||
|
static::$phpProcess->stop(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* HTTP client request |
||||
|
*/ |
||||
|
protected function request($method, $path, $options = []) |
||||
|
{ |
||||
|
$config = [ |
||||
|
'base_uri' => 'http://localhost:8000', |
||||
|
'http_errors' => false, // no exceptions for HTTP error codes
|
||||
|
'handler' => null, // reset Mock state from other tests
|
||||
|
]; |
||||
|
|
||||
|
$client = \rcmail::get_instance()->get_http_client($config); |
||||
|
|
||||
|
return $client->request($method, $path, $options); |
||||
|
} |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue