Repository: pusher/pusher-http-php (php)

Issue:
Provide more feedback when cURL execution returns 0
See: http://php.net/manual/en/function.curl-error.php

Right now the status code is set to 0 and the body blank. More information should be supplied to make it easier to debug what's going on with the library.



Discussion:

Patch:
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,19 @@
+# see http://about.travis-ci.org/docs/user/languages/php/ for more hints
+language: php
+
+# list any PHP version you want to test against
+php:
+  # using major version aliases
+
+  # aliased to 5.3.29
+  - 5.3
+  # aliased to a recent 5.4.x version
+  - 5.4
+  # aliased to a recent 5.5.x version
+  - 5.5
+  # aliased to a recent 5.6.x version
+  - 5.6
+  
+before_script: composer install  
+  
+script: phpunit --testsuite unit
diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
 # Changelog
 
+## 2.2.0 (2015-01-20)
+
+[CHANGED] `new Pusher($app_key, $app_secret, $app_id, $options)` - The `$options` parameter
+has been added as the forth parameter to the constructor and other additional 
+parameters are now deprecated.
+
 ## 2.1.3 (2012-12-22)
 
 [NEW] `$pusher->trigger` can now take an `array` of channel names as a first parameter to allow the same event to be published on multiple channels.
@@ -32,4 +38,4 @@
 
 [CHANGED] `get_channels()` now returns an object which has a `channels` property. This must be accessed to get the Array of channels in an application.
 
-[CHANGED] `get_presence_channels()` now returns an object which has a `channels` property. This must be accessed to get the Array of channels in an application.
\ No newline at end of file
+[CHANGED] `get_presence_channels()` now returns an object which has a `channels` property. This must be accessed to get the Array of channels in an application.
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,8 +1,10 @@
 # Pusher PHP Library
 
