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