Migrate tests

This commit is contained in:
Daniel Hensby 2018-06-12 14:26:19 +01:00 committed by Damian Mooyman
parent 6bb69d1ae5
commit e76cf93514
5 changed files with 343 additions and 16 deletions

View File

@ -0,0 +1,110 @@
<?php
namespace SilverStripe\Control\Tests;
use SilverStripe\Control\HTTP;
use SilverStripe\Control\Middleware\HTTPCacheControlMiddleware;
use SilverStripe\Control\Session;
use SilverStripe\Control\Tests\HTTPCacheControlIntegrationTest\RuleController;
use SilverStripe\Control\Tests\HTTPCacheControlIntegrationTest\SessionController;
use SilverStripe\Core\Config\Config;
use SilverStripe\Dev\FunctionalTest;
class HTTPCacheControlIntegrationTest extends FunctionalTest
{
protected static $extra_controllers = [
SessionController::class,
RuleController::class,
];
protected function setUp()
{
parent::setUp();
Config::modify()->remove(HTTP::class, 'disable_http_cache');
HTTPCacheControlMiddleware::reset();
}
public function testFormCSRF()
{
// CSRF sets caching to disabled
$response = $this->get('HTTPCacheControlIntegrationTest_SessionController/showform');
$header = $response->getHeader('Cache-Control');
$this->assertFalse($response->isError());
$this->assertNotContains('public', $header);
$this->assertNotContains('private', $header);
$this->assertContains('no-cache', $header);
$this->assertContains('no-store', $header);
$this->assertContains('must-revalidate', $header);
}
public function testPublicForm()
{
// Public forms (http get) allow public caching
$response = $this->get('HTTPCacheControlIntegrationTest_SessionController/showpublicform');
$header = $response->getHeader('Cache-Control');
$this->assertFalse($response->isError());
$this->assertContains('public', $header);
$this->assertContains('must-revalidate', $header);
$this->assertNotContains('no-cache', $response->getHeader('Cache-Control'));
$this->assertNotContains('no-store', $response->getHeader('Cache-Control'));
}
public function testPrivateActionsError()
{
// disallowed private actions don't cache
$response = $this->get('HTTPCacheControlIntegrationTest_SessionController/privateaction');
$header = $response->getHeader('Cache-Control');
$this->assertTrue($response->isError());
$this->assertContains('no-cache', $header);
$this->assertContains('no-store', $header);
$this->assertContains('must-revalidate', $header);
}
public function testPrivateActionsAuthenticated()
{
$this->logInWithPermission('ADMIN');
// Authenticated actions are private cache
$response = $this->get('HTTPCacheControlIntegrationTest_SessionController/privateaction');
$header = $response->getHeader('Cache-Control');
$this->assertFalse($response->isError());
$this->assertContains('private', $header);
$this->assertContains('must-revalidate', $header);
$this->assertNotContains('no-cache', $header);
$this->assertNotContains('no-store', $header);
}
public function testPrivateCache()
{
$response = $this->get('HTTPCacheControlIntegrationTest_RuleController/privateaction');
$header = $response->getHeader('Cache-Control');
$this->assertFalse($response->isError());
$this->assertContains('private', $header);
$this->assertContains('must-revalidate', $header);
$this->assertNotContains('no-cache', $header);
$this->assertNotContains('no-store', $header);
}
public function testPublicCache()
{
$response = $this->get('HTTPCacheControlIntegrationTest_RuleController/publicaction');
$header = $response->getHeader('Cache-Control');
$this->assertFalse($response->isError());
$this->assertContains('public', $header);
$this->assertContains('must-revalidate', $header);
$this->assertNotContains('no-cache', $header);
$this->assertNotContains('no-store', $header);
$this->assertContains('max-age=9000', $header);
}
public function testDisabledCache()
{
$response = $this->get('HTTPCacheControlIntegrationTest_RuleController/disabledaction');
$header = $response->getHeader('Cache-Control');
$this->assertFalse($response->isError());
$this->assertNotContains('public', $header);
$this->assertNotContains('private', $header);
$this->assertContains('no-cache', $header);
$this->assertContains('no-store', $header);
$this->assertContains('must-revalidate', $header);
}
}

