. * */ namespace Friendica\Test\src\Network; use Friendica\Network\Probe; use Friendica\Test\DiceHttpMockHandlerTrait; use Friendica\Test\FixtureTest; use GuzzleHttp\Middleware; class ProbeTest extends FixtureTest { use DiceHttpMockHandlerTrait; protected function setUp(): void { parent::setUp(); $this->setupHttpMockHandler(); } const TEMPLATENOBASE = '
Hello World!
'; const TEMPLATEBASE = 'Hello World!
'; const EXPECTED = [ 'https://example.org/path/to/blog/index.php' => [ 'index.xml' => 'https://example.org/path/to/blog/index.xml', './index.xml' => 'https://example.org/path/to/blog/index.xml', '../index.xml' => 'https://example.org/path/to/index.xml', '/index.xml' => 'https://example.org/index.xml', '//example.com/index.xml' => 'https://example.com/index.xml', ], 'https://example.org/path/to/blog/' => [ 'index.xml' => 'https://example.org/path/to/blog/index.xml', './index.xml' => 'https://example.org/path/to/blog/index.xml', '../index.xml' => 'https://example.org/path/to/index.xml', '/index.xml' => 'https://example.org/index.xml', '//example.com/index.xml' => 'https://example.com/index.xml', ], 'https://example.org/blog/' => [ 'index.xml' => 'https://example.org/blog/index.xml', './index.xml' => 'https://example.org/blog/index.xml', '../index.xml' => 'https://example.org/index.xml', '/index.xml' => 'https://example.org/index.xml', '//example.com/index.xml' => 'https://example.com/index.xml', ], 'https://example.org' => [ 'index.xml' => 'https://example.org/index.xml', './index.xml' => 'https://example.org/index.xml', '../index.xml' => 'https://example.org/index.xml', '/index.xml' => 'https://example.org/index.xml', '//example.com/index.xml' => 'https://example.com/index.xml', ], ]; private function replaceMacros($template, $vars) { foreach ($vars as $var => $value) { $template = str_replace('{{' . $var . '}}', $value, $template); } return $template; } /** * @small */ public function testGetFeedLinkNoBase() { foreach (self::EXPECTED as $url => $hrefs) { foreach ($hrefs as $href => $expected) { $body = $this->replaceMacros(self::TEMPLATENOBASE, ['$link' => $href]); $feedLink = Probe::getFeedLink($url, $body); self::assertEquals($expected, $feedLink, 'base url = ' . $url . ' | href = ' . $href); } } } /** * @small */ public function testGetFeedLinkBase() { foreach (self::EXPECTED as $url => $hrefs) { foreach ($hrefs as $href => $expected) { $body = $this->replaceMacros(self::TEMPLATEBASE, ['$url' => $url, '$link' => $href]); $feedLink = Probe::getFeedLink('http://example.com', $body); self::assertEquals($expected, $feedLink, 'base url = ' . $url . ' | href = ' . $href); } } } public function dataCleanUri(): array { return [ '@-first' => [ 'expected' => 'Artists4Future_Muenchen@climatejustice.global', 'uri' => '@Artists4Future_Muenchen@climatejustice.global', ], 'no-scheme-no-fragment' => [ 'expected' => 'example.com/path?arg=value', 'uri' => 'example.com/path?arg=value', ], /* This case makes little sense, both in our expectation of receiving it in any context and in the way we * do not change it in Probe::cleanUri, but it doesn't seem to be the source of any terrible security hole. */ 'no-scheme-fragment' => [ 'expected' => 'example.com/path?arg=value#fragment', 'uri' => 'example.com/path?arg=value#fragment', ], 'scheme-no-fragment' => [ 'expected' => 'https://example.com/path?arg=value', 'uri' => 'https://example.com/path?arg=value#fragment', ], 'scheme-fragment' => [ 'expected' => 'https://example.com/path?arg=value', 'uri' => 'https://example.com/path?arg=value#fragment', ], ]; } /** * @dataProvider dataCleanUri */ public function testCleanUri(string $expected, string $uri) { self::assertEquals($expected, Probe::cleanURI($uri)); } public function dataUri(): array { return [ 'Artists4Future_Muenchen@climatejustice.global' => [ 'uri' => 'Artists4Future_Muenchen@climatejustice.global', 'assertInfos' => [ 'name' => 'Artists4Future München', 'nick' => 'Artists4Future_Muenchen', 'url' => 'https://climatejustice.global/users/Artists4Future_Muenchen', 'alias' => 'https://climatejustice.global/@Artists4Future_Muenchen', 'photo' => 'https://cdn.masto.host/climatejusticeglobal/accounts/avatars/000/021/220/original/05ee9e827a5b47fc.jpg', 'header' => 'https://cdn.masto.host/climatejusticeglobal/accounts/headers/000/021/220/original/9b98b75cf696cd11.jpg', 'account-type' => 0, 'about' => 'Wir sind Künstler oder einfach gerne kreativ tätig und setzen uns unabhängig von politischen Parteien für den Klimaschutz ein. Die Bedingungen zu schaffen, die die [url=https://climatejustice.global/tags/Klimakrise]#Klimakrise[/url] verhindern/eindämmen (gemäß den Forderungen der [url=https://climatejustice.global/tags/Fridays4Future]#Fridays4Future[/url]) ist Aufgabe der Politik, muss aber gesamtgesellschaftlich getragen werden. Mit unseren künstlerischen Aktionen wollen wir einen anderen Zugang anbieten für wissenschaftlich rationale Argumente, speziell zur Erderwärmung und ihre Konsequenzen.', 'hide' => 0, 'batch' => 'https://climatejustice.global/inbox', 'notify' => 'https://climatejustice.global/users/Artists4Future_Muenchen/inbox', 'poll' => 'https://climatejustice.global/users/Artists4Future_Muenchen/outbox', 'subscribe' => 'https://climatejustice.global/authorize_interaction?uri={uri}', 'following' => 'https://climatejustice.global/users/Artists4Future_Muenchen/following', 'followers' => 'https://climatejustice.global/users/Artists4Future_Muenchen/followers', 'inbox' => 'https://climatejustice.global/users/Artists4Future_Muenchen/inbox', 'outbox' => 'https://climatejustice.global/users/Artists4Future_Muenchen/outbox', 'sharedinbox' => 'https://climatejustice.global/inbox', 'priority' => 0, 'network' => 'apub', 'pubkey' => '-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6pYKPuDKb+rmBB869uPV uLYFPosGxMUfenWqfWmFKzEqJ87rAft0IQDAL6dCoYE55ov/lEDNROhasTZLirZf M5b7/1JmwMrAfEiaciuYqDWT3/yDpnekOIdzP5iSClg4zt7e6HRFuClqo4+b6hIE DTMV4ksItvq/92MIu62pZ2SZr5ADPPZ/914lJ86hIH5BanbE8ZFzDS9vJA7V74rt Vvkr5c/OiUyuODNYApSl87Ez8cuj8Edt89YWkDCajQn3EkmXGeJY/VRjEDfcyk6r AvdUa0ArjXud3y3NkakVFZ0d7tmB20Vn9s/CfYHU8FXzbI1kFkov2BX899VVP5Ay xQIDAQAB -----END PUBLIC KEY-----', 'manually-approve' => 0, 'baseurl' => 'https://climatejustice.global', ] ] ]; } /** * @dataProvider dataUri */ public function testProbeUri(string $uri, array $assertInfos) { self::markTestIncomplete('hard work due mocking 19 different http-requests'); /** * Requests: * * GET : https://climatejustice.global/.well-known/webfinger?resource=acct:Artists4Future_Muenchen%40climatejustice.global * 200 * GET : http://localhost/.well-known/nodeinfo * 200 * GET : http://localhost/statistics.json * 404 * GET : http://localhost * 200 * GET : http://localhost/friendica/json * 404 * GET : http://localhost/friendika/json * 404 * GET : http://localhost/poco * 403 * GET : http://localhost/api/v1/directory?limit=1 * 200 * GET : http://localhost/.well-known/x-social-relay * 200 * GET : http://localhost/friendica * 404 * GET : https://climatejustice.global/users/Artists4Future_Muenchen * 200 * GET : https://climatejustice.global/users/Artists4Future_Muenchen/following * 200 * GET : https://climatejustice.global/users/Artists4Future_Muenchen/followers * 200 * GET : https://climatejustice.global/users/Artists4Future_Muenchen/outbox * 200 * GET : https://climatejustice.global/.well-known/nodeinfo * 200 * GET : https://climatejustice.global/nodeinfo/2.0 * 200 * GET : https://climatejustice.global/poco * 404 * GET : https://climatejustice.global/api/v1/directory?limit=1 * 200 * GET : https://climatejustice.global/.well-known/webfinger?resource=acct%3AArtists4Future_Muenchen%40climatejustice.global * 200 * */ $container = []; $history = Middleware::history($container); $this->httpRequestHandler->push($history); self::assertArraySubset($assertInfos, Probe::uri($uri, '', 0)); // Iterate over the requests and responses foreach ($container as $transaction) { echo $transaction['request']->getMethod() . " : " . $transaction['request']->getUri() . PHP_EOL; //> GET, HEAD if ($transaction['response']) { echo $transaction['response']->getStatusCode() . PHP_EOL; //> 200, 200 } elseif ($transaction['error']) { echo $transaction['error']; //> exception } } } }