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