4 * @covers PageDataRequestHandler
10 class PageDataRequestHandlerTest
extends \MediaWikiTestCase
{
15 private $interfaceTitle;
22 protected function setUp() {
25 $this->interfaceTitle
= Title
::newFromText( "Special:PageDataRequestHandlerTest" );
27 $this->obLevel
= ob_get_level();
30 protected function tearDown() {
31 $obLevel = ob_get_level();
33 while ( ob_get_level() > $this->obLevel
) {
37 if ( $obLevel !== $this->obLevel
) {
38 $this->fail( "Test changed output buffer level: was {$this->obLevel}" .
39 "before test, but $obLevel after test."
47 * @return PageDataRequestHandler
49 protected function newHandler() {
50 return new PageDataRequestHandler( 'json' );
54 * @param array $params
55 * @param string[] $headers
59 protected function makeOutputPage( array $params, array $headers ) {
61 $request = new FauxRequest( $params );
62 $request->response()->header( 'Status: 200 OK', true, 200 ); // init/reset
64 foreach ( $headers as $name => $value ) {
65 $request->setHeader( strtoupper( $name ), $value );
68 // construct Context and OutputPage
69 $context = new DerivativeContext( RequestContext
::getMain() );
70 $context->setRequest( $request );
72 $output = new OutputPage( $context );
73 $output->setTitle( $this->interfaceTitle
);
74 $context->setOutput( $output );
79 public function handleRequestProvider() {
83 $cases[] = [ '', [], [], '!!', 400 ];
85 $cases[] = [ '', [ 'target' => 'Helsinki' ], [], '!!', 303, [ 'Location' => '!.+!' ] ];
88 foreach ( $cases as $c ) {
92 if ( isset( $case[1]['target'] ) ) {
93 $case[0] .= $case[1]['target'];
94 unset( $case[1]['target'] );
97 $subpageCases[] = $case;
100 $cases = array_merge( $cases, $subpageCases );
104 [ 'target' => 'Helsinki' ],
105 [ 'Accept' => 'text/HTML' ],
108 [ 'Location' => '!Helsinki$!' ]
114 'target' => 'Helsinki',
115 'revision' => '4242',
117 [ 'Accept' => 'text/HTML' ],
120 [ 'Location' => '!Helsinki(\?|&)oldid=4242!' ]
129 [ 'Location' => '!Helsinki&action=raw!' ]
132 // #31: /Q5 with "Accept: text/foobar" triggers a 406
136 [ 'Accept' => 'text/foobar' ],
145 [ 'Accept' => 'text/HTML' ],
148 [ 'Location' => '!Helsinki$!' ]
155 * @dataProvider handleRequestProvider
157 * @param string $subpage The subpage to request (or '')
158 * @param array $params Request parameters
159 * @param array $headers Request headers
160 * @param string $expectedOutput Regex to match the output against.
161 * @param int $expectedStatusCode Expected HTTP status code.
162 * @param string[] $expectedHeaders Expected HTTP response headers.
164 public function testHandleRequest(
169 $expectedStatusCode = 200,
170 array $expectedHeaders = []
172 $output = $this->makeOutputPage( $params, $headers );
173 $request = $output->getRequest();
175 /* @var FauxResponse $response */
176 $response = $request->response();
179 $handler = $this->newHandler();
183 $handler->handleRequest( $subpage, $request, $output );
185 if ( $output->getRedirect() !== '' ) {
186 // hack to apply redirect to web response
190 $text = ob_get_contents();
193 $this->assertEquals( $expectedStatusCode, $response->getStatusCode(), 'status code' );
194 $this->assertRegExp( $expectedOutput, $text, 'output' );
196 foreach ( $expectedHeaders as $name => $exp ) {
197 $value = $response->getHeader( $name );
198 $this->assertNotNull( $value, "header: $name" );
199 $this->assertInternalType( 'string', $value, "header: $name" );
200 $this->assertRegExp( $exp, $value, "header: $name" );
202 } catch ( HttpError
$e ) {
204 $this->assertEquals( $expectedStatusCode, $e->getStatusCode(), 'status code' );
205 $this->assertRegExp( $expectedOutput, $e->getHTML(), 'error output' );
208 // We always set "Access-Control-Allow-Origin: *"
209 $this->assertSame( '*', $response->getHeader( 'Access-Control-Allow-Origin' ) );
212 public function provideHttpContentNegotiation() {
213 $helsinki = Title
::newFromText( 'Helsinki' );
215 'Accept Header of HTML' => [
217 [ 'ACCEPT' => 'text/html' ], // headers
220 'Accept Header without weights' => [
222 [ 'ACCEPT' => '*/*, text/html, text/x-wiki' ],
223 'Helsinki&action=raw'
225 'Accept Header with weights' => [
227 [ 'ACCEPT' => 'text/*; q=0.5, text/json; q=0.7, application/rdf+xml; q=0.8' ],
228 'Helsinki&action=raw'
230 'Accept Header accepting evertyhing and HTML' => [
232 [ 'ACCEPT' => 'text/html, */*' ],
233 'Helsinki&action=raw'
235 'No Accept Header' => [
238 'Helsinki&action=raw'
244 * @dataProvider provideHttpContentNegotiation
246 * @param Title $title
247 * @param array $headers Request headers
248 * @param string $expectedRedirectSuffix Expected suffix of the HTTP Location header.
252 public function testHttpContentNegotiation(
255 $expectedRedirectSuffix
257 /* @var FauxResponse $response */
258 $output = $this->makeOutputPage( [], $headers );
259 $request = $output->getRequest();
261 $handler = $this->newHandler();
262 $handler->httpContentNegotiation( $request, $output, $title );
264 $this->assertStringEndsWith(
265 $expectedRedirectSuffix,
266 $output->getRedirect(),