#!/www/server/bin/php -qC
<?php

# Tests for url.class, currently only constructor's parser

it::getopt("Usage: it_url.t [OPTIONS]");

# Create object and parse url
$url = new it_url('HTTP://falcon:joshua@www.Relog.CH:80/default.asp');

is(
	$url->url,
	'http://www.relog.ch/default.asp',
	'$url->url'
);

is(
	$url->protocol,
	'http',
	'$url->protocol'
);

is(
	$url->hostname,
	'relog.ch',
	'$url->hostname'
);

is(
	$url->realhostname,
	'www.relog.ch',
	'$url->realhostname'
);

is(
	$url->port,
	80,
	'$url->port'
);

is(
	$url->path,
	'default.asp',
	'$url->path'
);

is(
	$url->user,
	'falcon',
	'$url->user'
);

is(
	$url->pass,
	'joshua',
	'$url->pass'
);

# and now check for path
$url = new it_url('HTTP://falcon:joshua@www.Relog.CH:80/foo/bar.html');

is(
	$url->path,
	'foo/bar.html',
	'$url->path'
);

# punycode test
$url = new it_url('http://www.sörtsch.ch/?q=ültra#sörtsch');
is(
	$url->realhostname,
	'www.xn--srtsch-wxa.ch',
	'punycode $url->realhostname'
);

# it_url::absolute() tests
list ($_SERVER['HTTP_HOST'], $_SERVER['SERVER_PORT'], $_SERVER['HTTPS']) = ["gna.ch", null, null];
is(
	it_url::absolute("/"),
	'http://gna.ch/',
	'it_url::absolute basic'
);

list ($_SERVER['HTTP_HOST'], $_SERVER['SERVER_PORT'], $_SERVER['HTTPS']) = ["gna.ch:42", 42, null];
is(
	it_url::absolute("/port"),
	'http://gna.ch:42/port',
	'it_url::absolute with non-standard port'
);

list ($_SERVER['HTTP_HOST'], $_SERVER['SERVER_PORT'], $_SERVER['HTTPS']) = ["gna.ch", 443, true];
is(
	it_url::absolute("/https"),
	'https://gna.ch/https',
	'it_url::absolute for https'
);

list ($_SERVER['HTTP_HOST'], $_SERVER['SERVER_PORT'], $_SERVER['HTTPS']) = ["gna.ch", null, null];
is(
	it_url::absolute("/https", "https"),
	'https://gna.ch/https',
	'it_url::absolute force https in http context'
);

list ($_SERVER['HTTP_HOST'], $_SERVER['SERVER_PORT'], $_SERVER['HTTPS']) = ["gna.ch", 443, true];
is(
	it_url::absolute("/foo", "http"),
	'http://gna.ch/foo',
	'it_url::absolute force http in https context'
);

list ($_SERVER['HTTP_HOST'], $_SERVER['SERVER_PORT'], $_SERVER['HTTPS']) = ["gna.ch", null, null];
is(
	it_url::absolute("http://gna.ch/foo", "https"),
	'https://gna.ch/foo',
	'it_url::absolute force https overwriting existing url'
);


$url = new it_url('http://www.gna.ch/');
is((bool)$url->is_reachable(), true, "is_reachable($url->url)");

$url = new it_url('http://www.search.ch/not_found');
is((bool)$url->is_reachable(), false, "is_reachable($url->url)");

$url = new it_url('http://bogus.url');
is((bool)$url->is_reachable(), false, "is_reachable($url->url)");

$response = it_url::get(['url' => 'http://www.gna.ch/', 'assoc' => true]);
ok(
	strpos($response['data'], '</html>'), # UTF8SAFE
	'Get with url as named arg'
);
is(
	$response['status'],
	'200',
	'Reponse status = 200'
);
is(
	$response['headers']['Server'],
	'Apache',
	'Response headers correctly set'
);

$page = it_url::get('http://www.gna.ch/');
ok(
	strpos($page, '</html>'), # UTF8SAFE
	'it_url::get() static call'
);

require 'it_url_server.php';

handle_server(
	is(
		it_url::get('http://localhost:8000/'),
		"Testserver root output",
		'it_url::get() static call with port'
	)
);

handle_server(
	is(
		it_url::get('//localhost:8000/'),
		"Testserver root output",
		'it_url::get() static call with port but no protocol'
	)
);

handle_server(
	is(
		it_url::get(['url' => 'http://localhost:8000/', 'maxlength' => 100]),
		"Testserver root output",
		'it_url::get() static call with port and maxlength'
	)
);

handle_server(
	is(
		it_url::get(['url' => 'http://localhost:8000/', 'maxlength' => 5, 'it_error' => false]),
		false,
		'it_url::get() static call with port and too small maxlength'
	)
);

handle_server(
	is(
		it_url::get('http://localhost:8000/temp_redirect'),
		"Testserver output after temporary redirect",
		'it_url::get() follows temproary redirect'
	)
);

