<?php

if( !class_exists('WP_Http') )
	require ABSPATH . WPINC .'/http.php';

class WPTestHTTPAPI extends WPTestCase {

	/**
	 * Tests whether the function returns the same object.
	 *
	 * This test will be skewed on PHP5, because objects are passed by reference
	 * anyway.
	 */
	function test_should_return_WP_HTTP_Base_object_by_ref() {
		$expected = _wp_http_get_object();
		$actual = _wp_http_get_object();

		$this->assertSame($expected, $actual);
	}

	function test_fopen_transport_object_test_if_available() {
		if( ini_get('allow_url_fopen') != true ) {
			$this->markTestSkipped('PHP allow_url_fopen directive is not enabled.');
			return;
		}

		$this->assertTrue(WP_Http_Fopen::test());
	}

	function test_fsockopen_transport_not_available_and_function_not_exists() {
		if( false === strpos(ini_get('disable_functions'), 'fsockopen') ) {
			$this->markTestSkipped('Fsockopen() is not part of the disabled functions list.');
			return;
		}

		$this->assertFalse( function_exists('fsockopen') );
	}

	/**
	 * @covers WP_Http_Fsockopen::request
	 * @covers WP_Http_Fsockopen::test
	 */
	function test_fsockopen_transport_expects_200_wordpress_org_page_without_redirect() {
		if( false === WP_Http_Fsockopen::test() ) {
			$this->markTestSkipped('Fsockopen() is not available.');
			return;
		}

		$transport = new WP_Http_Fsockopen();

		$response = $transport->request('http://wordpress.org', null, null, array('method' => 'HEAD'));

		$this->assertFalse(is_wp_error($response));

		$expected = 200;

		$actual = $response['response']['code'];

		$this->assertEquals($expected, $actual);
	}

	/**
	 * @covers WP_Http_Fsockopen::request
	 * @covers WP_Http_Fsockopen::test
	 */
	function test_fsockopen_transport_expects_200_wordpress_org_page_with_redirect() {
		if( false === WP_Http_Fsockopen::test() ) {
			$this->markTestSkipped('Fsockopen() is not available.');
			return;
		}

		$transport = new WP_Http_Fsockopen();

		$response = $transport->request('http://www.wordpress.org', null, null, array('method' => 'HEAD'));

		$this->assertFalse(is_wp_error($response));

		$expected = 200;

		$actual = $response['response']['code'];

		$this->assertEquals($expected, $actual);
	}

	/**
	 * @covers WP_Http_Fopen::request
	 * @covers WP_Http_Fopen::test
	 */
	function test_fopen_transport_expects_200_wordpress_org_page_without_redirect() {
		if( false === WP_Http_Fopen::test() ) {
			$this->markTestSkipped('Fopen() is not available for http requests.');
			return;
		}

		$transport = new WP_Http_Fopen();

		$response = $transport->request('http://wordpress.org', null, null, array('method' => 'GET'));

		$this->assertFalse(is_wp_error($response));

		$expected = 200;

		$actual = $response['response']['code'];

		$this->assertEquals($expected, $actual);
	}

	/**
	 * @covers WP_Http_Fopen::request
	 * @covers WP_Http_Fopen::test
	 */
	function test_fopen_transport_expects_200_wordpress_org_page_with_redirect() {
		if( false === WP_Http_Fopen::test() ) {
			$this->markTestSkipped('Fopen() is not available for http requests.');
			return;
		}

		$transport = new WP_Http_Fopen();

		$response = $transport->request('http://www.wordpress.org', null, null, array('method' => 'GET'));

		$this->assertFalse(is_wp_error($response));

		$expected = 200;

		$actual = $response['response']['code'];

		$this->assertEquals($expected, $actual);
	}

	/**
	 * @covers WP_Http_Streams::request
	 * @covers WP_Http_Streams::test
	 */
	function test_streams_transport_expects_200_wordpress_org_page_without_redirect() {
		if( false === WP_Http_Streams::test() ) {
			$this->markTestSkipped('Streams is not available.');
			return;
		}

		$transport = new WP_Http_Streams();

		$response = $transport->request('http://wordpress.org', null, null, array('method' => 'GET'));

		$this->assertFalse(is_wp_error($response));

		$expected = 200;

		$actual = $response['response']['code'];

		$this->assertEquals($expected, $actual);
	}

