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