New configuration variable $wgRestAPIAdditionalRouteFiles allows specifying additional Core REST API route files to include. The initial use is to include development routes from new file coreDevelopmentRoutes.json only on testing wikis, but not on production wikis. Bug: T247997 Change-Id: Iff8a9b7f4cafb29162e9b10f3d32e2a85f6f58df
136 lines
4.1 KiB
PHP
136 lines
4.1 KiB
PHP
<?php
|
|
|
|
namespace MediaWiki\Tests\Rest;
|
|
|
|
use GuzzleHttp\Psr7\Uri;
|
|
use MediaWiki\Permissions\PermissionManager;
|
|
use MediaWiki\Rest\BasicAccess\StaticBasicAuthorizer;
|
|
use MediaWiki\Rest\Handler;
|
|
use MediaWiki\Rest\HttpException;
|
|
use MediaWiki\Rest\RequestData;
|
|
use MediaWiki\Rest\RequestInterface;
|
|
use MediaWiki\Rest\ResponseFactory;
|
|
use MediaWiki\Rest\Router;
|
|
use MediaWiki\Rest\Validator\Validator;
|
|
use Psr\Container\ContainerInterface;
|
|
use User;
|
|
use Wikimedia\ObjectFactory;
|
|
|
|
/**
|
|
* @covers \MediaWiki\Rest\Router
|
|
*/
|
|
class RouterTest extends \MediaWikiUnitTestCase {
|
|
/** @return Router */
|
|
private function createRouter(
|
|
RequestInterface $request,
|
|
$authError = null,
|
|
$additionalRouteFiles = []
|
|
) {
|
|
$objectFactory = new ObjectFactory(
|
|
$this->getMockForAbstractClass( ContainerInterface::class )
|
|
);
|
|
$permissionManager = $this->createMock( PermissionManager::class );
|
|
$routeFiles = array_merge( [ __DIR__ . '/testRoutes.json' ], $additionalRouteFiles );
|
|
return new Router(
|
|
$routeFiles,
|
|
[],
|
|
'/rest',
|
|
new \EmptyBagOStuff(),
|
|
new ResponseFactory( [] ),
|
|
new StaticBasicAuthorizer( $authError ),
|
|
$objectFactory,
|
|
new Validator( $objectFactory, $permissionManager, $request, new User )
|
|
);
|
|
}
|
|
|
|
public function testPrefixMismatch() {
|
|
$request = new RequestData( [ 'uri' => new Uri( '/bogus' ) ] );
|
|
$router = $this->createRouter( $request );
|
|
$response = $router->execute( $request );
|
|
$this->assertSame( 404, $response->getStatusCode() );
|
|
}
|
|
|
|
public function testWrongMethod() {
|
|
$request = new RequestData( [
|
|
'uri' => new Uri( '/rest/mock/RouterTest/hello' ),
|
|
'method' => 'OPTIONS'
|
|
] );
|
|
$router = $this->createRouter( $request );
|
|
$response = $router->execute( $request );
|
|
$this->assertSame( 405, $response->getStatusCode() );
|
|
$this->assertSame( 'Method Not Allowed', $response->getReasonPhrase() );
|
|
$this->assertSame( 'GET', $response->getHeaderLine( 'Allow' ) );
|
|
}
|
|
|
|
public function testHeadToGet() {
|
|
$request = new RequestData( [
|
|
'uri' => new Uri( '/rest/mock/RouterTest/hello' ),
|
|
'method' => 'HEAD'
|
|
] );
|
|
$router = $this->createRouter( $request );
|
|
$response = $router->execute( $request );
|
|
$this->assertSame( 200, $response->getStatusCode() );
|
|
}
|
|
|
|
public function testNoMatch() {
|
|
$request = new RequestData( [ 'uri' => new Uri( '/rest/bogus' ) ] );
|
|
$router = $this->createRouter( $request );
|
|
$response = $router->execute( $request );
|
|
$this->assertSame( 404, $response->getStatusCode() );
|
|
// TODO: add more information to the response body and test for its presence here
|
|
}
|
|
|
|
public static function throwHandlerFactory() {
|
|
return new class extends Handler {
|
|
public function execute() {
|
|
throw new HttpException( 'Mock error', 555 );
|
|
}
|
|
};
|
|
}
|
|
|
|
public function testException() {
|
|
$request = new RequestData( [ 'uri' => new Uri( '/rest/mock/RouterTest/throw' ) ] );
|
|
$router = $this->createRouter( $request );
|
|
$response = $router->execute( $request );
|
|
$this->assertSame( 555, $response->getStatusCode() );
|
|
$body = $response->getBody();
|
|
$body->rewind();
|
|
$data = json_decode( $body->getContents(), true );
|
|
$this->assertSame( 'Mock error', $data['message'] );
|
|
}
|
|
|
|
public function testBasicAccess() {
|
|
// Using the throwing handler is a way to assert that the handler is not executed
|
|
$request = new RequestData( [ 'uri' => new Uri( '/rest/mock/RouterTest/throw' ) ] );
|
|
$router = $this->createRouter( $request, 'test-error', [] );
|
|
$response = $router->execute( $request );
|
|
$this->assertSame( 403, $response->getStatusCode() );
|
|
$body = $response->getBody();
|
|
$body->rewind();
|
|
$data = json_decode( $body->getContents(), true );
|
|
$this->assertSame( 'test-error', $data['error'] );
|
|
}
|
|
|
|
/**
|
|
* @dataProvider providePaths
|
|
*/
|
|
public function testAdditionalEndpoints( $path ) {
|
|
$request = new RequestData( [
|
|
'uri' => new Uri( $path )
|
|
] );
|
|
$router = $this->createRouter(
|
|
$request,
|
|
null,
|
|
[ __DIR__ . '/testAdditionalRoutes.json' ]
|
|
);
|
|
$response = $router->execute( $request );
|
|
$this->assertSame( 200, $response->getStatusCode() );
|
|
}
|
|
|
|
public static function providePaths() {
|
|
return [
|
|
[ '/rest/mock/RouterTest/hello' ],
|
|
[ '/rest/mock/RouterTest/hello/two' ],
|
|
];
|
|
}
|
|
}
|