This makes the PSR-7 interface for the MWHttpRequest available to all consumers that want to make use of it. This is of general utility and should not be limited to Wikibase. Also, it allows us to drop the Guzzle dependency from Wikibase entirely. As an alternative to moving the adapter (as is done with this patch), it was considered to refactor MWHttpRequest to support the interface directly. While that would come without the overhead of an additional class, it would require adding the interface methods to an already large class and deprecating the now redundant legacy methods. This would be an invasive refactoring that would not only affect the classes inheriting from MWHttpRequest, but also its consumers. It would seem that a conceptual refactoring of that magnitude would require a more substantial consensus among contributors (and maybe consumers) of these classes. Moving this adapter is seen as a step in building the case for why using standardized interfaces is a good idea and allowing for the discussion to be grounded of incorporating an existing adapter into a base class rather than the hypothetical discussion of adjusting it to an so far unused interface. Bug: T263989 Depends-On: I56ad52b561460121a8c84313cbd431dc811e2ae1 Change-Id: I2a27dead1d5f1403b8d255c5daf9ba5e7c313476
136 lines
4.2 KiB
PHP
136 lines
4.2 KiB
PHP
<?php
|
|
|
|
declare( strict_types = 1 );
|
|
|
|
use MediaWiki\Http\MwHttpRequestToResponseInterfaceAdapter;
|
|
use Psr\Http\Message\StreamInterface;
|
|
|
|
/**
|
|
* @covers \MediaWiki\Http\MwHttpRequestToResponseInterfaceAdapter
|
|
*
|
|
* @group Http
|
|
* @group small
|
|
*
|
|
* @license GPL-2.0-or-later
|
|
*/
|
|
class MwHttpRequestToResponseInterfaceAdapterTest extends MediaWikiUnitTestCase {
|
|
|
|
public function testGivenNotExecutedRequest_constructorThrows() {
|
|
$req = $this->newMockMWHttpRequestWithHeaders( [] );
|
|
|
|
$this->expectException( \LogicException::class );
|
|
new MwHttpRequestToResponseInterfaceAdapter( $req );
|
|
}
|
|
|
|
public function testGetHeaders() {
|
|
$headers = [
|
|
'foo' => [ 'bar' ],
|
|
'some' => [ 'such', 'other' ]
|
|
];
|
|
$mwHttpReq = $this->newMockMWHttpRequestWithHeaders( $headers );
|
|
|
|
$response = new MwHttpRequestToResponseInterfaceAdapter( $mwHttpReq );
|
|
$this->assertEquals( $headers, $response->getHeaders() );
|
|
}
|
|
|
|
public function testHasHeader() {
|
|
$mwHttpReq = $this->newMockMWHttpRequestWithHeaders( [
|
|
'foo' => [ 'bar' ],
|
|
] );
|
|
$response = new MwHttpRequestToResponseInterfaceAdapter( $mwHttpReq );
|
|
$this->assertTrue( $response->hasHeader( 'foo' ) );
|
|
}
|
|
|
|
public function testGivenExistingHeader_getHeaderReturnsValuesArray() {
|
|
$headerValues = [ 'bar', 'baz' ];
|
|
$mwHttpReq = $this->newMockMWHttpRequestWithHeaders( [
|
|
'foo' => $headerValues,
|
|
] );
|
|
$response = new MwHttpRequestToResponseInterfaceAdapter( $mwHttpReq );
|
|
$this->assertEquals( $headerValues, $response->getHeader( 'foo' ) );
|
|
}
|
|
|
|
public function testGivenNonExistingHeader_getHeaderReturnsEmptyArray() {
|
|
$mwHttpReq = $this->newMockMWHttpRequestWithHeaders( [
|
|
'some-header' => [ 'some', 'such' ],
|
|
] );
|
|
$response = new MwHttpRequestToResponseInterfaceAdapter( $mwHttpReq );
|
|
$this->assertEquals( [], $response->getHeader( 'foo' ) );
|
|
}
|
|
|
|
public function testGetBody() {
|
|
$req = $this->newMockMWHttpRequestWithHeaders( [ 'Some-header' => [ 'abc' ] ] );
|
|
$body = '{ "some": "body" }';
|
|
$req->expects( $this->once() )
|
|
->method( 'getContent' )
|
|
->willReturn( $body );
|
|
|
|
$response = new MwHttpRequestToResponseInterfaceAdapter( $req );
|
|
|
|
$this->assertEquals( $body, $response->getBody() );
|
|
}
|
|
|
|
public function testGetStatusCode() {
|
|
$req = $this->newMockMWHttpRequestWithHeaders( [ 'Some-header' => [ 'abc' ] ] );
|
|
$status = 200;
|
|
$req->expects( $this->once() )
|
|
->method( 'getStatus' )
|
|
->willReturn( $status );
|
|
|
|
$response = new MwHttpRequestToResponseInterfaceAdapter( $req );
|
|
|
|
$this->assertEquals( $status, $response->getStatusCode() );
|
|
}
|
|
|
|
public function testGivenExistingHeader_getHeaderLineReturnsCommaSeparatedValues() {
|
|
$mwHttpReq = $this->newMockMWHttpRequestWithHeaders( [
|
|
'foo' => [ 'bar', 'baz' ],
|
|
] );
|
|
$response = new MwHttpRequestToResponseInterfaceAdapter( $mwHttpReq );
|
|
$this->assertEquals( 'bar,baz', $response->getHeaderLine( 'foo' ) );
|
|
}
|
|
|
|
public function testGivenNonExistingHeader_getHeaderLineReturnsEmptyString() {
|
|
$mwHttpReq = $this->newMockMWHttpRequestWithHeaders( [
|
|
'some-header' => [ 'some', 'such' ],
|
|
] );
|
|
$response = new MwHttpRequestToResponseInterfaceAdapter( $mwHttpReq );
|
|
$this->assertSame( '', $response->getHeaderLine( 'foo' ) );
|
|
}
|
|
|
|
public function testGetProtocolVersionIsNotImplemented() {
|
|
$this->expectException( \LogicException::class );
|
|
( new MwHttpRequestToResponseInterfaceAdapter( $this->createMock( MWHttpRequest::class ) ) )
|
|
->getProtocolVersion();
|
|
}
|
|
|
|
/**
|
|
* @dataProvider unsupportedMethodsProvider
|
|
*/
|
|
public function testBuilderMethodsThrowLogicException( string $method, $args ) {
|
|
$this->expectException( \LogicException::class );
|
|
( new MwHttpRequestToResponseInterfaceAdapter( $this->createMock( MWHttpRequest::class ) ) )
|
|
->{$method}( ...$args );
|
|
}
|
|
|
|
public function unsupportedMethodsProvider() {
|
|
return [
|
|
[ 'withAddedHeader', [ 'foo', 'bar' ] ],
|
|
[ 'withBody', [ $this->createMock( StreamInterface::class ) ] ],
|
|
[ 'withHeader', [ 'foo', 'bar' ] ],
|
|
[ 'withoutHeader', [ 'foo', 'bar' ] ],
|
|
[ 'withProtocolVersion', [ '1.1' ] ],
|
|
[ 'withStatus', [ 200 ] ],
|
|
];
|
|
}
|
|
|
|
private function newMockMWHttpRequestWithHeaders( array $headers ) {
|
|
$req = $this->createMock( MWHttpRequest::class );
|
|
$req->expects( $this->any() )
|
|
->method( 'getResponseHeaders' )
|
|
->willReturn( $headers );
|
|
|
|
return $req;
|
|
}
|
|
|
|
}
|