4 * This file is part of the Goutte package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Goutte\Tests;
15 use GuzzleHttp\Client as GuzzleClient;
16 use GuzzleHttp\Exception\RequestException;
17 use GuzzleHttp\Handler\MockHandler;
18 use GuzzleHttp\HandlerStack;
19 use GuzzleHttp\Psr7\Response as GuzzleResponse;
20 use GuzzleHttp\Middleware;
21 use Symfony\Component\BrowserKit\Cookie;
26 * @author Michael Dowling <michael@guzzlephp.org>
27 * @author Charles Sarrazin <charles@sarraz.in>
29 class ClientTest extends \PHPUnit_Framework_TestCase
32 /** @var MockHandler */
35 protected function getGuzzle(array $responses = [])
37 if (empty($responses)) {
38 $responses = [new GuzzleResponse(200, [], '<html><body><p>Hi</p></body></html>')];
40 $this->mock = new MockHandler($responses);
41 $handlerStack = HandlerStack::create($this->mock);
43 $handlerStack->push(Middleware::history($this->history));
44 $guzzle = new GuzzleClient(array('redirect.disable' => true, 'base_uri' => '', 'handler' => $handlerStack));
49 public function testCreatesDefaultClient()
51 $client = new Client();
52 $this->assertInstanceOf('GuzzleHttp\\ClientInterface', $client->getClient());
55 public function testUsesCustomClient()
57 $guzzle = new GuzzleClient();
58 $client = new Client();
59 $this->assertSame($client, $client->setClient($guzzle));
60 $this->assertSame($guzzle, $client->getClient());
63 public function testUsesCustomHeaders()
65 $guzzle = $this->getGuzzle();
66 $client = new Client();
67 $client->setClient($guzzle);
68 $client->setHeader('X-Test', 'test');
69 $client->request('GET', 'http://www.example.com/');
70 $this->assertEquals('test', end($this->history)['request']->getHeaderLine('X-Test'));
73 public function testCustomUserAgent()
75 $guzzle = $this->getGuzzle();
76 $client = new Client();
77 $client->setClient($guzzle);
78 $client->setHeader('User-Agent', 'foo');
79 $client->request('GET', 'http://www.example.com/');
80 $this->assertEquals('foo', end($this->history)['request']->getHeaderLine('User-Agent'));
83 public function testUsesAuth()
85 $guzzle = $this->getGuzzle();
86 $client = new Client();
87 $client->setClient($guzzle);
88 $client->setAuth('me', '**');
89 $client->request('GET', 'http://www.example.com/');
90 $request = end($this->history)['request'];
91 $this->assertEquals('Basic bWU6Kio=', $request->getHeaderLine('Authorization'));
94 public function testResetsAuth()
96 $guzzle = $this->getGuzzle();
97 $client = new Client();
98 $client->setClient($guzzle);
99 $client->setAuth('me', '**');
100 $client->resetAuth();
101 $client->request('GET', 'http://www.example.com/');
102 $request = end($this->history)['request'];
103 $this->assertEquals('', $request->getHeaderLine('authorization'));
106 public function testUsesCookies()
108 $guzzle = $this->getGuzzle();
109 $client = new Client();
110 $client->setClient($guzzle);
111 $client->getCookieJar()->set(new Cookie('test', '123'));
112 $client->request('GET', 'http://www.example.com/');
113 $request = end($this->history)['request'];
114 $this->assertEquals('test=123', $request->getHeaderLine('Cookie'));
117 public function testUsesCookiesWithCustomPort()
119 $guzzle = $this->getGuzzle();
120 $client = new Client();
121 $client->setClient($guzzle);
122 $client->getCookieJar()->set(new Cookie('test', '123'));
123 $client->request('GET', 'http://www.example.com:8000/');
124 $request = end($this->history)['request'];
125 $this->assertEquals('test=123', $request->getHeaderLine('Cookie'));
128 public function testUsesPostFiles()
130 $guzzle = $this->getGuzzle();
131 $client = new Client();
132 $client->setClient($guzzle);
135 'name' => 'test.txt',
136 'tmp_name' => __DIR__.'/fixtures.txt',
140 $client->request('POST', 'http://www.example.com/', array(), $files);
141 $request = end($this->history)['request'];
143 $stream = $request->getBody();
144 $boundary = $stream->getBoundary();
146 "--$boundary\r\nContent-Disposition: form-data; name=\"test\"; filename=\"test.txt\"\r\nContent-Length: 4\r\n"
147 ."Content-Type: text/plain\r\n\r\nfoo\n\r\n--$boundary--\r\n",
148 $stream->getContents()
152 public function testUsesPostNamedFiles()
154 $guzzle = $this->getGuzzle();
155 $client = new Client();
156 $client->setClient($guzzle);
158 'test' => __DIR__.'/fixtures.txt',
161 $client->request('POST', 'http://www.example.com/', array(), $files);
162 $request = end($this->history)['request'];
164 $stream = $request->getBody();
165 $boundary = $stream->getBoundary();
167 "--$boundary\r\nContent-Disposition: form-data; name=\"test\"; filename=\"fixtures.txt\"\r\nContent-Length: 4\r\n"
168 ."Content-Type: text/plain\r\n\r\nfoo\n\r\n--$boundary--\r\n",
169 $stream->getContents()
173 public function testUsesPostFilesNestedFields()
175 $guzzle = $this->getGuzzle();
176 $client = new Client();
177 $client->setClient($guzzle);
181 'name' => 'test.txt',
182 'tmp_name' => __DIR__.'/fixtures.txt',
187 $client->request('POST', 'http://www.example.com/', array(), $files);
188 $request = end($this->history)['request'];
190 $stream = $request->getBody();
191 $boundary = $stream->getBoundary();
193 "--$boundary\r\nContent-Disposition: form-data; name=\"form[test]\"; filename=\"test.txt\"\r\nContent-Length: 4\r\n"
194 ."Content-Type: text/plain\r\n\r\nfoo\n\r\n--$boundary--\r\n",
195 $stream->getContents()
199 public function testPostFormWithFiles()
201 $guzzle = $this->getGuzzle();
202 $client = new Client();
203 $client->setClient($guzzle);
205 'test' => __DIR__.'/fixtures.txt',
211 $client->request('POST', 'http://www.example.com/', $params, $files);
212 $request = end($this->history)['request'];
214 $stream = $request->getBody();
215 $boundary = $stream->getBoundary();
217 "--$boundary\r\nContent-Disposition: form-data; name=\"foo\"\r\nContent-Length: 3\r\n"
219 ."--$boundary\r\nContent-Disposition: form-data; name=\"test\"; filename=\"fixtures.txt\"\r\nContent-Length: 4\r\n"
220 ."Content-Type: text/plain\r\n\r\nfoo\n\r\n--$boundary--\r\n",
221 $stream->getContents());
224 public function testPostEmbeddedFormWithFiles()
226 $guzzle = $this->getGuzzle();
227 $client = new Client();
228 $client->setClient($guzzle);
230 'test' => __DIR__.'/fixtures.txt',
238 $client->request('POST', 'http://www.example.com/', $params, $files);
239 $request = end($this->history)['request'];
241 $stream = $request->getBody();
242 $boundary = $stream->getBoundary();
244 "--$boundary\r\nContent-Disposition: form-data; name=\"foo[bar]\"\r\nContent-Length: 3\r\n"
246 ."--$boundary\r\nContent-Disposition: form-data; name=\"test\"; filename=\"fixtures.txt\"\r\nContent-Length: 4\r\n"
247 ."Content-Type: text/plain\r\n\r\nfoo\n\r\n--$boundary--\r\n",
248 $stream->getContents());
251 public function testUsesPostFilesOnClientSide()
253 $guzzle = $this->getGuzzle();
254 $client = new Client();
255 $client->setClient($guzzle);
257 'test' => __DIR__.'/fixtures.txt',
260 $client->request('POST', 'http://www.example.com/', array(), $files);
261 $request = end($this->history)['request'];
263 $stream = $request->getBody();
264 $boundary = $stream->getBoundary();
266 "--$boundary\r\nContent-Disposition: form-data; name=\"test\"; filename=\"fixtures.txt\"\r\nContent-Length: 4\r\n"
267 ."Content-Type: text/plain\r\n\r\nfoo\n\r\n--$boundary--\r\n",
268 $stream->getContents()
272 public function testUsesPostFilesUploadError()
274 $guzzle = $this->getGuzzle();
275 $client = new Client();
276 $client->setClient($guzzle);
287 $client->request('POST', 'http://www.example.com/', array(), $files);
288 $request = end($this->history)['request'];
289 $stream = $request->getBody();
290 $boundary = $stream->getBoundary();
292 $this->assertEquals("--$boundary--\r\n", $stream->getContents());
295 public function testCreatesResponse()
297 $guzzle = $this->getGuzzle();
298 $client = new Client();
299 $client->setClient($guzzle);
300 $crawler = $client->request('GET', 'http://www.example.com/');
301 $this->assertEquals('Hi', $crawler->filter('p')->text());
304 public function testHandlesRedirectsCorrectly()
306 $guzzle = $this->getGuzzle([
307 new GuzzleResponse(301, array(
308 'Location' => 'http://www.example.com/',
310 new GuzzleResponse(200, [], '<html><body><p>Test</p></body></html>'),
313 $client = new Client();
314 $client->setClient($guzzle);
316 $crawler = $client->request('GET', 'http://www.example.com/');
317 $this->assertEquals('Test', $crawler->filter('p')->text());
319 // Ensure that two requests were sent
320 $this->assertEquals(2, count($this->history));
323 public function testConvertsGuzzleHeadersToArrays()
325 $guzzle = $this->getGuzzle([
326 new GuzzleResponse(200, array(
327 'Date' => 'Tue, 04 Jun 2013 13:22:41 GMT',
331 $client = new Client();
332 $client->setClient($guzzle);
333 $client->request('GET', 'http://www.example.com/');
334 $response = $client->getResponse();
335 $headers = $response->getHeaders();
337 $this->assertInternalType('array', array_shift($headers), 'Header not converted from Guzzle\Http\Message\Header to array');
340 public function testNullResponseException()
342 $this->setExpectedException('GuzzleHttp\Exception\RequestException');
343 $guzzle = $this->getGuzzle([
344 new RequestException('', $this->getMock('Psr\Http\Message\RequestInterface')),
346 $client = new Client();
347 $client->setClient($guzzle);
348 $client->request('GET', 'http://www.example.com/');
349 $client->getResponse();
352 public function testHttps()
354 $guzzle = $this->getGuzzle([
355 new GuzzleResponse(200, [], '<html><body><p>Test</p></body></html>'),
358 $client = new Client();
359 $client->setClient($guzzle);
360 $crawler = $client->request('GET', 'https://www.example.com/');
361 $this->assertEquals('Test', $crawler->filter('p')->text());
364 public function testCustomUserAgentConstructor()
366 $guzzle = $this->getGuzzle();
367 $client = new Client([
368 'HTTP_HOST' => '1.2.3.4',
369 'HTTP_USER_AGENT' => 'SomeHost',
371 $client->setClient($guzzle);
372 $client->request('GET', 'http://www.example.com/');
373 $this->assertEquals('SomeHost', end($this->history)['request']->getHeaderLine('User-Agent'));
376 public function testResetHeaders()
378 $client = new Client();
379 $client->setHeader('X-Test', 'test');
381 $reflectionProperty = new \ReflectionProperty('Goutte\Client', 'headers');
382 $reflectionProperty->setAccessible(true);
383 $this->assertEquals(array('x-test' => 'test'), $reflectionProperty->getValue($client));
385 $client->resetHeaders();
386 $this->assertEquals([], $reflectionProperty->getValue($client));
389 public function testRestart()
391 $client = new Client();
392 $client->setHeader('X-Test', 'test');
393 $client->setAuth('foo', 'bar');
395 $headersReflectionProperty = new \ReflectionProperty('Goutte\Client', 'headers');
396 $headersReflectionProperty->setAccessible(true);
397 $this->assertEquals(array('x-test' => 'test'), $headersReflectionProperty->getValue($client));
399 $authReflectionProperty = new \ReflectionProperty('Goutte\Client', 'auth');
400 $authReflectionProperty->setAccessible(true);
401 $this->assertEquals(array('foo', 'bar', 'basic'), $authReflectionProperty->getValue($client));
404 $this->assertEquals([], $headersReflectionProperty->getValue($client));
405 $this->assertNull($authReflectionProperty->getValue($client));