handle_server(
	is(
		it_url::get('http://localhost:8000/perm_redirect'),
		"Testserver output after permanent redirect",
		'it_url::get() follows permanent redirect'
	)
);

handle_server(
	is(
		it_url::get(['url' => 'http://localhost:8000/relative_redirect', 'it_error' => false]),
		"Testserver output after relative redirect",
		'it_url::get() follows relative redirect correctly'
	)
);

handle_server(
	is(
		it_url::get('http://localhost:8000/nohost_redirect'),
		"Testserver output after nohost redirect",
		'it_url::get() follows redirect without host correctly'
	)
);

handle_server(
	is(
		it_url::get('http://localhost:8000/created_redirect'),
		"Testserver output *before* created redirect",
		'it_url::get() does not follow Location of 201 (Created) result'
	)
);

$output = handle_server(
	ok(
		!it_url::get(['url' => U('http://localhost:8000/redirect_loop', ['num' => 40]), 'it_error' => false]),
		'it_url::get() handles redirect loop'
	)
);
$last_num = it::match('num=(\d+)', end($output));
if (!ok(
	$last_num == 20,
	'it_url::get() aborts redirect loop after 5 redirects'
))
	diag($output);

$output = handle_server(
	ok(
		!it_url::get(['url' => 'http://localhost:8000/does_not_exist', 'retries' => 4]),
		'it_url::get() on 404'
	)
);
if (!ok(
	count(preg_grep('/^Got Request:/', $output)) == 1,
	'it_url::get() does not retry on 404'
))
	diag($output);

$output = handle_server(
	ok(
		!it_url::get(['url' => 'http://localhost:8000/repeat?num=0', 'retries' => 4]),
		'it_url::get() on empty page'
	)
);
if (!ok(
	count(preg_grep('/^Got Request:/', $output)) == 5,
	'it_url::get() does retry on empty page'
))
	diag($output);

$output = handle_server(
	is(
		it_url::get(U('http://localhost:8000/empty')),
		'',
		'it_url::get() explicit empty result'
	)
);
if (!ok(
	count(preg_grep('/^Got Request:/', $output)) == 1,
	'it_url::get() does not retry on explicity empty page'
))
	diag($output);

handle_server(
	is(
		it_url::get(U('http://localhost:8000/get_server_value', ['key' => 'HTTP_HOST'])),
		'localhost:8000',
		'it_url::get() sets correct Host header'
	)
);

handle_server(
	is(
		it_url::get(U('http://localhost:8000/get_server_value', ['key' => 'HTTP_ACCEPT_LANGUAGE'])),
		T_lang(),
		'it_url::get() sets correct Accept-Language header'
	)
);

handle_server(
	ok(
		it::match('Mozilla', it_url::get(U('http://localhost:8000/get_server_value', ['key' => 'HTTP_USER_AGENT']))),
		'it_url::get() sets User-Agent containing Mozilla'
	)
);

handle_server(
	is(
		it_url::get(U('http://user:password@localhost:8000/get_server_value', ['key' => 'PHP_AUTH_USER'])),
		'user',
		'it_url::get() basic authentication user'
	)
);

handle_server(
	is(
		it_url::get(U('http://user:password@localhost:8000/get_server_value', ['key' => 'PHP_AUTH_PW'])),
		'password',
		'it_url::get() basic authentication password'
	)
);

$pages = it_url::get_multi(['urls' => ['a' => 'http://www.gna.ch/', 'b' => 'http://search.ch/']]);
ok(strpos($pages['a'], '</html>'), 'it_url::get_multi got first url'); # UTF8SAFE
ok(strpos($pages['b'], '</html>'), 'it_url::get_multi got second url'); # UTF8SAFE
is(count($pages), 2, 'it_url::get_multi no additional array elements');

handle_server(
	is(
		it_url::get('http://localhost:8000/maybe_error?chance=0'),
		"success"
	),
	is(
		it_url::get('http://localhost:8000/maybe_error?chance=100'),
		"failure"
	),
	is(
		it_url::get(['url' => 'http://localhost:8000/maybe_error?chance=10', 'retries' => 10]),
		"success",
		"Retry on sporadically failing url in ::get"
	),
	is(
		it_url::get_multi(['urls' => ['http://localhost:8000/maybe_error?chance=10'], 'retries' => 10]),
		["success"],
		"Retry on sporadically failing url in ::get_multi"
	)
);

is(it_url::parse("/foo"), ["/foo"], "it_url::parse path only");
is(it_url::parse("/foo?"), ["/foo"], "it_url::parse empty parameter");
is(it_url::parse("/foo?bar=baz&qux=quux"), ["/foo", 'bar' => "baz", 'qux' => "quux"], "it_url::parse parameters");
is(it_url::parse("/foo?b%E4r=b%E4z"), ["/foo", 'bär' => "bäz"]);