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