3 namespace Friendica\Test\src\Network;
5 use Friendica\Network\Probe;
6 use Friendica\Test\DiceHttpMockHandlerTrait;
7 use Friendica\Test\FixtureTest;
8 use GuzzleHttp\Middleware;
10 class ProbeTest extends FixtureTest
12 use DiceHttpMockHandlerTrait;
14 protected function setUp(): void
18 $this->setupHttpMockHandler();
21 const TEMPLATENOBASE = '
25 <title>Example Blog</title>
26 <link href="{{$link}}" rel="alternate" type="application/rss+xml" title="Example Blog" />
27 <link href="{{$link}}" rel="feed" type="application/rss+xml" title="Example Blog" />
34 const TEMPLATEBASE = '
38 <title>Example Blog</title>
39 <link href="{{$link}}" rel="alternate" type="application/rss+xml" title="Example Blog" />
40 <link href="{{$link}}" rel="feed" type="application/rss+xml" title="Example Blog" />
41 <base href="{{$url}}">
49 'https://example.org/path/to/blog/index.php' => [
50 'index.xml' => 'https://example.org/path/to/blog/index.xml',
51 './index.xml' => 'https://example.org/path/to/blog/index.xml',
52 '../index.xml' => 'https://example.org/path/to/index.xml',
53 '/index.xml' => 'https://example.org/index.xml',
54 '//example.com/index.xml' => 'https://example.com/index.xml',
56 'https://example.org/path/to/blog/' => [
57 'index.xml' => 'https://example.org/path/to/blog/index.xml',
58 './index.xml' => 'https://example.org/path/to/blog/index.xml',
59 '../index.xml' => 'https://example.org/path/to/index.xml',
60 '/index.xml' => 'https://example.org/index.xml',
61 '//example.com/index.xml' => 'https://example.com/index.xml',
63 'https://example.org/blog/' => [
64 'index.xml' => 'https://example.org/blog/index.xml',
65 './index.xml' => 'https://example.org/blog/index.xml',
66 '../index.xml' => 'https://example.org/index.xml',
67 '/index.xml' => 'https://example.org/index.xml',
68 '//example.com/index.xml' => 'https://example.com/index.xml',
70 'https://example.org' => [
71 'index.xml' => 'https://example.org/index.xml',
72 './index.xml' => 'https://example.org/index.xml',
73 '../index.xml' => 'https://example.org/index.xml',
74 '/index.xml' => 'https://example.org/index.xml',
75 '//example.com/index.xml' => 'https://example.com/index.xml',
79 private function replaceMacros($template, $vars)
81 foreach ($vars as $var => $value) {
82 $template = str_replace('{{' . $var . '}}', $value, $template);
91 public function testGetFeedLinkNoBase()
93 foreach (self::EXPECTED as $url => $hrefs) {
94 foreach ($hrefs as $href => $expected) {
95 $body = $this->replaceMacros(self::TEMPLATENOBASE, ['$link' => $href]);
97 $feedLink = Probe::getFeedLink($url, $body);
99 self::assertEquals($expected, $feedLink, 'base url = ' . $url . ' | href = ' . $href);
107 public function testGetFeedLinkBase()
109 foreach (self::EXPECTED as $url => $hrefs) {
110 foreach ($hrefs as $href => $expected) {
111 $body = $this->replaceMacros(self::TEMPLATEBASE, ['$url' => $url, '$link' => $href]);
113 $feedLink = Probe::getFeedLink('http://example.com', $body);
115 self::assertEquals($expected, $feedLink, 'base url = ' . $url . ' | href = ' . $href);
120 public function dataCleanUri(): array
124 'expected' => 'Artists4Future_Muenchen@climatejustice.global',
125 'uri' => '@Artists4Future_Muenchen@climatejustice.global',
127 'no-scheme-no-fragment' => [
128 'expected' => 'example.com/path?arg=value',
129 'uri' => 'example.com/path?arg=value',
131 /* This case makes little sense, both in our expectation of receiving it in any context and in the way we
132 * do not change it in Probe::cleanUri, but it doesn't seem to be the source of any terrible security hole.
134 'no-scheme-fragment' => [
135 'expected' => 'example.com/path?arg=value#fragment',
136 'uri' => 'example.com/path?arg=value#fragment',
138 'scheme-no-fragment' => [
139 'expected' => 'https://example.com/path?arg=value',
140 'uri' => 'https://example.com/path?arg=value#fragment',
142 'scheme-fragment' => [
143 'expected' => 'https://example.com/path?arg=value',
144 'uri' => 'https://example.com/path?arg=value#fragment',
150 * @dataProvider dataCleanUri
152 public function testCleanUri(string $expected, string $uri)
154 self::assertEquals($expected, Probe::cleanURI($uri));
157 public function dataUri(): array
160 'Artists4Future_Muenchen@climatejustice.global' => [
161 'uri' => 'Artists4Future_Muenchen@climatejustice.global',
163 'name' => 'Artists4Future München',
164 'nick' => 'Artists4Future_Muenchen',
165 'url' => 'https://climatejustice.global/users/Artists4Future_Muenchen',
166 'alias' => 'https://climatejustice.global/@Artists4Future_Muenchen',
167 'photo' => 'https://cdn.masto.host/climatejusticeglobal/accounts/avatars/000/021/220/original/05ee9e827a5b47fc.jpg',
168 'header' => 'https://cdn.masto.host/climatejusticeglobal/accounts/headers/000/021/220/original/9b98b75cf696cd11.jpg',
170 '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.',
172 'batch' => 'https://climatejustice.global/inbox',
173 'notify' => 'https://climatejustice.global/users/Artists4Future_Muenchen/inbox',
174 'poll' => 'https://climatejustice.global/users/Artists4Future_Muenchen/outbox',
175 'subscribe' => 'https://climatejustice.global/authorize_interaction?uri={uri}',
176 'following' => 'https://climatejustice.global/users/Artists4Future_Muenchen/following',
177 'followers' => 'https://climatejustice.global/users/Artists4Future_Muenchen/followers',
178 'inbox' => 'https://climatejustice.global/users/Artists4Future_Muenchen/inbox',
179 'outbox' => 'https://climatejustice.global/users/Artists4Future_Muenchen/outbox',
180 'sharedinbox' => 'https://climatejustice.global/inbox',
183 'pubkey' => '-----BEGIN PUBLIC KEY-----
184 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6pYKPuDKb+rmBB869uPV
185 uLYFPosGxMUfenWqfWmFKzEqJ87rAft0IQDAL6dCoYE55ov/lEDNROhasTZLirZf
186 M5b7/1JmwMrAfEiaciuYqDWT3/yDpnekOIdzP5iSClg4zt7e6HRFuClqo4+b6hIE
187 DTMV4ksItvq/92MIu62pZ2SZr5ADPPZ/914lJ86hIH5BanbE8ZFzDS9vJA7V74rt
188 Vvkr5c/OiUyuODNYApSl87Ez8cuj8Edt89YWkDCajQn3EkmXGeJY/VRjEDfcyk6r
189 AvdUa0ArjXud3y3NkakVFZ0d7tmB20Vn9s/CfYHU8FXzbI1kFkov2BX899VVP5Ay
191 -----END PUBLIC KEY-----',
192 'manually-approve' => 0,
193 'baseurl' => 'https://climatejustice.global',
200 * @dataProvider dataUri
202 public function testProbeUri(string $uri, array $assertInfos)
204 self::markTestIncomplete('hard work due mocking 19 different http-requests');
209 * GET : https://climatejustice.global/.well-known/webfinger?resource=acct:Artists4Future_Muenchen%40climatejustice.global
211 * GET : http://localhost/.well-known/nodeinfo
213 * GET : http://localhost/statistics.json
215 * GET : http://localhost
217 * GET : http://localhost/friendica/json
219 * GET : http://localhost/friendika/json
221 * GET : http://localhost/poco
223 * GET : http://localhost/api/v1/directory?limit=1
225 * GET : http://localhost/.well-known/x-social-relay
227 * GET : http://localhost/friendica
229 * GET : https://climatejustice.global/users/Artists4Future_Muenchen
231 * GET : https://climatejustice.global/users/Artists4Future_Muenchen/following
233 * GET : https://climatejustice.global/users/Artists4Future_Muenchen/followers
235 * GET : https://climatejustice.global/users/Artists4Future_Muenchen/outbox
237 * GET : https://climatejustice.global/.well-known/nodeinfo
239 * GET : https://climatejustice.global/nodeinfo/2.0
241 * GET : https://climatejustice.global/poco
243 * GET : https://climatejustice.global/api/v1/directory?limit=1
245 * GET : https://climatejustice.global/.well-known/webfinger?resource=acct%3AArtists4Future_Muenchen%40climatejustice.global
251 $history = Middleware::history($container);
253 $this->httpRequestHandler->push($history);
255 self::assertArraySubset($assertInfos, Probe::uri($uri, '', 0));
257 // Iterate over the requests and responses
258 foreach ($container as $transaction) {
259 echo $transaction['request']->getMethod() . " : " . $transaction['request']->getUri() . PHP_EOL;
261 if ($transaction['response']) {
262 echo $transaction['response']->getStatusCode() . PHP_EOL;
264 } elseif ($transaction['error']) {
265 echo $transaction['error'];