MiddlewareTest.php 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <?php
  2. namespace GuzzleHttp\Tests;
  3. use GuzzleHttp\Cookie\CookieJar;
  4. use GuzzleHttp\Cookie\SetCookie;
  5. use GuzzleHttp\Exception\RequestException;
  6. use GuzzleHttp\Handler\MockHandler;
  7. use GuzzleHttp\HandlerStack;
  8. use GuzzleHttp\MessageFormatter;
  9. use GuzzleHttp\Middleware;
  10. use GuzzleHttp\Promise\PromiseInterface;
  11. use GuzzleHttp\Psr7\Request;
  12. use GuzzleHttp\Psr7\Response;
  13. use Psr\Http\Message\RequestInterface;
  14. use Psr\Http\Message\ResponseInterface;
  15. use PHPUnit\Framework\TestCase;
  16. use Psr\Log\Test\TestLogger;
  17. class MiddlewareTest extends TestCase
  18. {
  19. public function testAddsCookiesToRequests()
  20. {
  21. $jar = new CookieJar();
  22. $m = Middleware::cookies($jar);
  23. $h = new MockHandler(
  24. [
  25. function (RequestInterface $request) {
  26. return new Response(200, [
  27. 'Set-Cookie' => new SetCookie([
  28. 'Name' => 'name',
  29. 'Value' => 'value',
  30. 'Domain' => 'foo.com'
  31. ])
  32. ]);
  33. }
  34. ]
  35. );
  36. $f = $m($h);
  37. $f(new Request('GET', 'http://foo.com'), ['cookies' => $jar])->wait();
  38. $this->assertCount(1, $jar);
  39. }
  40. /**
  41. * @expectedException \GuzzleHttp\Exception\ClientException
  42. */
  43. public function testThrowsExceptionOnHttpClientError()
  44. {
  45. $m = Middleware::httpErrors();
  46. $h = new MockHandler([new Response(404)]);
  47. $f = $m($h);
  48. $p = $f(new Request('GET', 'http://foo.com'), ['http_errors' => true]);
  49. $this->assertSame('pending', $p->getState());
  50. $p->wait();
  51. $this->assertSame('rejected', $p->getState());
  52. }
  53. /**
  54. * @expectedException \GuzzleHttp\Exception\ServerException
  55. */
  56. public function testThrowsExceptionOnHttpServerError()
  57. {
  58. $m = Middleware::httpErrors();
  59. $h = new MockHandler([new Response(500)]);
  60. $f = $m($h);
  61. $p = $f(new Request('GET', 'http://foo.com'), ['http_errors' => true]);
  62. $this->assertSame('pending', $p->getState());
  63. $p->wait();
  64. $this->assertSame('rejected', $p->getState());
  65. }
  66. /**
  67. * @dataProvider getHistoryUseCases
  68. */
  69. public function testTracksHistory($container)
  70. {
  71. $m = Middleware::history($container);
  72. $h = new MockHandler([new Response(200), new Response(201)]);
  73. $f = $m($h);
  74. $p1 = $f(new Request('GET', 'http://foo.com'), ['headers' => ['foo' => 'bar']]);
  75. $p2 = $f(new Request('HEAD', 'http://foo.com'), ['headers' => ['foo' => 'baz']]);
  76. $p1->wait();
  77. $p2->wait();
  78. $this->assertCount(2, $container);
  79. $this->assertSame(200, $container[0]['response']->getStatusCode());
  80. $this->assertSame(201, $container[1]['response']->getStatusCode());
  81. $this->assertSame('GET', $container[0]['request']->getMethod());
  82. $this->assertSame('HEAD', $container[1]['request']->getMethod());
  83. $this->assertSame('bar', $container[0]['options']['headers']['foo']);
  84. $this->assertSame('baz', $container[1]['options']['headers']['foo']);
  85. }
  86. public function getHistoryUseCases()
  87. {
  88. return [
  89. [[]], // 1. Container is an array
  90. [new \ArrayObject()] // 2. Container is an ArrayObject
  91. ];
  92. }
  93. public function testTracksHistoryForFailures()
  94. {
  95. $container = [];
  96. $m = Middleware::history($container);
  97. $request = new Request('GET', 'http://foo.com');
  98. $h = new MockHandler([new RequestException('error', $request)]);
  99. $f = $m($h);
  100. $f($request, [])->wait(false);
  101. $this->assertCount(1, $container);
  102. $this->assertSame('GET', $container[0]['request']->getMethod());
  103. $this->assertInstanceOf(RequestException::class, $container[0]['error']);
  104. }
  105. public function testTapsBeforeAndAfter()
  106. {
  107. $calls = [];
  108. $m = function ($handler) use (&$calls) {
  109. return function ($request, $options) use ($handler, &$calls) {
  110. $calls[] = '2';
  111. return $handler($request, $options);
  112. };
  113. };
  114. $m2 = Middleware::tap(
  115. function (RequestInterface $request, array $options) use (&$calls) {
  116. $calls[] = '1';
  117. },
  118. function (RequestInterface $request, array $options, PromiseInterface $p) use (&$calls) {
  119. $calls[] = '3';
  120. }
  121. );
  122. $h = new MockHandler([new Response()]);
  123. $b = new HandlerStack($h);
  124. $b->push($m2);
  125. $b->push($m);
  126. $comp = $b->resolve();
  127. $p = $comp(new Request('GET', 'http://foo.com'), []);
  128. $this->assertSame('123', implode('', $calls));
  129. $this->assertInstanceOf(PromiseInterface::class, $p);
  130. $this->assertSame(200, $p->wait()->getStatusCode());
  131. }
  132. public function testMapsRequest()
  133. {
  134. $h = new MockHandler([
  135. function (RequestInterface $request, array $options) {
  136. $this->assertSame('foo', $request->getHeaderLine('Bar'));
  137. return new Response(200);
  138. }
  139. ]);
  140. $stack = new HandlerStack($h);
  141. $stack->push(Middleware::mapRequest(function (RequestInterface $request) {
  142. return $request->withHeader('Bar', 'foo');
  143. }));
  144. $comp = $stack->resolve();
  145. $p = $comp(new Request('PUT', 'http://www.google.com'), []);
  146. $this->assertInstanceOf(PromiseInterface::class, $p);
  147. }
  148. public function testMapsResponse()
  149. {
  150. $h = new MockHandler([new Response(200)]);
  151. $stack = new HandlerStack($h);
  152. $stack->push(Middleware::mapResponse(function (ResponseInterface $response) {
  153. return $response->withHeader('Bar', 'foo');
  154. }));
  155. $comp = $stack->resolve();
  156. $p = $comp(new Request('PUT', 'http://www.google.com'), []);
  157. $p->wait();
  158. $this->assertSame('foo', $p->wait()->getHeaderLine('Bar'));
  159. }
  160. public function testLogsRequestsAndResponses()
  161. {
  162. $h = new MockHandler([new Response(200)]);
  163. $stack = new HandlerStack($h);
  164. $logger = new TestLogger();
  165. $formatter = new MessageFormatter();
  166. $stack->push(Middleware::log($logger, $formatter));
  167. $comp = $stack->resolve();
  168. $p = $comp(new Request('PUT', 'http://www.google.com'), []);
  169. $p->wait();
  170. $this->assertCount(1, $logger->records);
  171. $this->assertContains('"PUT / HTTP/1.1" 200', $logger->records[0]['message']);
  172. }
  173. public function testLogsRequestsAndResponsesCustomLevel()
  174. {
  175. $h = new MockHandler([new Response(200)]);
  176. $stack = new HandlerStack($h);
  177. $logger = new TestLogger();
  178. $formatter = new MessageFormatter();
  179. $stack->push(Middleware::log($logger, $formatter, 'debug'));
  180. $comp = $stack->resolve();
  181. $p = $comp(new Request('PUT', 'http://www.google.com'), []);
  182. $p->wait();
  183. $this->assertCount(1, $logger->records);
  184. $this->assertContains('"PUT / HTTP/1.1" 200', $logger->records[0]['message']);
  185. $this->assertSame('debug', $logger->records[0]['level']);
  186. }
  187. public function testLogsRequestsAndErrors()
  188. {
  189. $h = new MockHandler([new Response(404)]);
  190. $stack = new HandlerStack($h);
  191. $logger = new TestLogger();
  192. $formatter = new MessageFormatter('{code} {error}');
  193. $stack->push(Middleware::log($logger, $formatter));
  194. $stack->push(Middleware::httpErrors());
  195. $comp = $stack->resolve();
  196. $p = $comp(new Request('PUT', 'http://www.google.com'), ['http_errors' => true]);
  197. $p->wait(false);
  198. $this->assertCount(1, $logger->records);
  199. $this->assertContains('PUT http://www.google.com', $logger->records[0]['message']);
  200. $this->assertContains('404 Not Found', $logger->records[0]['message']);
  201. }
  202. }