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