REST: Testable EntryPoint
* Split EntryPoint into a static main() and a non-static execute() * Add tests for execute() Change-Id: I025356b04ddc5a16494f98c446d785d6bb05ab10
This commit is contained in:
parent
f1c11c2c49
commit
4e0e36397c
5 changed files with 134 additions and 13 deletions
|
|
@ -6,8 +6,16 @@ use ExtensionRegistry;
|
|||
use MediaWiki\MediaWikiServices;
|
||||
use RequestContext;
|
||||
use Title;
|
||||
use WebResponse;
|
||||
|
||||
class EntryPoint {
|
||||
/** @var RequestInterface */
|
||||
private $request;
|
||||
/** @var WebResponse */
|
||||
private $webResponse;
|
||||
/** @var Router */
|
||||
private $router;
|
||||
|
||||
public static function main() {
|
||||
// URL safety checks
|
||||
global $wgRequest;
|
||||
|
|
@ -21,8 +29,8 @@ class EntryPoint {
|
|||
RequestContext::getMain()->setTitle( $wgTitle );
|
||||
|
||||
$services = MediaWikiServices::getInstance();
|
||||
|
||||
$conf = $services->getMainConfig();
|
||||
|
||||
$request = new RequestFromGlobals( [
|
||||
'cookiePrefix' => $conf->get( 'CookiePrefix' )
|
||||
] );
|
||||
|
|
@ -36,20 +44,35 @@ class EntryPoint {
|
|||
new ResponseFactory
|
||||
);
|
||||
|
||||
$response = $router->execute( $request );
|
||||
$entryPoint = new self(
|
||||
$request,
|
||||
$wgRequest->response(),
|
||||
$router );
|
||||
$entryPoint->execute();
|
||||
}
|
||||
|
||||
$webResponse = $wgRequest->response();
|
||||
$webResponse->header(
|
||||
public function __construct( RequestInterface $request, WebResponse $webResponse,
|
||||
Router $router
|
||||
) {
|
||||
$this->request = $request;
|
||||
$this->webResponse = $webResponse;
|
||||
$this->router = $router;
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
$response = $this->router->execute( $this->request );
|
||||
|
||||
$this->webResponse->header(
|
||||
'HTTP/' . $response->getProtocolVersion() . ' ' .
|
||||
$response->getStatusCode() . ' ' .
|
||||
$response->getReasonPhrase() );
|
||||
|
||||
foreach ( $response->getRawHeaderLines() as $line ) {
|
||||
$webResponse->header( $line );
|
||||
$this->webResponse->header( $line );
|
||||
}
|
||||
|
||||
foreach ( $response->getCookies() as $cookie ) {
|
||||
$webResponse->setCookie(
|
||||
$this->webResponse->setCookie(
|
||||
$cookie['name'],
|
||||
$cookie['value'],
|
||||
$cookie['expiry'],
|
||||
|
|
|
|||
90
tests/phpunit/includes/Rest/EntryPointTest.php
Normal file
90
tests/phpunit/includes/Rest/EntryPointTest.php
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
|
||||
namespace MediaWiki\Tests\Rest;
|
||||
|
||||
use EmptyBagOStuff;
|
||||
use GuzzleHttp\Psr7\Uri;
|
||||
use GuzzleHttp\Psr7\Stream;
|
||||
use MediaWiki\Rest\Handler;
|
||||
use MediaWikiTestCase;
|
||||
use MediaWiki\Rest\EntryPoint;
|
||||
use MediaWiki\Rest\RequestData;
|
||||
use MediaWiki\Rest\ResponseFactory;
|
||||
use MediaWiki\Rest\Router;
|
||||
use WebResponse;
|
||||
|
||||
/**
|
||||
* @covers \MediaWiki\Rest\EntryPoint
|
||||
* @covers \MediaWiki\Rest\Router
|
||||
*/
|
||||
class EntryPointTest extends MediaWikiTestCase {
|
||||
private static $mockHandler;
|
||||
|
||||
private function createRouter() {
|
||||
return new Router(
|
||||
[ __DIR__ . '/testRoutes.json' ],
|
||||
[],
|
||||
'/rest',
|
||||
new EmptyBagOStuff(),
|
||||
new ResponseFactory() );
|
||||
}
|
||||
|
||||
private function createWebResponse() {
|
||||
return $this->getMockBuilder( WebResponse::class )
|
||||
->setMethods( [ 'header' ] )
|
||||
->getMock();
|
||||
}
|
||||
|
||||
public static function mockHandlerHeader() {
|
||||
return new class extends Handler {
|
||||
public function execute() {
|
||||
$response = $this->getResponseFactory()->create();
|
||||
$response->setHeader( 'Foo', 'Bar' );
|
||||
return $response;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public function testHeader() {
|
||||
$webResponse = $this->createWebResponse();
|
||||
$webResponse->expects( $this->any() )
|
||||
->method( 'header' )
|
||||
->withConsecutive(
|
||||
[ 'HTTP/1.1 200 OK', true, null ],
|
||||
[ 'Foo: Bar', true, null ]
|
||||
);
|
||||
|
||||
$entryPoint = new EntryPoint(
|
||||
new RequestData( [ 'uri' => new Uri( '/rest/mock/EntryPoint/header' ) ] ),
|
||||
$webResponse,
|
||||
$this->createRouter() );
|
||||
$entryPoint->execute();
|
||||
$this->assertTrue( true );
|
||||
}
|
||||
|
||||
public static function mockHandlerBodyRewind() {
|
||||
return new class extends Handler {
|
||||
public function execute() {
|
||||
$response = $this->getResponseFactory()->create();
|
||||
$stream = new Stream( fopen( 'php://memory', 'w+' ) );
|
||||
$stream->write( 'hello' );
|
||||
$response->setBody( $stream );
|
||||
return $response;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure EntryPoint rewinds a seekable body stream before reading.
|
||||
*/
|
||||
public function testBodyRewind() {
|
||||
$entryPoint = new EntryPoint(
|
||||
new RequestData( [ 'uri' => new Uri( '/rest/mock/EntryPoint/bodyRewind' ) ] ),
|
||||
$this->createWebResponse(),
|
||||
$this->createRouter() );
|
||||
ob_start();
|
||||
$entryPoint->execute();
|
||||
$this->assertSame( 'hello', ob_get_clean() );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -49,7 +49,7 @@ class HelloHandlerTest extends MediaWikiTestCase {
|
|||
/** @dataProvider provideTestViaRouter */
|
||||
public function testViaRouter( $requestInfo, $responseInfo ) {
|
||||
$router = new Router(
|
||||
[ __DIR__ . '/testRoutes.json' ],
|
||||
[ __DIR__ . '/../testRoutes.json' ],
|
||||
[],
|
||||
'/rest',
|
||||
new EmptyBagOStuff(),
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
[
|
||||
{
|
||||
"path": "/user/{name}/hello",
|
||||
"class": "MediaWiki\\Rest\\Handler\\HelloHandler"
|
||||
}
|
||||
]
|
||||
14
tests/phpunit/includes/Rest/testRoutes.json
Normal file
14
tests/phpunit/includes/Rest/testRoutes.json
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
[
|
||||
{
|
||||
"path": "/user/{name}/hello",
|
||||
"class": "MediaWiki\\Rest\\Handler\\HelloHandler"
|
||||
},
|
||||
{
|
||||
"path": "/mock/EntryPoint/header",
|
||||
"factory": "MediaWiki\\Tests\\Rest\\EntryPointTest::mockHandlerHeader"
|
||||
},
|
||||
{
|
||||
"path": "/mock/EntryPoint/bodyRewind",
|
||||
"factory": "MediaWiki\\Tests\\Rest\\EntryPointTest::mockHandlerBodyRewind"
|
||||
}
|
||||
]
|
||||
Loading…
Reference in a new issue