	/**
	 * @covers WP_Http_Streams::request
	 * @covers WP_Http_Streams::test
	 */
	function test_streams_transport_expects_200_wordpress_org_page_with_redirect() {
		if( false === WP_Http_Streams::test() ) {
			$this->markTestSkipped('Streams is not available.');
			return;
		}

		$transport = new WP_Http_Streams();

		$response = $transport->request('http://www.wordpress.org', null, null, array('method' => 'GET'));

		$this->assertFalse(is_wp_error($response));

		$expected = 200;

		$actual = $response['response']['code'];

		$this->assertEquals($expected, $actual);
	}

	/**
	 * @covers WP_Http_ExtHTTP::request
	 * @covers WP_Http_ExtHTTP::test
	 */
	function test_exthttp_transport_expects_200_wordpress_org_page_without_redirect() {
		if( false === WP_Http_ExtHTTP::test() ) {
			$this->markTestSkipped('The HTTP extension is not available.');
			return;
		}

		$transport = new WP_Http_ExtHTTP();

		$response = $transport->request('http://wordpress.org', null, null, array('method' => 'GET'));

		$this->assertFalse(is_wp_error($response));

		$expected = 200;

		$actual = $response['response']['code'];

		$this->assertEquals($expected, $actual);
	}

	/**
	 * @covers WP_Http_ExtHTTP::request
	 * @covers WP_Http_ExtHTTP::test
	 */
	function test_exthttp_transport_expects_200_wordpress_org_page_with_redirect() {
		if( false === WP_Http_ExtHTTP::test() ) {
			$this->markTestSkipped('The HTTP extension is not available.');
			return;
		}

		$transport = new WP_Http_ExtHTTP();

		$response = $transport->request('http://www.wordpress.org', null, null, array('method' => 'GET'));

		$this->assertFalse(is_wp_error($response));

		$expected = 200;

		$actual = $response['response']['code'];

		$this->assertEquals($expected, $actual);
	}

	function test_wp_remote_request_function_expects_200_response_from_wordpress_org_without_redirect() {
		$response = wp_remote_request('http://wordpress.org', null, null, array('method' => 'GET'));

		$this->assertFalse(is_wp_error($response));

		$expected = 200;

		$actual = $response['response']['code'];

		$this->assertEquals($expected, $actual);
	}

	function test_wp_remote_request_function_expects_200_response_from_wordpress_org_with_redirect() {
		$response = wp_remote_request('http://www.wordpress.org', null, null, array('method' => 'GET'));

		$this->assertFalse(is_wp_error($response));

		$expected = 200;

		$actual = $response['response']['code'];

		$this->assertEquals($expected, $actual);
	}

	/**
	 * @covers WP_Http_Fopen::request
	 */
	function test_fopen_transport_and_test_response_with_ssl() {
		if( !function_exists('openssl_open') ) {
			$this->markTestSkipped('The OpenSSL extension is not available.');
			return;
		}

		$transport = new WP_Http_Fopen();
		$response = $transport->request('https://www.google.com', null, null, array('method' => 'GET'));

		$expected = 200;
		$actual = $response['response']['code'];

		$this->assertEquals($expected, $actual);
	}

	/**
	 * @covers WP_Http_Streams::request
	 */
	function test_streams_transport_and_test_response_with_ssl() {
		if( !function_exists('openssl_open') ) {
			$this->markTestSkipped('The OpenSSL extension is not available.');
			return;
		}

		$transport = new WP_Http_Streams();
		$response = $transport->request('https://www.google.com', null, null, array('method' => 'GET'));

		$expected = 200;
		$actual = $response['response']['code'];

		$this->assertEquals($expected, $actual);
	}

	/**
	 * @covers WP_Http_Streams::request
	 */
	function test_exthttp_transport_and_test_response_with_ssl() {
		if( !function_exists('openssl_open') ) {
			$this->markTestSkipped('The OpenSSL extension is not available.');
			return;
		}

		$transport = new WP_Http_Streams();
		$response = $transport->request('https://www.google.com', null, null, array('method' => 'GET'));

		$expected = 200;
		$actual = $response['response']['code'];

		$this->assertEquals($expected, $actual);
	}

	/**
	 * @covers WP_Http_Streams::request
	 */
	function test_fsockopen_transport_and_test_response_with_ssl() {
		if( !function_exists('openssl_open') ) {
			$this->markTestSkipped('The OpenSSL extension is not available.');
			return;
		}

		$transport = new WP_Http_Streams();
		$response = $transport->request('https://www.google.com', null, null, array('method' => 'GET'));

		$expected = 200;
		$actual = $response['response']['code'];

		$this->assertEquals($expected, $actual);
	}