View File

@ -0,0 +1,45 @@
<?php
namespace SilverStripe\Control\Tests\HTTPCacheControlIntegrationTest;
use SilverStripe\Control\Controller;
use SilverStripe\Control\Middleware\HTTPCacheControlMiddleware;
use SilverStripe\Dev\TestOnly;
class RuleController extends Controller implements TestOnly
{
private static $url_segment = 'HTTPCacheControlIntegrationTest_RuleController';
private static $allowed_actions = [
'privateaction',
'publicaction',
'disabledaction',
];
protected function init()
{
parent::init();
// Prefer public by default
HTTPCacheControlMiddleware::singleton()->publicCache();
}
public function privateaction()
{
HTTPCacheControlMiddleware::singleton()->privateCache();
return 'private content';
}
public function publicaction()
{
HTTPCacheControlMiddleware::singleton()
->publicCache()
->setMaxAge(9000);
return 'public content';
}
public function disabledaction()
{
HTTPCacheControlMiddleware::singleton()->disableCache();
return 'uncached content';
}
}

View File

@ -0,0 +1,81 @@
<?php
namespace SilverStripe\Control\Tests\HTTPCacheControlIntegrationTest;
use SilverStripe\Control\Controller;
use SilverStripe\Control\Middleware\HTTPCacheControlMiddleware;
use SilverStripe\Dev\TestOnly;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\FormAction;
use SilverStripe\Forms\TextField;
use SilverStripe\Security\Permission;
use SilverStripe\Security\SecurityToken;
class SessionController extends Controller implements TestOnly
{
private static $url_segment = 'HTTPCacheControlIntegrationTest_SessionController';
private static $allowed_actions = [
'showform',
'privateaction',
'publicaction',
'showpublicform',
'Form',
];
protected function init()
{
parent::init();
// Prefer public by default
HTTPCacheControlMiddleware::singleton()->publicCache();
}
public function getContent()
{
return '<p>Hello world</p>';
}
public function showform()
{
// Form should be set to private due to CSRF
SecurityToken::enable();
return $this->renderWith('BlankPage');
}
public function showpublicform()
{
// Public form doesn't use CSRF and thus no session usage
SecurityToken::disable();
return $this->renderWith('BlankPage');
}
/**
* @return string
* @throws \SilverStripe\Control\HTTPResponse_Exception
*/
public function privateaction()
{
if (!Permission::check('ANYCODE')) {
$this->httpError(403, 'Not allowed');
}
return 'ok';
}
public function publicaction()
{
return 'Hello!';
}
public function Form()
{
$form = new Form(
$this,
'Form',
new FieldList(new TextField('Name')),
new FieldList(new FormAction('submit', 'Submit'))
);
$form->setFormMethod('GET');
return $form;
}
}

View File

