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