]> git.mxchange.org Git - friendica.git/blob - tests/src/Network/ProbeTest.php
Happy New Year 2023!
[friendica.git] / tests / src / Network / ProbeTest.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2010-2023, the Friendica project
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  *
20  */
21
22 namespace Friendica\Test\src\Network;
23
24 use Friendica\Network\Probe;
25 use Friendica\Test\DiceHttpMockHandlerTrait;
26 use Friendica\Test\FixtureTest;
27 use GuzzleHttp\Middleware;
28
29 class ProbeTest extends FixtureTest
30 {
31         use DiceHttpMockHandlerTrait;
32
33         protected function setUp(): void
34         {
35                 parent::setUp();
36
37                 $this->setupHttpMockHandler();
38         }
39
40         const TEMPLATENOBASE = '
41 <!DOCTYPE html>
42 <html lang="en-us">
43 <head>
44     <title>Example Blog</title>
45     <link href="{{$link}}" rel="alternate" type="application/rss+xml" title="Example Blog" />
46         <link href="{{$link}}" rel="feed" type="application/rss+xml" title="Example Blog" />
47 </head>
48 <body>
49     <p>Hello World!</p>
50 </body>
51 </html>';
52
53         const TEMPLATEBASE = '
54 <!DOCTYPE html>
55 <html lang="en-us">
56 <head>
57     <title>Example Blog</title>
58     <link href="{{$link}}" rel="alternate" type="application/rss+xml" title="Example Blog" />
59         <link href="{{$link}}" rel="feed" type="application/rss+xml" title="Example Blog" />
60     <base href="{{$url}}">
61 </head>
62 <body>
63     <p>Hello World!</p>
64 </body>
65 </html>';
66
67         const EXPECTED = [
68                 'https://example.org/path/to/blog/index.php' => [
69                         'index.xml'               => 'https://example.org/path/to/blog/index.xml',
70                         './index.xml'             => 'https://example.org/path/to/blog/index.xml',
71                         '../index.xml'            => 'https://example.org/path/to/index.xml',
72                         '/index.xml'              => 'https://example.org/index.xml',
73                         '//example.com/index.xml' => 'https://example.com/index.xml',
74                 ],
75                 'https://example.org/path/to/blog/' => [
76                         'index.xml'               => 'https://example.org/path/to/blog/index.xml',
77                         './index.xml'             => 'https://example.org/path/to/blog/index.xml',
78                         '../index.xml'            => 'https://example.org/path/to/index.xml',
79                         '/index.xml'              => 'https://example.org/index.xml',
80                         '//example.com/index.xml' => 'https://example.com/index.xml',
81                 ],
82                 'https://example.org/blog/' => [
83                         'index.xml'               => 'https://example.org/blog/index.xml',
84                         './index.xml'             => 'https://example.org/blog/index.xml',
85                         '../index.xml'            => 'https://example.org/index.xml',
86                         '/index.xml'              => 'https://example.org/index.xml',
87                         '//example.com/index.xml' => 'https://example.com/index.xml',
88                 ],
89                 'https://example.org' => [
90                         'index.xml'               => 'https://example.org/index.xml',
91                         './index.xml'             => 'https://example.org/index.xml',
92                         '../index.xml'            => 'https://example.org/index.xml',
93                         '/index.xml'              => 'https://example.org/index.xml',
94                         '//example.com/index.xml' => 'https://example.com/index.xml',
95                 ],
96         ];
97
98         private function replaceMacros($template, $vars)
99         {
100                 foreach ($vars as $var => $value) {
101                         $template = str_replace('{{' . $var . '}}', $value, $template);
102                 }
103
104                 return $template;
105         }
106
107         /**
108          * @small
109          */
110         public function testGetFeedLinkNoBase()
111         {
112                 foreach (self::EXPECTED as $url => $hrefs) {
113                         foreach ($hrefs as $href => $expected) {
114                                 $body = $this->replaceMacros(self::TEMPLATENOBASE, ['$link' => $href]);
115
116                                 $feedLink = Probe::getFeedLink($url, $body);
117
118                                 self::assertEquals($expected, $feedLink, 'base url = ' . $url . ' | href = ' . $href);
119                         }
120                 }
121         }
122
123         /**
124          * @small
125          */
126         public function testGetFeedLinkBase()
127         {
128                 foreach (self::EXPECTED as $url => $hrefs) {
129                         foreach ($hrefs as $href => $expected) {
130                                 $body = $this->replaceMacros(self::TEMPLATEBASE, ['$url' => $url, '$link' => $href]);
131
132                                 $feedLink = Probe::getFeedLink('http://example.com', $body);
133
134                                 self::assertEquals($expected, $feedLink, 'base url = ' . $url . ' | href = ' . $href);
135                         }
136                 }
137         }
138
139         public function dataCleanUri(): array
140         {
141                 return [
142                         '@-first' => [
143                                 'expected' => 'Artists4Future_Muenchen@climatejustice.global',
144                                 'uri'      => '@Artists4Future_Muenchen@climatejustice.global',
145                         ],
146                         'no-scheme-no-fragment' => [
147                                 'expected' => 'example.com/path?arg=value',
148                                 'uri'      => 'example.com/path?arg=value',
149                         ],
150                         /* This case makes little sense, both in our expectation of receiving it in any context and in the way we
151                          * do not change it in Probe::cleanUri, but it doesn't seem to be the source of any terrible security hole.
152                          */
153                         'no-scheme-fragment' => [
154                                 'expected' => 'example.com/path?arg=value#fragment',
155                                 'uri'      => 'example.com/path?arg=value#fragment',
156                         ],
157                         'scheme-no-fragment' => [
158                                 'expected' => 'https://example.com/path?arg=value',
159                                 'uri'      => 'https://example.com/path?arg=value#fragment',
160                         ],
161                         'scheme-fragment' => [
162                                 'expected' => 'https://example.com/path?arg=value',
163                                 'uri'      => 'https://example.com/path?arg=value#fragment',
164                         ],
165                 ];
166         }
167
168         /**
169          * @dataProvider dataCleanUri
170          */
171         public function testCleanUri(string $expected, string $uri)
172         {
173                 self::assertEquals($expected, Probe::cleanURI($uri));
174         }
175
176         public function dataUri(): array
177         {
178                 return [
179                         'Artists4Future_Muenchen@climatejustice.global' => [
180                                 'uri'         => 'Artists4Future_Muenchen@climatejustice.global',
181                                 'assertInfos' => [
182                                         'name'         => 'Artists4Future München',
183                                         'nick'         => 'Artists4Future_Muenchen',
184                                         'url'          => 'https://climatejustice.global/users/Artists4Future_Muenchen',
185                                         'alias'        => 'https://climatejustice.global/@Artists4Future_Muenchen',
186                                         'photo'        => 'https://cdn.masto.host/climatejusticeglobal/accounts/avatars/000/021/220/original/05ee9e827a5b47fc.jpg',
187                                         'header'       => 'https://cdn.masto.host/climatejusticeglobal/accounts/headers/000/021/220/original/9b98b75cf696cd11.jpg',
188                                         'account-type' => 0,
189                                         '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.',
190                                         'hide'         => 0,
191                                         'batch'        => 'https://climatejustice.global/inbox',
192                                         'notify'       => 'https://climatejustice.global/users/Artists4Future_Muenchen/inbox',
193                                         'poll'         => 'https://climatejustice.global/users/Artists4Future_Muenchen/outbox',
194                                         'subscribe'    => 'https://climatejustice.global/authorize_interaction?uri={uri}',
195                                         'following'    => 'https://climatejustice.global/users/Artists4Future_Muenchen/following',
196                                         'followers'    => 'https://climatejustice.global/users/Artists4Future_Muenchen/followers',
197                                         'inbox'        => 'https://climatejustice.global/users/Artists4Future_Muenchen/inbox',
198                                         'outbox'       => 'https://climatejustice.global/users/Artists4Future_Muenchen/outbox',
199                                         'sharedinbox'  => 'https://climatejustice.global/inbox',
200                                         'priority'     => 0,
201                                         'network'      => 'apub',
202                                         'pubkey'       => '-----BEGIN PUBLIC KEY-----
203 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6pYKPuDKb+rmBB869uPV
204 uLYFPosGxMUfenWqfWmFKzEqJ87rAft0IQDAL6dCoYE55ov/lEDNROhasTZLirZf
205 M5b7/1JmwMrAfEiaciuYqDWT3/yDpnekOIdzP5iSClg4zt7e6HRFuClqo4+b6hIE
206 DTMV4ksItvq/92MIu62pZ2SZr5ADPPZ/914lJ86hIH5BanbE8ZFzDS9vJA7V74rt
207 Vvkr5c/OiUyuODNYApSl87Ez8cuj8Edt89YWkDCajQn3EkmXGeJY/VRjEDfcyk6r
208 AvdUa0ArjXud3y3NkakVFZ0d7tmB20Vn9s/CfYHU8FXzbI1kFkov2BX899VVP5Ay
209 xQIDAQAB
210 -----END PUBLIC KEY-----',
211                                         'manually-approve' => 0,
212                                         'baseurl'          => 'https://climatejustice.global',
213                                 ]
214                         ]
215                 ];
216         }
217
218         /**
219          * @dataProvider dataUri
220          */
221         public function testProbeUri(string $uri, array $assertInfos)
222         {
223                 self::markTestIncomplete('hard work due mocking 19 different http-requests');
224
225                 /**
226                  * Requests:
227                  *
228                  * GET : https://climatejustice.global/.well-known/webfinger?resource=acct:Artists4Future_Muenchen%40climatejustice.global
229                  * 200
230                  * GET : http://localhost/.well-known/nodeinfo
231                  * 200
232                  * GET : http://localhost/statistics.json
233                  * 404
234                  * GET : http://localhost
235                  * 200
236                  * GET : http://localhost/friendica/json
237                  * 404
238                  * GET : http://localhost/friendika/json
239                  * 404
240                  * GET : http://localhost/poco
241                  * 403
242                  * GET : http://localhost/api/v1/directory?limit=1
243                  * 200
244                  * GET : http://localhost/.well-known/x-social-relay
245                  * 200
246                  * GET : http://localhost/friendica
247                  * 404
248                  * GET : https://climatejustice.global/users/Artists4Future_Muenchen
249                  * 200
250                  * GET : https://climatejustice.global/users/Artists4Future_Muenchen/following
251                  * 200
252                  * GET : https://climatejustice.global/users/Artists4Future_Muenchen/followers
253                  * 200
254                  * GET : https://climatejustice.global/users/Artists4Future_Muenchen/outbox
255                  * 200
256                  * GET : https://climatejustice.global/.well-known/nodeinfo
257                  * 200
258                  * GET : https://climatejustice.global/nodeinfo/2.0
259                  * 200
260                  * GET : https://climatejustice.global/poco
261                  * 404
262                  * GET : https://climatejustice.global/api/v1/directory?limit=1
263                  * 200
264                  * GET : https://climatejustice.global/.well-known/webfinger?resource=acct%3AArtists4Future_Muenchen%40climatejustice.global
265                  * 200
266                  *
267                  */
268
269                 $container = [];
270                 $history   = Middleware::history($container);
271
272                 $this->httpRequestHandler->push($history);
273
274                 self::assertArraySubset($assertInfos, Probe::uri($uri, '', 0));
275
276                 // Iterate over the requests and responses
277                 foreach ($container as $transaction) {
278                         echo $transaction['request']->getMethod() . " : " . $transaction['request']->getUri() . PHP_EOL;
279                         //> GET, HEAD
280                         if ($transaction['response']) {
281                                 echo $transaction['response']->getStatusCode() . PHP_EOL;
282                         //> 200, 200
283                         } elseif ($transaction['error']) {
284                                 echo $transaction['error'];
285                                 //> exception
286                         }
287                 }
288         }
289 }