CommentStore: Hard-deprecate newKey()
[lhc/web/wiklou.git] / tests / phpunit / includes / MultiHttpClientTest.php
1 <?php
2
3 /**
4 * Tests for MultiHttpClient
5 *
6 * The urls herein are not actually called, because we mock the return results.
7 *
8 * @covers MultiHttpClient
9 */
10 class MultiHttpClientTest extends MediaWikiTestCase {
11 protected $client;
12
13 protected function setUp() {
14 parent::setUp();
15 $client = $this->getMockBuilder( MultiHttpClient::class )
16 ->setConstructorArgs( [ [] ] )
17 ->setMethods( [ 'isCurlEnabled' ] )->getMock();
18 $client->method( 'isCurlEnabled' )->willReturn( false );
19 $this->client = $client;
20 }
21
22 private function getHttpRequest( $statusValue, $statusCode, $headers = [] ) {
23 $httpRequest = $this->getMockBuilder( PhpHttpRequest::class )
24 ->setConstructorArgs( [ '', [] ] )
25 ->getMock();
26 $httpRequest->expects( $this->any() )
27 ->method( 'execute' )
28 ->willReturn( Status::wrap( $statusValue ) );
29 $httpRequest->expects( $this->any() )
30 ->method( 'getResponseHeaders' )
31 ->willReturn( $headers );
32 $httpRequest->expects( $this->any() )
33 ->method( 'getStatus' )
34 ->willReturn( $statusCode );
35 return $httpRequest;
36 }
37
38 private function mockHttpRequestFactory( $httpRequest ) {
39 $factory = $this->getMockBuilder( MediaWiki\Http\HttpRequestFactory::class )
40 ->getMock();
41 $factory->expects( $this->any() )
42 ->method( 'create' )
43 ->willReturn( $httpRequest );
44 return $factory;
45 }
46
47 /**
48 * Test call of a single url that should succeed
49 */
50 public function testMultiHttpClientSingleSuccess() {
51 // Mock success
52 $httpRequest = $this->getHttpRequest( StatusValue::newGood( 200 ), 200 );
53 $this->setService( 'HttpRequestFactory', $this->mockHttpRequestFactory( $httpRequest ) );
54
55 list( $rcode, $rdesc, /* $rhdrs */, $rbody, $rerr ) = $this->client->run( [
56 'method' => 'GET',
57 'url' => "http://example.test",
58 ] );
59
60 $this->assertEquals( 200, $rcode );
61 }
62
63 /**
64 * Test call of a single url that should not exist, and therefore fail
65 */
66 public function testMultiHttpClientSingleFailure() {
67 // Mock an invalid tld
68 $httpRequest = $this->getHttpRequest(
69 StatusValue::newFatal( 'http-invalid-url', 'http://www.example.test' ), 0 );
70 $this->setService( 'HttpRequestFactory', $this->mockHttpRequestFactory( $httpRequest ) );
71
72 list( $rcode, $rdesc, /* $rhdrs */, $rbody, $rerr ) = $this->client->run( [
73 'method' => 'GET',
74 'url' => "http://www.example.test",
75 ] );
76
77 $failure = $rcode < 200 || $rcode >= 400;
78 $this->assertTrue( $failure );
79 }
80
81 /**
82 * Test call of multiple urls that should all succeed
83 */
84 public function testMultiHttpClientMultipleSuccess() {
85 // Mock success
86 $httpRequest = $this->getHttpRequest( StatusValue::newGood( 200 ), 200 );
87 $this->setService( 'HttpRequestFactory', $this->mockHttpRequestFactory( $httpRequest ) );
88
89 $reqs = [
90 [
91 'method' => 'GET',
92 'url' => 'http://example.test',
93 ],
94 [
95 'method' => 'GET',
96 'url' => 'https://get.test',
97 ],
98 ];
99 $responses = $this->client->runMulti( $reqs );
100 foreach ( $responses as $response ) {
101 list( $rcode, $rdesc, /* $rhdrs */, $rbody, $rerr ) = $response['response'];
102 $this->assertEquals( 200, $rcode );
103 }
104 }
105
106 /**
107 * Test call of multiple urls that should all fail
108 */
109 public function testMultiHttpClientMultipleFailure() {
110 // Mock page not found
111 $httpRequest = $this->getHttpRequest(
112 StatusValue::newFatal( "http-bad-status", 404, 'Not Found' ), 404 );
113 $this->setService( 'HttpRequestFactory', $this->mockHttpRequestFactory( $httpRequest ) );
114
115 $reqs = [
116 [
117 'method' => 'GET',
118 'url' => 'http://example.test/12345',
119 ],
120 [
121 'method' => 'GET',
122 'url' => 'http://example.test/67890' ,
123 ]
124 ];
125 $responses = $this->client->runMulti( $reqs );
126 foreach ( $responses as $response ) {
127 list( $rcode, $rdesc, /* $rhdrs */, $rbody, $rerr ) = $response['response'];
128 $failure = $rcode < 200 || $rcode >= 400;
129 $this->assertTrue( $failure );
130 }
131 }
132
133 /**
134 * Test of response header handling
135 */
136 public function testMultiHttpClientHeaders() {
137 // Represenative headers for typical requests, per MWHttpRequest::getResponseHeaders()
138 $headers = [
139 'content-type' => [
140 'text/html; charset=utf-8',
141 ],
142 'date' => [
143 'Wed, 18 Jul 2018 14:52:41 GMT',
144 ],
145 'set-cookie' => [
146 'COUNTRY=NAe6; expires=Wed, 25-Jul-2018 14:52:41 GMT; path=/; domain=.example.test',
147 'LAST_NEWS=1531925562; expires=Thu, 18-Jul-2019 14:52:41 GMT; path=/; domain=.example.test',
148 ]
149 ];
150
151 // Mock success with specific headers
152 $httpRequest = $this->getHttpRequest( StatusValue::newGood( 200 ), 200, $headers );
153 $this->setService( 'HttpRequestFactory', $this->mockHttpRequestFactory( $httpRequest ) );
154
155 list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->client->run( [
156 'method' => 'GET',
157 'url' => 'http://example.test',
158 ] );
159
160 $this->assertEquals( 200, $rcode );
161 $this->assertEquals( count( $headers ), count( $rhdrs ) );
162 foreach ( $headers as $name => $values ) {
163 $value = implode( ', ', $values );
164 $this->assertArrayHasKey( $name, $rhdrs );
165 $this->assertEquals( $value, $rhdrs[$name] );
166 }
167 }
168 }