]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - tests/integration/includes/http/MWHttpRequestTestCase.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / tests / integration / includes / http / MWHttpRequestTestCase.php
1 <?php
2
3 use Wikimedia\TestingAccessWrapper;
4
5 class MWHttpRequestTestCase extends PHPUnit_Framework_TestCase {
6         protected static $httpEngine;
7         protected $oldHttpEngine;
8
9         public function setUp() {
10                 parent::setUp();
11                 $this->oldHttpEngine = Http::$httpEngine;
12                 Http::$httpEngine = static::$httpEngine;
13
14                 try {
15                         $request = MWHttpRequest::factory( 'null:' );
16                 } catch ( DomainException $e ) {
17                         $this->markTestSkipped( static::$httpEngine . ' engine not supported' );
18                 }
19
20                 if ( static::$httpEngine === 'php' ) {
21                         $this->assertInstanceOf( PhpHttpRequest::class, $request );
22                 } else {
23                         $this->assertInstanceOf( CurlHttpRequest::class, $request );
24                 }
25         }
26
27         public function tearDown() {
28                 parent::tearDown();
29                 Http::$httpEngine = $this->oldHttpEngine;
30         }
31
32         // --------------------
33
34         public function testIsRedirect() {
35                 $request = MWHttpRequest::factory( 'http://httpbin.org/get' );
36                 $status = $request->execute();
37                 $this->assertTrue( $status->isGood() );
38                 $this->assertFalse( $request->isRedirect() );
39
40                 $request = MWHttpRequest::factory( 'http://httpbin.org/redirect/1' );
41                 $status = $request->execute();
42                 $this->assertTrue( $status->isGood() );
43                 $this->assertTrue( $request->isRedirect() );
44         }
45
46         public function testgetFinalUrl() {
47                 $request = MWHttpRequest::factory( 'http://httpbin.org/redirect/3' );
48                 if ( !$request->canFollowRedirects() ) {
49                         $this->markTestSkipped( 'cannot follow redirects' );
50                 }
51                 $status = $request->execute();
52                 $this->assertTrue( $status->isGood() );
53                 $this->assertNotSame( 'http://httpbin.org/get', $request->getFinalUrl() );
54
55                 $request = MWHttpRequest::factory( 'http://httpbin.org/redirect/3', [ 'followRedirects'
56                         => true ] );
57                 $status = $request->execute();
58                 $this->assertTrue( $status->isGood() );
59                 $this->assertSame( 'http://httpbin.org/get', $request->getFinalUrl() );
60                 $this->assertResponseFieldValue( 'url', 'http://httpbin.org/get', $request );
61
62                 $request = MWHttpRequest::factory( 'http://httpbin.org/redirect/3', [ 'followRedirects'
63                 => true ] );
64                 $status = $request->execute();
65                 $this->assertTrue( $status->isGood() );
66                 $this->assertSame( 'http://httpbin.org/get', $request->getFinalUrl() );
67                 $this->assertResponseFieldValue( 'url', 'http://httpbin.org/get', $request );
68
69                 if ( static::$httpEngine === 'curl' ) {
70                         $this->markTestIncomplete( 'maxRedirects seems to be ignored by CurlHttpRequest' );
71                         return;
72                 }
73
74                 $request = MWHttpRequest::factory( 'http://httpbin.org/redirect/3', [ 'followRedirects'
75                 => true, 'maxRedirects' => 1 ] );
76                 $status = $request->execute();
77                 $this->assertTrue( $status->isGood() );
78                 $this->assertNotSame( 'http://httpbin.org/get', $request->getFinalUrl() );
79         }
80
81         public function testSetCookie() {
82                 $request = MWHttpRequest::factory( 'http://httpbin.org/cookies' );
83                 $request->setCookie( 'foo', 'bar' );
84                 $request->setCookie( 'foo2', 'bar2', [ 'domain' => 'example.com' ] );
85                 $status = $request->execute();
86                 $this->assertTrue( $status->isGood() );
87                 $this->assertResponseFieldValue( 'cookies', [ 'foo' => 'bar' ], $request );
88         }
89
90         public function testSetCookieJar() {
91                 $request = MWHttpRequest::factory( 'http://httpbin.org/cookies' );
92                 $cookieJar = new CookieJar();
93                 $cookieJar->setCookie( 'foo', 'bar', [ 'domain' => 'httpbin.org' ] );
94                 $cookieJar->setCookie( 'foo2', 'bar2', [ 'domain' => 'example.com' ] );
95                 $request->setCookieJar( $cookieJar );
96                 $status = $request->execute();
97                 $this->assertTrue( $status->isGood() );
98                 $this->assertResponseFieldValue( 'cookies', [ 'foo' => 'bar' ], $request );
99
100                 $request = MWHttpRequest::factory( 'http://httpbin.org/cookies/set?foo=bar' );
101                 $cookieJar = new CookieJar();
102                 $request->setCookieJar( $cookieJar );
103                 $status = $request->execute();
104                 $this->assertTrue( $status->isGood() );
105                 $this->assertHasCookie( 'foo', 'bar', $request->getCookieJar() );
106
107                 $this->markTestIncomplete( 'CookieJar does not handle deletion' );
108                 return;
109
110                 $request = MWHttpRequest::factory( 'http://httpbin.org/cookies/delete?foo' );
111                 $cookieJar = new CookieJar();
112                 $cookieJar->setCookie( 'foo', 'bar', [ 'domain' => 'httpbin.org' ] );
113                 $cookieJar->setCookie( 'foo2', 'bar2', [ 'domain' => 'httpbin.org' ] );
114                 $request->setCookieJar( $cookieJar );
115                 $status = $request->execute();
116                 $this->assertTrue( $status->isGood() );
117                 $this->assertNotHasCookie( 'foo', $request->getCookieJar() );
118                 $this->assertHasCookie( 'foo2', 'bar2', $request->getCookieJar() );
119         }
120
121         public function testGetResponseHeaders() {
122                 $request = MWHttpRequest::factory( 'http://httpbin.org/response-headers?Foo=bar' );
123                 $status = $request->execute();
124                 $this->assertTrue( $status->isGood() );
125                 $headers = array_change_key_case( $request->getResponseHeaders(), CASE_LOWER );
126                 $this->assertArrayHasKey( 'foo', $headers );
127                 $this->assertSame( $request->getResponseHeader( 'Foo' ), 'bar' );
128         }
129
130         public function testSetHeader() {
131                 $request = MWHttpRequest::factory( 'http://httpbin.org/headers' );
132                 $request->setHeader( 'Foo', 'bar' );
133                 $status = $request->execute();
134                 $this->assertTrue( $status->isGood() );
135                 $this->assertResponseFieldValue( [ 'headers', 'Foo' ], 'bar', $request );
136         }
137
138         public function testGetStatus() {
139                 $request = MWHttpRequest::factory( 'http://httpbin.org/status/418' );
140                 $status = $request->execute();
141                 $this->assertFalse( $status->isOK() );
142                 $this->assertSame( $request->getStatus(), 418 );
143         }
144
145         public function testSetUserAgent() {
146                 $request = MWHttpRequest::factory( 'http://httpbin.org/user-agent' );
147                 $request->setUserAgent( 'foo' );
148                 $status = $request->execute();
149                 $this->assertTrue( $status->isGood() );
150                 $this->assertResponseFieldValue( 'user-agent', 'foo', $request );
151         }
152
153         public function testSetData() {
154                 $request = MWHttpRequest::factory( 'http://httpbin.org/post', [ 'method' => 'POST' ] );
155                 $request->setData( [ 'foo' => 'bar', 'foo2' => 'bar2' ] );
156                 $status = $request->execute();
157                 $this->assertTrue( $status->isGood() );
158                 $this->assertResponseFieldValue( 'form', [ 'foo' => 'bar', 'foo2' => 'bar2' ], $request );
159         }
160
161         public function testSetCallback() {
162                 if ( static::$httpEngine === 'php' ) {
163                         $this->markTestIncomplete( 'PhpHttpRequest does not use setCallback()' );
164                         return;
165                 }
166
167                 $request = MWHttpRequest::factory( 'http://httpbin.org/ip' );
168                 $data = '';
169                 $request->setCallback( function ( $fh, $content ) use ( &$data ) {
170                         $data .= $content;
171                         return strlen( $content );
172                 } );
173                 $status = $request->execute();
174                 $this->assertTrue( $status->isGood() );
175                 $data = json_decode( $data, true );
176                 $this->assertInternalType( 'array', $data );
177                 $this->assertArrayHasKey( 'origin', $data );
178         }
179
180         public function testBasicAuthentication() {
181                 $request = MWHttpRequest::factory( 'http://httpbin.org/basic-auth/user/pass', [
182                         'username' => 'user',
183                         'password' => 'pass',
184                 ] );
185                 $status = $request->execute();
186                 $this->assertTrue( $status->isGood() );
187                 $this->assertResponseFieldValue( 'authenticated', true, $request );
188
189                 $request = MWHttpRequest::factory( 'http://httpbin.org/basic-auth/user/pass', [
190                         'username' => 'user',
191                         'password' => 'wrongpass',
192                 ] );
193                 $status = $request->execute();
194                 $this->assertFalse( $status->isOK() );
195                 $this->assertSame( 401, $request->getStatus() );
196         }
197
198         // --------------------
199
200         /**
201          * Verifies that the request was successful, returned valid JSON and the given field of that
202          * JSON data is as expected.
203          * @param string|string[] $key Path to the data in the response object
204          * @param mixed $expectedValue
205          * @param MWHttpRequest $response
206          */
207         protected function assertResponseFieldValue( $key, $expectedValue, MWHttpRequest $response ) {
208                 $this->assertSame( 200, $response->getStatus(), 'response status is not 200' );
209                 $data = json_decode( $response->getContent(), true );
210                 $this->assertInternalType( 'array', $data, 'response is not JSON' );
211                 $keyPath = '';
212                 foreach ( (array)$key as $keySegment ) {
213                         $keyPath .= ( $keyPath ? '.' : '' ) . $keySegment;
214                         $this->assertArrayHasKey( $keySegment, $data, $keyPath . ' not found' );
215                         $data = $data[$keySegment];
216                 }
217                 $this->assertSame( $expectedValue, $data );
218         }
219
220         /**
221          * Asserts that the cookie jar has the given cookie with the given value.
222          * @param string $expectedName Cookie name
223          * @param string $expectedValue Cookie value
224          * @param CookieJar $cookieJar
225          */
226         protected function assertHasCookie( $expectedName, $expectedValue, CookieJar $cookieJar ) {
227                 $cookieJar = TestingAccessWrapper::newFromObject( $cookieJar );
228                 $cookies = array_change_key_case( $cookieJar->cookie, CASE_LOWER );
229                 $this->assertArrayHasKey( strtolower( $expectedName ), $cookies );
230                 $cookie = TestingAccessWrapper::newFromObject(
231                         $cookies[strtolower( $expectedName )] );
232                 $this->assertSame( $expectedValue, $cookie->value );
233         }
234
235         /**
236          * Asserts that the cookie jar does not have the given cookie.
237          * @param string $name Cookie name
238          * @param CookieJar $cookieJar
239          */
240         protected function assertNotHasCookie( $name, CookieJar $cookieJar ) {
241                 $cookieJar = TestingAccessWrapper::newFromObject( $cookieJar );
242                 $this->assertArrayNotHasKey( strtolower( $name ),
243                         array_change_key_case( $cookieJar->cookie, CASE_LOWER ) );
244         }
245 }