]> git.mxchange.org Git - friendica.git/blob - tests/src/Network/ProbeTest.php
Merge pull request #11056 from MrPetovan/bug/11055-probe-detect-url
[friendica.git] / tests / src / Network / ProbeTest.php
1 <?php
2
3 namespace Friendica\Test\src\Network;
4
5 use Friendica\Network\Probe;
6 use Friendica\Test\DiceHttpMockHandlerTrait;
7 use Friendica\Test\FixtureTest;
8 use GuzzleHttp\Middleware;
9
10 class ProbeTest extends FixtureTest
11 {
12         use DiceHttpMockHandlerTrait;
13
14         protected function setUp(): void
15         {
16                 parent::setUp();
17
18                 $this->setupHttpMockHandler();
19         }
20
21         const TEMPLATENOBASE = '
22 <!DOCTYPE html>
23 <html lang="en-us">
24 <head>
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" />
28 </head>
29 <body>
30     <p>Hello World!</p>
31 </body>
32 </html>';
33
34         const TEMPLATEBASE = '
35 <!DOCTYPE html>
36 <html lang="en-us">
37 <head>
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}}">
42 </head>
43 <body>
44     <p>Hello World!</p>
45 </body>
46 </html>';
47
48         const EXPECTED = [
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',
55                 ],
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',
62                 ],
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',
69                 ],
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',
76                 ],
77         ];
78
79         private function replaceMacros($template, $vars)
80         {
81                 foreach ($vars as $var => $value) {
82                         $template = str_replace('{{' . $var . '}}', $value, $template);
83                 }
84
85                 return $template;
86         }
87
88         /**
89          * @small
90          */
91         public function testGetFeedLinkNoBase()
92         {
93                 foreach (self::EXPECTED as $url => $hrefs) {
94                         foreach ($hrefs as $href => $expected) {
95                                 $body = $this->replaceMacros(self::TEMPLATENOBASE, ['$link' => $href]);
96
97                                 $feedLink = Probe::getFeedLink($url, $body);
98
99                                 self::assertEquals($expected, $feedLink, 'base url = ' . $url . ' | href = ' . $href);
100                         }
101                 }
102         }
103
104         /**
105          * @small
106          */
107         public function testGetFeedLinkBase()
108         {
109                 foreach (self::EXPECTED as $url => $hrefs) {
110                         foreach ($hrefs as $href => $expected) {
111                                 $body = $this->replaceMacros(self::TEMPLATEBASE, ['$url' => $url, '$link' => $href]);
112
113                                 $feedLink = Probe::getFeedLink('http://example.com', $body);
114
115                                 self::assertEquals($expected, $feedLink, 'base url = ' . $url . ' | href = ' . $href);
116                         }
117                 }
118         }
119
120         public function dataCleanUri(): array
121         {
122                 return [
123                         '@-first' => [
124                                 'expected' => 'Artists4Future_Muenchen@climatejustice.global',
125                                 'uri'      => '@Artists4Future_Muenchen@climatejustice.global',
126                         ],
127                         'no-scheme-no-fragment' => [
128                                 'expected' => 'example.com/path?arg=value',
129                                 'uri'      => 'example.com/path?arg=value',
130                         ],
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.
133                          */
134                         'no-scheme-fragment' => [
135                                 'expected' => 'example.com/path?arg=value#fragment',
136                                 'uri'      => 'example.com/path?arg=value#fragment',
137                         ],
138                         'scheme-no-fragment' => [
139                                 'expected' => 'https://example.com/path?arg=value',
140                                 'uri'      => 'https://example.com/path?arg=value#fragment',
141                         ],
142                         'scheme-fragment' => [
143                                 'expected' => 'https://example.com/path?arg=value',
144                                 'uri'      => 'https://example.com/path?arg=value#fragment',
145                         ],
146                 ];
147         }
148
149         /**
150          * @dataProvider dataCleanUri
151          */
152         public function testCleanUri(string $expected, string $uri)
153         {
154                 self::assertEquals($expected, Probe::cleanURI($uri));
155         }
156
157         public function dataUri(): array
158         {
159                 return [
160                         'Artists4Future_Muenchen@climatejustice.global' => [
161                                 'uri'         => 'Artists4Future_Muenchen@climatejustice.global',
162                                 'assertInfos' => [
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',
169                                         'account-type' => 0,
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.',
171                                         'hide'         => 0,
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',
181                                         'priority'     => 0,
182                                         'network'      => 'apub',
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
190 xQIDAQAB
191 -----END PUBLIC KEY-----',
192                                         'manually-approve' => 0,
193                                         'baseurl'          => 'https://climatejustice.global',
194                                 ]
195                         ]
196                 ];
197         }
198
199         /**
200          * @dataProvider dataUri
201          */
202         public function testProbeUri(string $uri, array $assertInfos)
203         {
204                 self::markTestIncomplete('hard work due mocking 19 different http-requests');
205
206                 /**
207                  * Requests:
208                  *
209                  * GET : https://climatejustice.global/.well-known/webfinger?resource=acct:Artists4Future_Muenchen%40climatejustice.global
210                  * 200
211                  * GET : http://localhost/.well-known/nodeinfo
212                  * 200
213                  * GET : http://localhost/statistics.json
214                  * 404
215                  * GET : http://localhost
216                  * 200
217                  * GET : http://localhost/friendica/json
218                  * 404
219                  * GET : http://localhost/friendika/json
220                  * 404
221                  * GET : http://localhost/poco
222                  * 403
223                  * GET : http://localhost/api/v1/directory?limit=1
224                  * 200
225                  * GET : http://localhost/.well-known/x-social-relay
226                  * 200
227                  * GET : http://localhost/friendica
228                  * 404
229                  * GET : https://climatejustice.global/users/Artists4Future_Muenchen
230                  * 200
231                  * GET : https://climatejustice.global/users/Artists4Future_Muenchen/following
232                  * 200
233                  * GET : https://climatejustice.global/users/Artists4Future_Muenchen/followers
234                  * 200
235                  * GET : https://climatejustice.global/users/Artists4Future_Muenchen/outbox
236                  * 200
237                  * GET : https://climatejustice.global/.well-known/nodeinfo
238                  * 200
239                  * GET : https://climatejustice.global/nodeinfo/2.0
240                  * 200
241                  * GET : https://climatejustice.global/poco
242                  * 404
243                  * GET : https://climatejustice.global/api/v1/directory?limit=1
244                  * 200
245                  * GET : https://climatejustice.global/.well-known/webfinger?resource=acct%3AArtists4Future_Muenchen%40climatejustice.global
246                  * 200
247                  *
248                  */
249
250                 $container = [];
251                 $history   = Middleware::history($container);
252
253                 $this->httpRequestHandler->push($history);
254
255                 self::assertArraySubset($assertInfos, Probe::uri($uri, '', 0));
256
257                 // Iterate over the requests and responses
258                 foreach ($container as $transaction) {
259                         echo $transaction['request']->getMethod() . " : " . $transaction['request']->getUri() . PHP_EOL;
260                         //> GET, HEAD
261                         if ($transaction['response']) {
262                                 echo $transaction['response']->getStatusCode() . PHP_EOL;
263                         //> 200, 200
264                         } elseif ($transaction['error']) {
265                                 echo $transaction['error'];
266                                 //> exception
267                         }
268                 }
269         }
270 }