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