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