wiki.techinc.nl/tests/integration/includes/http/MWHttpRequestTestCase.php
Gergő Tisza 1531659d25 Clean up http classes a bit
* added integration tests. We probably don't want automated tests
  to make external requests but these make manual testing more
  convenient. Documented some oddities discovered by testing.
* made ::$status, ::proxySetup() and ::getHeaderList()
  protected; they were not referenced in any gerrit-hosted extension
  and they provide no useful functionality to external callers.
  Similarly, marked ::read() and ::errorHandler() as internal
  (these are used as callbacks so can't be protected)
* removed inheritance abuse in ::execute()
* documented ::execute() as returning a StatusValue (but
  keep returning a Status for now)
* changed setCookie argument defaults to ones that make sense
* replaced MWException
* moved unit tests to the correct location
* fixed some code style issues

Change-Id: I5852fc75badc5d475ae30ec2c9376bde7024bd95
2016-11-30 19:00:44 -08:00

208 lines
7.7 KiB
PHP

<?php
class MWHttpRequestTestCase extends PHPUnit_Framework_TestCase {
protected static $httpEngine;
protected $oldHttpEngine;
public function setUp() {
parent::setUp();
$this->oldHttpEngine = Http::$httpEngine;
Http::$httpEngine = static::$httpEngine;
try {
$request = MWHttpRequest::factory( 'null:' );
} catch ( DomainException $e ) {
$this->markTestSkipped( static::$httpEngine . ' engine not supported' );
}
if ( static::$httpEngine === 'php' ) {
$this->assertInstanceOf( PhpHttpRequest::class, $request );
} else {
$this->assertInstanceOf( CurlHttpRequest::class, $request );
}
}
public function tearDown() {
parent::tearDown();
Http::$httpEngine = $this->oldHttpEngine;
}
// --------------------
public function testIsRedirect() {
$request = MWHttpRequest::factory( 'http://httpbin.org/get' );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
$this->assertFalse( $request->isRedirect() );
$request = MWHttpRequest::factory( 'http://httpbin.org/redirect/1' );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
$this->assertTrue( $request->isRedirect() );
}
public function testgetFinalUrl() {
$request = MWHttpRequest::factory( 'http://httpbin.org/redirect/3' );
if ( !$request->canFollowRedirects() ) {
$this->markTestSkipped( 'cannot follow redirects' );
}
$status = $request->execute();
$this->assertTrue( $status->isGood() );
$this->assertNotSame( 'http://httpbin.org/get', $request->getFinalUrl() );
$request = MWHttpRequest::factory( 'http://httpbin.org/redirect/3', [ 'followRedirects'
=> true ] );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
$this->assertSame( 'http://httpbin.org/get', $request->getFinalUrl() );
$this->assertResponseFieldValue( 'url', 'http://httpbin.org/get', $request );
$request = MWHttpRequest::factory( 'http://httpbin.org/redirect/3', [ 'followRedirects'
=> true ] );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
$this->assertSame( 'http://httpbin.org/get', $request->getFinalUrl() );
$this->assertResponseFieldValue( 'url', 'http://httpbin.org/get', $request );
if ( static::$httpEngine === 'curl' ) {
$this->markTestIncomplete( 'maxRedirects seems to be ignored by CurlHttpRequest' );
return;
}
$request = MWHttpRequest::factory( 'http://httpbin.org/redirect/3', [ 'followRedirects'
=> true, 'maxRedirects' => 1 ] );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
$this->assertNotSame( 'http://httpbin.org/get', $request->getFinalUrl() );
}
public function testSetCookie() {
$request = MWHttpRequest::factory( 'http://httpbin.org/cookies' );
$request->setCookie( 'foo', 'bar' );
$request->setCookie( 'foo2', 'bar2', [ 'domain' => 'example.com' ] );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
$this->assertResponseFieldValue( 'cookies', [ 'foo' => 'bar' ], $request );
}
public function testSetCookieJar() {
$request = MWHttpRequest::factory( 'http://httpbin.org/cookies' );
$cookieJar = new CookieJar();
$cookieJar->setCookie( 'foo', 'bar', [ 'domain' => 'httpbin.org' ] );
$cookieJar->setCookie( 'foo2', 'bar2', [ 'domain' => 'example.com' ] );
$request->setCookieJar( $cookieJar );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
$this->assertResponseFieldValue( 'cookies', [ 'foo' => 'bar' ], $request );
$request = MWHttpRequest::factory( 'http://httpbin.org/cookies/set?foo=bar' );
$cookieJar = new CookieJar();
$request->setCookieJar( $cookieJar );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
$this->assertHasCookie( 'foo', 'bar', $request->getCookieJar() );
$this->markTestIncomplete( 'CookieJar does not handle deletion' );
return;
$request = MWHttpRequest::factory( 'http://httpbin.org/cookies/delete?foo' );
$cookieJar = new CookieJar();
$cookieJar->setCookie( 'foo', 'bar', [ 'domain' => 'httpbin.org' ] );
$cookieJar->setCookie( 'foo2', 'bar2', [ 'domain' => 'httpbin.org' ] );
$request->setCookieJar( $cookieJar );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
$this->assertNotHasCookie( 'foo', $request->getCookieJar() );
$this->assertHasCookie( 'foo2', 'bar2', $request->getCookieJar() );
}
public function testGetResponseHeaders() {
$request = MWHttpRequest::factory( 'http://httpbin.org/response-headers?Foo=bar' );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
$headers = array_change_key_case( $request->getResponseHeaders(), CASE_LOWER );
$this->assertArrayHasKey( 'foo', $headers );
$this->assertSame( $request->getResponseHeader( 'Foo' ), 'bar' );
}
public function testSetHeader() {
$request = MWHttpRequest::factory( 'http://httpbin.org/headers' );
$request->setHeader( 'Foo', 'bar' );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
$this->assertResponseFieldValue( [ 'headers', 'Foo' ], 'bar', $request );
}
public function testGetStatus() {
$request = MWHttpRequest::factory( 'http://httpbin.org/status/418' );
$status = $request->execute();
$this->assertFalse( $status->isOK() );
$this->assertSame( $request->getStatus(), 418 );
}
public function testSetUserAgent() {
$request = MWHttpRequest::factory( 'http://httpbin.org/user-agent' );
$request->setUserAgent( 'foo' );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
$this->assertResponseFieldValue( 'user-agent', 'foo', $request );
}
public function testSetData() {
$request = MWHttpRequest::factory( 'http://httpbin.org/post', [ 'method' => 'POST' ] );
$request->setData( [ 'foo' => 'bar', 'foo2' => 'bar2' ] );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
$this->assertResponseFieldValue( 'form', [ 'foo' => 'bar', 'foo2' => 'bar2' ], $request );
}
public function testSetCallback() {
if ( static::$httpEngine === 'php' ) {
$this->markTestIncomplete( 'PhpHttpRequest does not use setCallback()' );
return;
}
$request = MWHttpRequest::factory( 'http://httpbin.org/ip' );
$data = '';
$request->setCallback( function ( $fh, $content ) use ( &$data ) {
$data .= $content;
return strlen( $content );
} );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
$data = json_decode( $data, true );
$this->assertInternalType( 'array', $data );
$this->assertArrayHasKey( 'origin', $data );
}
// --------------------
protected function assertResponseFieldValue( $key, $expectedValue, MWHttpRequest $response ) {
$this->assertSame( 200, $response->getStatus(), 'response status is not 200' );
$data = json_decode( $response->getContent(), true );
$this->assertInternalType( 'array', $data, 'response is not JSON' );
$keyPath = '';
foreach ( (array)$key as $keySegment ) {
$keyPath .= ( $keyPath ? '.' : '' ) . $keySegment;
$this->assertArrayHasKey( $keySegment, $data, $keyPath . ' not found' );
$data = $data[$keySegment];
}
$this->assertSame( $expectedValue, $data );
}
protected function assertHasCookie( $expectedName, $expectedValue, CookieJar $cookieJar ) {
$cookieJar = TestingAccessWrapper::newFromObject( $cookieJar );
$cookies = array_change_key_case( $cookieJar->cookie, CASE_LOWER );
$this->assertArrayHasKey( strtolower( $expectedName ), $cookies );
$cookie = TestingAccessWrapper::newFromObject(
$cookies[strtolower( $expectedName )] );
$this->assertSame( $expectedValue, $cookie->value );
}
protected function assertNotHasCookie( $name, CookieJar $cookieJar ) {
$cookieJar = TestingAccessWrapper::newFromObject( $cookieJar );
$this->assertArrayNotHasKey( strtolower( $name ),
array_change_key_case( $cookieJar->cookie, CASE_LOWER ) );
}
}