'http', 'host' => 'example.org', ]; $http = new Client($config); $result = $http->config(); foreach ($config as $key => $val) { $this->assertEquals($val, $result[$key]); } $result = $http->config([ 'auth' => ['username' => 'mark', 'password' => 'secret'] ]); $this->assertSame($result, $http); $result = $http->config(); $expected = [ 'scheme' => 'http', 'host' => 'example.org', 'auth' => ['username' => 'mark', 'password' => 'secret'] ]; foreach ($config as $key => $val) { $this->assertEquals($val, $result[$key]); } } /** * Data provider for buildUrl() tests * * @return array */ public static function urlProvider() { return [ [ 'http://example.com/test.html', 'http://example.com/test.html', [], null, 'Null options' ], [ 'http://example.com/test.html', 'http://example.com/test.html', [], [], 'Simple string' ], [ 'http://example.com/test.html', '/test.html', [], ['host' => 'example.com'], 'host name option', ], [ 'https://example.com/test.html', '/test.html', [], ['host' => 'example.com', 'scheme' => 'https'], 'HTTPS', ], [ 'http://example.com:8080/test.html', '/test.html', [], ['host' => 'example.com', 'port' => '8080'], 'Non standard port', ], [ 'http://example.com/test.html', '/test.html', [], ['host' => 'example.com', 'port' => '80'], 'standard port, does not display' ], [ 'https://example.com/test.html', '/test.html', [], ['host' => 'example.com', 'scheme' => 'https', 'port' => '443'], 'standard port, does not display' ], [ 'http://example.com/test.html', 'http://example.com/test.html', [], ['host' => 'example.com', 'scheme' => 'https'], 'options do not duplicate' ], [ 'http://example.com/search?q=hi+there&cat%5Bid%5D%5B0%5D=2&cat%5Bid%5D%5B1%5D=3', 'http://example.com/search', ['q' => 'hi there', 'cat' => ['id' => [2, 3]]], [], 'query string data.' ], [ 'http://example.com/search?q=hi+there&id=12', 'http://example.com/search?q=hi+there', ['id' => '12'], [], 'query string data with some already on the url.' ], ]; } /** * @dataProvider urlProvider */ public function testBuildUrl($expected, $url, $query, $opts) { $http = new Client(); $result = $http->buildUrl($url, $query, $opts); $this->assertEquals($expected, $result); } /** * test simple get request with headers & cookies. * * @return void */ public function testGetSimpleWithHeadersAndCookies() { $response = new Response(); $headers = [ 'User-Agent' => 'Cake', 'Connection' => 'close', 'Content-Type' => 'application/json', ]; $cookies = [ 'split' => 'value' ]; $mock = $this->getMock('Cake\Network\Http\Adapter\Stream', ['send']); $mock->expects($this->once()) ->method('send') ->with($this->logicalAnd( $this->isInstanceOf('Cake\Network\Http\Request'), $this->attributeEqualTo('_method', Request::METHOD_GET), $this->attributeEqualTo('_url', 'http://cakephp.org/test.html'), $this->attributeEqualTo('_headers', $headers), $this->attributeEqualTo('_cookies', $cookies) )) ->will($this->returnValue([$response])); $http = new Client(['adapter' => $mock]); $result = $http->get('http://cakephp.org/test.html', [], [ 'headers' => $headers, 'cookies' => $cookies, ]); $this->assertSame($result, $response); } /** * test get request with querystring data * * @return void */ public function testGetQuerystring() { $response = new Response(); $mock = $this->getMock('Cake\Network\Http\Adapter\Stream', ['send']); $mock->expects($this->once()) ->method('send') ->with($this->logicalAnd( $this->isInstanceOf('Cake\Network\Http\Request'), $this->attributeEqualTo('_method', Request::METHOD_GET), $this->attributeEqualTo('_url', 'http://cakephp.org/search?q=hi+there&Category%5Bid%5D%5B0%5D=2&Category%5Bid%5D%5B1%5D=3') )) ->will($this->returnValue([$response])); $http = new Client([ 'host' => 'cakephp.org', 'adapter' => $mock ]); $result = $http->get('/search', [ 'q' => 'hi there', 'Category' => ['id' => [2, 3]] ]); $this->assertSame($result, $response); } /** * test get request with string of query data. * * @return void */ public function testGetQuerystringString() { $response = new Response(); $mock = $this->getMock('Cake\Network\Http\Adapter\Stream', ['send']); $mock->expects($this->once()) ->method('send') ->with($this->logicalAnd( $this->isInstanceOf('Cake\Network\Http\Request'), $this->attributeEqualTo('_url', 'http://cakephp.org/search?q=hi+there&Category%5Bid%5D%5B0%5D=2&Category%5Bid%5D%5B1%5D=3') )) ->will($this->returnValue([$response])); $http = new Client([ 'host' => 'cakephp.org', 'adapter' => $mock ]); $data = [ 'q' => 'hi there', 'Category' => ['id' => [2, 3]] ]; $result = $http->get('/search', http_build_query($data)); $this->assertSame($response, $result); } /** * Test a GET with a request body. Services like * elasticsearch use this feature. * * @return void */ public function testGetWithContent() { $response = new Response(); $mock = $this->getMock('Cake\Network\Http\Adapter\Stream', ['send']); $mock->expects($this->once()) ->method('send') ->with($this->logicalAnd( $this->isInstanceOf('Cake\Network\Http\Request'), $this->attributeEqualTo('_method', Request::METHOD_GET), $this->attributeEqualTo('_url', 'http://cakephp.org/search'), $this->attributeEqualTo('_body', 'some data') )) ->will($this->returnValue([$response])); $http = new Client([ 'host' => 'cakephp.org', 'adapter' => $mock ]); $result = $http->get('/search', [ '_content' => 'some data' ]); $this->assertSame($result, $response); } /** * Test invalid authentication types throw exceptions. * * @expectedException \Cake\Core\Exception\Exception * @return void */ public function testInvalidAuthenticationType() { $mock = $this->getMock('Cake\Network\Http\Adapter\Stream', ['send']); $mock->expects($this->never()) ->method('send'); $http = new Client([ 'host' => 'cakephp.org', 'adapter' => $mock ]); $result = $http->get('/', [], [ 'auth' => ['type' => 'horribly broken'] ]); } /** * Test setting basic authentication with get * * @return void */ public function testGetWithAuthenticationAndProxy() { $response = new Response(); $mock = $this->getMock('Cake\Network\Http\Adapter\Stream', ['send']); $headers = [ 'Connection' => 'close', 'User-Agent' => 'CakePHP', 'Authorization' => 'Basic ' . base64_encode('mark:secret'), 'Proxy-Authorization' => 'Basic ' . base64_encode('mark:pass'), ]; $mock->expects($this->once()) ->method('send') ->with($this->logicalAnd( $this->isInstanceOf('Cake\Network\Http\Request'), $this->attributeEqualTo('_method', Request::METHOD_GET), $this->attributeEqualTo('_url', 'http://cakephp.org/'), $this->attributeEqualTo('_headers', $headers) )) ->will($this->returnValue([$response])); $http = new Client([ 'host' => 'cakephp.org', 'adapter' => $mock ]); $result = $http->get('/', [], [ 'auth' => ['username' => 'mark', 'password' => 'secret'], 'proxy' => ['username' => 'mark', 'password' => 'pass'], ]); $this->assertSame($result, $response); } /** * Return a list of HTTP methods. * * @return array */ public static function methodProvider() { return [ [Request::METHOD_GET], [Request::METHOD_POST], [Request::METHOD_PUT], [Request::METHOD_DELETE], [Request::METHOD_PATCH], [Request::METHOD_OPTIONS], [Request::METHOD_TRACE], ]; } /** * test simple POST request. * * @dataProvider methodProvider * @return void */ public function testMethodsSimple($method) { $response = new Response(); $mock = $this->getMock('Cake\Network\Http\Adapter\Stream', ['send']); $mock->expects($this->once()) ->method('send') ->with($this->logicalAnd( $this->isInstanceOf('Cake\Network\Http\Request'), $this->attributeEqualTo('_method', $method), $this->attributeEqualTo('_url', 'http://cakephp.org/projects/add') )) ->will($this->returnValue([$response])); $http = new Client([ 'host' => 'cakephp.org', 'adapter' => $mock ]); $result = $http->{$method}('/projects/add'); $this->assertSame($result, $response); } /** * Provider for testing the type option. * * @return array */ public static function typeProvider() { return [ ['application/json', 'application/json'], ['json', 'application/json'], ['xml', 'application/xml'], ['application/xml', 'application/xml'], ]; } /** * Test that using the 'type' option sets the correct headers * * @dataProvider typeProvider * @return void */ public function testPostWithTypeKey($type, $mime) { $response = new Response(); $data = 'some data'; $headers = [ 'Connection' => 'close', 'User-Agent' => 'CakePHP', 'Content-Type' => $mime, 'Accept' => $mime, ]; $mock = $this->getMock('Cake\Network\Http\Adapter\Stream', ['send']); $mock->expects($this->once()) ->method('send') ->with($this->logicalAnd( $this->attributeEqualTo('_method', Request::METHOD_POST), $this->attributeEqualTo('_body', $data), $this->attributeEqualTo('_headers', $headers) )) ->will($this->returnValue([$response])); $http = new Client([ 'host' => 'cakephp.org', 'adapter' => $mock ]); $http->post('/projects/add', $data, ['type' => $type]); } /** * Test that string payloads with no content type have a default content-type set. * * @return void */ public function testPostWithStringDataDefaultsToFormEncoding() { $response = new Response(); $data = 'some=value&more=data'; $headers = [ 'Connection' => 'close', 'User-Agent' => 'CakePHP', 'Content-Type' => 'application/x-www-form-urlencoded', ]; $mock = $this->getMock('Cake\Network\Http\Adapter\Stream', ['send']); $mock->expects($this->any()) ->method('send') ->with($this->logicalAnd( $this->attributeEqualTo('_body', $data), $this->attributeEqualTo('_headers', $headers) )) ->will($this->returnValue([$response])); $http = new Client([ 'host' => 'cakephp.org', 'adapter' => $mock ]); $http->post('/projects/add', $data); $http->put('/projects/add', $data); $http->delete('/projects/add', $data); } /** * Test that exceptions are raised on invalid types. * * @expectedException \Cake\Core\Exception\Exception * @return void */ public function testExceptionOnUnknownType() { $mock = $this->getMock('Cake\Network\Http\Adapter\Stream', ['send']); $mock->expects($this->never()) ->method('send'); $http = new Client([ 'host' => 'cakephp.org', 'adapter' => $mock ]); $http->post('/projects/add', 'it works', ['type' => 'invalid']); } /** * Test that Client stores cookies * * @return void */ public function testCookieStorage() { $adapter = $this->getMock( 'Cake\Network\Http\Adapter\Stream', ['send'] ); $cookieJar = $this->getMock('Cake\Network\Http\CookieCollection'); $headers = [ 'HTTP/1.0 200 Ok', 'Set-Cookie: first=1', 'Set-Cookie: expiring=now; Expires=Wed, 09-Jun-1999 10:18:14 GMT' ]; $response = new Response($headers, ''); $cookieJar->expects($this->at(0)) ->method('get') ->with('http://cakephp.org/projects') ->will($this->returnValue([])); $cookieJar->expects($this->at(1)) ->method('store') ->with($response); $adapter->expects($this->at(0)) ->method('send') ->will($this->returnValue([$response])); $http = new Client([ 'host' => 'cakephp.org', 'adapter' => $adapter, 'cookieJar' => $cookieJar ]); $http->get('/projects'); } /** * test head request with querystring data * * @return void */ public function testHeadQuerystring() { $response = new Response(); $mock = $this->getMock('Cake\Network\Http\Adapter\Stream', ['send']); $mock->expects($this->once()) ->method('send') ->with($this->logicalAnd( $this->isInstanceOf('Cake\Network\Http\Request'), $this->attributeEqualTo('_method', Request::METHOD_HEAD), $this->attributeEqualTo('_url', 'http://cakephp.org/search?q=hi+there') )) ->will($this->returnValue([$response])); $http = new Client([ 'host' => 'cakephp.org', 'adapter' => $mock ]); $result = $http->head('/search', [ 'q' => 'hi there', ]); $this->assertSame($result, $response); } }