mirror of
https://github.com/boostorg/boost-tasks.git
synced 2026-01-19 16:12:13 +00:00
393 lines
13 KiB
PHP
393 lines
13 KiB
PHP
<?php
|
|
|
|
use Tester\Assert;
|
|
use BoostTasks\Db;
|
|
use BoostTasks\GitHubCache;
|
|
use BoostTasks\GitHubCache_Response;
|
|
use BoostTasks\GitHubCache_Connection;
|
|
use BoostTasks\Log;
|
|
|
|
require_once(__DIR__.'/bootstrap.php');
|
|
|
|
class GitHubCacheTest extends TestBase {
|
|
function testGetFile() {
|
|
$cache = new GitHubCache();
|
|
$file_url = 'file://'.__FILE__;
|
|
$file = $cache->get($file_url);
|
|
Assert::same($file_url, $file->url);
|
|
Assert::null($file->next_url);
|
|
Assert::null($file->etag);
|
|
Assert::same(file_get_contents(__FILE__), $file->body);
|
|
}
|
|
|
|
function testGet() {
|
|
$cache = new GitHubCache();
|
|
$cache->connection = new MockConnection();
|
|
$one = $cache->get('one.html');
|
|
Assert::same('https://api.github.com/one.html', $one->url);
|
|
Assert::null($one->next_url);
|
|
Assert::same("One\n", $one->body);
|
|
|
|
$two = $cache->get('two.html');
|
|
Assert::same('https://api.github.com/two.html', $two->url);
|
|
// TODO: Should resolve the link header.
|
|
Assert::same('two2.html', $two->next_url);
|
|
Assert::same("[1]", $two->body);
|
|
}
|
|
|
|
function testGetWithEtag() {
|
|
$cache = new GitHubCache();
|
|
$mock_connection = new MockConnection();
|
|
$cache->connection = $mock_connection;
|
|
$one = $cache->get('one.html');
|
|
Assert::same(array(), $mock_connection->last_headers);
|
|
Assert::same("One\n", $one->body);
|
|
$one = $cache->get('one.html');
|
|
Assert::same(array('If-None-Match: abcdefg'), $mock_connection->last_headers);
|
|
Assert::same("One\n", $one->body);
|
|
}
|
|
|
|
function testGetWithRedirect() {
|
|
$cache = new GitHubCache();
|
|
$mock_connection = new MockConnection();
|
|
$cache->connection = $mock_connection;
|
|
$one = $cache->get('one_redirect.html');
|
|
Assert::same('https://api.github.com/one.html', $one->url);
|
|
Assert::same("One\n", $one->body);
|
|
|
|
Assert::exception(function() use($cache) {
|
|
$cache->get('redirect_loop1');
|
|
}, 'RuntimeException', '#redirect#');
|
|
|
|
Assert::exception(function() use($cache) {
|
|
$cache->get('redirect_loop2');
|
|
}, 'RuntimeException', '#redirect#');
|
|
|
|
Assert::exception(function() use($cache) {
|
|
$cache->get('redirect_loop3');
|
|
}, 'RuntimeException', '#redirect#');
|
|
}
|
|
|
|
function testGet404() {
|
|
$cache = new GitHubCache();
|
|
$cache->connection = new MockConnection();
|
|
Assert::Exception(function() use($cache) {
|
|
$cache->get('non-existant.html');
|
|
}, 'RuntimeException');
|
|
}
|
|
|
|
function testGetJson() {
|
|
$cache = new GitHubCache();
|
|
$cache->connection = new MockConnection();
|
|
Assert::equal((object) array('thing' => 10), $cache->getJson('json'));
|
|
Assert::null($cache->getJson('json_null'));
|
|
Assert::exception(function() use($cache) {
|
|
$cache->getJson('one.html');
|
|
}, 'RuntimeException');
|
|
}
|
|
|
|
function testIterator() {
|
|
$cache = new GitHubCache();
|
|
$cache->connection = new MockConnection();
|
|
$values = iterator_to_array($cache->iterate('two.html'));
|
|
Assert::same(array(1,2), $values);
|
|
}
|
|
|
|
function testResolveUrl() {
|
|
$cache = new GitHubCache();
|
|
Assert::same('http://www.example.com/', $cache->resolveUrl('http://www.example.com/'));
|
|
Assert::same('https://www.example.com/', $cache->resolveUrl('//www.example.com/'));
|
|
Assert::same('https://www.example.com/foobar.html', $cache->resolveUrl('//www.example.com/foobar.html'));
|
|
Assert::same('https://www.example.com/foobar.html?a=b', $cache->resolveUrl('//www.example.com/foobar.html?a=b'));
|
|
Assert::same('http://api.github.com/thing.html', $cache->resolveUrl('http:thing.html'));
|
|
Assert::same('http://api.github.com/thing.html', $cache->resolveUrl('http:/thing.html'));
|
|
Assert::same('https://api.github.com/foobar.html', $cache->resolveUrl('/foobar.html'));
|
|
Assert::same('https://api.github.com/foo/bar.html', $cache->resolveUrl('foo/bar.html'));
|
|
Assert::same('https://api.github.com/foobar.html?a=b', $cache->resolveUrl('foobar.html?a=b'));
|
|
Assert::same('https://api.github.com/.', $cache->resolveUrl('.'));
|
|
}
|
|
}
|
|
|
|
class MockConnection {
|
|
var $responses = array(
|
|
'https://api.github.com/one_redirect.html' => array(
|
|
'code' => 301,
|
|
'reason_phrase' => 'Moved',
|
|
'headers' => array('location' => 'https://api.github.com/one.html'),
|
|
'body' => "",
|
|
),
|
|
'https://api.github.com/redirect_loop1' => array(
|
|
'code' => 301,
|
|
'headers' => array('location' => 'https://api.github.com/redirect_loop1'),
|
|
),
|
|
'https://api.github.com/redirect_loop2' => array(
|
|
'code' => 301,
|
|
'headers' => array('location' => 'https://api.github.com/redirect_loop1'),
|
|
),
|
|
'https://api.github.com/redirect_loop3' => array(
|
|
'code' => 301,
|
|
'headers' => array('location' => 'https://api.github.com/redirect_loop3a'),
|
|
),
|
|
'https://api.github.com/redirect_loop3a' => array(
|
|
'code' => 301,
|
|
'headers' => array('location' => 'https://api.github.com/redirect_loop3'),
|
|
),
|
|
'https://api.github.com/one.html' => array(
|
|
'code' => 200,
|
|
'reason_phrase' => 'blah blah blah',
|
|
'headers' => array('etag' => 'abcdefg'),
|
|
'body' => "One\n",
|
|
),
|
|
'https://api.github.com/two.html' => array(
|
|
'code' => 200,
|
|
'reason_phrase' => 'blah blah blah',
|
|
'headers' => array('link' => array(array('url' => 'two2.html', 'rel' => 'next'))),
|
|
'body' => "[1]",
|
|
),
|
|
'https://api.github.com/two2.html' => array(
|
|
'code' => 200,
|
|
'reason_phrase' => 'blah blah blah',
|
|
'headers' => array(),
|
|
'body' => "[2]",
|
|
),
|
|
'https://api.github.com/json' => array(
|
|
'code' => '200',
|
|
'reason_phrase' => 'Success',
|
|
'headers' => array(),
|
|
'body' => '{"thing":10}',
|
|
),
|
|
'https://api.github.com/json_null' => array(
|
|
'code' => '200',
|
|
'reason_phrase' => 'Success',
|
|
'headers' => array(),
|
|
'body' => 'null',
|
|
),
|
|
404 => array(
|
|
'code' => 404,
|
|
'reason_phrase' => 'not found',
|
|
'headers' => array(),
|
|
'body' => 'not found',
|
|
),
|
|
);
|
|
var $last_headers;
|
|
|
|
function get($url, $headers = array()) {
|
|
$this->last_headers = $headers;
|
|
|
|
$response_values = array_get($this->responses, $url) ?: $this->responses[404];
|
|
|
|
if (!empty($response_values['headers']['etag'])) {
|
|
$etag = $response_values['headers']['etag'];
|
|
foreach($headers as $header) {
|
|
if (preg_match('@^If-None-Match:\s*(.*)$@', $header, $match)) {
|
|
if ($match[1] === $etag) {
|
|
$response = new GitHubCache_Response();
|
|
$response->code = 304;
|
|
return $response;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$response = new GitHubCache_Response();
|
|
foreach($response_values as $key => $value) {
|
|
$response->{$key} = $value;
|
|
}
|
|
return $response;
|
|
}
|
|
}
|
|
|
|
class GitHubCache_ConnectionTest extends TestBase {
|
|
function testGet() {
|
|
$connection = new GitHubCache_Connection();
|
|
$response = $connection->get('file://'.__FILE__);
|
|
Assert::same('200', $response->code);
|
|
Assert::same(file_get_contents(__FILE__), $response->body);
|
|
}
|
|
|
|
function testParseResponse() {
|
|
$response = GitHubCache_Connection::parseResponse(
|
|
"HTTP/1.1 200 OK\r
|
|
Date: Tue, 19 Jul 2016 12:00:00 GMT\r
|
|
Server: Apache/2.2.15 (Red Hat)\r
|
|
Accept-Ranges: bytes\r
|
|
Connection: close\r
|
|
Content-Type: text/html",
|
|
"Line 1\r\nLine 2"
|
|
);
|
|
Assert::same('200', $response->code);
|
|
Assert::same('OK', $response->reason_phrase);
|
|
Assert::same('text/html', $response->headers['content-type']);
|
|
Assert::same("Line 1\nLine 2", $response->body);
|
|
}
|
|
|
|
function testParseInvalidResponse() {
|
|
Assert::exception(function() {
|
|
GitHubCache_Connection::parseResponse("Blah blah", "Blah blah");
|
|
}, 'RuntimeException');
|
|
}
|
|
|
|
function testMessageHeaders() {
|
|
Assert::same(
|
|
array(
|
|
'date' => 'Tue, 19 Jul 2016 08:58:40 GMT',
|
|
'server' => 'Apache/2.2.15 (Red Hat)',
|
|
'accept-ranges' => 'bytes',
|
|
'connection' => 'close',
|
|
'content-type' => 'text/html',
|
|
'link' => array(array('url' => 'www.example.com', 'rel' => 'something')),
|
|
),
|
|
GitHubCache_Connection::parseMessageHeaders(
|
|
'Date: Tue, 19 Jul 2016 08:58:40 GMT
|
|
Server: Apache/2.2.15 (Red Hat)
|
|
Accept-Ranges: bytes
|
|
Connection: close
|
|
Content-Type: text/html
|
|
Link: <www.example.com>;rel=something'
|
|
)
|
|
);
|
|
}
|
|
|
|
function testDuplicateMessageHeaders() {
|
|
Assert::same(
|
|
array(
|
|
'val' => '1',
|
|
),
|
|
GitHubCache_Connection::parseMessageHeaders(
|
|
'Val: 1
|
|
Error thing'
|
|
)
|
|
);
|
|
|
|
$handlers = Log::$log->getHandlers();
|
|
Assert::true($handlers[0]->hasRecordThatContains(
|
|
'Error parsing http header', \Monolog\Logger::ERROR
|
|
));
|
|
}
|
|
|
|
function testParseLinkHeader() {
|
|
Assert::same(
|
|
array(array(
|
|
'url' => 'http://www.cern.ch/TheBook/chapter2',
|
|
'rel' => 'Previous',
|
|
)),
|
|
GitHubCache_Connection::parseLinkHeader(
|
|
'<http://www.cern.ch/TheBook/chapter2>; rel="Previous"'
|
|
)
|
|
);
|
|
|
|
Assert::same(
|
|
array(array(
|
|
'url' => 'mailto:timbl@w3.org',
|
|
'rev' => 'Made',
|
|
'title' => 'Tim Berners-Lee',
|
|
)),
|
|
GitHubCache_Connection::parseLinkHeader(
|
|
'<mailto:timbl@w3.org>; rev="Made"; title="Tim Berners-Lee"'
|
|
)
|
|
);
|
|
|
|
Assert::same(
|
|
array(
|
|
array(
|
|
'url' => '../media/contrast.css',
|
|
'rel' => 'stylesheet alternate',
|
|
'title' => 'High Contrast Styles',
|
|
'type' => 'text/css',
|
|
'media' => 'screen',
|
|
),
|
|
array(
|
|
'url' => '../media/print.css',
|
|
'rel' => 'stylesheet',
|
|
'type' => 'text/css',
|
|
'media' => 'print',
|
|
),
|
|
),
|
|
GitHubCache_Connection::parseLinkHeader('
|
|
<../media/contrast.css>; rel="stylesheet alternate";
|
|
title="High Contrast Styles"; type="text/css"; media="screen",
|
|
<../media/print.css>; rel="stylesheet"; type="text/css";
|
|
media="print"
|
|
')
|
|
);
|
|
|
|
Assert::same(
|
|
array(
|
|
array(
|
|
'url' => 'sec-12-glossary.xml',
|
|
'rel' => 'glossary',
|
|
'anchor' => '#sec12',
|
|
),
|
|
),
|
|
GitHubCache_Connection::parseLinkHeader(
|
|
'<sec-12-glossary.xml>; rel="glossary"; anchor="#sec12"'
|
|
)
|
|
);
|
|
|
|
Assert::same(
|
|
array(
|
|
array(
|
|
'url' => 'link.html',
|
|
),
|
|
),
|
|
GitHubCache_Connection::parseLinkHeader(
|
|
'<link.html>'
|
|
)
|
|
);
|
|
|
|
Assert::same(
|
|
array(
|
|
array(
|
|
'url' => 'link1.html',
|
|
),
|
|
array(
|
|
'url' => 'link2.html',
|
|
),
|
|
),
|
|
GitHubCache_Connection::parseLinkHeader(
|
|
'<link1.html>,<link2.html>'
|
|
)
|
|
);
|
|
|
|
Assert::same(
|
|
array(
|
|
array(
|
|
'url' => 'link.html',
|
|
'thing' => '";"',
|
|
'thing2' => '',
|
|
'thing3' => '',
|
|
),
|
|
),
|
|
GitHubCache_Connection::parseLinkHeader(
|
|
'<link.html> ; thing="\";\"" ; thing2="" ; thing3='
|
|
)
|
|
);
|
|
}
|
|
|
|
function testParseInvalidLinkHeader() {
|
|
Assert::exception(function() {
|
|
GitHubCache_Connection::parseLinkHeader('http://example.com/');
|
|
}, 'RuntimeException', '#Error parsing link#');
|
|
}
|
|
|
|
function testParseLinkHeaderDuplicateKey() {
|
|
Assert::same(
|
|
array(array(
|
|
'url' => 'http://example.com/',
|
|
'rel' => '1',
|
|
)),
|
|
GitHubCache_Connection::parseLinkHeader('<http://example.com/>;rel=1;rel=2')
|
|
);
|
|
|
|
$handlers = Log::$log->getHandlers();
|
|
Assert::true($handlers[0]->hasRecordThatContains(
|
|
'Duplicate link key', \Monolog\Logger::ERROR
|
|
));
|
|
}
|
|
}
|
|
|
|
$test = new GitHubCacheTest();
|
|
$test->run();
|
|
$test = new GitHubCache_ConnectionTest();
|
|
$test->run();
|