]> git.mxchange.org Git - friendica.git/blob - tests/legacy/ApiTest.php
ae290a9b732133a056a949450d703178bc4fb681
[friendica.git] / tests / legacy / ApiTest.php
1 <?php
2 /**
3  * ApiTest class.
4  */
5
6 namespace Friendica\Test\legacy;
7
8 use Friendica\App;
9 use Friendica\Core\Config\Capability\IManageConfigValues;
10 use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
11 use Friendica\Core\Protocol;
12 use Friendica\DI;
13 use Friendica\Module\BaseApi;
14 use Friendica\Network\HTTPException;
15 use Friendica\Security\BasicAuth;
16 use Friendica\Test\FixtureTest;
17 use Friendica\Util\Arrays;
18 use Friendica\Util\DateTimeFormat;
19 use Friendica\Util\Temporal;
20 use Monolog\Handler\TestHandler;
21
22 require_once __DIR__ . '/../../include/api.php';
23
24 /**
25  * Tests for the API functions.
26  *
27  * Functions that use header() need to be tested in a separate process.
28  * @see https://phpunit.de/manual/5.7/en/appendixes.annotations.html#appendixes.annotations.runTestsInSeparateProcesses
29  *
30  * @backupGlobals enabled
31  */
32 class ApiTest extends FixtureTest
33 {
34         /**
35          * @var TestHandler Can handle log-outputs
36          */
37         protected $logOutput;
38
39         /** @var array */
40         protected $selfUser;
41         /** @var array */
42         protected $friendUser;
43         /** @var array */
44         protected $otherUser;
45
46         protected $wrongUserId;
47
48         /** @var App */
49         protected $app;
50
51         /** @var IManageConfigValues */
52         protected $config;
53
54         /**
55          * Create variables used by tests.
56          */
57         protected function setUp() : void
58         {
59                 global $API, $called_api;
60                 $API = [];
61                 $called_api = [];
62
63                 parent::setUp();
64
65                 /** @var IManageConfigValues $config */
66                 $this->config = $this->dice->create(IManageConfigValues::class);
67
68                 $this->config->set('system', 'url', 'http://localhost');
69                 $this->config->set('system', 'hostname', 'localhost');
70                 $this->config->set('system', 'worker_dont_fork', true);
71
72                 // Default config
73                 $this->config->set('config', 'hostname', 'localhost');
74                 $this->config->set('system', 'throttle_limit_day', 100);
75                 $this->config->set('system', 'throttle_limit_week', 100);
76                 $this->config->set('system', 'throttle_limit_month', 100);
77                 $this->config->set('system', 'theme', 'system_theme');
78
79
80                 /** @var App app */
81                 $this->app = DI::app();
82
83                 DI::args()->setArgc(1);
84
85                 // User data that the test database is populated with
86                 $this->selfUser   = [
87                         'id'   => 42,
88                         'name' => 'Self contact',
89                         'nick' => 'selfcontact',
90                         'nurl' => 'http://localhost/profile/selfcontact'
91                 ];
92                 $this->friendUser = [
93                         'id'   => 44,
94                         'name' => 'Friend contact',
95                         'nick' => 'friendcontact',
96                         'nurl' => 'http://localhost/profile/friendcontact'
97                 ];
98                 $this->otherUser  = [
99                         'id'   => 43,
100                         'name' => 'othercontact',
101                         'nick' => 'othercontact',
102                         'nurl' => 'http://localhost/profile/othercontact'
103                 ];
104
105                 // User ID that we know is not in the database
106                 $this->wrongUserId = 666;
107
108                 DI::session()->start();
109
110                 // Most API require login so we force the session
111                 $_SESSION = [
112                         'allow_api'     => true,
113                         'authenticated' => true,
114                         'uid'           => $this->selfUser['id']
115                 ];
116         }
117
118         /**
119          * Assert that an user array contains expected keys.
120          *
121          * @param array $user User array
122          *
123          * @return void
124          */
125         private function assertSelfUser(array $user)
126         {
127                 self::assertEquals($this->selfUser['id'], $user['uid']);
128                 self::assertEquals($this->selfUser['id'], $user['cid']);
129                 self::assertEquals(1, $user['self']);
130                 self::assertEquals('DFRN', $user['location']);
131                 self::assertEquals($this->selfUser['name'], $user['name']);
132                 self::assertEquals($this->selfUser['nick'], $user['screen_name']);
133                 self::assertEquals('dfrn', $user['network']);
134                 self::assertTrue($user['verified']);
135         }
136
137         /**
138          * Assert that an user array contains expected keys.
139          *
140          * @param array $user User array
141          *
142          * @return void
143          */
144         private function assertOtherUser(array $user = [])
145         {
146                 self::assertEquals($this->otherUser['id'], $user['id']);
147                 self::assertEquals($this->otherUser['id'], $user['id_str']);
148                 self::assertEquals(0, $user['self']);
149                 self::assertEquals($this->otherUser['name'], $user['name']);
150                 self::assertEquals($this->otherUser['nick'], $user['screen_name']);
151                 self::assertFalse($user['verified']);
152         }
153
154         /**
155          * Assert that a status array contains expected keys.
156          *
157          * @param array $status Status array
158          *
159          * @return void
160          */
161         private function assertStatus(array $status = [])
162         {
163                 self::assertIsString($status['text'] ?? '');
164                 self::assertIsInt($status['id'] ?? '');
165                 // We could probably do more checks here.
166         }
167
168         /**
169          * Assert that a list array contains expected keys.
170          *
171          * @param array $list List array
172          *
173          * @return void
174          */
175         private function assertList(array $list = [])
176         {
177                 self::assertIsString($list['name']);
178                 self::assertIsInt($list['id']);
179                 self::assertIsString('string', $list['id_str']);
180                 self::assertContains($list['mode'], ['public', 'private']);
181                 // We could probably do more checks here.
182         }
183
184         /**
185          * Assert that the string is XML and contain the root element.
186          *
187          * @param string $result       XML string
188          * @param string $root_element Root element name
189          *
190          * @return void
191          */
192         private function assertXml($result = '', $root_element = '')
193         {
194                 self::assertStringStartsWith('<?xml version="1.0"?>', $result);
195                 self::assertStringContainsString('<' . $root_element, $result);
196                 // We could probably do more checks here.
197         }
198
199         /**
200          * Get the path to a temporary empty PNG image.
201          *
202          * @return string Path
203          */
204         private function getTempImage()
205         {
206                 $tmpFile = tempnam(sys_get_temp_dir(), 'tmp_file');
207                 file_put_contents(
208                         $tmpFile,
209                         base64_decode(
210                         // Empty 1x1 px PNG image
211                                 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg=='
212                         )
213                 );
214
215                 return $tmpFile;
216         }
217
218         /**
219          * Test the api_user() function.
220          *
221          * @return void
222          */
223         public function testApiUser()
224         {
225                 self::assertEquals($this->selfUser['id'], api_user());
226         }
227
228         /**
229          * Test the api_user() function with an unallowed user.
230          *
231          * @return void
232          */
233         public function testApiUserWithUnallowedUser()
234         {
235                 $_SESSION = ['allow_api' => false];
236                 self::assertEquals(false, api_user());
237         }
238
239         /**
240          * Test the api_source() function.
241          *
242          * @return void
243          */
244         public function testApiSource()
245         {
246                 self::assertEquals('api', api_source());
247         }
248
249         /**
250          * Test the api_source() function with a Twidere user agent.
251          *
252          * @return void
253          */
254         public function testApiSourceWithTwidere()
255         {
256                 $_SERVER['HTTP_USER_AGENT'] = 'Twidere';
257                 self::assertEquals('Twidere', api_source());
258         }
259
260         /**
261          * Test the api_source() function with a GET parameter.
262          *
263          * @return void
264          */
265         public function testApiSourceWithGet()
266         {
267                 $_GET['source'] = 'source_name';
268                 self::assertEquals('source_name', api_source());
269         }
270
271         /**
272          * Test the api_date() function.
273          *
274          * @return void
275          */
276         public function testApiDate()
277         {
278                 self::assertEquals('Wed Oct 10 00:00:00 +0000 1990', api_date('1990-10-10'));
279         }
280
281         /**
282          * Test the api_register_func() function.
283          *
284          * @return void
285          */
286         public function testApiRegisterFunc()
287         {
288                 global $API;
289                 self::assertNull(
290                         api_register_func(
291                                 'api_path',
292                                 function () {
293                                 },
294                                 true,
295                                 'method'
296                         )
297                 );
298                 self::assertTrue($API['api_path']['auth']);
299                 self::assertEquals('method', $API['api_path']['method']);
300                 self::assertTrue(is_callable($API['api_path']['func']));
301         }
302
303         /**
304          * Test the BasicAuth::getCurrentUserID() function without any login.
305          *
306          * @runInSeparateProcess
307          * @preserveGlobalState disabled
308          * @preserveGlobalState disabled
309          */
310         public function testApiLoginWithoutLogin()
311         {
312                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
313                 BasicAuth::getCurrentUserID(true);
314         }
315
316         /**
317          * Test the BasicAuth::getCurrentUserID() function with a bad login.
318          *
319          * @runInSeparateProcess
320          * @preserveGlobalState disabled
321          * @preserveGlobalState disabled
322          */
323         public function testApiLoginWithBadLogin()
324         {
325                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
326                 $_SERVER['PHP_AUTH_USER'] = 'user@server';
327                 BasicAuth::getCurrentUserID(true);
328         }
329
330         /**
331          * Test the BasicAuth::getCurrentUserID() function with oAuth.
332          *
333          * @return void
334          */
335         public function testApiLoginWithOauth()
336         {
337                 $this->markTestIncomplete('Can we test this easily?');
338         }
339
340         /**
341          * Test the BasicAuth::getCurrentUserID() function with authentication provided by an addon.
342          *
343          * @return void
344          */
345         public function testApiLoginWithAddonAuth()
346         {
347                 $this->markTestIncomplete('Can we test this easily?');
348         }
349
350         /**
351          * Test the BasicAuth::getCurrentUserID() function with a correct login.
352          *
353          * @runInSeparateProcess
354          * @preserveGlobalState disabled
355          * @doesNotPerformAssertions
356          */
357         public function testApiLoginWithCorrectLogin()
358         {
359                 $_SERVER['PHP_AUTH_USER'] = 'Test user';
360                 $_SERVER['PHP_AUTH_PW']   = 'password';
361                 BasicAuth::getCurrentUserID(true);
362         }
363
364         /**
365          * Test the BasicAuth::getCurrentUserID() function with a remote user.
366          *
367          * @runInSeparateProcess
368          * @preserveGlobalState disabled
369          */
370         public function testApiLoginWithRemoteUser()
371         {
372                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
373                 $_SERVER['REDIRECT_REMOTE_USER'] = '123456dXNlcjpwYXNzd29yZA==';
374                 BasicAuth::getCurrentUserID(true);
375         }
376
377         /**
378          * Test the api_check_method() function.
379          *
380          * @return void
381          */
382         public function testApiCheckMethod()
383         {
384                 self::assertFalse(api_check_method('method'));
385         }
386
387         /**
388          * Test the api_check_method() function with a correct method.
389          *
390          * @return void
391          */
392         public function testApiCheckMethodWithCorrectMethod()
393         {
394                 $_SERVER['REQUEST_METHOD'] = 'method';
395                 self::assertTrue(api_check_method('method'));
396         }
397
398         /**
399          * Test the api_check_method() function with a wildcard.
400          *
401          * @return void
402          */
403         public function testApiCheckMethodWithWildcard()
404         {
405                 self::assertTrue(api_check_method('*'));
406         }
407
408         /**
409          * Test the api_call() function.
410          *
411          * @runInSeparateProcess
412          * @preserveGlobalState disabled
413          */
414         public function testApiCall()
415         {
416                 global $API;
417                 $API['api_path']           = [
418                         'method' => 'method',
419                         'func'   => function () {
420                                 return ['data' => ['some_data']];
421                         }
422                 ];
423                 $_SERVER['REQUEST_METHOD'] = 'method';
424                 $_SERVER['QUERY_STRING'] = 'pagename=api_path';
425                 $_GET['callback']          = 'callback_name';
426
427                 $args = DI::args()->determine($_SERVER, $_GET);
428
429                 self::assertEquals(
430                         'callback_name(["some_data"])',
431                         api_call($this->app, $args)
432                 );
433         }
434
435         /**
436          * Test the api_call() function with the profiled enabled.
437          *
438          * @runInSeparateProcess
439          * @preserveGlobalState disabled
440          */
441         public function testApiCallWithProfiler()
442         {
443                 global $API;
444                 $API['api_path']           = [
445                         'method' => 'method',
446                         'func'   => function () {
447                                 return ['data' => ['some_data']];
448                         }
449                 ];
450
451                 $_SERVER['REQUEST_METHOD'] = 'method';
452                 $_SERVER['QUERY_STRING'] = 'pagename=api_path';
453
454                 $args = DI::args()->determine($_SERVER, $_GET);
455
456                 $this->config->set('system', 'profiler', true);
457                 $this->config->set('rendertime', 'callstack', true);
458                 $this->app->callstack = [
459                         'database'       => ['some_function' => 200],
460                         'database_write' => ['some_function' => 200],
461                         'cache'          => ['some_function' => 200],
462                         'cache_write'    => ['some_function' => 200],
463                         'network'        => ['some_function' => 200]
464                 ];
465
466                 self::assertEquals(
467                         '["some_data"]',
468                         api_call($this->app, $args)
469                 );
470         }
471
472         /**
473          * Test the api_call() function without any result.
474          *
475          * @runInSeparateProcess
476          * @preserveGlobalState disabled
477          */
478         public function testApiCallWithNoResult()
479         {
480                 // @todo How to test the new API?
481                 /*
482                 global $API;
483                 $API['api_path']           = [
484                         'method' => 'method',
485                         'func'   => function () {
486                                 return false;
487                         }
488                 ];
489                 $_SERVER['REQUEST_METHOD'] = 'method';
490                 $_SERVER['QUERY_STRING'] = 'pagename=api_path';
491
492                 $args = DI::args()->determine($_SERVER, $_GET);
493
494                 self::assertEquals(
495                         '{"status":{"error":"Internal Server Error","code":"500 Internal Server Error","request":"api_path"}}',
496                         api_call($this->app, $args)
497                 );
498                 */
499         }
500
501         /**
502          * Test the api_call() function with an unimplemented API.
503          *
504          * @runInSeparateProcess
505          * @preserveGlobalState disabled
506          */
507         public function testApiCallWithUninplementedApi()
508         {
509                 // @todo How to test the new API?
510                 /*
511                 self::assertEquals(
512                         '{"status":{"error":"Not Found","code":"404 Not Found","request":""}}',
513                         api_call($this->app)
514                 );
515                 */
516         }
517
518         /**
519          * Test the api_call() function with a JSON result.
520          *
521          * @runInSeparateProcess
522          * @preserveGlobalState disabled
523          */
524         public function testApiCallWithJson()
525         {
526                 global $API;
527                 $API['api_path']           = [
528                         'method' => 'method',
529                         'func'   => function () {
530                                 return ['data' => ['some_data']];
531                         }
532                 ];
533                 $_SERVER['REQUEST_METHOD'] = 'method';
534                 $_SERVER['QUERY_STRING'] = 'pagename=api_path.json';
535
536                 $args = DI::args()->determine($_SERVER, $_GET);
537
538                 self::assertEquals(
539                         '["some_data"]',
540                         api_call($this->app, $args)
541                 );
542         }
543
544         /**
545          * Test the api_call() function with an XML result.
546          *
547          * @runInSeparateProcess
548          * @preserveGlobalState disabled
549          */
550         public function testApiCallWithXml()
551         {
552                 global $API;
553                 $API['api_path']           = [
554                         'method' => 'method',
555                         'func'   => function () {
556                                 return 'some_data';
557                         }
558                 ];
559                 $_SERVER['REQUEST_METHOD'] = 'method';
560                 $_SERVER['QUERY_STRING'] = 'pagename=api_path.xml';
561
562                 $args = DI::args()->determine($_SERVER, $_GET);
563
564                 self::assertEquals(
565                         'some_data',
566                         api_call($this->app, $args)
567                 );
568         }
569
570         /**
571          * Test the api_call() function with an RSS result.
572          *
573          * @runInSeparateProcess
574          * @preserveGlobalState disabled
575          */
576         public function testApiCallWithRss()
577         {
578                 global $API;
579                 $API['api_path']           = [
580                         'method' => 'method',
581                         'func'   => function () {
582                                 return 'some_data';
583                         }
584                 ];
585                 $_SERVER['REQUEST_METHOD'] = 'method';
586                 $_SERVER['QUERY_STRING'] = 'pagename=api_path.rss';
587
588                 $args = DI::args()->determine($_SERVER, $_GET);
589
590                 self::assertEquals(
591                         '<?xml version="1.0" encoding="UTF-8"?>' . "\n" .
592                         'some_data',
593                         api_call($this->app, $args)
594                 );
595         }
596
597         /**
598          * Test the api_call() function with an Atom result.
599          *
600          * @runInSeparateProcess
601          * @preserveGlobalState disabled
602          */
603         public function testApiCallWithAtom()
604         {
605                 global $API;
606                 $API['api_path']           = [
607                         'method' => 'method',
608                         'func'   => function () {
609                                 return 'some_data';
610                         }
611                 ];
612                 $_SERVER['REQUEST_METHOD'] = 'method';
613                 $_SERVER['QUERY_STRING'] = 'pagename=api_path.atom';
614
615                 $args = DI::args()->determine($_SERVER, $_GET);
616
617                 self::assertEquals(
618                         '<?xml version="1.0" encoding="UTF-8"?>' . "\n" .
619                         'some_data',
620                         api_call($this->app, $args)
621                 );
622         }
623
624         /**
625          * Test the api_call() function with an unallowed method.
626          *
627          * @runInSeparateProcess
628          * @preserveGlobalState disabled
629          */
630         public function testApiCallWithWrongMethod()
631         {
632                 // Shouldn't be needed anymore due to the router?
633                 /*
634                 global $API;
635                 $API['api_path'] = ['method' => 'method'];
636
637                 $_SERVER['QUERY_STRING'] = 'pagename=api_path';
638
639                 $args = DI::args()->determine($_SERVER, $_GET);
640
641                 self::assertEquals(
642                         '{"status":{"error":"Method Not Allowed","code":"405 Method Not Allowed","request":"api_path"}}',
643                         api_call($this->app, $args)
644                 );
645                 */
646         }
647
648         /**
649          * Test the api_call() function with an unauthorized user.
650          *
651          * @runInSeparateProcess
652          * @preserveGlobalState disabled
653          */
654         public function testApiCallWithWrongAuth()
655         {
656                 // @todo How to test the new API?
657                 /*
658                 global $API;
659                 $API['api_path']           = [
660                         'method' => 'method',
661                         'auth'   => true
662                 ];
663                 $_SESSION['authenticated'] = false;
664                 $_SERVER['REQUEST_METHOD'] = 'method';
665                 $_SERVER['QUERY_STRING'] = 'pagename=api_path';
666
667                 $args = DI::args()->determine($_SERVER, $_GET);
668
669                 self::assertEquals(
670                         '{"status":{"error":"This API requires login","code":"401 Unauthorized","request":"api_path"}}',
671                         api_call($this->app, $args)
672                 );
673                 */
674         }
675
676         /**
677          * Test the api_error() function with a JSON result.
678          *
679          * @runInSeparateProcess
680          * @preserveGlobalState disabled
681          */
682         public function testApiErrorWithJson()
683         {
684                 // @todo How to test the new API?
685                 // self::assertEquals(
686                 //      '{"status":{"error":"error_message","code":"200 OK","request":""}}',
687                 //      api_error('json', new HTTPException\OKException('error_message'), DI::args())
688                 // );
689         }
690
691         /**
692          * Test the api_error() function with an XML result.
693          *
694          * @runInSeparateProcess
695          * @preserveGlobalState disabled
696          */
697         public function testApiErrorWithXml()
698         {
699                 // @todo How to test the new API?
700                 /*
701                 self::assertEquals(
702                         '<?xml version="1.0"?>' . "\n" .
703                         '<status xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" ' .
704                         'xmlns:friendica="http://friendi.ca/schema/api/1/" ' .
705                         'xmlns:georss="http://www.georss.org/georss">' . "\n" .
706                         '  <error>error_message</error>' . "\n" .
707                         '  <code>200 OK</code>' . "\n" .
708                         '  <request/>' . "\n" .
709                         '</status>' . "\n",
710                         api_error('xml', new HTTPException\OKException('error_message'), DI::args())
711                 );
712                 */
713         }
714
715         /**
716          * Test the api_error() function with an RSS result.
717          *
718          * @runInSeparateProcess
719          * @preserveGlobalState disabled
720          */
721         public function testApiErrorWithRss()
722         {
723                 // @todo How to test the new API?
724                 /*
725                 self::assertEquals(
726                         '<?xml version="1.0"?>' . "\n" .
727                         '<status xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" ' .
728                         'xmlns:friendica="http://friendi.ca/schema/api/1/" ' .
729                         'xmlns:georss="http://www.georss.org/georss">' . "\n" .
730                         '  <error>error_message</error>' . "\n" .
731                         '  <code>200 OK</code>' . "\n" .
732                         '  <request/>' . "\n" .
733                         '</status>' . "\n",
734                         api_error('rss', new HTTPException\OKException('error_message'), DI::args())
735                 );
736                 */
737         }
738
739         /**
740          * Test the api_error() function with an Atom result.
741          *
742          * @runInSeparateProcess
743          * @preserveGlobalState disabled
744          */
745         public function testApiErrorWithAtom()
746         {
747                 // @todo How to test the new API?
748                 /*
749                 self::assertEquals(
750                         '<?xml version="1.0"?>' . "\n" .
751                         '<status xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" ' .
752                         'xmlns:friendica="http://friendi.ca/schema/api/1/" ' .
753                         'xmlns:georss="http://www.georss.org/georss">' . "\n" .
754                         '  <error>error_message</error>' . "\n" .
755                         '  <code>200 OK</code>' . "\n" .
756                         '  <request/>' . "\n" .
757                         '</status>' . "\n",
758                         api_error('atom', new HTTPException\OKException('error_message'), DI::args())
759                 );
760                 */
761         }
762
763         /**
764          * Test the api_rss_extra() function.
765          *
766          * @return void
767          */
768         public function testApiRssExtra()
769         {
770                 $user_info = ['url' => 'user_url', 'lang' => 'en'];
771                 $result    = api_rss_extra($this->app, [], $user_info);
772                 self::assertEquals($user_info, $result['$user']);
773                 self::assertEquals($user_info['url'], $result['$rss']['alternate']);
774                 self::assertArrayHasKey('self', $result['$rss']);
775                 self::assertArrayHasKey('base', $result['$rss']);
776                 self::assertArrayHasKey('updated', $result['$rss']);
777                 self::assertArrayHasKey('atom_updated', $result['$rss']);
778                 self::assertArrayHasKey('language', $result['$rss']);
779                 self::assertArrayHasKey('logo', $result['$rss']);
780         }
781
782         /**
783          * Test the api_rss_extra() function without any user info.
784          *
785          * @return void
786          */
787         public function testApiRssExtraWithoutUserInfo()
788         {
789                 $result = api_rss_extra($this->app, [], null);
790                 self::assertIsArray($result['$user']);
791                 self::assertArrayHasKey('alternate', $result['$rss']);
792                 self::assertArrayHasKey('self', $result['$rss']);
793                 self::assertArrayHasKey('base', $result['$rss']);
794                 self::assertArrayHasKey('updated', $result['$rss']);
795                 self::assertArrayHasKey('atom_updated', $result['$rss']);
796                 self::assertArrayHasKey('language', $result['$rss']);
797                 self::assertArrayHasKey('logo', $result['$rss']);
798         }
799
800         /**
801          * Test the api_unique_id_to_nurl() function.
802          *
803          * @return void
804          */
805         public function testApiUniqueIdToNurl()
806         {
807                 self::assertFalse(api_unique_id_to_nurl($this->wrongUserId));
808         }
809
810         /**
811          * Test the api_unique_id_to_nurl() function with a correct ID.
812          *
813          * @return void
814          */
815         public function testApiUniqueIdToNurlWithCorrectId()
816         {
817                 self::assertEquals($this->otherUser['nurl'], api_unique_id_to_nurl($this->otherUser['id']));
818         }
819
820         /**
821          * Test the api_get_user() function.
822          *
823          * @return void
824          */
825         public function testApiGetUser()
826         {
827                 $user = api_get_user();
828                 self::assertSelfUser($user);
829                 self::assertEquals('708fa0', $user['profile_sidebar_fill_color']);
830                 self::assertEquals('6fdbe8', $user['profile_link_color']);
831                 self::assertEquals('ededed', $user['profile_background_color']);
832         }
833
834         /**
835          * Test the api_get_user() function with a Frio schema.
836          *
837          * @return void
838          */
839         public function testApiGetUserWithFrioSchema()
840         {
841                 $pConfig = $this->dice->create(IManagePersonalConfigValues::class);
842                 $pConfig->set($this->selfUser['id'], 'frio', 'schema', 'red');
843                 $user = api_get_user();
844                 self::assertSelfUser($user);
845                 self::assertEquals('708fa0', $user['profile_sidebar_fill_color']);
846                 self::assertEquals('6fdbe8', $user['profile_link_color']);
847                 self::assertEquals('ededed', $user['profile_background_color']);
848         }
849
850         /**
851          * Test the api_get_user() function with an empty Frio schema.
852          *
853          * @return void
854          */
855         public function testApiGetUserWithEmptyFrioSchema()
856         {
857                 $pConfig = $this->dice->create(IManagePersonalConfigValues::class);
858                 $pConfig->set($this->selfUser['id'], 'frio', 'schema', '---');
859                 $user = api_get_user();
860                 self::assertSelfUser($user);
861                 self::assertEquals('708fa0', $user['profile_sidebar_fill_color']);
862                 self::assertEquals('6fdbe8', $user['profile_link_color']);
863                 self::assertEquals('ededed', $user['profile_background_color']);
864         }
865
866         /**
867          * Test the api_get_user() function with a custom Frio schema.
868          *
869          * @return void
870          */
871         public function testApiGetUserWithCustomFrioSchema()
872         {
873                 $pConfig = $this->dice->create(IManagePersonalConfigValues::class);
874                 $pConfig->set($this->selfUser['id'], 'frio', 'schema', '---');
875                 $pConfig->set($this->selfUser['id'], 'frio', 'nav_bg', '#123456');
876                 $pConfig->set($this->selfUser['id'], 'frio', 'link_color', '#123456');
877                 $pConfig->set($this->selfUser['id'], 'frio', 'background_color', '#123456');
878                 $user = api_get_user();
879                 self::assertSelfUser($user);
880                 self::assertEquals('123456', $user['profile_sidebar_fill_color']);
881                 self::assertEquals('123456', $user['profile_link_color']);
882                 self::assertEquals('123456', $user['profile_background_color']);
883         }
884
885         /**
886          * Test the api_get_user() function with an user that is not allowed to use the API.
887          *
888          * @runInSeparateProcess
889          * @preserveGlobalState disabled
890          */
891         public function testApiGetUserWithoutApiUser()
892         {
893                 $_SERVER['PHP_AUTH_USER'] = 'Test user';
894                 $_SERVER['PHP_AUTH_PW']   = 'password';
895                 $_SESSION['allow_api']    = false;
896                 self::assertFalse(api_get_user());
897         }
898
899         /**
900          * Test the api_get_user() function with an user ID in a GET parameter.
901          *
902          * @return void
903          */
904         public function testApiGetUserWithGetId()
905         {
906                 $_GET['user_id'] = $this->otherUser['id'];
907                 self::assertOtherUser(api_get_user());
908         }
909
910         /**
911          * Test the api_get_user() function with a wrong user ID in a GET parameter.
912          *
913          * @return void
914          */
915         public function testApiGetUserWithWrongGetId()
916         {
917                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
918                 $_GET['user_id'] = $this->wrongUserId;
919                 self::assertOtherUser(api_get_user());
920         }
921
922         /**
923          * Test the api_get_user() function with an user name in a GET parameter.
924          *
925          * @return void
926          */
927         public function testApiGetUserWithGetName()
928         {
929                 $_GET['screen_name'] = $this->selfUser['nick'];
930                 self::assertSelfUser(api_get_user());
931         }
932
933         /**
934          * Test the api_get_user() function with a profile URL in a GET parameter.
935          *
936          * @return void
937          */
938         public function testApiGetUserWithGetUrl()
939         {
940                 $_GET['profileurl'] = $this->selfUser['nurl'];
941                 self::assertSelfUser(api_get_user());
942         }
943
944         /**
945          * Test the api_get_user() function with an user ID in the API path.
946          *
947          * @return void
948          */
949         public function testApiGetUserWithNumericCalledApi()
950         {
951                 global $called_api;
952                 $called_api         = ['api_path'];
953                 DI::args()->setArgv(['', $this->otherUser['id'] . '.json']);
954                 self::assertOtherUser(api_get_user());
955         }
956
957         /**
958          * Test the api_get_user() function with the $called_api global variable.
959          *
960          * @return void
961          */
962         public function testApiGetUserWithCalledApi()
963         {
964                 global $called_api;
965                 $called_api = ['api', 'api_path'];
966                 self::assertSelfUser(api_get_user());
967         }
968
969         /**
970          * Test the api_get_user() function with a valid user.
971          *
972          * @return void
973          */
974         public function testApiGetUserWithCorrectUser()
975         {
976                 self::assertOtherUser(api_get_user($this->otherUser['id']));
977         }
978
979         /**
980          * Test the api_get_user() function with a wrong user ID.
981          *
982          * @return void
983          */
984         public function testApiGetUserWithWrongUser()
985         {
986                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
987                 self::assertOtherUser(api_get_user($this->wrongUserId));
988         }
989
990         /**
991          * Test the api_get_user() function with a 0 user ID.
992          *
993          * @return void
994          */
995         public function testApiGetUserWithZeroUser()
996         {
997                 self::assertSelfUser(api_get_user(0));
998         }
999
1000         /**
1001          * Test the api_item_get_user() function.
1002          *
1003          * @return void
1004          */
1005         public function testApiItemGetUser()
1006         {
1007                 $users = api_item_get_user($this->app, []);
1008                 self::assertSelfUser($users[0]);
1009         }
1010
1011         /**
1012          * Test the api_item_get_user() function with a different item parent.
1013          *
1014          * @return void
1015          */
1016         public function testApiItemGetUserWithDifferentParent()
1017         {
1018                 $users = api_item_get_user($this->app, ['thr-parent' => 'item_parent', 'uri' => 'item_uri']);
1019                 self::assertSelfUser($users[0]);
1020                 self::assertEquals($users[0], $users[1]);
1021         }
1022
1023         /**
1024          * Test the Arrays::walkRecursive() function.
1025          *
1026          * @return void
1027          */
1028         public function testApiWalkRecursive()
1029         {
1030                 $array = ['item1'];
1031                 self::assertEquals(
1032                         $array,
1033                         Arrays::walkRecursive(
1034                                 $array,
1035                                 function () {
1036                                         // Should we test this with a callback that actually does something?
1037                                         return true;
1038                                 }
1039                         )
1040                 );
1041         }
1042
1043         /**
1044          * Test the Arrays::walkRecursive() function with an array.
1045          *
1046          * @return void
1047          */
1048         public function testApiWalkRecursiveWithArray()
1049         {
1050                 $array = [['item1'], ['item2']];
1051                 self::assertEquals(
1052                         $array,
1053                         Arrays::walkRecursive(
1054                                 $array,
1055                                 function () {
1056                                         // Should we test this with a callback that actually does something?
1057                                         return true;
1058                                 }
1059                         )
1060                 );
1061         }
1062
1063         /**
1064          * Test the BaseApi::reformatXML() function.
1065          *
1066          * @return void
1067          */
1068         public function testApiReformatXml()
1069         {
1070                 $item = true;
1071                 $key  = '';
1072                 self::assertTrue(BaseApi::reformatXML($item, $key));
1073                 self::assertEquals('true', $item);
1074         }
1075
1076         /**
1077          * Test the BaseApi::reformatXML() function with a statusnet_api key.
1078          *
1079          * @return void
1080          */
1081         public function testApiReformatXmlWithStatusnetKey()
1082         {
1083                 $item = '';
1084                 $key  = 'statusnet_api';
1085                 self::assertTrue(BaseApi::reformatXML($item, $key));
1086                 self::assertEquals('statusnet:api', $key);
1087         }
1088
1089         /**
1090          * Test the BaseApi::reformatXML() function with a friendica_api key.
1091          *
1092          * @return void
1093          */
1094         public function testApiReformatXmlWithFriendicaKey()
1095         {
1096                 $item = '';
1097                 $key  = 'friendica_api';
1098                 self::assertTrue(BaseApi::reformatXML($item, $key));
1099                 self::assertEquals('friendica:api', $key);
1100         }
1101
1102         /**
1103          * Test the BaseApi::createXML() function.
1104          *
1105          * @return void
1106          */
1107         public function testApiCreateXml()
1108         {
1109                 self::assertEquals(
1110                         '<?xml version="1.0"?>' . "\n" .
1111                         '<root_element xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" ' .
1112                         'xmlns:friendica="http://friendi.ca/schema/api/1/" ' .
1113                         'xmlns:georss="http://www.georss.org/georss">' . "\n" .
1114                         '  <data>some_data</data>' . "\n" .
1115                         '</root_element>' . "\n",
1116                         BaseApi::createXML(['data' => ['some_data']], 'root_element')
1117                 );
1118         }
1119
1120         /**
1121          * Test the BaseApi::createXML() function without any XML namespace.
1122          *
1123          * @return void
1124          */
1125         public function testApiCreateXmlWithoutNamespaces()
1126         {
1127                 self::assertEquals(
1128                         '<?xml version="1.0"?>' . "\n" .
1129                         '<ok>' . "\n" .
1130                         '  <data>some_data</data>' . "\n" .
1131                         '</ok>' . "\n",
1132                         BaseApi::createXML(['data' => ['some_data']], 'ok')
1133                 );
1134         }
1135
1136         /**
1137          * Test the BaseApi::formatData() function.
1138          *
1139          * @return void
1140          */
1141         public function testApiFormatData()
1142         {
1143                 $data = ['some_data'];
1144                 self::assertEquals($data, BaseApi::formatData('root_element', 'json', $data));
1145         }
1146
1147         /**
1148          * Test the BaseApi::formatData() function with an XML result.
1149          *
1150          * @return void
1151          */
1152         public function testApiFormatDataWithXml()
1153         {
1154                 self::assertEquals(
1155                         '<?xml version="1.0"?>' . "\n" .
1156                         '<root_element xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" ' .
1157                         'xmlns:friendica="http://friendi.ca/schema/api/1/" ' .
1158                         'xmlns:georss="http://www.georss.org/georss">' . "\n" .
1159                         '  <data>some_data</data>' . "\n" .
1160                         '</root_element>' . "\n",
1161                         BaseApi::formatData('root_element', 'xml', ['data' => ['some_data']])
1162                 );
1163         }
1164
1165         /**
1166          * Test the api_account_verify_credentials() function.
1167          *
1168          * @return void
1169          */
1170         public function testApiAccountVerifyCredentials()
1171         {
1172                 self::assertArrayHasKey('user', api_account_verify_credentials('json'));
1173         }
1174
1175         /**
1176          * Test the api_account_verify_credentials() function without an authenticated user.
1177          *
1178          * @return void
1179          */
1180         public function testApiAccountVerifyCredentialsWithoutAuthenticatedUser()
1181         {
1182                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
1183                 $_SESSION['authenticated'] = false;
1184                 api_account_verify_credentials('json');
1185         }
1186
1187         /**
1188          * Test the requestdata() function.
1189          *
1190          * @return void
1191          */
1192         public function testRequestdata()
1193         {
1194                 self::assertNull(requestdata('variable_name'));
1195         }
1196
1197         /**
1198          * Test the requestdata() function with a POST parameter.
1199          *
1200          * @return void
1201          */
1202         public function testRequestdataWithPost()
1203         {
1204                 $_POST['variable_name'] = 'variable_value';
1205                 self::assertEquals('variable_value', requestdata('variable_name'));
1206         }
1207
1208         /**
1209          * Test the requestdata() function with a GET parameter.
1210          *
1211          * @return void
1212          */
1213         public function testRequestdataWithGet()
1214         {
1215                 $_GET['variable_name'] = 'variable_value';
1216                 self::assertEquals('variable_value', requestdata('variable_name'));
1217         }
1218
1219         /**
1220          * Test the api_statuses_mediap() function.
1221          *
1222          * @return void
1223          */
1224         public function testApiStatusesMediap()
1225         {
1226                 DI::args()->setArgc(2);
1227
1228                 $_FILES         = [
1229                         'media' => [
1230                                 'id'       => 666,
1231                                 'size'     => 666,
1232                                 'width'    => 666,
1233                                 'height'   => 666,
1234                                 'tmp_name' => $this->getTempImage(),
1235                                 'name'     => 'spacer.png',
1236                                 'type'     => 'image/png'
1237                         ]
1238                 ];
1239                 $_GET['status'] = '<b>Status content</b>';
1240
1241                 $result = api_statuses_mediap('json');
1242                 self::assertStatus($result['status']);
1243         }
1244
1245         /**
1246          * Test the api_statuses_mediap() function without an authenticated user.
1247          *
1248          * @return void
1249          */
1250         public function testApiStatusesMediapWithoutAuthenticatedUser()
1251         {
1252                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
1253                 $_SESSION['authenticated'] = false;
1254                 api_statuses_mediap('json');
1255         }
1256
1257         /**
1258          * Test the api_statuses_update() function.
1259          *
1260          * @return void
1261          */
1262         public function testApiStatusesUpdate()
1263         {
1264                 $_GET['status']                = 'Status content #friendica';
1265                 $_GET['in_reply_to_status_id'] = -1;
1266                 $_GET['lat']                   = 48;
1267                 $_GET['long']                  = 7;
1268                 $_FILES                        = [
1269                         'media' => [
1270                                 'id'       => 666,
1271                                 'size'     => 666,
1272                                 'width'    => 666,
1273                                 'height'   => 666,
1274                                 'tmp_name' => $this->getTempImage(),
1275                                 'name'     => 'spacer.png',
1276                                 'type'     => 'image/png'
1277                         ]
1278                 ];
1279
1280                 $result = api_statuses_update('json');
1281                 self::assertStatus($result['status']);
1282         }
1283
1284         /**
1285          * Test the api_statuses_update() function with an HTML status.
1286          *
1287          * @return void
1288          */
1289         public function testApiStatusesUpdateWithHtml()
1290         {
1291                 $_GET['htmlstatus'] = '<b>Status content</b>';
1292
1293                 $result = api_statuses_update('json');
1294                 self::assertStatus($result['status']);
1295         }
1296
1297         /**
1298          * Test the api_statuses_update() function without an authenticated user.
1299          *
1300          * @return void
1301          */
1302         public function testApiStatusesUpdateWithoutAuthenticatedUser()
1303         {
1304                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
1305                 $_SESSION['authenticated'] = false;
1306                 api_statuses_update('json');
1307         }
1308
1309         /**
1310          * Test the api_statuses_update() function with a parent status.
1311          *
1312          * @return void
1313          */
1314         public function testApiStatusesUpdateWithParent()
1315         {
1316                 $this->markTestIncomplete('This triggers an exit() somewhere and kills PHPUnit.');
1317         }
1318
1319         /**
1320          * Test the api_statuses_update() function with a media_ids parameter.
1321          *
1322          * @return void
1323          */
1324         public function testApiStatusesUpdateWithMediaIds()
1325         {
1326                 $this->markTestIncomplete();
1327         }
1328
1329         /**
1330          * Test the api_statuses_update() function with the throttle limit reached.
1331          *
1332          * @return void
1333          */
1334         public function testApiStatusesUpdateWithDayThrottleReached()
1335         {
1336                 $this->markTestIncomplete();
1337         }
1338
1339         /**
1340          * Test the api_media_upload() function.
1341          * @runInSeparateProcess
1342          * @preserveGlobalState disabled
1343          */
1344         public function testApiMediaUpload()
1345         {
1346                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
1347                 api_media_upload();
1348         }
1349
1350         /**
1351          * Test the api_media_upload() function without an authenticated user.
1352          *
1353          * @return void
1354          */
1355         public function testApiMediaUploadWithoutAuthenticatedUser()
1356         {
1357                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
1358                 $_SESSION['authenticated'] = false;
1359                 api_media_upload();
1360         }
1361
1362         /**
1363          * Test the api_media_upload() function with an invalid uploaded media.
1364          *
1365          * @return void
1366          */
1367         public function testApiMediaUploadWithMedia()
1368         {
1369                 $this->expectException(\Friendica\Network\HTTPException\InternalServerErrorException::class);
1370                 $_FILES = [
1371                         'media' => [
1372                                 'id'       => 666,
1373                                 'tmp_name' => 'tmp_name'
1374                         ]
1375                 ];
1376                 api_media_upload();
1377         }
1378
1379         /**
1380          * Test the api_media_upload() function with an valid uploaded media.
1381          *
1382          * @return void
1383          */
1384         public function testApiMediaUploadWithValidMedia()
1385         {
1386                 $_FILES    = [
1387                         'media' => [
1388                                 'id'       => 666,
1389                                 'size'     => 666,
1390                                 'width'    => 666,
1391                                 'height'   => 666,
1392                                 'tmp_name' => $this->getTempImage(),
1393                                 'name'     => 'spacer.png',
1394                                 'type'     => 'image/png'
1395                         ]
1396                 ];
1397                 $app       = DI::app();
1398                 DI::args()->setArgc(2);
1399
1400                 $result = api_media_upload();
1401                 self::assertEquals('image/png', $result['media']['image']['image_type']);
1402                 self::assertEquals(1, $result['media']['image']['w']);
1403                 self::assertEquals(1, $result['media']['image']['h']);
1404                 self::assertNotEmpty($result['media']['image']['friendica_preview_url']);
1405         }
1406
1407         /**
1408          * Test the api_status_show() function.
1409          */
1410         public function testApiStatusShowWithJson()
1411         {
1412                 $result = api_status_show('json', 1);
1413                 self::assertStatus($result['status']);
1414         }
1415
1416         /**
1417          * Test the api_status_show() function with an XML result.
1418          */
1419         public function testApiStatusShowWithXml()
1420         {
1421                 $result = api_status_show('xml', 1);
1422                 self::assertXml($result, 'statuses');
1423         }
1424
1425         /**
1426          * Test the api_get_last_status() function
1427          */
1428         public function testApiGetLastStatus()
1429         {
1430                 $item = api_get_last_status($this->selfUser['id'], $this->selfUser['id']);
1431
1432                 self::assertNotNull($item);
1433         }
1434
1435         /**
1436          * Test the api_users_show() function.
1437          *
1438          * @return void
1439          */
1440         public function testApiUsersShow()
1441         {
1442                 $result = api_users_show('json');
1443                 // We can't use assertSelfUser() here because the user object is missing some properties.
1444                 self::assertEquals($this->selfUser['id'], $result['user']['cid']);
1445                 self::assertEquals('DFRN', $result['user']['location']);
1446                 self::assertEquals($this->selfUser['name'], $result['user']['name']);
1447                 self::assertEquals($this->selfUser['nick'], $result['user']['screen_name']);
1448                 self::assertEquals('dfrn', $result['user']['network']);
1449                 self::assertTrue($result['user']['verified']);
1450         }
1451
1452         /**
1453          * Test the api_users_show() function with an XML result.
1454          *
1455          * @return void
1456          */
1457         public function testApiUsersShowWithXml()
1458         {
1459                 $result = api_users_show('xml');
1460                 self::assertXml($result, 'statuses');
1461         }
1462
1463         /**
1464          * Test the api_users_search() function.
1465          *
1466          * @return void
1467          */
1468         public function testApiUsersSearch()
1469         {
1470                 $_GET['q'] = 'othercontact';
1471                 $result    = api_users_search('json');
1472                 self::assertOtherUser($result['users'][0]);
1473         }
1474
1475         /**
1476          * Test the api_users_search() function with an XML result.
1477          *
1478          * @return void
1479          */
1480         public function testApiUsersSearchWithXml()
1481         {
1482                 $_GET['q'] = 'othercontact';
1483                 $result    = api_users_search('xml');
1484                 self::assertXml($result, 'users');
1485         }
1486
1487         /**
1488          * Test the api_users_search() function without a GET q parameter.
1489          *
1490          * @return void
1491          */
1492         public function testApiUsersSearchWithoutQuery()
1493         {
1494                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
1495                 api_users_search('json');
1496         }
1497
1498         /**
1499          * Test the api_users_lookup() function.
1500          *
1501          * @return void
1502          */
1503         public function testApiUsersLookup()
1504         {
1505                 $this->expectException(\Friendica\Network\HTTPException\NotFoundException::class);
1506                 api_users_lookup('json');
1507         }
1508
1509         /**
1510          * Test the api_users_lookup() function with an user ID.
1511          *
1512          * @return void
1513          */
1514         public function testApiUsersLookupWithUserId()
1515         {
1516                 $_REQUEST['user_id'] = $this->otherUser['id'];
1517                 $result              = api_users_lookup('json');
1518                 self::assertOtherUser($result['users'][0]);
1519         }
1520
1521         /**
1522          * Test the api_search() function.
1523          *
1524          * @return void
1525          */
1526         public function testApiSearch()
1527         {
1528                 $_REQUEST['q']      = 'reply';
1529                 $_REQUEST['max_id'] = 10;
1530                 $result             = api_search('json');
1531                 foreach ($result['status'] as $status) {
1532                         self::assertStatus($status);
1533                         self::assertStringContainsStringIgnoringCase('reply', $status['text'], '', true);
1534                 }
1535         }
1536
1537         /**
1538          * Test the api_search() function a count parameter.
1539          *
1540          * @return void
1541          */
1542         public function testApiSearchWithCount()
1543         {
1544                 $_REQUEST['q']     = 'reply';
1545                 $_REQUEST['count'] = 20;
1546                 $result            = api_search('json');
1547                 foreach ($result['status'] as $status) {
1548                         self::assertStatus($status);
1549                         self::assertStringContainsStringIgnoringCase('reply', $status['text'], '', true);
1550                 }
1551         }
1552
1553         /**
1554          * Test the api_search() function with an rpp parameter.
1555          *
1556          * @return void
1557          */
1558         public function testApiSearchWithRpp()
1559         {
1560                 $_REQUEST['q']   = 'reply';
1561                 $_REQUEST['rpp'] = 20;
1562                 $result          = api_search('json');
1563                 foreach ($result['status'] as $status) {
1564                         self::assertStatus($status);
1565                         self::assertStringContainsStringIgnoringCase('reply', $status['text'], '', true);
1566                 }
1567         }
1568
1569         /**
1570          * Test the api_search() function with an q parameter contains hashtag.
1571          * @doesNotPerformAssertions
1572          */
1573         public function testApiSearchWithHashtag()
1574         {
1575                 $_REQUEST['q'] = '%23friendica';
1576                 $result        = api_search('json');
1577                 foreach ($result['status'] as $status) {
1578                         self::assertStatus($status);
1579                         self::assertStringContainsStringIgnoringCase('#friendica', $status['text'], '', true);
1580                 }
1581         }
1582
1583         /**
1584          * Test the api_search() function with an exclude_replies parameter.
1585          * @doesNotPerformAssertions
1586          */
1587         public function testApiSearchWithExcludeReplies()
1588         {
1589                 $_REQUEST['max_id']          = 10;
1590                 $_REQUEST['exclude_replies'] = true;
1591                 $_REQUEST['q']               = 'friendica';
1592                 $result                      = api_search('json');
1593                 foreach ($result['status'] as $status) {
1594                         self::assertStatus($status);
1595                 }
1596         }
1597
1598         /**
1599          * Test the api_search() function without an authenticated user.
1600          *
1601          * @return void
1602          */
1603         public function testApiSearchWithUnallowedUser()
1604         {
1605                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
1606                 $_SESSION['allow_api'] = false;
1607                 $_GET['screen_name']   = $this->selfUser['nick'];
1608                 api_search('json');
1609         }
1610
1611         /**
1612          * Test the api_search() function without any GET query parameter.
1613          *
1614          * @return void
1615          */
1616         public function testApiSearchWithoutQuery()
1617         {
1618                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
1619                 api_search('json');
1620         }
1621
1622         /**
1623          * Test the api_statuses_home_timeline() function.
1624          *
1625          * @return void
1626          */
1627         public function testApiStatusesHomeTimeline()
1628         {
1629                 $_REQUEST['max_id']          = 10;
1630                 $_REQUEST['exclude_replies'] = true;
1631                 $_REQUEST['conversation_id'] = 1;
1632                 $result                      = api_statuses_home_timeline('json');
1633                 self::assertNotEmpty($result['status']);
1634                 foreach ($result['status'] as $status) {
1635                         self::assertStatus($status);
1636                 }
1637         }
1638
1639         /**
1640          * Test the api_statuses_home_timeline() function with a negative page parameter.
1641          *
1642          * @return void
1643          */
1644         public function testApiStatusesHomeTimelineWithNegativePage()
1645         {
1646                 $_REQUEST['page'] = -2;
1647                 $result           = api_statuses_home_timeline('json');
1648                 self::assertNotEmpty($result['status']);
1649                 foreach ($result['status'] as $status) {
1650                         self::assertStatus($status);
1651                 }
1652         }
1653
1654         /**
1655          * Test the api_statuses_home_timeline() with an unallowed user.
1656          *
1657          * @return void
1658          */
1659         public function testApiStatusesHomeTimelineWithUnallowedUser()
1660         {
1661                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
1662                 $_SESSION['allow_api'] = false;
1663                 $_GET['screen_name']   = $this->selfUser['nick'];
1664                 api_statuses_home_timeline('json');
1665         }
1666
1667         /**
1668          * Test the api_statuses_home_timeline() function with an RSS result.
1669          *
1670          * @return void
1671          */
1672         public function testApiStatusesHomeTimelineWithRss()
1673         {
1674                 $result = api_statuses_home_timeline('rss');
1675                 self::assertXml($result, 'statuses');
1676         }
1677
1678         /**
1679          * Test the api_statuses_public_timeline() function.
1680          *
1681          * @return void
1682          */
1683         public function testApiStatusesPublicTimeline()
1684         {
1685                 $_REQUEST['max_id']          = 10;
1686                 $_REQUEST['conversation_id'] = 1;
1687                 $result                      = api_statuses_public_timeline('json');
1688                 self::assertNotEmpty($result['status']);
1689                 foreach ($result['status'] as $status) {
1690                         self::assertStatus($status);
1691                 }
1692         }
1693
1694         /**
1695          * Test the api_statuses_public_timeline() function with the exclude_replies parameter.
1696          *
1697          * @return void
1698          */
1699         public function testApiStatusesPublicTimelineWithExcludeReplies()
1700         {
1701                 $_REQUEST['max_id']          = 10;
1702                 $_REQUEST['exclude_replies'] = true;
1703                 $result                      = api_statuses_public_timeline('json');
1704                 self::assertNotEmpty($result['status']);
1705                 foreach ($result['status'] as $status) {
1706                         self::assertStatus($status);
1707                 }
1708         }
1709
1710         /**
1711          * Test the api_statuses_public_timeline() function with a negative page parameter.
1712          *
1713          * @return void
1714          */
1715         public function testApiStatusesPublicTimelineWithNegativePage()
1716         {
1717                 $_REQUEST['page'] = -2;
1718                 $result           = api_statuses_public_timeline('json');
1719                 self::assertNotEmpty($result['status']);
1720                 foreach ($result['status'] as $status) {
1721                         self::assertStatus($status);
1722                 }
1723         }
1724
1725         /**
1726          * Test the api_statuses_public_timeline() function with an unallowed user.
1727          *
1728          * @return void
1729          */
1730         public function testApiStatusesPublicTimelineWithUnallowedUser()
1731         {
1732                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
1733                 $_SESSION['allow_api'] = false;
1734                 $_GET['screen_name']   = $this->selfUser['nick'];
1735                 api_statuses_public_timeline('json');
1736         }
1737
1738         /**
1739          * Test the api_statuses_public_timeline() function with an RSS result.
1740          *
1741          * @return void
1742          */
1743         public function testApiStatusesPublicTimelineWithRss()
1744         {
1745                 $result = api_statuses_public_timeline('rss');
1746                 self::assertXml($result, 'statuses');
1747         }
1748
1749         /**
1750          * Test the api_statuses_networkpublic_timeline() function.
1751          *
1752          * @return void
1753          */
1754         public function testApiStatusesNetworkpublicTimeline()
1755         {
1756                 $_REQUEST['max_id'] = 10;
1757                 $result             = api_statuses_networkpublic_timeline('json');
1758                 self::assertNotEmpty($result['status']);
1759                 foreach ($result['status'] as $status) {
1760                         self::assertStatus($status);
1761                 }
1762         }
1763
1764         /**
1765          * Test the api_statuses_networkpublic_timeline() function with a negative page parameter.
1766          *
1767          * @return void
1768          */
1769         public function testApiStatusesNetworkpublicTimelineWithNegativePage()
1770         {
1771                 $_REQUEST['page'] = -2;
1772                 $result           = api_statuses_networkpublic_timeline('json');
1773                 self::assertNotEmpty($result['status']);
1774                 foreach ($result['status'] as $status) {
1775                         self::assertStatus($status);
1776                 }
1777         }
1778
1779         /**
1780          * Test the api_statuses_networkpublic_timeline() function with an unallowed user.
1781          *
1782          * @return void
1783          */
1784         public function testApiStatusesNetworkpublicTimelineWithUnallowedUser()
1785         {
1786                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
1787                 $_SESSION['allow_api'] = false;
1788                 $_GET['screen_name']   = $this->selfUser['nick'];
1789                 api_statuses_networkpublic_timeline('json');
1790         }
1791
1792         /**
1793          * Test the api_statuses_networkpublic_timeline() function with an RSS result.
1794          *
1795          * @return void
1796          */
1797         public function testApiStatusesNetworkpublicTimelineWithRss()
1798         {
1799                 $result = api_statuses_networkpublic_timeline('rss');
1800                 self::assertXml($result, 'statuses');
1801         }
1802
1803         /**
1804          * Test the api_statuses_show() function.
1805          *
1806          * @return void
1807          */
1808         public function testApiStatusesShow()
1809         {
1810                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
1811                 api_statuses_show('json');
1812         }
1813
1814         /**
1815          * Test the api_statuses_show() function with an ID.
1816          *
1817          * @return void
1818          */
1819         public function testApiStatusesShowWithId()
1820         {
1821                 DI::args()->setArgv(['', '', '', 1]);
1822                 $result = api_statuses_show('json');
1823                 self::assertStatus($result['status']);
1824         }
1825
1826         /**
1827          * Test the api_statuses_show() function with the conversation parameter.
1828          *
1829          * @return void
1830          */
1831         public function testApiStatusesShowWithConversation()
1832         {
1833                 DI::args()->setArgv(['', '', '', 1]);
1834                 $_REQUEST['conversation'] = 1;
1835                 $result                   = api_statuses_show('json');
1836                 self::assertNotEmpty($result['status']);
1837                 foreach ($result['status'] as $status) {
1838                         self::assertStatus($status);
1839                 }
1840         }
1841
1842         /**
1843          * Test the api_statuses_show() function with an unallowed user.
1844          *
1845          * @return void
1846          */
1847         public function testApiStatusesShowWithUnallowedUser()
1848         {
1849                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
1850                 $_SESSION['allow_api'] = false;
1851                 $_GET['screen_name']   = $this->selfUser['nick'];
1852                 api_statuses_show('json');
1853         }
1854
1855         /**
1856          * Test the api_conversation_show() function.
1857          *
1858          * @return void
1859          */
1860         public function testApiConversationShow()
1861         {
1862                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
1863                 api_conversation_show('json');
1864         }
1865
1866         /**
1867          * Test the api_conversation_show() function with an ID.
1868          *
1869          * @return void
1870          */
1871         public function testApiConversationShowWithId()
1872         {
1873                 DI::args()->setArgv(['', '', '', 1]);
1874                 $_REQUEST['max_id'] = 10;
1875                 $_REQUEST['page']   = -2;
1876                 $result             = api_conversation_show('json');
1877                 self::assertNotEmpty($result['status']);
1878                 foreach ($result['status'] as $status) {
1879                         self::assertStatus($status);
1880                 }
1881         }
1882
1883         /**
1884          * Test the api_conversation_show() function with an unallowed user.
1885          *
1886          * @return void
1887          */
1888         public function testApiConversationShowWithUnallowedUser()
1889         {
1890                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
1891                 $_SESSION['allow_api'] = false;
1892                 $_GET['screen_name']   = $this->selfUser['nick'];
1893                 api_conversation_show('json');
1894         }
1895
1896         /**
1897          * Test the api_statuses_repeat() function.
1898          *
1899          * @return void
1900          */
1901         public function testApiStatusesRepeat()
1902         {
1903                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
1904                 api_statuses_repeat('json');
1905         }
1906
1907         /**
1908          * Test the api_statuses_repeat() function without an authenticated user.
1909          *
1910          * @return void
1911          */
1912         public function testApiStatusesRepeatWithoutAuthenticatedUser()
1913         {
1914                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
1915                 $_SESSION['authenticated'] = false;
1916                 api_statuses_repeat('json');
1917         }
1918
1919         /**
1920          * Test the api_statuses_repeat() function with an ID.
1921          *
1922          * @return void
1923          */
1924         public function testApiStatusesRepeatWithId()
1925         {
1926                 DI::args()->setArgv(['', '', '', 1]);
1927                 $result = api_statuses_repeat('json');
1928                 self::assertStatus($result['status']);
1929
1930                 // Also test with a shared status
1931                 DI::args()->setArgv(['', '', '', 5]);
1932                 $result = api_statuses_repeat('json');
1933                 self::assertStatus($result['status']);
1934         }
1935
1936         /**
1937          * Test the api_statuses_destroy() function.
1938          *
1939          * @return void
1940          */
1941         public function testApiStatusesDestroy()
1942         {
1943                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
1944                 api_statuses_destroy('json');
1945         }
1946
1947         /**
1948          * Test the api_statuses_destroy() function without an authenticated user.
1949          *
1950          * @return void
1951          */
1952         public function testApiStatusesDestroyWithoutAuthenticatedUser()
1953         {
1954                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
1955                 $_SESSION['authenticated'] = false;
1956                 api_statuses_destroy('json');
1957         }
1958
1959         /**
1960          * Test the api_statuses_destroy() function with an ID.
1961          *
1962          * @return void
1963          */
1964         public function testApiStatusesDestroyWithId()
1965         {
1966                 DI::args()->setArgv(['', '', '', 1]);
1967                 $result = api_statuses_destroy('json');
1968                 self::assertStatus($result['status']);
1969         }
1970
1971         /**
1972          * Test the api_statuses_mentions() function.
1973          *
1974          * @return void
1975          */
1976         public function testApiStatusesMentions()
1977         {
1978                 $this->app->setLoggedInUserNickname($this->selfUser['nick']);
1979                 $_REQUEST['max_id'] = 10;
1980                 $result             = api_statuses_mentions('json');
1981                 self::assertEmpty($result['status']);
1982                 // We should test with mentions in the database.
1983         }
1984
1985         /**
1986          * Test the api_statuses_mentions() function with a negative page parameter.
1987          *
1988          * @return void
1989          */
1990         public function testApiStatusesMentionsWithNegativePage()
1991         {
1992                 $_REQUEST['page'] = -2;
1993                 $result           = api_statuses_mentions('json');
1994                 self::assertEmpty($result['status']);
1995         }
1996
1997         /**
1998          * Test the api_statuses_mentions() function with an unallowed user.
1999          *
2000          * @return void
2001          */
2002         public function testApiStatusesMentionsWithUnallowedUser()
2003         {
2004                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
2005                 $_SESSION['allow_api'] = false;
2006                 $_GET['screen_name']   = $this->selfUser['nick'];
2007                 api_statuses_mentions('json');
2008         }
2009
2010         /**
2011          * Test the api_statuses_mentions() function with an RSS result.
2012          *
2013          * @return void
2014          */
2015         public function testApiStatusesMentionsWithRss()
2016         {
2017                 $result = api_statuses_mentions('rss');
2018                 self::assertXml($result, 'statuses');
2019         }
2020
2021         /**
2022          * Test the api_statuses_user_timeline() function.
2023          *
2024          * @return void
2025          */
2026         public function testApiStatusesUserTimeline()
2027         {
2028                 $_REQUEST['max_id']          = 10;
2029                 $_REQUEST['exclude_replies'] = true;
2030                 $_REQUEST['conversation_id'] = 1;
2031                 $result                      = api_statuses_user_timeline('json');
2032                 self::assertNotEmpty($result['status']);
2033                 foreach ($result['status'] as $status) {
2034                         self::assertStatus($status);
2035                 }
2036         }
2037
2038         /**
2039          * Test the api_statuses_user_timeline() function with a negative page parameter.
2040          *
2041          * @return void
2042          */
2043         public function testApiStatusesUserTimelineWithNegativePage()
2044         {
2045                 $_REQUEST['page'] = -2;
2046                 $result           = api_statuses_user_timeline('json');
2047                 self::assertNotEmpty($result['status']);
2048                 foreach ($result['status'] as $status) {
2049                         self::assertStatus($status);
2050                 }
2051         }
2052
2053         /**
2054          * Test the api_statuses_user_timeline() function with an RSS result.
2055          *
2056          * @return void
2057          */
2058         public function testApiStatusesUserTimelineWithRss()
2059         {
2060                 $result = api_statuses_user_timeline('rss');
2061                 self::assertXml($result, 'statuses');
2062         }
2063
2064         /**
2065          * Test the api_statuses_user_timeline() function with an unallowed user.
2066          *
2067          * @return void
2068          */
2069         public function testApiStatusesUserTimelineWithUnallowedUser()
2070         {
2071                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
2072                 $_SESSION['allow_api'] = false;
2073                 $_GET['screen_name']   = $this->selfUser['nick'];
2074                 api_statuses_user_timeline('json');
2075         }
2076
2077         /**
2078          * Test the api_favorites_create_destroy() function.
2079          *
2080          * @return void
2081          */
2082         public function testApiFavoritesCreateDestroy()
2083         {
2084                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
2085                 DI::args()->setArgv(['api', '1.1', 'favorites', 'create']);
2086                 api_favorites_create_destroy('json');
2087         }
2088
2089         /**
2090          * Test the api_favorites_create_destroy() function with an invalid ID.
2091          *
2092          * @return void
2093          */
2094         public function testApiFavoritesCreateDestroyWithInvalidId()
2095         {
2096                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
2097                 DI::args()->setArgv(['api', '1.1', 'favorites', 'create', '12.json']);
2098                 api_favorites_create_destroy('json');
2099         }
2100
2101         /**
2102          * Test the api_favorites_create_destroy() function with an invalid action.
2103          *
2104          * @return void
2105          */
2106         public function testApiFavoritesCreateDestroyWithInvalidAction()
2107         {
2108                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
2109                 DI::args()->setArgv(['api', '1.1', 'favorites', 'change.json']);
2110                 $_REQUEST['id'] = 1;
2111                 api_favorites_create_destroy('json');
2112         }
2113
2114         /**
2115          * Test the api_favorites_create_destroy() function with the create action.
2116          *
2117          * @return void
2118          */
2119         public function testApiFavoritesCreateDestroyWithCreateAction()
2120         {
2121                 DI::args()->setArgv(['api', '1.1', 'favorites', 'create.json']);
2122                 $_REQUEST['id'] = 3;
2123                 $result         = api_favorites_create_destroy('json');
2124                 self::assertStatus($result['status']);
2125         }
2126
2127         /**
2128          * Test the api_favorites_create_destroy() function with the create action and an RSS result.
2129          *
2130          * @return void
2131          */
2132         public function testApiFavoritesCreateDestroyWithCreateActionAndRss()
2133         {
2134                 DI::args()->setArgv(['api', '1.1', 'favorites', 'create.rss']);
2135                 $_REQUEST['id'] = 3;
2136                 $result         = api_favorites_create_destroy('rss');
2137                 self::assertXml($result, 'status');
2138         }
2139
2140         /**
2141          * Test the api_favorites_create_destroy() function with the destroy action.
2142          *
2143          * @return void
2144          */
2145         public function testApiFavoritesCreateDestroyWithDestroyAction()
2146         {
2147                 DI::args()->setArgv(['api', '1.1', 'favorites', 'destroy.json']);
2148                 $_REQUEST['id'] = 3;
2149                 $result         = api_favorites_create_destroy('json');
2150                 self::assertStatus($result['status']);
2151         }
2152
2153         /**
2154          * Test the api_favorites_create_destroy() function without an authenticated user.
2155          *
2156          * @return void
2157          */
2158         public function testApiFavoritesCreateDestroyWithoutAuthenticatedUser()
2159         {
2160                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
2161                 DI::args()->setArgv(['api', '1.1', 'favorites', 'create.json']);
2162                 $_SESSION['authenticated'] = false;
2163                 api_favorites_create_destroy('json');
2164         }
2165
2166         /**
2167          * Test the api_favorites() function.
2168          *
2169          * @return void
2170          */
2171         public function testApiFavorites()
2172         {
2173                 $_REQUEST['page']   = -1;
2174                 $_REQUEST['max_id'] = 10;
2175                 $result             = api_favorites('json');
2176                 foreach ($result['status'] as $status) {
2177                         self::assertStatus($status);
2178                 }
2179         }
2180
2181         /**
2182          * Test the api_favorites() function with an RSS result.
2183          *
2184          * @return void
2185          */
2186         public function testApiFavoritesWithRss()
2187         {
2188                 $result = api_favorites('rss');
2189                 self::assertXml($result, 'statuses');
2190         }
2191
2192         /**
2193          * Test the api_favorites() function with an unallowed user.
2194          *
2195          * @return void
2196          */
2197         public function testApiFavoritesWithUnallowedUser()
2198         {
2199                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
2200                 $_SESSION['allow_api'] = false;
2201                 $_GET['screen_name']   = $this->selfUser['nick'];
2202                 api_favorites('json');
2203         }
2204
2205         /**
2206          * Test the api_format_messages() function.
2207          *
2208          * @return void
2209          */
2210         public function testApiFormatMessages()
2211         {
2212                 $result = api_format_messages(
2213                         ['id' => 1, 'uri-id' => 1, 'title' => 'item_title', 'body' => '[b]item_body[/b]'],
2214                         ['id' => 2, 'uri-id' => 2, 'screen_name' => 'recipient_name'],
2215                         ['id' => 3, 'uri-id' => 2, 'screen_name' => 'sender_name']
2216                 );
2217                 self::assertEquals('item_title' . "\n" . 'item_body', $result['text']);
2218                 self::assertEquals(1, $result['id']);
2219                 self::assertEquals(2, $result['recipient_id']);
2220                 self::assertEquals(3, $result['sender_id']);
2221                 self::assertEquals('recipient_name', $result['recipient_screen_name']);
2222                 self::assertEquals('sender_name', $result['sender_screen_name']);
2223         }
2224
2225         /**
2226          * Test the api_format_messages() function with HTML.
2227          *
2228          * @return void
2229          */
2230         public function testApiFormatMessagesWithHtmlText()
2231         {
2232                 $_GET['getText'] = 'html';
2233                 $result          = api_format_messages(
2234                         ['id' => 1, 'uri-id' => 1, 'title' => 'item_title', 'body' => '[b]item_body[/b]'],
2235                         ['id' => 2, 'uri-id' => 2, 'screen_name' => 'recipient_name'],
2236                         ['id' => 3, 'uri-id' => 3, 'screen_name' => 'sender_name']
2237                 );
2238                 self::assertEquals('item_title', $result['title']);
2239                 self::assertEquals('<strong>item_body</strong>', $result['text']);
2240         }
2241
2242         /**
2243          * Test the api_format_messages() function with plain text.
2244          *
2245          * @return void
2246          */
2247         public function testApiFormatMessagesWithPlainText()
2248         {
2249                 $_GET['getText'] = 'plain';
2250                 $result          = api_format_messages(
2251                         ['id' => 1, 'uri-id' => 1, 'title' => 'item_title', 'body' => '[b]item_body[/b]'],
2252                         ['id' => 2, 'uri-id' => 2, 'screen_name' => 'recipient_name'],
2253                         ['id' => 3, 'uri-id' => 3, 'screen_name' => 'sender_name']
2254                 );
2255                 self::assertEquals('item_title', $result['title']);
2256                 self::assertEquals('item_body', $result['text']);
2257         }
2258
2259         /**
2260          * Test the api_format_messages() function with the getUserObjects GET parameter set to false.
2261          *
2262          * @return void
2263          */
2264         public function testApiFormatMessagesWithoutUserObjects()
2265         {
2266                 $_GET['getUserObjects'] = 'false';
2267                 $result                 = api_format_messages(
2268                         ['id' => 1, 'uri-id' => 1, 'title' => 'item_title', 'body' => '[b]item_body[/b]'],
2269                         ['id' => 2, 'uri-id' => 2, 'screen_name' => 'recipient_name'],
2270                         ['id' => 3, 'uri-id' => 3, 'screen_name' => 'sender_name']
2271                 );
2272                 self::assertTrue(!isset($result['sender']));
2273                 self::assertTrue(!isset($result['recipient']));
2274         }
2275
2276         /**
2277          * Test the api_convert_item() function.
2278          *
2279          * @return void
2280          */
2281         public function testApiConvertItem()
2282         {
2283                 $result = api_convert_item(
2284                         [
2285                                 'network' => 'feed',
2286                                 'title'   => 'item_title',
2287                                 'uri-id'  => 1,
2288                                 // We need a long string to test that it is correctly cut
2289                                 'body'    => 'perspiciatis impedit voluptatem quis molestiae ea qui ' .
2290                                              'reiciendis dolorum aut ducimus sunt consequatur inventore dolor ' .
2291                                              'officiis pariatur doloremque nemo culpa aut quidem qui dolore ' .
2292                                              'laudantium atque commodi alias voluptatem non possimus aperiam ' .
2293                                              'ipsum rerum consequuntur aut amet fugit quia aliquid praesentium ' .
2294                                              'repellendus quibusdam et et inventore mollitia rerum sit autem ' .
2295                                              'pariatur maiores ipsum accusantium perferendis vel sit possimus ' .
2296                                              'veritatis nihil distinctio qui eum repellat officia illum quos ' .
2297                                              'impedit quam iste esse unde qui suscipit aut facilis ut inventore ' .
2298                                              'omnis exercitationem quo magnam consequatur maxime aut illum ' .
2299                                              'soluta quaerat natus unde aspernatur et sed beatae nihil ullam ' .
2300                                              'temporibus corporis ratione blanditiis perspiciatis impedit ' .
2301                                              'voluptatem quis molestiae ea qui reiciendis dolorum aut ducimus ' .
2302                                              'sunt consequatur inventore dolor officiis pariatur doloremque ' .
2303                                              'nemo culpa aut quidem qui dolore laudantium atque commodi alias ' .
2304                                              'voluptatem non possimus aperiam ipsum rerum consequuntur aut ' .
2305                                              'amet fugit quia aliquid praesentium repellendus quibusdam et et ' .
2306                                              'inventore mollitia rerum sit autem pariatur maiores ipsum accusantium ' .
2307                                              'perferendis vel sit possimus veritatis nihil distinctio qui eum ' .
2308                                              'repellat officia illum quos impedit quam iste esse unde qui ' .
2309                                              'suscipit aut facilis ut inventore omnis exercitationem quo magnam ' .
2310                                              'consequatur maxime aut illum soluta quaerat natus unde aspernatur ' .
2311                                              'et sed beatae nihil ullam temporibus corporis ratione blanditiis',
2312                                 'plink'   => 'item_plink'
2313                         ]
2314                 );
2315                 self::assertStringStartsWith('item_title', $result['text']);
2316                 self::assertStringStartsWith('<h4>item_title</h4><br>perspiciatis impedit voluptatem', $result['html']);
2317         }
2318
2319         /**
2320          * Test the api_convert_item() function with an empty item body.
2321          *
2322          * @return void
2323          */
2324         public function testApiConvertItemWithoutBody()
2325         {
2326                 $result = api_convert_item(
2327                         [
2328                                 'network' => 'feed',
2329                                 'title'   => 'item_title',
2330                                 'uri-id'  => -1,
2331                                 'body'    => '',
2332                                 'plink'   => 'item_plink'
2333                         ]
2334                 );
2335                 self::assertEquals("item_title", $result['text']);
2336                 self::assertEquals('<h4>item_title</h4><br>item_plink', $result['html']);
2337         }
2338
2339         /**
2340          * Test the api_convert_item() function with the title in the body.
2341          *
2342          * @return void
2343          */
2344         public function testApiConvertItemWithTitleInBody()
2345         {
2346                 $result = api_convert_item(
2347                         [
2348                                 'title'  => 'item_title',
2349                                 'body'   => 'item_title item_body',
2350                                 'uri-id' => 1,
2351                         ]
2352                 );
2353                 self::assertEquals('item_title item_body', $result['text']);
2354                 self::assertEquals('<h4>item_title</h4><br>item_title item_body', $result['html']);
2355         }
2356
2357         /**
2358          * Test the api_get_attachments() function.
2359          *
2360          * @return void
2361          */
2362         public function testApiGetAttachments()
2363         {
2364                 $body = 'body';
2365                 self::assertEmpty(api_get_attachments($body, 0));
2366         }
2367
2368         /**
2369          * Test the api_get_attachments() function with an img tag.
2370          *
2371          * @return void
2372          */
2373         public function testApiGetAttachmentsWithImage()
2374         {
2375                 $body = '[img]http://via.placeholder.com/1x1.png[/img]';
2376                 self::assertIsArray(api_get_attachments($body, 0));
2377         }
2378
2379         /**
2380          * Test the api_get_attachments() function with an img tag and an AndStatus user agent.
2381          *
2382          * @return void
2383          */
2384         public function testApiGetAttachmentsWithImageAndAndStatus()
2385         {
2386                 $_SERVER['HTTP_USER_AGENT'] = 'AndStatus';
2387                 $body                       = '[img]http://via.placeholder.com/1x1.png[/img]';
2388                 self::assertIsArray(api_get_attachments($body, 0));
2389         }
2390
2391         /**
2392          * Test the api_get_entitities() function.
2393          *
2394          * @return void
2395          */
2396         public function testApiGetEntitities()
2397         {
2398                 $text = 'text';
2399                 self::assertIsArray(api_get_entitities($text, 'bbcode', 0));
2400         }
2401
2402         /**
2403          * Test the api_get_entitities() function with the include_entities parameter.
2404          *
2405          * @return void
2406          */
2407         public function testApiGetEntititiesWithIncludeEntities()
2408         {
2409                 $_REQUEST['include_entities'] = 'true';
2410                 $text                         = 'text';
2411                 $result                       = api_get_entitities($text, 'bbcode', 0);
2412                 self::assertIsArray($result['hashtags']);
2413                 self::assertIsArray($result['symbols']);
2414                 self::assertIsArray($result['urls']);
2415                 self::assertIsArray($result['user_mentions']);
2416         }
2417
2418         /**
2419          * Test the api_format_items_embeded_images() function.
2420          *
2421          * @return void
2422          */
2423         public function testApiFormatItemsEmbededImages()
2424         {
2425                 self::assertEquals(
2426                         'text ' . DI::baseUrl() . '/display/item_guid',
2427                         api_format_items_embeded_images(['guid' => 'item_guid'], 'text data:image/foo')
2428                 );
2429         }
2430
2431         /**
2432          * Test the api_contactlink_to_array() function.
2433          *
2434          * @return void
2435          */
2436         public function testApiContactlinkToArray()
2437         {
2438                 self::assertEquals(
2439                         [
2440                                 'name' => 'text',
2441                                 'url'  => '',
2442                         ],
2443                         api_contactlink_to_array('text')
2444                 );
2445         }
2446
2447         /**
2448          * Test the api_contactlink_to_array() function with an URL.
2449          *
2450          * @return void
2451          */
2452         public function testApiContactlinkToArrayWithUrl()
2453         {
2454                 self::assertEquals(
2455                         [
2456                                 'name' => ['link_text'],
2457                                 'url'  => ['url'],
2458                         ],
2459                         api_contactlink_to_array('text <a href="url">link_text</a>')
2460                 );
2461         }
2462
2463         /**
2464          * Test the api_format_items_activities() function.
2465          *
2466          * @return void
2467          */
2468         public function testApiFormatItemsActivities()
2469         {
2470                 $item   = ['uid' => 0, 'uri' => ''];
2471                 $result = api_format_items_activities($item);
2472                 self::assertArrayHasKey('like', $result);
2473                 self::assertArrayHasKey('dislike', $result);
2474                 self::assertArrayHasKey('attendyes', $result);
2475                 self::assertArrayHasKey('attendno', $result);
2476                 self::assertArrayHasKey('attendmaybe', $result);
2477         }
2478
2479         /**
2480          * Test the api_format_items_activities() function with an XML result.
2481          *
2482          * @return void
2483          */
2484         public function testApiFormatItemsActivitiesWithXml()
2485         {
2486                 $item   = ['uid' => 0, 'uri' => ''];
2487                 $result = api_format_items_activities($item, 'xml');
2488                 self::assertArrayHasKey('friendica:like', $result);
2489                 self::assertArrayHasKey('friendica:dislike', $result);
2490                 self::assertArrayHasKey('friendica:attendyes', $result);
2491                 self::assertArrayHasKey('friendica:attendno', $result);
2492                 self::assertArrayHasKey('friendica:attendmaybe', $result);
2493         }
2494
2495         /**
2496          * Test the api_format_items() function.
2497          * @doesNotPerformAssertions
2498          */
2499         public function testApiFormatItems()
2500         {
2501                 $items  = [
2502                         [
2503                                 'item_network'   => 'item_network',
2504                                 'source'         => 'web',
2505                                 'coord'          => '5 7',
2506                                 'body'           => '',
2507                                 'verb'           => '',
2508                                 'author-id'      => 43,
2509                                 'author-network' => Protocol::DFRN,
2510                                 'author-link'    => 'http://localhost/profile/othercontact',
2511                                 'plink'          => '',
2512                         ]
2513                 ];
2514                 $result = api_format_items($items, ['id' => 0], true);
2515                 foreach ($result as $status) {
2516                         self::assertStatus($status);
2517                 }
2518         }
2519
2520         /**
2521          * Test the api_format_items() function with an XML result.
2522          * @doesNotPerformAssertions
2523          */
2524         public function testApiFormatItemsWithXml()
2525         {
2526                 $items  = [
2527                         [
2528                                 'coord'          => '5 7',
2529                                 'body'           => '',
2530                                 'verb'           => '',
2531                                 'author-id'      => 43,
2532                                 'author-network' => Protocol::DFRN,
2533                                 'author-link'    => 'http://localhost/profile/othercontact',
2534                                 'plink'          => '',
2535                         ]
2536                 ];
2537                 $result = api_format_items($items, ['id' => 0], true, 'xml');
2538                 foreach ($result as $status) {
2539                         self::assertStatus($status);
2540                 }
2541         }
2542
2543         /**
2544          * Test the api_format_items() function.
2545          *
2546          * @return void
2547          */
2548         public function testApiAccountRateLimitStatus()
2549         {
2550                 // @todo How to test the new API?
2551                 // $result = api_account_rate_limit_status('json');
2552                 // self::assertEquals(150, $result['hash']['remaining_hits']);
2553                 // self::assertEquals(150, $result['hash']['hourly_limit']);
2554                 // self::assertIsInt($result['hash']['reset_time_in_seconds']);
2555         }
2556
2557         /**
2558          * Test the api_format_items() function with an XML result.
2559          *
2560          * @return void
2561          */
2562         public function testApiAccountRateLimitStatusWithXml()
2563         {
2564                 // @todo How to test the new API?
2565                 // $result = api_account_rate_limit_status('xml');
2566                 // self::assertXml($result, 'hash');
2567         }
2568
2569         /**
2570          * Test the api_help_test() function.
2571          *
2572          * @return void
2573          */
2574         public function testApiHelpTest()
2575         {
2576                 // @todo How to test the new API?
2577                 // $result = \Friendica\Module\Api\Friendica\Help\Test::rawcontent(['extension' => 'json']);
2578                 // self::assertEquals(['ok' => 'ok'], $result);
2579         }
2580
2581         /**
2582          * Test the api_help_test() function with an XML result.
2583          *
2584          * @return void
2585          */
2586         public function testApiHelpTestWithXml()
2587         {
2588                 // @todo How to test the new API?
2589                 // $result = api_help_test('xml');
2590                 // self::assertXml($result, 'ok');
2591         }
2592
2593         /**
2594          * Test the api_lists_list() function.
2595          *
2596          * @return void
2597          */
2598         public function testApiListsList()
2599         {
2600                 $result = api_lists_list('json');
2601                 self::assertEquals(['lists_list' => []], $result);
2602         }
2603
2604         /**
2605          * Test the api_lists_ownerships() function.
2606          *
2607          * @return void
2608          */
2609         public function testApiListsOwnerships()
2610         {
2611                 $result = api_lists_ownerships('json');
2612                 foreach ($result['lists']['lists'] as $list) {
2613                         self::assertList($list);
2614                 }
2615         }
2616
2617         /**
2618          * Test the api_lists_ownerships() function without an authenticated user.
2619          *
2620          * @return void
2621          */
2622         public function testApiListsOwnershipsWithoutAuthenticatedUser()
2623         {
2624                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
2625                 $_SESSION['authenticated'] = false;
2626                 api_lists_ownerships('json');
2627         }
2628
2629         /**
2630          * Test the api_lists_statuses() function.
2631          *
2632          * @return void
2633          */
2634         public function testApiListsStatuses()
2635         {
2636                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
2637                 api_lists_statuses('json');
2638         }
2639
2640         /**
2641          * Test the api_lists_statuses() function with a list ID.
2642          * @doesNotPerformAssertions
2643          */
2644         public function testApiListsStatusesWithListId()
2645         {
2646                 $_REQUEST['list_id'] = 1;
2647                 $_REQUEST['page']    = -1;
2648                 $_REQUEST['max_id']  = 10;
2649                 $result              = api_lists_statuses('json');
2650                 foreach ($result['status'] as $status) {
2651                         self::assertStatus($status);
2652                 }
2653         }
2654
2655         /**
2656          * Test the api_lists_statuses() function with a list ID and a RSS result.
2657          *
2658          * @return void
2659          */
2660         public function testApiListsStatusesWithListIdAndRss()
2661         {
2662                 $_REQUEST['list_id'] = 1;
2663                 $result              = api_lists_statuses('rss');
2664                 self::assertXml($result, 'statuses');
2665         }
2666
2667         /**
2668          * Test the api_lists_statuses() function with an unallowed user.
2669          *
2670          * @return void
2671          */
2672         public function testApiListsStatusesWithUnallowedUser()
2673         {
2674                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
2675                 $_SESSION['allow_api'] = false;
2676                 $_GET['screen_name']   = $this->selfUser['nick'];
2677                 api_lists_statuses('json');
2678         }
2679
2680         /**
2681          * Test the api_statuses_f() function.
2682          *
2683          * @return void
2684          */
2685         public function testApiStatusesFWithFriends()
2686         {
2687                 $_GET['page'] = -1;
2688                 $result       = api_statuses_f('friends');
2689                 self::assertArrayHasKey('user', $result);
2690         }
2691
2692         /**
2693          * Test the api_statuses_f() function.
2694          *
2695          * @return void
2696          */
2697         public function testApiStatusesFWithFollowers()
2698         {
2699                 $result = api_statuses_f('followers');
2700                 self::assertArrayHasKey('user', $result);
2701         }
2702
2703         /**
2704          * Test the api_statuses_f() function.
2705          *
2706          * @return void
2707          */
2708         public function testApiStatusesFWithBlocks()
2709         {
2710                 $result = api_statuses_f('blocks');
2711                 self::assertArrayHasKey('user', $result);
2712         }
2713
2714         /**
2715          * Test the api_statuses_f() function.
2716          *
2717          * @return void
2718          */
2719         public function testApiStatusesFWithIncoming()
2720         {
2721                 $result = api_statuses_f('incoming');
2722                 self::assertArrayHasKey('user', $result);
2723         }
2724
2725         /**
2726          * Test the api_statuses_f() function an undefined cursor GET variable.
2727          *
2728          * @return void
2729          */
2730         public function testApiStatusesFWithUndefinedCursor()
2731         {
2732                 $_GET['cursor'] = 'undefined';
2733                 self::assertFalse(api_statuses_f('friends'));
2734         }
2735
2736         /**
2737          * Test the api_statuses_friends() function.
2738          *
2739          * @return void
2740          */
2741         public function testApiStatusesFriends()
2742         {
2743                 $result = api_statuses_friends('json');
2744                 self::assertArrayHasKey('user', $result);
2745         }
2746
2747         /**
2748          * Test the api_statuses_friends() function an undefined cursor GET variable.
2749          *
2750          * @return void
2751          */
2752         public function testApiStatusesFriendsWithUndefinedCursor()
2753         {
2754                 $_GET['cursor'] = 'undefined';
2755                 self::assertFalse(api_statuses_friends('json'));
2756         }
2757
2758         /**
2759          * Test the api_statuses_followers() function.
2760          *
2761          * @return void
2762          */
2763         public function testApiStatusesFollowers()
2764         {
2765                 $result = api_statuses_followers('json');
2766                 self::assertArrayHasKey('user', $result);
2767         }
2768
2769         /**
2770          * Test the api_statuses_followers() function an undefined cursor GET variable.
2771          *
2772          * @return void
2773          */
2774         public function testApiStatusesFollowersWithUndefinedCursor()
2775         {
2776                 $_GET['cursor'] = 'undefined';
2777                 self::assertFalse(api_statuses_followers('json'));
2778         }
2779
2780         /**
2781          * Test the api_blocks_list() function.
2782          *
2783          * @return void
2784          */
2785         public function testApiBlocksList()
2786         {
2787                 $result = api_blocks_list('json');
2788                 self::assertArrayHasKey('user', $result);
2789         }
2790
2791         /**
2792          * Test the api_blocks_list() function an undefined cursor GET variable.
2793          *
2794          * @return void
2795          */
2796         public function testApiBlocksListWithUndefinedCursor()
2797         {
2798                 $_GET['cursor'] = 'undefined';
2799                 self::assertFalse(api_blocks_list('json'));
2800         }
2801
2802         /**
2803          * Test the api_friendships_incoming() function.
2804          *
2805          * @return void
2806          */
2807         public function testApiFriendshipsIncoming()
2808         {
2809                 $result = api_friendships_incoming('json');
2810                 self::assertArrayHasKey('id', $result);
2811         }
2812
2813         /**
2814          * Test the api_friendships_incoming() function an undefined cursor GET variable.
2815          *
2816          * @return void
2817          */
2818         public function testApiFriendshipsIncomingWithUndefinedCursor()
2819         {
2820                 $_GET['cursor'] = 'undefined';
2821                 self::assertFalse(api_friendships_incoming('json'));
2822         }
2823
2824         /**
2825          * Test the api_statusnet_config() function.
2826          *
2827          * @return void
2828          */
2829         public function testApiStatusnetConfig()
2830         {
2831                 $result = api_statusnet_config('json');
2832                 self::assertEquals('localhost', $result['config']['site']['server']);
2833                 self::assertEquals('default', $result['config']['site']['theme']);
2834                 self::assertEquals(DI::baseUrl() . '/images/friendica-64.png', $result['config']['site']['logo']);
2835                 self::assertTrue($result['config']['site']['fancy']);
2836                 self::assertEquals('en', $result['config']['site']['language']);
2837                 self::assertEquals('UTC', $result['config']['site']['timezone']);
2838                 self::assertEquals(200000, $result['config']['site']['textlimit']);
2839                 self::assertEquals('false', $result['config']['site']['private']);
2840                 self::assertEquals('false', $result['config']['site']['ssl']);
2841                 self::assertEquals(30, $result['config']['site']['shorturllength']);
2842         }
2843
2844         /**
2845          * Test the api_statusnet_version() function.
2846          *
2847          * @return void
2848          */
2849         public function testApiStatusnetVersion()
2850         {
2851                 // @todo How to test the new API?
2852                 // $result = api_statusnet_version('json');
2853                 // self::assertEquals('0.9.7', $result['version']);
2854         }
2855
2856         /**
2857          * Test the api_direct_messages_new() function.
2858          *
2859          * @return void
2860          */
2861         public function testApiDirectMessagesNew()
2862         {
2863                 $result = api_direct_messages_new('json');
2864                 self::assertNull($result);
2865         }
2866
2867         /**
2868          * Test the api_direct_messages_new() function without an authenticated user.
2869          *
2870          * @return void
2871          */
2872         public function testApiDirectMessagesNewWithoutAuthenticatedUser()
2873         {
2874                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
2875                 $_SESSION['authenticated'] = false;
2876                 api_direct_messages_new('json');
2877         }
2878
2879         /**
2880          * Test the api_direct_messages_new() function with an user ID.
2881          *
2882          * @return void
2883          */
2884         public function testApiDirectMessagesNewWithUserId()
2885         {
2886                 $_POST['text']    = 'message_text';
2887                 $_POST['user_id'] = $this->otherUser['id'];
2888                 $result           = api_direct_messages_new('json');
2889                 self::assertEquals(['direct_message' => ['error' => -1]], $result);
2890         }
2891
2892         /**
2893          * Test the api_direct_messages_new() function with a screen name.
2894          *
2895          * @return void
2896          */
2897         public function testApiDirectMessagesNewWithScreenName()
2898         {
2899                 $this->app->setLoggedInUserNickname($this->selfUser['nick']);
2900                 $_POST['text']        = 'message_text';
2901                 $_POST['screen_name'] = $this->friendUser['nick'];
2902                 $result               = api_direct_messages_new('json');
2903                 self::assertStringContainsString('message_text', $result['direct_message']['text']);
2904                 self::assertEquals('selfcontact', $result['direct_message']['sender_screen_name']);
2905                 self::assertEquals(1, $result['direct_message']['friendica_seen']);
2906         }
2907
2908         /**
2909          * Test the api_direct_messages_new() function with a title.
2910          *
2911          * @return void
2912          */
2913         public function testApiDirectMessagesNewWithTitle()
2914         {
2915                 $this->app->setLoggedInUserNickname($this->selfUser['nick']);
2916                 $_POST['text']        = 'message_text';
2917                 $_POST['screen_name'] = $this->friendUser['nick'];
2918                 $_REQUEST['title']    = 'message_title';
2919                 $result               = api_direct_messages_new('json');
2920                 self::assertStringContainsString('message_text', $result['direct_message']['text']);
2921                 self::assertStringContainsString('message_title', $result['direct_message']['text']);
2922                 self::assertEquals('selfcontact', $result['direct_message']['sender_screen_name']);
2923                 self::assertEquals(1, $result['direct_message']['friendica_seen']);
2924         }
2925
2926         /**
2927          * Test the api_direct_messages_new() function with an RSS result.
2928          *
2929          * @return void
2930          */
2931         public function testApiDirectMessagesNewWithRss()
2932         {
2933                 $this->app->setLoggedInUserNickname($this->selfUser['nick']);
2934                 $_POST['text']        = 'message_text';
2935                 $_POST['screen_name'] = $this->friendUser['nick'];
2936                 $result               = api_direct_messages_new('rss');
2937                 self::assertXml($result, 'direct-messages');
2938         }
2939
2940         /**
2941          * Test the api_direct_messages_destroy() function.
2942          *
2943          * @return void
2944          */
2945         public function testApiDirectMessagesDestroy()
2946         {
2947                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
2948                 api_direct_messages_destroy('json');
2949         }
2950
2951         /**
2952          * Test the api_direct_messages_destroy() function with the friendica_verbose GET param.
2953          *
2954          * @return void
2955          */
2956         public function testApiDirectMessagesDestroyWithVerbose()
2957         {
2958                 $_GET['friendica_verbose'] = 'true';
2959                 $result                    = api_direct_messages_destroy('json');
2960                 self::assertEquals(
2961                         [
2962                                 '$result' => [
2963                                         'result'  => 'error',
2964                                         'message' => 'message id or parenturi not specified'
2965                                 ]
2966                         ],
2967                         $result
2968                 );
2969         }
2970
2971         /**
2972          * Test the api_direct_messages_destroy() function without an authenticated user.
2973          *
2974          * @return void
2975          */
2976         public function testApiDirectMessagesDestroyWithoutAuthenticatedUser()
2977         {
2978                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
2979                 $_SESSION['authenticated'] = false;
2980                 api_direct_messages_destroy('json');
2981         }
2982
2983         /**
2984          * Test the api_direct_messages_destroy() function with a non-zero ID.
2985          *
2986          * @return void
2987          */
2988         public function testApiDirectMessagesDestroyWithId()
2989         {
2990                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
2991                 $_REQUEST['id'] = 1;
2992                 api_direct_messages_destroy('json');
2993         }
2994
2995         /**
2996          * Test the api_direct_messages_destroy() with a non-zero ID and the friendica_verbose GET param.
2997          *
2998          * @return void
2999          */
3000         public function testApiDirectMessagesDestroyWithIdAndVerbose()
3001         {
3002                 $_REQUEST['id']                  = 1;
3003                 $_REQUEST['friendica_parenturi'] = 'parent_uri';
3004                 $_GET['friendica_verbose']       = 'true';
3005                 $result                          = api_direct_messages_destroy('json');
3006                 self::assertEquals(
3007                         [
3008                                 '$result' => [
3009                                         'result'  => 'error',
3010                                         'message' => 'message id not in database'
3011                                 ]
3012                         ],
3013                         $result
3014                 );
3015         }
3016
3017         /**
3018          * Test the api_direct_messages_destroy() function with a non-zero ID.
3019          *
3020          * @return void
3021          */
3022         public function testApiDirectMessagesDestroyWithCorrectId()
3023         {
3024                 $this->markTestIncomplete('We need to add a dataset for this.');
3025         }
3026
3027         /**
3028          * Test the api_direct_messages_box() function.
3029          *
3030          * @return void
3031          */
3032         public function testApiDirectMessagesBoxWithSentbox()
3033         {
3034                 $_REQUEST['page']   = -1;
3035                 $_REQUEST['max_id'] = 10;
3036                 $result             = api_direct_messages_box('json', 'sentbox', 'false');
3037                 self::assertArrayHasKey('direct_message', $result);
3038         }
3039
3040         /**
3041          * Test the api_direct_messages_box() function.
3042          *
3043          * @return void
3044          */
3045         public function testApiDirectMessagesBoxWithConversation()
3046         {
3047                 $result = api_direct_messages_box('json', 'conversation', 'false');
3048                 self::assertArrayHasKey('direct_message', $result);
3049         }
3050
3051         /**
3052          * Test the api_direct_messages_box() function.
3053          *
3054          * @return void
3055          */
3056         public function testApiDirectMessagesBoxWithAll()
3057         {
3058                 $result = api_direct_messages_box('json', 'all', 'false');
3059                 self::assertArrayHasKey('direct_message', $result);
3060         }
3061
3062         /**
3063          * Test the api_direct_messages_box() function.
3064          *
3065          * @return void
3066          */
3067         public function testApiDirectMessagesBoxWithInbox()
3068         {
3069                 $result = api_direct_messages_box('json', 'inbox', 'false');
3070                 self::assertArrayHasKey('direct_message', $result);
3071         }
3072
3073         /**
3074          * Test the api_direct_messages_box() function.
3075          *
3076          * @return void
3077          */
3078         public function testApiDirectMessagesBoxWithVerbose()
3079         {
3080                 $result = api_direct_messages_box('json', 'sentbox', 'true');
3081                 self::assertEquals(
3082                         [
3083                                 '$result' => [
3084                                         'result'  => 'error',
3085                                         'message' => 'no mails available'
3086                                 ]
3087                         ],
3088                         $result
3089                 );
3090         }
3091
3092         /**
3093          * Test the api_direct_messages_box() function with a RSS result.
3094          *
3095          * @return void
3096          */
3097         public function testApiDirectMessagesBoxWithRss()
3098         {
3099                 $result = api_direct_messages_box('rss', 'sentbox', 'false');
3100                 self::assertXml($result, 'direct-messages');
3101         }
3102
3103         /**
3104          * Test the api_direct_messages_box() function without an authenticated user.
3105          *
3106          * @return void
3107          */
3108         public function testApiDirectMessagesBoxWithUnallowedUser()
3109         {
3110                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
3111                 $_SESSION['allow_api'] = false;
3112                 $_GET['screen_name']   = $this->selfUser['nick'];
3113                 api_direct_messages_box('json', 'sentbox', 'false');
3114         }
3115
3116         /**
3117          * Test the api_direct_messages_sentbox() function.
3118          *
3119          * @return void
3120          */
3121         public function testApiDirectMessagesSentbox()
3122         {
3123                 $result = api_direct_messages_sentbox('json');
3124                 self::assertArrayHasKey('direct_message', $result);
3125         }
3126
3127         /**
3128          * Test the api_direct_messages_inbox() function.
3129          *
3130          * @return void
3131          */
3132         public function testApiDirectMessagesInbox()
3133         {
3134                 $result = api_direct_messages_inbox('json');
3135                 self::assertArrayHasKey('direct_message', $result);
3136         }
3137
3138         /**
3139          * Test the api_direct_messages_all() function.
3140          *
3141          * @return void
3142          */
3143         public function testApiDirectMessagesAll()
3144         {
3145                 $result = api_direct_messages_all('json');
3146                 self::assertArrayHasKey('direct_message', $result);
3147         }
3148
3149         /**
3150          * Test the api_direct_messages_conversation() function.
3151          *
3152          * @return void
3153          */
3154         public function testApiDirectMessagesConversation()
3155         {
3156                 $result = api_direct_messages_conversation('json');
3157                 self::assertArrayHasKey('direct_message', $result);
3158         }
3159
3160         /**
3161          * Test the api_oauth_request_token() function.
3162          *
3163          * @return void
3164          */
3165         public function testApiOauthRequestToken()
3166         {
3167                 $this->markTestIncomplete('exit() kills phpunit as well');
3168         }
3169
3170         /**
3171          * Test the api_oauth_access_token() function.
3172          *
3173          * @return void
3174          */
3175         public function testApiOauthAccessToken()
3176         {
3177                 $this->markTestIncomplete('exit() kills phpunit as well');
3178         }
3179
3180         /**
3181          * Test the api_fr_photoalbum_delete() function.
3182          *
3183          * @return void
3184          */
3185         public function testApiFrPhotoalbumDelete()
3186         {
3187                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
3188                 api_fr_photoalbum_delete('json');
3189         }
3190
3191         /**
3192          * Test the api_fr_photoalbum_delete() function with an album name.
3193          *
3194          * @return void
3195          */
3196         public function testApiFrPhotoalbumDeleteWithAlbum()
3197         {
3198                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
3199                 $_REQUEST['album'] = 'album_name';
3200                 api_fr_photoalbum_delete('json');
3201         }
3202
3203         /**
3204          * Test the api_fr_photoalbum_delete() function with an album name.
3205          *
3206          * @return void
3207          */
3208         public function testApiFrPhotoalbumDeleteWithValidAlbum()
3209         {
3210                 $this->markTestIncomplete('We need to add a dataset for this.');
3211         }
3212
3213         /**
3214          * Test the api_fr_photoalbum_delete() function.
3215          *
3216          * @return void
3217          */
3218         public function testApiFrPhotoalbumUpdate()
3219         {
3220                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
3221                 api_fr_photoalbum_update('json');
3222         }
3223
3224         /**
3225          * Test the api_fr_photoalbum_delete() function with an album name.
3226          *
3227          * @return void
3228          */
3229         public function testApiFrPhotoalbumUpdateWithAlbum()
3230         {
3231                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
3232                 $_REQUEST['album'] = 'album_name';
3233                 api_fr_photoalbum_update('json');
3234         }
3235
3236         /**
3237          * Test the api_fr_photoalbum_delete() function with an album name.
3238          *
3239          * @return void
3240          */
3241         public function testApiFrPhotoalbumUpdateWithAlbumAndNewAlbum()
3242         {
3243                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
3244                 $_REQUEST['album']     = 'album_name';
3245                 $_REQUEST['album_new'] = 'album_name';
3246                 api_fr_photoalbum_update('json');
3247         }
3248
3249         /**
3250          * Test the api_fr_photoalbum_update() function without an authenticated user.
3251          *
3252          * @return void
3253          */
3254         public function testApiFrPhotoalbumUpdateWithoutAuthenticatedUser()
3255         {
3256                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
3257                 $_SESSION['authenticated'] = false;
3258                 api_fr_photoalbum_update('json');
3259         }
3260
3261         /**
3262          * Test the api_fr_photoalbum_delete() function with an album name.
3263          *
3264          * @return void
3265          */
3266         public function testApiFrPhotoalbumUpdateWithValidAlbum()
3267         {
3268                 $this->markTestIncomplete('We need to add a dataset for this.');
3269         }
3270
3271         /**
3272          * Test the api_fr_photos_list() function.
3273          *
3274          * @return void
3275          */
3276         public function testApiFrPhotosList()
3277         {
3278                 $result = api_fr_photos_list('json');
3279                 self::assertArrayHasKey('photo', $result);
3280         }
3281
3282         /**
3283          * Test the api_fr_photos_list() function without an authenticated user.
3284          *
3285          * @return void
3286          */
3287         public function testApiFrPhotosListWithoutAuthenticatedUser()
3288         {
3289                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
3290                 $_SESSION['authenticated'] = false;
3291                 api_fr_photos_list('json');
3292         }
3293
3294         /**
3295          * Test the api_fr_photo_create_update() function.
3296          */
3297         public function testApiFrPhotoCreateUpdate()
3298         {
3299                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
3300                 api_fr_photo_create_update('json');
3301         }
3302
3303         /**
3304          * Test the api_fr_photo_create_update() function without an authenticated user.
3305          *
3306          * @return void
3307          */
3308         public function testApiFrPhotoCreateUpdateWithoutAuthenticatedUser()
3309         {
3310                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
3311                 $_SESSION['authenticated'] = false;
3312                 api_fr_photo_create_update('json');
3313         }
3314
3315         /**
3316          * Test the api_fr_photo_create_update() function with an album name.
3317          *
3318          * @return void
3319          */
3320         public function testApiFrPhotoCreateUpdateWithAlbum()
3321         {
3322                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
3323                 $_REQUEST['album'] = 'album_name';
3324                 api_fr_photo_create_update('json');
3325         }
3326
3327         /**
3328          * Test the api_fr_photo_create_update() function with the update mode.
3329          *
3330          * @return void
3331          */
3332         public function testApiFrPhotoCreateUpdateWithUpdate()
3333         {
3334                 $this->markTestIncomplete('We need to create a dataset for this');
3335         }
3336
3337         /**
3338          * Test the api_fr_photo_create_update() function with an uploaded file.
3339          *
3340          * @return void
3341          */
3342         public function testApiFrPhotoCreateUpdateWithFile()
3343         {
3344                 $this->markTestIncomplete();
3345         }
3346
3347         /**
3348          * Test the api_fr_photo_delete() function.
3349          *
3350          * @return void
3351          */
3352         public function testApiFrPhotoDelete()
3353         {
3354                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
3355                 api_fr_photo_delete('json');
3356         }
3357
3358         /**
3359          * Test the api_fr_photo_delete() function without an authenticated user.
3360          *
3361          * @return void
3362          */
3363         public function testApiFrPhotoDeleteWithoutAuthenticatedUser()
3364         {
3365                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
3366                 $_SESSION['authenticated'] = false;
3367                 api_fr_photo_delete('json');
3368         }
3369
3370         /**
3371          * Test the api_fr_photo_delete() function with a photo ID.
3372          *
3373          * @return void
3374          */
3375         public function testApiFrPhotoDeleteWithPhotoId()
3376         {
3377                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
3378                 $_REQUEST['photo_id'] = 1;
3379                 api_fr_photo_delete('json');
3380         }
3381
3382         /**
3383          * Test the api_fr_photo_delete() function with a correct photo ID.
3384          *
3385          * @return void
3386          */
3387         public function testApiFrPhotoDeleteWithCorrectPhotoId()
3388         {
3389                 $this->markTestIncomplete('We need to create a dataset for this.');
3390         }
3391
3392         /**
3393          * Test the api_fr_photo_detail() function.
3394          *
3395          * @return void
3396          */
3397         public function testApiFrPhotoDetail()
3398         {
3399                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
3400                 api_fr_photo_detail('json');
3401         }
3402
3403         /**
3404          * Test the api_fr_photo_detail() function without an authenticated user.
3405          *
3406          * @return void
3407          */
3408         public function testApiFrPhotoDetailWithoutAuthenticatedUser()
3409         {
3410                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
3411                 $_SESSION['authenticated'] = false;
3412                 api_fr_photo_detail('json');
3413         }
3414
3415         /**
3416          * Test the api_fr_photo_detail() function with a photo ID.
3417          *
3418          * @return void
3419          */
3420         public function testApiFrPhotoDetailWithPhotoId()
3421         {
3422                 $this->expectException(\Friendica\Network\HTTPException\NotFoundException::class);
3423                 $_REQUEST['photo_id'] = 1;
3424                 api_fr_photo_detail('json');
3425         }
3426
3427         /**
3428          * Test the api_fr_photo_detail() function with a correct photo ID.
3429          *
3430          * @return void
3431          */
3432         public function testApiFrPhotoDetailCorrectPhotoId()
3433         {
3434                 $this->markTestIncomplete('We need to create a dataset for this.');
3435         }
3436
3437         /**
3438          * Test the api_account_update_profile_image() function.
3439          *
3440          * @return void
3441          */
3442         public function testApiAccountUpdateProfileImage()
3443         {
3444                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
3445                 api_account_update_profile_image('json');
3446         }
3447
3448         /**
3449          * Test the api_account_update_profile_image() function without an authenticated user.
3450          *
3451          * @return void
3452          */
3453         public function testApiAccountUpdateProfileImageWithoutAuthenticatedUser()
3454         {
3455                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
3456                 $_SESSION['authenticated'] = false;
3457                 api_account_update_profile_image('json');
3458         }
3459
3460         /**
3461          * Test the api_account_update_profile_image() function with an uploaded file.
3462          *
3463          * @return void
3464          */
3465         public function testApiAccountUpdateProfileImageWithUpload()
3466         {
3467                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
3468                 $this->markTestIncomplete();
3469         }
3470
3471
3472         /**
3473          * Test the api_account_update_profile() function.
3474          *
3475          * @return void
3476          */
3477         public function testApiAccountUpdateProfile()
3478         {
3479                 $_POST['name']        = 'new_name';
3480                 $_POST['description'] = 'new_description';
3481                 $result               = api_account_update_profile('json');
3482                 // We can't use assertSelfUser() here because the user object is missing some properties.
3483                 self::assertEquals($this->selfUser['id'], $result['user']['cid']);
3484                 self::assertEquals('DFRN', $result['user']['location']);
3485                 self::assertEquals($this->selfUser['nick'], $result['user']['screen_name']);
3486                 self::assertEquals('dfrn', $result['user']['network']);
3487                 self::assertEquals('new_name', $result['user']['name']);
3488                 self::assertEquals('new_description', $result['user']['description']);
3489         }
3490
3491         /**
3492          * Test the check_acl_input() function.
3493          *
3494          * @return void
3495          */
3496         public function testCheckAclInput()
3497         {
3498                 $result = check_acl_input('<aclstring>');
3499                 // Where does this result come from?
3500                 self::assertEquals(1, $result);
3501         }
3502
3503         /**
3504          * Test the check_acl_input() function with an empty ACL string.
3505          *
3506          * @return void
3507          */
3508         public function testCheckAclInputWithEmptyAclString()
3509         {
3510                 $result = check_acl_input(' ');
3511                 self::assertFalse($result);
3512         }
3513
3514         /**
3515          * Test the save_media_to_database() function.
3516          *
3517          * @return void
3518          */
3519         public function testSaveMediaToDatabase()
3520         {
3521                 $this->markTestIncomplete();
3522         }
3523
3524         /**
3525          * Test the post_photo_item() function.
3526          *
3527          * @return void
3528          */
3529         public function testPostPhotoItem()
3530         {
3531                 $this->markTestIncomplete();
3532         }
3533
3534         /**
3535          * Test the prepare_photo_data() function.
3536          *
3537          * @return void
3538          */
3539         public function testPreparePhotoData()
3540         {
3541                 $this->markTestIncomplete();
3542         }
3543
3544         /**
3545          * Test the api_share_as_retweet() function with a valid item.
3546          *
3547          * @return void
3548          */
3549         public function testApiShareAsRetweetWithValidItem()
3550         {
3551                 $this->markTestIncomplete();
3552         }
3553
3554         /**
3555          * Test the api_in_reply_to() function.
3556          *
3557          * @return void
3558          */
3559         public function testApiInReplyTo()
3560         {
3561                 $result = api_in_reply_to(['id' => 0, 'parent' => 0, 'uri' => '', 'thr-parent' => '']);
3562                 self::assertArrayHasKey('status_id', $result);
3563                 self::assertArrayHasKey('user_id', $result);
3564                 self::assertArrayHasKey('status_id_str', $result);
3565                 self::assertArrayHasKey('user_id_str', $result);
3566                 self::assertArrayHasKey('screen_name', $result);
3567         }
3568
3569         /**
3570          * Test the api_in_reply_to() function with a valid item.
3571          *
3572          * @return void
3573          */
3574         public function testApiInReplyToWithValidItem()
3575         {
3576                 $this->markTestIncomplete();
3577         }
3578
3579         /**
3580          * Test the api_clean_plain_items() function.
3581          *
3582          * @return void
3583          */
3584         public function testApiCleanPlainItems()
3585         {
3586                 $_REQUEST['include_entities'] = 'true';
3587                 $result                       = api_clean_plain_items('some_text [url="some_url"]some_text[/url]');
3588                 self::assertEquals('some_text [url="some_url"]"some_url"[/url]', $result);
3589         }
3590
3591         /**
3592          * Test the api_best_nickname() function.
3593          *
3594          * @return void
3595          */
3596         public function testApiBestNickname()
3597         {
3598                 $contacts = [];
3599                 $result   = api_best_nickname($contacts);
3600                 self::assertNull($result);
3601         }
3602
3603         /**
3604          * Test the api_best_nickname() function with contacts.
3605          *
3606          * @return void
3607          */
3608         public function testApiBestNicknameWithContacts()
3609         {
3610                 $this->markTestIncomplete();
3611         }
3612
3613         /**
3614          * Test the api_friendica_group_show() function.
3615          *
3616          * @return void
3617          */
3618         public function testApiFriendicaGroupShow()
3619         {
3620                 $this->markTestIncomplete();
3621         }
3622
3623         /**
3624          * Test the api_friendica_group_delete() function.
3625          *
3626          * @return void
3627          */
3628         public function testApiFriendicaGroupDelete()
3629         {
3630                 $this->markTestIncomplete();
3631         }
3632
3633         /**
3634          * Test the api_lists_destroy() function.
3635          *
3636          * @return void
3637          */
3638         public function testApiListsDestroy()
3639         {
3640                 $this->markTestIncomplete();
3641         }
3642
3643         /**
3644          * Test the group_create() function.
3645          *
3646          * @return void
3647          */
3648         public function testGroupCreate()
3649         {
3650                 $this->markTestIncomplete();
3651         }
3652
3653         /**
3654          * Test the api_friendica_group_create() function.
3655          *
3656          * @return void
3657          */
3658         public function testApiFriendicaGroupCreate()
3659         {
3660                 $this->markTestIncomplete();
3661         }
3662
3663         /**
3664          * Test the api_lists_create() function.
3665          *
3666          * @return void
3667          */
3668         public function testApiListsCreate()
3669         {
3670                 $this->markTestIncomplete();
3671         }
3672
3673         /**
3674          * Test the api_friendica_group_update() function.
3675          *
3676          * @return void
3677          */
3678         public function testApiFriendicaGroupUpdate()
3679         {
3680                 $this->markTestIncomplete();
3681         }
3682
3683         /**
3684          * Test the api_lists_update() function.
3685          *
3686          * @return void
3687          */
3688         public function testApiListsUpdate()
3689         {
3690                 $this->markTestIncomplete();
3691         }
3692
3693         /**
3694          * Test the api_friendica_activity() function.
3695          *
3696          * @return void
3697          */
3698         public function testApiFriendicaActivity()
3699         {
3700                 $this->markTestIncomplete();
3701         }
3702
3703         /**
3704          * Test the api_friendica_notification() function.
3705          *
3706          * @return void
3707          */
3708         public function testApiFriendicaNotification()
3709         {
3710                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
3711                 api_friendica_notification('json');
3712         }
3713
3714         /**
3715          * Test the api_friendica_notification() function without an authenticated user.
3716          *
3717          * @return void
3718          */
3719         public function testApiFriendicaNotificationWithoutAuthenticatedUser()
3720         {
3721                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
3722                 $_SESSION['authenticated'] = false;
3723                 api_friendica_notification('json');
3724         }
3725
3726         /**
3727          * Test the api_friendica_notification() function with empty result
3728          *
3729          * @return void
3730          */
3731         public function testApiFriendicaNotificationWithEmptyResult()
3732         {
3733                 DI::args()->setArgv(['api', 'friendica', 'notification']);
3734                 $_SESSION['uid'] = 41;
3735                 $result          = api_friendica_notification('json');
3736                 self::assertEquals(['note' => false], $result);
3737         }
3738
3739         /**
3740          * Test the api_friendica_notification() function with an XML result.
3741          *
3742          * @return void
3743          */
3744         public function testApiFriendicaNotificationWithXmlResult()
3745         {
3746                 DI::args()->setArgv(['api', 'friendica', 'notification']);
3747                 $result  = api_friendica_notification('xml');
3748                 $date = DateTimeFormat::local('2020-01-01 12:12:02');
3749                 $dateRel = Temporal::getRelativeDate('2020-01-01 07:12:02');
3750
3751                 $assertXml=<<<XML
3752 <?xml version="1.0"?>
3753 <notes>
3754   <note date="$date" date_rel="$dateRel" id="1" iid="4" link="http://localhost/notification/1" msg="A test reply from an item" msg_cache="A test reply from an item" msg_html="A test reply from an item" msg_plain="A test reply from an item" name="Reply to" name_cache="Reply to" otype="item" parent="" photo="http://localhost/" seen="false" timestamp="1577880722" type="8" uid="42" url="http://localhost/display/1" verb="http://activitystrea.ms/schema/1.0/post"/>
3755 </notes>
3756 XML;
3757                 self::assertXmlStringEqualsXmlString($assertXml, $result);
3758         }
3759
3760         /**
3761          * Test the api_friendica_notification() function with an JSON result.
3762          *
3763          * @return void
3764          */
3765         public function testApiFriendicaNotificationWithJsonResult()
3766         {
3767                 DI::args()->setArgv(['api', 'friendica', 'notification']);
3768                 $result = json_encode(api_friendica_notification('json'));
3769                 self::assertJson($result);
3770         }
3771
3772         /**
3773          * Test the api_friendica_notification_seen() function.
3774          *
3775          * @return void
3776          */
3777         public function testApiFriendicaNotificationSeen()
3778         {
3779                 $this->markTestIncomplete();
3780         }
3781
3782         /**
3783          * Test the api_friendica_direct_messages_setseen() function.
3784          *
3785          * @return void
3786          */
3787         public function testApiFriendicaDirectMessagesSetseen()
3788         {
3789                 $this->markTestIncomplete();
3790         }
3791
3792         /**
3793          * Test the api_friendica_direct_messages_search() function.
3794          *
3795          * @return void
3796          */
3797         public function testApiFriendicaDirectMessagesSearch()
3798         {
3799                 $this->markTestIncomplete();
3800         }
3801
3802         /**
3803          * Test the api_saved_searches_list() function.
3804          *
3805          * @return void
3806          */
3807         public function testApiSavedSearchesList()
3808         {
3809                 // $result = api_saved_searches_list('json');
3810                 // self::assertEquals(1, $result['terms'][0]['id']);
3811                 // self::assertEquals(1, $result['terms'][0]['id_str']);
3812                 // self::assertEquals('Saved search', $result['terms'][0]['name']);
3813                 // self::assertEquals('Saved search', $result['terms'][0]['query']);
3814         }
3815 }