Merge "Add config for serving main Page from the domain root"
[lhc/web/wiklou.git] / tests / phpunit / unit / includes / Rest / RouterTest.php
1 <?php
2
3 namespace MediaWiki\Tests\Rest;
4
5 use GuzzleHttp\Psr7\Uri;
6 use MediaWiki\Permissions\PermissionManager;
7 use MediaWiki\Rest\BasicAccess\StaticBasicAuthorizer;
8 use MediaWiki\Rest\Handler;
9 use MediaWiki\Rest\HttpException;
10 use MediaWiki\Rest\RequestData;
11 use MediaWiki\Rest\RequestInterface;
12 use MediaWiki\Rest\ResponseFactory;
13 use MediaWiki\Rest\Router;
14 use MediaWiki\Rest\Validator\Validator;
15 use Psr\Container\ContainerInterface;
16 use Wikimedia\ObjectFactory;
17 use User;
18
19 /**
20 * @covers \MediaWiki\Rest\Router
21 */
22 class RouterTest extends \MediaWikiUnitTestCase {
23 /** @return Router */
24 private function createRouter( RequestInterface $request, $authError = null ) {
25 $objectFactory = new ObjectFactory(
26 $this->getMockForAbstractClass( ContainerInterface::class )
27 );
28 $permissionManager = $this->createMock( PermissionManager::class );
29 return new Router(
30 [ __DIR__ . '/testRoutes.json' ],
31 [],
32 '/rest',
33 new \EmptyBagOStuff(),
34 new ResponseFactory( [] ),
35 new StaticBasicAuthorizer( $authError ),
36 $objectFactory,
37 new Validator( $objectFactory, $permissionManager, $request, new User )
38 );
39 }
40
41 public function testPrefixMismatch() {
42 $request = new RequestData( [ 'uri' => new Uri( '/bogus' ) ] );
43 $router = $this->createRouter( $request );
44 $response = $router->execute( $request );
45 $this->assertSame( 404, $response->getStatusCode() );
46 }
47
48 public function testWrongMethod() {
49 $request = new RequestData( [
50 'uri' => new Uri( '/rest/user/joe/hello' ),
51 'method' => 'OPTIONS'
52 ] );
53 $router = $this->createRouter( $request );
54 $response = $router->execute( $request );
55 $this->assertSame( 405, $response->getStatusCode() );
56 $this->assertSame( 'Method Not Allowed', $response->getReasonPhrase() );
57 $this->assertSame( 'GET', $response->getHeaderLine( 'Allow' ) );
58 }
59
60 public function testHeadToGet() {
61 $request = new RequestData( [
62 'uri' => new Uri( '/rest/user/joe/hello' ),
63 'method' => 'HEAD'
64 ] );
65 $router = $this->createRouter( $request );
66 $response = $router->execute( $request );
67 $this->assertSame( 200, $response->getStatusCode() );
68 }
69
70 public function testNoMatch() {
71 $request = new RequestData( [ 'uri' => new Uri( '/rest/bogus' ) ] );
72 $router = $this->createRouter( $request );
73 $response = $router->execute( $request );
74 $this->assertSame( 404, $response->getStatusCode() );
75 // TODO: add more information to the response body and test for its presence here
76 }
77
78 public static function throwHandlerFactory() {
79 return new class extends Handler {
80 public function execute() {
81 throw new HttpException( 'Mock error', 555 );
82 }
83 };
84 }
85
86 public function testException() {
87 $request = new RequestData( [ 'uri' => new Uri( '/rest/mock/RouterTest/throw' ) ] );
88 $router = $this->createRouter( $request );
89 $response = $router->execute( $request );
90 $this->assertSame( 555, $response->getStatusCode() );
91 $body = $response->getBody();
92 $body->rewind();
93 $data = json_decode( $body->getContents(), true );
94 $this->assertSame( 'Mock error', $data['message'] );
95 }
96
97 public function testBasicAccess() {
98 // Using the throwing handler is a way to assert that the handler is not executed
99 $request = new RequestData( [ 'uri' => new Uri( '/rest/mock/RouterTest/throw' ) ] );
100 $router = $this->createRouter( $request, 'test-error' );
101 $response = $router->execute( $request );
102 $this->assertSame( 403, $response->getStatusCode() );
103 $body = $response->getBody();
104 $body->rewind();
105 $data = json_decode( $body->getContents(), true );
106 $this->assertSame( 'test-error', $data['error'] );
107 }
108 }