	/**
	 * @covers WP_Http::processHeaders
	 */
	function test_wp_http_process_headers() {
		$headers = WP_Http::processHeaders("Content-type: text/html\r\nConnection: close\r\n");

		$this->assertEquals(2, count($headers['headers']));

		$this->assertTrue( isset($headers['headers']['content-type']) );
		$this->assertEquals('text/html', $headers['headers']['content-type']);

		$this->assertTrue( isset($headers['headers']['connection']) );
		$this->assertEquals('close', $headers['headers']['connection']);
	}

	/**
	 * @covers WP_Http::processHeaders
	 */
	function test_wp_http_base_process_headers_and_get_response() {
		$headers = WP_Http::processHeaders("HTTP/1.1 200 OK\r\nContent-type: text/html\r\nConnection: close\r\n");

		$this->assertEquals(2, count($headers['headers']));
		$this->assertEquals(2, count($headers['response']));

		$this->assertTrue( isset($headers['headers']['content-type']) );
		$this->assertEquals('text/html', $headers['headers']['content-type']);

		$this->assertTrue( isset($headers['headers']['connection']) );
		$this->assertEquals('close', $headers['headers']['connection']);

		$this->assertEquals(200, $headers['response']['code']);
		$this->assertEquals('OK', $headers['response']['message']);
	}

	/**
	 * @covers WP_Http::processResponse
	 */
	function test_process_response_get_values_raw_response_for_body_headers_and_response() {
		$response = WP_Http::processResponse("HTTP/1.1 200 OK\r\nLocation: http://www.example.org\r\nContent-type: text/html\r\nConnection: close\r\n\r\nTest Body");

		$this->assertTrue( is_array($response) );

		$this->assertEquals('Test Body', $response['body']);

		$this->assertEquals("HTTP/1.1 200 OK\r\nLocation: http://www.example.org\r\nContent-type: text/html\r\nConnection: close", $response['headers']);
	}

	function test_process_response_get_values_using_helper_functions_and_all_headers() {
		$arrResponse = WP_Http::processResponse("HTTP/1.1 200 OK\r\nLocation: http://www.example.org\r\nContent-type: text/html\r\nConnection: close\r\n\r\nTest Body");
		$headers = WP_Http::processHeaders($arrResponse['headers']);
		$response = array('body' => $arrResponse['body'], 'headers' => $headers['headers'], 'response' => $headers['response']);

		$this->assertTrue( is_array($response) );

		$this->assertEquals('Test Body', wp_remote_retrieve_body($response));

		$headers = wp_remote_retrieve_headers($response);

		$this->assertEquals('http://www.example.org', $headers['location']);
		$this->assertEquals('text/html', $headers['content-type']);
		$this->assertEquals('close', $headers['connection']);

		$this->assertEquals(200, wp_remote_retrieve_response_code($response));
		$this->assertEquals('OK', wp_remote_retrieve_response_message($response));
	}

	function test_process_response_get_values_using_helper_functions_and_by_single_headers() {
		$arrResponse = WP_Http::processResponse("HTTP/1.1 200 OK\r\nLocation: http://www.example.org\r\nContent-type: text/html\r\nConnection: close\r\n\r\nTest Body");
		$headers = WP_Http::processHeaders($arrResponse['headers']);
		$response = array('body' => $arrResponse['body'], 'headers' => $headers['headers'], 'response' => $headers['response']);

		$this->assertTrue( is_array($response) );

		$this->assertEquals('Test Body', wp_remote_retrieve_body($response));

		$this->assertEquals('http://www.example.org', wp_remote_retrieve_header($response, 'location'));
		$this->assertEquals('text/html', wp_remote_retrieve_header($response, 'content-type'));
		$this->assertEquals('close', wp_remote_retrieve_header($response, 'connection'));

		$this->assertEquals(200, wp_remote_retrieve_response_code($response));
		$this->assertEquals('OK', wp_remote_retrieve_response_message($response));
	}

	function test_isRedirect_should_be_a_redirect() {
		$headers = array(
			'content-type' => 'text/html; charset=utf-8',
			'location' => 'http://wordpress.org/',
			'date' => 'Thu, 31 Jul 2008 23:09:15 GMT',
			'server' => 'LiteSpeed',
			'connection' => 'close',
		);

		$this->assertTrue(WP_Http::isRedirect($headers));
	}

	function test_isRedirect_should_not_be_a_redirect() {
		$headers = array(
			'content-type' => 'text/html; charset=utf-8',
			'date' => 'Thu, 31 Jul 2008 23:09:15 GMT',
			'server' => 'LiteSpeed',
			'connection' => 'close',
		);

		$this->assertFalse(WP_Http::isRedirect($headers));
	}
}

?>