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