@ -7,6 +7,8 @@ use SilverStripe\Control\Director;
use SilverStripe\Control\HTTP; use SilverStripe\Control\HTTP;
use SilverStripe\Control\HTTPRequest; use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\HTTPResponse; use SilverStripe\Control\HTTPResponse;
use SilverStripe\Control\Middleware\HTTPCacheControlMiddleware;
use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Injector\Injector; use SilverStripe\Core\Injector\Injector;
use SilverStripe\Core\Kernel; use SilverStripe\Core\Kernel;
use SilverStripe\Dev\FunctionalTest; use SilverStripe\Dev\FunctionalTest;
@ -18,31 +20,45 @@ use SilverStripe\Dev\FunctionalTest;
*/ */
class HTTPTest extends FunctionalTest class HTTPTest extends FunctionalTest
{ {
protected function setUp()
{
parent::setUp();
// Remove dev-only config
Config::modify()->remove(HTTP::class, 'disable_http_cache');
HTTPCacheControlMiddleware::reset();
}
public function testAddCacheHeaders() public function testAddCacheHeaders()
{ {
$body = "<html><head></head><body><h1>Mysite</h1></body></html>"; $body = "<html><head></head><body><h1>Mysite</h1></body></html>";
$response = new HTTPResponse($body, 200); $response = new HTTPResponse($body, 200);
$this->assertEmpty($response->getHeader('Cache-Control')); HTTPCacheControlMiddleware::singleton()->publicCache();
HTTP::set_cache_age(30); HTTP::set_cache_age(30);
HTTP::add_cache_headers($response); HTTP::add_cache_headers($response);
$this->assertNotEmpty($response->getHeader('Cache-Control')); $this->assertNotEmpty($response->getHeader('Cache-Control'));
// Ensure max-age is zero for development.
/** @var Kernel $kernel */ /** @var Kernel $kernel */
$kernel = Injector::inst()->get(Kernel::class); $kernel = Injector::inst()->get(Kernel::class);
$kernel->setEnvironment(Kernel::DEV); // Ensure cache headers are set correctly when disabled via config (e.g. when dev)
Config::modify()->set(HTTP::class, 'disable_http_cache', true);
HTTPCacheControlMiddleware::reset();
HTTPCacheControlMiddleware::singleton()->publicCache();
HTTP::set_cache_age(30);
$response = new HTTPResponse($body, 200); $response = new HTTPResponse($body, 200);
HTTP::add_cache_headers($response); HTTP::add_cache_headers($response);
$this->assertContains('max-age=0', $response->getHeader('Cache-Control')); $this->assertContains('no-cache', $response->getHeader('Cache-Control'));
$this->assertContains('no-store', $response->getHeader('Cache-Control'));
$this->assertContains('must-revalidate', $response->getHeader('Cache-Control'));
// Ensure max-age setting is respected in production. // Ensure max-age setting is respected in production.
$kernel->setEnvironment(Kernel::LIVE); Config::modify()->remove(HTTP::class, 'disable_http_cache');
HTTPCacheControlMiddleware::reset();
HTTPCacheControlMiddleware::singleton()->publicCache();
HTTP::set_cache_age(30);
$response = new HTTPResponse($body, 200); $response = new HTTPResponse($body, 200);
HTTP::add_cache_headers($response); HTTP::add_cache_headers($response);
$this->assertContains('max-age=30', explode(', ', $response->getHeader('Cache-Control'))); $this->assertContains('max-age=30', $response->getHeader('Cache-Control'));
$this->assertNotContains('max-age=0', $response->getHeader('Cache-Control')); $this->assertNotContains('max-age=0', $response->getHeader('Cache-Control'));
// Still "live": Ensure header's aren't overridden if already set (using purposefully different values). // Still "live": Ensure header's aren't overridden if already set (using purposefully different values).
@ -51,35 +67,41 @@ class HTTPTest extends FunctionalTest
'Pragma' => 'no-cache', 'Pragma' => 'no-cache',
'Cache-Control' => 'max-age=0, no-cache, no-store', 'Cache-Control' => 'max-age=0, no-cache, no-store',
); );
HTTPCacheControlMiddleware::reset();
HTTPCacheControlMiddleware::singleton()->publicCache();
HTTP::set_cache_age(30);
$response = new HTTPResponse($body, 200); $response = new HTTPResponse($body, 200);
foreach ($headers as $name => $value) { foreach ($headers as $name => $value) {
$response->addHeader($name, $value); $response->addHeader($name, $value);
} }
// Expect a warning if the header is already set
$this->expectException(
\PHPUnit_Framework_Error_Warning::class,
'Cache-Control header has already been set. '
. 'Please use HTTPCacheControl API to set caching options instead.'
);
HTTP::add_cache_headers($response); HTTP::add_cache_headers($response);
foreach ($headers as $name => $value) {
$this->assertEquals($value, $response->getHeader($name));
}
} }
public function testConfigVary() public function testConfigVary()
{ {
/** @var Kernel $kernel */
$kernel = Injector::inst()->get(Kernel::class);
$body = "<html><head></head><body><h1>Mysite</h1></body></html>"; $body = "<html><head></head><body><h1>Mysite</h1></body></html>";
$response = new HTTPResponse($body, 200); $response = new HTTPResponse($body, 200);
$kernel->setEnvironment(Kernel::LIVE);
HTTP::set_cache_age(30); HTTP::set_cache_age(30);
HTTP::add_cache_headers($response); HTTP::add_cache_headers($response);
$v = $response->getHeader('Vary'); $v = $response->getHeader('Vary');
$this->assertNotEmpty($v); $this->assertNotEmpty($v);
$this->assertContains("Cookie", $v);
$this->assertContains("X-Forwarded-Protocol", $v); $this->assertContains("X-Forwarded-Protocol", $v);
$this->assertContains("User-Agent", $v); $this->assertContains("X-Requested-With", $v);
$this->assertContains("Accept", $v); $this->assertNotContains("Cookie", $v);
$this->assertNotContains("User-Agent", $v);
$this->assertNotContains("Accept", $v);
HTTP::config()->update('vary', ''); HTTP::config()->update('vary', '');
HTTPCacheControlMiddleware::reset();
$response = new HTTPResponse($body, 200); $response = new HTTPResponse($body, 200);
HTTP::add_cache_headers($response); HTTP::add_cache_headers($response);

View File

@ -0,0 +1,69 @@
<?php
namespace SilverStripe\Control\Tests\Middleware;
use SilverStripe\Control\Middleware\HTTPCacheControlMiddleware;
use SilverStripe\Dev\SapphireTest;
class HTTPCacheControlMiddlewareTest extends SapphireTest
{
public function testCachingPriorities()
{
$hcc = new HTTPCacheControlMiddleware();
$this->assertTrue($this->isDisabled($hcc), 'caching starts as disabled');
$hcc->enableCache();
$this->assertFalse($this->isDisabled($hcc));
$hcc->publicCache();
$this->assertTrue($this->isPublic($hcc), 'public can be set at start');
$hcc->privateCache();
$this->assertTrue($this->isPrivate($hcc), 'private overrides public');
$hcc->publicCache();
$this->assertFalse($this->isPublic($hcc), 'public does not overrides private');
$hcc->disableCache();
$this->assertTrue($this->isDisabled($hcc), 'disabled overrides private');
$hcc->privateCache();
$this->assertFalse($this->isPrivate($hcc), 'private does not override disabled');
$hcc->enableCache(true);
$this->assertFalse($this->isDisabled($hcc));
$hcc->publicCache(true);
$this->assertTrue($this->isPublic($hcc), 'force-public overrides disabled');
$hcc->privateCache();
$this->assertFalse($this->isPrivate($hcc), 'private does not overrdie force-public');
$hcc->privateCache(true);
$this->assertTrue($this->isPrivate($hcc), 'force-private overrides force-public');
$hcc->publicCache(true);
$this->assertFalse($this->isPublic($hcc), 'force-public does not override force-private');
$hcc->disableCache(true);
$this->assertTrue($this->isDisabled($hcc), 'force-disabled overrides force-private');
$hcc->publicCache(true);
$this->assertFalse($this->isPublic($hcc), 'force-public does not overrides force-disabled');
}
protected function isPrivate(HTTPCacheControlMiddleware $hcc)
{
return $hcc->hasDirective('private') && !$hcc->hasDirective('public') && !$hcc->hasDirective('no-cache');
}
protected function isPublic(HTTPCacheControlMiddleware $hcc)
{
return $hcc->hasDirective('public') && !$hcc->hasDirective('private') && !$hcc->hasDirective('no-cache');
}
protected function isDisabled(HTTPCacheControlMiddleware $hcc)
{
return $hcc->hasDirective('no-cache') && !$hcc->hasDirective('private') && !$hcc->hasDirective('public');
}
}