diff --git a/src/Browser.php b/src/Browser.php index 48e64fcb..91604994 100644 --- a/src/Browser.php +++ b/src/Browser.php @@ -3,9 +3,10 @@ namespace React\Http; use Psr\Http\Message\ResponseInterface; +use RingCentral\Psr7\Request; use RingCentral\Psr7\Uri; use React\EventLoop\LoopInterface; -use React\Http\Io\MessageFactory; +use React\Http\Io\ReadableBodyStream; use React\Http\Io\Sender; use React\Http\Io\Transaction; use React\Promise\PromiseInterface; @@ -19,7 +20,6 @@ class Browser { private $transaction; - private $messageFactory; private $baseUrl; private $protocolVersion = '1.1'; @@ -59,10 +59,8 @@ class Browser */ public function __construct(LoopInterface $loop, ConnectorInterface $connector = null) { - $this->messageFactory = new MessageFactory(); $this->transaction = new Transaction( - Sender::createFromLoop($loop, $connector, $this->messageFactory), - $this->messageFactory, + Sender::createFromLoop($loop, $connector), $loop ); } @@ -721,18 +719,22 @@ private function withOptions(array $options) * @param string $method * @param string $url * @param array $headers - * @param string|ReadableStreamInterface $contents + * @param string|ReadableStreamInterface $body * @return PromiseInterface */ - private function requestMayBeStreaming($method, $url, array $headers = array(), $contents = '') + private function requestMayBeStreaming($method, $url, array $headers = array(), $body = '') { if ($this->baseUrl !== null) { // ensure we're actually below the base URL $url = Uri::resolve($this->baseUrl, $url); } - $request = $this->messageFactory->request($method, $url, $headers, $contents, $this->protocolVersion); + if ($body instanceof ReadableStreamInterface) { + $body = new ReadableBodyStream($body); + } - return $this->transaction->send($request); + return $this->transaction->send( + new Request($method, $url, $headers, $body, $this->protocolVersion) + ); } } diff --git a/src/Client/Response.php b/src/Client/Response.php index be19eb4c..2de64bb0 100644 --- a/src/Client/Response.php +++ b/src/Client/Response.php @@ -86,11 +86,24 @@ private function getHeader($name) return isset($normalized[$name]) ? (array)$normalized[$name] : array(); } - private function getHeaderLine($name) + /** + * @param string $name + * @return string + */ + public function getHeaderLine($name) { return implode(', ' , $this->getHeader($name)); } + /** + * @param string $name + * @return bool + */ + public function hasHeader($name) + { + return $this->getHeader($name) !== array(); + } + /** @internal */ public function handleData($data) { diff --git a/src/Io/MessageFactory.php b/src/Io/MessageFactory.php deleted file mode 100644 index f3d0993d..00000000 --- a/src/Io/MessageFactory.php +++ /dev/null @@ -1,78 +0,0 @@ -body($content), $protocolVersion); - } - - /** - * Creates a new instance of ResponseInterface for the given response parameters - * - * @param string $protocolVersion - * @param int $status - * @param string $reason - * @param array $headers - * @param ReadableStreamInterface|string $body - * @param ?string $requestMethod - * @return Response - * @uses self::body() - */ - public function response($protocolVersion, $status, $reason, $headers = array(), $body = '', $requestMethod = null) - { - $response = new Response($status, $headers, $body instanceof ReadableStreamInterface ? null : $body, $protocolVersion, $reason); - - if ($body instanceof ReadableStreamInterface) { - $length = null; - $code = $response->getStatusCode(); - if ($requestMethod === 'HEAD' || ($code >= 100 && $code < 200) || $code == 204 || $code == 304) { - $length = 0; - } elseif (\strtolower($response->getHeaderLine('Transfer-Encoding')) === 'chunked') { - $length = null; - } elseif ($response->hasHeader('Content-Length')) { - $length = (int)$response->getHeaderLine('Content-Length'); - } - - $response = $response->withBody(new ReadableBodyStream($body, $length)); - } - - return $response; - } - - /** - * Creates a new instance of StreamInterface for the given body contents - * - * @param ReadableStreamInterface|string $body - * @return StreamInterface - */ - public function body($body) - { - if ($body instanceof ReadableStreamInterface) { - return new ReadableBodyStream($body); - } - - return \RingCentral\Psr7\stream_for($body); - } -} diff --git a/src/Io/Sender.php b/src/Io/Sender.php index 6f3367e5..6cba0495 100644 --- a/src/Io/Sender.php +++ b/src/Io/Sender.php @@ -6,6 +6,7 @@ use React\EventLoop\LoopInterface; use React\Http\Client\Client as HttpClient; use React\Http\Client\Response as ResponseStream; +use React\Http\Message\Response; use React\Promise\PromiseInterface; use React\Promise\Deferred; use React\Socket\ConnectorInterface; @@ -47,13 +48,12 @@ class Sender * @param ConnectorInterface|null $connector * @return self */ - public static function createFromLoop(LoopInterface $loop, ConnectorInterface $connector = null, MessageFactory $messageFactory) + public static function createFromLoop(LoopInterface $loop, ConnectorInterface $connector = null) { - return new self(new HttpClient($loop, $connector), $messageFactory); + return new self(new HttpClient($loop, $connector)); } private $http; - private $messageFactory; /** * [internal] Instantiate Sender @@ -61,10 +61,9 @@ public static function createFromLoop(LoopInterface $loop, ConnectorInterface $c * @param HttpClient $http * @internal */ - public function __construct(HttpClient $http, MessageFactory $messageFactory) + public function __construct(HttpClient $http) { $this->http = $http; - $this->messageFactory = $messageFactory; } /** @@ -109,16 +108,22 @@ public function send(RequestInterface $request) $deferred->reject($error); }); - $messageFactory = $this->messageFactory; - $requestStream->on('response', function (ResponseStream $responseStream) use ($deferred, $messageFactory, $request) { + $requestStream->on('response', function (ResponseStream $responseStream) use ($deferred, $request) { + $length = null; + $code = $responseStream->getCode(); + if ($request->getMethod() === 'HEAD' || ($code >= 100 && $code < 200) || $code == 204 || $code == 304) { + $length = 0; + } elseif ($responseStream->hasHeader('Content-Length')) { + $length = (int) $responseStream->getHeaderLine('Content-Length'); + } + // apply response header values from response stream - $deferred->resolve($messageFactory->response( - $responseStream->getVersion(), + $deferred->resolve(new Response( $responseStream->getCode(), - $responseStream->getReasonPhrase(), $responseStream->getHeaders(), - $responseStream, - $request->getMethod() + new ReadableBodyStream($responseStream, $length), + $responseStream->getVersion(), + $responseStream->getReasonPhrase() )); }); diff --git a/src/Io/Transaction.php b/src/Io/Transaction.php index 93741dcc..9449503f 100644 --- a/src/Io/Transaction.php +++ b/src/Io/Transaction.php @@ -5,6 +5,7 @@ use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\UriInterface; +use RingCentral\Psr7\Request; use RingCentral\Psr7\Uri; use React\EventLoop\LoopInterface; use React\Http\Message\ResponseException; @@ -18,7 +19,6 @@ class Transaction { private $sender; - private $messageFactory; private $loop; // context: http.timeout (ini_get('default_socket_timeout'): 60) @@ -37,10 +37,9 @@ class Transaction private $maximumSize = 16777216; // 16 MiB = 2^24 bytes - public function __construct(Sender $sender, MessageFactory $messageFactory, LoopInterface $loop) + public function __construct(Sender $sender, LoopInterface $loop) { $this->sender = $sender; - $this->messageFactory = $messageFactory; $this->loop = $loop; } @@ -55,7 +54,7 @@ public function withOptions(array $options) if (property_exists($transaction, $name)) { // restore default value if null is given if ($value === null) { - $default = new self($this->sender, $this->messageFactory, $this->loop); + $default = new self($this->sender, $this->loop); $value = $default->$name; } @@ -186,11 +185,10 @@ public function bufferResponse(ResponseInterface $response, $deferred) } // buffer stream and resolve with buffered body - $messageFactory = $this->messageFactory; $maximumSize = $this->maximumSize; $promise = \React\Promise\Stream\buffer($stream, $maximumSize)->then( - function ($body) use ($response, $messageFactory) { - return $response->withBody($messageFactory->body($body)); + function ($body) use ($response) { + return $response->withBody(\RingCentral\Psr7\stream_for($body)); }, function ($e) use ($stream, $maximumSize) { // try to close stream if buffering fails (or is cancelled) @@ -280,7 +278,7 @@ private function makeRedirectRequest(RequestInterface $request, UriInterface $lo // naïve approach.. $method = ($request->getMethod() === 'HEAD') ? 'HEAD' : 'GET'; - return $this->messageFactory->request($method, $location, $request->getHeaders()); + return new Request($method, $location, $request->getHeaders()); } private function progress($name, array $args = array()) diff --git a/tests/FunctionalBrowserTest.php b/tests/FunctionalBrowserTest.php index f4495565..59cba0b9 100644 --- a/tests/FunctionalBrowserTest.php +++ b/tests/FunctionalBrowserTest.php @@ -64,14 +64,22 @@ public function setUpBrowserAndServer() ); } - if ($path === '/status/300') { + if ($path === '/status/204') { return new Response( - 300, + 204, array(), '' ); } + if ($path === '/status/304') { + return new Response( + 304, + array(), + 'Not modified' + ); + } + if ($path === '/status/404') { return new Response( 404, @@ -308,12 +316,24 @@ public function testFollowRedirectsZeroRejectsOnRedirect() Block\await($browser->get($this->base . 'redirect-to?url=get'), $this->loop); } - /** - * @doesNotPerformAssertions - */ - public function testResponseStatus300WithoutLocationShouldResolveWithoutFollowingRedirect() + public function testResponseStatus204ShouldResolveWithEmptyBody() { - Block\await($this->browser->get($this->base . 'status/300'), $this->loop); + $response = Block\await($this->browser->get($this->base . 'status/204'), $this->loop); + $this->assertFalse($response->hasHeader('Content-Length')); + + $body = $response->getBody(); + $this->assertEquals(0, $body->getSize()); + $this->assertEquals('', (string) $body); + } + + public function testResponseStatus304ShouldResolveWithEmptyBodyButContentLengthResponseHeader() + { + $response = Block\await($this->browser->get($this->base . 'status/304'), $this->loop); + $this->assertEquals('12', $response->getHeaderLine('Content-Length')); + + $body = $response->getBody(); + $this->assertEquals(0, $body->getSize()); + $this->assertEquals('', (string) $body); } /** @@ -595,9 +615,33 @@ public function testSendsExplicitHttp10Request() public function testHeadRequestReceivesResponseWithEmptyBodyButWithContentLengthResponseHeader() { $response = Block\await($this->browser->head($this->base . 'get'), $this->loop); - $this->assertEquals('', (string)$response->getBody()); - $this->assertEquals(0, $response->getBody()->getSize()); $this->assertEquals('5', $response->getHeaderLine('Content-Length')); + + $body = $response->getBody(); + $this->assertEquals(0, $body->getSize()); + $this->assertEquals('', (string) $body); + } + + public function testRequestStreamingGetReceivesResponseWithStreamingBodyAndKnownSize() + { + $response = Block\await($this->browser->requestStreaming('GET', $this->base . 'get'), $this->loop); + $this->assertEquals('5', $response->getHeaderLine('Content-Length')); + + $body = $response->getBody(); + $this->assertEquals(5, $body->getSize()); + $this->assertEquals('', (string) $body); + $this->assertInstanceOf('React\Stream\ReadableStreamInterface', $body); + } + + public function testRequestStreamingGetReceivesResponseWithStreamingBodyAndUnknownSizeFromStreamingEndpoint() + { + $response = Block\await($this->browser->requestStreaming('GET', $this->base . 'stream/1'), $this->loop); + $this->assertFalse($response->hasHeader('Content-Length')); + + $body = $response->getBody(); + $this->assertNull($body->getSize()); + $this->assertEquals('', (string) $body); + $this->assertInstanceOf('React\Stream\ReadableStreamInterface', $body); } public function testRequestStreamingGetReceivesStreamingResponseBody() diff --git a/tests/Io/MessageFactoryTest.php b/tests/Io/MessageFactoryTest.php deleted file mode 100644 index ae2dcdf9..00000000 --- a/tests/Io/MessageFactoryTest.php +++ /dev/null @@ -1,135 +0,0 @@ -messageFactory = new MessageFactory(); - } - - public function testBodyString() - { - $body = $this->messageFactory->body('hi'); - - $this->assertInstanceOf('Psr\Http\Message\StreamInterface', $body); - $this->assertNotInstanceOf('React\Stream\ReadableStreamInterface', $body); - $this->assertEquals(2, $body->getSize()); - $this->assertEquals('hi', (string)$body); - } - - public function testBodyReadableStream() - { - $stream = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock(); - $body = $this->messageFactory->body($stream); - - $this->assertInstanceOf('Psr\Http\Message\StreamInterface', $body); - $this->assertInstanceOf('React\Stream\ReadableStreamInterface', $body); - $this->assertEquals(null, $body->getSize()); - $this->assertEquals('', (string)$body); - } - - public function testResponseWithBodyString() - { - $response = $this->messageFactory->response('1.1', 200, 'OK', array(), 'hi'); - - $body = $response->getBody(); - $this->assertInstanceOf('Psr\Http\Message\StreamInterface', $body); - $this->assertNotInstanceOf('React\Stream\ReadableStreamInterface', $body); - $this->assertEquals(2, $body->getSize()); - $this->assertEquals('hi', (string)$body); - } - - public function testResponseWithStreamingBodyHasUnknownSizeByDefault() - { - $stream = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock(); - $response = $this->messageFactory->response('1.1', 200, 'OK', array(), $stream); - - $body = $response->getBody(); - $this->assertInstanceOf('Psr\Http\Message\StreamInterface', $body); - $this->assertInstanceOf('React\Stream\ReadableStreamInterface', $body); - $this->assertNull($body->getSize()); - $this->assertEquals('', (string)$body); - } - - public function testResponseWithStreamingBodyHasSizeFromContentLengthHeader() - { - $stream = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock(); - $response = $this->messageFactory->response('1.1', 200, 'OK', array('Content-Length' => '100'), $stream); - - $body = $response->getBody(); - $this->assertInstanceOf('Psr\Http\Message\StreamInterface', $body); - $this->assertInstanceOf('React\Stream\ReadableStreamInterface', $body); - $this->assertEquals(100, $body->getSize()); - $this->assertEquals('', (string)$body); - } - - public function testResponseWithStreamingBodyHasUnknownSizeWithTransferEncodingChunkedHeader() - { - $stream = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock(); - $response = $this->messageFactory->response('1.1', 200, 'OK', array('Transfer-Encoding' => 'chunked'), $stream); - - $body = $response->getBody(); - $this->assertInstanceOf('Psr\Http\Message\StreamInterface', $body); - $this->assertInstanceOf('React\Stream\ReadableStreamInterface', $body); - $this->assertNull($body->getSize()); - $this->assertEquals('', (string)$body); - } - - public function testResponseWithStreamingBodyHasZeroSizeForInformationalResponse() - { - $stream = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock(); - $response = $this->messageFactory->response('1.1', 101, 'OK', array('Content-Length' => '100'), $stream); - - $body = $response->getBody(); - $this->assertInstanceOf('Psr\Http\Message\StreamInterface', $body); - $this->assertInstanceOf('React\Stream\ReadableStreamInterface', $body); - $this->assertEquals(0, $body->getSize()); - $this->assertEquals('', (string)$body); - } - - public function testResponseWithStreamingBodyHasZeroSizeForNoContentResponse() - { - $stream = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock(); - $response = $this->messageFactory->response('1.1', 204, 'OK', array('Content-Length' => '100'), $stream); - - $body = $response->getBody(); - $this->assertInstanceOf('Psr\Http\Message\StreamInterface', $body); - $this->assertInstanceOf('React\Stream\ReadableStreamInterface', $body); - $this->assertEquals(0, $body->getSize()); - $this->assertEquals('', (string)$body); - } - - public function testResponseWithStreamingBodyHasZeroSizeForNotModifiedResponse() - { - $stream = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock(); - $response = $this->messageFactory->response('1.1', 304, 'OK', array('Content-Length' => '100'), $stream); - - $body = $response->getBody(); - $this->assertInstanceOf('Psr\Http\Message\StreamInterface', $body); - $this->assertInstanceOf('React\Stream\ReadableStreamInterface', $body); - $this->assertEquals(0, $body->getSize()); - $this->assertEquals('', (string)$body); - } - - public function testResponseWithStreamingBodyHasZeroSizeForHeadRequestMethod() - { - $stream = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock(); - $response = $this->messageFactory->response('1.1', 200, 'OK', array('Content-Length' => '100'), $stream, 'HEAD'); - - $body = $response->getBody(); - $this->assertInstanceOf('Psr\Http\Message\StreamInterface', $body); - $this->assertInstanceOf('React\Stream\ReadableStreamInterface', $body); - $this->assertEquals(0, $body->getSize()); - $this->assertEquals('', (string)$body); - } -} diff --git a/tests/Io/SenderTest.php b/tests/Io/SenderTest.php index 35eb22e7..1c6d1d6b 100644 --- a/tests/Io/SenderTest.php +++ b/tests/Io/SenderTest.php @@ -26,7 +26,7 @@ public function setUpLoop() public function testCreateFromLoop() { - $sender = Sender::createFromLoop($this->loop, null, $this->getMockBuilder('React\Http\Io\MessageFactory')->getMock()); + $sender = Sender::createFromLoop($this->loop, null); $this->assertInstanceOf('React\Http\Io\Sender', $sender); } @@ -36,7 +36,7 @@ public function testSenderRejectsInvalidUri() $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); $connector->expects($this->never())->method('connect'); - $sender = new Sender(new HttpClient($this->loop, $connector), $this->getMockBuilder('React\Http\Io\MessageFactory')->getMock()); + $sender = new Sender(new HttpClient($this->loop, $connector)); $request = new Request('GET', 'www.google.com'); @@ -51,7 +51,7 @@ public function testSenderConnectorRejection() $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); $connector->expects($this->once())->method('connect')->willReturn(Promise\reject(new \RuntimeException('Rejected'))); - $sender = new Sender(new HttpClient($this->loop, $connector), $this->getMockBuilder('React\Http\Io\MessageFactory')->getMock()); + $sender = new Sender(new HttpClient($this->loop, $connector)); $request = new Request('GET', 'http://www.google.com/'); @@ -71,7 +71,7 @@ public function testSendPostWillAutomaticallySendContentLengthHeader() '1.1' )->willReturn($this->getMockBuilder('React\Http\Client\Request')->disableOriginalConstructor()->getMock()); - $sender = new Sender($client, $this->getMockBuilder('React\Http\Io\MessageFactory')->getMock()); + $sender = new Sender($client); $request = new Request('POST', 'http://www.google.com/', array(), 'hello'); $sender->send($request); @@ -87,7 +87,7 @@ public function testSendPostWillAutomaticallySendContentLengthZeroHeaderForEmpty '1.1' )->willReturn($this->getMockBuilder('React\Http\Client\Request')->disableOriginalConstructor()->getMock()); - $sender = new Sender($client, $this->getMockBuilder('React\Http\Io\MessageFactory')->getMock()); + $sender = new Sender($client); $request = new Request('POST', 'http://www.google.com/', array(), ''); $sender->send($request); @@ -106,7 +106,7 @@ public function testSendPostStreamWillAutomaticallySendTransferEncodingChunked() '1.1' )->willReturn($outgoing); - $sender = new Sender($client, $this->getMockBuilder('React\Http\Io\MessageFactory')->getMock()); + $sender = new Sender($client); $stream = new ThroughStream(); $request = new Request('POST', 'http://www.google.com/', array(), new ReadableBodyStream($stream)); @@ -122,7 +122,7 @@ public function testSendPostStreamWillAutomaticallyPipeChunkEncodeBodyForWriteAn $client = $this->getMockBuilder('React\Http\Client\Client')->disableOriginalConstructor()->getMock(); $client->expects($this->once())->method('request')->willReturn($outgoing); - $sender = new Sender($client, $this->getMockBuilder('React\Http\Io\MessageFactory')->getMock()); + $sender = new Sender($client); $stream = new ThroughStream(); $request = new Request('POST', 'http://www.google.com/', array(), new ReadableBodyStream($stream)); @@ -142,7 +142,7 @@ public function testSendPostStreamWillAutomaticallyPipeChunkEncodeBodyForEnd() $client = $this->getMockBuilder('React\Http\Client\Client')->disableOriginalConstructor()->getMock(); $client->expects($this->once())->method('request')->willReturn($outgoing); - $sender = new Sender($client, $this->getMockBuilder('React\Http\Io\MessageFactory')->getMock()); + $sender = new Sender($client); $stream = new ThroughStream(); $request = new Request('POST', 'http://www.google.com/', array(), new ReadableBodyStream($stream)); @@ -162,7 +162,7 @@ public function testSendPostStreamWillRejectWhenRequestBodyEmitsErrorEvent() $client = $this->getMockBuilder('React\Http\Client\Client')->disableOriginalConstructor()->getMock(); $client->expects($this->once())->method('request')->willReturn($outgoing); - $sender = new Sender($client, $this->getMockBuilder('React\Http\Io\MessageFactory')->getMock()); + $sender = new Sender($client); $expected = new \RuntimeException(); $stream = new ThroughStream(); @@ -192,7 +192,7 @@ public function testSendPostStreamWillRejectWhenRequestBodyClosesWithoutEnd() $client = $this->getMockBuilder('React\Http\Client\Client')->disableOriginalConstructor()->getMock(); $client->expects($this->once())->method('request')->willReturn($outgoing); - $sender = new Sender($client, $this->getMockBuilder('React\Http\Io\MessageFactory')->getMock()); + $sender = new Sender($client); $stream = new ThroughStream(); $request = new Request('POST', 'http://www.google.com/', array(), new ReadableBodyStream($stream)); @@ -220,7 +220,7 @@ public function testSendPostStreamWillNotRejectWhenRequestBodyClosesAfterEnd() $client = $this->getMockBuilder('React\Http\Client\Client')->disableOriginalConstructor()->getMock(); $client->expects($this->once())->method('request')->willReturn($outgoing); - $sender = new Sender($client, $this->getMockBuilder('React\Http\Io\MessageFactory')->getMock()); + $sender = new Sender($client); $stream = new ThroughStream(); $request = new Request('POST', 'http://www.google.com/', array(), new ReadableBodyStream($stream)); @@ -247,7 +247,7 @@ public function testSendPostStreamWithExplicitContentLengthWillSendHeaderAsIs() '1.1' )->willReturn($this->getMockBuilder('React\Http\Client\Request')->disableOriginalConstructor()->getMock()); - $sender = new Sender($client, $this->getMockBuilder('React\Http\Io\MessageFactory')->getMock()); + $sender = new Sender($client); $stream = new ThroughStream(); $request = new Request('POST', 'http://www.google.com/', array('Content-Length' => '100'), new ReadableBodyStream($stream)); @@ -264,7 +264,7 @@ public function testSendGetWillNotPassContentLengthHeaderForEmptyRequestBody() '1.1' )->willReturn($this->getMockBuilder('React\Http\Client\Request')->disableOriginalConstructor()->getMock()); - $sender = new Sender($client, $this->getMockBuilder('React\Http\Io\MessageFactory')->getMock()); + $sender = new Sender($client); $request = new Request('GET', 'http://www.google.com/'); $sender->send($request); @@ -280,7 +280,7 @@ public function testSendCustomMethodWillNotPassContentLengthHeaderForEmptyReques '1.1' )->willReturn($this->getMockBuilder('React\Http\Client\Request')->disableOriginalConstructor()->getMock()); - $sender = new Sender($client, $this->getMockBuilder('React\Http\Io\MessageFactory')->getMock()); + $sender = new Sender($client); $request = new Request('CUSTOM', 'http://www.google.com/'); $sender->send($request); @@ -296,7 +296,7 @@ public function testSendCustomMethodWithExplicitContentLengthZeroWillBePassedAsI '1.1' )->willReturn($this->getMockBuilder('React\Http\Client\Request')->disableOriginalConstructor()->getMock()); - $sender = new Sender($client, $this->getMockBuilder('React\Http\Io\MessageFactory')->getMock()); + $sender = new Sender($client); $request = new Request('CUSTOM', 'http://www.google.com/', array('Content-Length' => '0')); $sender->send($request); @@ -311,7 +311,7 @@ public function testCancelRequestWillCancelConnector() $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); $connector->expects($this->once())->method('connect')->willReturn($promise); - $sender = new Sender(new HttpClient($this->loop, $connector), $this->getMockBuilder('React\Http\Io\MessageFactory')->getMock()); + $sender = new Sender(new HttpClient($this->loop, $connector)); $request = new Request('GET', 'http://www.google.com/'); @@ -330,7 +330,7 @@ public function testCancelRequestWillCloseConnection() $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); $connector->expects($this->once())->method('connect')->willReturn(Promise\resolve($connection)); - $sender = new Sender(new HttpClient($this->loop, $connector), $this->getMockBuilder('React\Http\Io\MessageFactory')->getMock()); + $sender = new Sender(new HttpClient($this->loop, $connector)); $request = new Request('GET', 'http://www.google.com/'); @@ -387,7 +387,7 @@ public function testRequestProtocolVersion(Request $Request, $method, $uri, $hea $http->expects($this->once())->method('request')->with($method, $uri, $headers, $protocolVersion)->willReturn($request); - $sender = new Sender($http, $this->getMockBuilder('React\Http\Io\MessageFactory')->getMock()); + $sender = new Sender($http); $sender->send($Request); } } diff --git a/tests/Io/TransactionTest.php b/tests/Io/TransactionTest.php index 88320bf0..384a74a6 100644 --- a/tests/Io/TransactionTest.php +++ b/tests/Io/TransactionTest.php @@ -5,7 +5,7 @@ use Clue\React\Block; use PHPUnit\Framework\MockObject\MockObject; use Psr\Http\Message\RequestInterface; -use React\Http\Io\MessageFactory; +use RingCentral\Psr7\Response; use React\Http\Io\Transaction; use React\Http\Message\ResponseException; use React\EventLoop\Factory; @@ -13,7 +13,8 @@ use React\Promise\Deferred; use React\Stream\ThroughStream; use React\Tests\Http\TestCase; -use RingCentral\Psr7\Response; +use RingCentral\Psr7\Request; +use React\Http\Io\ReadableBodyStream; class TransactionTest extends TestCase { @@ -21,7 +22,7 @@ public function testWithOptionsReturnsNewInstanceWithChangedOption() { $sender = $this->makeSenderMock(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - $transaction = new Transaction($sender, new MessageFactory(), $loop); + $transaction = new Transaction($sender, $loop); $new = $transaction->withOptions(array('followRedirects' => false)); @@ -38,7 +39,7 @@ public function testWithOptionsDoesNotChangeOriginalInstance() { $sender = $this->makeSenderMock(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - $transaction = new Transaction($sender, new MessageFactory(), $loop); + $transaction = new Transaction($sender, $loop); $transaction->withOptions(array('followRedirects' => false)); @@ -52,7 +53,7 @@ public function testWithOptionsNullValueReturnsNewInstanceWithDefaultOption() { $sender = $this->makeSenderMock(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - $transaction = new Transaction($sender, new MessageFactory(), $loop); + $transaction = new Transaction($sender, $loop); $transaction = $transaction->withOptions(array('followRedirects' => false)); $transaction = $transaction->withOptions(array('followRedirects' => null)); @@ -65,8 +66,6 @@ public function testWithOptionsNullValueReturnsNewInstanceWithDefaultOption() public function testTimeoutExplicitOptionWillStartTimeoutTimer() { - $messageFactory = new MessageFactory(); - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); $loop->expects($this->once())->method('addTimer')->with(2, $this->anything())->willReturn($timer); @@ -77,7 +76,7 @@ public function testTimeoutExplicitOptionWillStartTimeoutTimer() $sender = $this->getMockBuilder('React\Http\Io\Sender')->disableOriginalConstructor()->getMock(); $sender->expects($this->once())->method('send')->with($this->equalTo($request))->willReturn(new \React\Promise\Promise(function () { })); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $transaction = $transaction->withOptions(array('timeout' => 2)); $promise = $transaction->send($request); @@ -86,8 +85,6 @@ public function testTimeoutExplicitOptionWillStartTimeoutTimer() public function testTimeoutImplicitFromIniWillStartTimeoutTimer() { - $messageFactory = new MessageFactory(); - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); $loop->expects($this->once())->method('addTimer')->with(2, $this->anything())->willReturn($timer); @@ -98,7 +95,7 @@ public function testTimeoutImplicitFromIniWillStartTimeoutTimer() $sender = $this->getMockBuilder('React\Http\Io\Sender')->disableOriginalConstructor()->getMock(); $sender->expects($this->once())->method('send')->with($this->equalTo($request))->willReturn(new \React\Promise\Promise(function () { })); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $old = ini_get('default_socket_timeout'); ini_set('default_socket_timeout', '2'); @@ -110,8 +107,6 @@ public function testTimeoutImplicitFromIniWillStartTimeoutTimer() public function testTimeoutExplicitOptionWillRejectWhenTimerFires() { - $messageFactory = new MessageFactory(); - $timeout = null; $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); @@ -126,7 +121,7 @@ public function testTimeoutExplicitOptionWillRejectWhenTimerFires() $sender = $this->getMockBuilder('React\Http\Io\Sender')->disableOriginalConstructor()->getMock(); $sender->expects($this->once())->method('send')->with($this->equalTo($request))->willReturn(new \React\Promise\Promise(function () { })); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $transaction = $transaction->withOptions(array('timeout' => 2)); $promise = $transaction->send($request); @@ -144,18 +139,16 @@ public function testTimeoutExplicitOptionWillRejectWhenTimerFires() public function testTimeoutExplicitOptionWillNotStartTimeoutWhenSenderResolvesImmediately() { - $messageFactory = new MessageFactory(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); $loop->expects($this->never())->method('addTimer'); $request = $this->getMockBuilder('Psr\Http\Message\RequestInterface')->getMock(); - $response = $messageFactory->response(1.0, 200, 'OK', array(), ''); + $response = new Response(200, array(), ''); $sender = $this->getMockBuilder('React\Http\Io\Sender')->disableOriginalConstructor()->getMock(); $sender->expects($this->once())->method('send')->with($this->equalTo($request))->willReturn(Promise\resolve($response)); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $transaction = $transaction->withOptions(array('timeout' => 0.001)); $promise = $transaction->send($request); @@ -165,21 +158,19 @@ public function testTimeoutExplicitOptionWillNotStartTimeoutWhenSenderResolvesIm public function testTimeoutExplicitOptionWillCancelTimeoutTimerWhenSenderResolvesLaterOn() { - $messageFactory = new MessageFactory(); - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); $loop->expects($this->once())->method('addTimer')->willReturn($timer); $loop->expects($this->once())->method('cancelTimer')->with($timer); $request = $this->getMockBuilder('Psr\Http\Message\RequestInterface')->getMock(); - $response = $messageFactory->response(1.0, 200, 'OK', array(), ''); + $response = new Response(200, array(), ''); $deferred = new Deferred(); $sender = $this->getMockBuilder('React\Http\Io\Sender')->disableOriginalConstructor()->getMock(); $sender->expects($this->once())->method('send')->with($this->equalTo($request))->willReturn($deferred->promise()); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $transaction = $transaction->withOptions(array('timeout' => 0.001)); $promise = $transaction->send($request); @@ -191,8 +182,6 @@ public function testTimeoutExplicitOptionWillCancelTimeoutTimerWhenSenderResolve public function testTimeoutExplicitOptionWillNotStartTimeoutWhenSenderRejectsImmediately() { - $messageFactory = new MessageFactory(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); $loop->expects($this->never())->method('addTimer'); @@ -202,7 +191,7 @@ public function testTimeoutExplicitOptionWillNotStartTimeoutWhenSenderRejectsImm $sender = $this->getMockBuilder('React\Http\Io\Sender')->disableOriginalConstructor()->getMock(); $sender->expects($this->once())->method('send')->with($this->equalTo($request))->willReturn(Promise\reject($exception)); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $transaction = $transaction->withOptions(array('timeout' => 0.001)); $promise = $transaction->send($request); @@ -212,8 +201,6 @@ public function testTimeoutExplicitOptionWillNotStartTimeoutWhenSenderRejectsImm public function testTimeoutExplicitOptionWillCancelTimeoutTimerWhenSenderRejectsLaterOn() { - $messageFactory = new MessageFactory(); - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); $loop->expects($this->once())->method('addTimer')->willReturn($timer); @@ -225,7 +212,7 @@ public function testTimeoutExplicitOptionWillCancelTimeoutTimerWhenSenderRejects $sender = $this->getMockBuilder('React\Http\Io\Sender')->disableOriginalConstructor()->getMock(); $sender->expects($this->once())->method('send')->with($this->equalTo($request))->willReturn($deferred->promise()); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $transaction = $transaction->withOptions(array('timeout' => 0.001)); $promise = $transaction->send($request); @@ -238,8 +225,6 @@ public function testTimeoutExplicitOptionWillCancelTimeoutTimerWhenSenderRejects public function testTimeoutExplicitNegativeWillNotStartTimeoutTimer() { - $messageFactory = new MessageFactory(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); $loop->expects($this->never())->method('addTimer'); @@ -248,7 +233,7 @@ public function testTimeoutExplicitNegativeWillNotStartTimeoutTimer() $sender = $this->getMockBuilder('React\Http\Io\Sender')->disableOriginalConstructor()->getMock(); $sender->expects($this->once())->method('send')->with($this->equalTo($request))->willReturn(new \React\Promise\Promise(function () { })); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $transaction = $transaction->withOptions(array('timeout' => -1)); $promise = $transaction->send($request); @@ -257,18 +242,16 @@ public function testTimeoutExplicitNegativeWillNotStartTimeoutTimer() public function testTimeoutExplicitOptionWillNotStartTimeoutTimerWhenRequestBodyIsStreaming() { - $messageFactory = new MessageFactory(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); $loop->expects($this->never())->method('addTimer'); $stream = new ThroughStream(); - $request = $messageFactory->request('POST', 'http://example.com', array(), $stream); + $request = new Request('POST', 'http://example.com', array(), new ReadableBodyStream($stream)); $sender = $this->getMockBuilder('React\Http\Io\Sender')->disableOriginalConstructor()->getMock(); $sender->expects($this->once())->method('send')->with($this->equalTo($request))->willReturn(new \React\Promise\Promise(function () { })); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $transaction = $transaction->withOptions(array('timeout' => 2)); $promise = $transaction->send($request); @@ -277,8 +260,6 @@ public function testTimeoutExplicitOptionWillNotStartTimeoutTimerWhenRequestBody public function testTimeoutExplicitOptionWillStartTimeoutTimerWhenStreamingRequestBodyIsAlreadyClosed() { - $messageFactory = new MessageFactory(); - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); $loop->expects($this->once())->method('addTimer')->with(2, $this->anything())->willReturn($timer); @@ -286,12 +267,12 @@ public function testTimeoutExplicitOptionWillStartTimeoutTimerWhenStreamingReque $stream = new ThroughStream(); $stream->close(); - $request = $messageFactory->request('POST', 'http://example.com', array(), $stream); + $request = new Request('POST', 'http://example.com', array(), new ReadableBodyStream($stream)); $sender = $this->getMockBuilder('React\Http\Io\Sender')->disableOriginalConstructor()->getMock(); $sender->expects($this->once())->method('send')->with($this->equalTo($request))->willReturn(new \React\Promise\Promise(function () { })); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $transaction = $transaction->withOptions(array('timeout' => 2)); $promise = $transaction->send($request); @@ -300,20 +281,18 @@ public function testTimeoutExplicitOptionWillStartTimeoutTimerWhenStreamingReque public function testTimeoutExplicitOptionWillStartTimeoutTimerWhenStreamingRequestBodyClosesWhileSenderIsStillPending() { - $messageFactory = new MessageFactory(); - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); $loop->expects($this->once())->method('addTimer')->with(2, $this->anything())->willReturn($timer); $loop->expects($this->never())->method('cancelTimer'); $stream = new ThroughStream(); - $request = $messageFactory->request('POST', 'http://example.com', array(), $stream); + $request = new Request('POST', 'http://example.com', array(), new ReadableBodyStream($stream)); $sender = $this->getMockBuilder('React\Http\Io\Sender')->disableOriginalConstructor()->getMock(); $sender->expects($this->once())->method('send')->with($this->equalTo($request))->willReturn(new \React\Promise\Promise(function () { })); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $transaction = $transaction->withOptions(array('timeout' => 2)); $promise = $transaction->send($request); @@ -324,19 +303,17 @@ public function testTimeoutExplicitOptionWillStartTimeoutTimerWhenStreamingReque public function testTimeoutExplicitOptionWillNotStartTimeoutTimerWhenStreamingRequestBodyClosesAfterSenderRejects() { - $messageFactory = new MessageFactory(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); $loop->expects($this->never())->method('addTimer'); $stream = new ThroughStream(); - $request = $messageFactory->request('POST', 'http://example.com', array(), $stream); + $request = new Request('POST', 'http://example.com', array(), new ReadableBodyStream($stream)); $deferred = new Deferred(); $sender = $this->getMockBuilder('React\Http\Io\Sender')->disableOriginalConstructor()->getMock(); $sender->expects($this->once())->method('send')->with($this->equalTo($request))->willReturn($deferred->promise()); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $transaction = $transaction->withOptions(array('timeout' => 2)); $promise = $transaction->send($request); @@ -348,8 +325,6 @@ public function testTimeoutExplicitOptionWillNotStartTimeoutTimerWhenStreamingRe public function testTimeoutExplicitOptionWillRejectWhenTimerFiresAfterStreamingRequestBodyCloses() { - $messageFactory = new MessageFactory(); - $timeout = null; $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); @@ -360,12 +335,12 @@ public function testTimeoutExplicitOptionWillRejectWhenTimerFiresAfterStreamingR $loop->expects($this->never())->method('cancelTimer'); $stream = new ThroughStream(); - $request = $messageFactory->request('POST', 'http://example.com', array(), $stream); + $request = new Request('POST', 'http://example.com', array(), new ReadableBodyStream($stream)); $sender = $this->getMockBuilder('React\Http\Io\Sender')->disableOriginalConstructor()->getMock(); $sender->expects($this->once())->method('send')->with($this->equalTo($request))->willReturn(new \React\Promise\Promise(function () { })); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $transaction = $transaction->withOptions(array('timeout' => 2)); $promise = $transaction->send($request); @@ -393,7 +368,7 @@ public function testReceivingErrorResponseWillRejectWithResponseException() $sender = $this->makeSenderMock(); $sender->expects($this->once())->method('send')->with($this->equalTo($request))->willReturn(Promise\resolve($response)); - $transaction = new Transaction($sender, new MessageFactory(), $loop); + $transaction = new Transaction($sender, $loop); $transaction = $transaction->withOptions(array('timeout' => -1)); $promise = $transaction->send($request); @@ -408,7 +383,6 @@ public function testReceivingErrorResponseWillRejectWithResponseException() public function testReceivingStreamingBodyWillResolveWithBufferedResponseByDefault() { - $messageFactory = new MessageFactory(); $loop = Factory::create(); $stream = new ThroughStream(); @@ -418,13 +392,13 @@ public function testReceivingStreamingBodyWillResolveWithBufferedResponseByDefau }); $request = $this->getMockBuilder('Psr\Http\Message\RequestInterface')->getMock(); - $response = $messageFactory->response(1.0, 200, 'OK', array(), $stream); + $response = new Response(200, array(), new ReadableBodyStream($stream)); // mock sender to resolve promise with the given $response in response to the given $request $sender = $this->makeSenderMock(); $sender->expects($this->once())->method('send')->with($this->equalTo($request))->willReturn(Promise\resolve($response)); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $promise = $transaction->send($request); $response = Block\await($promise, $loop); @@ -435,7 +409,6 @@ public function testReceivingStreamingBodyWillResolveWithBufferedResponseByDefau public function testReceivingStreamingBodyWithSizeExceedingMaximumResponseBufferWillRejectAndCloseResponseStream() { - $messageFactory = new MessageFactory(); $loop = Factory::create(); $stream = new ThroughStream(); @@ -443,13 +416,13 @@ public function testReceivingStreamingBodyWithSizeExceedingMaximumResponseBuffer $request = $this->getMockBuilder('Psr\Http\Message\RequestInterface')->getMock(); - $response = $messageFactory->response(1.0, 200, 'OK', array('Content-Length' => '100000000'), $stream); + $response = new Response(200, array('Content-Length' => '100000000'), new ReadableBodyStream($stream, 100000000)); // mock sender to resolve promise with the given $response in response to the given $request $sender = $this->makeSenderMock(); $sender->expects($this->once())->method('send')->with($this->equalTo($request))->willReturn(Promise\resolve($response)); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $promise = $transaction->send($request); $this->setExpectedException('OverflowException'); @@ -458,7 +431,6 @@ public function testReceivingStreamingBodyWithSizeExceedingMaximumResponseBuffer public function testCancelBufferingResponseWillCloseStreamAndReject() { - $messageFactory = new MessageFactory(); $loop = Factory::create(); $stream = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock(); @@ -466,13 +438,13 @@ public function testCancelBufferingResponseWillCloseStreamAndReject() $stream->expects($this->once())->method('close'); $request = $this->getMockBuilder('Psr\Http\Message\RequestInterface')->getMock(); - $response = $messageFactory->response(1.0, 200, 'OK', array(), $stream); + $response = new Response(200, array(), new ReadableBodyStream($stream)); // mock sender to resolve promise with the given $response in response to the given $request $sender = $this->makeSenderMock(); $sender->expects($this->once())->method('send')->with($this->equalTo($request))->willReturn(Promise\resolve($response)); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $promise = $transaction->send($request); $promise->cancel(); @@ -482,17 +454,16 @@ public function testCancelBufferingResponseWillCloseStreamAndReject() public function testReceivingStreamingBodyWillResolveWithStreamingResponseIfStreamingIsEnabled() { - $messageFactory = new MessageFactory(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); $request = $this->getMockBuilder('Psr\Http\Message\RequestInterface')->getMock(); - $response = $messageFactory->response(1.0, 200, 'OK', array(), $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock()); + $response = new Response(200, array(), new ReadableBodyStream($this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock())); // mock sender to resolve promise with the given $response in response to the given $request $sender = $this->makeSenderMock(); $sender->expects($this->once())->method('send')->with($this->equalTo($request))->willReturn(Promise\resolve($response)); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $transaction = $transaction->withOptions(array('streaming' => true, 'timeout' => -1)); $promise = $transaction->send($request); @@ -504,16 +475,15 @@ public function testReceivingStreamingBodyWillResolveWithStreamingResponseIfStre public function testResponseCode304WithoutLocationWillResolveWithResponseAsIs() { - $messageFactory = new MessageFactory(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); // conditional GET request will respond with 304 (Not Modified - $request = $messageFactory->request('GET', 'http://example.com', array('If-None-Match' => '"abc"')); - $response = $messageFactory->response(1.0, 304, null, array('ETag' => '"abc"')); + $request = new Request('GET', 'http://example.com', array('If-None-Match' => '"abc"')); + $response = new Response(304, array('ETag' => '"abc"')); $sender = $this->makeSenderMock(); $sender->expects($this->once())->method('send')->with($request)->willReturn(Promise\resolve($response)); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $transaction = $transaction->withOptions(array('timeout' => -1)); $promise = $transaction->send($request); @@ -522,12 +492,11 @@ public function testResponseCode304WithoutLocationWillResolveWithResponseAsIs() public function testCustomRedirectResponseCode333WillFollowLocationHeaderAndSendRedirectedRequest() { - $messageFactory = new MessageFactory(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); // original GET request will respond with custom 333 redirect status code and follow location header - $requestOriginal = $messageFactory->request('GET', 'http://example.com'); - $response = $messageFactory->response(1.0, 333, null, array('Location' => 'foo')); + $requestOriginal = new Request('GET', 'http://example.com'); + $response = new Response(333, array('Location' => 'foo')); $sender = $this->makeSenderMock(); $sender->expects($this->exactly(2))->method('send')->withConsecutive( array($requestOriginal), @@ -539,27 +508,26 @@ public function testCustomRedirectResponseCode333WillFollowLocationHeaderAndSend new \React\Promise\Promise(function () { }) ); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $transaction->send($requestOriginal); } public function testFollowingRedirectWithSpecifiedHeaders() { - $messageFactory = new MessageFactory(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); $customHeaders = array('User-Agent' => 'Chrome'); - $requestWithUserAgent = $messageFactory->request('GET', 'http://example.com', $customHeaders); + $requestWithUserAgent = new Request('GET', 'http://example.com', $customHeaders); $sender = $this->makeSenderMock(); // mock sender to resolve promise with the given $redirectResponse in // response to the given $requestWithUserAgent - $redirectResponse = $messageFactory->response(1.0, 301, null, array('Location' => 'http://redirect.com')); + $redirectResponse = new Response(301, array('Location' => 'http://redirect.com')); $sender->expects($this->at(0))->method('send')->willReturn(Promise\resolve($redirectResponse)); // mock sender to resolve promise with the given $okResponse in // response to the given $requestWithUserAgent - $okResponse = $messageFactory->response(1.0, 200, 'OK'); + $okResponse = new Response(200); $that = $this; $sender->expects($this->at(1)) ->method('send') @@ -568,27 +536,26 @@ public function testFollowingRedirectWithSpecifiedHeaders() return true; }))->willReturn(Promise\resolve($okResponse)); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $transaction->send($requestWithUserAgent); } public function testRemovingAuthorizationHeaderWhenChangingHostnamesDuringRedirect() { - $messageFactory = new MessageFactory(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); $customHeaders = array('Authorization' => 'secret'); - $requestWithAuthorization = $messageFactory->request('GET', 'http://example.com', $customHeaders); + $requestWithAuthorization = new Request('GET', 'http://example.com', $customHeaders); $sender = $this->makeSenderMock(); // mock sender to resolve promise with the given $redirectResponse in // response to the given $requestWithAuthorization - $redirectResponse = $messageFactory->response(1.0, 301, null, array('Location' => 'http://redirect.com')); + $redirectResponse = new Response(301, array('Location' => 'http://redirect.com')); $sender->expects($this->at(0))->method('send')->willReturn(Promise\resolve($redirectResponse)); // mock sender to resolve promise with the given $okResponse in // response to the given $requestWithAuthorization - $okResponse = $messageFactory->response(1.0, 200, 'OK'); + $okResponse = new Response(200); $that = $this; $sender->expects($this->at(1)) ->method('send') @@ -597,27 +564,26 @@ public function testRemovingAuthorizationHeaderWhenChangingHostnamesDuringRedire return true; }))->willReturn(Promise\resolve($okResponse)); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $transaction->send($requestWithAuthorization); } public function testAuthorizationHeaderIsForwardedWhenRedirectingToSameDomain() { - $messageFactory = new MessageFactory(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); $customHeaders = array('Authorization' => 'secret'); - $requestWithAuthorization = $messageFactory->request('GET', 'http://example.com', $customHeaders); + $requestWithAuthorization = new Request('GET', 'http://example.com', $customHeaders); $sender = $this->makeSenderMock(); // mock sender to resolve promise with the given $redirectResponse in // response to the given $requestWithAuthorization - $redirectResponse = $messageFactory->response(1.0, 301, null, array('Location' => 'http://example.com/new')); + $redirectResponse = new Response(301, array('Location' => 'http://example.com/new')); $sender->expects($this->at(0))->method('send')->willReturn(Promise\resolve($redirectResponse)); // mock sender to resolve promise with the given $okResponse in // response to the given $requestWithAuthorization - $okResponse = $messageFactory->response(1.0, 200, 'OK'); + $okResponse = new Response(200); $that = $this; $sender->expects($this->at(1)) ->method('send') @@ -626,26 +592,25 @@ public function testAuthorizationHeaderIsForwardedWhenRedirectingToSameDomain() return true; }))->willReturn(Promise\resolve($okResponse)); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $transaction->send($requestWithAuthorization); } public function testAuthorizationHeaderIsForwardedWhenLocationContainsAuthentication() { - $messageFactory = new MessageFactory(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - $request = $messageFactory->request('GET', 'http://example.com'); + $request = new Request('GET', 'http://example.com'); $sender = $this->makeSenderMock(); // mock sender to resolve promise with the given $redirectResponse in // response to the given $requestWithAuthorization - $redirectResponse = $messageFactory->response(1.0, 301, null, array('Location' => 'http://user:pass@example.com/new')); + $redirectResponse = new Response(301, array('Location' => 'http://user:pass@example.com/new')); $sender->expects($this->at(0))->method('send')->willReturn(Promise\resolve($redirectResponse)); // mock sender to resolve promise with the given $okResponse in // response to the given $requestWithAuthorization - $okResponse = $messageFactory->response(1.0, 200, 'OK'); + $okResponse = new Response(200); $that = $this; $sender->expects($this->at(1)) ->method('send') @@ -655,13 +620,12 @@ public function testAuthorizationHeaderIsForwardedWhenLocationContainsAuthentica return true; }))->willReturn(Promise\resolve($okResponse)); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $transaction->send($request); } public function testSomeRequestHeadersShouldBeRemovedWhenRedirecting() { - $messageFactory = new MessageFactory(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); $customHeaders = array( @@ -669,17 +633,17 @@ public function testSomeRequestHeadersShouldBeRemovedWhenRedirecting() 'Content-Length' => '111', ); - $requestWithCustomHeaders = $messageFactory->request('GET', 'http://example.com', $customHeaders); + $requestWithCustomHeaders = new Request('GET', 'http://example.com', $customHeaders); $sender = $this->makeSenderMock(); // mock sender to resolve promise with the given $redirectResponse in // response to the given $requestWithCustomHeaders - $redirectResponse = $messageFactory->response(1.0, 301, null, array('Location' => 'http://example.com/new')); + $redirectResponse = new Response(301, array('Location' => 'http://example.com/new')); $sender->expects($this->at(0))->method('send')->willReturn(Promise\resolve($redirectResponse)); // mock sender to resolve promise with the given $okResponse in // response to the given $requestWithCustomHeaders - $okResponse = $messageFactory->response(1.0, 200, 'OK'); + $okResponse = new Response(200); $that = $this; $sender->expects($this->at(1)) ->method('send') @@ -689,16 +653,15 @@ public function testSomeRequestHeadersShouldBeRemovedWhenRedirecting() return true; }))->willReturn(Promise\resolve($okResponse)); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $transaction->send($requestWithCustomHeaders); } public function testCancelTransactionWillCancelRequest() { - $messageFactory = new MessageFactory(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - $request = $messageFactory->request('GET', 'http://example.com'); + $request = new Request('GET', 'http://example.com'); $sender = $this->makeSenderMock(); $pending = new \React\Promise\Promise(function () { }, $this->expectCallableOnce()); @@ -706,7 +669,7 @@ public function testCancelTransactionWillCancelRequest() // mock sender to return pending promise which should be cancelled when cancelling result $sender->expects($this->once())->method('send')->willReturn($pending); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $promise = $transaction->send($request); $promise->cancel(); @@ -714,14 +677,12 @@ public function testCancelTransactionWillCancelRequest() public function testCancelTransactionWillCancelTimeoutTimer() { - $messageFactory = new MessageFactory(); - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); $loop->expects($this->once())->method('addTimer')->willReturn($timer); $loop->expects($this->once())->method('cancelTimer')->with($timer); - $request = $messageFactory->request('GET', 'http://example.com'); + $request = new Request('GET', 'http://example.com'); $sender = $this->makeSenderMock(); $pending = new \React\Promise\Promise(function () { }, function () { throw new \RuntimeException(); }); @@ -729,7 +690,7 @@ public function testCancelTransactionWillCancelTimeoutTimer() // mock sender to return pending promise which should be cancelled when cancelling result $sender->expects($this->once())->method('send')->willReturn($pending); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $transaction = $transaction->withOptions(array('timeout' => 2)); $promise = $transaction->send($request); @@ -738,14 +699,13 @@ public function testCancelTransactionWillCancelTimeoutTimer() public function testCancelTransactionWillCancelRedirectedRequest() { - $messageFactory = new MessageFactory(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - $request = $messageFactory->request('GET', 'http://example.com'); + $request = new Request('GET', 'http://example.com'); $sender = $this->makeSenderMock(); // mock sender to resolve promise with the given $redirectResponse in - $redirectResponse = $messageFactory->response(1.0, 301, null, array('Location' => 'http://example.com/new')); + $redirectResponse = new Response(301, array('Location' => 'http://example.com/new')); $sender->expects($this->at(0))->method('send')->willReturn(Promise\resolve($redirectResponse)); $pending = new \React\Promise\Promise(function () { }, $this->expectCallableOnce()); @@ -753,7 +713,7 @@ public function testCancelTransactionWillCancelRedirectedRequest() // mock sender to return pending promise which should be cancelled when cancelling result $sender->expects($this->at(1))->method('send')->willReturn($pending); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $promise = $transaction->send($request); $promise->cancel(); @@ -761,10 +721,9 @@ public function testCancelTransactionWillCancelRedirectedRequest() public function testCancelTransactionWillCancelRedirectedRequestAgain() { - $messageFactory = new MessageFactory(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - $request = $messageFactory->request('GET', 'http://example.com'); + $request = new Request('GET', 'http://example.com'); $sender = $this->makeSenderMock(); // mock sender to resolve promise with the given $redirectResponse in @@ -776,31 +735,30 @@ public function testCancelTransactionWillCancelRedirectedRequestAgain() // mock sender to return pending promise which should be cancelled when cancelling result $sender->expects($this->at(1))->method('send')->willReturn($second); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $promise = $transaction->send($request); // mock sender to resolve promise with the given $redirectResponse in - $first->resolve($messageFactory->response(1.0, 301, null, array('Location' => 'http://example.com/new'))); + $first->resolve(new Response(301, array('Location' => 'http://example.com/new'))); $promise->cancel(); } public function testCancelTransactionWillCloseBufferingStream() { - $messageFactory = new MessageFactory(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - $request = $messageFactory->request('GET', 'http://example.com'); + $request = new Request('GET', 'http://example.com'); $sender = $this->makeSenderMock(); $body = new ThroughStream(); $body->on('close', $this->expectCallableOnce()); // mock sender to resolve promise with the given $redirectResponse in - $redirectResponse = $messageFactory->response(1.0, 301, null, array('Location' => 'http://example.com/new'), $body); + $redirectResponse = new Response(301, array('Location' => 'http://example.com/new'), new ReadableBodyStream($body)); $sender->expects($this->once())->method('send')->willReturn(Promise\resolve($redirectResponse)); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $promise = $transaction->send($request); $promise->cancel(); @@ -808,36 +766,34 @@ public function testCancelTransactionWillCloseBufferingStream() public function testCancelTransactionWillCloseBufferingStreamAgain() { - $messageFactory = new MessageFactory(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - $request = $messageFactory->request('GET', 'http://example.com'); + $request = new Request('GET', 'http://example.com'); $sender = $this->makeSenderMock(); $first = new Deferred(); $sender->expects($this->once())->method('send')->willReturn($first->promise()); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $promise = $transaction->send($request); $body = new ThroughStream(); $body->on('close', $this->expectCallableOnce()); // mock sender to resolve promise with the given $redirectResponse in - $first->resolve($messageFactory->response(1.0, 301, null, array('Location' => 'http://example.com/new'), $body)); + $first->resolve(new Response(301, array('Location' => 'http://example.com/new'), new ReadableBodyStream($body))); $promise->cancel(); } public function testCancelTransactionShouldCancelSendingPromise() { - $messageFactory = new MessageFactory(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - $request = $messageFactory->request('GET', 'http://example.com'); + $request = new Request('GET', 'http://example.com'); $sender = $this->makeSenderMock(); // mock sender to resolve promise with the given $redirectResponse in - $redirectResponse = $messageFactory->response(1.0, 301, null, array('Location' => 'http://example.com/new')); + $redirectResponse = new Response(301, array('Location' => 'http://example.com/new')); $sender->expects($this->at(0))->method('send')->willReturn(Promise\resolve($redirectResponse)); $pending = new \React\Promise\Promise(function () { }, $this->expectCallableOnce()); @@ -845,7 +801,7 @@ public function testCancelTransactionShouldCancelSendingPromise() // mock sender to return pending promise which should be cancelled when cancelling result $sender->expects($this->at(1))->method('send')->willReturn($pending); - $transaction = new Transaction($sender, $messageFactory, $loop); + $transaction = new Transaction($sender, $loop); $promise = $transaction->send($request); $promise->cancel();