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