-This is a PHP library for interacting with the Pusher REST API.
+[![Build Status](https://travis-ci.org/pusher/pusher-php-server.svg)](https://travis-ci.org/pusher/pusher-php-server)
 
-Register at <http://pusher.com> and use the application credentials within your app as shown below.
+PHP library for interacting with the Pusher HTTP API.
+
+Register at <https://pusher.com> and use the application credentials within your app as shown below.
 
 ## Installation
 
@@ -17,174 +19,209 @@ Or you can clone or download the library files.
 
 Use the credentials from your Pusher application to create a new `Pusher` instance.
 
-    $app_id = 'YOUR_APP_ID';
-    $app_key = 'YOUR_APP_KEY';
-    $app_secret = 'YOUR_APP_SECRET';
+```php
+$app_id = 'YOUR_APP_ID';
+$app_key = 'YOUR_APP_KEY';
+$app_secret = 'YOUR_APP_SECRET';
 
-    $pusher = new Pusher( $app_key, $app_secret, $app_id );
+$pusher = new Pusher( $app_key, $app_secret, $app_id );
+```
+    
+A forth parameter `$options` parameter can also be passed. The available options are:
 
-By default calls will be made over a non-encrypted connection. To change this to make calls over HTTPS:
+* `scheme` - e.g. http or https
+* `host` - the host e.g. api.pusherapp.com. No trailing forward slash.
+* `port` - the http port
+* `timeout` - the HTTP timeout
+* `encrypted` - quick option to use scheme of https and port 443.
 
-    $pusher = new Pusher( $app_key, $app_secret, $app_id, false, 'https://api.pusherapp.com', 443 );
+For example, by default calls will be made over a non-encrypted connection. To change this to make calls over HTTPS use:
+
+```php
+$pusher = new Pusher( $app_key, $app_secret, $app_id, array( 'encrypted' => true ) );
+```
+
+*Note: The `$options` parameter was introduced in version 2.2.0 of the library.
+Previously additional parameters could be passed for each option, but this was
+becoming unwieldy. However, backwards compatibility has been maintained.*
 
 ## Publishing/Triggering events
 
 To trigger an event on one or more channels use the `trigger` function.
 
 ### A single channel
-    
-    $pusher->trigger( 'my-channel', 'my_event', 'hello world' );
+
+```php    
+$pusher->trigger( 'my-channel', 'my_event', 'hello world' );
+```
 
 ### Multiple channels
 
-    $pusher->trigger( [ 'channel-1', 'channel-2' ], 'my_event', 'hello world' );
+```php
+$pusher->trigger( [ 'channel-1', 'channel-2' ], 'my_event', 'hello world' );
+```
 
 ### Arrays
 
 Objects are automatically converted to JSON format:
 
-    $array['name'] = 'joe';
-    $array['message_count'] = 23;
+```php
+$array['name'] = 'joe';
+$array['message_count'] = 23;
 
-    $pusher->trigger('my_channel', 'my_event', $array);
+$pusher->trigger('my_channel', 'my_event', $array);
+```
 
 The output of this will be:
 
-    "{'name': 'joe', 'message_count': 23}"
+```json
+"{'name': 'joe', 'message_count': 23}"
+```
 
 ### Socket id
 
 In order to avoid duplicates you can optionally specify the sender's socket id while triggering an event ([http://pusherapp.com/docs/duplicates](http://pusherapp.com/docs/duplicates)):
 
-    $pusher->trigger('my-channel','event','data','socket_id');
-
-### Debugging
-
-You can either turn on debugging by setting the fifth argument to true, like so:
-
-    $pusher->trigger('my-channel', 'event', 'data', null, true)
-
-or with all requests:
-
-    $pusher = new Pusher($key, $secret, $app_id, true);
-
-On failed requests, this will return the server's response, instead of false.
-
-### Logging
-
-You can pass an object with a `log` function to the `pusher->set_logger` function so that you can log information from the library.
-
-    class MyLogger {
-        public function log( $msg ) {
-            print_r( $msg . "\n" );
-        }
-    }
+```php
+$pusher->trigger('my-channel','event','data','socket_id');
+```
     
-    $pusher->set_logger( new MyLogger() );
-
 ### JSON format
-
+    
 If your data is already encoded in JSON format, you can avoid a second encoding step by setting the sixth argument true, like so:
 
-	$pusher->trigger('my-channel', 'event', 'data', null, false, true)
+```php    
+$pusher->trigger('my-channel', 'event', 'data', null, false, true)
+```
 
 ## Authenticating Private channels
 
 To authorise your users to access private channels on Pusher, you can use the socket_auth function:
 
-    $pusher->socket_auth('my-channel','socket_id');
+```php
+$pusher->socket_auth('my-channel','socket_id');
+```
 
 ## Authenticating Presence channels
 
 Using presence channels is similar to private channels, but you can specify extra data to identify that particular user:
 
-    $pusher->presence_auth('my-channel','socket_id', 'user_id', 'user_info');
+```php
+$pusher->presence_auth('my-channel','socket_id', 'user_id', 'user_info');
+```
 
 ### Presence example
 
 First set this variable in your JS app:
 
-    Pusher.channel_auth_endpoint = '/presence_auth.php';
+```php
+Pusher.channel_auth_endpoint = '/presence_auth.php';
+```
 
 Next, create the following in presence_auth.php:
 
-    <?php
-    header('Content-Type: application/json');
-    if ($_SESSION['user_id']){
-      $sql = "SELECT * FROM `users` WHERE id='$_SESSION[user_id]'";
-      $result = mysql_query($sql,$mysql);
-      $user = mysql_fetch_assoc($result);
-    } else {
-      die('aaargh, no-one is logged in')
-    }
-    
-    $pusher = new Pusher($key, $secret, $app_id);
-    $presence_data = array('name' => $user['name']);
-    echo $pusher->presence_auth($_POST['channel_name'], $_POST['socket_id'], $user['id'], $presence_data);
-    ?>
+```php
+<?php
+header('Content-Type: application/json');
+if ($_SESSION['user_id']){
+  $sql = "SELECT * FROM `users` WHERE id='$_SESSION[user_id]'";
+  $result = mysql_query($sql,$mysql);
+  $user = mysql_fetch_assoc($result);
+} else {
+  die('aaargh, no-one is logged in')
+}
+
+$pusher = new Pusher($key, $secret, $app_id);
+$presence_data = array('name' => $user['name']);
+echo $pusher->presence_auth($_POST['channel_name'], $_POST['socket_id'], $user['id'], $presence_data);
+```
 
 Note: this assumes that you store your users in a table called `users` and that those users have a `name` column. It also assumes that you have a login mechanism that stores the `user_id` of the logged in user in the session.
 
 ## Application State Queries
 
-## Generic get function
+### Generic get function
 
-    pusher->get( $path, $params ) 
+```php
+$pusher->get( $path, $params );
+```
 
 Used to make `GET` queries against the Pusher REST API. Handles authentication.
 
 Response is an associative array with a `result` index. The contents of this index is dependent on the REST method that was called. However, a `status` property to allow the HTTP status code is always present and a `result` property will be set if the status code indicates a successful call to the API.
 
-    $response = $pusher->get( '/channels' );
-    $http_status_code = $response[ 'status' ];
-    $result = $response[ 'result' ];
+```php
+$response = $pusher->get( '/channels' );
+$http_status_code = $response[ 'status' ];
+$result = $response[ 'result' ];
+```
 
 ### Get information about a channel
 
-    get_channel_info( $name )
+```php
+$pusher->get_channel_info( $name );
+```
 
 It's also possible to get information about a channel from the Pusher REST API.
 
-    $info = $pusher->get_channel_info('channel-name');
-    $channel_occupied = $info->occupied;
+```php
+$info = $pusher->get_channel_info('channel-name');
+$channel_occupied = $info->occupied;
+```
 
 This can also be achieved using the generic `pusher->get` function:
 
-    pusher->get( '/channels/channel-name' );    
+```php
+$pusher->get( '/channels/channel-name' );
+```
     
 ### Get a list of application channels
 
-    get_channels()
+```php
+$pusher->get_channels()
+```
 
 It's also possible to get a list of channels for an application from the Pusher REST API.
 
-    $result = $pusher->get_channels();
-    $channel_count = count($result->channels); // $channels is an Array
+```php
+$result = $pusher->get_channels();
+$channel_count = count($result->channels); // $channels is an Array
+```
 
 This can also be achieved using the generic `pusher->get` function:
 
-    pusher->get( '/channels' );
+```php
+$pusher->get( '/channels' );
+```
   
 ### Get a filtered list of application channels
 
-    get_channels( array( 'filter_by_prefix' => 'some_filter' ) )
+```php
+$pusher->get_channels( array( 'filter_by_prefix' => 'some_filter' ) )
+```
 
 It's also possible to get a list of channels based on their name prefix. To do this you need to supply an $options parameter to the call. In the following example the call will return a list of all channels with a 'presence-' prefix. This is idea for fetching a list of all presence channels.
 
-    $results = $pusher->get_channels( array( 'filter_by_prefix' => 'presence-') );
-    $channel_count = count($result->channels); // $channels is an Array
+```php
+$results = $pusher->get_channels( array( 'filter_by_prefix' => 'presence-') );
+$channel_count = count($result->channels); // $channels is an Array
+```
 
 This can also be achieved using the generic `pusher->get` function:
 
-    $pusher->get( '/channels', array( 'filter_by_prefix' => 'presence-' ) );
+```php
+$pusher->get( '/channels', array( 'filter_by_prefix' => 'presence-' ) );
+```
 
 ### Get user information from a presence channel
 
-    $response = $pusher->get( '/channels/presence-channel-name/users' )
+```php
+$response = $pusher->get( '/channels/presence-channel-name/users' )
+```
 
 The `$response` is in the format:
 
-```
+```php
 Array
 (
     [body] => {"users":[{"id":"a_user_id"}]}
@@ -202,6 +239,29 @@ Array
         )
 )
 ```
+
+## Debugging & Logging
+
+The best way to debug your applications interaction with server is to set a logger
+for the library so you can see the internal workings within the library and interactions
+with the Pusher service.
+
+You set up logging by passing an object with a `log` function to the `pusher->set_logger`
+function:
+
+```php
+class MyLogger {
+  public function log( $msg ) {
+    print_r( $msg . "\n" );
+  }
+}
+
+$pusher->set_logger( new MyLogger() );
+```
+
+If you use the above example in code executed from the console/terminal the debug
+information will be output there. If you use this within a web app then the output
+will appear within the generated app output e.g. HTML.
     
 ## Running the tests
 
@@ -213,5 +273,8 @@ Requires [phpunit](https://github.com/sebastianbergmann/phpunit/).
     
 ## License
 
-Copyright 2010, Squeeks. Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php 
+Copyright 2014, Pusher. Licensed under the MIT license:
+http://www.opensource.org/licenses/mit-license.php 
 
+Copyright 2010, Squeeks. Licensed under the MIT license:
+http://www.opensource.org/licenses/mit-license.php 
diff --git a/lib/Pusher.php b/lib/Pusher.php
--- a/lib/Pusher.php
+++ b/lib/Pusher.php
@@ -50,44 +50,110 @@ public static function get_pusher()
 
 class Pusher
 {
-	public static $VERSION = '2.0.0';
-
-	private $settings = array ();
+	public static $VERSION = '2.2.0';
+
+	private $settings = array(
+		'scheme' => 'http',
+		'host' => 'api.pusherapp.com',
+		'port' => 80,
+		'timeout' => 30,
+		'debug' => false
+	);
 	private $logger = null;
 
 	/**
-	* PHP5 Constructor. 
-	* 
-	* Initializes a new Pusher instance with key, secret , app ID and channel. 
-	* You can optionally turn on debugging for all requests by setting debug to true.
-	* 
-	* @param string $auth_key
-	* @param string $secret
-	* @param int $app_id
-	* @param bool $debug [optional]
-	* @param string $host [optional]
-	* @param int $port [optional]
-	* @param int $timeout [optional]
-	*/
-	public function __construct( $auth_key, $secret, $app_id, $debug = false, $host = 'http://api.pusherapp.com', $port = '80', $timeout = 30 )
+	 * PHP5 Constructor. 
+	 * 
+	 * Initializes a new Pusher instance with key, secret , app ID and channel. 
+	 * You can optionally turn on debugging for all requests by setting debug to true.
+	 * 
+	 * @param string $auth_key
+	 * @param string $secret
+	 * @param int $app_id
+	 * @param bool $options [optional]
+	 *		Options to configure the Pusher instance.
+	 * 	Was previously a debug flag. Legacy support for this exists if a boolean is passed.
+	 * 	scheme - e.g. http or https
+	 * 	host - the host e.g. api.pusherapp.com. No trailing forward slash.
+	 * 	port - the http port
+	 * 	timeout - the http timeout
+	 * 	encrypted - quick option to use scheme of https and port 443.
+	 * @param string $host [optional] - deprecated
+	 * @param int $port [optional] - deprecated
+	 * @param int $timeout [optional] - deprecated
+	 */
+	public function __construct( $auth_key, $secret, $app_id, $options = array(), $host = null, $port = null, $timeout = null )
 	{
-		// Check compatibility, disable for speed improvement
 		$this->check_compatibility();
 
-		// Setup defaults
-		$this->settings['server'] = $host;
-		$this->settings['port']		= $port;
-		$this->settings['auth_key'] = $auth_key;
-		$this->settings['secret'] = $secret;
-		$this->settings['app_id'] = $app_id;
-		$this->settings['url']		= '/apps/' . $this->settings['app_id'];
-		$this->settings['debug']	= $debug;
-		$this->settings['timeout']	= $timeout;
+		/** Start backward compatibility with old constructor **/
+		if( is_bool( $options ) === true ) {
+			$options = array(
+				'debug' => $options
+			);
+		}
+
+		if( !is_null( $host ) ) {
+			$match = null;
+			preg_match("/(http[s]?)\:\/\/(.*)/", $host, $match);
+			
+			if( count( $match ) === 3 ) {
+				$this->settings[ 'scheme' ] = $match[ 1 ];
+				$host = $match[ 2 ];
+			}
+			
+			$this->settings[ 'host' ] = $host;
+			
+			$this->log( 'Legacy $host parameter provided: ' . 
+									$this->settings[ 'scheme' ] + ' host: ' + $this->settings[ 'host' ] );
+		}
+
+		if( !is_null( $port ) ) {
+			$options[ 'port' ] = $port;
+		}
+
+		if( !is_null( $timeout ) ) {
+			$options[ 'timeout' ] = $timeout;
+		}
+		
+		/** End backward compatibility with old constructor **/
+		
+		if( isset( $options[ 'encrypted' ] ) &&
+				$options[ 'encrypted' ] === true &&
+				!isset( $options[ 'scheme' ] ) &&
+				!isset( $options[ 'port' ] ) ) {
+						
+			$options[ 'scheme' ] = 'https';
+			$options[ 'port' ] = 443;
+		}
+
+		$this->settings['auth_key'] 	= $auth_key;
+		$this->settings['secret'] 		= $secret;
+		$this->settings['app_id'] 		= $app_id;
+		$this->settings['base_path']	= '/apps/' . $this->settings['app_id'];
+
+		foreach( $options as $key => $value ) {
+			// only set if valid setting/option
+			if( isset( $this->settings[ $key ] ) ) {
+				$this->settings[ $key ] = $value;
+			}
+		}
+		
+		// ensure host doesn't have a scheme prefix
+		$this->settings[ 'host' ] = 
+			preg_replace( '/http[s]?\:\/\//', '', $this->settings[ 'host' ], 1 );
+	}
 
+	/**
+	 * Fetch the settings.
+	 * @return array
+	 */
+	public function getSettings() {
+		return $this->settings;
 	}
 
 	/**
-	 * Set a logger to be informed of interal log messages.
+	 * Set a logger to be informed of internal log messages.
 	 */
 	public function set_logger( $logger ) {
 		$this->logger = $logger;
@@ -132,7 +198,9 @@ private function create_curl($s_url, $request_method = 'GET', $query_params = ar
 			$s_url,
 			$query_params);
 
-		$full_url = $this->settings['server'] . ':' . $this->settings['port'] . $s_url . '?' . $signed_query;
+		$full_url = $this->settings['scheme'] . '://' .
+								$this->settings['host'] . ':' . 
+								$this->settings['port'] . $s_url . '?' . $signed_query;
 
 		$this->log( 'curl_init( ' . $full_url . ' )' );
 		
@@ -161,6 +229,10 @@ private function exec_curl( $ch ) {
 		$response[ 'status' ] = curl_getinfo($ch, CURLINFO_HTTP_CODE);
 
 		$this->log( 'exec_curl response: ' . print_r( $response, true ) );
+		
+		if( $response[ 'body' ] === false ) {
+			$this->log( 'exec_curl error: ' . curl_error( $ch ) );
+		}
 
 		curl_close( $ch );
 
@@ -168,15 +240,16 @@ private function exec_curl( $ch ) {
 	}
 	
 	/**
-	 *	Build the required HMAC'd auth string
+	 * Build the required HMAC'd auth string
 	 *
-	 *	@param string $auth_key
-	 *	@param string $auth_secret
-	 *	@param string $request_path
-	 *	@param array $query_params
-	 *	@param string $auth_version [optional]
-	 *	@param string $auth_timestamp [optional]
-	 *	@return string
+	 * @param string $auth_key
+	 * @param string $auth_secret
+	 * @param string $request_method
+	 * @param string $request_path
+	 * @param array $query_params
+	 * @param string $auth_version [optional]
+	 * @param string $auth_timestamp [optional]
+	 * @return string
 	 */
 	public static function build_auth_query_string($auth_key, $auth_secret, $request_method, $request_path,
 		$query_params = array(), $auth_version = '1.0', $auth_timestamp = null)
@@ -223,16 +296,16 @@ public static function array_implode( $glue, $separator, $array ) {
 	}
 
 	/**
-	* Trigger an event by providing event name and payload. 
-	* Optionally provide a socket ID to exclude a client (most likely the sender).
-	*
-	* @param array $channel An array of channel names to publish the event on.
-	* @param string $event
-	* @param mixed $data Event data
-	* @param int $socket_id [optional]
-	* @param bool $debug [optional]
-	* @return bool|string
-	*/
+	 * Trigger an event by providing event name and payload. 
+	 * Optionally provide a socket ID to exclude a client (most likely the sender).
+	 *
+	 * @param array $channels An array of channel names to publish the event on.
+	 * @param string $event
+	 * @param mixed $data Event data
+	 * @param int $socket_id [optional]
+	 * @param bool $debug [optional]
+	 * @return bool|string
+	 */
 	public function trigger( $channels, $event, $data, $socket_id = null, $debug = false, $already_encoded = false )
 	{
 		if( is_string( $channels ) === true ) {
@@ -246,7 +319,7 @@ public function trigger( $channels, $event, $data, $socket_id = null, $debug = f
 
 		$query_params = array();
 		
-		$s_url = $this->settings['url'] . '/events';		
+		$s_url = $this->settings['base_path'] . '/events';		
 		
 		$data_encoded = $already_encoded ? $data : json_encode( $data );
 
@@ -289,12 +362,12 @@ public function trigger( $channels, $event, $data, $socket_id = null, $debug = f
 	}
 	
 	/**
-	  *	Fetch channel information for a specific channel.
-	  *
-	  * @param string $channel The name of the channel
-	  * @param array $params Additional parameters for the query e.g. $params = array( 'info' => 'connection_count' )
-	  *	@return object
-	  */
+	 *	Fetch channel information for a specific channel.
+	 *
+	 * @param string $channel The name of the channel
+	 * @param array $params Additional parameters for the query e.g. $params = array( 'info' => 'connection_count' )
+	 *	@return object
+	 */
 	public function get_channel_info($channel, $params = array() )
 	{
 		$response = $this->get( '/channels/' . $channel, $params );
@@ -337,15 +410,15 @@ public function get_channels($params = array())
 
 	/**
 	 * GET arbitrary REST API resource using a synchronous http client.
-   * All request signing is handled automatically.
-   *  
-   * @param string path Path excluding /apps/APP_ID
-   * @param params array API params (see http://pusher.com/docs/rest_api)
-   *
-   * @return See Pusher API docs
+	 * All request signing is handled automatically.
+	 *	
+	 * @param string path Path excluding /apps/APP_ID
+	 * @param params array API params (see http://pusher.com/docs/rest_api)
+	 *
+	 * @return See Pusher API docs
 	 */
 	public function get( $path, $params = array() ) {
-		$s_url = $this->settings['url'] . $path;	
+		$s_url = $this->settings['base_path'] . $path;	
 
 		$ch = $this->create_curl( $s_url, 'GET', $params );
 
@@ -364,12 +437,12 @@ public function get( $path, $params = array() ) {
 	}
 
 	/**
-	* Creates a socket signature
-	* 
-	* @param int $socket_id
-	* @param string $custom_data
-	* @return string
-	*/
+	 * Creates a socket signature
+	 * 
+	 * @param int $socket_id
+	 * @param string $custom_data
+	 * @return string
+	 */
 	public function socket_auth( $channel, $socket_id, $custom_data = false )
 	{
 		if($custom_data == true)
@@ -391,13 +464,13 @@ public function socket_auth( $channel, $socket_id, $custom_data = false )
 	}
 
 	/**
-	* Creates a presence signature (an extension of socket signing)
-	*
-	* @param int $socket_id
-	* @param string $user_id
-	* @param mixed $user_info
-	* @return string
-	*/
+	 * Creates a presence signature (an extension of socket signing)
+	 *
+	 * @param int $socket_id
+	 * @param string $user_id
+	 * @param mixed $user_info
+	 * @return string
+	 */
 	public function presence_auth( $channel, $socket_id, $user_id, $user_info = false )
 	{
 
diff --git a/phpunit.xml b/phpunit.xml
new file mode 100644
--- /dev/null
+++ b/phpunit.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit backupGlobals="false"
+  backupStaticAttributes="false"
+  bootstrap="./test/test_includes.php"
+  colors="true"
+  convertErrorsToExceptions="true"
+  convertNoticesToExceptions="true"
+  convertWarningsToExceptions="true"
+  processIsolation="false"
+  stopOnFailure="false"
+  syntaxCheck="false"
+  >
+  <testsuites>
+    <testsuite name="all">
+      <directory>./test/</directory>
+    </testsuite>
+    
+    <testsuite name="unit">
+      <directory>./test/unit/</directory>
+    </testsuite>
+    
+    <testsuite name="acceptance">
+      <directory>./test/acceptance/</directory>
+    </testsuite>
+  </testsuites>
+</phpunit>


Test patch:
diff --git a/test/acceptance/channelQueryTest.php b/test/acceptance/channelQueryTest.php
--- a/test/acceptance/channelQueryTest.php
+++ b/test/acceptance/channelQueryTest.php
@@ -1,6 +1,4 @@
 <?php
-
-  require_once( dirname(__FILE__) . '/../test_includes.php' );
 	
 	class PusherChannelQueryTest extends PHPUnit_Framework_TestCase
 	{
diff --git a/test/acceptance/triggerTest.php b/test/acceptance/triggerTest.php
--- a/test/acceptance/triggerTest.php
+++ b/test/acceptance/triggerTest.php
@@ -1,7 +1,5 @@
 <?php
 
-	require_once( dirname(__FILE__) . '/../test_includes.php' );
-
 	class PusherPushTest extends PHPUnit_Framework_TestCase
 	{
 
@@ -24,18 +22,31 @@ public function testObjectConstruct()
 		{
 			$this->assertNotNull($this->pusher, 'Created new Pusher object');
 		}
-
+		
 		public function testStringPush()
 		{
 			$string_trigger = $this->pusher->trigger('test_channel', 'my_event', 'Test string');
 			$this->assertTrue($string_trigger, 'Trigger with string payload');
 		}
-
+		
 		public function testArrayPush()
 		{
 			$structure_trigger = $this->pusher->trigger('test_channel', 'my_event', array( 'test' => 1 ));
 			$this->assertTrue($structure_trigger, 'Trigger with structured payload');
 		}
+		
+		public function testEncryptedPush()
+		{
+			$options = array(
+				'encrypted' => true,
+				'host' => PUSHERAPP_HOST
+			);
+			$pusher = new Pusher(PUSHERAPP_AUTHKEY, PUSHERAPP_SECRET, PUSHERAPP_APPID, $options);
+			$pusher->set_logger( new TestLogger() );
+			
+			$structure_trigger = $pusher->trigger('test_channel', 'my_event', array( 'encrypted' => 1 ));
+			$this->assertTrue($structure_trigger, 'Trigger with over encrypted connection');
+		}
 
 		public function testSendingOver10kBMessageReturns413() {
 			$data = str_pad( '' , 11 * 1024, 'a' );
@@ -43,7 +54,7 @@ public function testSendingOver10kBMessageReturns413() {
 			$response = $this->pusher->trigger('test_channel', 'my_event', $data, null, true );
 			$this->assertEquals( 413, $response[ 'status' ] , '413 HTTP status response expected');
 		}
-
+		
 		/**
      * @expectedException PusherException
      */
@@ -55,12 +66,12 @@ public function test_triggering_event_on_over_100_channels_throws_exception() {
 			$data = array( 'event_name' => 'event_data' );
 			$response = $this->pusher->trigger( $channels, 'my_event', $data );
 		}
-
+		
 		public function test_triggering_event_on_multiple_channels() {
 			$data = array( 'event_name' => 'event_data' );
 			$channels = array( 'test_channel_1', 'test_channel_2' );
 			$response = $this->pusher->trigger( $channels, 'my_event', $data );
-
+		
 			$this->assertTrue( $response );
 		}
 	}
diff --git a/test/test_includes.php b/test/test_includes.php
--- a/test/test_includes.php
+++ b/test/test_includes.php
@@ -16,4 +16,4 @@
 
 require_once($dir . '/../lib/Pusher.php');
 
-require_once( $dir . '/TestLogger.php' );
\ No newline at end of file
+require_once( $dir . '/TestLogger.php' );
diff --git a/test/unit/authQueryStringTest.php b/test/unit/authQueryStringTest.php
--- a/test/unit/authQueryStringTest.php
+++ b/test/unit/authQueryStringTest.php
@@ -1,6 +1,4 @@
 <?php
-
-	require_once( dirname(__FILE__) . '/../test_includes.php' );
 	
 	class PusherAuthQueryString extends PHPUnit_Framework_TestCase
 	{
diff --git a/test/unit/pusherConstructorTest.php b/test/unit/pusherConstructorTest.php
new file mode 100644
--- /dev/null
+++ b/test/unit/pusherConstructorTest.php
@@ -0,0 +1,99 @@
+<?php
+	
+	class PusherConstructorTest extends PHPUnit_Framework_TestCase
+	{
+
+		protected function setUp()
+		{
+		}
+
+		public function testDebugCanBeSetViaLegacyParameter() {
+			$pusher = new Pusher( 'app_key', 'app_secret', 'app_id', true );
+
+			$settings = $pusher->getSettings();
+			$this->assertEquals( true, $settings[ 'debug' ] );
+		}
+
+		public function testHostAndSchemeCanBeSetViaLegacyParameter() {
+			$scheme = 'http';
+			$host = 'test.com';
+			$legacy_host = "$scheme://$host";
+			$pusher = new Pusher( 'app_key', 'app_secret', 'app_id', false, $legacy_host );
+
+			$settings = $pusher->getSettings();
+			$this->assertEquals( $scheme, $settings[ 'scheme' ] );
+			$this->assertEquals( $host, $settings[ 'host' ] );
+		}
+		
+		public function testLegacyHostParamWithNoSchemeCanBeUsedResultsInHostBeingUsedWithDefaultScheme() {
+			$host = 'test.com';
+			$pusher = new Pusher( 'app_key', 'app_secret', 'app_id', false, $host );
+			
+			$settings = $pusher->getSettings();
+			$this->assertEquals( $host, $settings[ 'host' ] );
+		}
+
+		public function testSchemeIsSetViaLegacyParameter() {
+			$host = 'https://test.com';
+			$port = 90;
+			$pusher = new Pusher( 'app_key', 'app_secret', 'app_id', false, $host, $port );
+			
+			$settings = $pusher->getSettings();
+			$this->assertEquals( 'https', $settings[ 'scheme' ] );
+		}
+
+		public function testPortCanBeSetViaLegacyParameter() {
+			$host = 'https://test.com';
+			$port = 90;
+			$pusher = new Pusher( 'app_key', 'app_secret', 'app_id', false, $host, $port );
+
+			$settings = $pusher->getSettings();
+			$this->assertEquals( $port, $settings[ 'port' ] );
+		}
+
+		public function testTimeoutCanBeSetViaLegacyParameter() {
+			$host = 'http://test.com';
+			$port = 90;
+			$timeout = 90;
+			$pusher = new Pusher( 'app_key', 'app_secret', 'app_id', false, $host, $port, $timeout );
+
+			$settings = $pusher->getSettings();
+			$this->assertEquals( $timeout, $settings[ 'timeout' ] );
+		}
+		
+		public function testEncryptedOptionWillSetHostAndPort() {
+			$options = array( 'encrypted' => true );
+			$pusher = new Pusher( 'app_key', 'app_secret', 'app_id', $options );
+			
+			$settings = $pusher->getSettings();
+			$this->assertEquals( 'https', $settings[ 'scheme' ], 'https' );
+			$this->assertEquals( 'api.pusherapp.com', $settings[ 'host' ] );
+			$this->assertEquals( '443', $settings[ 'port' ] );
+		}
+		
+		public function testEncryptedOptionWillBeOverwrittenByHostAndPortOptionsSetHostAndPort() {
+			$options = array(
+				'encrytped' => true,
+				'host' => 'test.com',
+				'port' => '3000'
+			);
+			$pusher = new Pusher( 'app_key', 'app_secret', 'app_id', $options );
+			
+			$settings = $pusher->getSettings();
+			$this->assertEquals( 'http', $settings[ 'scheme' ] );
+			$this->assertEquals( $options[ 'host' ], $settings[ 'host' ] );
+			$this->assertEquals( $options[ 'port' ], $settings[ 'port' ] );
+		}	
+		
+		public function testSchemeIsStrippedAndIgnoredFromHostInOptions() {
+			$options = array(
+				'host' => 'https://test.com'
+			);
+			$pusher = new Pusher( 'app_key', 'app_secret', 'app_id', $options );
+			
+			$settings = $pusher->getSettings();
+			$this->assertEquals( 'http', $settings[ 'scheme' ] );
+			$this->assertEquals( 'test.com', $settings[ 'host' ] );
+		}		
+
+	}
diff --git a/test/unit/socketAuthTest.php b/test/unit/socketAuthTest.php
--- a/test/unit/socketAuthTest.php
+++ b/test/unit/socketAuthTest.php
@@ -1,6 +1,4 @@
 <?php
-
-	require_once( dirname(__FILE__) . '/../test_includes.php' );
 	
 	class PusherSocketAuthTest extends PHPUnit_Framework_TestCase
 	{