Skip to content
Permalink
Browse files

Start implementing request building.

* Add highlevel tests for GET.
* Add tests for url building.
  • Loading branch information...
markstory committed Dec 20, 2012
1 parent b869624 commit 55660bb34bd2e5382f40a273a79f2ff406638b43
Showing with 279 additions and 0 deletions.
  1. +155 −0 lib/Cake/Network/Http/Client.php
  2. +124 −0 lib/Cake/Test/TestCase/Network/Http/ClientTest.php
@@ -13,9 +13,164 @@
*/
namespace Cake\Network\Http;
use Cake\Network\Http\Request;
use Cake\Network\Http\Response;
use Cake\Utility\Hash;
/**
* The end user interface for doing HTTP requests.
*
* ### Scoped clients
*
* ### Doing requests
*
* ### Using authentication
*
*/
class Client {
protected $_config = [];
protected $_adapter;
/**
* Create a new HTTP Client.
*
* ### Config options
*
*
* @param array $config Config options for scoped clients.
*/
public function __construct($config = []) {
$adapter = 'Cake\Network\Http\Adapter\Stream';
if (isset($config['adapter'])) {
$adapter = $config['adapter'];
unset($config['adapter']);
}
$this->_config = $config;
if (is_string($adapter)) {
$adapter = new $adapter();
}
$this->_adapter = $adapter;
}
/**
* Get or set additional config options.
*
* Setting config will use Hash::merge() for appending into
* the existing configuration.
*
* @param array|null $config Configuration options. null to get.
* @return this|array
*/
public function config($config = null) {
if ($config === null) {
return $this->_config;
}
$this->_config = Hash::merge($this->_config, $config);
return $this;
}
/**
* Do a GET request.
*
* @param string $url The url or path you want to request.
* @param array $data The query data you want to send.
* @param array $options Additional options for the request.
* @return Cake\Network\Http\Response
*/
public function get($url, $data = [], $options = []) {
$options = $this->_mergeOptions($options);
$request = $this->_createRequest(Request::METHOD_GET, $url, $data, $options);
return $this->_adapter->send($request, $options);
}
/**
* Do a POST request.
*
* @param string $url The url or path you want to request.
* @param array $data The post data you want to send.
* @param array $options Additional options for the request.
* @return Cake\Network\Http\Response
*/
public function post($url, $data = [], $options = []) {
}
/**
* Do a PUT request.
*
* @param string $url The url or path you want to request.
* @param array $data The request data you want to send.
* @param array $options Additional options for the request.
* @return Cake\Network\Http\Response
*/
public function put($url, $data = [], $options = []) {
}
/**
* Do a PATCH request.
*
* @param string $url The url or path you want to request.
* @param array $data The request data you want to send.
* @param array $options Additional options for the request.
* @return Cake\Network\Http\Response
*/
public function patch($url, $data = [], $options = []) {
}
/**
* Do a DELETE request.
*
* @param string $url The url or path you want to request.
* @param array $data The request data you want to send.
* @param array $options Additional options for the request.
* @return Cake\Network\Http\Response
*/
public function delete($url, $data = [], $options = []) {
}
protected function _mergeOptions($options)
{
return Hash::merge($this->_config, $options);
}
/**
* Generate a URL based on the scoped client options.
*
* @param string $url Either a full URL or just the path.
* @param array $options The config options stored with Client::config()
* @return string A complete url with scheme, port, host, path.
*/
public function buildUrl($url, $options = []) {
if (empty($options)) {
return $url;
}
$defaults = [
'host' => null,
'port' => null,
'scheme' => 'http',
];
$options = array_merge($defaults, (array)$options);
$defaultPorts = [
'http' => 80,
'https' => 443
];
$out = $options['scheme'] . '://' . $options['host'];
if ($options['port'] && $options['port'] != $defaultPorts[$options['scheme']]) {
$out .= ':' . $options['port'];
}
$out .= '/' . ltrim($url, '/');
return $out;
}
protected function _createRequest($method, $url, $data, $options) {
$url = $this->buildUrl($url, $options);
$request = new Request();
$request->method($method)
->url($url)
->content($data);
return $request;
}
}
@@ -0,0 +1,124 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since CakePHP(tm) v 3.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
namespace Cake\Test\TestCase\Network\Http;
use Cake\Network\Http\Client;
use Cake\Network\Http\Request;
use Cake\Network\Http\Response;
use Cake\TestSuite\TestCase;
/**
* HTTP client test.
*/
class ClientTest extends TestCase {
/**
* Test storing config options and modifying them.
*
* @return void
*/
public function testConstructConfig() {
$config = [
'scheme' => 'http',
'host' => 'example.org',
];
$http = new Client($config);
$this->assertEquals($config, $http->config());
$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']
];
$this->assertEquals($expected, $result);
}
public static function urlProvider() {
return [
[
// simple
'http://example.com/test.html',
'http://example.com/test.html',
null
],
[
// simple array opts
'http://example.com/test.html',
'http://example.com/test.html',
[]
],
[
'http://example.com/test.html',
'/test.html',
['host' => 'example.com']
],
[
'https://example.com/test.html',
'/test.html',
['host' => 'example.com', 'scheme' => 'https']
],
[
'http://example.com:8080/test.html',
'/test.html',
['host' => 'example.com', 'port' => '8080']
],
[
'http://example.com/test.html',
'/test.html',
['host' => 'example.com', 'port' => '80']
],
[
'https://example.com/test.html',
'/test.html',
['host' => 'example.com', 'scheme' => 'https', 'port' => '443']
],
];
}
/**
* @dataProvider urlProvider
*/
public function testBuildUrl($expected, $url, $opts) {
$http = new Client();
$result = $http->buildUrl($url, $opts);
$this->assertEquals($expected, $result);
}
public function testGet() {
$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')
))
->will($this->returnValue($response));
$http = new Client([
'host' => 'cakephp.org',
'adapter' => $mock
]);
$result = $http->get('/test.html');
$this->assertSame($result, $response);
}
}

0 comments on commit 55660bb

Please sign in to comment.
You can’t perform that action at this time.