
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