]> git.mxchange.org Git - friendica.git/blob - tests/legacy/ApiTest.php
800bc772e457e424ffd8f32c387d07d69ef5103d
[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_lists_list() function.
2572          *
2573          * @return void
2574          */
2575         public function testApiListsList()
2576         {
2577                 $result = api_lists_list('json');
2578                 self::assertEquals(['lists_list' => []], $result);
2579         }
2580
2581         /**
2582          * Test the api_lists_ownerships() function.
2583          *
2584          * @return void
2585          */
2586         public function testApiListsOwnerships()
2587         {
2588                 $result = api_lists_ownerships('json');
2589                 foreach ($result['lists']['lists'] as $list) {
2590                         self::assertList($list);
2591                 }
2592         }
2593
2594         /**
2595          * Test the api_lists_ownerships() function without an authenticated user.
2596          *
2597          * @return void
2598          */
2599         public function testApiListsOwnershipsWithoutAuthenticatedUser()
2600         {
2601                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
2602                 $_SESSION['authenticated'] = false;
2603                 api_lists_ownerships('json');
2604         }
2605
2606         /**
2607          * Test the api_lists_statuses() function.
2608          *
2609          * @return void
2610          */
2611         public function testApiListsStatuses()
2612         {
2613                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
2614                 api_lists_statuses('json');
2615         }
2616
2617         /**
2618          * Test the api_lists_statuses() function with a list ID.
2619          * @doesNotPerformAssertions
2620          */
2621         public function testApiListsStatusesWithListId()
2622         {
2623                 $_REQUEST['list_id'] = 1;
2624                 $_REQUEST['page']    = -1;
2625                 $_REQUEST['max_id']  = 10;
2626                 $result              = api_lists_statuses('json');
2627                 foreach ($result['status'] as $status) {
2628                         self::assertStatus($status);
2629                 }
2630         }
2631
2632         /**
2633          * Test the api_lists_statuses() function with a list ID and a RSS result.
2634          *
2635          * @return void
2636          */
2637         public function testApiListsStatusesWithListIdAndRss()
2638         {
2639                 $_REQUEST['list_id'] = 1;
2640                 $result              = api_lists_statuses('rss');
2641                 self::assertXml($result, 'statuses');
2642         }
2643
2644         /**
2645          * Test the api_lists_statuses() function with an unallowed user.
2646          *
2647          * @return void
2648          */
2649         public function testApiListsStatusesWithUnallowedUser()
2650         {
2651                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
2652                 $_SESSION['allow_api'] = false;
2653                 $_GET['screen_name']   = $this->selfUser['nick'];
2654                 api_lists_statuses('json');
2655         }
2656
2657         /**
2658          * Test the api_statuses_f() function.
2659          *
2660          * @return void
2661          */
2662         public function testApiStatusesFWithFriends()
2663         {
2664                 $_GET['page'] = -1;
2665                 $result       = api_statuses_f('friends');
2666                 self::assertArrayHasKey('user', $result);
2667         }
2668
2669         /**
2670          * Test the api_statuses_f() function.
2671          *
2672          * @return void
2673          */
2674         public function testApiStatusesFWithFollowers()
2675         {
2676                 $result = api_statuses_f('followers');
2677                 self::assertArrayHasKey('user', $result);
2678         }
2679
2680         /**
2681          * Test the api_statuses_f() function.
2682          *
2683          * @return void
2684          */
2685         public function testApiStatusesFWithBlocks()
2686         {
2687                 $result = api_statuses_f('blocks');
2688                 self::assertArrayHasKey('user', $result);
2689         }
2690
2691         /**
2692          * Test the api_statuses_f() function.
2693          *
2694          * @return void
2695          */
2696         public function testApiStatusesFWithIncoming()
2697         {
2698                 $result = api_statuses_f('incoming');
2699                 self::assertArrayHasKey('user', $result);
2700         }
2701
2702         /**
2703          * Test the api_statuses_f() function an undefined cursor GET variable.
2704          *
2705          * @return void
2706          */
2707         public function testApiStatusesFWithUndefinedCursor()
2708         {
2709                 $_GET['cursor'] = 'undefined';
2710                 self::assertFalse(api_statuses_f('friends'));
2711         }
2712
2713         /**
2714          * Test the api_statuses_friends() function.
2715          *
2716          * @return void
2717          */
2718         public function testApiStatusesFriends()
2719         {
2720                 $result = api_statuses_friends('json');
2721                 self::assertArrayHasKey('user', $result);
2722         }
2723
2724         /**
2725          * Test the api_statuses_friends() function an undefined cursor GET variable.
2726          *
2727          * @return void
2728          */
2729         public function testApiStatusesFriendsWithUndefinedCursor()
2730         {
2731                 $_GET['cursor'] = 'undefined';
2732                 self::assertFalse(api_statuses_friends('json'));
2733         }
2734
2735         /**
2736          * Test the api_statuses_followers() function.
2737          *
2738          * @return void
2739          */
2740         public function testApiStatusesFollowers()
2741         {
2742                 $result = api_statuses_followers('json');
2743                 self::assertArrayHasKey('user', $result);
2744         }
2745
2746         /**
2747          * Test the api_statuses_followers() function an undefined cursor GET variable.
2748          *
2749          * @return void
2750          */
2751         public function testApiStatusesFollowersWithUndefinedCursor()
2752         {
2753                 $_GET['cursor'] = 'undefined';
2754                 self::assertFalse(api_statuses_followers('json'));
2755         }
2756
2757         /**
2758          * Test the api_blocks_list() function.
2759          *
2760          * @return void
2761          */
2762         public function testApiBlocksList()
2763         {
2764                 $result = api_blocks_list('json');
2765                 self::assertArrayHasKey('user', $result);
2766         }
2767
2768         /**
2769          * Test the api_blocks_list() function an undefined cursor GET variable.
2770          *
2771          * @return void
2772          */
2773         public function testApiBlocksListWithUndefinedCursor()
2774         {
2775                 $_GET['cursor'] = 'undefined';
2776                 self::assertFalse(api_blocks_list('json'));
2777         }
2778
2779         /**
2780          * Test the api_friendships_incoming() function.
2781          *
2782          * @return void
2783          */
2784         public function testApiFriendshipsIncoming()
2785         {
2786                 $result = api_friendships_incoming('json');
2787                 self::assertArrayHasKey('id', $result);
2788         }
2789
2790         /**
2791          * Test the api_friendships_incoming() function an undefined cursor GET variable.
2792          *
2793          * @return void
2794          */
2795         public function testApiFriendshipsIncomingWithUndefinedCursor()
2796         {
2797                 $_GET['cursor'] = 'undefined';
2798                 self::assertFalse(api_friendships_incoming('json'));
2799         }
2800
2801         /**
2802          * Test the api_statusnet_config() function.
2803          *
2804          * @return void
2805          */
2806         public function testApiStatusnetConfig()
2807         {
2808                 $result = api_statusnet_config('json');
2809                 self::assertEquals('localhost', $result['config']['site']['server']);
2810                 self::assertEquals('default', $result['config']['site']['theme']);
2811                 self::assertEquals(DI::baseUrl() . '/images/friendica-64.png', $result['config']['site']['logo']);
2812                 self::assertTrue($result['config']['site']['fancy']);
2813                 self::assertEquals('en', $result['config']['site']['language']);
2814                 self::assertEquals('UTC', $result['config']['site']['timezone']);
2815                 self::assertEquals(200000, $result['config']['site']['textlimit']);
2816                 self::assertEquals('false', $result['config']['site']['private']);
2817                 self::assertEquals('false', $result['config']['site']['ssl']);
2818                 self::assertEquals(30, $result['config']['site']['shorturllength']);
2819         }
2820
2821         /**
2822          * Test the api_statusnet_version() function.
2823          *
2824          * @return void
2825          */
2826         public function testApiStatusnetVersion()
2827         {
2828                 // @todo How to test the new API?
2829                 // $result = api_statusnet_version('json');
2830                 // self::assertEquals('0.9.7', $result['version']);
2831         }
2832
2833         /**
2834          * Test the api_direct_messages_new() function.
2835          *
2836          * @return void
2837          */
2838         public function testApiDirectMessagesNew()
2839         {
2840                 $result = api_direct_messages_new('json');
2841                 self::assertNull($result);
2842         }
2843
2844         /**
2845          * Test the api_direct_messages_new() function without an authenticated user.
2846          *
2847          * @return void
2848          */
2849         public function testApiDirectMessagesNewWithoutAuthenticatedUser()
2850         {
2851                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
2852                 $_SESSION['authenticated'] = false;
2853                 api_direct_messages_new('json');
2854         }
2855
2856         /**
2857          * Test the api_direct_messages_new() function with an user ID.
2858          *
2859          * @return void
2860          */
2861         public function testApiDirectMessagesNewWithUserId()
2862         {
2863                 $_POST['text']    = 'message_text';
2864                 $_POST['user_id'] = $this->otherUser['id'];
2865                 $result           = api_direct_messages_new('json');
2866                 self::assertEquals(['direct_message' => ['error' => -1]], $result);
2867         }
2868
2869         /**
2870          * Test the api_direct_messages_new() function with a screen name.
2871          *
2872          * @return void
2873          */
2874         public function testApiDirectMessagesNewWithScreenName()
2875         {
2876                 $this->app->setLoggedInUserNickname($this->selfUser['nick']);
2877                 $_POST['text']        = 'message_text';
2878                 $_POST['screen_name'] = $this->friendUser['nick'];
2879                 $result               = api_direct_messages_new('json');
2880                 self::assertStringContainsString('message_text', $result['direct_message']['text']);
2881                 self::assertEquals('selfcontact', $result['direct_message']['sender_screen_name']);
2882                 self::assertEquals(1, $result['direct_message']['friendica_seen']);
2883         }
2884
2885         /**
2886          * Test the api_direct_messages_new() function with a title.
2887          *
2888          * @return void
2889          */
2890         public function testApiDirectMessagesNewWithTitle()
2891         {
2892                 $this->app->setLoggedInUserNickname($this->selfUser['nick']);
2893                 $_POST['text']        = 'message_text';
2894                 $_POST['screen_name'] = $this->friendUser['nick'];
2895                 $_REQUEST['title']    = 'message_title';
2896                 $result               = api_direct_messages_new('json');
2897                 self::assertStringContainsString('message_text', $result['direct_message']['text']);
2898                 self::assertStringContainsString('message_title', $result['direct_message']['text']);
2899                 self::assertEquals('selfcontact', $result['direct_message']['sender_screen_name']);
2900                 self::assertEquals(1, $result['direct_message']['friendica_seen']);
2901         }
2902
2903         /**
2904          * Test the api_direct_messages_new() function with an RSS result.
2905          *
2906          * @return void
2907          */
2908         public function testApiDirectMessagesNewWithRss()
2909         {
2910                 $this->app->setLoggedInUserNickname($this->selfUser['nick']);
2911                 $_POST['text']        = 'message_text';
2912                 $_POST['screen_name'] = $this->friendUser['nick'];
2913                 $result               = api_direct_messages_new('rss');
2914                 self::assertXml($result, 'direct-messages');
2915         }
2916
2917         /**
2918          * Test the api_direct_messages_destroy() function.
2919          *
2920          * @return void
2921          */
2922         public function testApiDirectMessagesDestroy()
2923         {
2924                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
2925                 api_direct_messages_destroy('json');
2926         }
2927
2928         /**
2929          * Test the api_direct_messages_destroy() function with the friendica_verbose GET param.
2930          *
2931          * @return void
2932          */
2933         public function testApiDirectMessagesDestroyWithVerbose()
2934         {
2935                 $_GET['friendica_verbose'] = 'true';
2936                 $result                    = api_direct_messages_destroy('json');
2937                 self::assertEquals(
2938                         [
2939                                 '$result' => [
2940                                         'result'  => 'error',
2941                                         'message' => 'message id or parenturi not specified'
2942                                 ]
2943                         ],
2944                         $result
2945                 );
2946         }
2947
2948         /**
2949          * Test the api_direct_messages_destroy() function without an authenticated user.
2950          *
2951          * @return void
2952          */
2953         public function testApiDirectMessagesDestroyWithoutAuthenticatedUser()
2954         {
2955                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
2956                 $_SESSION['authenticated'] = false;
2957                 api_direct_messages_destroy('json');
2958         }
2959
2960         /**
2961          * Test the api_direct_messages_destroy() function with a non-zero ID.
2962          *
2963          * @return void
2964          */
2965         public function testApiDirectMessagesDestroyWithId()
2966         {
2967                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
2968                 $_REQUEST['id'] = 1;
2969                 api_direct_messages_destroy('json');
2970         }
2971
2972         /**
2973          * Test the api_direct_messages_destroy() with a non-zero ID and the friendica_verbose GET param.
2974          *
2975          * @return void
2976          */
2977         public function testApiDirectMessagesDestroyWithIdAndVerbose()
2978         {
2979                 $_REQUEST['id']                  = 1;
2980                 $_REQUEST['friendica_parenturi'] = 'parent_uri';
2981                 $_GET['friendica_verbose']       = 'true';
2982                 $result                          = api_direct_messages_destroy('json');
2983                 self::assertEquals(
2984                         [
2985                                 '$result' => [
2986                                         'result'  => 'error',
2987                                         'message' => 'message id not in database'
2988                                 ]
2989                         ],
2990                         $result
2991                 );
2992         }
2993
2994         /**
2995          * Test the api_direct_messages_destroy() function with a non-zero ID.
2996          *
2997          * @return void
2998          */
2999         public function testApiDirectMessagesDestroyWithCorrectId()
3000         {
3001                 $this->markTestIncomplete('We need to add a dataset for this.');
3002         }
3003
3004         /**
3005          * Test the api_direct_messages_box() function.
3006          *
3007          * @return void
3008          */
3009         public function testApiDirectMessagesBoxWithSentbox()
3010         {
3011                 $_REQUEST['page']   = -1;
3012                 $_REQUEST['max_id'] = 10;
3013                 $result             = api_direct_messages_box('json', 'sentbox', 'false');
3014                 self::assertArrayHasKey('direct_message', $result);
3015         }
3016
3017         /**
3018          * Test the api_direct_messages_box() function.
3019          *
3020          * @return void
3021          */
3022         public function testApiDirectMessagesBoxWithConversation()
3023         {
3024                 $result = api_direct_messages_box('json', 'conversation', 'false');
3025                 self::assertArrayHasKey('direct_message', $result);
3026         }
3027
3028         /**
3029          * Test the api_direct_messages_box() function.
3030          *
3031          * @return void
3032          */
3033         public function testApiDirectMessagesBoxWithAll()
3034         {
3035                 $result = api_direct_messages_box('json', 'all', 'false');
3036                 self::assertArrayHasKey('direct_message', $result);
3037         }
3038
3039         /**
3040          * Test the api_direct_messages_box() function.
3041          *
3042          * @return void
3043          */
3044         public function testApiDirectMessagesBoxWithInbox()
3045         {
3046                 $result = api_direct_messages_box('json', 'inbox', 'false');
3047                 self::assertArrayHasKey('direct_message', $result);
3048         }
3049
3050         /**
3051          * Test the api_direct_messages_box() function.
3052          *
3053          * @return void
3054          */
3055         public function testApiDirectMessagesBoxWithVerbose()
3056         {
3057                 $result = api_direct_messages_box('json', 'sentbox', 'true');
3058                 self::assertEquals(
3059                         [
3060                                 '$result' => [
3061                                         'result'  => 'error',
3062                                         'message' => 'no mails available'
3063                                 ]
3064                         ],
3065                         $result
3066                 );
3067         }
3068
3069         /**
3070          * Test the api_direct_messages_box() function with a RSS result.
3071          *
3072          * @return void
3073          */
3074         public function testApiDirectMessagesBoxWithRss()
3075         {
3076                 $result = api_direct_messages_box('rss', 'sentbox', 'false');
3077                 self::assertXml($result, 'direct-messages');
3078         }
3079
3080         /**
3081          * Test the api_direct_messages_box() function without an authenticated user.
3082          *
3083          * @return void
3084          */
3085         public function testApiDirectMessagesBoxWithUnallowedUser()
3086         {
3087                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
3088                 $_SESSION['allow_api'] = false;
3089                 $_GET['screen_name']   = $this->selfUser['nick'];
3090                 api_direct_messages_box('json', 'sentbox', 'false');
3091         }
3092
3093         /**
3094          * Test the api_direct_messages_sentbox() function.
3095          *
3096          * @return void
3097          */
3098         public function testApiDirectMessagesSentbox()
3099         {
3100                 $result = api_direct_messages_sentbox('json');
3101                 self::assertArrayHasKey('direct_message', $result);
3102         }
3103
3104         /**
3105          * Test the api_direct_messages_inbox() function.
3106          *
3107          * @return void
3108          */
3109         public function testApiDirectMessagesInbox()
3110         {
3111                 $result = api_direct_messages_inbox('json');
3112                 self::assertArrayHasKey('direct_message', $result);
3113         }
3114
3115         /**
3116          * Test the api_direct_messages_all() function.
3117          *
3118          * @return void
3119          */
3120         public function testApiDirectMessagesAll()
3121         {
3122                 $result = api_direct_messages_all('json');
3123                 self::assertArrayHasKey('direct_message', $result);
3124         }
3125
3126         /**
3127          * Test the api_direct_messages_conversation() function.
3128          *
3129          * @return void
3130          */
3131         public function testApiDirectMessagesConversation()
3132         {
3133                 $result = api_direct_messages_conversation('json');
3134                 self::assertArrayHasKey('direct_message', $result);
3135         }
3136
3137         /**
3138          * Test the api_oauth_request_token() function.
3139          *
3140          * @return void
3141          */
3142         public function testApiOauthRequestToken()
3143         {
3144                 $this->markTestIncomplete('exit() kills phpunit as well');
3145         }
3146
3147         /**
3148          * Test the api_oauth_access_token() function.
3149          *
3150          * @return void
3151          */
3152         public function testApiOauthAccessToken()
3153         {
3154                 $this->markTestIncomplete('exit() kills phpunit as well');
3155         }
3156
3157         /**
3158          * Test the api_fr_photos_list() function.
3159          *
3160          * @return void
3161          */
3162         public function testApiFrPhotosList()
3163         {
3164                 $result = api_fr_photos_list('json');
3165                 self::assertArrayHasKey('photo', $result);
3166         }
3167
3168         /**
3169          * Test the api_fr_photos_list() function without an authenticated user.
3170          *
3171          * @return void
3172          */
3173         public function testApiFrPhotosListWithoutAuthenticatedUser()
3174         {
3175                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
3176                 $_SESSION['authenticated'] = false;
3177                 api_fr_photos_list('json');
3178         }
3179
3180         /**
3181          * Test the api_fr_photo_create_update() function.
3182          */
3183         public function testApiFrPhotoCreateUpdate()
3184         {
3185                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
3186                 api_fr_photo_create_update('json');
3187         }
3188
3189         /**
3190          * Test the api_fr_photo_create_update() function without an authenticated user.
3191          *
3192          * @return void
3193          */
3194         public function testApiFrPhotoCreateUpdateWithoutAuthenticatedUser()
3195         {
3196                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
3197                 $_SESSION['authenticated'] = false;
3198                 api_fr_photo_create_update('json');
3199         }
3200
3201         /**
3202          * Test the api_fr_photo_create_update() function with an album name.
3203          *
3204          * @return void
3205          */
3206         public function testApiFrPhotoCreateUpdateWithAlbum()
3207         {
3208                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
3209                 $_REQUEST['album'] = 'album_name';
3210                 api_fr_photo_create_update('json');
3211         }
3212
3213         /**
3214          * Test the api_fr_photo_create_update() function with the update mode.
3215          *
3216          * @return void
3217          */
3218         public function testApiFrPhotoCreateUpdateWithUpdate()
3219         {
3220                 $this->markTestIncomplete('We need to create a dataset for this');
3221         }
3222
3223         /**
3224          * Test the api_fr_photo_create_update() function with an uploaded file.
3225          *
3226          * @return void
3227          */
3228         public function testApiFrPhotoCreateUpdateWithFile()
3229         {
3230                 $this->markTestIncomplete();
3231         }
3232
3233         /**
3234          * Test the api_fr_photo_detail() function.
3235          *
3236          * @return void
3237          */
3238         public function testApiFrPhotoDetail()
3239         {
3240                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
3241                 api_fr_photo_detail('json');
3242         }
3243
3244         /**
3245          * Test the api_fr_photo_detail() function without an authenticated user.
3246          *
3247          * @return void
3248          */
3249         public function testApiFrPhotoDetailWithoutAuthenticatedUser()
3250         {
3251                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
3252                 $_SESSION['authenticated'] = false;
3253                 api_fr_photo_detail('json');
3254         }
3255
3256         /**
3257          * Test the api_fr_photo_detail() function with a photo ID.
3258          *
3259          * @return void
3260          */
3261         public function testApiFrPhotoDetailWithPhotoId()
3262         {
3263                 $this->expectException(\Friendica\Network\HTTPException\NotFoundException::class);
3264                 $_REQUEST['photo_id'] = 1;
3265                 api_fr_photo_detail('json');
3266         }
3267
3268         /**
3269          * Test the api_fr_photo_detail() function with a correct photo ID.
3270          *
3271          * @return void
3272          */
3273         public function testApiFrPhotoDetailCorrectPhotoId()
3274         {
3275                 $this->markTestIncomplete('We need to create a dataset for this.');
3276         }
3277
3278         /**
3279          * Test the api_account_update_profile_image() function.
3280          *
3281          * @return void
3282          */
3283         public function testApiAccountUpdateProfileImage()
3284         {
3285                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
3286                 api_account_update_profile_image('json');
3287         }
3288
3289         /**
3290          * Test the api_account_update_profile_image() function without an authenticated user.
3291          *
3292          * @return void
3293          */
3294         public function testApiAccountUpdateProfileImageWithoutAuthenticatedUser()
3295         {
3296                 $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
3297                 $_SESSION['authenticated'] = false;
3298                 api_account_update_profile_image('json');
3299         }
3300
3301         /**
3302          * Test the api_account_update_profile_image() function with an uploaded file.
3303          *
3304          * @return void
3305          */
3306         public function testApiAccountUpdateProfileImageWithUpload()
3307         {
3308                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
3309                 $this->markTestIncomplete();
3310         }
3311
3312
3313         /**
3314          * Test the api_account_update_profile() function.
3315          *
3316          * @return void
3317          */
3318         public function testApiAccountUpdateProfile()
3319         {
3320                 $_POST['name']        = 'new_name';
3321                 $_POST['description'] = 'new_description';
3322                 $result               = api_account_update_profile('json');
3323                 // We can't use assertSelfUser() here because the user object is missing some properties.
3324                 self::assertEquals($this->selfUser['id'], $result['user']['cid']);
3325                 self::assertEquals('DFRN', $result['user']['location']);
3326                 self::assertEquals($this->selfUser['nick'], $result['user']['screen_name']);
3327                 self::assertEquals('dfrn', $result['user']['network']);
3328                 self::assertEquals('new_name', $result['user']['name']);
3329                 self::assertEquals('new_description', $result['user']['description']);
3330         }
3331
3332         /**
3333          * Test the check_acl_input() function.
3334          *
3335          * @return void
3336          */
3337         public function testCheckAclInput()
3338         {
3339                 $result = check_acl_input('<aclstring>');
3340                 // Where does this result come from?
3341                 self::assertEquals(1, $result);
3342         }
3343
3344         /**
3345          * Test the check_acl_input() function with an empty ACL string.
3346          *
3347          * @return void
3348          */
3349         public function testCheckAclInputWithEmptyAclString()
3350         {
3351                 $result = check_acl_input(' ');
3352                 self::assertFalse($result);
3353         }
3354
3355         /**
3356          * Test the save_media_to_database() function.
3357          *
3358          * @return void
3359          */
3360         public function testSaveMediaToDatabase()
3361         {
3362                 $this->markTestIncomplete();
3363         }
3364
3365         /**
3366          * Test the post_photo_item() function.
3367          *
3368          * @return void
3369          */
3370         public function testPostPhotoItem()
3371         {
3372                 $this->markTestIncomplete();
3373         }
3374
3375         /**
3376          * Test the prepare_photo_data() function.
3377          *
3378          * @return void
3379          */
3380         public function testPreparePhotoData()
3381         {
3382                 $this->markTestIncomplete();
3383         }
3384
3385         /**
3386          * Test the api_share_as_retweet() function with a valid item.
3387          *
3388          * @return void
3389          */
3390         public function testApiShareAsRetweetWithValidItem()
3391         {
3392                 $this->markTestIncomplete();
3393         }
3394
3395         /**
3396          * Test the api_in_reply_to() function.
3397          *
3398          * @return void
3399          */
3400         public function testApiInReplyTo()
3401         {
3402                 $result = api_in_reply_to(['id' => 0, 'parent' => 0, 'uri' => '', 'thr-parent' => '']);
3403                 self::assertArrayHasKey('status_id', $result);
3404                 self::assertArrayHasKey('user_id', $result);
3405                 self::assertArrayHasKey('status_id_str', $result);
3406                 self::assertArrayHasKey('user_id_str', $result);
3407                 self::assertArrayHasKey('screen_name', $result);
3408         }
3409
3410         /**
3411          * Test the api_in_reply_to() function with a valid item.
3412          *
3413          * @return void
3414          */
3415         public function testApiInReplyToWithValidItem()
3416         {
3417                 $this->markTestIncomplete();
3418         }
3419
3420         /**
3421          * Test the api_clean_plain_items() function.
3422          *
3423          * @return void
3424          */
3425         public function testApiCleanPlainItems()
3426         {
3427                 $_REQUEST['include_entities'] = 'true';
3428                 $result                       = api_clean_plain_items('some_text [url="some_url"]some_text[/url]');
3429                 self::assertEquals('some_text [url="some_url"]"some_url"[/url]', $result);
3430         }
3431
3432         /**
3433          * Test the api_best_nickname() function.
3434          *
3435          * @return void
3436          */
3437         public function testApiBestNickname()
3438         {
3439                 $contacts = [];
3440                 $result   = api_best_nickname($contacts);
3441                 self::assertNull($result);
3442         }
3443
3444         /**
3445          * Test the api_best_nickname() function with contacts.
3446          *
3447          * @return void
3448          */
3449         public function testApiBestNicknameWithContacts()
3450         {
3451                 $this->markTestIncomplete();
3452         }
3453
3454         /**
3455          * Test the api_friendica_group_show() function.
3456          *
3457          * @return void
3458          */
3459         public function testApiFriendicaGroupShow()
3460         {
3461                 $this->markTestIncomplete();
3462         }
3463
3464         /**
3465          * Test the api_friendica_group_delete() function.
3466          *
3467          * @return void
3468          */
3469         public function testApiFriendicaGroupDelete()
3470         {
3471                 $this->markTestIncomplete();
3472         }
3473
3474         /**
3475          * Test the api_lists_destroy() function.
3476          *
3477          * @return void
3478          */
3479         public function testApiListsDestroy()
3480         {
3481                 $this->markTestIncomplete();
3482         }
3483
3484         /**
3485          * Test the group_create() function.
3486          *
3487          * @return void
3488          */
3489         public function testGroupCreate()
3490         {
3491                 $this->markTestIncomplete();
3492         }
3493
3494         /**
3495          * Test the api_friendica_group_create() function.
3496          *
3497          * @return void
3498          */
3499         public function testApiFriendicaGroupCreate()
3500         {
3501                 $this->markTestIncomplete();
3502         }
3503
3504         /**
3505          * Test the api_lists_create() function.
3506          *
3507          * @return void
3508          */
3509         public function testApiListsCreate()
3510         {
3511                 $this->markTestIncomplete();
3512         }
3513
3514         /**
3515          * Test the api_friendica_group_update() function.
3516          *
3517          * @return void
3518          */
3519         public function testApiFriendicaGroupUpdate()
3520         {
3521                 $this->markTestIncomplete();
3522         }
3523
3524         /**
3525          * Test the api_lists_update() function.
3526          *
3527          * @return void
3528          */
3529         public function testApiListsUpdate()
3530         {
3531                 $this->markTestIncomplete();
3532         }
3533
3534         /**
3535          * Test the api_friendica_activity() function.
3536          *
3537          * @return void
3538          */
3539         public function testApiFriendicaActivity()
3540         {
3541                 $this->markTestIncomplete();
3542         }
3543
3544         /**
3545          * Test the api_friendica_notification_seen() function.
3546          *
3547          * @return void
3548          */
3549         public function testApiFriendicaNotificationSeen()
3550         {
3551                 $this->markTestIncomplete();
3552         }
3553
3554         /**
3555          * Test the api_friendica_direct_messages_setseen() function.
3556          *
3557          * @return void
3558          */
3559         public function testApiFriendicaDirectMessagesSetseen()
3560         {
3561                 $this->markTestIncomplete();
3562         }
3563
3564         /**
3565          * Test the api_friendica_direct_messages_search() function.
3566          *
3567          * @return void
3568          */
3569         public function testApiFriendicaDirectMessagesSearch()
3570         {
3571                 $this->markTestIncomplete();
3572         }
3573
3574         /**
3575          * Test the api_saved_searches_list() function.
3576          *
3577          * @return void
3578          */
3579         public function testApiSavedSearchesList()
3580         {
3581                 // $result = api_saved_searches_list('json');
3582                 // self::assertEquals(1, $result['terms'][0]['id']);
3583                 // self::assertEquals(1, $result['terms'][0]['id_str']);
3584                 // self::assertEquals('Saved search', $result['terms'][0]['name']);
3585                 // self::assertEquals('Saved search', $result['terms'][0]['query']);
3586         }
3587 }