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